1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// This file is part of linux-support. It is subject to the license terms in the COPYRIGHT file found in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/linux-support/master/COPYRIGHT. No part of linux-support, including this file, may be copied, modified, propagated, or distributed except according to the terms contained in the COPYRIGHT file.
// Copyright © 2020 The developers of linux-support. See the COPYRIGHT file in the top-level directory of this distribution and at https://raw.githubusercontent.com/lemonrock/linux-support/master/COPYRIGHT.
/// Back log can not exceed `i32::MAX`.
///
/// Back log is constrained globally by the maximum in `/proc/sys/net/core/somaxconn`.
/// The default in this file is `128`; this is also the constant `SOMAXCONN`.
///
/// Old, but informative, advice adapted from <https://tangentsoft.net/wskfaq/advanced.html#backlog>:-
///
/// "When a connection request comes into a network stack, it first checks to see if any program is listening on the requested port.
/// If so, the stack replies to the remote peer, completing the connection.
/// The stack stores the connection information in a queue called the connection backlog.
/// (When there are connections in the backlog, the accept() call simply causes the stack to remove the oldest connection from the connection backlog and return a socket for it).
///
/// One of the parameters to the listen() call sets the size of the connection backlog for a particular socket.
/// When the backlog fills up, the stack begins rejecting connection attempts.
///
/// Rejecting connections is a good thing if your program is written to accept new connections as fast as it reasonably can.
/// If the backlog fills up despite your program’s best efforts, it means your server has hit its load limit.
/// If the stack were to accept more connections, your program wouldn’t be able to handle them as well as it should, so the client will think your server is hanging.
/// At least if the connection is rejected, the client will know the server is too busy and will try again later.
///
/// The proper value for listen()’s backlog parameter depends on how many connections you expect to see in the time between accept() calls.
/// Let’s say you expect an average of 1000 connections per second, with a burst value of 3000 connections per second.
/// (I picked these values because they’re easy to manipulate, not because they’re representative of the real world)!
/// To handle the burst load with a short connection backlog, your server’s time between accept() calls must be under 0.3 milliseconds.
/// Let’s say you’ve measured your time-to-accept under load, and it’s 0.8 milliseconds: fast enough to handle the normal load, but too slow to handle your burst value.
/// In this case, you could make backlog relatively large to let the stack queue up connections under burst conditions.
/// Assuming that these bursts are short, your program will quickly catch up and clear out the connection backlog.
/// ///
/// If your program is quick about calling accept(), low backlog limits are not normally a problem.
/// However, it does mean that concerted attempts to make lots of connections in a short period of time can fill the backlog queue. This makes low backlog values a bad choice for a high-load server: either a legitimate load or a SYN flood attack can overload a server on such a platform.
///
/// Beware that large backlogs make SYN flood attacks much more, shall we say, effective.
/// (In Windows NT: since the backlog queue is in non-pageable system memory, a SYN flood can cause the queue to eat a lot of this precious memory resource).
///
/// You will note that SYN attacks are dangerous for systems with both very short and very long backlog queues.
/// The point is that a middle ground is the best course if you expect your server to withstand SYN attacks.
//
/// A program can rely too much on the backlog feature.
/// Consider a single-threaded blocking server: the design means it can only handle one connection at a time
/// However, it can set up a large backlog, making the stack accept and hold connections until the program gets around to handling the next one.
/// You should not take advantage of the feature this way unless your connection rate is very low and the connection times are very short.
;