Hello everyone, I have found uncommon issues in the TCP protocol that may be of interest to you. This is a quite long post.
Before anything else, I do not use uIP. I use a self-made minimal TCP/IP stack that is tailored specifically to a particular chipset and somewhat tailored to the particular use that I have for it. That use is streaming audio from Shoutcast & Icecast servers, which use (slightly modified) HTTP for the data transfer. I do, however, look into the uIP source code for guidance when the RFCs toy with my sanity. In my stack, I set the TCP MSS to 512. I set the TCP window to twice the MSS, though. I have noticed that both Linux and Microsoft Windows hosts will send you packets of at most half the size of the window. I blame this to a side effect of the Nagle algorithm (in the Nagle algorithm, a receiver sends a single ACK for every two incoming packets, therefore a transmitter should send at least two packets, whose summed size does not exceed the receiver's window). When streaming audio (from a Microsoft Windows Icecast server), I have noticed that sometimes I receive a packet that contains partially old data and partially new data. Say that I have already received and acknowledged 10000 bytes, and I get a packet with sequence number 9800 and size 500. If I ignore this packet and send a new acknowledgement for 10000 bytes, I get the same packet again (sequence number 9800, size 500). Repeating it a few times does not help. I guess that the complete packet is kept in a queue for retransmission and that the Windows host feels that I should just accept the packet because 9800 + 500 is greater than my ACK number. The fix is to process the 300 new byes and ACK these. This applies to uIP too. In version 1.9 (that I just downloaded), line 1407 tests whether the sequence number matches exactly the one that was expected. This was also my strategy, and it will therefore fail similarly when a packet with overlapping data is received. One side remark: overlapping data packets are uncommon. I saw 4 of such packets in 90 minutes of test streaming at 128 kb/s, which gives an average of one "glitch" in every 20 megabytes received. A second issue is even rarer: out of order reception. My window is 1024 and my MSS is 512. It has happened that I receive a packet that drops into the high part of the window before I get the packet that drops into the low part of the window. So, let's say that I have received and acknowledged 10000 bytes and I am expecting a packet with 10001 to 10512, but I get 10513 to 11024. Dropping the packet and sending an ACK for 10000 does not help, I get the same packet again. Blame yourself, one might say, you put the window at 1024 bytes, so you should not complain when you get what you asked for. However, this could arrive, too, if the window size is the same as the MSS. Out of order reception is just part of the TCP protocol. If you cannot handle it, bad luck. I cannot handle out of order reception. Since I lack RAM for sufficiently large buffers, I am using a serial buffer. What I have implemented is to reduce the TCP window once I get an out-of-order packet (and send an ACK with the sequence number that I wish to receive next). If the remote host monitors the window size, as it should, it cannot resend the packet, because it is now beyond the window. I do not know yet if this works, because an out-of-order reception has not happened since I implemented this (I have only done a 90 minutes streaming audio test as of now). Again, in uIP, this would need a modification of handling a received TCP data packet. I hope this is useful for anyone. I realise that uIP is probably used more often for transmitting data rather than receiving data, and that the amount of data typically is not as large as it is with streaming audio. Anyway, best regards, Thiadmer