aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-09-17 16:24:01 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-09-17 16:24:01 +0200
commitd7ea34ee710fe97fc57235dce165fcc5f50a512a (patch)
tree4d6aea04b91c2bd984bc18aae52ad09aedb71756
parent32ed30d96b56ea7322218061f09e62feda9948e3 (diff)
downloadbusybox-w32-d7ea34ee710fe97fc57235dce165fcc5f50a512a.tar.gz
busybox-w32-d7ea34ee710fe97fc57235dce165fcc5f50a512a.tar.bz2
busybox-w32-d7ea34ee710fe97fc57235dce165fcc5f50a512a.zip
Documentation update
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--docs/tcp.txt21
1 files changed, 16 insertions, 5 deletions
diff --git a/docs/tcp.txt b/docs/tcp.txt
index 766766387..2000f3110 100644
--- a/docs/tcp.txt
+++ b/docs/tcp.txt
@@ -18,8 +18,11 @@ What will happen if we close the socket?
18 received after close() is called, its TCP SHOULD send a RST 18 received after close() is called, its TCP SHOULD send a RST
19 to show that data was lost." 19 to show that data was lost."
20 20
21IOW: if we just close(sock) now, kernel can reset the TCP connection, 21IOW: if we just close(sock) now, kernel can reset the TCP connection
22discarding some not-yet sent data. 22(send RST packet).
23
24This is problematic for two reasons: it discards some not-yet sent
25data, and it may be reported as error, not EOF, on peer's side.
23 26
24What can be done about it? 27What can be done about it?
25 28
@@ -46,14 +49,14 @@ This makes kernel send FIN after all data is written:
46 49
47However, experiments on Linux 3.9.4 show that kernel can return from 50However, experiments on Linux 3.9.4 show that kernel can return from
48shutdown() and from close() before all data is sent, 51shutdown() and from close() before all data is sent,
49and if peer sends any data to us after this, kernel stll responds with 52and if peer sends any data to us after this, kernel still responds with
50RST before all our data is sent. 53RST before all our data is sent.
51 54
52In practice the protocol in use often does not allow peer to send 55In practice the protocol in use often does not allow peer to send
53such data to us, in which case this solution is acceptable. 56such data to us, in which case this solution is acceptable.
54 57
55If you know that peer is going to close its end after it sees our FIN 58Solution #3: if you know that peer is going to close its end after it sees
56(as EOF), it might be a good idea to perform a read after shutdown(). 59our FIN (as EOF), it might be a good idea to perform a read after shutdown().
57When read finishes with 0-sized result, we conclude that peer received all 60When read finishes with 0-sized result, we conclude that peer received all
58the data, saw EOF, and closed its end. 61the data, saw EOF, and closed its end.
59 62
@@ -61,6 +64,14 @@ However, this incurs small performance penalty (we run for a longer time)
61and requires safeguards (nonblocking reads, timeouts etc) against 64and requires safeguards (nonblocking reads, timeouts etc) against
62malicious peers which don't close the connection. 65malicious peers which don't close the connection.
63 66
67Solutions #1 and #2 can be combined:
68
69 /* ...set up struct linger... then: */
70 setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
71 shutdown(sock, SHUT_WR);
72 /* At this point, kernel sent FIN packet, not RST, to the peer, */
73 /* even if there is buffered read data from the peer. */
74 close(sock);
64 75
65 Defeating Nagle. 76 Defeating Nagle.
66 77