GNU libmicrohttpd 0.9.77
Loading...
Searching...
No Matches
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
40const char *
41MHD_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
249int
250MHD_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
376int
378 fd_set *set,
379 MHD_socket *max_fd,
380 unsigned int fd_setsize)
381{
382 if ( (NULL == set) ||
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
406int
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
441int
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{
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)
int MHD_socket_noninheritable_(MHD_socket sock)
int MHD_socket_nonblocking_(MHD_socket sock)
MHD_socket MHD_socket_create_listen_(int pf)
#define MHD_SCKT_FD_FITS_FDSET_SETSIZE_(fd, pset, setsize)
#define MHD_SCKT_ADD_FD_TO_FDSET_SETSIZE_(fd, pset, setsize)
#define MHD_socket_close_(fd)
#define MHD_socket_get_error_()
#define MHD_socket_fset_error_(err)
#define NULL
int MHD_socket
Definition microhttpd.h:207
int fd
#define MHD_INVALID_SOCKET
Definition microhttpd.h:208