GNU libmicrohttpd 0.9.71
mhd_sockets.c
Go to the documentation of this file.
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2014-2016 Karlson2k (Evgeny Grin)
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
19*/
25#include "mhd_sockets.h"
26
27#ifdef MHD_WINSOCK_SOCKETS
28
34const char*
35MHD_W32_strerror_winsock_ (int err)
36{
37 switch (err)
38 {
39 case 0:
40 return "No error";
41 case WSA_INVALID_HANDLE:
42 return "Specified event object handle is invalid";
43 case WSA_NOT_ENOUGH_MEMORY:
44 return "Insufficient memory available";
45 case WSA_INVALID_PARAMETER:
46 return "One or more parameters are invalid";
47 case WSA_OPERATION_ABORTED:
48 return "Overlapped operation aborted";
49 case WSA_IO_INCOMPLETE:
50 return "Overlapped I/O event object not in signaled state";
51 case WSA_IO_PENDING:
52 return "Overlapped operations will complete later";
53 case WSAEINTR:
54 return "Interrupted function call";
55 case WSAEBADF:
56 return "File handle is not valid";
57 case WSAEACCES:
58 return "Permission denied";
59 case WSAEFAULT:
60 return "Bad address";
61 case WSAEINVAL:
62 return "Invalid argument";
63 case WSAEMFILE:
64 return "Too many open files";
65 case WSAEWOULDBLOCK:
66 return "Resource temporarily unavailable";
67 case WSAEINPROGRESS:
68 return "Operation now in progress";
69 case WSAEALREADY:
70 return "Operation already in progress";
71 case WSAENOTSOCK:
72 return "Socket operation on nonsocket";
73 case WSAEDESTADDRREQ:
74 return "Destination address required";
75 case WSAEMSGSIZE:
76 return "Message too long";
77 case WSAEPROTOTYPE:
78 return "Protocol wrong type for socket";
79 case WSAENOPROTOOPT:
80 return "Bad protocol option";
81 case WSAEPROTONOSUPPORT:
82 return "Protocol not supported";
83 case WSAESOCKTNOSUPPORT:
84 return "Socket type not supported";
85 case WSAEOPNOTSUPP:
86 return "Operation not supported";
87 case WSAEPFNOSUPPORT:
88 return "Protocol family not supported";
89 case WSAEAFNOSUPPORT:
90 return "Address family not supported by protocol family";
91 case WSAEADDRINUSE:
92 return "Address already in use";
93 case WSAEADDRNOTAVAIL:
94 return "Cannot assign requested address";
95 case WSAENETDOWN:
96 return "Network is down";
97 case WSAENETUNREACH:
98 return "Network is unreachable";
99 case WSAENETRESET:
100 return "Network dropped connection on reset";
101 case WSAECONNABORTED:
102 return "Software caused connection abort";
103 case WSAECONNRESET:
104 return "Connection reset by peer";
105 case WSAENOBUFS:
106 return "No buffer space available";
107 case WSAEISCONN:
108 return "Socket is already connected";
109 case WSAENOTCONN:
110 return "Socket is not connected";
111 case WSAESHUTDOWN:
112 return "Cannot send after socket shutdown";
113 case WSAETOOMANYREFS:
114 return "Too many references";
115 case WSAETIMEDOUT:
116 return "Connection timed out";
117 case WSAECONNREFUSED:
118 return "Connection refused";
119 case WSAELOOP:
120 return "Cannot translate name";
121 case WSAENAMETOOLONG:
122 return "Name too long";
123 case WSAEHOSTDOWN:
124 return "Host is down";
125 case WSAEHOSTUNREACH:
126 return "No route to host";
127 case WSAENOTEMPTY:
128 return "Directory not empty";
129 case WSAEPROCLIM:
130 return "Too many processes";
131 case WSAEUSERS:
132 return "User quota exceeded";
133 case WSAEDQUOT:
134 return "Disk quota exceeded";
135 case WSAESTALE:
136 return "Stale file handle reference";
137 case WSAEREMOTE:
138 return "Item is remote";
139 case WSASYSNOTREADY:
140 return "Network subsystem is unavailable";
141 case WSAVERNOTSUPPORTED:
142 return "Winsock.dll version out of range";
143 case WSANOTINITIALISED:
144 return "Successful WSAStartup not yet performed";
145 case WSAEDISCON:
146 return "Graceful shutdown in progress";
147 case WSAENOMORE:
148 return "No more results";
149 case WSAECANCELLED:
150 return "Call has been canceled";
151 case WSAEINVALIDPROCTABLE:
152 return "Procedure call table is invalid";
153 case WSAEINVALIDPROVIDER:
154 return "Service provider is invalid";
155 case WSAEPROVIDERFAILEDINIT:
156 return "Service provider failed to initialize";
157 case WSASYSCALLFAILURE:
158 return "System call failure";
159 case WSASERVICE_NOT_FOUND:
160 return "Service not found";
161 case WSATYPE_NOT_FOUND:
162 return "Class type not found";
163 case WSA_E_NO_MORE:
164 return "No more results";
165 case WSA_E_CANCELLED:
166 return "Call was canceled";
167 case WSAEREFUSED:
168 return "Database query was refused";
169 case WSAHOST_NOT_FOUND:
170 return "Host not found";
171 case WSATRY_AGAIN:
172 return "Nonauthoritative host not found";
173 case WSANO_RECOVERY:
174 return "This is a nonrecoverable error";
175 case WSANO_DATA:
176 return "Valid name, no data record of requested type";
177 case WSA_QOS_RECEIVERS:
178 return "QoS receivers";
179 case WSA_QOS_SENDERS:
180 return "QoS senders";
181 case WSA_QOS_NO_SENDERS:
182 return "No QoS senders";
183 case WSA_QOS_NO_RECEIVERS:
184 return "QoS no receivers";
185 case WSA_QOS_REQUEST_CONFIRMED:
186 return "QoS request confirmed";
187 case WSA_QOS_ADMISSION_FAILURE:
188 return "QoS admission error";
189 case WSA_QOS_POLICY_FAILURE:
190 return "QoS policy failure";
191 case WSA_QOS_BAD_STYLE:
192 return "QoS bad style";
193 case WSA_QOS_BAD_OBJECT:
194 return "QoS bad object";
195 case WSA_QOS_TRAFFIC_CTRL_ERROR:
196 return "QoS traffic control error";
197 case WSA_QOS_GENERIC_ERROR:
198 return "QoS generic error";
199 case WSA_QOS_ESERVICETYPE:
200 return "QoS service type error";
201 case WSA_QOS_EFLOWSPEC:
202 return "QoS flowspec error";
203 case WSA_QOS_EPROVSPECBUF:
204 return "Invalid QoS provider buffer";
205 case WSA_QOS_EFILTERSTYLE:
206 return "Invalid QoS filter style";
207 case WSA_QOS_EFILTERTYPE:
208 return "Invalid QoS filter type";
209 case WSA_QOS_EFILTERCOUNT:
210 return "Incorrect QoS filter count";
211 case WSA_QOS_EOBJLENGTH:
212 return "Invalid QoS object length";
213 case WSA_QOS_EFLOWCOUNT:
214 return "Incorrect QoS flow count";
215 case WSA_QOS_EUNKOWNPSOBJ:
216 return "Unrecognized QoS object";
217 case WSA_QOS_EPOLICYOBJ:
218 return "Invalid QoS policy object";
219 case WSA_QOS_EFLOWDESC:
220 return "Invalid QoS flow descriptor";
221 case WSA_QOS_EPSFLOWSPEC:
222 return "Invalid QoS provider-specific flowspec";
223 case WSA_QOS_EPSFILTERSPEC:
224 return "Invalid QoS provider-specific filterspec";
225 case WSA_QOS_ESDMODEOBJ:
226 return "Invalid QoS shape discard mode object";
227 case WSA_QOS_ESHAPERATEOBJ:
228 return "Invalid QoS shaping rate object";
229 case WSA_QOS_RESERVED_PETYPE:
230 return "Reserved policy QoS element type";
231 }
232 return "Unknown winsock error";
233}
234
235
243int
244MHD_W32_socket_pair_ (SOCKET sockets_pair[2], int non_blk)
245{
246 int i;
247
248 if (! sockets_pair)
249 {
250 WSASetLastError (WSAEFAULT);
251 return 0;
252 }
253
254#define PAIRMAXTRYIES 800
255 for (i = 0; i < PAIRMAXTRYIES; i++)
256 {
257 struct sockaddr_in listen_addr;
258 SOCKET listen_s;
259 static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
260 int addr_len = c_addinlen;
261 unsigned long on_val = 1;
262 unsigned long off_val = 0;
263
264 listen_s = socket (AF_INET,
265 SOCK_STREAM,
266 IPPROTO_TCP);
267 if (INVALID_SOCKET == listen_s)
268 break; /* can't create even single socket */
269
270 listen_addr.sin_family = AF_INET;
271 listen_addr.sin_port = 0; /* same as htons(0) */
272 listen_addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
273 if ( ((0 == bind (listen_s,
274 (struct sockaddr*) &listen_addr,
275 c_addinlen)) &&
276 (0 == listen (listen_s,
277 1) ) &&
278 (0 == getsockname (listen_s,
279 (struct sockaddr*) &listen_addr,
280 &addr_len))) )
281 {
282 SOCKET client_s = socket (AF_INET,
283 SOCK_STREAM,
284 IPPROTO_TCP);
285 struct sockaddr_in accepted_from_addr;
286 struct sockaddr_in client_addr;
287 SOCKET server_s;
288
289 if (INVALID_SOCKET == client_s)
290 {
291 /* try again */
292 closesocket (listen_s);
293 continue;
294 }
295
296 if ( (0 != ioctlsocket (client_s,
297 FIONBIO,
298 &on_val)) ||
299 ( (0 != connect (client_s,
300 (struct sockaddr*) &listen_addr,
301 c_addinlen)) &&
302 (WSAGetLastError () != WSAEWOULDBLOCK)) )
303 {
304 /* try again */
305 closesocket (listen_s);
306 closesocket (client_s);
307 continue;
308 }
309
310 addr_len = c_addinlen;
311 server_s = accept (listen_s,
312 (struct sockaddr*) &accepted_from_addr,
313 &addr_len);
314 if (INVALID_SOCKET == server_s)
315 {
316 /* try again */
317 closesocket (listen_s);
318 closesocket (client_s);
319 continue;
320 }
321
322 addr_len = c_addinlen;
323 if ( (0 == getsockname (client_s,
324 (struct sockaddr*) &client_addr,
325 &addr_len)) &&
326 (accepted_from_addr.sin_family == client_addr.sin_family) &&
327 (accepted_from_addr.sin_port == client_addr.sin_port) &&
328 (accepted_from_addr.sin_addr.s_addr ==
329 client_addr.sin_addr.s_addr) &&
330 ( (0 != non_blk) ?
331 (0 == ioctlsocket (server_s,
332 FIONBIO,
333 &on_val)) :
334 (0 == ioctlsocket (client_s,
335 FIONBIO,
336 &off_val)) ) )
337 {
338 closesocket (listen_s);
339 sockets_pair[0] = server_s;
340 sockets_pair[1] = client_s;
341 return ! 0;
342 }
343 closesocket (server_s);
344 closesocket (client_s);
345 }
346 closesocket (listen_s);
347 }
348
349 sockets_pair[0] = INVALID_SOCKET;
350 sockets_pair[1] = INVALID_SOCKET;
351 WSASetLastError (WSAECONNREFUSED);
352
353 return 0;
354}
355
356
357#endif /* MHD_WINSOCK_SOCKETS */
358
359
370int
372 fd_set *set,
373 MHD_socket *max_fd,
374 unsigned int fd_setsize)
375{
376 if ( (NULL == set) ||
378 return 0;
380 set,
381 fd_setsize))
382 return 0;
384 set,
385 fd_setsize);
386 if ( (NULL != max_fd) &&
387 ( (fd > *max_fd) ||
388 (MHD_INVALID_SOCKET == *max_fd) ) )
389 *max_fd = fd;
390 return ! 0;
391}
392
393
400int
402{
403#if defined(MHD_POSIX_SOCKETS)
404 int flags;
405
406 flags = fcntl (sock,
407 F_GETFL);
408 if (-1 == flags)
409 return 0;
410
411 if ( ((flags | O_NONBLOCK) != flags) &&
412 (0 != fcntl (sock,
413 F_SETFL,
414 flags | O_NONBLOCK)) )
415 return 0;
416#elif defined(MHD_WINSOCK_SOCKETS)
417 unsigned long flags = 1;
418
419 if (0 != ioctlsocket (sock,
420 FIONBIO,
421 &flags))
422 return 0;
423#endif /* MHD_WINSOCK_SOCKETS */
424 return ! 0;
425}
426
427
435int
437{
438#if defined(MHD_POSIX_SOCKETS)
439 int flags;
440
441 flags = fcntl (sock,
442 F_GETFD);
443 if (-1 == flags)
444 return 0;
445
446 if ( ((flags | FD_CLOEXEC) != flags) &&
447 (0 != fcntl (sock,
448 F_SETFD,
449 flags | FD_CLOEXEC)) )
450 return 0;
451#elif defined(MHD_WINSOCK_SOCKETS)
452 if (! SetHandleInformation ((HANDLE) sock,
453 HANDLE_FLAG_INHERIT,
454 0))
455 return 0;
456#endif /* MHD_WINSOCK_SOCKETS */
457 return ! 0;
458}
459
460
470int
472 bool on)
473{
474#ifdef TCP_NODELAY
475 {
476 const MHD_SCKT_OPT_BOOL_ off_val = 0;
477 const MHD_SCKT_OPT_BOOL_ on_val = 1;
478 /* Disable Nagle's algorithm for normal buffering */
479 return setsockopt (sock,
480 IPPROTO_TCP,
481 TCP_NODELAY,
482 (const void *) (on) ? &on_val : &off_val,
483 sizeof (on_val));
484 }
485#else
486 (void) sock;
487 return 0;
488#endif /* TCP_NODELAY */
489}
490
491
499int
501 bool on)
502{
503#if defined(MHD_TCP_CORK_NOPUSH)
504 const MHD_SCKT_OPT_BOOL_ off_val = 0;
505 const MHD_SCKT_OPT_BOOL_ on_val = 1;
506
507 /* Disable extra buffering */
508 if (MHD_INVALID_SOCKET == sock)
509 {
510 errno = EBADF;
511 return 0; /* failed */
512 }
513 if (0 != setsockopt (sock,
514 IPPROTO_TCP,
515 MHD_TCP_CORK_NOPUSH,
516 (const void *) (on ? &on_val : &off_val),
517 sizeof (off_val)))
518 return 0; /* failed */
519#if defined(__FreeBSD__) && __FreeBSD__ + 0 >= 9
520 /* FreeBSD do not need zero-send for flushing starting from version 9 */
521 return 1;
522#elif defined(TCP_NOPUSH) && ! defined(TCP_CORK)
523 {
524 const int dummy = 0;
525 /* Force flush data with zero send otherwise Darwin and some BSD systems
526 will add 5 seconds delay. Not required with TCP_CORK as switching off
527 TCP_CORK always flushes socket buffer. */
528 if (0 > send (sock,
529 &dummy,
530 0,
531 0))
532 return 0; /* even force flush failed!? */
533 return 1; /* success */
534 }
535#else
536 return 1; /* success */
537#endif
538#else
539 /* do not have MHD_TCP_CORK_NOPUSH at all */
540 return 0;
541#endif
542}
543
544
551int
553{
554#if defined(MHD_TCP_CORK_NOPUSH)
555 int res = ! MHD_socket_set_nodelay_ (sock,
556 true);
557 /* Disable extra buffering */
558 return MHD_socket_cork_ (sock,
559 false) && res;
560#elif defined(HAVE_MSG_MORE)
561 return ! MHD_socket_set_nodelay_ (sock,
562 true);
563#else
564 return ! MHD_socket_set_nodelay_ (sock,
565 false);
566#endif /* MHD_TCP_CORK_NOPUSH */
567}
568
569
578{
580 int cloexec_set;
581#if defined(SOCK_NOSIGPIPE) || defined(MHD_socket_nosignal_)
582 int nosigpipe_set;
583#endif /* SOCK_NOSIGPIPE || MHD_socket_nosignal_ */
584
585#if defined(MHD_POSIX_SOCKETS) && (defined(SOCK_CLOEXEC) || \
586 defined(SOCK_NOSIGPIPE) )
587 fd = socket (pf,
588 SOCK_STREAM | SOCK_CLOEXEC | MAYBE_SOCK_NOSIGPIPE,
589 0);
590 cloexec_set = (MAYBE_SOCK_CLOEXEC != 0);
591#if defined(SOCK_NOSIGPIPE) || defined(MHD_socket_nosignal_)
592 nosigpipe_set = (MAYBE_SOCK_NOSIGPIPE != 0);
593#endif /* SOCK_NOSIGPIPE || MHD_socket_nosignal_ */
594#elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
595 fd = WSASocketW (pf,
596 SOCK_STREAM,
597 0,
598 NULL,
599 0,
600 WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
601 cloexec_set = ! 0;
602#else /* !SOCK_CLOEXEC */
604#endif /* !SOCK_CLOEXEC */
605 if (MHD_INVALID_SOCKET == fd)
606 {
607 fd = socket (pf,
608 SOCK_STREAM,
609 0);
610 cloexec_set = 0;
611 }
612 if (MHD_INVALID_SOCKET == fd)
613 return MHD_INVALID_SOCKET;
614
615#if defined(MHD_socket_nosignal_)
616 if ( (! nosigpipe_set) &&
617 (0 == MHD_socket_nosignal_ (fd)) &&
618 (0 == MAYBE_MSG_NOSIGNAL) )
619 {
620 /* SIGPIPE disable is possible on this platform
621 * (so application expect that it will be disabled),
622 * but failed to be disabled here and it is not
623 * possible to disable SIGPIPE by MSG_NOSIGNAL. */
624 const int err = MHD_socket_get_error_ ();
625 (void) MHD_socket_close_ (fd);
627 return MHD_INVALID_SOCKET;
628 }
629#endif /* defined(MHD_socket_nosignal_) */
630 if (! cloexec_set)
632
633 return fd;
634}
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: mhd_sockets.c:377
int MHD_socket_noninheritable_(MHD_socket sock)
Definition: mhd_sockets.c:442
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:407
MHD_socket MHD_socket_create_listen_(int pf)
Definition: mhd_sockets.c:474
#define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd, pset, setsize)
Definition: mhd_sockets.h:287
#define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd, pset, setsize)
Definition: mhd_sockets.h:322
int MHD_SCKT_OPT_BOOL_
Definition: mhd_sockets.h:203
#define MAYBE_MSG_NOSIGNAL
Definition: mhd_sockets.h:169
#define MHD_socket_close_(fd)
Definition: mhd_sockets.h:238
#define MHD_socket_get_error_()
Definition: mhd_sockets.h:523
#define MHD_socket_fset_error_(err)
Definition: mhd_sockets.h:555
#define MAYBE_SOCK_CLOEXEC
Definition: mhd_sockets.h:157
#define NULL
Definition: reason_phrase.c:30
int MHD_socket_cork_(MHD_socket sock, bool on)
Definition: mhd_sockets.c:500
int MHD_socket_buffering_reset_(MHD_socket sock)
Definition: mhd_sockets.c:552
int MHD_socket_set_nodelay_(MHD_socket sock, bool on)
Definition: mhd_sockets.c:471
#define MAYBE_SOCK_NOSIGPIPE
Definition: mhd_sockets.h:174
int MHD_socket
Definition: microhttpd.h:195
int fd
Definition: microhttpd.h:3166
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:196