I got a pcap package use tcpdump command. In this pcap, the TCP close in 2-way handshake!
Questions:
In this picture, can anyone determine who initiated the signal to close the connection?
why TCP close in 2-way handshake? it does not make sense!
This is only a half-close, initiated by the side that sent the FIN. A full close would require a FIN in the other direction, and a corresponding ACK.
Related
I am trying to find out a way to send exactly one TCP packet and verify this on Rx side that same has been received (no other packet) using tcpdump. I am new to networking world. Hence any help/explaination would be much appreciated.
These tools are for performance measurements and not for packet crafting. They always establish a full TCP connection for measurements. Since even a TCP connection with no data transfer consists of 6 packets (initial handshake to establish connection and handshake for connection close) you will not be able to send a single TCP packet using these tools.
Just a thought - configure the Rx side NOT to accept a tcp-ip connection from the Tx side, then attempt a connection from Tx side. You should see a (single) SYN packet on the Rx side, to which it won't respond. [Unfortunately, the Tx side will then retry the SYN packet a number of times].
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.
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.
in a tcp program written in Linux C
I want to close a tcp connectin
I used close(sockfd)
I notice this function will initiate a FIN/ACK packet to the other peer
but if the other peer doesn't respond an ACK due to network problem or tcp sequnce number inconsistency(e.g the tcp stack of the other peer crashes)
then it seems the tcp connection can't be closed
it will always be in FIN_WAIT1 status
how to deal with this?
how to close the tcp connection in such cases?
TCP deals with it. You don't have to deal with it. You can't deal with it.
By default, this is transparently handled by the TCP implementation according to system-wide configuration parameters which are system-dependent.
This can be overridden by setting the SO_LINGER socket option using setsockopt(), in which case the call to close() blocks until the specified timeout is reached.
Edit: I should add that most of the time using SO_LINGER is only worth the hassle if the goal is to add some error handling such as logging an error message stating that possibly some data was not received by the other end.
The way I understand this, there are 2 ways to close TCP connection:
send FIN flag
send RST flag
RST causes immediate connection termination, while in FIN you get a confirmation.
Do I understand this right, and are there any other distinctions between the two? Can those 2 flags be used together?
FIN says: "I finished talking to you, but I'll still listen to everything you have to say until you say that you're done."
RST says: "There is no conversation. I won't say anything and I won't listen to anything you say."
RST is useful if you have long lasting TCP connection with little traffic. If one of the computers is restarted, it forgets about the connection, and the other computer gets RST, as soon as it sends another packet.
FIN or RST would be sent in the following case
your process close the socket
OS is doing the resource cleanup when your process exit without closing socket.
If your process call close(), FIN would be sent from the closing side by default (note: you can set socket option SO_LINGER to make it send RST instead of FIN)
If your process exit without closing the socket, kernel would close the tcp connection and do the clean up for your process. FIN or RST can be sent. If there is data in your receive queue, RST would be sent. Otherwise, FIN would be sent.
You can loop through tcp_close() in tcp.c for more details.(I am using kernel-2.6.32-573.7.1 from redhat branch)
From RFC 1122, which everybody keeps citing, but not actually quoting, against me:
A TCP connection may terminate in two ways: (1) the normal
TCP close sequence using a FIN handshake, and (2) an "abort"
in which one or more RST segments are sent and the
connection state is immediately discarded.
It is not possible to use both at the same time. The concept doesn't even begin to make sense.
It is possible by means of trickery which I will not describe here to close a TCP connection with an RST instead of a FIN, but it's a stupid idea, which is why I am not documenting it. For one thing, all pending data in flight is lost.