[En-Nut-Discussion] TcpSock.c: Randomize the local port
Mark E. Scott Jr.
mscott at awfs.net
Thu Nov 17 19:28:13 CET 2005
When I developed my own TCP stack and ran into this problem, I made the
stack detect whether the server thought it already had an open
connection. Trying to remember which bit wasn't set, but if the other
end thought it was a pre-existing connection, one of the bits in the
syn/ack/etc sequence wasn't set. When I saw this, I had the client send
a RST and tear down the connection to start anew.
Mark E. Scott, Jr.
mscott at awfs.net
AWS, Inc.
512-478-7727
-----Original Message-----
From: en-nut-discussion-bounces at egnite.de
[mailto:en-nut-discussion-bounces at egnite.de] On Behalf Of Michel
Hendriks
Sent: Thursday, November 17, 2005 9:03 AM
To: 'Ethernut User Chat (English)'
Subject: [En-Nut-Discussion] TcpSock.c: Randomize the local port
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
_______________________________________________
En-Nut-Discussion mailing list
En-Nut-Discussion at egnite.de
http://www.egnite.de/mailman/listinfo.cgi/en-nut-discussion
More information about the En-Nut-Discussion
mailing list