GNU libmicrohttpd  0.9.72
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 
34 const char*
35 MHD_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 
243 int
244 MHD_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 
370 int
372  fd_set *set,
373  MHD_socket *max_fd,
374  unsigned int fd_setsize)
375 {
376  if ( (NULL == set) ||
377  (MHD_INVALID_SOCKET == fd) )
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 
400 int
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 
435 int
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 
470 int
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 
499 int
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(_MHD_CORK_RESET_PUSH_DATA)
520  return 1;
521 #else /* ! _MHD_CORK_RESET_PUSH_DATA */
522  if (! on)
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  return 1;
536 #endif /* ! _MHD_CORK_RESET_PUSH_DATA */
537 #else /* ! MHD_TCP_CORK_NOPUSH */
538  /* do not have MHD_TCP_CORK_NOPUSH at all */
539  (void) sock; (void) on; /* Mute compiler warnings */
540  return 0;
541 #endif /* ! MHD_TCP_CORK_NOPUSH */
542 }
543 
544 
551 int
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 {
579  MHD_socket fd;
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 | SOCK_NOSIGPIPE_OR_ZERO,
589  0);
590  if (MHD_INVALID_SOCKET != fd)
591  {
592  cloexec_set = (SOCK_CLOEXEC_OR_ZERO != 0);
593 #if defined(SOCK_NOSIGPIPE) || defined(MHD_socket_nosignal_)
594  nosigpipe_set = (SOCK_NOSIGPIPE_OR_ZERO != 0);
595 #endif /* SOCK_NOSIGPIPE || MHD_socket_nosignal_ */
596  }
597 #elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
598  fd = WSASocketW (pf,
599  SOCK_STREAM,
600  0,
601  NULL,
602  0,
603  WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
604  cloexec_set = ! 0;
605 #else /* !SOCK_CLOEXEC */
607 #endif /* !SOCK_CLOEXEC */
608  if (MHD_INVALID_SOCKET == fd)
609  {
610  fd = socket (pf,
611  SOCK_STREAM,
612  0);
613  cloexec_set = 0;
614 #if defined(SOCK_NOSIGPIPE) || defined(MHD_socket_nosignal_)
615  nosigpipe_set = 0;
616 #endif /* SOCK_NOSIGPIPE || MHD_socket_nosignal_ */
617  }
618  if (MHD_INVALID_SOCKET == fd)
619  return MHD_INVALID_SOCKET;
620 
621 #if defined(MHD_socket_nosignal_)
622  if ( (! nosigpipe_set) &&
623  (0 == MHD_socket_nosignal_ (fd)) &&
624  (0 == MSG_NOSIGNAL_OR_ZERO) )
625  {
626  /* SIGPIPE disable is possible on this platform
627  * (so application expect that it will be disabled),
628  * but failed to be disabled here and it is not
629  * possible to disable SIGPIPE by MSG_NOSIGNAL. */
630  const int err = MHD_socket_get_error_ ();
631  (void) MHD_socket_close_ (fd);
633  return MHD_INVALID_SOCKET;
634  }
635 #endif /* defined(MHD_socket_nosignal_) */
636  if (! cloexec_set)
638 
639  return fd;
640 }
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 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 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 SOCK_NOSIGPIPE_OR_ZERO
Definition: mhd_sockets.h:178
#define MSG_NOSIGNAL_OR_ZERO
Definition: mhd_sockets.h:184
#define SOCK_CLOEXEC_OR_ZERO
Definition: mhd_sockets.h:166
int MHD_socket
Definition: microhttpd.h:196
int fd
Definition: microhttpd.h:3195
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:197