[En-Nut-Discussion] TcpSock.c: Randomize the local port
Michel Hendriks
michel at stream-it.nl
Thu Nov 17 16:02:31 CET 2005
Hi,
I've found an interesting thing which I would like to discuss.
I have an application that automatically connects to a webserver when
ethernut starts up. It downloads a large file and then basically does
nothing until it reboots and repeats this whole thing again. Now sometimes
Ethernut is not able to complete the download (think of users turning it
off, watchdog reset, etc). When Ethernut is started again within a short
time sometimes Ethernut does not get a connection.
I analyzed this using ethereal and I think I saw the following behaviour:
When, after a reboot, Ethernut reconnects to the same server using the same
local ip address, the same local port, the same remote address/port, it
starts with TCP packets that use the ISN (which is 1000000). But the server
still thinks he should use the original sequence numbers and thus keeps
sending ACKs for completely different sequence numbers until finally a TCP
error is generated. (Off course, it Ethernut completes the download it also
closes the connection nicely and this problem does not occur :-))
So I've been thinking about possible solutions and I have come up with the
following solution: randomize the local port number in Ethernut so the
server does not mistake the new session for an already running session.
Adjustment made to tcpsock.c:
int NutTcpConnect(TCPSOCKET * sock, u_long addr, u_short port)
{
--------------------snip
--------------------end snip
/*
* Find an unused local port.
*/
do {
/* Michel Hendriks. Try to randomize the local port */
if (last_local_port == 4096)
last_local_port = 4096 + (u_short)NutGetMillis();
if (++last_local_port == 0)
last_local_port = 4096;
--------------------etc
I've tested this extensively and indeed it seems to solve this problem. Any
thoughts?
Greetings,
Michel
More information about the En-Nut-Discussion
mailing list