def _rdt_rcv(self, src_addr, dst_addr, segment): src_port, dst_port, seq_no, ack_no, \ flags, _, _, _ = read_header(segment) if dst_port != self.porta: # Ignora segmentos que não são destinados à porta do nosso servidor return payload = segment[4 * (flags >> 12):] id_conexao = (src_addr, src_port, dst_addr, dst_port) if (flags & FLAGS_SYN) == FLAGS_SYN: conexao = self.conexoes[id_conexao] = Conexao( self, id_conexao, seq_no) if self.callback: self.callback(conexao) elif id_conexao in self.conexoes: # Passa para a conexão adequada se ela já estiver estabelecida self.conexoes[id_conexao]._rdt_rcv(seq_no, ack_no, flags, payload) if (flags & FLAGS_FIN) == FLAGS_FIN: self.conexoes.pop(id_conexao) else: print('%s:%d -> %s:%d (pacote associado a conexão desconhecida)' % (src_addr, src_port, dst_addr, dst_port))
def _rdt_rcv(self, src_addr, dst_addr, segment): src_port, dst_port, seq_no, ack_no, \ flags, _, _, _ = read_header(segment) if dst_port != self.porta: # Ignora segmentos que não são destinados à porta do nosso servidor return try: pseudohdr = str2addr(src_addr) + str2addr(dst_addr) + \ struct.pack('!HH', 0x0006, len(segment)) if calc_checksum(pseudohdr + segment) != 0: print('descartando segmento com checksum incorreto') return
def _start_connection(self, id_conexao, segment): src_port, dst_port, seq_no, ack_no, \ flags, _, _, _ = read_header(segment) src_addr, src_port, dst_addr, dst_port = id_conexao ack_no = seq_no + 1 seq_no = random.randint(40, 0xfff) cabecalho = make_header(dst_port, src_port, seq_no, ack_no, FLAGS_SYN | FLAGS_ACK) cabecalho = fix_checksum(cabecalho, src_addr, dst_addr) self.rede.enviar(cabecalho, src_addr) print(f'{src_addr}:{src_port}', 'connected with', f'{dst_addr}:{dst_port}') print('handshaking: seq->', seq_no, 'ack->', ack_no) return Conexao(self, id_conexao, seq_no + 1, ack_no)
def _rdt_rcv(self, src_addr, dst_addr, segment): src_port, dst_port, seq_no, ack_no, \ flags, _, _, _ = read_header(segment) if dst_port != self.porta: # Ignora segmentos que não são destinados à porta do nosso servidor return payload = segment[4 * (flags >> 12):] id_conexao = (src_addr, src_port, dst_addr, dst_port) if (flags & FLAGS_SYN) == FLAGS_SYN and self.status_conexao == 1: tmp = ack_no ack_no = seq_no + 1 seq_no = tmp self.id_conexao = id_conexao cabecalho = make_header(dst_port, src_port, seq_no, ack_no, FLAGS_ACK) cabecalho = fix_checksum(cabecalho, src_addr, dst_addr) self.rede.enviar(cabecalho, src_addr) self.conexao = Conexao(self, id_conexao, seq_no, ack_no) self.status_conexao = 2 if self.callback: self.callback(self.conexao) elif id_conexao == self.id_conexao and self.status_conexao == 2: # Passa para a conexão adequada se ela já estiver estabelecida self.conexao._rdt_rcv(seq_no, ack_no, flags, payload) elif self.status_conexao != 2: print('%s:%d -> %s:%d (conexão não estabelecida)' % (src_addr, src_port, dst_addr, dst_port)) else: print('%s:%d -> %s:%d (pacote associado a conexão desconhecida)' % (src_addr, src_port, dst_addr, dst_port))