#!/usr/bin/env python3
# Antes de usar, execute o seguinte comando para evitar que o Linux feche
# as conexões TCP que o seu programa estiver tratando:
#
# sudo iptables -I OUTPUT -p tcp --tcp-flags RST RST -j DROP


# Este é um exemplo de um programa que faz eco, ou seja, envia de volta para
# o cliente tudo que for recebido em uma conexão.

import asyncio
from camadarede import CamadaRedeLinux
from mytcp import Servidor

def dados_recebidos(conexao, dados):
    if dados == b'':
        conexao.fechar()
    else:
        conexao.enviar(dados)   # envia de volta

def conexao_aceita(conexao):
    conexao.registrar_recebedor(dados_recebidos)   # usa esse mesmo recebedor para toda conexão aceita

rede = CamadaRedeLinux()
servidor = Servidor(rede, 7000)
servidor.registrar_monitor_de_conexoes_aceitas(conexao_aceita)
asyncio.get_event_loop().run_forever()
Ejemplo n.º 2
0
def main():
    global recebido, conexao

    rede = CamadaRede()
    dst_port = random.randint(10, 1023)
    servidor = Servidor(rede, dst_port)
    servidor.registrar_monitor_de_conexoes_aceitas(conexao_aceita)

    src_port = random.randint(1024, 0xffff)
    seq_no = random.randint(0, 0xffff)
    src_addr, dst_addr = '10.%d.1.%d'%(random.randint(1, 10), random.randint(0,255)), '10.%d.1.%d'%(random.randint(11, 20), random.randint(0, 255))
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, 0, FLAGS_SYN), src_addr, dst_addr))
    segmento, _ = rede.fila[0]
    _, _, ack_no, ack, flags, _, _, _ = read_header(segmento)
    assert 4*(flags>>12) == len(segmento), 'O SYN+ACK não deveria ter payload'
    assert (flags & FLAGS_ACK) == FLAGS_ACK
    rede.fila.clear()

    seq_no += 1
    ack_no += 1
    assert ack == seq_no

    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))
    rede.fila.clear()

    payload = os.urandom(MSS)
    conexao.enviar(payload)
    assert len(rede.fila) == 1

    yield from asyncio.sleep(0.2)

    while len(rede.fila) > 0:
        segmento, _ = rede.fila.pop(0)
        _, _, seq, ack, flags, _, _, _ = read_header(segmento)
        assert seq == ack_no
        assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
        assert segmento[4*(flags>>12):] == payload

    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    payload = os.urandom(MSS)
    conexao.enviar(payload)
    assert len(rede.fila) == 1
    rede.fila.clear()  # descarta

    yield from asyncio.sleep(1.5)

    while len(rede.fila) > 0:
        segmento, _ = rede.fila.pop(0)
        _, _, seq, ack, flags, _, _, _ = read_header(segmento)
        assert seq == ack_no
        assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
        assert segmento[4*(flags>>12):] == payload

    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    payload = os.urandom(2*MSS)
    conexao.enviar(payload)
    rede.fila.clear()  # descarta

    yield from asyncio.sleep(1.5)

    while len(rede.fila) > 0:
        segmento, _ = rede.fila.pop(0)
        _, _, seq, ack, flags, _, _, _ = read_header(segmento)
        print("ack "+str(ack_no)+" seq "+str(seq))
        # Apenas o segmento mais antigo deve ser reenviado no timeout
        assert seq == ack_no
        assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
        assert segmento[4*(flags>>12):] == payload[:MSS]

    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    yield from asyncio.sleep(1.5)

    segmento, _ = rede.fila.pop(0)
    _, _, seq, ack, flags, _, _, _ = read_header(segmento)
    # Agora deve vir o segundo segmento
    assert seq == ack_no
    assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
    assert segmento[4*(flags>>12):] == payload[MSS:]

    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))
Ejemplo n.º 3
0
server = Server()

# Integração com as demais camadas

driver = ZyboSerialDriver()
linha_serial = driver.obter_porta(4)
pty = driver.expor_porta_ao_linux(5)
outra_ponta = '192.168.123.1'
nossa_ponta = '192.168.123.2'
porta_tcp = 7000

print('Conecte o RX da porta 4 com o TX da porta 5 e vice-versa.')
print('Para conectar a outra ponta da camada física, execute:')
print()
print('sudo slattach -vLp slip {}'.format(pty.pty_name))
print('sudo ifconfig sl0 {} pointopoint {} mtu 1500'.format(
    outra_ponta, nossa_ponta))
print()
print('Acesse o serviço com o comando: nc {} {}'.format(nossa_ponta, porta_tcp))
print()

enlace = CamadaEnlace({outra_ponta: linha_serial})
rede = CamadaRede(enlace)
rede.definir_endereco_host(nossa_ponta)
rede.definir_tabela_encaminhamento([
    ('0.0.0.0/0', outra_ponta)
])
tcp = Tcp(rede, porta_tcp)
tcp.registrar_monitor_de_conexoes_aceitas(server.conexao_aceita)
asyncio.get_event_loop().run_forever()
Ejemplo n.º 4
0
    conexao.registrar_recebedor(dados_recebidos)   # usa esse mesmo recebedor para toda conexão aceita


# Integração com as demais camadas

driver = ZyboSerialDriver()
linha_serial = driver.obter_porta(4)
pty = driver.expor_porta_ao_linux(5)
outra_ponta = '192.168.123.1'
nossa_ponta = '192.168.123.2'
porta_tcp = 7000

print('Conecte o RX da porta 4 com o TX da porta 5 e vice-versa.')
print('Para conectar a outra ponta da camada física, execute:')
print()
print('sudo slattach -vLp slip {}'.format(pty.pty_name))
print('sudo ifconfig sl0 {} pointopoint {} mtu 1500'.format(outra_ponta, nossa_ponta))
print()
print('Acesse o serviço com o comando: nc {} {}'.format(nossa_ponta, porta_tcp))
print()

enlace = CamadaEnlace({outra_ponta: linha_serial})
rede = CamadaRede(enlace)
rede.definir_endereco_host(nossa_ponta)
rede.definir_tabela_encaminhamento([
    ('0.0.0.0/0', outra_ponta)
])
servidor = Servidor(rede, porta_tcp)
servidor.registrar_monitor_de_conexoes_aceitas(conexao_aceita)
asyncio.get_event_loop().run_forever()
Ejemplo n.º 5
0
def main():
    global recebido, conexao

    rede = CamadaRede()
    dst_port = random.randint(10, 1023)
    servidor = Servidor(rede, dst_port)
    servidor.registrar_monitor_de_conexoes_aceitas(conexao_aceita)

    src_port = random.randint(1024, 0xffff)
    seq_no = random.randint(0, 0xffff)
    src_addr, dst_addr = '10.%d.%d.%d'%(random.randint(1, 10), random.randint(0,255), random.randint(0,255)), '10.%d.%d.%d'%(random.randint(11,20), random.randint(0,255), random.randint(0,255))
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, 0, FLAGS_SYN), src_addr, dst_addr))
    segmento, _ = rede.fila[0]
    _, _, ack_no, ack, flags, _, _, _ = read_header(segmento)
    assert 4*(flags>>12) == len(segmento), 'O SYN+ACK não deveria ter payload'
    assert (flags & FLAGS_ACK) == FLAGS_ACK
    rede.fila.clear()

    seq_no += 1
    ack_no += 1
    assert ack == seq_no

    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))
    rede.fila.clear()

    payload = os.urandom(MSS)
    conexao.enviar(payload)
    assert len(rede.fila) == 1

    yield from asyncio.sleep(0.1)

    while len(rede.fila) > 0:
        segmento, _ = rede.fila.pop(0)
        _, _, seq, ack, flags, _, _, _ = read_header(segmento)
        assert seq == ack_no
        assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
        assert segmento[4*(flags>>12):] == payload

    ack_no += len(payload)
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    payload = os.urandom(14*MSS)
    conexao.enviar(payload)
    for winsize in (2, 3, 4, 5):
        assert len(rede.fila) == winsize, 'A janela neste momento deveria ser de %d MSS, mas foi de %d MSS' % (winsize, len(rede.fila))
        for _ in range(winsize):
            segmento, _ = rede.fila.pop(0)
            _, _, seq, ack, flags, _, _, _ = read_header(segmento)
            assert seq == ack_no
            assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
            assert segmento[4*(flags>>12):] == payload[:MSS]
            payload = payload[MSS:]
            ack_no += MSS
        if winsize == 5:
            # Causa um timeout
            yield from asyncio.sleep(0.25)
            assert len(rede.fila) == 1, 'Deveria ter acontecido a retransmissão de um segmento'
            rede.fila.clear()
        else:
            yield from asyncio.sleep(0.1)
        rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    payload = os.urandom(12*MSS)
    conexao.enviar(payload)
    for winsize in (3, 4, 5):
        assert len(rede.fila) == winsize, 'A janela neste momento deveria ser de %d MSS, mas foi de %d MSS' % (winsize, len(rede.fila))
        for _ in range(winsize):
            segmento, _ = rede.fila.pop(0)
            _, _, seq, ack, flags, _, _, _ = read_header(segmento)
            assert seq == ack_no
            assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
            assert segmento[4*(flags>>12):] == payload[:MSS]
            payload = payload[MSS:]
            ack_no += MSS
        yield from asyncio.sleep(0.1)
        rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))
Ejemplo n.º 6
0
def main():
    global recebido, conexao

    rede = CamadaRede()
    dst_port = random.randint(10, 1023)
    servidor = Servidor(rede, dst_port)
    servidor.registrar_monitor_de_conexoes_aceitas(conexao_aceita)

    src_port = random.randint(1024, 0xffff)
    seq_no = random.randint(0, 0xffff)
    src_addr, dst_addr = '10.%d.%d.%d'%(random.randint(1, 10), random.randint(0,255), random.randint(0,255)), '10.%d.%d.%d'%(random.randint(11,20), random.randint(0,255), random.randint(0,255))
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, 0, FLAGS_SYN), src_addr, dst_addr))
    segmento, _ = rede.fila[0]
    _, _, ack_no, ack, flags, _, _, _ = read_header(segmento)
    assert 4*(flags>>12) == len(segmento), 'O SYN+ACK não deveria ter payload'
    assert (flags & FLAGS_ACK) == FLAGS_ACK
    rede.fila.clear()

    seq_no += 1
    ack_no += 1
    assert ack == seq_no

    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))
    rede.fila.clear()

    payload = os.urandom(MSS)
    conexao.enviar(payload)
    assert len(rede.fila) == 1

    yield from asyncio.sleep(0.1)

    while len(rede.fila) > 0:
        segmento, _ = rede.fila.pop(0)
        _, _, seq, ack, flags, _, _, _ = read_header(segmento)
        assert seq == ack_no
        assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
        assert segmento[4*(flags>>12):] == payload

    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    payload = os.urandom(MSS)
    conexao.enviar(payload)
    assert len(rede.fila) == 1
    rede.fila.clear()  # descarta

    # sample_rtt = 0.1
    # estimated_rtt = sample_rtt = 0.1
    # dev_rtt = sample_rtt/2 = 0.05
    # timeout_interval = estimated_rtt + 4*dev_rtt  = 0.3
    # 0.29 < timeout_interval < 0.31
    yield from asyncio.sleep(0.29)
    assert len(rede.fila) == 0, 'Não deveria ter retransmitido ainda'
    yield from asyncio.sleep(0.02)
    assert len(rede.fila) == 1, 'Já deveria ter retransmitido'

    segmento, _ = rede.fila.pop(0)
    _, _, seq, ack, flags, _, _, _ = read_header(segmento)
    assert seq == ack_no
    assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
    assert segmento[4*(flags>>12):] == payload

    # Verifica se o tempo de segmentos retransmitidos está sendo ignorado
    yield from asyncio.sleep(2)
    rede.fila.clear()
    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))
    payload = os.urandom(MSS)
    conexao.enviar(payload)
    assert len(rede.fila) == 1
    rede.fila.clear()  # descarta
    yield from asyncio.sleep(0.25)
    assert len(rede.fila) == 0, 'Não deveria ter retransmitido ainda'
    yield from asyncio.sleep(0.06)
    assert len(rede.fila) == 1, 'Já deveria ter retransmitido'
    segmento, _ = rede.fila.pop(0)
    _, _, seq, ack, flags, _, _, _ = read_header(segmento)
    assert seq == ack_no
    assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
    assert segmento[4*(flags>>12):] == payload
    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    payload = os.urandom(MSS)
    conexao.enviar(payload)
    yield from asyncio.sleep(0.001)
    assert len(rede.fila) == 1
    segmento, _ = rede.fila.pop(0)
    _, _, seq, ack, flags, _, _, _ = read_header(segmento)
    assert seq == ack_no
    assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
    assert segmento[4*(flags>>12):] == payload
    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))

    payload = os.urandom(MSS)
    conexao.enviar(payload)
    assert len(rede.fila) == 1
    rede.fila.clear()  # descarta

    # sample_rtt = 0.001
    # estimated_rtt = (1-0.125)*0.1 + 0.125*0.001 = 0.087625
    # dev_rtt = (1-0.25)*0.05 + 0.25*abs(0.001-0.1) = 0.06225
    # timeout_interval = estimated_rtt + 4*dev_rtt = 0.336625
    # 0.32 < timeout_interval < 0.34
    yield from asyncio.sleep(0.32)
    assert len(rede.fila) == 0, 'Não deveria ter retransmitido ainda'
    yield from asyncio.sleep(0.02)
    assert len(rede.fila) == 1, 'Já deveria ter retransmitido'

    segmento, _ = rede.fila.pop(0)
    _, _, seq, ack, flags, _, _, _ = read_header(segmento)
    assert seq == ack_no
    assert (flags & FLAGS_ACK) == FLAGS_ACK and ack == seq_no
    assert segmento[4*(flags>>12):] == payload
    ack_no += MSS
    rede.callback(src_addr, dst_addr, fix_checksum(make_header(src_port, dst_port, seq_no, ack_no, FLAGS_ACK), src_addr, dst_addr))