Add notes about TCP programming quirks.
[platform/upstream/busybox.git] / docs / tcp.txt
1         Some less-widely known details of TCP connections.
2
3         Properly closing the connection.
4
5 After this code sequence:
6
7     sock = socket(AF_INET, SOCK_STREAM, 0);
8     connect(sock, &remote, sizeof(remote));
9     write(sock, buffer, 1000000);
10
11 a large block of data is only buffered by kernel, it can't be sent all at once.
12 What 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
21 IOW: if we just close(sock) now, kernel can reset the TCP connection,
22 discarding some not-yet sent data.
23
24 What can be done about it?
25
26 Solution #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
41 Solution #2: tell kernel that you are done sending.
42 This makes kernel send FIN, not RST:
43
44     shutdown(sock, SHUT_WR);
45     close(sock);
46
47
48         Defeating Nagle.
49
50 Method #1: manually control whether partial sends are allowed:
51
52 This prevents partially filled packets being sent:
53
54     int state = 1;
55     setsockopt(fd, IPPROTO_TCP, TCP_CORK, &state, sizeof(state));
56
57 and 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
62 Method #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));