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