Exemple #1
0
    def _rdt_rcv(self, seq_no, ack_no, flags, payload):
        src_addr, src_port, dst_addr, dst_port = self.id_conexao

        if self.ack_no == seq_no:

            if DEBUG:
                print(f'{src_addr}:{src_port}', 'receiving: seq->', seq_no,
                      'ack->', ack_no, 'bytes->', len(payload))

            if (flags & FLAGS_FIN) == FLAGS_FIN and not self.closing:
                self.closing = True
                self.callback(self, b'')
                self.ack_no += 1
                src_addr, src_port, dst_addr, dst_port = self.id_conexao
                cabecalho = make_header(dst_port, src_port, self.seq_no,
                                        self.ack_no, FLAGS_FIN | FLAGS_ACK)
                cabecalho = fix_checksum(cabecalho, dst_addr, src_addr)
                self.servidor.rede.enviar(cabecalho, src_addr)
                return
            elif (flags & FLAGS_ACK) == FLAGS_ACK and self.closing:
                print(f'Fechada a conexão com {src_addr}:{src_port}')
                self.servidor.conexoes.pop(self.id_conexao)
                return

            if ack_no > self.send_base and (flags & FLAGS_ACK) == FLAGS_ACK:
                self.nao_confirmados = self.nao_confirmados[ack_no -
                                                            self.send_base:]
                self.send_base = ack_no

                if self.nao_confirmados:
                    if DEBUG:
                        print('++Timer restarted++')
                    self._start_timer()
                else:
                    if DEBUG:
                        print('++Timer stopped++')
                    self._stop_timer()
                    if not self.retransmitindo:
                        self.final_moment = time.time()
                        self.calc_rtt()

            if self.last_seq == ack_no:
                self.janela += 1
                if DEBUG:
                    print('Updated window', self.janela, 'MSS')
                self._send_pending()

            self.retransmitindo = False
            self.ack_no += len(payload)

            if len(payload) > 0:  # Só Deus sabe, mas funciona
                dados = make_header(src_port, dst_port, self.seq_no,
                                    self.ack_no, flags)
                dados = fix_checksum(dados, src_addr, dst_addr)
                self.servidor.rede.enviar(dados, src_addr)

                self.callback(self, payload)
Exemple #2
0
 def fechar(self):
     """
     Usado pela camada de aplicação para fechar a conexão
     """
     src_addr, src_port, dst_addr, dst_port = self.id_conexao
     cabecalho = make_header(dst_port, src_port, self.seq_no, self.seq_no, FLAGS_FIN)
     cabecalho = fix_checksum(cabecalho, dst_addr, src_addr)
     self.servidor.rede.enviar(cabecalho, src_addr)
Exemple #3
0
 def _start_connection(self):
     src_addr, src_port, dst_addr, dst_port = self.id_conexao
     cabecalho = make_header(dst_port, src_port,self.seq_no,self.ack_no,FLAGS_SYN | FLAGS_ACK)
     cabecalho = fix_checksum(cabecalho, src_addr, dst_addr)
     self.servidor.rede.enviar(cabecalho,src_addr)
     self.seq_no += 1
     self.send_base = self.seq_no
     if DEBUG:
         print(f'{src_addr}:{src_port}', 'connected with', f'{dst_addr}:{dst_port}')
         print('handshaking: seq->',self.seq_no,'ack->',self.ack_no)
Exemple #4
0
    def start_connection(self, dst_addr, dst_port):
        src_addr = self.rede.meu_endereco
        src_port = self.porta

        ack_no = 0
        seq_no = 0

        cabecalho = make_header(src_port, dst_port, seq_no, ack_no, FLAGS_SYN)
        cabecalho = fix_checksum(cabecalho, src_addr, dst_addr)
        self.rede.enviar(cabecalho, dst_addr)
        print(f'{src_addr}:{src_port}', 'connecting with',
              f'{dst_addr}:{dst_port}')
        print('handshaking: seq->', seq_no, 'ack->', ack_no)
        self.status_conexao = 1
Exemple #5
0
    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)
Exemple #6
0
    def _send_ack_segment(self, payload):
        src_addr, src_port, dst_addr, dst_port = self.id_conexao
        seq_no = None
        if self.retransmitindo:
            seq_no = self.send_base
        else:
            seq_no = self.seq_no
            self.seq_no += len(payload)
            self.nao_confirmados = self.nao_confirmados + payload
        cabecalho = make_header(dst_port, src_port, seq_no, self.ack_no,
                                FLAGS_ACK)
        segmento = fix_checksum(cabecalho + payload, dst_addr, src_addr)
        self.servidor.rede.enviar(segmento, src_addr)

        if self.timer is None:
            self.initial_moment = time.time()
            self._start_timer()
Exemple #7
0
    def _rdt_rcv(self, seq_no, ack_no, flags, payload):

        src_addr, src_port, dst_addr, dst_port = self.id_conexao

        if self.ack_no == seq_no:
            if DEBUG:
                print(src_addr, 'receiving: seq->', seq_no, 'ack->', ack_no,
                      'bytes->', len(payload))

            if ack_no > self.send_base and (flags & FLAGS_ACK) == FLAGS_ACK:
                self.nao_confirmados = self.nao_confirmados[ack_no -
                                                            self.send_base:]
                self.send_base = ack_no

                if self.nao_confirmados:
                    if DEBUG:
                        print('++Timer restarted++')
                    self._start_timer()
                else:
                    if DEBUG:
                        print('++Timer stopped++')
                    self._stop_timer()
                    if not self.retransmitindo:
                        self.final_moment = time.time()
                        self.calc_rtt()

            self.retransmitindo = False
            self.ack_no += len(payload)

            if (flags & FLAGS_FIN) == FLAGS_FIN:
                self.ack_no += 1  # É preciso somar, pois quando é enviada a flag FIN não há payload
                flags = FLAGS_FIN | FLAGS_ACK

            if ((flags & FLAGS_FIN) == FLAGS_FIN
                ) or len(payload) > 0:  # Só Deus sabe, mas funciona
                dados = make_header(src_port, dst_port, self.seq_no,
                                    self.ack_no, flags)
                dados = fix_checksum(dados, src_addr, dst_addr)
                self.servidor.rede.enviar(dados, src_addr)

            self.callback(self, payload)
Exemple #8
0
    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))