From ad546ec6062e47f08352ff2c4038aba3479bfb82 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 27 Jul 2013 14:35:51 +0200 Subject: Update docs/tcp.txt Signed-off-by: Denys Vlasenko --- docs/tcp.txt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/tcp.txt b/docs/tcp.txt index 7951e1c8b..c867c6da9 100644 --- a/docs/tcp.txt +++ b/docs/tcp.txt @@ -39,11 +39,28 @@ Solution #1: block until sending is done: close(sock); Solution #2: tell kernel that you are done sending. -This makes kernel send FIN, not RST: +This makes kernel send FIN after all data is written: shutdown(sock, SHUT_WR); close(sock); +However, experiments on Linux 3.9.4 show that kernel can return from +shutdown() and from close() before all data is sent, +and if peer sends any data to us after this, kernel stll responds with +RST before all our data is sent. + +In practice the protocol in use often does not allow peer to send +such data to us, in which case this solution is acceptable. + +If you know that peer is going to close its end after it sees our FIN +(as EOF), it might be a good idea to perform a read after shutdown(). +When read finishes with 0-sized result, we conclude that peer received all +the data, saw EOF, and closed its end. + +However, this incurs small performance penalty (we run for a longer time) +and requires safeguards (nonblocking reads, timeouts etc) against +malicious peers which don't close the connection. + Defeating Nagle. -- cgit v1.2.3