Beispiel #1
0
def test_gnrc_tcp_queue_get_local_returns_0(child):
    """ This test verifies that queue_get_local returns 0 then put after listen.
        And the endpoint content is as are as expected.
    """
    # Enter listen with accept all address
    listen_addr = '::'
    listen_port = generate_port_number()
    riot_srv = RiotTcpServer(child, listen_port)
    riot_srv.listen()
    riot_srv.queue_get_local()
    child.expect_exact('Endpoint: addr.ipv6=:: netif=0 port={}'.format(
        listen_port)
    )
    riot_srv.stop_listen()

    # Enter listen with specified address
    listen_addr = 'fe80::4c49:c7ff:fecd:34a3'
    listen_port = generate_port_number()
    riot_srv = RiotTcpServer(child, listen_port, listen_addr)
    riot_srv.listen()
    riot_srv.queue_get_local()
    child.expect_exact('Endpoint: addr.ipv6={} netif=0 port={}'.format(
        listen_addr, listen_port)
    )
    riot_srv.stop_listen()
Beispiel #2
0
def test_connection_listen_accept_cycle(child, iterations=10):
    """ This test verifies sock_tcp in a typical server role by
        accepting a connection, exchange data, teardown connection, handle the next one
    """
    # Setup RIOT Node as server
    with SockTcpServer(child, generate_port_number()) as sock_srv:
        # Establish multiple connections iterativly
        for i in range(iterations):
            print('\n    Running listen/accept iteration {}'.format(i), end='')

            with HostTcpClient(sock_srv) as host_cli:
                # Accept connection from host system
                sock_srv.accept(timeout_ms=0)

                # Send data from host to RIOT
                data = '0123456789'
                host_cli.send(data)
                sock_srv.read(data, 1000)

                # Send data from RIOT to host
                sock_srv.write(data)
                host_cli.receive(data)

                # Randomize connection teardown: The connections
                # can be closed from either Regardless the type of the connection teardown
                # sock_srv must be able to accept the next connection
                dice_throw = random.randint(0, 1)
                if dice_throw == 0:
                    sock_srv.disconnect()
                    host_cli.close()

                elif dice_throw == 1:
                    host_cli.close()
                    sock_srv.disconnect()
Beispiel #3
0
def test_gnrc_tcp_recv_respects_GNRC_TCP_NO_TIMEOUT(child):
    """ gnrc_tcp_recv timeout mechanism must be disabled if GNRC_TCP_NO_TIMEOUT
        is set as timeout value.
    """

    pexpect_timeout_sec = _GNRC_TCP_NO_TIMEOUT + 1
    payload = "12345"

    # Setup Host as server
    with HostTcpServer(generate_port_number()) as host_srv:
        # Setup Riot as client
        with RiotTcpClient(child, host_srv):

            # Accept connection
            host_srv.accept()

            # Wait for incoming data blocking.
            # This gnrc_tcp_recv must not return until some Data was sent.
            child.sendline('gnrc_tcp_recv {} {}'.format(_GNRC_TCP_NO_TIMEOUT, len(payload)))
            returned = True
            try:
                child.expect_exact('gnrc_tcp_recv: re', timeout=pexpect_timeout_sec)
            except pexpect.TIMEOUT:
                returned = False
            finally:
                if returned:
                    raise RuntimeError('gnrc_tcp_recv returned')

            # Send data to unblock gnrc_tcp_recv and teardown the connection
            host_srv.send(payload)
            child.expect_exact('gnrc_tcp_recv: received {}'.format(len(payload)))
            host_srv.close()
Beispiel #4
0
def test_gnrc_tcp_accept_respects_GNRC_TCP_NO_TIMEOUT(child):
    """ gnrc_tcp_accept timeout mechanism must be disabled if GNRC_TCP_NO_TIMEOUT
        is set as timeout value.
    """

    pexpect_timeout_sec = _GNRC_TCP_NO_TIMEOUT + 1

    riot_srv = RiotTcpServer(child, generate_port_number())
    riot_srv.listen()

    child.sendline('gnrc_tcp_accept {}'.format(_GNRC_TCP_NO_TIMEOUT))

    # The test is successful if gnrc_tcp_accept does not return before pexpects timeout.
    # Afterwards the connection must be still able to accept a connection.
    returned = True
    try:
        child.expect_exact('gnrc_tcp_accept: returns', timeout=pexpect_timeout_sec)
    except pexpect.TIMEOUT:
        returned = False
    finally:
        if returned:
            raise RuntimeError('gnrc_tcp_accept returned')

    # Ensure that gnrc_tcp_accept returns after the test host connects
    with HostTcpClient(riot_srv):
        child.expect_exact('gnrc_tcp_accept: returns 0')
        riot_srv.close()
Beispiel #5
0
def test_connection_lifecycle_as_server(child):
    """ Open/close a single connection as sock tcp server """
    # Setup Riot Node as server
    with SockTcpServer(child, generate_port_number()) as sock_srv:

        # Verify listen parameters
        sock_srv.queue_get_local()
        child.expect_exact('Endpoint: addr.ipv6=:: netif=0 port={}'.format(
            sock_srv.listen_port))

        # Setup Host as client
        with HostTcpClient(sock_srv) as host_cli:
            # Accept connection
            sock_srv.accept(timeout_ms=1000)

            # Verify connection endpoints from sock perspective
            sock_srv.get_local()
            child.expect_exact(
                'Endpoint: addr.ipv6={} netif={} port={}'.format(
                    sock_srv.address, sock_srv.interface,
                    sock_srv.listen_port))

            sock_srv.get_remote()
            child.expect_exact('Endpoint: addr.ipv6={}'.format(
                host_cli.address))

            # Close connection
            sock_srv.disconnect()
Beispiel #6
0
def test_gnrc_tcp_garbage_packets_option_parsing(child):
    """ This test verfies that malformed option don't break TCP
        doesn't break GNRC_TCP. See: https://github.com/RIOT-OS/RIOT/issues/12086
    """
    # Setup RIOT as server
    with RiotTcpServer(child, generate_port_number()) as riot_srv:
        # Construct HostTcpClient to lookup node properties
        host_cli = HostTcpClient(riot_srv)

        # Try to accept incoming connection from host system.
        child.sendline('gnrc_tcp_accept 2000')

        tcp_hdr = TCP(dport=int(riot_srv.listen_port),
                      flags="S",
                      sport=2342,
                      seq=1,
                      dataofs=6)

        sendp(Ether(dst=riot_srv.mac) /
              IPv6(src=host_cli.address, dst=riot_srv.address) / tcp_hdr /
              b"\x50\x00\x00\x00",
              iface=host_cli.interface,
              verbose=0)

        # check if server actually still works
        with host_cli:
            child.expect_exact('gnrc_tcp_accept: returns 0')

        riot_srv.close()
Beispiel #7
0
def test_gnrc_tcp_garbage_packets_short_payload(child):
    """ Receive unusually short payload with timeout. Verifies fix for
        https://github.com/RIOT-OS/RIOT/issues/11999
    """
    # Setup RIOT as server
    with RiotTcpServer(child, generate_port_number()) as riot_srv:
        # Setup Host as client
        with HostTcpClient(riot_srv) as host_cli:
            # Accept new connection
            riot_srv.accept(timeout_ms=2000)

            # Receive 1 byte with timeout, this should block
            child.sendline('gnrc_tcp_recv 1000000 1')
            child.expect_exact('gnrc_tcp_recv: argc=3, '
                               'argv[0] = gnrc_tcp_recv, '
                               'argv[1] = 1000000, argv[2] = 1')

            # Send 1 byte from host to RIOT
            assert 1 == host_cli.sock.send(b"f")

            # Receive 1 byte
            child.expect_exact('gnrc_tcp_recv: received 1', timeout=20)

            # Close connection
            riot_srv.close()
Beispiel #8
0
def test_gnrc_tcp_garbage_packets_short_header(child):
    """ This test verifies fix malformed tcp header. See
        https://github.com/RIOT-OS/RIOT/issues/12086
    """
    # Setup RIOT as server
    with RiotTcpServer(child, generate_port_number()) as riot_srv:

        # Construct HostTcpClient to lookup node properties
        host_cli = HostTcpClient(riot_srv)

        # Try to accept incoming connection from host system.
        child.sendline('gnrc_tcp_accept 2000')

        # Build malformed short header with SYN Flag
        tcp_hdr = TCP(dport=int(riot_srv.listen_port),
                      flags="S",
                      sport=2342,
                      seq=1,
                      dataofs=6)
        tcp_hdr = raw(tcp_hdr)[:-2]
        sendp(Ether(dst=riot_srv.mac) /
              IPv6(src=host_cli.address, dst=riot_srv.address) / tcp_hdr,
              iface=host_cli.interface,
              verbose=0)

        # Establish normal tcp connection from host system to check if RIOT node
        # was able to recover from malformed packet
        with host_cli:
            child.expect_exact('gnrc_tcp_accept: returns 0')

        riot_srv.close()
Beispiel #9
0
def test_gnrc_tcp_accept_returns_ETIMEDOUT(child):
    """ gnrc_tcp_accept must return with -ETIMEDOUT
        if no connection is ready and timeout is not 0
    """
    riot_srv = RiotTcpServer(child, generate_port_number())
    riot_srv.listen()

    child.sendline('gnrc_tcp_accept 1000')
    child.expect_exact('gnrc_tcp_accept: returns -ETIMEDOUT')
Beispiel #10
0
def test_connection_lifecycle_as_server(child):
    """ Open/close a single connection as tcp server """
    # Setup RIOT as server
    with RiotTcpServer(child, generate_port_number()) as riot_srv:
        # Setup Host as client
        with HostTcpClient(riot_srv):
            # Accept and close connection
            riot_srv.accept(timeout_ms=1000)
            riot_srv.close()
Beispiel #11
0
def test_connection_lifecycle_as_client(child):
    """ Open/close a single connection as tcp client """
    # Setup Host as server
    with HostTcpServer(generate_port_number()) as host_srv:
        # Setup Riot as client
        with RiotTcpClient(child, host_srv):
            # Accept and close connection
            host_srv.accept()
            host_srv.close()
Beispiel #12
0
def test_gnrc_tcp_accept_returns_ENOMEM(child):
    """ gnrc_tcp_accept must return with -ENOMEM
        if all TCBs already handle a connection
    """
    with RiotTcpServer(child, generate_port_number()) as riot_srv:
        # Establish connection to ensure that all TCBs are in use
        with HostTcpClient(riot_srv):
            riot_srv.accept(timeout_ms=0)

            # Out of memory accept should return immediately despite a huge timeout.
            child.sendline('gnrc_tcp_accept 100000000')
            child.expect_exact('gnrc_tcp_accept: returns -ENOMEM')
Beispiel #13
0
def test_send_data_from_host_to_riot(child):
    """ Send Data from Host system to RIOT node """
    # Setup RIOT as server
    with RiotTcpServer(child, generate_port_number()) as riot_srv:
        # Setup Host as client
        with HostTcpClient(riot_srv) as host_cli:
            # Accept and close connection
            riot_srv.accept(timeout_ms=1000)

            # Send Data from Host system to RIOT
            data = '0123456789' * 200
            host_cli.send(data)
            riot_srv.receive(timeout_ms=1000, sent_payload=data)

            riot_srv.close()
Beispiel #14
0
def test_send_data_from_host_to_riot(child):
    """ Send Data from Host system to RIOT node """
    # Setup Riot Node as server
    with SockTcpServer(child, generate_port_number()) as sock_srv:
        # Setup Host as client
        with HostTcpClient(sock_srv) as host_cli:
            # Accept and close connection
            sock_srv.accept(timeout_ms=1000)

            # Send Data from Host system to RIOT
            data = '0123456789'
            host_cli.send(data)
            sock_srv.read(data, 1000)

            sock_srv.disconnect()
Beispiel #15
0
def test_send_data_from_riot_to_host(child):
    """ Send Data from RIOT Node to Host system """
    # Setup Host as server
    with HostTcpServer(generate_port_number()) as host_srv:
        # Setup Riot as client
        with RiotTcpClient(child, host_srv) as riot_cli:
            # Accept and close connection
            host_srv.accept()

            # Send Data from RIOT to Host system and verify reception
            data = '0123456789' * 200
            riot_cli.send(timeout_ms=0, payload_to_send=data)
            host_srv.receive(data)

            # Teardown connection
            host_srv.close()
Beispiel #16
0
def test_connection_listen_accept_cycle(child, iterations=10):
    """ This test verifies gnrc_tcp in a typical server role by
        accepting a connection, exchange data, teardown connection, handle the next one
    """
    # Setup RIOT Node as server
    with RiotTcpServer(child, generate_port_number()) as riot_srv:
        # Establish multiple connections iterativly
        for i in range(iterations):
            print('\n    Running listen/accept iteration {}'.format(i), end='')

            with HostTcpClient(riot_srv) as host_cli:
                # Accept connection from host system
                riot_srv.accept(timeout_ms=0)

                # Send data from host to RIOT
                data = '0123456789'
                host_cli.send(payload_to_send=data)
                riot_srv.receive(timeout_ms=500, sent_payload=data)

                # Send data from RIOT to host
                riot_srv.send(timeout_ms=500, payload_to_send=data)
                host_cli.receive(sent_payload=data)

                # Randomize connection teardown: The connections
                # can't be either closed or aborted from either
                # side. Regardless the type of the connection teardown
                # riot_srv must be able to accept the next connection
                # Note: python sockets don't offer abort...
                dice_throw = random.randint(0, 3)
                if dice_throw == 0:
                    riot_srv.close()
                    host_cli.close()

                elif dice_throw == 1:
                    riot_srv.abort()
                    host_cli.close()

                elif dice_throw == 2:
                    host_cli.close()
                    riot_srv.close()

                elif dice_throw == 3:
                    host_cli.close()
                    riot_srv.abort()
Beispiel #17
0
def test_gnrc_tcp_get_remote_returns_0(child):
    """ This test verifies that get_remote returns 0 in a connected state
        and the used endpoint contains the expected connection parameters
    """
    # Setup Host as server
    with HostTcpServer(generate_port_number()) as host_srv:
        # Setup Riot as client
        with RiotTcpClient(child, host_srv) as riot_cli:

            # Accept connection
            host_srv.accept()

            # Get and verify local endpoint
            riot_cli.get_remote()
            child.expect_exact('Endpoint: addr.ipv6={} netif=0 port={}'.format(
                host_srv.address, host_srv.listen_port))

            # Close connection
            host_srv.close()
Beispiel #18
0
def test_gnrc_tcp_garbage_packets_ack_instead_of_sym(child):
    """ This test verfies that sending and ACK instead of a SYN.
        doesn't break GNRC_TCP.
    """
    # Setup RIOT as server
    with RiotTcpServer(child, generate_port_number()) as riot_srv:
        # Construct HostTcpClient to lookup node properties
        host_cli = HostTcpClient(riot_srv)

        # Try to accept incoming connection from host system.
        # Use timeout of 15s discarding 1000 packages can take a while on smaller platforms
        child.sendline('gnrc_tcp_accept 15000')

        # Check if debug output is enabled. Send fewer packets on if it is disabled
        # To ensure that the amount of generated output doesn't break the test
        debug = child.expect(
            [pexpect.TIMEOUT, r'GNRC_TCP: Enter "\S+", File: .+\(\d+\)\s'],
            timeout=1)

        if debug:
            count = 10
        else:
            count = 1000

        # see https://github.com/RIOT-OS/RIOT/pull/12001
        provided_data = base64.b64decode("rwsQf2pekYLaU+exUBBwgPDKAAA=")
        tcp_hdr = TCP(provided_data)
        assert provided_data == raw(tcp_hdr)

        # set destination port to application specific port
        tcp_hdr.dport = int(riot_srv.listen_port)
        sendp(Ether(dst=riot_srv.mac) /
              IPv6(src=host_cli.address, dst=riot_srv.address) / tcp_hdr,
              iface=host_cli.interface,
              verbose=0,
              count=count)

        # check if server actually still works
        with host_cli:
            child.expect_exact('gnrc_tcp_accept: returns 0')

        riot_srv.close()
Beispiel #19
0
def test_gnrc_tcp_send_behavior_on_zero_length_buffer_size(child):
    """ This test verifies that gnrc_tcp_send accepts zero length payload
        and returns 0.
    """
    with HostTcpServer(generate_port_number()) as host_srv:
        riot_cli = RiotTcpClient(child, host_srv)

        # Call gnrc_tcp_send with on data and no timeout on unconnected TCB
        # This must return -ENOTCONN
        child.sendline('gnrc_tcp_send 0 0')
        child.expect_exact('gnrc_tcp_send: returns -ENOTCONN')

        with riot_cli:
            host_srv.accept()

            # Call gnrc_tcp_send with on data and no timeout
            # This must return 0 not -EAGAIN
            child.sendline('gnrc_tcp_send 0 0')
            child.expect_exact('gnrc_tcp_send: returns 0')

            host_srv.close()
Beispiel #20
0
def test_connection_lifecycle_as_client(child):
    """ Open/close a single connection as sock tcp client """
    # Setup Host as server
    with HostTcpServer(generate_port_number()) as host_srv:
        # Setup Riot Node as client
        local_port = 54321
        with SockTcpClient(child, host_srv, local_port) as sock_cli:
            # Accept, verify Endpoints and close connection
            host_srv.accept()

            # Verify connection endpoints from sock perspective
            sock_cli.get_local()
            child.expect_exact(
                'Endpoint: addr.ipv6={} netif={} port={}'.format(
                    sock_cli.address, sock_cli.interface, sock_cli.local_port))

            sock_cli.get_remote()
            child.expect_exact('Endpoint: addr.ipv6={} netif=0 port={}'.format(
                host_srv.address, host_srv.listen_port))

            # Close Connection
            host_srv.close()
Beispiel #21
0
def test_gnrc_tcp_recv_behavior_on_closed_connection(child):
    """ This test ensures that a gnrc_tcp_recv doesn't block if a connection
        was closed already.
    """
    # Setup Host as server
    with HostTcpServer(generate_port_number()) as host_srv:
        # Setup Riot as client
        with RiotTcpClient(child, host_srv) as riot_cli:
            # Accept connection
            host_srv.accept()

            # Transmit data to RIOT client and close connection from host side
            data = 'test_data_'
            host_srv.send(payload_to_send=data)
            host_srv.close()

            # Read half amount of data with huge timeout.
            # Expectency: direct with verified test data. Timeout doesn't matter
            half_data_len = int(len(data) / 2)
            huge_timeout_ms = 1000000000
            no_timeout_ms = 0
            riot_cli.receive(timeout_ms=huge_timeout_ms,
                             sent_payload=data[:half_data_len])

            # Read half amount of data without timeout.
            # Expectency: direct return with verified test data
            riot_cli.receive(timeout_ms=no_timeout_ms,
                             sent_payload=data[half_data_len:])

            # All received data is read, try to read 1 byte with timeout.
            # Expectency: fast return despite timeout since the connection is already closed
            child.sendline('gnrc_tcp_recv {} 1'.format(huge_timeout_ms))
            child.expect_exact('gnrc_tcp_recv: returns 0')

            # All received data is read, try to read 1 byte without timeout.
            # Expectency: fast return since the connection is already closed
            child.sendline('gnrc_tcp_recv {} 1'.format(no_timeout_ms))
            child.expect_exact('gnrc_tcp_recv: returns 0')