Giter Club home page Giter Club logo

picotcp's People

Contributors

adxlarbi avatar alexandervp avatar bogdanlu avatar brechtdevlieger avatar brunochevalier avatar danielinux avatar dekumans avatar douwedb avatar frederikvs avatar gmacario avatar jelledevleeschouwer avatar jibi avatar jonasvanpelt avatar jorisverhaegen avatar laurensmiers avatar ludolinux avatar matthiasvp avatar maximevince avatar mhagmajer avatar milanplatisa avatar mkrrr avatar phalox avatar q-thomas avatar schnommus avatar sergegadeyne avatar simonmaes avatar swendrickx avatar tassdevon avatar tassinfo avatar toonst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

picotcp's Issues

Sending a fragmented packet to a UDP socket is messing up receiving.

enabled ip fragmentation
created a udp socket that reads data from network
if you send a small packet (non fragmented) everything is fine.
if the packet is fragmented the socket goes nuts and the call to receiveFrom returns 1024 always (we are asking 1024 from it).

This the link to test (both mbed app and py/scapy script)
https://docs.google.com/a/tass.be/file/d/0B1BRitC1U1OeRWhuUFZiSWlxMEU/edit?usp=sharing
https://docs.google.com/a/tass.be/file/d/0B1BRitC1U1OeZkdWLWdJQTJSbXc/edit?usp=sharing

Mbed: DHCP: EthernetInterface.connect() returns -1 when first try fails. What now?

Discover, Offer, Request, but the server does not respond with ACK or NAK. The following should happen:
RFC 2131 p17:
"The client retransmits the DHCPREQUEST according to the retransmission algorithm. A client might retransmit the DHCPREQUEST message four times, for a total delay of 60 seconds, before restarting the initialization procedure. If the client receives neither a DHCPACK or a DHCPNAK message after employing the retransmission algorithm, the client reverts to INIT state and restarts the initialization process.
The client SHOULD notify the user that the initialization process has failed and is restarting."
This notification of failure is done by the connect() method (EthernetInterface class) by returning -1. The DHCP client however, restarts the negotiation procedure in the background. How can the user program know (from the mbed BSD interface) that the second negotiation will succeed or not?

Commit 9315c3 breaks Pico-to-pico TCP connection

commit 9315c3e
Author: Andrei Carp <andrei@andrei-Vostro-3560.(none)>
Date: Tue Jul 16 08:50:50 2013 +0300

Philippe's patch that fixes #753. It doesn't fix #745, the connection still stalls.

The above introduces a regression in pico-to-pico TCP connection (the connection in autotest.sh stalls).

TCP ZeroWindow is making the connection stall.

Discovered on mbed, when a Zero Window message comes, the application believes an error was received and closes the connection, which remains in an undefined state.

Maybe the application should be noticed it should try again later(via pico_err).

DHCP: PicoTCP keeps discovering when going back to 'init' state

When T1 (renewal-time) expires the client sends a DHCP Request (for renewal) to the leasing server. When the servers answers this request with a NAK, the DHCP client goes to the 'init' state. (see RFC2131 DHCP p34).

At this point the PicoTCP stack just sends DHCP Discover messages regardless DHCP Offer messages from the server.

Wireshark MBED: https://dl.dropboxusercontent.com/u/49342572/dhcp_mbed
As a comparison: Wireshark Linux stack: https://dl.dropboxusercontent.com/u/49342572/dhcp_linux_stack

TCP queue limit does not take into account headers overhead

When filling up the TCP queues (based on rbtrees), the size of the headers is not taken into account, leading to a miscalculation of the memory currently used.

In particular, when using very small segments (e.g. no-nagle and frequent writes with a few bytes), the overhead can be 10x the payload of the queue, quickly consuming the memory available even if the socket size is correctly set. The socket space limit is never reached so the TCP memory pressure feedbacks are ineffective.

Suggested possible solutions:

  • Keep an additional counter in TCP queue that estimates the real amount of memory used for TCP transmission in either direction, something that relies on the frame->buffer_size rather than the payload size, and use this value to decide whether to accept a new incoming segment or to enqueue in pico_socket_sendto. The old counter (the current queue size based on the payloads) must be kept in order to allow underlying TCP metrics to work correctly.
  • Add a limit based on the number of packets (ZMidi workaround) - and let the user set a packet-based additional limit. The limit would sit in the pico_socket.h just after the byte-based limit.

The first solution would be preferred if possible because it requires less configuration on the user/integrator side.

@maximevince please add your comments below and feel free to reassign to @andreixc who is currently working on the module in case you don't have time to introduce a fix.

Sending packets to a non-existing host (neither linux or picotcp) makes the stack respond with ICMP

PicoTCP has the following IP : 192.168.1.81
Linux has the following IP : 192.168.1.2

Linux sends a SYN towards 192.168.1.100 with a broadcast MAC.
PicoTCP gets the packet, starts sending ARPs on the network asking who has
192.168.1.100?
After it doesn't get an answer it replies to 192.168.1.2 with ICMP host unreachable.

At a first glance, this looks non-severe, but if I flood the network with these kind of packets PicoTCP will finish the memory and in the end kill the rtos.

To reproduce this init picoTCP either on linux or mbed and use the script to send packets:
https://docs.google.com/a/tass.be/file/d/0B1BRitC1U1OeeHhLNklVa2xGS1E/edit?usp=sharing

TCP: picotcp sends ICMP unreachable instaid of TCP RST

When you send a TCP segment to a closed port of picotcp (SYN, SYN|ACK, ACK, PSH|ACK,... except for RST), it responds with ICMP unreachable.
RFC793:
"If the connection does not exist (CLOSED) then a reset is sent in response to any incoming segment except another reset. In particular, SYNs addressed to a non-existent connection are rejected by this means. "
The linux stack will respond with a RST segment when you send a segment to a non listening port.

The definition of ICMP port unreachable:
"Port Unreachable - generated if the designated transport protocol (e.g., UDP) is unable to demultiplex the datagram in the transport layer of the final destination but has no protocol mechanism to inform the sender"

Is the ICMP unreachable a way for picotcp to protect the TCP layer from overload on a SYN attack? What should be the correct response for pico?

DNS client is leaking connections

For each retransmission of the dns query a socket remains in the tree,
without ever being closed.

Each time pico_dns_client_send is called it opens a new socket but it doesn't check
if the previous socket was closed.

In pico_dns_client_retransmission we could close the socket before calling pico_dns_client_send(key);

TCP doesn't wait for the other side to finish sending.

When running the robustness test, the following behavior was observed:

we send out FIN,ACK once
the other side hasn't finished sending out its data so it retransmits some frames
we reply with ICMP port unreachable.

Shouldn't we wait for the other side to send FIN,ACK and then delete the socket?
And until we get back the FIN,ACK back maybe we should resend it.
After this point, the next connection passes the 3whs then the board hangs.
I saved a log file.

tcp_send_rst is trying to access net pointer from a closed socket

In some cases after previous connection was closed and still a retransmission comes
from the mbed website the board would hang. This is caused by an illegal memory access since Keil reported that the Fault registers were set.

The offending instruction is in tcp_send_rst,
f = t->sock.net->alloc(t->sock.net, PICO_SIZE_TCPHDR + opt_len);
because t->sock.net was NULL, I'm working to figure out exactly what is happening.
I know that it has something to do with the socket being removed from tree and the socket was in PICO_SOCKET_STATE_TCP_LAST_ACK.

The reason why this happens is still not clear, keep checking this.

DHCP: client takes wrong IP

When a DHCP server offers the client an IP in the BOOTP yiaddr-field, the client sends a DHCP request with the offered IP in the yiaddr field.
When the server then ACK's, but he places a different IP in the yiaddr field now, the picotcp client assigns himself the IP that was originally offered.
(The ubuntu stack assigns himself the second one)

DNS client is leaking memory like a drain

Testing on the mbed board (using Pico_Robustness_Test).
The board hangs in like a minute or so.
Using the memory wrapper I could see that the stack is using ~17 Kb of ram.
Adding a counter to the trees I could observe that the UDPTable has ~20 connections left (hanging) in the tree.

Investigating...

SYN flood produces HardFault

A SYN flood with only a changing source port (same ip's same destination port) produces a HardFault after 40 to 50 SYN packets.

HOWTO reproduce:

sudo ./run.sh --test denialofserviceattack testcases/hardware/tcp_connect_bench_dut.txt

Flooding UDP socket with small packets causes HardFault

If you flood a udp socket with packets(in this case I used small packets-1 byte payload), but the socket doesn't read anything, the board will enter hard fault.

The script I used
import sys, socket
import random, string
import select
from time import sleep

SERVER_ADDRESS = "192.168.1.81"
SERVER_PORT = 6677
PACKET = 'a'

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((SERVER_ADDRESS,SERVER_PORT))

s.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)

cnt = 0
while(True):
print "Sending packet %d" % cnt
s.sendall(PACKET)
sleep(0.001)
cnt+=1

The mbed application opens a socket, binds it to 6677 and then calls thread::wait forever, so the stack can tick.

TCP Zombie socket is not dropped

Letting an mbed test to run I could observe that there are cases when socket connections start to accumulate into memory.

The case when this happens is this one:
The mbed site sends out FIN,ACK
We reply with FIN,ACK
the socket remains in PICO_SOCKET_STATE_TCP_LAST_ACK and
the final ACK never comes and the deletion of the socket is never triggered.

Maybe when going to PICO_SOCKET_STATE_TCP_LAST_ACK we start a timer to make sure we drop the socket.

TCP retransmission timer causes illegal memory acces.

While working on the mbed board I could observe that from time to time the board is freezing.
The last function calls to the stack are :
tcp_retrans_timeout->tcp_add_retransmission_timer and the offending memory pointer is passed to pico_tree_first_node which will rise a Hard Fault.

After 3WHS no data was being sent out.

At the beginning this bug seemed to be directly connected with the mbed porting.
This is untrue.

After checking the queues I could observe that a frame that was supposed to go out
was getting stuck in the output queue.
This is the reason why when we were closing the socket nothing was being sent out (output queue still had frames).

The root cause is in pico_sockets_loop.
if (s != NULL)
break;
s is never NULL so this instruction breaks all the time.

The correct check here is the following:
if(index && index->keyValue)
break;

When Nagle is enabled, sending fails after 5120 bytes, due to a memory leak

If you run the test from task #719

This is the output:

Starting the receiving part...
Received : 1048576 bytes
Expected : 1048576 bytes
Receiving has passed...

Starting the sending part...
Send error
Sent : 5120 bytes
Expected : 1048576 bytes
Sending part of the test has failed. Exiting connection.
Socket closed!
Test was finished...

TCP connection stalls under heavy packet loss

This is issue 745 on internal redmine.

See test test/python/tcpbench-delay.py

If loss is decreased, the test succeeds. If 5% as with the current script, the connection lingers indefinitely.

Find the cause and fix.

TCP: connection state not closed after passive close when still data in receive buffer

Test setup:
client (linux) -> server (picotcp)

  1. Establish connection with a picotcp socket
  2. Send a data segment (that will be acknowledged by picotcp) but don't let the application that uses picotcp receive the data (picotcp keeps it in a buffer)
  3. close the connection with the linux client (linux sends FIN first)

After this testsequence the connection is still in the established state. This is not the case when picotcp has empty buffers.
The state is checked from within the socket callback function (mbed code: wakeup() from stack_endpoint.cpp)

DHCP client doesn't repeat queries

If there is no DHCP server to answer the first 3 queries (first call to pico_dhcp_initiate_negotiation) , there will be no other request for a new IP, even if pico_dhcp_initiate_negotiation is called again. So if the dhcp doesn't get an answer at its first question it will never ask again.

Large fragmented packet sent to a TCP socket causes bad behavior

If you send a fragmented packet larger than the buffer size of the socket,
the packet remains blocked somewhere on ip layer or causes hard fault.

If the fragmented packet total size is lower than the socket buffer everything is fine.

Test and main can be found here.
https://docs.google.com/a/tass.be/file/d/0B1BRitC1U1OedHZKc1I5Zndxck0/edit?usp=sharing
https://docs.google.com/a/tass.be/file/d/0B1BRitC1U1Oedk5PUVFGNXVNLUk/edit?usp=sharing

Autotest is failing with segmentation fault in the icmp/ping module

Internal redmine issue #672

The offending test is the one starting at line 52 in the script (DHCP test)

DHCP TEST
./test/autotest.sh: line 52: 10741 Segmentation fault ./build/test/picoapp.elf --barevde pic0:/tmp/pic0.ctl: -a dhcpclient:pic0

Core was generated by `./build/test/picoapp.elf --barevde pic0 /tmp/pic0.ctl  -a dhcpclient pic0'.

Program terminated with signal 11, Segmentation fault.
#0  0x08054d58 in cookie_compare (ka=0x9a63a20, kb=0x9a60020) at modules/pico_icmp4.c:175
175      if (a->id < b->id)
(gdb) p a
$1 = (struct pico_icmp4_ping_cookie *) 0x9a63a20
(gdb) p b
$2 = (struct pico_icmp4_ping_cookie *) 0x9a60020
(gdb) p a->id
$3 = 37312
(gdb) p b->id
Cannot access memory at address 0x9a60026
(gdb) up
#1  0x08067ea1 in pico_tree_findKey (tree=0x80704b4, key=0x9a60020) at stack/pico_tree.c:179
179          result = tree->compare(found->keyValue, key);
(gdb) p key
$4 = (void *) 0x9a60020
(gdb) l
174    
175      while(IS_NOT_LEAF(found))
176      {
177          int result;
178    
179          result = tree->compare(found->keyValue, key);
180          if(result == 0)
181             return found->keyValue;
182          else if(result < 0)
183           found = found->rightChild;
(gdb) up
#2  0x08054f7e in next_ping (now=4235431418, arg=0x9a60020) at modules/pico_icmp4.c:238
238        if(pico_tree_findKey(&Pings,cookie)){
(gdb) l
233    
234    static void next_ping(unsigned long now, void *arg)
235    {
236      struct pico_icmp4_ping_cookie *newcookie, *cookie = (struct pico_icmp4_ping_cookie *)arg;
237    
238        if(pico_tree_findKey(&Pings,cookie)){
239        if (cookie->seq < cookie->count) {
240          newcookie = pico_zalloc(sizeof(struct pico_icmp4_ping_cookie));
241          if (!newcookie)
242            return;
(gdb) p cookie
$5 = (struct pico_icmp4_ping_cookie *) 0x9a60020
(gdb) up
#3  0x08067483 in pico_check_timers () at stack/pico_stack.c:479
479        t->timer(pico_tick, t->arg);
(gdb) quit

Route table can contain IP links that are no longer valid

SCENARIO:

  • route table contains two routes both using the same IP link
  • dhcp lease time expires and we go back to INIT state trying to get a new IP
  • we delete the IP link which inside calls a route delete (only once)

RESULT:

  • route table contains 1 route with a IP link no longer valid -> very dangerous as the memory allocated for the IP link has been freed

EXPECTED RESULT:

  • when deleting a IP link, all routes using that link should be deleted also

SOLUTION PROPOSED:

  • in IPv4 module, create a function pico_ipv4_route_del_iplink that will be called only by pico_ipv4_link_del. This function will search the Routes tree for any route using the IP link to be deleted, and will remove that route from the tree
  • update pico_ipv4_route_del to make it clear what parameters are actually needed: gateway and link params are not actually needed as the key to search in the Routes tree is netmask/ip address/metric in the order of importance

TCP: PicoTCP does not respond to duplicate SYN

remote client -> PicoTCP server

When a PicoTCP server is within the connection established state, it does not react to another SYN from the same socket (same port and ip). This can be the case when the remote client has crashed, reboots and tries to reconnect to the PicoTCP server. Normally the client will choose another source port, but this is not guaranteed.
The server should react with a simple ACK instaid. The remote client will discover that the ack number is wrong (number from original connection) and will send a RST to the server. The connection on the server should be closed now.
See RFC793 p34 half open connection discovery

RB Tree, Leaf colour was being changed.

While I was digging through the stack I observed that the LEAF color was being changed to red which is not allowed!

The fix I suggest is in pico_tree.c :
fix_insert_collisions changed the while to this :
while(node->parent->color == RED && IS_NOT_LEAF(GRANPA(node)) )

TCP needs a better garbage collector.

TCP layer needs a component that is able to close and remove from the socket tree the sockets that haven't had activity in some time or sockets which for some reason closing or opening remained stuck in some state.

While working with the mbed platform I could observe that during time tcp sockets in the following states
0x070F (PICO_SOCKET_STATE_TCP_LAST_ACK)
0x090F (PICO_SOCKET_STATE_TCP_FIN_WAIT2)
0x0004 (PICO_SOCKET_STATE_BOUND)

As an idea we could use a timer to check all sockets and a timestamp to see the last time that socket had activity and/or we should make the states when establishing/closing a connection to timeout and lead to dropping of sockets.

DHCP client is leaking memory.

This was discovered on the mbed platform.
If you connect the board to a network where there is no DHCP server
for each xid generated and tried for 5 times 100 bytes of ram is lost.
Even if the server responds later on the previous memory is lost.

Each time Ethernet::connect is called it will call pico_dhcp_initiate_negotiation which will create a new cookie, but when it fails there is no way to cleanup the used memory.

Basically if you repeat the call to pico_dhcp_initiate_negotiation memory is leaked.

Mbed: NULL pointer accessed after SYN, SYNACK, RST

This is a bug within the mbed stack_endpoint.cpp.
When a valid RST TCP segment is received instaid of an ACK after an initial SYN, SYNACK, a hardfault occures due to NULL pointer access. When RST is received, the wakeup function (in stack_endpoint.cpp) gets an ev equal to PICO_SOCK_EV_ERR and pico_err is equal to PICO_ERR_ECONNRESET, thus the socket will be closed and ep->s will be accessed. But before that on line 66, ep is overwritten with ep_accepted (ep_accepted seems not NULL in the debugger, therefore the if statement on line 64 is executed). Because no socket was accepted before, ep (overwritten by ep_accepted) has a non valid socket field.
One line 82, pico_socket_close() will access the socket that is a NULL pointer.

Code snippet:

60 static void wakeup(uint16_t ev, struct pico_socket *s)
61 {
62   struct stack_endpoint *ep = (struct stack_endpoint *)s->priv;
63   if (!ep) {
64     if (ep_accepting != NULL) {
65         ptsock_dbg("Delivering %02x to accepting socket...\n", ev);
66         ep = ep_accepting;
67     } else {
68         ptsock_dbg("WAKEUP: socket not found! ev=%04x\n", ev);
69         return;
70     }
71   }
72   //if (((ep->revents & PICO_SOCK_EV_RD) == 0) && (ev & PICO_SOCK_EV_RD))
73   //  printf("Activating RD\n");
74   ep->revents |= ev;
75 
76   if(ev & PICO_SOCK_EV_ERR)
77   {
78     if(pico_err == PICO_ERR_ECONNRESET)
79     {
80       ptsock_dbg("Connection reset by peer...\n");
81       ep->state = SOCK_RESET_BY_PEER;
82       pico_socket_close(ep->s);
83       ep->s->priv = NULL;
84     }
85   }

Memory content of ep after line 66 has been executed:

screenshot from 2013-08-09 14 10 56

TCP: RST|ACK after split-handshake attack?

Host A is a client not listening on any port. Host B is a malicious server listening on port 80.
A --- SYN ---> B
A <--- SYN --- B
A --- ???? ---> B
If host A is a picotcp instance, it will react with a RST|ACK segment.
If host A is a linux stack, it will react with SYN|ACK.
This is known as the split-handshake attack.
Is there an intentional reason why picotcp responds differently, or is this a bug?

Flooding TCP socket with small packets causes inactivity until the socket is dropped.

With the current implementation, if we open a tcp socket to a certain port and flood it with 1 byte packets, after ~50 packets the stack will report a zero window and the board will be unresponsive for a few minutes until the socket is dropped( the board doesn't enter hard fault, but it will not respond to any ping, arping etc).

After the memory is freed the stack is responsive again.
This is caused because we are not taking into consideration the overhead on this frames.

I don't think it correct that we report zero window after 50 packets (50 bytes used from a 4K buffer).

https://docs.google.com/a/tass.be/file/d/0B1BRitC1U1OeSHhzSlNzeGFvYUk/edit?usp=sharing

Tick timer has a wrap-around every 49.71 days

This is issue 724 in internal redmine

System tick counter is 32 bit in size, and counts every ms..

2^32
/ 1000 --> ms
/ 3600 --> hours
/ 24 --> days

= 49.71 days.

I propose to increase the counter to an unsigned long long everywhere... That timer should never ever overflow.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.