aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/mhd_send.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/mhd_send.c')
-rw-r--r--src/microhttpd/mhd_send.c76
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;