Bug 1983 - socket(s, 1) said to discard sent data
Summary: socket(s, 1) said to discard sent data
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: manual (show other bugs)
Version: 2.3.5
: P2 normal
Target Milestone: ---
Assignee: Roland McGrath
: 11489 (view as bug list)
Depends on:
Reported: 2005-12-06 11:54 IST by Per Cederqvist
Modified: 2014-06-30 18:16 IST (History)
3 users (show)

See Also:
Last reconfirmed:
fweimer: security-

Program to help demonstrate that the documentation is wrong (641 bytes, text/plain)
2007-10-16 16:53 IST, Neil Roberts

Note You need to log in before you can comment on or make changes to this bug.
Description Per Cederqvist 2005-12-06 11:54:43 IST
The Closing a Socket node says that shutdown works like this:

>    `1'
>          Stop trying to transmit data from this socket.  Discard any
>          data waiting to be sent.  Stop looking for acknowledgement of
>          data already sent; don't retransmit it if it is lost.

I have looked at shutdown(3n) in Solaris 10, and in the Single Unix
Specification, and they both say nothing about discarding data waiting
to be sent.  Does shutdown() really do that?  If it does, I think it
is a bug.  To the best of my understanding, the reason why you would
use shutdown(s,1) on a TCP socket is to send a FIN packet to the remote
side, but you typically still want all the data to arrive there.  (If any
data is discarded, I would naively assume that it would follow the policy
set up by SO_LINGER.)

My (rather unfounded) hypothesis is that the glibc manual is wrong in
this section.

(Page 11 of the document "An Introduction to OpenSSL Programming (Part I)",
which can be found at http://www.rtfm.com/openssl-examples/, shows why it
can be useful to force a FIN packet while still not wanting to discard
any sent data (the close_notify in this case).)
Comment 1 Neil Roberts 2007-10-16 16:48:46 IST
I've just wasted a fair amount of coding time after being mislead by this bug so
I'm just commenting in the hope that it will encourage someone to change it.

You can demonstrate that it doesn't discard the pending send data with the
attached program. The program opens a connection to the given web server, sleeps
for 5 seconds, then calls shutdown. If you disconnect your network cable or set
up a firewall within those five seconds, you can see with tcpdump that the OS
still tries to send the data even though shutdown was called.

# Establish connection

17:42:39.081415 IP > S
4039457085:4039457085(0) win 5840 <mss 1460,sackOK,timestamp 385240294
0,nop,wscale 3>
17:42:39.268932 IP > S
810590603:810590603(0) ack 4039457086 win 5792 <mss 1418,sackOK,timestamp
3715979507 385240294,nop,wscale 4>
17:42:39.268970 IP > . ack 1 win 730
<nop,nop,timestamp 385240341 3715979507>

# Sleep for five seconds, network cable is pulled out in this time

# Now you can see that the client is still trying to send the data, even though
shutdown has been called and the program is no longer running.

17:42:44.271789 IP > P 1:1025(1024) ack 1
win 730 <nop,nop,timestamp 385241592 3715979507>
17:42:44.272235 IP > F 1025:1025(0) ack 1
win 730 <nop,nop,timestamp 385241592 3715979507>
17:42:45.219521 IP > P 1:1025(1024) ack 1
win 730 <nop,nop,timestamp 385241829 3715979507>
17:42:47.115725 IP > P 1:1025(1024) ack 1
win 730 <nop,nop,timestamp 385242303 3715979507>
17:42:50.908161 IP > P 1:1025(1024) ack 1
win 730 <nop,nop,timestamp 385243251 3715979507>
17:42:58.493019 IP > P 1:1025(1024) ack 1
win 730 <nop,nop,timestamp 385245147 3715979507>
17:43:13.662722 IP > P 1:1025(1024) ack 1
win 730 <nop,nop,timestamp 385248939 3715979507>
17:43:44.002164 IP > P 1:1025(1024) ack 1
win 730 <nop,nop,timestamp 385256523 3715979507>
Comment 2 Neil Roberts 2007-10-16 16:53:07 IST
Created attachment 2045 [details]
Program to help demonstrate that the documentation is wrong
Comment 3 herefishy 2012-08-28 22:17:09 IST
I am not so sure the manual is wrong, especially for a remote socket vs. on on the LAN. 

Please refer to my bug report, with sample client and server code.  By actual test it demonstrates that, at least for data sizes around 4K bytes, data is lost unless the connection is deliberately held open by a sleep(1) before close(socket). This was the case for Linux/CentOS but not Solaris, and was MUCH more prone to happen on a remote host but not as often (very rarely) on the local LAN. 


Examples and statistics are included with the above linked bug report.
Comment 4 Ondrej Bilka 2013-10-21 06:48:29 IST
*** Bug 11489 has been marked as a duplicate of this bug. ***