With a typical web-browser, the normal behavior is for the server to close the session after they have received the request via the client. But that's doesn't always happen in that order. In this post we will look at some closing for tcp-sessions.
Here's the opposite, where a server closes the session first;
( the client sits at 10.0.18.11 in these examples )
sh-3.2$
sudo tshark -r active*close.pcap -R 'tcp.port==55876'
21 15.184532000 10.0.18.11-> 64.124.19.179 TCP 78 55876
> http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=16 TSval=816445360 TSecr=0
SACK_PERM=1
22 15.286232000 64.124.19.179 -> 10.0.18.11
TCP 66 http > 55876 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1430
SACK_PERM=1 WS=128
23 15.286279000 10.0.18.11-> 64.124.19.179 TCP 54 55876
> http [ACK] Seq=1 Ack=1 Win=262144 Len=0
24
15.286337000 10.0.18.11->
64.124.19.179 HTTP 205 GET / HTTP/1.1
25 15.377931000 64.124.19.179 -> 10.0.18.11
TCP 60 http > 55876 [ACK] Seq=1 Ack=152 Win=6912 Len=0
33 25.378766000 64.124.19.179 -> 10.0.18.11
TCP 60 http > 55876 [FIN, ACK] Seq=1 Ack=152 Win=6912 Len=0
34 25.379010000 10.0.18.11-> 64.124.19.179 TCP 54 55876
> http [ACK] Seq=152 Ack=2 Win=262144 Len=0
35 25.379271000 10.0.18.11-> 64.124.19.179 TCP 54 55876
> http [FIN, ACK] Seq=152 Ack=2 Win=262144 Len=0
36 25.467514000 64.124.19.179 -> 10.0.18.11
TCP 60 http > 55876 [ACK] Seq=2 Ack=153 Win=6912 Len=0
sh-3.2$
I bold the line containing the FIN-ACK and from the direction of the server. Now let's compare the normal TCP close typically done by a client.
-->
sh-3.2$
sudo tshark -r normalclose.pcap -R
'tcp.port==56154'
1 0.000000000
10.0.18.11-> 15.193.113.27 TCP 78 56154 > http [SYN] Seq=0
Win=65535 Len=0 MSS=1460 WS=16 TSval=816940518 TSecr=0 SACK_PERM=1
2 0.044037000 15.193.113.27 -> 10.0.18.11
TCP 78 http > 56154 [SYN, ACK] Seq=0 Ack=1 Win=32768 Len=0 MSS=1380
SACK_PERM=1 WS=1 TSval=3823454198 TSecr=816940518
3 0.044278000
10.0.18.11-> 15.193.113.27 TCP 66 56154 > http [ACK] Seq=1 Ack=1
Win=131328 Len=0 TSval=816940561 TSecr=3823454198
4 0.044447000
10.0.18.11-> 15.193.113.27 HTTP 208 HEAD / HTTP/1.1
5 0.151665000 15.193.113.27 -> 10.0.18.11
TCP 383 [TCP segment of a reassembled PDU]
6 0.151972000
10.0.18.11-> 15.193.113.27 TCP 66 56154 > http [ACK] Seq=143
Ack=318 Win=131008 Len=0 TSval=816940667 TSecr=3823454209
7 0.152167000
10.0.18.11-> 15.193.113.27 TCP 66 56154 > http [FIN, ACK] Seq=143
Ack=318 Win=131072 Len=0 TSval=816940667 TSecr=3823454209
8 0.198413000 15.193.113.27 -> 10.0.18.11
TCP 66 http > 56154 [ACK] Seq=318 Ack=144 Win=32768 Len=0 TSval=3823454213
TSecr=816940561
9 0.198646000
10.0.18.11-> 15.193.113.27 TCP 66 [TCP Dup ACK 7#1] 56154 > http
[ACK] Seq=144 Ack=318 Win=131072 Len=0 TSval=816940711 TSecr=3823454213
10 0.203468000 15.193.113.27 -> 10.0.18.11
HTTP 66 HTTP/1.1 200 OK
11 0.203732000
10.0.18.11-> 15.193.113.27 TCP 66 56154 > http [ACK] Seq=144
Ack=319 Win=131072 Len=0 TSval=816940715 TSecr=3823454213
sh-3.2$
sh-3.2$
Notice the client initializing the closure first? Also you see some duplicate ACK that's not relevant.
Here's another client side closure;
-->
sh-3.2$
sudo tshark -r normalclose.pcap -R
'tcp.port==56421' -tad
1 2013-06-22 23:40:09.145392000 10.0.18.11-> 140.211.167.51 TCP 78 56421
> http [SYN] Seq=0 Win=65535 Len=0 MSS=1460 WS=16 TSval=817520647 TSecr=0
SACK_PERM=1
2 2013-06-22 23:40:09.236713000
140.211.167.51 -> 10.0.18.11 TCP 74 http > 56421 [SYN, ACK] Seq=0 Ack=1
Win=14480 Len=0 MSS=1380 SACK_PERM=1 TSval=2005662022 TSecr=817520647 WS=128
3 2013-06-22 23:40:09.237021000 10.0.18.11-> 140.211.167.51 TCP 66 56421
> http [ACK] Seq=1 Ack=1 Win=131328 Len=0 TSval=817520736 TSecr=2005662022
4 2013-06-22 23:40:09.237193000 10.0.18.11-> 140.211.167.51 HTTP 207 HEAD
/ HTTP/1.1
5 2013-06-22 23:40:09.330093000
140.211.167.51 -> 10.0.18.11 TCP 66 http > 56421 [ACK] Seq=1 Ack=142
Win=15616 Len=0 TSval=2005662116 TSecr=817520736
6 2013-06-22 23:40:09.331312000
140.211.167.51 -> 10.0.18.11 TCP 255 [TCP segment of a reassembled PDU]
7 2013-06-22 23:40:09.331584000 10.0.18.11-> 140.211.167.51 TCP 66 56421
> http [ACK] Seq=142 Ack=190 Win=131136 Len=0 TSval=817520829
TSecr=2005662116
8 2013-06-22 23:40:09.331977000 10.0.18.11-> 140.211.167.51 TCP 66 56421
> http [FIN, ACK] Seq=142 Ack=190 Win=131136 Len=0 TSval=817520829
TSecr=2005662116
9 2013-06-22 23:40:09.428806000
140.211.167.51 -> 10.0.18.11 TCP 66 http > 56421 [FIN, ACK] Seq=190
Ack=143 Win=15616 Len=0 TSval=2005662210 TSecr=817520829
10 2013-06-22 23:40:09.429067000 10.0.18.11-> 140.211.167.51 TCP 66 56421
> http [ACK] Seq=143 Ack=191 Win=131136 Len=0 TSval=817520925
TSecr=2005662210
sh-3.2$
Same here, the client sends the FIN-ACK and the server immediately sends back a FIN-ACK and doesn't even bother to wait for the client #2nd ACK.
And lastly, here's a look at another client and server tear-down, once again initialized by the server;
sh-3.2$
sudo tshark -r normalclose.pcap -R 'tcp.port==56155'
12 6.023331000
10.0.18.11-> 156.151.59.35 TCP 78 56155 > http [SYN] Seq=0
Win=65535 Len=0 MSS=1460 WS=16 TSval=816946451 TSecr=0 SACK_PERM=1
13 6.126083000 156.151.59.35 -> 10.0.18.11
TCP 78 http > 56155 [SYN, ACK] Seq=0 Ack=1 Win=4290 Len=0 MSS=1430 WS=1
TSval=1863626880 TSecr=816946451 SACK_PERM=1
14 6.126398000
10.0.18.11-> 156.151.59.35 TCP 66 56155 > http [ACK] Seq=1 Ack=1
Win=131872 Len=0 TSval=816946553 TSecr=1863626880
15 6.126548000
10.0.18.11-> 156.151.59.35 HTTP 209 HEAD / HTTP/1.1
16 6.249165000 156.151.59.35 -> 10.0.18.11
HTTP 203 HTTP/1.0 301 Moved Permanently
17 6.249460000
10.0.18.11-> 156.151.59.35 TCP 66 56155 > http [ACK] Seq=144
Ack=138 Win=131728 Len=0 TSval=816946674 TSecr=1863627001
18 6.249666000 156.151.59.35 -> 10.0.18.11
TCP 66 http > 56155 [FIN, ACK] Seq=138 Ack=144 Win=4433 Len=0
TSval=1863627001 TSecr=816946553
19 6.249714000
10.0.18.11-> 156.151.59.35 TCP 66 56155 > http [FIN, ACK] Seq=144
Ack=138 Win=131728 Len=0 TSval=816946674 TSecr=1863627001
20 6.249827000
10.0.18.11-> 156.151.59.35 TCP 66 56155 > http [FIN, ACK] Seq=144
Ack=139 Win=131728 Len=0 TSval=816946674 TSecr=1863627001
21 6.354273000 156.151.59.35 -> 10.0.18.11
TCP 66 http > 56155 [ACK] Seq=139 Ack=145 Win=4433 Len=0 TSval=1863627108
TSecr=816946674
22 6.354555000
10.0.18.11-> 156.151.59.35 TCP 66 [TCP Dup ACK 20#1] 56155 > http
[ACK] Seq=145 Ack=139 Win=131728 Len=0 TSval=816946777 TSecr=1863627108
23 6.355058000 156.151.59.35 -> 10.0.18.11
TCP 66 [TCP Dup ACK 21#1] http > 56155 [ACK] Seq=139 Ack=145 Win=4433 Len=0
TSval=1863627108 TSecr=816946674
sh-3.2$
So a server can close the tcp connection 1st.
TCP allows for either party to close the sessions. When the server closes the session 1st ( by sending the initial FIN-ACK ) it's called a "active close".
NOTE: In the above last pcap example, and due to the short delay between packets #18 & #19, I believe this yet another close type, known as a simultaneously close.
( keep theses below thoughts in mind when dealing with tcp )
All TCP sessions goes thru these states;
LISTEN ( server listening and awaiting for connections )
SYN-SENT ( a cliet Sending a request to Synchronize a session )
SYN-RECEIVED ( server ack the client and completion of the Synchronize the session via sequence #s )
ESTABLISHED ( client +server are actively establish, does not necessary mean we are passing data )
FIN-WAIT1 ( awaiting a connection termination state or ack from the remote )
FIN-WAIT2 ( awaiting a connection termination state from remote )
CLOSE-WAIT ( awaiting a connection termination from the local machine )
CLOSING ( a waiting a connection termination from the remote host )
LAST-ACK ( ack of the last closing state)
TIME-WAIT ( a state to ensure that the session is closed )
CLOSED ( a psuedo state it really doesn't exists & means we are close and not sending data )
With the active close, this is acceptable and not bad behavior. The server does not have to wait for the session to be torn down via the client or even the "Acknowledg" the client requests.
With a lot of tcp based applications & those that deals with "web" services, the server may start the tear down 1st. So keep that thought in mind.
^ ^
=( * * )=
/ ` \
Ken Felix
Freelance Network/Security Engineer
kfelix ---a--t--- hyperfeed dot com