aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-07-25 14:00:37 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-07-25 14:00:37 +0200
commit7801148a816a2ab1c2f9437c8992c86722361147 (patch)
tree1da9e43efdfdee33e9ada4bbf86ddcd551ade133 /docs
parent688a7e3f0454363e1dfed481e95afcdb818b1c91 (diff)
downloadbusybox-w32-7801148a816a2ab1c2f9437c8992c86722361147.tar.gz
busybox-w32-7801148a816a2ab1c2f9437c8992c86722361147.tar.bz2
busybox-w32-7801148a816a2ab1c2f9437c8992c86722361147.zip
Add notes about TCP programming quirks.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'docs')
-rw-r--r--docs/tcp.txt65
1 files changed, 65 insertions, 0 deletions
diff --git a/docs/tcp.txt b/docs/tcp.txt
new file mode 100644
index 000000000..7951e1c8b
--- /dev/null
+++ b/docs/tcp.txt
@@ -0,0 +1,65 @@
1 Some less-widely known details of TCP connections.
2
3 Properly closing the connection.
4
5After this code sequence:
6
7 sock = socket(AF_INET, SOCK_STREAM, 0);
8 connect(sock, &remote, sizeof(remote));
9 write(sock, buffer, 1000000);
10
11a large block of data is only buffered by kernel, it can't be sent all at once.
12What will happen if we close the socket?
13
14"A host MAY implement a 'half-duplex' TCP close sequence, so that
15 an application that has called close() cannot continue to read
16 data from the connection. If such a host issues a close() call
17 while received data is still pending in TCP, or if new data is
18 received after close() is called, its TCP SHOULD send a RST
19 to show that data was lost."
20
21IOW: if we just close(sock) now, kernel can reset the TCP connection,
22discarding some not-yet sent data.
23
24What can be done about it?
25
26Solution #1: block until sending is done:
27
28 /* When enabled, a close(2) or shutdown(2) will not return until
29 * all queued messages for the socket have been successfully sent
30 * or the linger timeout has been reached.
31 */
32 struct linger {
33 int l_onoff; /* linger active */
34 int l_linger; /* how many seconds to linger for */
35 } linger;
36 linger.l_onoff = 1;
37 linger.l_linger = SOME_NUM;
38 setsockopt(sock, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger));
39 close(sock);
40
41Solution #2: tell kernel that you are done sending.
42This makes kernel send FIN, not RST:
43
44 shutdown(sock, SHUT_WR);
45 close(sock);
46
47
48 Defeating Nagle.
49
50Method #1: manually control whether partial sends are allowed:
51
52This prevents partially filled packets being sent:
53
54 int state = 1;
55 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
56
57and this forces last, partially filled packet (if any) to be sent:
58
59 int state = 0;
60 setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
61
62Method #2: make any write to immediately send data, even if it's partial:
63
64 int state = 1;
65 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state));