TCP Three way handshake - Piggybacking ACKs - networking

I understand that in the three-way handshake, sometimes the receiving end will send a SYNACK packet when establishing a connection (piggybacking), but when would it ever send a SYN and then an ACK packet?
For example:
->SYN
<-SYN_ACK
->ACK
versus:
->SYN
<-SYN
->SYN_ACK
Thanks!

No it won't - here's the reason why
SYN is typically sent by the 'client' (eg. your browser) when it wants to open a TCP connection to a server (eg. your web server). A server has no way of 'knowing' beforehand which client wants to open a connection (and hence send a SYN) to it. So it cannot send an unsolicited SYN.
SYN and ACK are flags, so the SYN-ACK from server is an ACK to the client's SYN (and it's own SYN). Technically, it can send them separately, but, sending SYN and ACK separately would involve additional half round trip. 'cos then it would be a four way handshake ((c)SYN -> , <- SYN(s), <-ACK(s), (c)ACK ->) that doesn't achieve any more reliability than three way handshake offers. Consequently it makes no sense to do that way.
Having said so you could theoretically design a protocol with 4 way handshake, but TCP isn't designed so.
Hope that helps.

Related

Are request and response part of two different TCP connections?

I am very new to networking, so this might sound simple. Though I have tried to look here and here and here and have got few basics of TCP, there are few questions whose answers I am not certain about.
Is a request and response part of 2 different TCP establishments. To explain that :
Is a connection established, kept alive until all packets are delivered, request sent and connection closed for each request and same happens for its response.
or
A connection is opened, request sent, connection kept alive, response arrives and connection closed.
Is the ACK number always 1 + sequence number of sent segment.
Is a request and response part of 2 different TCP establishments
You need just 3 packets to handshake and establish a bidirectional TCP connection. So no, you do not establish TCP connection for receiving and sending parts.
On the other hand, there is a sutdown() system call which allows to shutdown a part of the bidirectional connection. See man shutdown(2). So there is a possibility to establish a unidirectional connection by opening a bidirectional and then shutdown one of the sides.
Is the ACK number always 1 + sequence number of sent segment.
We usually do not send ACK for every received packet. There are also selective ACKs, retransmissions etc. So in general, the answer is no, the ACK number is not always seq + 1.
On the other hand, if you are sending a small amount of data and waiting for the confirmation, no errors or packet loss occurred, most probably there will be just one packet with that data and one ACK with seq + 1.
Hope that helps.

Mechanism for determining MSS during TCP 3-Way Handshake

I'm troubleshooting a MTU/MSS issue that is causing fragmentation over a PPPoE service. Below is a packet dump of a TCP 3-Way Handshake from a different service (that is working as expected) that relates to my question.
I understand the way PMTUD works as this: by setting the Don't Fragment (DF) bit to 1 in the IP header, a router along the path to the destination that requires fragmentation of the packet sends an ICMP back to the host to adjust the MSS size accordingly. However, my understanding is that this will only happen when fragmentation occurs (packets greater than the path MTU). This suggests that PMTUD works during the data exchange phase, NOT when TCP 3-Way Handshake is negotiated (since these are small packets, 78 bytes in this case).
In the above packet capture the SYN packet sends a MSS=1460 (which is too large, due to the 8 byte overhead of PPPoE) and the SYN/ACK response from the server sends back the correct MSS=1452. What mechanism does TCP use to determine the MSS during this exchange?
Maybe, the server hasn't computed the MSS during this three-way handshake. For instance, if the system administrator has observed a lot of fragmentation, he can have set the MSS of the whole system to 1452 (with the command ip tcp adjust-mss 1452), so when you are doing the three-way handshake, the server only advertises its default MSS. Is it applicable to your case?
What you're probably seeing here is the result of what's known as MSS clamping where the network on which the server is attached to modifies the MSS in the outgoing SYN/ACK packets to signal to the sender to use a lower MSS. This is commonly done on networks that perform some form of tunnelling such as PPPoE on ADSL.

TCP four-way handshake

Four-way handshake connection termination can be reduced to three-way and even two way one. Is it possible the three-way handshake connection establishment would be extended to four-way?
SYN=>
<=ACK
<=SYN
ACK=>
Given the semantics of SYN and ACK it should be possible to send SYN+ACK in different packets and those delay the handshake. E.g. client sends a SYN, server replies with an ACK to acknowledge the wish of the client for a new connection, but it does not grant the wish yet. Later the server sends a SYN and gets the matching ACK back from the client and the connection is established. But I doubt that anybody does connection establishment this way and it might be, that some OS will croak on it.
But, there is another scenario for a four-way-handshake, however with a different ordering of the packets. It could happen, if both side try to establish a connection to the other side at the same time, e.g. both send a SYN to the peer, and get an ACK back. It is described in the RFC 793 (TCP) section 3.4. But I doubt you will ever see such a handshake, because it does not fit into the typical client-server-scenario where one end is waiting for connects and the other end does the connect.
Edit: the handshake you envision exists and it is called "split handshake". See http://hackmageddon.com/2011/04/17/tcp-split-handshake-attack-explained/ . And like I expected, it is not universally supported.

What if a TCP handshake segment is lost?

In TCP 3-way handshake, 3 segments will be sent (SYN, SYN ACK, ACK). What if the third segment(ACK) is lost? Is the sender going to resend the segment or give up establishing the connection? And how do the two hosts know the segment is lost?
TCP has a sequence number in all packets. Hence it's easy to know if a packet was lost or not. If a host doesn't get an ACK on a packet he just resends it.
In most cases though, even if that ACK was lost, there will be no resending for a very simple reason. Directly after the ACK, the host that opened the TCP protocol is likely to start sending data. That data will, as all TCP packets, have an ACK number, so the recipient would get an ACK that way. Hence, the sender of the SYN-ACK should reasonably not care that it didn't get the ACK, because it gets an "implicit" ACK in the following package.
The re-send of the SYN-ACK is only necessary of there no data is received at all.
Update: I found the place in the RFC that specified exactly this:
If our SYN has been acknowledged (perhaps in this
incoming segment) the precedence level of the incoming segment must
match the local precedence level exactly, if it does not a reset
must be sent.
In other words, if the ACK is dropped but the next packet is not dropped, then everything is fine. Otherwise, the connection must be reset. Which makes perfect sense.
I am not an expert on this particular situation, but I suspect what will happen is the client will think it is connected but the server will not. If the client tries to send data to the server, the server will reject it and send a RST packet to the client so it can reset its "connection".

Regarding TCP SYN flood: Why is half-open connections worse than established connections?

THIS IS NOT ASKED FOR HACKING PURPOSES. I am studying computer science and I am just curious.
So..
When the host A sends a TCP SYN to host B, host B allocates space for receiving buffer etc., sends a SYNACK back to host A and host A allocates such space as well, then sends an ACK back to host B. The connection is then established.
But why does a half-open connection (one where the last ACK from A is never sent) tear down host B more than a fully established connection?
A half-open connection does not take more resources than a fully opened connection and a bunch of them do not overwhelm a server more easily, quickly, or surely than fully opened connections.
But you only need to send one packet to a server to make it create a half-open connection, whereas you need to complete a TCP handshake (1 send, 1 receive, another send) to create a fully open connection. So you can create lots of half-open connections from a spoofed IP address or quickly generate millions of them from a DDoS platform. You don't have to be in a position to receive the SYN|ACK replies. You don't even have to care if the server is able to produce those replies fast enough.
This assumes absence of SYN cookies or other defenses against half-open connections.

Resources