diff options
Diffstat (limited to 'src/microhttpd/mhd_send.c')
-rw-r--r-- | src/microhttpd/mhd_send.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/src/microhttpd/mhd_send.c b/src/microhttpd/mhd_send.c index 6c080ccb..923fcae4 100644 --- a/src/microhttpd/mhd_send.c +++ b/src/microhttpd/mhd_send.c | |||
@@ -30,6 +30,13 @@ | |||
30 | // TODO: sendfile() wrappers. | 30 | // TODO: sendfile() wrappers. |
31 | 31 | ||
32 | #include "platform.h" | 32 | #include "platform.h" |
33 | #include "internal.h" | ||
34 | |||
35 | #ifdef HAVE_STDBOOL_H | ||
36 | #include <stdbool.h> | ||
37 | #endif | ||
38 | #include <errno.h> | ||
39 | |||
33 | 40 | ||
34 | // NOTE: TCP_CORK == TCP_NOPUSH in FreeBSD. | 41 | // NOTE: TCP_CORK == TCP_NOPUSH in FreeBSD. |
35 | // TCP_CORK is Linux. | 42 | // TCP_CORK is Linux. |
@@ -98,6 +105,7 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, | |||
98 | bool want_cork, have_cork, have_more; | 105 | bool want_cork, have_cork, have_more; |
99 | /* The socket. */ | 106 | /* The socket. */ |
100 | MHD_socket s = connection->socket_fd; | 107 | MHD_socket s = connection->socket_fd; |
108 | int eno, ret, optval; | ||
101 | 109 | ||
102 | // new code... | 110 | // new code... |
103 | /* Get socket options, change/set options if necessary. */ | 111 | /* Get socket options, change/set options if necessary. */ |
@@ -128,29 +136,29 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, | |||
128 | 136 | ||
129 | bool use_corknopush; | 137 | bool use_corknopush; |
130 | 138 | ||
131 | #if HAVE_NODELAY | 139 | #if TCP_NODELAY |
132 | use_corknopush = false; | 140 | use_corknopush = false; |
133 | #elif HAVE_CORK | 141 | #elif TCP_CORK |
134 | use_corknopush = true; | 142 | use_corknopush = true; |
135 | #elif HAVE_NOPUSH | 143 | #elif TCP_NOPUSH |
136 | use_corknopush = true; | 144 | use_corknopush = true; |
137 | #endif | 145 | #endif |
138 | 146 | ||
139 | #if HAVE_CORK | 147 | #if TCP_CORK |
140 | if (use_corknopush) | 148 | if (use_corknopush) |
141 | { | 149 | { |
142 | if (have_cork && ! want_cork) | 150 | if (have_cork && ! want_cork) |
143 | { | 151 | { |
144 | setsockopt (s, IPPROTO_TCP, TCP_CORK, 1, sizeof (int)) || | 152 | optval = 1; |
145 | (setsockopt (s, IPPROTO_TCP, TCP_NODELAY, 1, sizeof (int)) &&connection | 153 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &optval, sizeof (&optval)) || |
146 | ->sk_tcp_nodelay = true); | 154 | (setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (&optval)) && (connection->sk_tcp_nodelay = true)); |
147 | //setsockopt (cork-on); // or nodelay on // + update connection->sk_tcp_nodelay_on | 155 | //setsockopt (cork-on); // or nodelay on // + update connection->sk_tcp_nodelay_on |
148 | // When we have CORK, we can have NODELAY on the same system, | 156 | // When we have CORK, we can have NODELAY on the same system, |
149 | // at least since Linux 2.2 and both can be combined since | 157 | // at least since Linux 2.2 and both can be combined since |
150 | // Linux 2.5.71. See tcp(7). No other system in 2019-06 has TCP_CORK. | 158 | // Linux 2.5.71. See tcp(7). No other system in 2019-06 has TCP_CORK. |
151 | } | 159 | } |
152 | } | 160 | } |
153 | #elif HAVE_NOPUSH | 161 | #elif TCP_NOPUSH |
154 | /* | 162 | /* |
155 | * TCP_NOPUSH on FreeBSD is equal to cork on Linux, with the | 163 | * TCP_NOPUSH on FreeBSD is equal to cork on Linux, with the |
156 | * exception that we know that TCP_NOPUSH will definitely | 164 | * exception that we know that TCP_NOPUSH will definitely |
@@ -160,40 +168,42 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, | |||
160 | { | 168 | { |
161 | if (have_cork && ! want_cork) | 169 | if (have_cork && ! want_cork) |
162 | { | 170 | { |
163 | setsockopt (s, IPPROTO_TCP, TCP_NOPUSH, 1, sizeof (int)); | 171 | optval = 1; |
172 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NOPUSH, &optval, sizeof (&optval)); | ||
164 | // TODO: set corknopush to true here? | 173 | // TODO: set corknopush to true here? |
165 | // connection->sk_tcp_cork_nopush_on = true; | 174 | // connection->sk_tcp_cork_nopush_on = true; |
166 | } | 175 | } |
167 | } | 176 | } |
168 | #endif | 177 | #endif |
169 | #if HAVE_NODELAY | 178 | #if TCP_NODELAY |
170 | if (! use_corknopush) | 179 | if (! use_corknopush) |
171 | { | 180 | { |
172 | if (! have_cork && want_cork) | 181 | if (! have_cork && want_cork) |
173 | { | 182 | { |
183 | optval = 0; | ||
174 | // setsockopt (nodelay-off); | 184 | // setsockopt (nodelay-off); |
175 | setsockopt (s, IPPROTO_TCP, TCP_NODELAY, 0, sizeof (int)); | 185 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (&optval)); |
176 | connection->sk_tcp_nodelay = false; | 186 | connection->sk_tcp_nodelay_on = false; |
177 | } | 187 | } |
178 | // ... | 188 | // ... |
179 | } | 189 | } |
180 | #endif | 190 | #endif |
181 | 191 | ||
182 | 192 | ||
183 | ret = send (s, buffer, buffer_size, want_cork ? MSG_MORE : 0); | 193 | ret = send (connection->socket_fd, buffer, buffer_size, want_cork ? MSG_MORE : 0); |
184 | eno = errno; | 194 | eno = errno; |
185 | #if HAVE_CORK | 195 | #if TCP_CORK |
186 | if (use_corknopush) | 196 | if (use_corknopush) |
187 | { | 197 | { |
188 | if (! have_cork && want_cork && ! have_more) | 198 | if (! have_cork && want_cork && ! have_more) |
189 | { | 199 | { |
200 | optval = 0; | ||
190 | //setsockopt (cork-off); // or nodelay off // + update connection->sk_tcp_nodelay_on | 201 | //setsockopt (cork-off); // or nodelay off // + update connection->sk_tcp_nodelay_on |
191 | setsockopt (s, IPPROTO_TCP, TCP_CORK, 0, sizeof (int)) || | 202 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &optval, sizeof (&optval)) || |
192 | (setsockopt (s, IPPROTO_TCP, TCP_NODELAY, 0, sizeof (int)) &&connection | 203 | (setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (&optval)) && (connection->sk_tcp_nodelay_on = false)); |
193 | ->sk_tcp_nodelay_on = false); | ||
194 | } | 204 | } |
195 | } | 205 | } |
196 | #elif HAVE_NOPUSH | 206 | #elif TCP_NOPUSH |
197 | // We don't have MSG_MORE. | 207 | // We don't have MSG_MORE. |
198 | if (use_corknopush) | 208 | if (use_corknopush) |
199 | { | 209 | { |
@@ -201,17 +211,18 @@ MHD_send_on_connection_ (struct MHD_Connection *connection, | |||
201 | } | 211 | } |
202 | #endif | 212 | #endif |
203 | 213 | ||
204 | #if HAVE_NODELAY | 214 | #if TCP_NODELAY |
205 | if (! use_corknopush) | 215 | if (! use_corknopush) |
206 | { | 216 | { |
207 | if (have_cork && ! want_cork) | 217 | if (have_cork && ! want_cork) |
208 | { | 218 | { |
219 | optval = 1; | ||
209 | // setsockopt (nodelay - on); | 220 | // setsockopt (nodelay - on); |
210 | setsockopt (s, | 221 | setsockopt (connection->socket_fd, |
211 | IPPROTO_TCP, | 222 | IPPROTO_TCP, |
212 | TCP_NODELAY, | 223 | TCP_NODELAY, |
213 | 1, | 224 | &optval, |
214 | sizeof (int)) &&connection->sk_tcp_nodelay_on = true; | 225 | sizeof (&optval)) && (connection->sk_tcp_nodelay_on = true); |
215 | } | 226 | } |
216 | // ... | 227 | // ... |
217 | } | 228 | } |
@@ -239,26 +250,26 @@ MHD_send_on_connection2_ (struct MHD_Connection *connection, | |||
239 | #if HAVE_WRITEV | 250 | #if HAVE_WRITEV |
240 | MHD_socket s = connection->socket_fd; | 251 | MHD_socket s = connection->socket_fd; |
241 | bool have_cork, have_more; | 252 | bool have_cork, have_more; |
242 | int iovcnt; | 253 | int iovcnt, optval; |
243 | struct iovec vector[2]; | 254 | struct iovec vector[2]; |
244 | 255 | ||
245 | have_cork = ! connection->sk_tcp_nodelay_on; | 256 | have_cork = ! connection->sk_tcp_nodelay_on; |
246 | #if HAVE_NODELAY | 257 | #if TCP_NODELAY |
247 | use_corknopush = false; | 258 | use_corknopush = false; |
248 | #elif HAVE_CORK | 259 | #elif TCP_CORK |
249 | use_corknopush = true; | 260 | use_corknopush = true; |
250 | #elif HAVE_NOPUSH | 261 | #elif TCP_NOPUSH |
251 | use_corknopush = true; | 262 | use_corknopush = true; |
252 | #endif | 263 | #endif |
253 | 264 | ||
254 | #if HAVE_NODELAY | 265 | #if TCP_NODELAY |
255 | if (! use_corknopush) | 266 | if (! use_corknopush) |
256 | { | 267 | { |
257 | if (! have_cork && want_cork) | 268 | if (! have_cork && want_cork) |
258 | { | 269 | { |
270 | optval = 0; | ||
259 | // setsockopt (nodelay-off); | 271 | // setsockopt (nodelay-off); |
260 | setsockopt (s, IPPROTO_TCP, TCP_NODELAY, 0, sizeof (int)); | 272 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof (&optval)) && (connection->sk_tcp_nodelay = false); |
261 | connection->sk_tcp_nodelay = false; | ||
262 | } | 273 | } |
263 | // ... | 274 | // ... |
264 | } | 275 | } |
@@ -269,17 +280,18 @@ MHD_send_on_connection2_ (struct MHD_Connection *connection, | |||
269 | vector[1].iov_base = buffer; | 280 | vector[1].iov_base = buffer; |
270 | vector[1].iov_len = strlen (buffer); | 281 | vector[1].iov_len = strlen (buffer); |
271 | iovcnt = sizeof (vector) / sizeof (struct iovec); | 282 | iovcnt = sizeof (vector) / sizeof (struct iovec); |
272 | ret = writev (s, vector, iovcnt); | 283 | ret = writev (connection->socket_fd, vector, iovcnt); |
273 | #if HAVE_CORK | 284 | #if TCP_CORK |
274 | { | 285 | { |
275 | int eno; | 286 | int eno; |
276 | 287 | ||
277 | eno = errno; | 288 | eno = errno; |
278 | if ((ret == header_len + buffer_len) && have_cork) | 289 | if ((ret == header_len + buffer_len) && have_cork) |
279 | { | 290 | { |
291 | optval = 0; | ||
280 | // response complete, definitely uncork! | 292 | // response complete, definitely uncork! |
281 | // setsockopt (cork-off); | 293 | // setsockopt (cork-off); |
282 | setsockopt (s, IPPROTO_TCP, TCP_CORK, 0, sizeof (int)); | 294 | setsockopt (connection->socket_fd, IPPROTO_TCP, TCP_CORK, &optval, sizeof (&optval)); |
283 | // connection->sk_tcp_cork_nopush_on = true; | 295 | // connection->sk_tcp_cork_nopush_on = true; |
284 | } | 296 | } |
285 | errno = eno; | 297 | errno = eno; |