EmbeddedRelated.com
Forums
Memfault Beyond the Launch

TCP packets : end of thre-way handshake and start of data-transmission - how to detect ?

Started by R.Wieser May 4, 2009
Hello Mike,

> Call it whatever you like internally, but it must never show on the wire. > Read a few sniffer traces. Ethereal is a free download.
My bad it seems. I allways assumed that the "accept" function moved the connection to a high port, so the "listen" port was kept free to accept whomever tried to connect to it. And yes, looking at some snifs I made some time ago I see that the port-numbers to not change during, or after the three-way handshake. Regards, Rudy Wieser -- Origional message MikeWhy <boat042-nospam@yahoo.com> schreef in berichtnieuws nBGLl.29139$YU2.9088@nlpi066.nbdc.sbc.com...
> "R.Wieser" <address@not.available> wrote in message > news:49ff23cf$0$4628$e4fe514c@dreader25.news.xs4all.nl... > > Hello Rocky, > > > >> I think you find that you (server) need to do this in response > >> to the 1st SYN, not after the three-way handshake. > > > > :-) That is exactly what I tried and described in my initial message
and
> > which fails (gets responded to with a Reset). > > > >> It is only necessary if you expect to have multiple incoming > >> connections to a given port. > > > > As I'm implementing a Server I should consider the possibility of
multiple
> > incoming connections, don't you think ? :-) Although its not
specified
> > as > > mandatory, I think it will help to keep mixups between the different > > requests at a minimum. > > Call it whatever you like internally, but it must never show on the wire. > Read a few sniffer traces. Ethereal is a free download.
Hello Rocky,

   It looks that an assumption of how things work got the better of me : I
allways thought that the "accept" function would take over the connection
and move it from the origional port to high-numbered one.   Looking at at a
few packet-sniff logs (as suggested by "MikeWhy", who allso replied to me) I
realized that that assumption was wrong.

Now if I can only get that years-old misconception outof my head and replace
it with the correct way-of-working

Regards,
  Rudy Wieser


-- Origional message
Rocky <RobertGush@gmail.com> schreef in berichtnieuws
adcb55bb-595b-4583-ba86-2c9206b931cb@z7g2000vbh.googlegroups.com...
On May 4, 7:22 pm, "R.Wieser" <addr...@not.available> wrote:
> > > I think you find that you (server) need to do this in response > > to the 1st SYN, not after the three-way handshake. > > :-) That is exactly what I tried and described in my initial message and > which fails (gets responded to with a Reset). > > > It is only necessary if you expect to have multiple incoming > > connections to a given port. >
I think that David put it correctly. When you change the socket (not port number) you do not need to change the port number on the server. The server knows the intended socket because the SOURCE_IP:PORT of incoming packets will be unique for a given connection. For example, assume your IP is 192.168.0.1 and you are listening on port 23. When a SYN comes in from 192.168.0.123 it will have a source port of (for example) 12345. The source port on clients is normally chosen sequentially (on windows machines) so it is normally always different on a subsequent or concurrent connection. Obviously it will repeat eventually. Thus your unique socket indentifier on your server is: 192.168.0.1:23 and 192.168.0.123:12345. Your transactions from the first threeway handshake will use these parameters. Your software will transfer these parameters to a 'connection socket' (as opposed to a listening socket). The main difference is that if a packet comes in that DOES NOT match a connected socket, then it is presented to the listening socket. I hope this gives you some idea... I know what I mean :) Rocky
Hello Tauno,

> There is no danger of a mix-up: a TCP connection is > identified by a set of four numbers: the source IP, > destination IP, source port and destination port.
Hmmm ... thats 12 (IPv4) or 16 (IPv6) bytes only to define a two-way socket. As I'm working on a controller with very limited memory (just 2048 *Bytes* of RAM, which allso needs to hold the ethernet-packet itself as well as the stack) I hoped I could use another method to uniquely identify a connection : by (ab)using (a few bits of) the new-to-be-assigned portnumber together with the Acknowledge-number. But alas, that idea is now outof the window.
> After the three-way handshake is completed, you're not > allowed to do any kinds of re-direct: the conversation is > on and the four > numbers fixed till FIN/ACK's or RST.
Yep, thats clear to me now. Thanks for explaining. Regards, Rudy Wieser -- Origional message Tauno Voipio <tauno.voipio@INVALIDiki.fi> schreef in berichtnieuws TDGLl.166$eh7.33@read4.inet.fi...
> R.Wieser wrote: > > Hello Rocky, > > > >> I think you find that you (server) need to do this in response > >> to the 1st SYN, not after the three-way handshake. > > > > :-) That is exactly what I tried and described in my initial message
and
> > which fails (gets responded to with a Reset). > > > >> It is only necessary if you expect to have multiple incoming > >> connections to a given port. > > > > As I'm implementing a Server I should consider the possibility of
multiple
> > incoming connections, don't you think ? :-) Although its not
specified as
> > mandatory, I think it will help to keep mixups between the different > > requests at a minimum. > > > > Regards, > > Rudy Wieser > > > > > > -- Origional message > > Rocky <RobertGush@gmail.com> schreef in berichtnieuws > > a0d1a1dc-2631-42b4-860c-315c4ce485f4@g19g2000vbi.googlegroups.com... > > On May 4, 6:46 pm, "R.Wieser" <addr...@not.available> wrote: > >> Hello David, > >> > >> Thanks for your reply, but somehow I can't seem to extract from it what
I
> >> need : > >> > > <snip> > >> Thank you for that info, but can you tell me how I should, after the > > initial > >> contact, re-direct the client to another port ? > >> > > > > I think you find that you (server) need to do this in response to the > > 1st SYN, not after the three-way handshake. It is only necessary if > > you expect to have multiple incoming connections to a given port. > > > TCP does not allow a port re-direct a la TFTP. > > There is no danger of a mix-up: a TCP connection is identified by > a set of four numbers: the source IP, destination IP, source port > and destination port. For the same client and server, the source > ports are different for different connections. > > After the three-way handshake is completed, you're not allowed to > do any kinds of re-direct: the conversation is on and the four > numbers fixed till FIN/ACK's or RST. > > -- > > Tauno Voipio > tauno voipio (at) iki fi
"R.Wieser" <address@not.available> wrote in message 
news:49ff4a50$1$19398$e4fe514c@dreader16.news.xs4all.nl...
> Hello Rocky, > > It looks that an assumption of how things work got the better of me : I > allways thought that the "accept" function would take over the connection > and move it from the origional port to high-numbered one. Looking at at > a > few packet-sniff logs (as suggested by "MikeWhy", who allso replied to me) > I > realized that that assumption was wrong. > > Now if I can only get that years-old misconception outof my head and > replace > it with the correct way-of-working
You might be remembering that accept() returns a new socket, bound to the new connection. The original listener socket is still there. Anyway, now that you know, you'll just know.
On Mon, 04 May 2009 18:46:29 +0200, R.Wieser wrote:

> Thanks for your reply, but somehow I can't seem to extract from it what I > need : > >> RFC 793 Section 3.4 (Establishing a connection) says in part: > <snip quote> > > Its not the client actually sending data before it should I'm concerned > about (as the controller does not have enough RAM to store the data I will > probably just drop the connection), but how figure out which packets to skip > before I'm allowed to send some data myself :
You're allowed to send data with the SYN/ACK; that doesn't mean that the client will accept it. But ideally, you shouldn't send any data until after the client ACK's your SYN+ACK. This prevents a rogue client from using your server as a DoS "amplifier" (sending a SYN with a spoofed source address).
> Currently I receive two > different ACK responses to my SYN/ACK (the second packet re-defines the > window-size). When I send some data after receiving the first ACK the > client behaves as if I did not send that packet at all (mind you, this is on > a LAN). > > I can ofcourse "fix" this by checking the Acknowledgement-number and as it > did not change re-send the data, but a) would like to know why it does not > respond to my data b) have not enough resources in the controller to send a > packet again anyway. :-\
If you can't re-send, you can't implement TCP. Even on a LAN, packets get dropped; you can't discard data until it has been ACK'd.
>> That is a feature of the sockets API, and doesn't quite work the >> way you might think it does. (I was also confused by this when >> I first started using TCP/IP.) > > Thank you for that info, but can you tell me how I should, after the initial > contact, re-direct the client to another port ?
You can't redirect the client to another port. If the client connects from port 123 to port 456, all subsequent client->server packets will be from 123 to 456, and all subsequent server->client packets must be from 456->123. If you send anything else, expect a RST.
On Mon, 04 May 2009 22:06:34 +0200, R.Wieser wrote:

>> There is no danger of a mix-up: a TCP connection is >> identified by a set of four numbers: the source IP, >> destination IP, source port and destination port. > > Hmmm ... thats 12 (IPv4) or 16 (IPv6) bytes only to define a two-way socket. > As I'm working on a controller with very limited memory (just 2048 *Bytes* > of RAM, which allso needs to hold the ethernet-packet itself as well as the > stack) I hoped I could use another method to uniquely identify a connection > : by (ab)using (a few bits of) the new-to-be-assigned portnumber together > with the Acknowledge-number. But alas, that idea is now outof the window.
You need to store all of that, plus both sequence numbers (another 8 bytes), timers, the client's receive window, the path MTU, the client's MAC address, probably some other stuff. Resist the temptation to try to get away with implementing only what you think you need based upon a handful of test cases. Expect the client and intermediate routers to behave in every way the standards permit them to.
On 2009-05-04, Nobody <nobody@nowhere.com> wrote:

> Resist the temptation to try to get away with implementing > only what you think you need based upon a handful of test > cases. Expect the client and intermediate routers to behave in > every way the standards permit them to.
And a few ways the standards don't permit them to. -- Grant Edwards grante Yow! He is the MELBA-BEING at ... the ANGEL CAKE visi.com ... XEROX him ... XEROX him --
R.Wieser <address@not.available> wrote:

> Hello David, > > Thanks for your reply, but somehow I can't seem to extract from it what I > need : > > > RFC 793 Section 3.4 (Establishing a connection) says in part: > <snip quote> > > Its not the client actually sending data before it should I'm concerned > about (as the controller does not have enough RAM to store the data I will > probably just drop the connection), but how figure out which packets to skip > before I'm allowed to send some data myself : Currently I receive two > different ACK responses to my SYN/ACK (the second packet re-defines the > window-size). When I send some data after receiving the first ACK the > client behaves as if I did not send that packet at all (mind you, this is on > a LAN).
In that situation you aren't allowed to send data in response to the ACK of your SYN, because that ACK said the window size was zero. The receiver is allowed to throw away data you send which falls outside the receiver's window. You must wait until the second ACK which says the window size is nonzero. You could only send data with your responding SYN/ACK or in response to the client's subsequent ACK if the client had indicated a nonzero window size in the previous packet, and it seems that most common TCP/IP implementations never do that during the three-way handshake. It occurs to me that the SYN packets are usually also negotiating MSS, and some TCP implementations may want to wait for MSS to be established in both directions before reporting their window size.
> I can ofcourse "fix" this by checking the Acknowledgement-number and as it > did not change re-send the data, but a) would like to know why it does not > respond to my data b) have not enough resources in the controller to send a > packet again anyway. :-\
Don't use the arrival of a specific packet directly as a trigger to send: you should be copying the window size out of the received packets (strictly it is the range of bytes starting from the ack sequence number up to the end of the window, and you may need to allow for data you had previously sent but which the receiver hasn't acknowledged yet). Wait until the window size is nonzero before sending. You should also check that you aren't sending too much data, e.g. the client might open a very small window initially, preventing you from sending all your data. In this situation you might not be able to send at all unless the client opens its window further, unless you send your data in several small pieces. You might want to look at the open source uIP project to get some implementation ideas. It is designed to be used on very small systems with limited memory. -- David Empson dempson@actrix.gen.nz
On Mon, 4 May 2009 22:06:34 +0200, "R.Wieser" <address@not.available>
wrote:

>Hello Tauno, > >> There is no danger of a mix-up: a TCP connection is >> identified by a set of four numbers: the source IP, >> destination IP, source port and destination port. > >Hmmm ... thats 12 (IPv4) or 16 (IPv6) bytes only to define a two-way socket. >As I'm working on a controller with very limited memory (just 2048 *Bytes* >of RAM, which allso needs to hold the ethernet-packet itself as well as the >stack) I hoped I could use another method to uniquely identify a connection >: by (ab)using (a few bits of) the new-to-be-assigned portnumber together >with the Acknowledge-number. But alas, that idea is now outof the window.
Is there a specific reason why you insist on implementing TCP/IP with such small resources ? UDP would be much more suitable for such small devices. Paul
Hello Nobody,

> But ideally, you shouldn't send any data until > after the client ACK's your SYN+ACK.
Thats the problem, I did (only start to send *after* the clients ACK).
> If you can't re-send, you can't implement TCP. Even on a > LAN, packets get dropped; you can't discard data until it > has been ACK'd.
Too little RAM in the controller for that I'm afraid. But I may try to figure out a method to work around it *after* I get the connection to work.
> You can't redirect the client to another port.
Yep, that has been made clear to me now. :-) Regards, Rudy Wieser -- Origional message Nobody <nobody@nowhere.com> schreef in berichtnieuws pan.2009.05.04.22.42.34.875000@nowhere.com...
> On Mon, 04 May 2009 18:46:29 +0200, R.Wieser wrote: > > > Thanks for your reply, but somehow I can't seem to extract from it
what I
> > need : > > > >> RFC 793 Section 3.4 (Establishing a connection) says in part: > > <snip quote> > > > > Its not the client actually sending data before it should I'm concerned > > about (as the controller does not have enough RAM to store the data I
will
> > probably just drop the connection), but how figure out which packets to
skip
> > before I'm allowed to send some data myself : > > You're allowed to send data with the SYN/ACK; that doesn't mean that the > client will accept it. But ideally, you shouldn't send any data until > after the client ACK's your SYN+ACK. This prevents a rogue client from > using your server as a DoS "amplifier" (sending a SYN with a spoofed > source address). > > > Currently I receive two > > different ACK responses to my SYN/ACK (the second packet re-defines the > > window-size). When I send some data after receiving the first ACK the > > client behaves as if I did not send that packet at all (mind you, this
is on
> > a LAN). > > > > I can ofcourse "fix" this by checking the Acknowledgement-number and as
it
> > did not change re-send the data, but a) would like to know why it does
not
> > respond to my data b) have not enough resources in the controller to
send a
> > packet again anyway. :-\ > > If you can't re-send, you can't implement TCP. Even on a LAN, packets get > dropped; you can't discard data until it has been ACK'd. > > >> That is a feature of the sockets API, and doesn't quite work the > >> way you might think it does. (I was also confused by this when > >> I first started using TCP/IP.) > > > > Thank you for that info, but can you tell me how I should, after the
initial
> > contact, re-direct the client to another port ? > > You can't redirect the client to another port. If the client connects > from port 123 to port 456, all subsequent client->server packets will be > from 123 to 456, and all subsequent server->client packets must be from > 456->123. If you send anything else, expect a RST. >

Memfault Beyond the Launch