GNU libmicrohttpd  0.9.29
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 */
20 
27 #include "mhd_sockets.h"
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif /* HAVE_UNISTD_H */
31 #include <fcntl.h>
32 
33 #ifdef MHD_WINSOCK_SOCKETS
34 
40 const char* MHD_W32_strerror_winsock_(int err)
41 {
42  switch (err)
43  {
44  case 0:
45  return "No error";
46  case WSA_INVALID_HANDLE:
47  return "Specified event object handle is invalid";
48  case WSA_NOT_ENOUGH_MEMORY:
49  return "Insufficient memory available";
50  case WSA_INVALID_PARAMETER:
51  return "One or more parameters are invalid";
52  case WSA_OPERATION_ABORTED:
53  return "Overlapped operation aborted";
54  case WSA_IO_INCOMPLETE:
55  return "Overlapped I/O event object not in signaled state";
56  case WSA_IO_PENDING:
57  return "Overlapped operations will complete later";
58  case WSAEINTR:
59  return "Interrupted function call";
60  case WSAEBADF:
61  return "File handle is not valid";
62  case WSAEACCES:
63  return "Permission denied";
64  case WSAEFAULT:
65  return "Bad address";
66  case WSAEINVAL:
67  return "Invalid argument";
68  case WSAEMFILE:
69  return "Too many open files";
70  case WSAEWOULDBLOCK:
71  return "Resource temporarily unavailable";
72  case WSAEINPROGRESS:
73  return "Operation now in progress";
74  case WSAEALREADY:
75  return "Operation already in progress";
76  case WSAENOTSOCK:
77  return "Socket operation on nonsocket";
78  case WSAEDESTADDRREQ:
79  return "Destination address required";
80  case WSAEMSGSIZE:
81  return "Message too long";
82  case WSAEPROTOTYPE:
83  return "Protocol wrong type for socket";
84  case WSAENOPROTOOPT:
85  return "Bad protocol option";
86  case WSAEPROTONOSUPPORT:
87  return "Protocol not supported";
88  case WSAESOCKTNOSUPPORT:
89  return "Socket type not supported";
90  case WSAEOPNOTSUPP:
91  return "Operation not supported";
92  case WSAEPFNOSUPPORT:
93  return "Protocol family not supported";
94  case WSAEAFNOSUPPORT:
95  return "Address family not supported by protocol family";
96  case WSAEADDRINUSE:
97  return "Address already in use";
98  case WSAEADDRNOTAVAIL:
99  return "Cannot assign requested address";
100  case WSAENETDOWN:
101  return "Network is down";
102  case WSAENETUNREACH:
103  return "Network is unreachable";
104  case WSAENETRESET:
105  return "Network dropped connection on reset";
106  case WSAECONNABORTED:
107  return "Software caused connection abort";
108  case WSAECONNRESET:
109  return "Connection reset by peer";
110  case WSAENOBUFS:
111  return "No buffer space available";
112  case WSAEISCONN:
113  return "Socket is already connected";
114  case WSAENOTCONN:
115  return "Socket is not connected";
116  case WSAESHUTDOWN:
117  return "Cannot send after socket shutdown";
118  case WSAETOOMANYREFS:
119  return "Too many references";
120  case WSAETIMEDOUT:
121  return "Connection timed out";
122  case WSAECONNREFUSED:
123  return "Connection refused";
124  case WSAELOOP:
125  return "Cannot translate name";
126  case WSAENAMETOOLONG:
127  return "Name too long";
128  case WSAEHOSTDOWN:
129  return "Host is down";
130  case WSAEHOSTUNREACH:
131  return "No route to host";
132  case WSAENOTEMPTY:
133  return "Directory not empty";
134  case WSAEPROCLIM:
135  return "Too many processes";
136  case WSAEUSERS:
137  return "User quota exceeded";
138  case WSAEDQUOT:
139  return "Disk quota exceeded";
140  case WSAESTALE:
141  return "Stale file handle reference";
142  case WSAEREMOTE:
143  return "Item is remote";
144  case WSASYSNOTREADY:
145  return "Network subsystem is unavailable";
146  case WSAVERNOTSUPPORTED:
147  return "Winsock.dll version out of range";
148  case WSANOTINITIALISED:
149  return "Successful WSAStartup not yet performed";
150  case WSAEDISCON:
151  return "Graceful shutdown in progress";
152  case WSAENOMORE:
153  return "No more results";
154  case WSAECANCELLED:
155  return "Call has been canceled";
156  case WSAEINVALIDPROCTABLE:
157  return "Procedure call table is invalid";
158  case WSAEINVALIDPROVIDER:
159  return "Service provider is invalid";
160  case WSAEPROVIDERFAILEDINIT:
161  return "Service provider failed to initialize";
162  case WSASYSCALLFAILURE:
163  return "System call failure";
164  case WSASERVICE_NOT_FOUND:
165  return "Service not found";
166  case WSATYPE_NOT_FOUND:
167  return "Class type not found";
168  case WSA_E_NO_MORE:
169  return "No more results";
170  case WSA_E_CANCELLED:
171  return "Call was canceled";
172  case WSAEREFUSED:
173  return "Database query was refused";
174  case WSAHOST_NOT_FOUND:
175  return "Host not found";
176  case WSATRY_AGAIN:
177  return "Nonauthoritative host not found";
178  case WSANO_RECOVERY:
179  return "This is a nonrecoverable error";
180  case WSANO_DATA:
181  return "Valid name, no data record of requested type";
182  case WSA_QOS_RECEIVERS:
183  return "QoS receivers";
184  case WSA_QOS_SENDERS:
185  return "QoS senders";
186  case WSA_QOS_NO_SENDERS:
187  return "No QoS senders";
188  case WSA_QOS_NO_RECEIVERS:
189  return "QoS no receivers";
190  case WSA_QOS_REQUEST_CONFIRMED:
191  return "QoS request confirmed";
192  case WSA_QOS_ADMISSION_FAILURE:
193  return "QoS admission error";
194  case WSA_QOS_POLICY_FAILURE:
195  return "QoS policy failure";
196  case WSA_QOS_BAD_STYLE:
197  return "QoS bad style";
198  case WSA_QOS_BAD_OBJECT:
199  return "QoS bad object";
200  case WSA_QOS_TRAFFIC_CTRL_ERROR:
201  return "QoS traffic control error";
202  case WSA_QOS_GENERIC_ERROR:
203  return "QoS generic error";
204  case WSA_QOS_ESERVICETYPE:
205  return "QoS service type error";
206  case WSA_QOS_EFLOWSPEC:
207  return "QoS flowspec error";
208  case WSA_QOS_EPROVSPECBUF:
209  return "Invalid QoS provider buffer";
210  case WSA_QOS_EFILTERSTYLE:
211  return "Invalid QoS filter style";
212  case WSA_QOS_EFILTERTYPE:
213  return "Invalid QoS filter type";
214  case WSA_QOS_EFILTERCOUNT:
215  return "Incorrect QoS filter count";
216  case WSA_QOS_EOBJLENGTH:
217  return "Invalid QoS object length";
218  case WSA_QOS_EFLOWCOUNT:
219  return "Incorrect QoS flow count";
220  case WSA_QOS_EUNKOWNPSOBJ:
221  return "Unrecognized QoS object";
222  case WSA_QOS_EPOLICYOBJ:
223  return "Invalid QoS policy object";
224  case WSA_QOS_EFLOWDESC:
225  return "Invalid QoS flow descriptor";
226  case WSA_QOS_EPSFLOWSPEC:
227  return "Invalid QoS provider-specific flowspec";
228  case WSA_QOS_EPSFILTERSPEC:
229  return "Invalid QoS provider-specific filterspec";
230  case WSA_QOS_ESDMODEOBJ:
231  return "Invalid QoS shape discard mode object";
232  case WSA_QOS_ESHAPERATEOBJ:
233  return "Invalid QoS shaping rate object";
234  case WSA_QOS_RESERVED_PETYPE:
235  return "Reserved policy QoS element type";
236  }
237  return "Unknown winsock error";
238 }
239 
240 
248 int
249 MHD_W32_socket_pair_(SOCKET sockets_pair[2], int non_blk)
250 {
251  int i;
252 
253  if (! sockets_pair)
254  {
255  WSASetLastError (WSAEFAULT);
256  return 0;
257  }
258 
259 #define PAIRMAXTRYIES 800
260  for (i = 0; i < PAIRMAXTRYIES; i++)
261  {
262  struct sockaddr_in listen_addr;
263  SOCKET listen_s;
264  static const int c_addinlen = sizeof(struct sockaddr_in); /* help compiler to optimize */
265  int addr_len = c_addinlen;
266  unsigned long on_val = 1;
267  unsigned long off_val = 0;
268 
269  listen_s = socket (AF_INET,
270  SOCK_STREAM,
271  IPPROTO_TCP);
272  if (INVALID_SOCKET == listen_s)
273  break; /* can't create even single socket */
274 
275  listen_addr.sin_family = AF_INET;
276  listen_addr.sin_port = 0; /* same as htons(0) */
277  listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
278  if ( (0 == bind (listen_s,
279  (struct sockaddr*) &listen_addr,
280  c_addinlen) &&
281  (0 == listen (listen_s,
282  1) ) &&
283  (0 == getsockname (listen_s,
284  (struct sockaddr*) &listen_addr,
285  &addr_len))) )
286  {
287  SOCKET client_s = socket(AF_INET,
288  SOCK_STREAM,
289  IPPROTO_TCP);
290  struct sockaddr_in accepted_from_addr;
291  struct sockaddr_in client_addr;
292  SOCKET server_s;
293 
294  if (INVALID_SOCKET == client_s)
295  {
296  /* try again */
297  closesocket (listen_s);
298  continue;
299  }
300 
301  if ( (0 != ioctlsocket (client_s,
302  FIONBIO,
303  &on_val)) ||
304  ( (0 != connect (client_s,
305  (struct sockaddr*) &listen_addr,
306  c_addinlen)) &&
307  (WSAGetLastError() != WSAEWOULDBLOCK)) )
308  {
309  /* try again */
310  closesocket (listen_s);
311  closesocket (client_s);
312  continue;
313  }
314 
315  addr_len = c_addinlen;
316  server_s = accept (listen_s,
317  (struct sockaddr*) &accepted_from_addr,
318  &addr_len);
319  if (INVALID_SOCKET == server_s)
320  {
321  /* try again */
322  closesocket (listen_s);
323  closesocket (client_s);
324  continue;
325  }
326 
327  addr_len = c_addinlen;
328  if ( (0 == getsockname (client_s,
329  (struct sockaddr*) &client_addr,
330  &addr_len)) &&
331  (accepted_from_addr.sin_family == client_addr.sin_family) &&
332  (accepted_from_addr.sin_port == client_addr.sin_port) &&
333  (accepted_from_addr.sin_addr.s_addr == client_addr.sin_addr.s_addr) &&
334  ( (0 != non_blk) ?
335  (0 == ioctlsocket(server_s,
336  FIONBIO,
337  &on_val)) :
338  (0 == ioctlsocket(client_s,
339  FIONBIO,
340  &off_val)) ) )
341  {
342  closesocket (listen_s);
343  sockets_pair[0] = server_s;
344  sockets_pair[1] = client_s;
345  return !0;
346  }
347  closesocket (server_s);
348  closesocket (client_s);
349  }
350  closesocket(listen_s);
351  }
352 
353  sockets_pair[0] = INVALID_SOCKET;
354  sockets_pair[1] = INVALID_SOCKET;
355  WSASetLastError(WSAECONNREFUSED);
356 
357  return 0;
358 }
359 
360 #endif /* MHD_WINSOCK_SOCKETS */
361 
362 
373 int
375  fd_set *set,
376  MHD_socket *max_fd,
377  unsigned int fd_setsize)
378 {
379  if ( (NULL == set) ||
380  (MHD_INVALID_SOCKET == fd) )
381  return 0;
383  set,
384  fd_setsize))
385  return 0;
387  set,
388  fd_setsize);
389  if ( (NULL != max_fd) &&
390  ( (fd > *max_fd) ||
391  (MHD_INVALID_SOCKET == *max_fd) ) )
392  *max_fd = fd;
393  return ! 0;
394 }
395 
396 
403 int
405 {
406 #if defined(MHD_POSIX_SOCKETS)
407  int flags;
408 
409  flags = fcntl (sock,
410  F_GETFL);
411  if (-1 == flags)
412  return 0;
413 
414  if ( ((flags | O_NONBLOCK) != flags) &&
415  (0 != fcntl (sock,
416  F_SETFL,
417  flags | O_NONBLOCK)) )
418  return 0;
419 #elif defined(MHD_WINSOCK_SOCKETS)
420  unsigned long flags = 1;
421 
422  if (0 != ioctlsocket (sock,
423  FIONBIO,
424  &flags))
425  return 0;
426 #endif /* MHD_WINSOCK_SOCKETS */
427  return !0;
428 }
429 
430 
438 int
440 {
441 #if defined(MHD_POSIX_SOCKETS)
442  int flags;
443 
444  flags = fcntl (sock,
445  F_GETFD);
446  if (-1 == flags)
447  return 0;
448 
449  if ( ((flags | FD_CLOEXEC) != flags) &&
450  (0 != fcntl (sock,
451  F_SETFD,
452  flags | FD_CLOEXEC)) )
453  return 0;
454 #elif defined(MHD_WINSOCK_SOCKETS)
455  if (! SetHandleInformation ((HANDLE)sock,
456  HANDLE_FLAG_INHERIT,
457  0))
458  return 0;
459 #endif /* MHD_WINSOCK_SOCKETS */
460  return !0;
461 }
462 
463 
472 {
473  int domain;
474  MHD_socket fd;
475  int cloexec_set;
476 
477 #ifdef HAVE_INET6
478  domain = (use_ipv6) ? PF_INET6 : PF_INET;
479 #else /* ! HAVE_INET6 */
480  if (use_ipv6)
481  return MHD_INVALID_SOCKET;
482  domain = PF_INET;
483 #endif /* ! HAVE_INET6 */
484 
485 #if defined(MHD_POSIX_SOCKETS) && defined(SOCK_CLOEXEC)
486  fd = socket (domain,
487  SOCK_STREAM | SOCK_CLOEXEC,
488  0);
489  cloexec_set = !0;
490 #elif defined(MHD_WINSOCK_SOCKETS) && defined (WSA_FLAG_NO_HANDLE_INHERIT)
491  fd = WSASocketW (domain,
492  SOCK_STREAM,
493  0,
494  NULL,
495  0,
496  WSA_FLAG_NO_HANDLE_INHERIT);
497  cloexec_set = !0;
498 #else /* !SOCK_CLOEXEC */
499  fd = MHD_INVALID_SOCKET;
500 #endif /* !SOCK_CLOEXEC */
501  if (MHD_INVALID_SOCKET == fd)
502  {
503  fd = socket (domain,
504  SOCK_STREAM,
505  0);
506  cloexec_set = 0;
507  }
508  if (MHD_INVALID_SOCKET == fd)
509  return MHD_INVALID_SOCKET;
510 #ifdef MHD_socket_nosignal_
511  if(! MHD_socket_nosignal_(fd))
512  {
513  const int err = MHD_socket_get_error_ ();
514  (void) MHD_socket_close_ (fd);
516  return MHD_INVALID_SOCKET;
517  }
518 #endif /* MHD_socket_nosignal_ */
519  if (! cloexec_set)
520  (void) MHD_socket_noninheritable_ (fd);
521 
522  return fd;
523 }
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:404
#define NULL
Definition: reason_phrase.c:31
#define MHD_socket_fset_error_(err)
Definition: mhd_sockets.h:538
#define MHD_socket_get_error_()
Definition: mhd_sockets.h:507
int MHD_socket
Definition: microhttpd.h:181
MHD_socket MHD_socket_create_listen_(int use_ipv6)
Definition: mhd_sockets.c:471
#define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd, pset, setsize)
Definition: mhd_sockets.h:310
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:182
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: mhd_sockets.c:374
int MHD_socket_noninheritable_(MHD_socket sock)
Definition: mhd_sockets.c:439
#define MHD_socket_close_(fd)
Definition: mhd_sockets.h:236
#define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd, pset, setsize)
Definition: mhd_sockets.h:284