5 ms·
TL;DR: "Because if TCP handshake were 2-way only, the receiver couldn't confirm if it could send packets successfully or sender could receive them". And that s
by sedatk 2y ago
TL;DR: "Because if TCP handshake were 2-way only, the receiver couldn't confirm if it could send packets successfully or sender could receive them".
And that sounds bogus to me. Connection initiation isn't about testing if packets can reach or not. It's about acknowledgement, building a two peer consensus about how to handle upcoming packets from a peer, not reliability checks. In that sense, I don't even think the third step is necessary, but apparently, it's needed to handle the case of both endpoints going into a timeout loop, this article explains it perfectly: https://www.baeldung.com/cs/handshakes https://www.baeldung.com/cs/handshakes
- toast0 2y agoYou can only reach consensus if the peers can each receive packets that the other sent. So reaching consensus and testing for reachability in both directions are the same. In a client/server scenario, the client knows the connection is good when it receives the SYN+ACK, but the server doesn't know until it receives the resulting ACK. So the third packet is necessary to communicate consensus to the server; it doesn't need to be a pure ACK though, it can have data, if the client's stack makes it possible to queue outgoing data before the SYN+ACK is received.
- sedatk 2y ago> You can only reach consensus if the peers can each receive packets that the other sent. So reaching consensus and testing for reachability in both directions are the same. No, that's not the intent of a handshake. Assume a hypothetical Internet where every node has guaranteed connectivity to every other node that never fails. Do we suddenly lose the need to do a 3-way handshake? No. It's not about testing connectivity, that's semantically wrong. And what's the meaning of testing connectivity for a connection of an arbitrary length and with a quality of unknown degree throughout? It doesn't make any sense. There is no "knowing the connection is good", there is a process of building up consensus. The peers are only interested in an answer to this question: "Does the other party assume a connection?". If we knew the answer to that question beforehand, we wouldn't need a handshake at all. Reachability, transmissibility are all irrelevant. And, UDP actually works like that. Both endpoints assume willingness to connect. That's why you don't need a handshake with UDP. TCP-FO worked liked that too, removing the need for a TCP handshake completely, because it could persist the consensus information.
- toast0 2y agoUDP doesn't include a protocol handshake, and there is no consensus on if the peers are communicating, unless the application adds that. Lack of consensus/lack of handshake on UDP is why protocols with large responses become tools for DDoS reflection, and TCP protocols with large responses don't. TCP protocols with large responses can still be used for DDoS, but only when the target takes an active part --- either filling its outbound bandwidth to serve the large response to distributed requestors or being induced into making a request with a large response that fills its inbound bandwidth. TCP Fast Open is interesting, but didn't seem to go anywhere. Speculatively including one MSS worth of data in the handshake process seems like it could be useful in some circumstances, but the server side implications of processing a request without an expectation that the client will receive the response are hard. (Of course, TCP can't and doesn't guarantee the client will receive the response, but when you have recent consensus on communication, you can expect it will). The crypto context shows evidence of past communication, but does not show evidence of current communication.
- cryptonector 2y agoTCP-FO lets you use recent proof of return routability to get 1 MSS of data in the SYN packet. It's akin (if you squint hard) to multiplexing multiple connections onto one. So TCP-FO ought to have become useful, but mainly it's going to be useful in local networks, not on the big bad Internet. And TCP-FO does require more state on the server.
- tsimionescu 2y agoWe don't even need to assume a perfect internet where all hosts are always connected, we just need to assume an internet where all hosts are who they say they are, and there is no way to forge your source address. In that case, yes, you wouldn't need a three-way handshake. The client would send a SYN, the server would send a SYN-ACK plus any data it wants (e.g. an SMTP banner), and the client would send any data it wants as well with the next segment (e.g. an SMTP request). If the server doesn't receive anything, it could re-send the SYN-ACK+data, just like any other packet. The reason this isn't done in reality is mainly that using a server's resources to send a lot of data blindly, in response to a very small request, is wasteful (if the reverse path is not accessible, the server is using all those resources retrying for nothing). It is also dangerous, if the source IP of the SYN is forged, then the server ends up sending lots of data to a victim's IP. This often happens with DNS, for example.
- m463 2y agowithout a 3-way handshake, wouldn't it be easier to do spoofing? or a man-in-the-middle attack? I think now there are ways to do the 3-way handshake in hardware at hardware speeds, and only involve software if the connection has been vetted. This can protect against Denial-Of-Service attacks.
- sedatk 2y agoNo and no. IP spoofing was already trivial with 3-way handshake. That's why random TCP sequence numbers were introduced. It's now harder, but for some scenarios, SYN cookies might also be needed.
- toast0 2y ago> I think now there are ways to do the 3-way handshake in hardware at hardware speeds, and only involve software if the connection has been vetted. This can protect against Denial-Of-Service attacks. Do we need hardware for this? Syncookies have provided a software method to handle large volumes of inbound syn without memory restrictions since the late 90s, and it's been in all major platforms except Mac since the late 2000s; Apple forked FreeBSD's tcp months before FreeBSD added syncookies, and last I checked, Apple never pulled them in. My testing is a bit old, but I had more trouble generating line rate syns at 2x10g than handling them several years ago. Are syncookies in software enough at 100g? I'm not sure, but I'd assume so. There's plenty of things to hardware accelerate on a NIC, but syn handling doesn't seem worthwhile IMHO.
- tsimionescu 2y agoThere is no significant difference between a two-way handshake and a three-way handshake, given the other parts of the TCP protocol, IF the client is the one that sends the first piece of data after the handshake. It is in fact very common for optimized hosts to send data with the "third part of the handshake", which makes it perfectly equivalent to using a two-way handshake. This happens because the first segment the client sends after the handshake must ACK the server's sequence number, regardless of whether this is "the third part of the handshake" or "the first data packet after a two-way handshake". The problem appears if the server would like to be the first to send data on a new connection. If the server included its data with the SYN-ACK, that would work perfectly well with benign clients, but it would be a vector for DoS attacks. An attacker could send a small packet with a forged source IP, and cause the server to send a large response to the victim's IP. So, the server can't safely send data until it receives an ACK with its secret SEQ number from the client.
- zokier 2y agoYeah, as a proof it is dubious as it doesn't really define what "established" means in this context. The baeldung article is just wrong > The client, in turn, receives the delayed ACK and assumes that it refers to the last sent SYN message ACKs have acknowledgement numbers, so this sort of confusion can not happen.
- f1shy 2y agoThanks for the link with the correct explanation: Particularly, the two-way handshake presents potential problems when the ACK message from the server delays too much. Thus, if a connection timeout occurs, the client sends another SYN message with a new sequence number (Z, for example) to the server. However, if the server previously sent an ACK (which is delayed), it’ll discard this new SYN message. The client, in turn, receives the delayed ACK and assumes that it refers to the last sent SYN message. Here’s where the error happens: the client will send messages with the sequence number Z, while the server expects messages following the sequence number X.
- deleted 2y ago[deleted]
- zokier 2y agoThat is possibly even more wrong explanation. Hosts do not blindly assume what is getting acknowledged by ACKs
- dcuthbertson 2y agoThanks for explaining the why. I'm glad it falls somewhere between the X and the Z.
- tsimionescu 2y agoThis is a bogus explanation, one that has nothing to do with TCP. In TCP every segment has a SEQ number and an ACK number, regardless of it being a handshake segment or a data segment. This completely negates the described problem: the server's first response to a SYN includes "SEQ=Y, ACK=X". If the client which just sent "SYN seq=Z" receives the ACK for SEQ=X, it will drop this ACK and wait for a new one. Also, a server which receives a new SYN has no reason to drop it, it will send a new ACK instead.
- phicoh 2y agoThe thing the consider is who is the first to send data over the connection. If it is the client, then a two-way handshake is enough: client sends a SYN, server sends a SYN+ACK, then the clients data which ACKs the server's SYN. These days that is the most common model. HTTP and TLS work like that. However, what if the server sends first? For example the banner of SMTP. In that case the client sends a SYN, the server sends a SYN+ACK, the client sends an ACK and only then the server start sending data. In general, an operating system doesn't know what is going to happen. So the client's kernel will just send the ACK immediately even if it will be followed by a data segment shortly after.