Documentation update
No binary (build failed)
—
(log yok)
| @@ -18,8 +18,11 @@ What will happen if we close the socket? | |
| received after close() is called, its TCP SHOULD send a RST | |
| to show that data was lost." | |
| - | IOW: if we just close(sock) now, kernel can reset the TCP connection, |
| - | discarding some not-yet sent data. |
| + | IOW: if we just close(sock) now, kernel can reset the TCP connection |
| + | (send RST packet). |
| + | |
| + | This is problematic for two reasons: it discards some not-yet sent |
| + | data, and it may be reported as error, not EOF, on peer's side. |
| What can be done about it? | |
| @@ -46,14 +49,14 @@ This makes kernel send FIN after all data is written: | |
| 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 |
| + | and if peer sends any data to us after this, kernel still 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(). |
| + | Solution #3: 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. | |
| @@ -61,6 +64,14 @@ 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. | |
| + | Solutions #1 and #2 can be combined: |
| + | |
| + | /* ...set up struct linger... then: */ |
| + | setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); |
| + | shutdown(sock, SHUT_WR); |
| + | /* At this point, kernel sent FIN packet, not RST, to the peer, */ |
| + | /* even if there is buffered read data from the peer. */ |
| + | close(sock); |
| Defeating Nagle. | |