blob: 1aa7d8d378e54513feedc4056219ca341dec4ab9 [file] [log] [blame]
Daniel Erat748945e2015-08-11 09:22:30 -06001/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2007-2014 Daniel Pittman and Christian Grothoff
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
21/**
22 * @file microhttpd/daemon.c
23 * @brief A minimal-HTTP server library
24 * @author Daniel Pittman
25 * @author Christian Grothoff
26 */
27#if defined(_WIN32) && !defined(__CYGWIN__)
28/* override small default value */
29#define FD_SETSIZE 1024
30#define MHD_DEFAULT_FD_SETSIZE 64
31#else
32#define MHD_DEFAULT_FD_SETSIZE FD_SETSIZE
33#endif
34#include "platform.h"
35#include "internal.h"
36#include "response.h"
37#include "connection.h"
38#include "memorypool.h"
39#include <limits.h>
40#include "autoinit_funcs.h"
41
42#if HAVE_SEARCH_H
43#include <search.h>
44#else
45#include "tsearch.h"
46#endif
47
48#if HTTPS_SUPPORT
49#include "connection_https.h"
50#include <gcrypt.h>
51#endif
52
53#if defined(HAVE_POLL_H) && defined(HAVE_POLL)
54#include <poll.h>
55#endif
56
57#ifdef LINUX
58#include <sys/sendfile.h>
59#endif
60
61#ifdef _WIN32
62#ifndef WIN32_LEAN_AND_MEAN
63#define WIN32_LEAN_AND_MEAN 1
64#endif /* !WIN32_LEAN_AND_MEAN */
65#include <windows.h>
66#include <process.h>
67#endif
68
69#ifndef HAVE_ACCEPT4
70#define HAVE_ACCEPT4 0
71#endif
72
73/**
74 * Default connection limit.
75 */
76#ifndef WINDOWS
77#define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4
78#else
79#define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
80#endif
81
82/**
83 * Default memory allowed per connection.
84 */
85#define MHD_POOL_SIZE_DEFAULT (32 * 1024)
86
87#ifdef TCP_FASTOPEN
88/**
89 * Default TCP fastopen queue size.
90 */
91#define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10
92#endif
93
94/**
95 * Print extra messages with reasons for closing
96 * sockets? (only adds non-error messages).
97 */
98#define DEBUG_CLOSE MHD_NO
99
100/**
101 * Print extra messages when establishing
102 * connections? (only adds non-error messages).
103 */
104#define DEBUG_CONNECT MHD_NO
105
106#ifndef LINUX
107#ifndef MSG_NOSIGNAL
108#define MSG_NOSIGNAL 0
109#endif
110#endif
111
112#ifndef SOCK_CLOEXEC
113#define SOCK_CLOEXEC 0
114#endif
115
116#ifndef EPOLL_CLOEXEC
117#define EPOLL_CLOEXEC 0
118#endif
119
120
121/**
122 * Default implementation of the panic function,
123 * prints an error message and aborts.
124 *
125 * @param cls unused
126 * @param file name of the file with the problem
127 * @param line line number with the problem
128 * @param reason error message with details
129 */
130static void
131mhd_panic_std (void *cls,
132 const char *file,
133 unsigned int line,
134 const char *reason)
135{
136#if HAVE_MESSAGES
137 fprintf (stderr, "Fatal error in GNU libmicrohttpd %s:%u: %s\n",
138 file, line, reason);
139#endif
140 abort ();
141}
142
143
144/**
145 * Handler for fatal errors.
146 */
147MHD_PanicCallback mhd_panic;
148
149/**
150 * Closure argument for "mhd_panic".
151 */
152void *mhd_panic_cls;
153
154#ifdef _WIN32
155/**
156 * Track initialization of winsock
157 */
158static int mhd_winsock_inited_ = 0;
159#endif
160
161/**
162 * Trace up to and return master daemon. If the supplied daemon
163 * is a master, then return the daemon itself.
164 *
165 * @param daemon handle to a daemon
166 * @return master daemon handle
167 */
168static struct MHD_Daemon*
169MHD_get_master (struct MHD_Daemon *daemon)
170{
171 while (NULL != daemon->master)
172 daemon = daemon->master;
173 return daemon;
174}
175
176
177/**
178 * Maintain connection count for single address.
179 */
180struct MHD_IPCount
181{
182 /**
183 * Address family. AF_INET or AF_INET6 for now.
184 */
185 int family;
186
187 /**
188 * Actual address.
189 */
190 union
191 {
192 /**
193 * IPv4 address.
194 */
195 struct in_addr ipv4;
196#if HAVE_INET6
197 /**
198 * IPv6 address.
199 */
200 struct in6_addr ipv6;
201#endif
202 } addr;
203
204 /**
205 * Counter.
206 */
207 unsigned int count;
208};
209
210
211/**
212 * Lock shared structure for IP connection counts and connection DLLs.
213 *
214 * @param daemon handle to daemon where lock is
215 */
216static void
217MHD_ip_count_lock (struct MHD_Daemon *daemon)
218{
219 if (MHD_YES != MHD_mutex_lock_(&daemon->per_ip_connection_mutex))
220 {
221 MHD_PANIC ("Failed to acquire IP connection limit mutex\n");
222 }
223}
224
225
226/**
227 * Unlock shared structure for IP connection counts and connection DLLs.
228 *
229 * @param daemon handle to daemon where lock is
230 */
231static void
232MHD_ip_count_unlock (struct MHD_Daemon *daemon)
233{
234 if (MHD_YES != MHD_mutex_unlock_(&daemon->per_ip_connection_mutex))
235 {
236 MHD_PANIC ("Failed to release IP connection limit mutex\n");
237 }
238}
239
240
241/**
242 * Tree comparison function for IP addresses (supplied to tsearch() family).
243 * We compare everything in the struct up through the beginning of the
244 * 'count' field.
245 *
246 * @param a1 first address to compare
247 * @param a2 second address to compare
248 * @return -1, 0 or 1 depending on result of compare
249 */
250static int
251MHD_ip_addr_compare (const void *a1, const void *a2)
252{
253 return memcmp (a1, a2, offsetof (struct MHD_IPCount, count));
254}
255
256
257/**
258 * Parse address and initialize 'key' using the address.
259 *
260 * @param addr address to parse
261 * @param addrlen number of bytes in addr
262 * @param key where to store the parsed address
263 * @return #MHD_YES on success and #MHD_NO otherwise (e.g., invalid address type)
264 */
265static int
266MHD_ip_addr_to_key (const struct sockaddr *addr,
267 socklen_t addrlen,
268 struct MHD_IPCount *key)
269{
270 memset(key, 0, sizeof(*key));
271
272 /* IPv4 addresses */
273 if (sizeof (struct sockaddr_in) == addrlen)
274 {
275 const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
276 key->family = AF_INET;
277 memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr));
278 return MHD_YES;
279 }
280
281#if HAVE_INET6
282 /* IPv6 addresses */
283 if (sizeof (struct sockaddr_in6) == addrlen)
284 {
285 const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
286 key->family = AF_INET6;
287 memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr));
288 return MHD_YES;
289 }
290#endif
291
292 /* Some other address */
293 return MHD_NO;
294}
295
296
297/**
298 * Check if IP address is over its limit.
299 *
300 * @param daemon handle to daemon where connection counts are tracked
301 * @param addr address to add (or increment counter)
302 * @param addrlen number of bytes in addr
303 * @return Return #MHD_YES if IP below limit, #MHD_NO if IP has surpassed limit.
304 * Also returns #MHD_NO if fails to allocate memory.
305 */
306static int
307MHD_ip_limit_add (struct MHD_Daemon *daemon,
308 const struct sockaddr *addr,
309 socklen_t addrlen)
310{
311 struct MHD_IPCount *key;
312 void **nodep;
313 void *node;
314 int result;
315
316 daemon = MHD_get_master (daemon);
317 /* Ignore if no connection limit assigned */
318 if (0 == daemon->per_ip_connection_limit)
319 return MHD_YES;
320
321 if (NULL == (key = malloc (sizeof(*key))))
322 return MHD_NO;
323
324 /* Initialize key */
325 if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key))
326 {
327 /* Allow unhandled address types through */
328 free (key);
329 return MHD_YES;
330 }
331 MHD_ip_count_lock (daemon);
332
333 /* Search for the IP address */
334 if (NULL == (nodep = tsearch (key,
335 &daemon->per_ip_connection_count,
336 &MHD_ip_addr_compare)))
337 {
338#if HAVE_MESSAGES
339 MHD_DLOG (daemon,
340 "Failed to add IP connection count node\n");
341#endif
342 MHD_ip_count_unlock (daemon);
343 free (key);
344 return MHD_NO;
345 }
346 node = *nodep;
347 /* If we got an existing node back, free the one we created */
348 if (node != key)
349 free(key);
350 key = (struct MHD_IPCount *) node;
351 /* Test if there is room for another connection; if so,
352 * increment count */
353 result = (key->count < daemon->per_ip_connection_limit);
354 if (MHD_YES == result)
355 ++key->count;
356
357 MHD_ip_count_unlock (daemon);
358 return result;
359}
360
361
362/**
363 * Decrement connection count for IP address, removing from table
364 * count reaches 0.
365 *
366 * @param daemon handle to daemon where connection counts are tracked
367 * @param addr address to remove (or decrement counter)
368 * @param addrlen number of bytes in @a addr
369 */
370static void
371MHD_ip_limit_del (struct MHD_Daemon *daemon,
372 const struct sockaddr *addr,
373 socklen_t addrlen)
374{
375 struct MHD_IPCount search_key;
376 struct MHD_IPCount *found_key;
377 void **nodep;
378
379 daemon = MHD_get_master (daemon);
380 /* Ignore if no connection limit assigned */
381 if (0 == daemon->per_ip_connection_limit)
382 return;
383 /* Initialize search key */
384 if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key))
385 return;
386
387 MHD_ip_count_lock (daemon);
388
389 /* Search for the IP address */
390 if (NULL == (nodep = tfind (&search_key,
391 &daemon->per_ip_connection_count,
392 &MHD_ip_addr_compare)))
393 {
394 /* Something's wrong if we couldn't find an IP address
395 * that was previously added */
396 MHD_PANIC ("Failed to find previously-added IP address\n");
397 }
398 found_key = (struct MHD_IPCount *) *nodep;
399 /* Validate existing count for IP address */
400 if (0 == found_key->count)
401 {
402 MHD_PANIC ("Previously-added IP address had 0 count\n");
403 }
404 /* Remove the node entirely if count reduces to 0 */
405 if (0 == --found_key->count)
406 {
407 tdelete (found_key,
408 &daemon->per_ip_connection_count,
409 &MHD_ip_addr_compare);
410 free (found_key);
411 }
412
413 MHD_ip_count_unlock (daemon);
414}
415
416
417#if HTTPS_SUPPORT
418/**
419 * Callback for receiving data from the socket.
420 *
421 * @param connection the MHD_Connection structure
422 * @param other where to write received data to
423 * @param i maximum size of other (in bytes)
424 * @return number of bytes actually received
425 */
426static ssize_t
427recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
428{
429 int res;
430
431 if (MHD_YES == connection->tls_read_ready)
432 {
433 connection->daemon->num_tls_read_ready--;
434 connection->tls_read_ready = MHD_NO;
435 }
436 res = gnutls_record_recv (connection->tls_session, other, i);
437 if ( (GNUTLS_E_AGAIN == res) ||
438 (GNUTLS_E_INTERRUPTED == res) )
439 {
440 MHD_set_socket_errno_ (EINTR);
441#if EPOLL_SUPPORT
442 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
443#endif
444 return -1;
445 }
446 if (res < 0)
447 {
448 /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
449 disrupted); set errno to something caller will interpret
450 correctly as a hard error */
451 MHD_set_socket_errno_ (ECONNRESET);
452 return res;
453 }
454 if (res == i)
455 {
456 connection->tls_read_ready = MHD_YES;
457 connection->daemon->num_tls_read_ready++;
458 }
459 return res;
460}
461
462
463/**
464 * Callback for writing data to the socket.
465 *
466 * @param connection the MHD connection structure
467 * @param other data to write
468 * @param i number of bytes to write
469 * @return actual number of bytes written
470 */
471static ssize_t
472send_tls_adapter (struct MHD_Connection *connection,
473 const void *other, size_t i)
474{
475 int res;
476
477 res = gnutls_record_send (connection->tls_session, other, i);
478 if ( (GNUTLS_E_AGAIN == res) ||
479 (GNUTLS_E_INTERRUPTED == res) )
480 {
481 MHD_set_socket_errno_ (EINTR);
482#if EPOLL_SUPPORT
483 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
484#endif
485 return -1;
486 }
487 if (res < 0)
488 {
489 /* some other GNUTLS error, should set 'errno'; as we do not
490 really understand the error (not listed in GnuTLS
491 documentation explicitly), we set 'errno' to something that
492 will cause the connection to fail. */
493 MHD_set_socket_errno_ (ECONNRESET);
494 return -1;
495 }
496 return res;
497}
498
499
500/**
501 * Read and setup our certificate and key.
502 *
503 * @param daemon handle to daemon to initialize
504 * @return 0 on success
505 */
506static int
507MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
508{
509 gnutls_datum_t key;
510 gnutls_datum_t cert;
511 int ret;
512
513#if GNUTLS_VERSION_MAJOR >= 3
514 if (NULL != daemon->cert_callback)
515 {
516 gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
517 daemon->cert_callback);
518 }
519#endif
520 if (NULL != daemon->https_mem_trust)
521 {
522 cert.data = (unsigned char *) daemon->https_mem_trust;
523 cert.size = strlen (daemon->https_mem_trust);
524 if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, &cert,
525 GNUTLS_X509_FMT_PEM) < 0)
526 {
527#if HAVE_MESSAGES
528 MHD_DLOG(daemon,
529 "Bad trust certificate format\n");
530#endif
531 return -1;
532 }
533 }
534
535 if (MHD_YES == daemon->have_dhparams)
536 {
537 gnutls_certificate_set_dh_params (daemon->x509_cred,
538 daemon->https_mem_dhparams);
539 }
540 /* certificate & key loaded from memory */
541 if ( (NULL != daemon->https_mem_cert) &&
542 (NULL != daemon->https_mem_key) )
543 {
544 key.data = (unsigned char *) daemon->https_mem_key;
545 key.size = strlen (daemon->https_mem_key);
546 cert.data = (unsigned char *) daemon->https_mem_cert;
547 cert.size = strlen (daemon->https_mem_cert);
548
549 if (NULL != daemon->https_key_password) {
550#if GNUTLS_VERSION_NUMBER >= 0x030111
551 ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
552 &cert, &key,
553 GNUTLS_X509_FMT_PEM,
554 daemon->https_key_password,
555 0);
556#else
557#if HAVE_MESSAGES
558 MHD_DLOG (daemon,
559 "Failed to setup x509 certificate/key: pre 3.X.X version " \
560 "of GnuTLS does not support setting key password");
561#endif
562 return -1;
563#endif
564 }
565 else
566 ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
567 &cert, &key,
568 GNUTLS_X509_FMT_PEM);
569#if HAVE_MESSAGES
570 if (0 != ret)
571 MHD_DLOG (daemon,
572 "GnuTLS failed to setup x509 certificate/key: %s\n",
573 gnutls_strerror (ret));
574#endif
575 return ret;
576 }
577#if GNUTLS_VERSION_MAJOR >= 3
578 if (NULL != daemon->cert_callback)
579 return 0;
580#endif
581#if HAVE_MESSAGES
582 MHD_DLOG (daemon,
583 "You need to specify a certificate and key location\n");
584#endif
585 return -1;
586}
587
588
589/**
590 * Initialize security aspects of the HTTPS daemon
591 *
592 * @param daemon handle to daemon to initialize
593 * @return 0 on success
594 */
595static int
596MHD_TLS_init (struct MHD_Daemon *daemon)
597{
598 switch (daemon->cred_type)
599 {
600 case GNUTLS_CRD_CERTIFICATE:
601 if (0 !=
602 gnutls_certificate_allocate_credentials (&daemon->x509_cred))
603 return GNUTLS_E_MEMORY_ERROR;
604 return MHD_init_daemon_certificate (daemon);
605 default:
606#if HAVE_MESSAGES
607 MHD_DLOG (daemon,
608 "Error: invalid credentials type %d specified.\n",
609 daemon->cred_type);
610#endif
611 return -1;
612 }
613}
614#endif
615
616
617/**
618 * Add @a fd to the @a set. If @a fd is
619 * greater than @a max_fd, set @a max_fd to @a fd.
620 *
621 * @param fd file descriptor to add to the @a set
622 * @param set set to modify
623 * @param max_fd maximum value to potentially update
624 * @param fd_setsize value of FD_SETSIZE
625 * @return #MHD_YES on success, #MHD_NO otherwise
626 */
627static int
628add_to_fd_set (MHD_socket fd,
629 fd_set *set,
630 MHD_socket *max_fd,
631 unsigned int fd_setsize)
632{
633 if (NULL == set)
634 return MHD_NO;
635#ifdef MHD_WINSOCK_SOCKETS
636 if (set->fd_count >= fd_setsize)
637 {
638 if (FD_ISSET(fd, set))
639 return MHD_YES;
640 else
641 return MHD_NO;
642 }
643#else // ! MHD_WINSOCK_SOCKETS
644 if (fd >= fd_setsize)
645 return MHD_NO;
646#endif // ! MHD_WINSOCK_SOCKETS
647 FD_SET (fd, set);
648 if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) &&
649 ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) )
650 *max_fd = fd;
651
652 return MHD_YES;
653}
654
655#undef MHD_get_fdset
656
657/**
658 * Obtain the `select()` sets for this daemon.
659 * Daemon's FDs will be added to fd_sets. To get only
660 * daemon FDs in fd_sets, call FD_ZERO for each fd_set
661 * before calling this function. FD_SETSIZE is assumed
662 * to be platform's default.
663 *
664 * @param daemon daemon to get sets from
665 * @param read_fd_set read set
666 * @param write_fd_set write set
667 * @param except_fd_set except set
668 * @param max_fd increased to largest FD added (if larger
669 * than existing value); can be NULL
670 * @return #MHD_YES on success, #MHD_NO if this
671 * daemon was not started with the right
672 * options for this call or any FD didn't
673 * fit fd_set.
674 * @ingroup event
675 */
676int
677MHD_get_fdset (struct MHD_Daemon *daemon,
678 fd_set *read_fd_set,
679 fd_set *write_fd_set,
680 fd_set *except_fd_set,
681 MHD_socket *max_fd)
682{
683 return MHD_get_fdset2(daemon, read_fd_set,
684 write_fd_set, except_fd_set,
685 max_fd, MHD_DEFAULT_FD_SETSIZE);
686}
687
688/**
689 * Obtain the `select()` sets for this daemon.
690 * Daemon's FDs will be added to fd_sets. To get only
691 * daemon FDs in fd_sets, call FD_ZERO for each fd_set
692 * before calling this function. Passing custom FD_SETSIZE
693 * as @a fd_setsize allow usage of larger/smaller than
694 * platform's default fd_sets.
695 *
696 * @param daemon daemon to get sets from
697 * @param read_fd_set read set
698 * @param write_fd_set write set
699 * @param except_fd_set except set
700 * @param max_fd increased to largest FD added (if larger
701 * than existing value); can be NULL
702 * @param fd_setsize value of FD_SETSIZE
703 * @return #MHD_YES on success, #MHD_NO if this
704 * daemon was not started with the right
705 * options for this call or any FD didn't
706 * fit fd_set.
707 * @ingroup event
708 */
709int
710MHD_get_fdset2 (struct MHD_Daemon *daemon,
711 fd_set *read_fd_set,
712 fd_set *write_fd_set,
713 fd_set *except_fd_set,
714 MHD_socket *max_fd,
715 unsigned int fd_setsize)
716{
717 struct MHD_Connection *pos;
718
719 if ( (NULL == daemon)
720 || (NULL == read_fd_set)
721 || (NULL == write_fd_set)
722 || (MHD_YES == daemon->shutdown)
723 || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
724 || (0 != (daemon->options & MHD_USE_POLL)))
725 return MHD_NO;
726#if EPOLL_SUPPORT
727 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
728 {
729 /* we're in epoll mode, use the epoll FD as a stand-in for
730 the entire event set */
731
732 return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd, fd_setsize);
733 }
734#endif
735 if (MHD_INVALID_SOCKET != daemon->socket_fd &&
736 MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd, fd_setsize))
737 return MHD_NO;
738
739 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
740 {
741 switch (pos->event_loop_info)
742 {
743 case MHD_EVENT_LOOP_INFO_READ:
744 if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
745 return MHD_NO;
746 break;
747 case MHD_EVENT_LOOP_INFO_WRITE:
748 if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd, fd_setsize))
749 return MHD_NO;
750 if (pos->read_buffer_size > pos->read_buffer_offset &&
751 MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
752 return MHD_NO;
753 break;
754 case MHD_EVENT_LOOP_INFO_BLOCK:
755 if (pos->read_buffer_size > pos->read_buffer_offset &&
756 MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
757 return MHD_NO;
758 break;
759 case MHD_EVENT_LOOP_INFO_CLEANUP:
760 /* this should never happen */
761 break;
762 }
763 }
764#if DEBUG_CONNECT
765#if HAVE_MESSAGES
766 if (NULL != max_fd)
767 MHD_DLOG (daemon,
768 "Maximum socket in select set: %d\n",
769 *max_fd);
770#endif
771#endif
772 return MHD_YES;
773}
774
775
776/**
777 * Main function of the thread that handles an individual
778 * connection when #MHD_USE_THREAD_PER_CONNECTION is set.
779 *
780 * @param data the `struct MHD_Connection` this thread will handle
781 * @return always 0
782 */
783static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
784MHD_handle_connection (void *data)
785{
786 struct MHD_Connection *con = data;
787 int num_ready;
788 fd_set rs;
789 fd_set ws;
790 MHD_socket max;
791 struct timeval tv;
792 struct timeval *tvp;
793 unsigned int timeout;
794 time_t now;
795#if WINDOWS
796 MHD_pipe spipe = con->daemon->wpipe[0];
797 char tmp;
798#ifdef HAVE_POLL
799 int extra_slot;
800#endif /* HAVE_POLL */
801#define EXTRA_SLOTS 1
802#else /* !WINDOWS */
803#define EXTRA_SLOTS 0
804#endif /* !WINDOWS */
805#ifdef HAVE_POLL
806 struct pollfd p[1 + EXTRA_SLOTS];
807#endif
808
809 timeout = con->daemon->connection_timeout;
810 while ( (MHD_YES != con->daemon->shutdown) &&
811 (MHD_CONNECTION_CLOSED != con->state) )
812 {
813 tvp = NULL;
814 if (timeout > 0)
815 {
816 now = MHD_monotonic_time();
817 if (now - con->last_activity > timeout)
818 tv.tv_sec = 0;
819 else
820 tv.tv_sec = timeout - (now - con->last_activity);
821 tv.tv_usec = 0;
822 tvp = &tv;
823 }
824#if HTTPS_SUPPORT
825 if (MHD_YES == con->tls_read_ready)
826 {
827 /* do not block (more data may be inside of TLS buffers waiting for us) */
828 tv.tv_sec = 0;
829 tv.tv_usec = 0;
830 tvp = &tv;
831 }
832#endif
833 if (0 == (con->daemon->options & MHD_USE_POLL))
834 {
835 /* use select */
836 int err_state = 0;
837 FD_ZERO (&rs);
838 FD_ZERO (&ws);
839 max = 0;
840 switch (con->event_loop_info)
841 {
842 case MHD_EVENT_LOOP_INFO_READ:
843 if (MHD_YES !=
844 add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
845 err_state = 1;
846 break;
847 case MHD_EVENT_LOOP_INFO_WRITE:
848 if (MHD_YES !=
849 add_to_fd_set (con->socket_fd, &ws, &max, FD_SETSIZE))
850 err_state = 1;
851 if ( (con->read_buffer_size > con->read_buffer_offset) &&
852 (MHD_YES !=
853 add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE)) )
854 err_state = 1;
855 break;
856 case MHD_EVENT_LOOP_INFO_BLOCK:
857 if ( (con->read_buffer_size > con->read_buffer_offset) &&
858 (MHD_YES !=
859 add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE)) )
860 err_state = 1;
861 tv.tv_sec = 0;
862 tv.tv_usec = 0;
863 tvp = &tv;
864 break;
865 case MHD_EVENT_LOOP_INFO_CLEANUP:
866 /* how did we get here!? */
867 goto exit;
868 }
869#if WINDOWS
870 if (MHD_INVALID_PIPE_ != spipe)
871 {
872 if (MHD_YES !=
873 add_to_fd_set (spipe, &rs, &max, FD_SETSIZE))
874 err_state = 1;
875 }
876#endif
877 if (0 != err_state)
878 {
879#if HAVE_MESSAGES
880 MHD_DLOG (con->daemon,
881 "Can't add FD to fd_set\n");
882#endif
883 goto exit;
884 }
885
886 num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp);
887 if (num_ready < 0)
888 {
889 if (EINTR == MHD_socket_errno_)
890 continue;
891#if HAVE_MESSAGES
892 MHD_DLOG (con->daemon,
893 "Error during select (%d): `%s'\n",
894 MHD_socket_errno_,
895 MHD_socket_last_strerr_ ());
896#endif
897 break;
898 }
899#if WINDOWS
900 /* drain signaling pipe */
901 if ( (MHD_INVALID_PIPE_ != spipe) &&
902 (FD_ISSET (spipe, &rs)) )
903 (void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp));
904#endif
905 /* call appropriate connection handler if necessary */
906 if ( (FD_ISSET (con->socket_fd, &rs))
907#if HTTPS_SUPPORT
908 || (MHD_YES == con->tls_read_ready)
909#endif
910 )
911 con->read_handler (con);
912 if (FD_ISSET (con->socket_fd, &ws))
913 con->write_handler (con);
914 if (MHD_NO == con->idle_handler (con))
915 goto exit;
916 }
917#ifdef HAVE_POLL
918 else
919 {
920 /* use poll */
921 memset (&p, 0, sizeof (p));
922 p[0].fd = con->socket_fd;
923 switch (con->event_loop_info)
924 {
925 case MHD_EVENT_LOOP_INFO_READ:
926 p[0].events |= POLLIN;
927 break;
928 case MHD_EVENT_LOOP_INFO_WRITE:
929 p[0].events |= POLLOUT;
930 if (con->read_buffer_size > con->read_buffer_offset)
931 p[0].events |= POLLIN;
932 break;
933 case MHD_EVENT_LOOP_INFO_BLOCK:
934 if (con->read_buffer_size > con->read_buffer_offset)
935 p[0].events |= POLLIN;
936 tv.tv_sec = 0;
937 tv.tv_usec = 0;
938 tvp = &tv;
939 break;
940 case MHD_EVENT_LOOP_INFO_CLEANUP:
941 /* how did we get here!? */
942 goto exit;
943 }
944#if WINDOWS
945 extra_slot = 0;
946 if (MHD_INVALID_PIPE_ != spipe)
947 {
948 p[1].events |= POLLIN;
949 p[1].fd = spipe;
950 p[1].revents = 0;
951 extra_slot = 1;
952 }
953#endif
954 if (MHD_sys_poll_ (p,
955#if WINDOWS
956 1 + extra_slot,
957#else
958 1,
959#endif
960 (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
961 {
962 if (EINTR == MHD_socket_errno_)
963 continue;
964#if HAVE_MESSAGES
965 MHD_DLOG (con->daemon,
966 "Error during poll: `%s'\n",
967 MHD_socket_last_strerr_ ());
968#endif
969 break;
970 }
971#if WINDOWS
972 /* drain signaling pipe */
973 if ( (MHD_INVALID_PIPE_ != spipe) &&
974 (0 != (p[1].revents & (POLLERR | POLLHUP))) )
975 (void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp));
976#endif
977 if ( (0 != (p[0].revents & POLLIN))
978#if HTTPS_SUPPORT
979 || (MHD_YES == con->tls_read_ready)
980#endif
981 )
982 con->read_handler (con);
983 if (0 != (p[0].revents & POLLOUT))
984 con->write_handler (con);
985 if (0 != (p[0].revents & (POLLERR | POLLHUP)))
986 MHD_connection_close (con, MHD_REQUEST_TERMINATED_WITH_ERROR);
987 if (MHD_NO == con->idle_handler (con))
988 goto exit;
989 }
990#endif
991 }
992 if (MHD_CONNECTION_IN_CLEANUP != con->state)
993 {
994#if DEBUG_CLOSE
995#if HAVE_MESSAGES
996 MHD_DLOG (con->daemon,
997 "Processing thread terminating, closing connection\n");
998#endif
999#endif
1000 if (MHD_CONNECTION_CLOSED != con->state)
1001 MHD_connection_close (con,
1002 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
1003 con->idle_handler (con);
1004 }
1005exit:
1006 if (NULL != con->response)
1007 {
1008 MHD_destroy_response (con->response);
1009 con->response = NULL;
1010 }
1011
1012 if (NULL != con->daemon->notify_connection)
1013 con->daemon->notify_connection (con->daemon->notify_connection_cls,
1014 con,
1015 &con->socket_context,
1016 MHD_CONNECTION_NOTIFY_CLOSED);
1017
1018 return (MHD_THRD_RTRN_TYPE_)0;
1019}
1020
1021
1022/**
1023 * Callback for receiving data from the socket.
1024 *
1025 * @param connection the MHD connection structure
1026 * @param other where to write received data to
1027 * @param i maximum size of other (in bytes)
1028 * @return number of bytes actually received
1029 */
1030static ssize_t
1031recv_param_adapter (struct MHD_Connection *connection,
1032 void *other,
1033 size_t i)
1034{
1035 ssize_t ret;
1036
1037 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
1038 (MHD_CONNECTION_CLOSED == connection->state) )
1039 {
1040 MHD_set_socket_errno_ (ENOTCONN);
1041 return -1;
1042 }
1043 ret = recv (connection->socket_fd, other, i, MSG_NOSIGNAL);
1044#if EPOLL_SUPPORT
1045 if (ret < (ssize_t) i)
1046 {
1047 /* partial read --- no longer read-ready */
1048 connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
1049 }
1050#endif
1051 return ret;
1052}
1053
1054
1055/**
1056 * Callback for writing data to the socket.
1057 *
1058 * @param connection the MHD connection structure
1059 * @param other data to write
1060 * @param i number of bytes to write
1061 * @return actual number of bytes written
1062 */
1063static ssize_t
1064send_param_adapter (struct MHD_Connection *connection,
1065 const void *other,
1066 size_t i)
1067{
1068 ssize_t ret;
1069#if LINUX
1070 MHD_socket fd;
1071 off_t offset;
1072 off_t left;
1073#endif
1074
1075 if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
1076 (MHD_CONNECTION_CLOSED == connection->state) )
1077 {
1078 MHD_set_socket_errno_ (ENOTCONN);
1079 return -1;
1080 }
1081 if (0 != (connection->daemon->options & MHD_USE_SSL))
1082 return send (connection->socket_fd, other, i, MSG_NOSIGNAL);
1083#if LINUX
1084 if ( (connection->write_buffer_append_offset ==
1085 connection->write_buffer_send_offset) &&
1086 (NULL != connection->response) &&
1087 (MHD_INVALID_SOCKET != (fd = connection->response->fd)) )
1088 {
1089 /* can use sendfile */
1090 offset = (off_t) connection->response_write_position + connection->response->fd_off;
1091 left = connection->response->total_size - connection->response_write_position;
1092 if (left > SSIZE_MAX)
1093 left = SSIZE_MAX; /* cap at return value limit */
1094 if (-1 != (ret = sendfile (connection->socket_fd,
1095 fd,
1096 &offset,
1097 (size_t) left)))
1098 {
1099#if EPOLL_SUPPORT
1100 if (ret < left)
1101 {
1102 /* partial write --- no longer write-ready */
1103 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
1104 }
1105#endif
1106 return ret;
1107 }
1108 const int err = MHD_socket_errno_;
1109 if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) )
1110 return 0;
1111 if ( (EINVAL == err) || (EBADF == err) )
1112 return -1;
1113 /* None of the 'usual' sendfile errors occurred, so we should try
1114 to fall back to 'SEND'; see also this thread for info on
1115 odd libc/Linux behavior with sendfile:
1116 http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
1117 }
1118#endif
1119 ret = send (connection->socket_fd, other, i, MSG_NOSIGNAL);
1120#if EPOLL_SUPPORT
1121 if (ret < (ssize_t) i)
1122 {
1123 /* partial write --- no longer write-ready */
1124 connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
1125 }
1126#endif
1127 /* Handle broken kernel / libc, returning -1 but not setting errno;
1128 kill connection as that should be safe; reported on mailinglist here:
1129 http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */
1130 if ( (-1 == ret) && (0 == errno) )
1131 errno = ECONNRESET;
1132 return ret;
1133}
1134
1135
1136/**
1137 * Signature of main function for a thread.
1138 *
1139 * @param cls closure argument for the function
1140 * @return termination code from the thread
1141 */
1142typedef MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *ThreadStartRoutine)(void *cls);
1143
1144
1145/**
1146 * Create a thread and set the attributes according to our options.
1147 *
1148 * @param thread handle to initialize
1149 * @param daemon daemon with options
1150 * @param start_routine main function of thread
1151 * @param arg argument for start_routine
1152 * @return 0 on success
1153 */
1154static int
1155create_thread (MHD_thread_handle_ *thread,
1156 const struct MHD_Daemon *daemon,
1157 ThreadStartRoutine start_routine,
1158 void *arg)
1159{
1160#if defined(MHD_USE_POSIX_THREADS)
1161 pthread_attr_t attr;
1162 pthread_attr_t *pattr;
1163 int ret;
1164
1165 if (0 != daemon->thread_stack_size)
1166 {
1167 if (0 != (ret = pthread_attr_init (&attr)))
1168 goto ERR;
1169 if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size)))
1170 {
1171 pthread_attr_destroy (&attr);
1172 goto ERR;
1173 }
1174 pattr = &attr;
1175 }
1176 else
1177 {
1178 pattr = NULL;
1179 }
1180 ret = pthread_create (thread, pattr,
1181 start_routine, arg);
1182#ifdef HAVE_PTHREAD_SETNAME_NP
1183 (void) pthread_setname_np (*thread, "libmicrohttpd");
1184#endif /* HAVE_PTHREAD_SETNAME_NP */
1185 if (0 != daemon->thread_stack_size)
1186 pthread_attr_destroy (&attr);
1187 return ret;
1188 ERR:
1189#if HAVE_MESSAGES
1190 MHD_DLOG (daemon,
1191 "Failed to set thread stack size\n");
1192#endif
1193 errno = EINVAL;
1194 return ret;
1195#elif defined(MHD_USE_W32_THREADS)
1196 unsigned threadID;
1197 *thread = (HANDLE)_beginthreadex(NULL, (unsigned)daemon->thread_stack_size, start_routine,
1198 arg, 0, &threadID);
1199 if (NULL == (*thread))
1200 return errno;
1201
1202 W32_SetThreadName(threadID, "libmicrohttpd");
1203
1204 return 0;
1205#endif
1206}
1207
1208
1209/**
1210 * Add another client connection to the set of connections
1211 * managed by MHD. This API is usually not needed (since
1212 * MHD will accept inbound connections on the server socket).
1213 * Use this API in special cases, for example if your HTTP
1214 * server is behind NAT and needs to connect out to the
1215 * HTTP client.
1216 *
1217 * The given client socket will be managed (and closed!) by MHD after
1218 * this call and must no longer be used directly by the application
1219 * afterwards.
1220 *
1221 * Per-IP connection limits are ignored when using this API.
1222 *
1223 * @param daemon daemon that manages the connection
1224 * @param client_socket socket to manage (MHD will expect
1225 * to receive an HTTP request from this socket next).
1226 * @param addr IP address of the client
1227 * @param addrlen number of bytes in @a addr
1228 * @param external_add perform additional operations needed due
1229 * to the application calling us directly
1230 * @return #MHD_YES on success, #MHD_NO if this daemon could
1231 * not handle the connection (i.e. malloc failed, etc).
1232 * The socket will be closed in any case; 'errno' is
1233 * set to indicate further details about the error.
1234 */
1235static int
1236internal_add_connection (struct MHD_Daemon *daemon,
1237 MHD_socket client_socket,
1238 const struct sockaddr *addr,
1239 socklen_t addrlen,
1240 int external_add)
1241{
1242 struct MHD_Connection *connection;
1243 int res_thread_create;
1244 unsigned int i;
1245 int eno;
1246 struct MHD_Daemon *worker;
1247#if OSX
1248 static int on = 1;
1249#endif
1250
1251 if (NULL != daemon->worker_pool)
1252 {
1253 /* have a pool, try to find a pool with capacity; we use the
1254 socket as the initial offset into the pool for load
1255 balancing */
1256 for (i=0;i<daemon->worker_pool_size;i++)
1257 {
1258 worker = &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
1259 if (worker->connections < worker->connection_limit)
1260 return internal_add_connection (worker,
1261 client_socket,
1262 addr, addrlen,
1263 external_add);
1264 }
1265 /* all pools are at their connection limit, must refuse */
1266 if (0 != MHD_socket_close_ (client_socket))
1267 MHD_PANIC ("close failed\n");
1268#if ENFILE
1269 errno = ENFILE;
1270#endif
1271 return MHD_NO;
1272 }
1273
1274#ifndef WINDOWS
1275 if ( (client_socket >= FD_SETSIZE) &&
1276 (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) )
1277 {
1278#if HAVE_MESSAGES
1279 MHD_DLOG (daemon,
1280 "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
1281 client_socket,
1282 FD_SETSIZE);
1283#endif
1284 if (0 != MHD_socket_close_ (client_socket))
1285 MHD_PANIC ("close failed\n");
1286#if EINVAL
1287 errno = EINVAL;
1288#endif
1289 return MHD_NO;
1290 }
1291#endif
1292
1293
1294#if HAVE_MESSAGES
1295#if DEBUG_CONNECT
1296 MHD_DLOG (daemon,
1297 "Accepted connection on socket %d\n",
1298 client_socket);
1299#endif
1300#endif
1301 if ( (daemon->connections == daemon->connection_limit) ||
1302 (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) )
1303 {
1304 /* above connection limit - reject */
1305#if HAVE_MESSAGES
1306 MHD_DLOG (daemon,
1307 "Server reached connection limit (closing inbound connection)\n");
1308#endif
1309 if (0 != MHD_socket_close_ (client_socket))
1310 MHD_PANIC ("close failed\n");
1311#if ENFILE
1312 errno = ENFILE;
1313#endif
1314 return MHD_NO;
1315 }
1316
1317 /* apply connection acceptance policy if present */
1318 if ( (NULL != daemon->apc) &&
1319 (MHD_NO == daemon->apc (daemon->apc_cls,
1320 addr, addrlen)) )
1321 {
1322#if DEBUG_CLOSE
1323#if HAVE_MESSAGES
1324 MHD_DLOG (daemon,
1325 "Connection rejected, closing connection\n");
1326#endif
1327#endif
1328 if (0 != MHD_socket_close_ (client_socket))
1329 MHD_PANIC ("close failed\n");
1330 MHD_ip_limit_del (daemon, addr, addrlen);
1331#if EACCESS
1332 errno = EACCESS;
1333#endif
1334 return MHD_NO;
1335 }
1336
1337#if OSX
1338#ifdef SOL_SOCKET
1339#ifdef SO_NOSIGPIPE
1340 setsockopt (client_socket,
1341 SOL_SOCKET, SO_NOSIGPIPE,
1342 &on, sizeof (on));
1343#endif
1344#endif
1345#endif
1346
1347 if (NULL == (connection = malloc (sizeof (struct MHD_Connection))))
1348 {
1349 eno = errno;
1350#if HAVE_MESSAGES
1351 MHD_DLOG (daemon,
1352 "Error allocating memory: %s\n",
1353 MHD_strerror_ (errno));
1354#endif
1355 if (0 != MHD_socket_close_ (client_socket))
1356 MHD_PANIC ("close failed\n");
1357 MHD_ip_limit_del (daemon, addr, addrlen);
1358 errno = eno;
1359 return MHD_NO;
1360 }
1361 memset (connection,
1362 0,
1363 sizeof (struct MHD_Connection));
1364 connection->pool = MHD_pool_create (daemon->pool_size);
1365 if (NULL == connection->pool)
1366 {
1367#if HAVE_MESSAGES
1368 MHD_DLOG (daemon,
1369 "Error allocating memory: %s\n",
1370 MHD_strerror_ (errno));
1371#endif
1372 if (0 != MHD_socket_close_ (client_socket))
1373 MHD_PANIC ("close failed\n");
1374 MHD_ip_limit_del (daemon, addr, addrlen);
1375 free (connection);
1376#if ENOMEM
1377 errno = ENOMEM;
1378#endif
1379 return MHD_NO;
1380 }
1381
1382 connection->connection_timeout = daemon->connection_timeout;
1383 if (NULL == (connection->addr = malloc (addrlen)))
1384 {
1385 eno = errno;
1386#if HAVE_MESSAGES
1387 MHD_DLOG (daemon,
1388 "Error allocating memory: %s\n",
1389 MHD_strerror_ (errno));
1390#endif
1391 if (0 != MHD_socket_close_ (client_socket))
1392 MHD_PANIC ("close failed\n");
1393 MHD_ip_limit_del (daemon, addr, addrlen);
1394 MHD_pool_destroy (connection->pool);
1395 free (connection);
1396 errno = eno;
1397 return MHD_NO;
1398 }
1399 memcpy (connection->addr, addr, addrlen);
1400 connection->addr_len = addrlen;
1401 connection->socket_fd = client_socket;
1402 connection->daemon = daemon;
1403 connection->last_activity = MHD_monotonic_time();
1404
1405 /* set default connection handlers */
1406 MHD_set_http_callbacks_ (connection);
1407 connection->recv_cls = &recv_param_adapter;
1408 connection->send_cls = &send_param_adapter;
1409
1410 if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
1411 {
1412 /* non-blocking sockets are required on most systems and for GNUtls;
1413 however, they somehow cause serious problems on CYGWIN (#1824);
1414 in turbo mode, we assume that non-blocking was already set
1415 by 'accept4' or whoever calls 'MHD_add_connection' */
1416#ifdef CYGWIN
1417 if (0 != (daemon->options & MHD_USE_SSL))
1418#endif
1419 {
1420 /* make socket non-blocking */
1421#if !defined(WINDOWS) || defined(CYGWIN)
1422 int flags = fcntl (connection->socket_fd, F_GETFL);
1423 if ( (-1 == flags) ||
1424 (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
1425 {
1426#if HAVE_MESSAGES
1427 MHD_DLOG (daemon,
1428 "Failed to make socket non-blocking: %s\n",
1429 MHD_socket_last_strerr_ ());
1430#endif
1431 }
1432#else
1433 unsigned long flags = 1;
1434 if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
1435 {
1436#if HAVE_MESSAGES
1437 MHD_DLOG (daemon,
1438 "Failed to make socket non-blocking: %s\n",
1439 MHD_socket_last_strerr_ ());
1440#endif
1441 }
1442#endif
1443 }
1444 }
1445
1446#if HTTPS_SUPPORT
1447 if (0 != (daemon->options & MHD_USE_SSL))
1448 {
1449 connection->recv_cls = &recv_tls_adapter;
1450 connection->send_cls = &send_tls_adapter;
1451 connection->state = MHD_TLS_CONNECTION_INIT;
1452 MHD_set_https_callbacks (connection);
1453 gnutls_init (&connection->tls_session, GNUTLS_SERVER);
1454 gnutls_priority_set (connection->tls_session,
1455 daemon->priority_cache);
1456 switch (daemon->cred_type)
1457 {
1458 /* set needed credentials for certificate authentication. */
1459 case GNUTLS_CRD_CERTIFICATE:
1460 gnutls_credentials_set (connection->tls_session,
1461 GNUTLS_CRD_CERTIFICATE,
1462 daemon->x509_cred);
1463 break;
1464 default:
1465#if HAVE_MESSAGES
1466 MHD_DLOG (connection->daemon,
1467 "Failed to setup TLS credentials: unknown credential type %d\n",
1468 daemon->cred_type);
1469#endif
1470 if (0 != MHD_socket_close_ (client_socket))
1471 MHD_PANIC ("close failed\n");
1472 MHD_ip_limit_del (daemon, addr, addrlen);
1473 free (connection->addr);
1474 free (connection);
1475 MHD_PANIC ("Unknown credential type");
1476#if EINVAL
1477 errno = EINVAL;
1478#endif
1479 return MHD_NO;
1480 }
1481 gnutls_transport_set_ptr (connection->tls_session,
1482 (gnutls_transport_ptr_t) connection);
1483 gnutls_transport_set_pull_function (connection->tls_session,
1484 (gnutls_pull_func) &recv_param_adapter);
1485 gnutls_transport_set_push_function (connection->tls_session,
1486 (gnutls_push_func) &send_param_adapter);
1487
1488 if (daemon->https_mem_trust)
1489 gnutls_certificate_server_set_request (connection->tls_session,
1490 GNUTLS_CERT_REQUEST);
1491 }
1492#endif
1493
1494 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1495 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1496 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1497 XDLL_insert (daemon->normal_timeout_head,
1498 daemon->normal_timeout_tail,
1499 connection);
1500 DLL_insert (daemon->connections_head,
1501 daemon->connections_tail,
1502 connection);
1503 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1504 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1505 MHD_PANIC ("Failed to release cleanup mutex\n");
1506
1507 if (NULL != daemon->notify_connection)
1508 daemon->notify_connection (daemon->notify_connection_cls,
1509 connection,
1510 &connection->socket_context,
1511 MHD_CONNECTION_NOTIFY_STARTED);
1512
1513 /* attempt to create handler thread */
1514 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1515 {
1516 res_thread_create = create_thread (&connection->pid,
1517 daemon,
1518 &MHD_handle_connection,
1519 connection);
1520 if (0 != res_thread_create)
1521 {
1522 eno = errno;
1523#if HAVE_MESSAGES
1524 MHD_DLOG (daemon,
1525 "Failed to create a thread: %s\n",
1526 MHD_strerror_ (res_thread_create));
1527#endif
1528 goto cleanup;
1529 }
1530 }
1531 else
1532 if ( (MHD_YES == external_add) &&
1533 (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1534 (1 != MHD_pipe_write_ (daemon->wpipe[1], "n", 1)) )
1535 {
1536#if HAVE_MESSAGES
1537 MHD_DLOG (daemon,
1538 "failed to signal new connection via pipe");
1539#endif
1540 }
1541#if EPOLL_SUPPORT
1542 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1543 {
1544 if (0 == (daemon->options & MHD_USE_EPOLL_TURBO))
1545 {
1546 struct epoll_event event;
1547
1548 event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1549 event.data.ptr = connection;
1550 if (0 != epoll_ctl (daemon->epoll_fd,
1551 EPOLL_CTL_ADD,
1552 client_socket,
1553 &event))
1554 {
1555 eno = errno;
1556#if HAVE_MESSAGES
1557 MHD_DLOG (daemon,
1558 "Call to epoll_ctl failed: %s\n",
1559 MHD_socket_last_strerr_ ());
1560#endif
1561 goto cleanup;
1562 }
1563 connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1564 }
1565 else
1566 {
1567 connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
1568 | MHD_EPOLL_STATE_IN_EREADY_EDLL;
1569 EDLL_insert (daemon->eready_head,
1570 daemon->eready_tail,
1571 connection);
1572 }
1573 }
1574#endif
1575 daemon->connections++;
1576 return MHD_YES;
1577 cleanup:
1578 if (NULL != daemon->notify_connection)
1579 daemon->notify_connection (daemon->notify_connection_cls,
1580 connection,
1581 &connection->socket_context,
1582 MHD_CONNECTION_NOTIFY_CLOSED);
1583 if (0 != MHD_socket_close_ (client_socket))
1584 MHD_PANIC ("close failed\n");
1585 MHD_ip_limit_del (daemon, addr, addrlen);
1586 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1587 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1588 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1589 DLL_remove (daemon->connections_head,
1590 daemon->connections_tail,
1591 connection);
1592 XDLL_remove (daemon->normal_timeout_head,
1593 daemon->normal_timeout_tail,
1594 connection);
1595 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1596 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1597 MHD_PANIC ("Failed to release cleanup mutex\n");
1598 MHD_pool_destroy (connection->pool);
1599 free (connection->addr);
1600 free (connection);
1601#if EINVAL
1602 errno = eno;
1603#endif
1604 return MHD_NO;
1605}
1606
1607
1608/**
1609 * Suspend handling of network data for a given connection. This can
1610 * be used to dequeue a connection from MHD's event loop (external
1611 * select, internal select or thread pool; not applicable to
1612 * thread-per-connection!) for a while.
1613 *
1614 * If you use this API in conjunction with a internal select or a
1615 * thread pool, you must set the option #MHD_USE_PIPE_FOR_SHUTDOWN to
1616 * ensure that a resumed connection is immediately processed by MHD.
1617 *
1618 * Suspended connections continue to count against the total number of
1619 * connections allowed (per daemon, as well as per IP, if such limits
1620 * are set). Suspended connections will NOT time out; timeouts will
1621 * restart when the connection handling is resumed. While a
1622 * connection is suspended, MHD will not detect disconnects by the
1623 * client.
1624 *
1625 * The only safe time to suspend a connection is from the
1626 * #MHD_AccessHandlerCallback.
1627 *
1628 * Finally, it is an API violation to call #MHD_stop_daemon while
1629 * having suspended connections (this will at least create memory and
1630 * socket leaks or lead to undefined behavior). You must explicitly
1631 * resume all connections before stopping the daemon.
1632 *
1633 * @param connection the connection to suspend
1634 */
1635void
1636MHD_suspend_connection (struct MHD_Connection *connection)
1637{
1638 struct MHD_Daemon *daemon;
1639
1640 daemon = connection->daemon;
1641 if (MHD_USE_SUSPEND_RESUME != (daemon->options & MHD_USE_SUSPEND_RESUME))
1642 MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1643 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1644 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1645 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1646 DLL_remove (daemon->connections_head,
1647 daemon->connections_tail,
1648 connection);
1649 DLL_insert (daemon->suspended_connections_head,
1650 daemon->suspended_connections_tail,
1651 connection);
1652 if (connection->connection_timeout == daemon->connection_timeout)
1653 XDLL_remove (daemon->normal_timeout_head,
1654 daemon->normal_timeout_tail,
1655 connection);
1656 else
1657 XDLL_remove (daemon->manual_timeout_head,
1658 daemon->manual_timeout_tail,
1659 connection);
1660#if EPOLL_SUPPORT
1661 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1662 {
1663 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1664 {
1665 EDLL_remove (daemon->eready_head,
1666 daemon->eready_tail,
1667 connection);
1668 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
1669 }
1670 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
1671 {
1672 if (0 != epoll_ctl (daemon->epoll_fd,
1673 EPOLL_CTL_DEL,
1674 connection->socket_fd,
1675 NULL))
1676 MHD_PANIC ("Failed to remove FD from epoll set\n");
1677 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1678 }
1679 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
1680 }
1681#endif
1682 connection->suspended = MHD_YES;
1683 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1684 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1685 MHD_PANIC ("Failed to release cleanup mutex\n");
1686}
1687
1688
1689/**
1690 * Resume handling of network data for suspended connection. It is
1691 * safe to resume a suspended connection at any time. Calling this function
1692 * on a connection that was not previously suspended will result
1693 * in undefined behavior.
1694 *
1695 * @param connection the connection to resume
1696 */
1697void
1698MHD_resume_connection (struct MHD_Connection *connection)
1699{
1700 struct MHD_Daemon *daemon;
1701
1702 daemon = connection->daemon;
1703 if (MHD_USE_SUSPEND_RESUME != (daemon->options & MHD_USE_SUSPEND_RESUME))
1704 MHD_PANIC ("Cannot resume connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1705 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1706 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1707 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1708 connection->resuming = MHD_YES;
1709 daemon->resuming = MHD_YES;
1710 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1711 (1 != MHD_pipe_write_ (daemon->wpipe[1], "r", 1)) )
1712 {
1713#if HAVE_MESSAGES
1714 MHD_DLOG (daemon,
1715 "failed to signal resume via pipe");
1716#endif
1717 }
1718 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1719 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1720 MHD_PANIC ("Failed to release cleanup mutex\n");
1721}
1722
1723
1724/**
1725 * Run through the suspended connections and move any that are no
1726 * longer suspended back to the active state.
1727 *
1728 * @param daemon daemon context
1729 * @return #MHD_YES if a connection was actually resumed
1730 */
1731static int
1732resume_suspended_connections (struct MHD_Daemon *daemon)
1733{
1734 struct MHD_Connection *pos;
1735 struct MHD_Connection *next = NULL;
1736 int ret;
1737
1738 ret = MHD_NO;
1739 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1740 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1741 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1742 if (MHD_YES == daemon->resuming)
1743 next = daemon->suspended_connections_head;
1744
1745 while (NULL != (pos = next))
1746 {
1747 next = pos->next;
1748 if (MHD_NO == pos->resuming)
1749 continue;
1750 ret = MHD_YES;
1751 DLL_remove (daemon->suspended_connections_head,
1752 daemon->suspended_connections_tail,
1753 pos);
1754 DLL_insert (daemon->connections_head,
1755 daemon->connections_tail,
1756 pos);
1757 if (pos->connection_timeout == daemon->connection_timeout)
1758 XDLL_insert (daemon->normal_timeout_head,
1759 daemon->normal_timeout_tail,
1760 pos);
1761 else
1762 XDLL_insert (daemon->manual_timeout_head,
1763 daemon->manual_timeout_tail,
1764 pos);
1765#if EPOLL_SUPPORT
1766 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1767 {
1768 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1769 MHD_PANIC ("Resumed connection was already in EREADY set\n");
1770 /* we always mark resumed connections as ready, as we
1771 might have missed the edge poll event during suspension */
1772 EDLL_insert (daemon->eready_head,
1773 daemon->eready_tail,
1774 pos);
1775 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
1776 pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
1777 }
1778#endif
1779 pos->suspended = MHD_NO;
1780 pos->resuming = MHD_NO;
1781 }
1782 daemon->resuming = MHD_NO;
1783 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1784 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1785 MHD_PANIC ("Failed to release cleanup mutex\n");
1786 return ret;
1787}
1788
1789
1790/**
1791 * Change socket options to be non-blocking, non-inheritable.
1792 *
1793 * @param daemon daemon context
1794 * @param sock socket to manipulate
1795 */
1796static void
1797make_nonblocking_noninheritable (struct MHD_Daemon *daemon,
1798 MHD_socket sock)
1799{
1800#ifdef WINDOWS
1801 DWORD dwFlags;
1802 unsigned long flags = 1;
1803
1804 if (0 != ioctlsocket (sock, FIONBIO, &flags))
1805 {
1806#if HAVE_MESSAGES
1807 MHD_DLOG (daemon,
1808 "Failed to make socket non-blocking: %s\n",
1809 MHD_socket_last_strerr_ ());
1810#endif
1811 }
1812 if (!GetHandleInformation ((HANDLE) sock, &dwFlags) ||
1813 ((dwFlags != (dwFlags & ~HANDLE_FLAG_INHERIT)) &&
1814 !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)))
1815 {
1816#if HAVE_MESSAGES
1817 MHD_DLOG (daemon,
1818 "Failed to make socket non-inheritable: %u\n",
1819 (unsigned int) GetLastError ());
1820#endif
1821 }
1822#else
1823 int flags;
1824 int nonblock;
1825
1826 nonblock = O_NONBLOCK;
1827#ifdef CYGWIN
1828 if (0 == (daemon->options & MHD_USE_SSL))
1829 nonblock = 0;
1830#endif
1831 flags = fcntl (sock, F_GETFD);
1832 if ( ( (-1 == flags) ||
1833 ( (flags != (flags | FD_CLOEXEC)) &&
1834 (0 != fcntl (sock, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) )
1835 {
1836#if HAVE_MESSAGES
1837 MHD_DLOG (daemon,
1838 "Failed to make socket non-inheritable: %s\n",
1839 MHD_socket_last_strerr_ ());
1840#endif
1841 }
1842#endif
1843}
1844
1845
1846/**
1847 * Add another client connection to the set of connections managed by
1848 * MHD. This API is usually not needed (since MHD will accept inbound
1849 * connections on the server socket). Use this API in special cases,
1850 * for example if your HTTP server is behind NAT and needs to connect
1851 * out to the HTTP client, or if you are building a proxy.
1852 *
1853 * If you use this API in conjunction with a internal select or a
1854 * thread pool, you must set the option
1855 * #MHD_USE_PIPE_FOR_SHUTDOWN to ensure that the freshly added
1856 * connection is immediately processed by MHD.
1857 *
1858 * The given client socket will be managed (and closed!) by MHD after
1859 * this call and must no longer be used directly by the application
1860 * afterwards.
1861 *
1862 * Per-IP connection limits are ignored when using this API.
1863 *
1864 * @param daemon daemon that manages the connection
1865 * @param client_socket socket to manage (MHD will expect
1866 * to receive an HTTP request from this socket next).
1867 * @param addr IP address of the client
1868 * @param addrlen number of bytes in @a addr
1869 * @return #MHD_YES on success, #MHD_NO if this daemon could
1870 * not handle the connection (i.e. malloc() failed, etc).
1871 * The socket will be closed in any case; `errno` is
1872 * set to indicate further details about the error.
1873 * @ingroup specialized
1874 */
1875int
1876MHD_add_connection (struct MHD_Daemon *daemon,
1877 MHD_socket client_socket,
1878 const struct sockaddr *addr,
1879 socklen_t addrlen)
1880{
1881 make_nonblocking_noninheritable (daemon,
1882 client_socket);
1883 return internal_add_connection (daemon,
1884 client_socket,
1885 addr, addrlen,
1886 MHD_YES);
1887}
1888
1889
1890/**
1891 * Accept an incoming connection and create the MHD_Connection object for
1892 * it. This function also enforces policy by way of checking with the
1893 * accept policy callback.
1894 *
1895 * @param daemon handle with the listen socket
1896 * @return #MHD_YES on success (connections denied by policy or due
1897 * to 'out of memory' and similar errors) are still considered
1898 * successful as far as #MHD_accept_connection() is concerned);
1899 * a return code of #MHD_NO only refers to the actual
1900 * accept() system call.
1901 */
1902static int
1903MHD_accept_connection (struct MHD_Daemon *daemon)
1904{
1905#if HAVE_INET6
1906 struct sockaddr_in6 addrstorage;
1907#else
1908 struct sockaddr_in addrstorage;
1909#endif
1910 struct sockaddr *addr = (struct sockaddr *) &addrstorage;
1911 socklen_t addrlen;
1912 MHD_socket s;
1913 MHD_socket fd;
1914 int nonblock;
1915
1916 addrlen = sizeof (addrstorage);
1917 memset (addr, 0, sizeof (addrstorage));
1918 if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd))
1919 return MHD_NO;
1920#ifdef HAVE_SOCK_NONBLOCK
1921 nonblock = SOCK_NONBLOCK;
1922#else
1923 nonblock = 0;
1924#endif
1925#ifdef CYGWIN
1926 if (0 == (daemon->options & MHD_USE_SSL))
1927 nonblock = 0;
1928#endif
1929#if HAVE_ACCEPT4
1930 s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock);
1931#else
1932 s = accept (fd, addr, &addrlen);
1933#endif
1934 if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0))
1935 {
1936#if HAVE_MESSAGES
1937 const int err = MHD_socket_errno_;
1938 /* This could be a common occurance with multiple worker threads */
1939 if ( (EINVAL == err) &&
1940 (MHD_INVALID_SOCKET == daemon->socket_fd) )
1941 return MHD_NO; /* can happen during shutdown */
1942 if ((EAGAIN != err) && (EWOULDBLOCK != err))
1943 MHD_DLOG (daemon,
1944 "Error accepting connection: %s\n",
1945 MHD_socket_last_strerr_ ());
1946#endif
1947 if (MHD_INVALID_SOCKET != s)
1948 {
1949 if (0 != MHD_socket_close_ (s))
1950 MHD_PANIC ("close failed\n");
1951 /* just in case */
1952 }
1953 return MHD_NO;
1954 }
1955#if !defined(HAVE_ACCEPT4) || HAVE_ACCEPT4+0 == 0 || !defined(HAVE_SOCK_NONBLOCK) || SOCK_CLOEXEC+0 == 0
1956 make_nonblocking_noninheritable (daemon, s);
1957#endif
1958#if HAVE_MESSAGES
1959#if DEBUG_CONNECT
1960 MHD_DLOG (daemon,
1961 "Accepted connection on socket %d\n",
1962 s);
1963#endif
1964#endif
1965 (void) internal_add_connection (daemon, s,
1966 addr, addrlen,
1967 MHD_NO);
1968 return MHD_YES;
1969}
1970
1971
1972/**
1973 * Free resources associated with all closed connections.
1974 * (destroy responses, free buffers, etc.). All closed
1975 * connections are kept in the "cleanup" doubly-linked list.
1976 *
1977 * @param daemon daemon to clean up
1978 */
1979static void
1980MHD_cleanup_connections (struct MHD_Daemon *daemon)
1981{
1982 struct MHD_Connection *pos;
1983
1984 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1985 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1986 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1987 while (NULL != (pos = daemon->cleanup_head))
1988 {
1989 DLL_remove (daemon->cleanup_head,
1990 daemon->cleanup_tail,
1991 pos);
1992 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1993 (MHD_NO == pos->thread_joined) )
1994 {
1995 if (0 != MHD_join_thread_ (pos->pid))
1996 {
1997 MHD_PANIC ("Failed to join a thread\n");
1998 }
1999 }
2000 MHD_pool_destroy (pos->pool);
2001#if HTTPS_SUPPORT
2002 if (NULL != pos->tls_session)
2003 gnutls_deinit (pos->tls_session);
2004#endif
2005 if (NULL != daemon->notify_connection)
2006 daemon->notify_connection (daemon->notify_connection_cls,
2007 pos,
2008 &pos->socket_context,
2009 MHD_CONNECTION_NOTIFY_CLOSED);
2010 MHD_ip_limit_del (daemon, pos->addr, pos->addr_len);
2011#if EPOLL_SUPPORT
2012 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2013 {
2014 EDLL_remove (daemon->eready_head,
2015 daemon->eready_tail,
2016 pos);
2017 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2018 }
2019 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2020 (MHD_INVALID_SOCKET != daemon->epoll_fd) &&
2021 (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
2022 {
2023 /* epoll documentation suggests that closing a FD
2024 automatically removes it from the epoll set; however,
2025 this is not true as if we fail to do manually remove it,
2026 we are still seeing an event for this fd in epoll,
2027 causing grief (use-after-free...) --- at least on my
2028 system. */
2029 if (0 != epoll_ctl (daemon->epoll_fd,
2030 EPOLL_CTL_DEL,
2031 pos->socket_fd,
2032 NULL))
2033 MHD_PANIC ("Failed to remove FD from epoll set\n");
2034 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
2035 }
2036#endif
2037 if (NULL != pos->response)
2038 {
2039 MHD_destroy_response (pos->response);
2040 pos->response = NULL;
2041 }
2042 if (MHD_INVALID_SOCKET != pos->socket_fd)
2043 {
2044#ifdef WINDOWS
2045 shutdown (pos->socket_fd, SHUT_WR);
2046#endif
2047 if (0 != MHD_socket_close_ (pos->socket_fd))
2048 MHD_PANIC ("close failed\n");
2049 }
2050 if (NULL != pos->addr)
2051 free (pos->addr);
2052 free (pos);
2053 daemon->connections--;
2054 }
2055 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2056 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
2057 MHD_PANIC ("Failed to release cleanup mutex\n");
2058}
2059
2060
2061/**
2062 * Obtain timeout value for `select()` for this daemon (only needed if
2063 * connection timeout is used). The returned value is how long
2064 * `select()` or `poll()` should at most block, not the timeout value set
2065 * for connections. This function MUST NOT be called if MHD is
2066 * running with #MHD_USE_THREAD_PER_CONNECTION.
2067 *
2068 * @param daemon daemon to query for timeout
2069 * @param timeout set to the timeout (in milliseconds)
2070 * @return #MHD_YES on success, #MHD_NO if timeouts are
2071 * not used (or no connections exist that would
2072 * necessiate the use of a timeout right now).
2073 * @ingroup event
2074 */
2075int
2076MHD_get_timeout (struct MHD_Daemon *daemon,
2077 MHD_UNSIGNED_LONG_LONG *timeout)
2078{
2079 time_t earliest_deadline;
2080 time_t now;
2081 struct MHD_Connection *pos;
2082 int have_timeout;
2083
2084 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2085 {
2086#if HAVE_MESSAGES
2087 MHD_DLOG (daemon,
2088 "Illegal call to MHD_get_timeout\n");
2089#endif
2090 return MHD_NO;
2091 }
2092
2093#if HTTPS_SUPPORT
2094 if (0 != daemon->num_tls_read_ready)
2095 {
2096 /* if there is any TLS connection with data ready for
2097 reading, we must not block in the event loop */
2098 *timeout = 0;
2099 return MHD_YES;
2100 }
2101#endif
2102
2103 have_timeout = MHD_NO;
2104 earliest_deadline = 0; /* avoid compiler warnings */
2105 for (pos = daemon->manual_timeout_head; NULL != pos; pos = pos->nextX)
2106 {
2107 if (0 != pos->connection_timeout)
2108 {
2109 if ( (! have_timeout) ||
2110 (earliest_deadline > pos->last_activity + pos->connection_timeout) )
2111 earliest_deadline = pos->last_activity + pos->connection_timeout;
2112#if HTTPS_SUPPORT
2113 if ( (0 != (daemon->options & MHD_USE_SSL)) &&
2114 (0 != gnutls_record_check_pending (pos->tls_session)) )
2115 earliest_deadline = 0;
2116#endif
2117 have_timeout = MHD_YES;
2118 }
2119 }
2120 /* normal timeouts are sorted, so we only need to look at the 'head' */
2121 pos = daemon->normal_timeout_head;
2122 if ( (NULL != pos) &&
2123 (0 != pos->connection_timeout) )
2124 {
2125 if ( (! have_timeout) ||
2126 (earliest_deadline > pos->last_activity + pos->connection_timeout) )
2127 earliest_deadline = pos->last_activity + pos->connection_timeout;
2128#if HTTPS_SUPPORT
2129 if ( (0 != (daemon->options & MHD_USE_SSL)) &&
2130 (0 != gnutls_record_check_pending (pos->tls_session)) )
2131 earliest_deadline = 0;
2132#endif
2133 have_timeout = MHD_YES;
2134 }
2135
2136 if (MHD_NO == have_timeout)
2137 return MHD_NO;
2138 now = MHD_monotonic_time();
2139 if (earliest_deadline < now)
2140 *timeout = 0;
2141 else
2142 *timeout = 1000 * (1 + earliest_deadline - now);
2143 return MHD_YES;
2144}
2145
2146
2147/**
2148 * Run webserver operations. This method should be called by clients
2149 * in combination with #MHD_get_fdset if the client-controlled select
2150 * method is used.
2151 *
2152 * You can use this function instead of #MHD_run if you called
2153 * `select()` on the result from #MHD_get_fdset. File descriptors in
2154 * the sets that are not controlled by MHD will be ignored. Calling
2155 * this function instead of #MHD_run is more efficient as MHD will
2156 * not have to call `select()` again to determine which operations are
2157 * ready.
2158 *
2159 * @param daemon daemon to run select loop for
2160 * @param read_fd_set read set
2161 * @param write_fd_set write set
2162 * @param except_fd_set except set (not used, can be NULL)
2163 * @return #MHD_NO on serious errors, #MHD_YES on success
2164 * @ingroup event
2165 */
2166int
2167MHD_run_from_select (struct MHD_Daemon *daemon,
2168 const fd_set *read_fd_set,
2169 const fd_set *write_fd_set,
2170 const fd_set *except_fd_set)
2171{
2172 MHD_socket ds;
2173 char tmp;
2174 struct MHD_Connection *pos;
2175 struct MHD_Connection *next;
2176
2177#if EPOLL_SUPPORT
2178 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2179 {
2180 /* we're in epoll mode, the epoll FD stands for
2181 the entire event set! */
2182 if (daemon->epoll_fd >= FD_SETSIZE)
2183 return MHD_NO; /* poll fd too big, fail hard */
2184 if (FD_ISSET (daemon->epoll_fd, read_fd_set))
2185 return MHD_run (daemon);
2186 return MHD_YES;
2187 }
2188#endif
2189
2190 /* select connection thread handling type */
2191 if ( (MHD_INVALID_SOCKET != (ds = daemon->socket_fd)) &&
2192 (FD_ISSET (ds, read_fd_set)) )
2193 (void) MHD_accept_connection (daemon);
2194 /* drain signaling pipe to avoid spinning select */
2195 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2196 (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
2197 (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2198
2199 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2200 {
2201 /* do not have a thread per connection, process all connections now */
2202 next = daemon->connections_head;
2203 while (NULL != (pos = next))
2204 {
2205 next = pos->next;
2206 ds = pos->socket_fd;
2207 if (MHD_INVALID_SOCKET == ds)
2208 continue;
2209 switch (pos->event_loop_info)
2210 {
2211 case MHD_EVENT_LOOP_INFO_READ:
2212 if ( (FD_ISSET (ds, read_fd_set))
2213#if HTTPS_SUPPORT
2214 || (MHD_YES == pos->tls_read_ready)
2215#endif
2216 )
2217 pos->read_handler (pos);
2218 break;
2219 case MHD_EVENT_LOOP_INFO_WRITE:
2220 if ( (FD_ISSET (ds, read_fd_set)) &&
2221 (pos->read_buffer_size > pos->read_buffer_offset) )
2222 pos->read_handler (pos);
2223 if (FD_ISSET (ds, write_fd_set))
2224 pos->write_handler (pos);
2225 break;
2226 case MHD_EVENT_LOOP_INFO_BLOCK:
2227 if ( (FD_ISSET (ds, read_fd_set)) &&
2228 (pos->read_buffer_size > pos->read_buffer_offset) )
2229 pos->read_handler (pos);
2230 break;
2231 case MHD_EVENT_LOOP_INFO_CLEANUP:
2232 /* should never happen */
2233 break;
2234 }
2235 pos->idle_handler (pos);
2236 }
2237 }
2238 MHD_cleanup_connections (daemon);
2239 return MHD_YES;
2240}
2241
2242
2243/**
2244 * Main internal select() call. Will compute select sets, call select()
2245 * and then #MHD_run_from_select with the result.
2246 *
2247 * @param daemon daemon to run select() loop for
2248 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
2249 * @return #MHD_NO on serious errors, #MHD_YES on success
2250 */
2251static int
2252MHD_select (struct MHD_Daemon *daemon,
2253 int may_block)
2254{
2255 int num_ready;
2256 fd_set rs;
2257 fd_set ws;
2258 fd_set es;
2259 MHD_socket max;
2260 struct timeval timeout;
2261 struct timeval *tv;
2262 MHD_UNSIGNED_LONG_LONG ltimeout;
2263
2264 timeout.tv_sec = 0;
2265 timeout.tv_usec = 0;
2266 if (MHD_YES == daemon->shutdown)
2267 return MHD_NO;
2268 FD_ZERO (&rs);
2269 FD_ZERO (&ws);
2270 FD_ZERO (&es);
2271 max = MHD_INVALID_SOCKET;
2272 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2273 {
2274 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) &&
2275 (MHD_YES == resume_suspended_connections (daemon)) )
2276 may_block = MHD_NO;
2277
2278 /* single-threaded, go over everything */
2279 if (MHD_NO == MHD_get_fdset2 (daemon, &rs, &ws, &es, &max, FD_SETSIZE))
2280 return MHD_NO;
2281
2282 /* If we're at the connection limit, no need to
2283 accept new connections; however, make sure
2284 we do not miss the shutdown, so only do this
2285 optimization if we have a shutdown signaling
2286 pipe. */
2287 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2288 (daemon->connections == daemon->connection_limit) &&
2289 (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) )
2290 FD_CLR (daemon->socket_fd, &rs);
2291 }
2292 else
2293 {
2294 /* accept only, have one thread per connection */
2295 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2296 (MHD_YES != add_to_fd_set (daemon->socket_fd,
2297 &rs,
2298 &max,
2299 FD_SETSIZE)) )
2300 return MHD_NO;
2301 }
2302 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2303 (MHD_YES != add_to_fd_set (daemon->wpipe[0],
2304 &rs,
2305 &max,
2306 FD_SETSIZE)) )
2307 return MHD_NO;
2308
2309 tv = NULL;
2310 if (MHD_NO == may_block)
2311 {
2312 timeout.tv_usec = 0;
2313 timeout.tv_sec = 0;
2314 tv = &timeout;
2315 }
2316 else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2317 (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
2318 {
2319 /* ltimeout is in ms */
2320 timeout.tv_usec = (ltimeout % 1000) * 1000;
2321 timeout.tv_sec = ltimeout / 1000;
2322 tv = &timeout;
2323 }
2324 if (MHD_INVALID_SOCKET == max)
2325 return MHD_YES;
2326 num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, &es, tv);
2327 if (MHD_YES == daemon->shutdown)
2328 return MHD_NO;
2329 if (num_ready < 0)
2330 {
2331 if (EINTR == MHD_socket_errno_)
2332 return MHD_YES;
2333#if HAVE_MESSAGES
2334 MHD_DLOG (daemon,
2335 "select failed: %s\n",
2336 MHD_socket_last_strerr_ ());
2337#endif
2338 return MHD_NO;
2339 }
2340 return MHD_run_from_select (daemon, &rs, &ws, &es);
2341}
2342
2343
2344#ifdef HAVE_POLL
2345/**
2346 * Process all of our connections and possibly the server
2347 * socket using poll().
2348 *
2349 * @param daemon daemon to run poll loop for
2350 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
2351 * @return #MHD_NO on serious errors, #MHD_YES on success
2352 */
2353static int
2354MHD_poll_all (struct MHD_Daemon *daemon,
2355 int may_block)
2356{
2357 unsigned int num_connections;
2358 struct MHD_Connection *pos;
2359 struct MHD_Connection *next;
2360
2361 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) &&
2362 (MHD_YES == resume_suspended_connections (daemon)) )
2363 may_block = MHD_NO;
2364
2365 /* count number of connections and thus determine poll set size */
2366 num_connections = 0;
2367 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2368 num_connections++;
2369 {
2370 MHD_UNSIGNED_LONG_LONG ltimeout;
2371 unsigned int i;
2372 int timeout;
2373 unsigned int poll_server;
2374 int poll_listen;
2375 int poll_pipe;
2376 char tmp;
2377 struct pollfd *p;
2378
2379 p = malloc(sizeof (struct pollfd) * (2 + num_connections));
2380 if (NULL == p)
2381 {
2382#if HAVE_MESSAGES
2383 MHD_DLOG(daemon,
2384 "Error allocating memory: %s\n",
2385 MHD_strerror_(errno));
2386#endif
2387 return MHD_NO;
2388 }
2389 memset (p, 0, sizeof (struct pollfd) * (2 + num_connections));
2390 poll_server = 0;
2391 poll_listen = -1;
2392 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2393 (daemon->connections < daemon->connection_limit) )
2394 {
2395 /* only listen if we are not at the connection limit */
2396 p[poll_server].fd = daemon->socket_fd;
2397 p[poll_server].events = POLLIN;
2398 p[poll_server].revents = 0;
2399 poll_listen = (int) poll_server;
2400 poll_server++;
2401 }
2402 poll_pipe = -1;
2403 if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2404 {
2405 p[poll_server].fd = daemon->wpipe[0];
2406 p[poll_server].events = POLLIN;
2407 p[poll_server].revents = 0;
2408 poll_pipe = (int) poll_server;
2409 poll_server++;
2410 }
2411 if (may_block == MHD_NO)
2412 timeout = 0;
2413 else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2414 (MHD_YES != MHD_get_timeout (daemon, &ltimeout)) )
2415 timeout = -1;
2416 else
2417 timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
2418
2419 i = 0;
2420 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2421 {
2422 p[poll_server+i].fd = pos->socket_fd;
2423 switch (pos->event_loop_info)
2424 {
2425 case MHD_EVENT_LOOP_INFO_READ:
2426 p[poll_server+i].events |= POLLIN;
2427 break;
2428 case MHD_EVENT_LOOP_INFO_WRITE:
2429 p[poll_server+i].events |= POLLOUT;
2430 if (pos->read_buffer_size > pos->read_buffer_offset)
2431 p[poll_server+i].events |= POLLIN;
2432 break;
2433 case MHD_EVENT_LOOP_INFO_BLOCK:
2434 if (pos->read_buffer_size > pos->read_buffer_offset)
2435 p[poll_server+i].events |= POLLIN;
2436 break;
2437 case MHD_EVENT_LOOP_INFO_CLEANUP:
2438 timeout = 0; /* clean up "pos" immediately */
2439 break;
2440 }
2441 i++;
2442 }
2443 if (0 == poll_server + num_connections)
2444 {
2445 free(p);
2446 return MHD_YES;
2447 }
2448 if (MHD_sys_poll_(p, poll_server + num_connections, timeout) < 0)
2449 {
2450 if (EINTR == MHD_socket_errno_)
2451 {
2452 free(p);
2453 return MHD_YES;
2454 }
2455#if HAVE_MESSAGES
2456 MHD_DLOG (daemon,
2457 "poll failed: %s\n",
2458 MHD_socket_last_strerr_ ());
2459#endif
2460 free(p);
2461 return MHD_NO;
2462 }
2463 /* handle shutdown */
2464 if (MHD_YES == daemon->shutdown)
2465 {
2466 free(p);
2467 return MHD_NO;
2468 }
2469 i = 0;
2470 next = daemon->connections_head;
2471 while (NULL != (pos = next))
2472 {
2473 next = pos->next;
2474 switch (pos->event_loop_info)
2475 {
2476 case MHD_EVENT_LOOP_INFO_READ:
2477 /* first, sanity checks */
2478 if (i >= num_connections)
2479 break; /* connection list changed somehow, retry later ... */
2480 if (p[poll_server+i].fd != pos->socket_fd)
2481 break; /* fd mismatch, something else happened, retry later ... */
2482 /* normal handling */
2483 if (0 != (p[poll_server+i].revents & POLLIN))
2484 pos->read_handler (pos);
2485 pos->idle_handler (pos);
2486 i++;
2487 break;
2488 case MHD_EVENT_LOOP_INFO_WRITE:
2489 /* first, sanity checks */
2490 if (i >= num_connections)
2491 break; /* connection list changed somehow, retry later ... */
2492 if (p[poll_server+i].fd != pos->socket_fd)
2493 break; /* fd mismatch, something else happened, retry later ... */
2494 /* normal handling */
2495 if (0 != (p[poll_server+i].revents & POLLIN))
2496 pos->read_handler (pos);
2497 if (0 != (p[poll_server+i].revents & POLLOUT))
2498 pos->write_handler (pos);
2499 pos->idle_handler (pos);
2500 i++;
2501 break;
2502 case MHD_EVENT_LOOP_INFO_BLOCK:
2503 if (0 != (p[poll_server+i].revents & POLLIN))
2504 pos->read_handler (pos);
2505 pos->idle_handler (pos);
2506 break;
2507 case MHD_EVENT_LOOP_INFO_CLEANUP:
2508 pos->idle_handler (pos);
2509 break;
2510 }
2511 }
2512 /* handle 'listen' FD */
2513 if ( (-1 != poll_listen) &&
2514 (0 != (p[poll_listen].revents & POLLIN)) )
2515 (void) MHD_accept_connection (daemon);
2516
2517 /* handle pipe FD */
2518 if ( (-1 != poll_pipe) &&
2519 (0 != (p[poll_pipe].revents & POLLIN)) )
2520 (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2521
2522 free(p);
2523 }
2524 return MHD_YES;
2525}
2526
2527
2528/**
2529 * Process only the listen socket using poll().
2530 *
2531 * @param daemon daemon to run poll loop for
2532 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
2533 * @return #MHD_NO on serious errors, #MHD_YES on success
2534 */
2535static int
2536MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2537 int may_block)
2538{
2539 struct pollfd p[2];
2540 int timeout;
2541 unsigned int poll_count;
2542 int poll_listen;
2543
2544 memset (&p, 0, sizeof (p));
2545 poll_count = 0;
2546 poll_listen = -1;
2547 if (MHD_INVALID_SOCKET != daemon->socket_fd)
2548 {
2549 p[poll_count].fd = daemon->socket_fd;
2550 p[poll_count].events = POLLIN;
2551 p[poll_count].revents = 0;
2552 poll_listen = poll_count;
2553 poll_count++;
2554 }
2555 if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2556 {
2557 p[poll_count].fd = daemon->wpipe[0];
2558 p[poll_count].events = POLLIN;
2559 p[poll_count].revents = 0;
2560 poll_count++;
2561 }
2562 if (MHD_NO == may_block)
2563 timeout = 0;
2564 else
2565 timeout = -1;
2566 if (0 == poll_count)
2567 return MHD_YES;
2568 if (MHD_sys_poll_(p, poll_count, timeout) < 0)
2569 {
2570 if (EINTR == MHD_socket_errno_)
2571 return MHD_YES;
2572#if HAVE_MESSAGES
2573 MHD_DLOG (daemon,
2574 "poll failed: %s\n",
2575 MHD_socket_last_strerr_ ());
2576#endif
2577 return MHD_NO;
2578 }
2579 /* handle shutdown */
2580 if (MHD_YES == daemon->shutdown)
2581 return MHD_NO;
2582 if ( (-1 != poll_listen) &&
2583 (0 != (p[poll_listen].revents & POLLIN)) )
2584 (void) MHD_accept_connection (daemon);
2585 return MHD_YES;
2586}
2587#endif
2588
2589
2590/**
2591 * Do poll()-based processing.
2592 *
2593 * @param daemon daemon to run poll()-loop for
2594 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
2595 * @return #MHD_NO on serious errors, #MHD_YES on success
2596 */
2597static int
2598MHD_poll (struct MHD_Daemon *daemon,
2599 int may_block)
2600{
2601#ifdef HAVE_POLL
2602 if (MHD_YES == daemon->shutdown)
2603 return MHD_NO;
2604 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2605 return MHD_poll_all (daemon, may_block);
2606 else
2607 return MHD_poll_listen_socket (daemon, may_block);
2608#else
2609 return MHD_NO;
2610#endif
2611}
2612
2613
2614#if EPOLL_SUPPORT
2615
2616/**
2617 * How many events to we process at most per epoll() call? Trade-off
2618 * between required stack-size and number of system calls we have to
2619 * make; 128 should be way enough to avoid more than one system call
2620 * for most scenarios, and still be moderate in stack size
2621 * consumption. Embedded systems might want to choose a smaller value
2622 * --- but why use epoll() on such a system in the first place?
2623 */
2624#define MAX_EVENTS 128
2625
2626
2627/**
2628 * Do epoll()-based processing (this function is allowed to
2629 * block if @a may_block is set to #MHD_YES).
2630 *
2631 * @param daemon daemon to run poll loop for
2632 * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
2633 * @return #MHD_NO on serious errors, #MHD_YES on success
2634 */
2635static int
2636MHD_epoll (struct MHD_Daemon *daemon,
2637 int may_block)
2638{
2639 struct MHD_Connection *pos;
2640 struct MHD_Connection *next;
2641 struct epoll_event events[MAX_EVENTS];
2642 struct epoll_event event;
2643 int timeout_ms;
2644 MHD_UNSIGNED_LONG_LONG timeout_ll;
2645 int num_events;
2646 unsigned int i;
2647 unsigned int series_length;
2648 char tmp;
2649
2650 if (-1 == daemon->epoll_fd)
2651 return MHD_NO; /* we're down! */
2652 if (MHD_YES == daemon->shutdown)
2653 return MHD_NO;
2654 if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2655 (daemon->connections < daemon->connection_limit) &&
2656 (MHD_NO == daemon->listen_socket_in_epoll) )
2657 {
2658 event.events = EPOLLIN;
2659 event.data.ptr = daemon;
2660 if (0 != epoll_ctl (daemon->epoll_fd,
2661 EPOLL_CTL_ADD,
2662 daemon->socket_fd,
2663 &event))
2664 {
2665#if HAVE_MESSAGES
2666 MHD_DLOG (daemon,
2667 "Call to epoll_ctl failed: %s\n",
2668 MHD_socket_last_strerr_ ());
2669#endif
2670 return MHD_NO;
2671 }
2672 daemon->listen_socket_in_epoll = MHD_YES;
2673 }
2674 if ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2675 (daemon->connections == daemon->connection_limit) )
2676 {
2677 /* we're at the connection limit, disable listen socket
2678 for event loop for now */
2679 if (0 != epoll_ctl (daemon->epoll_fd,
2680 EPOLL_CTL_DEL,
2681 daemon->socket_fd,
2682 NULL))
2683 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2684 daemon->listen_socket_in_epoll = MHD_NO;
2685 }
2686 if (MHD_YES == may_block)
2687 {
2688 if (MHD_YES == MHD_get_timeout (daemon,
2689 &timeout_ll))
2690 {
2691 if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
2692 timeout_ms = INT_MAX;
2693 else
2694 timeout_ms = (int) timeout_ll;
2695 }
2696 else
2697 timeout_ms = -1;
2698 }
2699 else
2700 timeout_ms = 0;
2701
2702 /* drain 'epoll' event queue; need to iterate as we get at most
2703 MAX_EVENTS in one system call here; in practice this should
2704 pretty much mean only one round, but better an extra loop here
2705 than unfair behavior... */
2706 num_events = MAX_EVENTS;
2707 while (MAX_EVENTS == num_events)
2708 {
2709 /* update event masks */
2710 num_events = epoll_wait (daemon->epoll_fd,
2711 events, MAX_EVENTS, timeout_ms);
2712 if (-1 == num_events)
2713 {
2714 if (EINTR == MHD_socket_errno_)
2715 return MHD_YES;
2716#if HAVE_MESSAGES
2717 MHD_DLOG (daemon,
2718 "Call to epoll_wait failed: %s\n",
2719 MHD_socket_last_strerr_ ());
2720#endif
2721 return MHD_NO;
2722 }
2723 for (i=0;i<(unsigned int) num_events;i++)
2724 {
2725 if (NULL == events[i].data.ptr)
2726 continue; /* shutdown signal! */
2727 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2728 (daemon->wpipe[0] == events[i].data.fd) )
2729 {
2730 (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2731 continue;
2732 }
2733 if (daemon != events[i].data.ptr)
2734 {
2735 /* this is an event relating to a 'normal' connection,
2736 remember the event and if appropriate mark the
2737 connection as 'eready'. */
2738 pos = events[i].data.ptr;
2739 if (0 != (events[i].events & EPOLLIN))
2740 {
2741 pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
2742 if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
2743 (pos->read_buffer_size > pos->read_buffer_offset) ) &&
2744 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2745 {
2746 EDLL_insert (daemon->eready_head,
2747 daemon->eready_tail,
2748 pos);
2749 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2750 }
2751 }
2752 if (0 != (events[i].events & EPOLLOUT))
2753 {
2754 pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
2755 if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
2756 (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2757 {
2758 EDLL_insert (daemon->eready_head,
2759 daemon->eready_tail,
2760 pos);
2761 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2762 }
2763 }
2764 }
2765 else /* must be listen socket */
2766 {
2767 /* run 'accept' until it fails or we are not allowed to take
2768 on more connections */
2769 series_length = 0;
2770 while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2771 (daemon->connections < daemon->connection_limit) &&
2772 (series_length < 128) )
2773 series_length++;
2774 }
2775 }
2776 }
2777
2778 /* we handle resumes here because we may have ready connections
2779 that will not be placed into the epoll list immediately. */
2780 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) &&
2781 (MHD_YES == resume_suspended_connections (daemon)) )
2782 may_block = MHD_NO;
2783
2784 /* process events for connections */
2785 while (NULL != (pos = daemon->eready_tail))
2786 {
2787 EDLL_remove (daemon->eready_head,
2788 daemon->eready_tail,
2789 pos);
2790 pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2791 if (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info)
2792 pos->read_handler (pos);
2793 if (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info)
2794 pos->write_handler (pos);
2795 pos->idle_handler (pos);
2796 }
2797
2798 /* Finally, handle timed-out connections; we need to do this here
2799 as the epoll mechanism won't call the 'idle_handler' on everything,
2800 as the other event loops do. As timeouts do not get an explicit
2801 event, we need to find those connections that might have timed out
2802 here.
2803
2804 Connections with custom timeouts must all be looked at, as we
2805 do not bother to sort that (presumably very short) list. */
2806 next = daemon->manual_timeout_head;
2807 while (NULL != (pos = next))
2808 {
2809 next = pos->nextX;
2810 pos->idle_handler (pos);
2811 }
2812 /* Connections with the default timeout are sorted by prepending
2813 them to the head of the list whenever we touch the connection;
2814 thus it sufficies to iterate from the tail until the first
2815 connection is NOT timed out */
2816 next = daemon->normal_timeout_tail;
2817 while (NULL != (pos = next))
2818 {
2819 next = pos->prevX;
2820 pos->idle_handler (pos);
2821 if (MHD_CONNECTION_CLOSED != pos->state)
2822 break; /* sorted by timeout, no need to visit the rest! */
2823 }
2824 return MHD_YES;
2825}
2826#endif
2827
2828
2829/**
2830 * Run webserver operations (without blocking unless in client
2831 * callbacks). This method should be called by clients in combination
2832 * with #MHD_get_fdset if the client-controlled select method is used.
2833 *
2834 * This function is a convenience method, which is useful if the
2835 * fd_sets from #MHD_get_fdset were not directly passed to `select()`;
2836 * with this function, MHD will internally do the appropriate `select()`
2837 * call itself again. While it is always safe to call #MHD_run (in
2838 * external select mode), you should call #MHD_run_from_select if
2839 * performance is important (as it saves an expensive call to
2840 * `select()`).
2841 *
2842 * @param daemon daemon to run
2843 * @return #MHD_YES on success, #MHD_NO if this
2844 * daemon was not started with the right
2845 * options for this call.
2846 * @ingroup event
2847 */
2848int
2849MHD_run (struct MHD_Daemon *daemon)
2850{
2851 if ( (MHD_YES == daemon->shutdown) ||
2852 (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2853 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2854 return MHD_NO;
2855 if (0 != (daemon->options & MHD_USE_POLL))
2856 {
2857 MHD_poll (daemon, MHD_NO);
2858 MHD_cleanup_connections (daemon);
2859 }
2860#if EPOLL_SUPPORT
2861 else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2862 {
2863 MHD_epoll (daemon, MHD_NO);
2864 MHD_cleanup_connections (daemon);
2865 }
2866#endif
2867 else
2868 {
2869 MHD_select (daemon, MHD_NO);
2870 /* MHD_select does MHD_cleanup_connections already */
2871 }
2872 return MHD_YES;
2873}
2874
2875
2876/**
2877 * Thread that runs the select loop until the daemon
2878 * is explicitly shut down.
2879 *
2880 * @param cls 'struct MHD_Deamon' to run select loop in a thread for
2881 * @return always 0 (on shutdown)
2882 */
2883static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
2884MHD_select_thread (void *cls)
2885{
2886 struct MHD_Daemon *daemon = cls;
2887
2888 while (MHD_YES != daemon->shutdown)
2889 {
2890 if (0 != (daemon->options & MHD_USE_POLL))
2891 MHD_poll (daemon, MHD_YES);
2892#if EPOLL_SUPPORT
2893 else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2894 MHD_epoll (daemon, MHD_YES);
2895#endif
2896 else
2897 MHD_select (daemon, MHD_YES);
2898 MHD_cleanup_connections (daemon);
2899 }
2900 return (MHD_THRD_RTRN_TYPE_)0;
2901}
2902
2903
2904/**
2905 * Process escape sequences ('%HH') Updates val in place; the
2906 * result should be UTF-8 encoded and cannot be larger than the input.
2907 * The result must also still be 0-terminated.
2908 *
2909 * @param cls closure (use NULL)
2910 * @param connection handle to connection, not used
2911 * @param val value to unescape (modified in the process)
2912 * @return length of the resulting val (strlen(val) maybe
2913 * shorter afterwards due to elimination of escape sequences)
2914 */
2915static size_t
2916unescape_wrapper (void *cls,
2917 struct MHD_Connection *connection,
2918 char *val)
2919{
2920 return MHD_http_unescape (val);
2921}
2922
2923
2924/**
2925 * Start a webserver on the given port. Variadic version of
2926 * #MHD_start_daemon_va.
2927 *
2928 * @param flags combination of `enum MHD_FLAG` values
2929 * @param port port to bind to
2930 * @param apc callback to call to check which clients
2931 * will be allowed to connect; you can pass NULL
2932 * in which case connections from any IP will be
2933 * accepted
2934 * @param apc_cls extra argument to @a apc
2935 * @param dh handler called for all requests (repeatedly)
2936 * @param dh_cls extra argument to @a dh
2937 * @return NULL on error, handle to daemon on success
2938 * @ingroup event
2939 */
2940struct MHD_Daemon *
2941MHD_start_daemon (unsigned int flags,
2942 uint16_t port,
2943 MHD_AcceptPolicyCallback apc,
2944 void *apc_cls,
2945 MHD_AccessHandlerCallback dh, void *dh_cls, ...)
2946{
2947 struct MHD_Daemon *daemon;
2948 va_list ap;
2949
2950 va_start (ap, dh_cls);
2951 daemon = MHD_start_daemon_va (flags, port, apc, apc_cls, dh, dh_cls, ap);
2952 va_end (ap);
2953 return daemon;
2954}
2955
2956
2957/**
2958 * Stop accepting connections from the listening socket. Allows
2959 * clients to continue processing, but stops accepting new
2960 * connections. Note that the caller is responsible for closing the
2961 * returned socket; however, if MHD is run using threads (anything but
2962 * external select mode), it must not be closed until AFTER
2963 * #MHD_stop_daemon has been called (as it is theoretically possible
2964 * that an existing thread is still using it).
2965 *
2966 * Note that some thread modes require the caller to have passed
2967 * #MHD_USE_PIPE_FOR_SHUTDOWN when using this API. If this daemon is
2968 * in one of those modes and this option was not given to
2969 * #MHD_start_daemon, this function will return #MHD_INVALID_SOCKET.
2970 *
2971 * @param daemon daemon to stop accepting new connections for
2972 * @return old listen socket on success, #MHD_INVALID_SOCKET if
2973 * the daemon was already not listening anymore
2974 * @ingroup specialized
2975 */
2976MHD_socket
2977MHD_quiesce_daemon (struct MHD_Daemon *daemon)
2978{
2979 unsigned int i;
2980 MHD_socket ret;
2981
2982 ret = daemon->socket_fd;
2983 if (MHD_INVALID_SOCKET == ret)
2984 return MHD_INVALID_SOCKET;
2985 if ( (MHD_INVALID_PIPE_ == daemon->wpipe[1]) &&
2986 (0 != (daemon->options & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION))) )
2987 {
2988#if HAVE_MESSAGES
2989 MHD_DLOG (daemon,
2990 "Using MHD_quiesce_daemon in this mode requires MHD_USE_PIPE_FOR_SHUTDOWN\n");
2991#endif
2992 return MHD_INVALID_SOCKET;
2993 }
2994
2995 if (NULL != daemon->worker_pool)
2996 for (i = 0; i < daemon->worker_pool_size; i++)
2997 {
2998 daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET;
2999#if EPOLL_SUPPORT
3000 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3001 (-1 != daemon->worker_pool[i].epoll_fd) &&
3002 (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) )
3003 {
3004 if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
3005 EPOLL_CTL_DEL,
3006 ret,
3007 NULL))
3008 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
3009 daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO;
3010 }
3011#endif
3012 }
3013 daemon->socket_fd = MHD_INVALID_SOCKET;
3014#if EPOLL_SUPPORT
3015 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3016 (-1 != daemon->epoll_fd) &&
3017 (MHD_YES == daemon->listen_socket_in_epoll) )
3018 {
3019 if (0 != epoll_ctl (daemon->epoll_fd,
3020 EPOLL_CTL_DEL,
3021 ret,
3022 NULL))
3023 MHD_PANIC ("Failed to remove listen FD from epoll set\n");
3024 daemon->listen_socket_in_epoll = MHD_NO;
3025 }
3026#endif
3027 return ret;
3028}
3029
3030
3031/**
3032 * Signature of the MHD custom logger function.
3033 *
3034 * @param cls closure
3035 * @param format format string
3036 * @param va arguments to the format string (fprintf-style)
3037 */
3038typedef void (*VfprintfFunctionPointerType)(void *cls,
3039 const char *format,
3040 va_list va);
3041
3042
3043/**
3044 * Parse a list of options given as varargs.
3045 *
3046 * @param daemon the daemon to initialize
3047 * @param servaddr where to store the server's listen address
3048 * @param ap the options
3049 * @return #MHD_YES on success, #MHD_NO on error
3050 */
3051static int
3052parse_options_va (struct MHD_Daemon *daemon,
3053 const struct sockaddr **servaddr,
3054 va_list ap);
3055
3056
3057/**
3058 * Parse a list of options given as varargs.
3059 *
3060 * @param daemon the daemon to initialize
3061 * @param servaddr where to store the server's listen address
3062 * @param ... the options
3063 * @return #MHD_YES on success, #MHD_NO on error
3064 */
3065static int
3066parse_options (struct MHD_Daemon *daemon,
3067 const struct sockaddr **servaddr,
3068 ...)
3069{
3070 va_list ap;
3071 int ret;
3072
3073 va_start (ap, servaddr);
3074 ret = parse_options_va (daemon, servaddr, ap);
3075 va_end (ap);
3076 return ret;
3077}
3078
3079
3080/**
3081 * Parse a list of options given as varargs.
3082 *
3083 * @param daemon the daemon to initialize
3084 * @param servaddr where to store the server's listen address
3085 * @param ap the options
3086 * @return #MHD_YES on success, #MHD_NO on error
3087 */
3088static int
3089parse_options_va (struct MHD_Daemon *daemon,
3090 const struct sockaddr **servaddr,
3091 va_list ap)
3092{
3093 enum MHD_OPTION opt;
3094 struct MHD_OptionItem *oa;
3095 unsigned int i;
3096#if HTTPS_SUPPORT
3097 int ret;
3098 const char *pstr;
3099#endif
3100
3101 while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
3102 {
3103 switch (opt)
3104 {
3105 case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
3106 daemon->pool_size = va_arg (ap, size_t);
3107 break;
3108 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
3109 daemon->pool_increment= va_arg (ap, size_t);
3110 break;
3111 case MHD_OPTION_CONNECTION_LIMIT:
3112 daemon->connection_limit = va_arg (ap, unsigned int);
3113 break;
3114 case MHD_OPTION_CONNECTION_TIMEOUT:
3115 daemon->connection_timeout = va_arg (ap, unsigned int);
3116 break;
3117 case MHD_OPTION_NOTIFY_COMPLETED:
3118 daemon->notify_completed =
3119 va_arg (ap, MHD_RequestCompletedCallback);
3120 daemon->notify_completed_cls = va_arg (ap, void *);
3121 break;
3122 case MHD_OPTION_NOTIFY_CONNECTION:
3123 daemon->notify_connection =
3124 va_arg (ap, MHD_NotifyConnectionCallback);
3125 daemon->notify_connection_cls = va_arg (ap, void *);
3126 break;
3127 case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
3128 daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
3129 break;
3130 case MHD_OPTION_SOCK_ADDR:
3131 *servaddr = va_arg (ap, const struct sockaddr *);
3132 break;
3133 case MHD_OPTION_URI_LOG_CALLBACK:
3134 daemon->uri_log_callback =
3135 va_arg (ap, LogCallback);
3136 daemon->uri_log_callback_cls = va_arg (ap, void *);
3137 break;
3138 case MHD_OPTION_THREAD_POOL_SIZE:
3139 daemon->worker_pool_size = va_arg (ap, unsigned int);
3140 if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon)))
3141 {
3142#if HAVE_MESSAGES
3143 MHD_DLOG (daemon,
3144 "Specified thread pool size (%u) too big\n",
3145 daemon->worker_pool_size);
3146#endif
3147 return MHD_NO;
3148 }
3149 break;
3150#if HTTPS_SUPPORT
3151 case MHD_OPTION_HTTPS_MEM_KEY:
3152 if (0 != (daemon->options & MHD_USE_SSL))
3153 daemon->https_mem_key = va_arg (ap, const char *);
3154#if HAVE_MESSAGES
3155 else
3156 MHD_DLOG (daemon,
3157 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3158 opt);
3159#endif
3160 break;
3161 case MHD_OPTION_HTTPS_KEY_PASSWORD:
3162 if (0 != (daemon->options & MHD_USE_SSL))
3163 daemon->https_key_password = va_arg (ap, const char *);
3164#if HAVE_MESSAGES
3165 else
3166 MHD_DLOG (daemon,
3167 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3168 opt);
3169#endif
3170 break;
3171 case MHD_OPTION_HTTPS_MEM_CERT:
3172 if (0 != (daemon->options & MHD_USE_SSL))
3173 daemon->https_mem_cert = va_arg (ap, const char *);
3174#if HAVE_MESSAGES
3175 else
3176 MHD_DLOG (daemon,
3177 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3178 opt);
3179#endif
3180 break;
3181 case MHD_OPTION_HTTPS_MEM_TRUST:
3182 if (0 != (daemon->options & MHD_USE_SSL))
3183 daemon->https_mem_trust = va_arg (ap, const char *);
3184#if HAVE_MESSAGES
3185 else
3186 MHD_DLOG (daemon,
3187 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3188 opt);
3189#endif
3190 break;
3191 case MHD_OPTION_HTTPS_CRED_TYPE:
3192 daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, int);
3193 break;
3194 case MHD_OPTION_HTTPS_MEM_DHPARAMS:
3195 if (0 != (daemon->options & MHD_USE_SSL))
3196 {
3197 const char *arg = va_arg (ap, const char *);
3198 gnutls_datum_t dhpar;
3199
3200 if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
3201 {
3202#if HAVE_MESSAGES
3203 MHD_DLOG(daemon,
3204 "Error initializing DH parameters\n");
3205#endif
3206 return MHD_NO;
3207 }
3208 dhpar.data = (unsigned char *) arg;
3209 dhpar.size = strlen (arg);
3210 if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, &dhpar,
3211 GNUTLS_X509_FMT_PEM) < 0)
3212 {
3213#if HAVE_MESSAGES
3214 MHD_DLOG(daemon,
3215 "Bad Diffie-Hellman parameters format\n");
3216#endif
3217 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
3218 return MHD_NO;
3219 }
3220 daemon->have_dhparams = MHD_YES;
3221 }
3222 else
3223 {
3224#if HAVE_MESSAGES
3225 MHD_DLOG (daemon,
3226 "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3227 opt);
3228#endif
3229 return MHD_NO;
3230 }
3231 break;
3232 case MHD_OPTION_HTTPS_PRIORITIES:
3233 if (0 != (daemon->options & MHD_USE_SSL))
3234 {
3235 gnutls_priority_deinit (daemon->priority_cache);
3236 ret = gnutls_priority_init (&daemon->priority_cache,
3237 pstr = va_arg (ap, const char*),
3238 NULL);
3239 if (GNUTLS_E_SUCCESS != ret)
3240 {
3241#if HAVE_MESSAGES
3242 MHD_DLOG (daemon,
3243 "Setting priorities to `%s' failed: %s\n",
3244 pstr,
3245 gnutls_strerror (ret));
3246#endif
3247 daemon->priority_cache = NULL;
3248 return MHD_NO;
3249 }
3250 }
3251 break;
3252 case MHD_OPTION_HTTPS_CERT_CALLBACK:
3253#if GNUTLS_VERSION_MAJOR < 3
3254#if HAVE_MESSAGES
3255 MHD_DLOG (daemon,
3256 "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n");
3257#endif
3258 return MHD_NO;
3259#else
3260 if (0 != (daemon->options & MHD_USE_SSL))
3261 daemon->cert_callback = va_arg (ap, gnutls_certificate_retrieve_function2 *);
3262 break;
3263#endif
3264#endif
3265#ifdef DAUTH_SUPPORT
3266 case MHD_OPTION_DIGEST_AUTH_RANDOM:
3267 daemon->digest_auth_rand_size = va_arg (ap, size_t);
3268 daemon->digest_auth_random = va_arg (ap, const char *);
3269 break;
3270 case MHD_OPTION_NONCE_NC_SIZE:
3271 daemon->nonce_nc_size = va_arg (ap, unsigned int);
3272 break;
3273#endif
3274 case MHD_OPTION_LISTEN_SOCKET:
3275 daemon->socket_fd = va_arg (ap, MHD_socket);
3276 break;
3277 case MHD_OPTION_EXTERNAL_LOGGER:
3278#if HAVE_MESSAGES
3279 daemon->custom_error_log =
3280 va_arg (ap, VfprintfFunctionPointerType);
3281 daemon->custom_error_log_cls = va_arg (ap, void *);
3282#else
3283 va_arg (ap, VfprintfFunctionPointerType);
3284 va_arg (ap, void *);
3285#endif
3286 break;
3287 case MHD_OPTION_THREAD_STACK_SIZE:
3288 daemon->thread_stack_size = va_arg (ap, size_t);
3289 break;
3290#ifdef TCP_FASTOPEN
3291 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
3292 daemon->fastopen_queue_size = va_arg (ap, unsigned int);
3293 break;
3294#endif
3295 case MHD_OPTION_LISTENING_ADDRESS_REUSE:
3296 daemon->listening_address_reuse = va_arg (ap, unsigned int) ? 1 : -1;
3297 break;
3298 case MHD_OPTION_ARRAY:
3299 oa = va_arg (ap, struct MHD_OptionItem*);
3300 i = 0;
3301 while (MHD_OPTION_END != (opt = oa[i].option))
3302 {
3303 switch (opt)
3304 {
3305 /* all options taking 'size_t' */
3306 case MHD_OPTION_CONNECTION_MEMORY_LIMIT:
3307 case MHD_OPTION_CONNECTION_MEMORY_INCREMENT:
3308 case MHD_OPTION_THREAD_STACK_SIZE:
3309 if (MHD_YES != parse_options (daemon,
3310 servaddr,
3311 opt,
3312 (size_t) oa[i].value,
3313 MHD_OPTION_END))
3314 return MHD_NO;
3315 break;
3316 /* all options taking 'unsigned int' */
3317 case MHD_OPTION_NONCE_NC_SIZE:
3318 case MHD_OPTION_CONNECTION_LIMIT:
3319 case MHD_OPTION_CONNECTION_TIMEOUT:
3320 case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
3321 case MHD_OPTION_THREAD_POOL_SIZE:
3322 case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE:
3323 case MHD_OPTION_LISTENING_ADDRESS_REUSE:
3324 if (MHD_YES != parse_options (daemon,
3325 servaddr,
3326 opt,
3327 (unsigned int) oa[i].value,
3328 MHD_OPTION_END))
3329 return MHD_NO;
3330 break;
3331 /* all options taking 'enum' */
3332 case MHD_OPTION_HTTPS_CRED_TYPE:
3333 if (MHD_YES != parse_options (daemon,
3334 servaddr,
3335 opt,
3336 (int) oa[i].value,
3337 MHD_OPTION_END))
3338 return MHD_NO;
3339 break;
3340 /* all options taking 'MHD_socket' */
3341 case MHD_OPTION_LISTEN_SOCKET:
3342 if (MHD_YES != parse_options (daemon,
3343 servaddr,
3344 opt,
3345 (MHD_socket) oa[i].value,
3346 MHD_OPTION_END))
3347 return MHD_NO;
3348 break;
3349 /* all options taking one pointer */
3350 case MHD_OPTION_SOCK_ADDR:
3351 case MHD_OPTION_HTTPS_MEM_KEY:
3352 case MHD_OPTION_HTTPS_KEY_PASSWORD:
3353 case MHD_OPTION_HTTPS_MEM_CERT:
3354 case MHD_OPTION_HTTPS_MEM_TRUST:
3355 case MHD_OPTION_HTTPS_MEM_DHPARAMS:
3356 case MHD_OPTION_HTTPS_PRIORITIES:
3357 case MHD_OPTION_ARRAY:
3358 case MHD_OPTION_HTTPS_CERT_CALLBACK:
3359 if (MHD_YES != parse_options (daemon,
3360 servaddr,
3361 opt,
3362 oa[i].ptr_value,
3363 MHD_OPTION_END))
3364 return MHD_NO;
3365 break;
3366 /* all options taking two pointers */
3367 case MHD_OPTION_NOTIFY_COMPLETED:
3368 case MHD_OPTION_NOTIFY_CONNECTION:
3369 case MHD_OPTION_URI_LOG_CALLBACK:
3370 case MHD_OPTION_EXTERNAL_LOGGER:
3371 case MHD_OPTION_UNESCAPE_CALLBACK:
3372 if (MHD_YES != parse_options (daemon,
3373 servaddr,
3374 opt,
3375 (void *) oa[i].value,
3376 oa[i].ptr_value,
3377 MHD_OPTION_END))
3378 return MHD_NO;
3379 break;
3380 /* options taking size_t-number followed by pointer */
3381 case MHD_OPTION_DIGEST_AUTH_RANDOM:
3382 if (MHD_YES != parse_options (daemon,
3383 servaddr,
3384 opt,
3385 (size_t) oa[i].value,
3386 oa[i].ptr_value,
3387 MHD_OPTION_END))
3388 return MHD_NO;
3389 break;
3390 default:
3391 return MHD_NO;
3392 }
3393 i++;
3394 }
3395 break;
3396 case MHD_OPTION_UNESCAPE_CALLBACK:
3397 daemon->unescape_callback =
3398 va_arg (ap, UnescapeCallback);
3399 daemon->unescape_callback_cls = va_arg (ap, void *);
3400 break;
3401 default:
3402#if HAVE_MESSAGES
3403 if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
3404 (opt <= MHD_OPTION_HTTPS_PRIORITIES)) || (opt == MHD_OPTION_HTTPS_MEM_TRUST))
3405 {
3406 MHD_DLOG (daemon,
3407 "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
3408 opt);
3409 }
3410 else
3411 {
3412 MHD_DLOG (daemon,
3413 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
3414 opt);
3415 }
3416#endif
3417 return MHD_NO;
3418 }
3419 }
3420 return MHD_YES;
3421}
3422
3423
3424/**
3425 * Create a listen socket, if possible with SOCK_CLOEXEC flag set.
3426 *
3427 * @param daemon daemon for which we create the socket
3428 * @param domain socket domain (i.e. PF_INET)
3429 * @param type socket type (usually SOCK_STREAM)
3430 * @param protocol desired protocol, 0 for default
3431 */
3432static MHD_socket
3433create_socket (struct MHD_Daemon *daemon,
3434 int domain, int type, int protocol)
3435{
3436 int ctype = type | SOCK_CLOEXEC;
3437 MHD_socket fd;
3438
3439 /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
3440 * implementations do not set ai_socktype, e.g. RHL6.2. */
3441 fd = socket (domain, ctype, protocol);
3442 if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 != SOCK_CLOEXEC) )
3443 {
3444 ctype = type;
3445 fd = socket(domain, type, protocol);
3446 }
3447 if (MHD_INVALID_SOCKET == fd)
3448 return MHD_INVALID_SOCKET;
3449 if (type == ctype)
3450 make_nonblocking_noninheritable (daemon, fd);
3451 return fd;
3452}
3453
3454
3455#if EPOLL_SUPPORT
3456/**
3457 * Setup epoll() FD for the daemon and initialize it to listen
3458 * on the listen FD.
3459 *
3460 * @param daemon daemon to initialize for epoll()
3461 * @return #MHD_YES on success, #MHD_NO on failure
3462 */
3463static int
3464setup_epoll_to_listen (struct MHD_Daemon *daemon)
3465{
3466 struct epoll_event event;
3467
3468#ifdef HAVE_EPOLL_CREATE1
3469 daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
3470#else /* !HAVE_EPOLL_CREATE1 */
3471 daemon->epoll_fd = epoll_create (MAX_EVENTS);
3472#endif /* !HAVE_EPOLL_CREATE1 */
3473 if (-1 == daemon->epoll_fd)
3474 {
3475#if HAVE_MESSAGES
3476 MHD_DLOG (daemon,
3477 "Call to epoll_create1 failed: %s\n",
3478 MHD_socket_last_strerr_ ());
3479#endif
3480 return MHD_NO;
3481 }
3482#ifndef HAVE_EPOLL_CREATE1
3483 else
3484 {
3485 int fdflags = fcntl (daemon->epoll_fd, F_GETFD);
3486 if (0 > fdflags || 0 > fcntl (daemon->epoll_fd, F_SETFD, fdflags | FD_CLOEXEC))
3487 {
3488#if HAVE_MESSAGES
3489 MHD_DLOG (daemon,
3490 "Failed to change flags on epoll fd: %s\n",
3491 MHD_socket_last_strerr_ ());
3492#endif /* HAVE_MESSAGES */
3493 }
3494 }
3495#endif /* !HAVE_EPOLL_CREATE1 */
3496 if (0 == EPOLL_CLOEXEC)
3497 make_nonblocking_noninheritable (daemon,
3498 daemon->epoll_fd);
3499 if (MHD_INVALID_SOCKET == daemon->socket_fd)
3500 return MHD_YES; /* non-listening daemon */
3501 event.events = EPOLLIN;
3502 event.data.ptr = daemon;
3503 if (0 != epoll_ctl (daemon->epoll_fd,
3504 EPOLL_CTL_ADD,
3505 daemon->socket_fd,
3506 &event))
3507 {
3508#if HAVE_MESSAGES
3509 MHD_DLOG (daemon,
3510 "Call to epoll_ctl failed: %s\n",
3511 MHD_socket_last_strerr_ ());
3512#endif
3513 return MHD_NO;
3514 }
3515 if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
3516 (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) )
3517 {
3518 event.events = EPOLLIN | EPOLLET;
3519 event.data.ptr = NULL;
3520 event.data.fd = daemon->wpipe[0];
3521 if (0 != epoll_ctl (daemon->epoll_fd,
3522 EPOLL_CTL_ADD,
3523 daemon->wpipe[0],
3524 &event))
3525 {
3526#if HAVE_MESSAGES
3527 MHD_DLOG (daemon,
3528 "Call to epoll_ctl failed: %s\n",
3529 MHD_socket_last_strerr_ ());
3530#endif
3531 return MHD_NO;
3532 }
3533 }
3534 daemon->listen_socket_in_epoll = MHD_YES;
3535 return MHD_YES;
3536}
3537#endif
3538
3539
3540/**
3541 * Start a webserver on the given port.
3542 *
3543 * @param flags combination of `enum MHD_FLAG` values
3544 * @param port port to bind to (in host byte order)
3545 * @param apc callback to call to check which clients
3546 * will be allowed to connect; you can pass NULL
3547 * in which case connections from any IP will be
3548 * accepted
3549 * @param apc_cls extra argument to @a apc
3550 * @param dh handler called for all requests (repeatedly)
3551 * @param dh_cls extra argument to @a dh
3552 * @param ap list of options (type-value pairs,
3553 * terminated with #MHD_OPTION_END).
3554 * @return NULL on error, handle to daemon on success
3555 * @ingroup event
3556 */
3557struct MHD_Daemon *
3558MHD_start_daemon_va (unsigned int flags,
3559 uint16_t port,
3560 MHD_AcceptPolicyCallback apc,
3561 void *apc_cls,
3562 MHD_AccessHandlerCallback dh, void *dh_cls,
3563 va_list ap)
3564{
3565 const int on = 1;
3566 struct MHD_Daemon *daemon;
3567 MHD_socket socket_fd;
3568 struct sockaddr_in servaddr4;
3569#if HAVE_INET6
3570 struct sockaddr_in6 servaddr6;
3571#endif
3572 const struct sockaddr *servaddr = NULL;
3573 socklen_t addrlen;
3574 unsigned int i;
3575 int res_thread_create;
3576 int use_pipe;
3577
3578#ifndef HAVE_INET6
3579 if (0 != (flags & MHD_USE_IPv6))
3580 return NULL;
3581#endif
3582#ifndef HAVE_POLL
3583 if (0 != (flags & MHD_USE_POLL))
3584 return NULL;
3585#endif
3586#if ! HTTPS_SUPPORT
3587 if (0 != (flags & MHD_USE_SSL))
3588 return NULL;
3589#endif
3590#ifndef TCP_FASTOPEN
3591 if (0 != (flags & MHD_USE_TCP_FASTOPEN))
3592 return NULL;
3593#endif
3594 if (NULL == dh)
3595 return NULL;
3596 if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
3597 return NULL;
3598 memset (daemon, 0, sizeof (struct MHD_Daemon));
3599#if EPOLL_SUPPORT
3600 daemon->epoll_fd = -1;
3601#endif
3602 /* try to open listen socket */
3603#if HTTPS_SUPPORT
3604 if (0 != (flags & MHD_USE_SSL))
3605 {
3606 gnutls_priority_init (&daemon->priority_cache,
3607 "NORMAL",
3608 NULL);
3609 }
3610#endif
3611 daemon->socket_fd = MHD_INVALID_SOCKET;
3612 daemon->listening_address_reuse = 0;
3613 daemon->options = flags;
3614#if WINDOWS
3615 /* Winsock is broken with respect to 'shutdown';
3616 this disables us calling 'shutdown' on W32. */
3617 daemon->options |= MHD_USE_EPOLL_TURBO;
3618#endif
3619 daemon->port = port;
3620 daemon->apc = apc;
3621 daemon->apc_cls = apc_cls;
3622 daemon->default_handler = dh;
3623 daemon->default_handler_cls = dh_cls;
3624 daemon->connections = 0;
3625 daemon->connection_limit = MHD_MAX_CONNECTIONS_DEFAULT;
3626 daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
3627 daemon->pool_increment = MHD_BUF_INC_SIZE;
3628 daemon->unescape_callback = &unescape_wrapper;
3629 daemon->connection_timeout = 0; /* no timeout */
3630 daemon->wpipe[0] = MHD_INVALID_PIPE_;
3631 daemon->wpipe[1] = MHD_INVALID_PIPE_;
3632#if HAVE_MESSAGES
3633 daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
3634 daemon->custom_error_log_cls = stderr;
3635#endif
3636#ifdef HAVE_LISTEN_SHUTDOWN
3637 use_pipe = (0 != (daemon->options & (MHD_USE_NO_LISTEN_SOCKET | MHD_USE_PIPE_FOR_SHUTDOWN)));
3638#else
3639 use_pipe = 1; /* yes, must use pipe to signal shutdown */
3640#endif
3641 if (0 == (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
3642 use_pipe = 0; /* useless if we are using 'external' select */
3643 if ( (use_pipe) && (0 != MHD_pipe_ (daemon->wpipe)) )
3644 {
3645#if HAVE_MESSAGES
3646 MHD_DLOG (daemon,
3647 "Failed to create control pipe: %s\n",
3648 MHD_strerror_ (errno));
3649#endif
3650 free (daemon);
3651 return NULL;
3652 }
3653#ifndef WINDOWS
3654 if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) &&
3655 (1 == use_pipe) &&
3656 (daemon->wpipe[0] >= FD_SETSIZE) )
3657 {
3658#if HAVE_MESSAGES
3659 MHD_DLOG (daemon,
3660 "file descriptor for control pipe exceeds maximum value\n");
3661#endif
3662 if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
3663 MHD_PANIC ("close failed\n");
3664 if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
3665 MHD_PANIC ("close failed\n");
3666 free (daemon);
3667 return NULL;
3668 }
3669#endif
3670#ifdef DAUTH_SUPPORT
3671 daemon->digest_auth_rand_size = 0;
3672 daemon->digest_auth_random = NULL;
3673 daemon->nonce_nc_size = 4; /* tiny */
3674#endif
3675#if HTTPS_SUPPORT
3676 if (0 != (flags & MHD_USE_SSL))
3677 {
3678 daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
3679 }
3680#endif
3681
3682
3683 if (MHD_YES != parse_options_va (daemon, &servaddr, ap))
3684 {
3685#if HTTPS_SUPPORT
3686 if ( (0 != (flags & MHD_USE_SSL)) &&
3687 (NULL != daemon->priority_cache) )
3688 gnutls_priority_deinit (daemon->priority_cache);
3689#endif
3690 free (daemon);
3691 return NULL;
3692 }
3693#ifdef DAUTH_SUPPORT
3694 if (daemon->nonce_nc_size > 0)
3695 {
3696 if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
3697 sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
3698 {
3699#if HAVE_MESSAGES
3700 MHD_DLOG (daemon,
3701 "Specified value for NC_SIZE too large\n");
3702#endif
3703#if HTTPS_SUPPORT
3704 if (0 != (flags & MHD_USE_SSL))
3705 gnutls_priority_deinit (daemon->priority_cache);
3706#endif
3707 free (daemon);
3708 return NULL;
3709 }
3710 daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
3711 if (NULL == daemon->nnc)
3712 {
3713#if HAVE_MESSAGES
3714 MHD_DLOG (daemon,
3715 "Failed to allocate memory for nonce-nc map: %s\n",
3716 MHD_strerror_ (errno));
3717#endif
3718#if HTTPS_SUPPORT
3719 if (0 != (flags & MHD_USE_SSL))
3720 gnutls_priority_deinit (daemon->priority_cache);
3721#endif
3722 free (daemon);
3723 return NULL;
3724 }
3725 }
3726
3727 if (MHD_YES != MHD_mutex_create_ (&daemon->nnc_lock))
3728 {
3729#if HAVE_MESSAGES
3730 MHD_DLOG (daemon,
3731 "MHD failed to initialize nonce-nc mutex\n");
3732#endif
3733#if HTTPS_SUPPORT
3734 if (0 != (flags & MHD_USE_SSL))
3735 gnutls_priority_deinit (daemon->priority_cache);
3736#endif
3737 free (daemon->nnc);
3738 free (daemon);
3739 return NULL;
3740 }
3741#endif
3742
3743 /* Thread pooling currently works only with internal select thread model */
3744 if ( (0 == (flags & MHD_USE_SELECT_INTERNALLY)) &&
3745 (daemon->worker_pool_size > 0) )
3746 {
3747#if HAVE_MESSAGES
3748 MHD_DLOG (daemon,
3749 "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
3750#endif
3751 goto free_and_fail;
3752 }
3753
3754 if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3755 (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) )
3756 {
3757#if HAVE_MESSAGES
3758 MHD_DLOG (daemon,
3759 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_SUSPEND_RESUME is not supported.\n");
3760#endif
3761 goto free_and_fail;
3762 }
3763
3764#ifdef __SYMBIAN32__
3765 if (0 != (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
3766 {
3767#if HAVE_MESSAGES
3768 MHD_DLOG (daemon,
3769 "Threaded operations are not supported on Symbian.\n");
3770#endif
3771 goto free_and_fail;
3772 }
3773#endif
3774 if ( (MHD_INVALID_SOCKET == daemon->socket_fd) &&
3775 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3776 {
3777 /* try to open listen socket */
3778 if (0 != (flags & MHD_USE_IPv6))
3779 socket_fd = create_socket (daemon,
3780 PF_INET6, SOCK_STREAM, 0);
3781 else
3782 socket_fd = create_socket (daemon,
3783 PF_INET, SOCK_STREAM, 0);
3784 if (MHD_INVALID_SOCKET == socket_fd)
3785 {
3786#if HAVE_MESSAGES
3787 MHD_DLOG (daemon,
3788 "Call to socket failed: %s\n",
3789 MHD_socket_last_strerr_ ());
3790#endif
3791 goto free_and_fail;
3792 }
3793
3794 /* Apply the socket options according to listening_address_reuse. */
3795 if (0 == daemon->listening_address_reuse)
3796 {
3797 /* No user requirement, use "traditional" default SO_REUSEADDR,
3798 and do not fail if it doesn't work */
3799 if (0 > setsockopt (socket_fd,
3800 SOL_SOCKET,
3801 SO_REUSEADDR,
3802 (void*)&on, sizeof (on)))
3803 {
3804#if HAVE_MESSAGES
3805 MHD_DLOG (daemon,
3806 "setsockopt failed: %s\n",
3807 MHD_socket_last_strerr_ ());
3808#endif
3809 }
3810 }
3811 else if (daemon->listening_address_reuse > 0)
3812 {
3813 /* User requested to allow reusing listening address:port.
3814 * Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
3815 * Fail if SO_REUSEPORT does not exist or setsockopt fails.
3816 */
3817#ifdef _WIN32
3818 /* SO_REUSEADDR on W32 has the same semantics
3819 as SO_REUSEPORT on BSD/Linux */
3820 if (0 > setsockopt (socket_fd,
3821 SOL_SOCKET,
3822 SO_REUSEADDR,
3823 (void*)&on, sizeof (on)))
3824 {
3825#if HAVE_MESSAGES
3826 MHD_DLOG (daemon,
3827 "setsockopt failed: %s\n",
3828 MHD_socket_last_strerr_ ());
3829#endif
3830 goto free_and_fail;
3831 }
3832#else
3833#ifndef SO_REUSEPORT
3834#ifdef LINUX
3835/* Supported since Linux 3.9, but often not present (or commented out)
3836 in the headers at this time; but 15 is reserved for this and
3837 thus should be safe to use. */
3838#define SO_REUSEPORT 15
3839#endif
3840#endif
3841#ifdef SO_REUSEPORT
3842 if (0 > setsockopt (socket_fd,
3843 SOL_SOCKET,
3844 SO_REUSEPORT,
3845 (void*)&on, sizeof (on)))
3846 {
3847#if HAVE_MESSAGES
3848 MHD_DLOG (daemon,
3849 "setsockopt failed: %s\n",
3850 MHD_socket_last_strerr_ ());
3851#endif
3852 goto free_and_fail;
3853 }
3854#else
3855 /* we're supposed to allow address:port re-use, but
3856 on this platform we cannot; fail hard */
3857#if HAVE_MESSAGES
3858 MHD_DLOG (daemon,
3859 "Cannot allow listening address reuse: SO_REUSEPORT not defined\n");
3860#endif
3861 goto free_and_fail;
3862#endif
3863#endif
3864 }
3865 else /* if (daemon->listening_address_reuse < 0) */
3866 {
3867 /* User requested to disallow reusing listening address:port.
3868 * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
3869 * is used. Fail if it does not exist or setsockopt fails.
3870 */
3871#ifdef _WIN32
3872#ifdef SO_EXCLUSIVEADDRUSE
3873 if (0 > setsockopt (socket_fd,
3874 SOL_SOCKET,
3875 SO_EXCLUSIVEADDRUSE,
3876 (void*)&on, sizeof (on)))
3877 {
3878#if HAVE_MESSAGES
3879 MHD_DLOG (daemon,
3880 "setsockopt failed: %s\n",
3881 MHD_socket_last_strerr_ ());
3882#endif
3883 goto free_and_fail;
3884 }
3885#else /* SO_EXCLUSIVEADDRUSE not defined on W32? */
3886#if HAVE_MESSAGES
3887 MHD_DLOG (daemon,
3888 "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n");
3889#endif
3890 goto free_and_fail;
3891#endif
3892#endif /* _WIN32 */
3893 }
3894
3895 /* check for user supplied sockaddr */
3896#if HAVE_INET6
3897 if (0 != (flags & MHD_USE_IPv6))
3898 addrlen = sizeof (struct sockaddr_in6);
3899 else
3900#endif
3901 addrlen = sizeof (struct sockaddr_in);
3902 if (NULL == servaddr)
3903 {
3904#if HAVE_INET6
3905 if (0 != (flags & MHD_USE_IPv6))
3906 {
3907 memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
3908 servaddr6.sin6_family = AF_INET6;
3909 servaddr6.sin6_port = htons (port);
3910#if HAVE_SOCKADDR_IN_SIN_LEN
3911 servaddr6.sin6_len = sizeof (struct sockaddr_in6);
3912#endif
3913 servaddr = (struct sockaddr *) &servaddr6;
3914 }
3915 else
3916#endif
3917 {
3918 memset (&servaddr4, 0, sizeof (struct sockaddr_in));
3919 servaddr4.sin_family = AF_INET;
3920 servaddr4.sin_port = htons (port);
3921#if HAVE_SOCKADDR_IN_SIN_LEN
3922 servaddr4.sin_len = sizeof (struct sockaddr_in);
3923#endif
3924 servaddr = (struct sockaddr *) &servaddr4;
3925 }
3926 }
3927 daemon->socket_fd = socket_fd;
3928
3929 if (0 != (flags & MHD_USE_IPv6))
3930 {
3931#ifdef IPPROTO_IPV6
3932#ifdef IPV6_V6ONLY
3933 /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
3934 (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
3935 and may also be missing on older POSIX systems; good luck if you have any of those,
3936 your IPv6 socket may then also bind against IPv4 anyway... */
3937#ifndef WINDOWS
3938 const int
3939#else
3940 const char
3941#endif
3942 on = (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK));
3943 if (0 > setsockopt (socket_fd,
3944 IPPROTO_IPV6, IPV6_V6ONLY,
3945 &on, sizeof (on)))
3946 {
3947#if HAVE_MESSAGES
3948 MHD_DLOG (daemon,
3949 "setsockopt failed: %s\n",
3950 MHD_socket_last_strerr_ ());
3951#endif
3952 }
3953#endif
3954#endif
3955 }
3956 if (-1 == bind (socket_fd, servaddr, addrlen))
3957 {
3958#if HAVE_MESSAGES
3959 MHD_DLOG (daemon,
3960 "Failed to bind to port %u: %s\n",
3961 (unsigned int) port,
3962 MHD_socket_last_strerr_ ());
3963#endif
3964 if (0 != MHD_socket_close_ (socket_fd))
3965 MHD_PANIC ("close failed\n");
3966 goto free_and_fail;
3967 }
3968#ifdef TCP_FASTOPEN
3969 if (0 != (flags & MHD_USE_TCP_FASTOPEN))
3970 {
3971 if (0 == daemon->fastopen_queue_size)
3972 daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
3973 if (0 != setsockopt (socket_fd,
3974 IPPROTO_TCP, TCP_FASTOPEN,
3975 &daemon->fastopen_queue_size,
3976 sizeof (daemon->fastopen_queue_size)))
3977 {
3978#if HAVE_MESSAGES
3979 MHD_DLOG (daemon,
3980 "setsockopt failed: %s\n",
3981 MHD_socket_last_strerr_ ());
3982#endif
3983 }
3984 }
3985#endif
3986#if EPOLL_SUPPORT
3987 if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3988 {
3989 int sk_flags = fcntl (socket_fd, F_GETFL);
3990 if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3991 {
3992#if HAVE_MESSAGES
3993 MHD_DLOG (daemon,
3994 "Failed to make listen socket non-blocking: %s\n",
3995 MHD_socket_last_strerr_ ());
3996#endif
3997 if (0 != MHD_socket_close_ (socket_fd))
3998 MHD_PANIC ("close failed\n");
3999 goto free_and_fail;
4000 }
4001 }
4002#endif
4003 if (listen (socket_fd, 32) < 0)
4004 {
4005#if HAVE_MESSAGES
4006 MHD_DLOG (daemon,
4007 "Failed to listen for connections: %s\n",
4008 MHD_socket_last_strerr_ ());
4009#endif
4010 if (0 != MHD_socket_close_ (socket_fd))
4011 MHD_PANIC ("close failed\n");
4012 goto free_and_fail;
4013 }
4014 }
4015 else
4016 {
4017 socket_fd = daemon->socket_fd;
4018 }
4019#ifndef WINDOWS
4020 if ( (socket_fd >= FD_SETSIZE) &&
4021 (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
4022 {
4023#if HAVE_MESSAGES
4024 MHD_DLOG (daemon,
4025 "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
4026 socket_fd,
4027 FD_SETSIZE);
4028#endif
4029 if (0 != MHD_socket_close_ (socket_fd))
4030 MHD_PANIC ("close failed\n");
4031 goto free_and_fail;
4032 }
4033#endif
4034
4035#if EPOLL_SUPPORT
4036 if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) &&
4037 (0 == daemon->worker_pool_size) &&
4038 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
4039 {
4040 if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))
4041 {
4042#if HAVE_MESSAGES
4043 MHD_DLOG (daemon,
4044 "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL_LINUX_ONLY is not supported.\n");
4045#endif
4046 goto free_and_fail;
4047 }
4048 if (MHD_YES != setup_epoll_to_listen (daemon))
4049 goto free_and_fail;
4050 }
4051#else
4052 if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
4053 {
4054#if HAVE_MESSAGES
4055 MHD_DLOG (daemon,
4056 "epoll is not supported on this platform by this build.\n");
4057#endif
4058 goto free_and_fail;
4059 }
4060#endif
4061
4062 if (MHD_YES != MHD_mutex_create_ (&daemon->per_ip_connection_mutex))
4063 {
4064#if HAVE_MESSAGES
4065 MHD_DLOG (daemon,
4066 "MHD failed to initialize IP connection limit mutex\n");
4067#endif
4068 if ( (MHD_INVALID_SOCKET != socket_fd) &&
4069 (0 != MHD_socket_close_ (socket_fd)) )
4070 MHD_PANIC ("close failed\n");
4071 goto free_and_fail;
4072 }
4073 if (MHD_YES != MHD_mutex_create_ (&daemon->cleanup_connection_mutex))
4074 {
4075#if HAVE_MESSAGES
4076 MHD_DLOG (daemon,
4077 "MHD failed to initialize IP connection limit mutex\n");
4078#endif
4079 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4080 if ( (MHD_INVALID_SOCKET != socket_fd) &&
4081 (0 != MHD_socket_close_ (socket_fd)) )
4082 MHD_PANIC ("close failed\n");
4083 goto free_and_fail;
4084 }
4085
4086#if HTTPS_SUPPORT
4087 /* initialize HTTPS daemon certificate aspects & send / recv functions */
4088 if ((0 != (flags & MHD_USE_SSL)) && (0 != MHD_TLS_init (daemon)))
4089 {
4090#if HAVE_MESSAGES
4091 MHD_DLOG (daemon,
4092 "Failed to initialize TLS support\n");
4093#endif
4094 if ( (MHD_INVALID_SOCKET != socket_fd) &&
4095 (0 != MHD_socket_close_ (socket_fd)) )
4096 MHD_PANIC ("close failed\n");
4097 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4098 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4099 goto free_and_fail;
4100 }
4101#endif
4102 if ( ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) ||
4103 ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) &&
4104 (0 == daemon->worker_pool_size)) ) &&
4105 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) &&
4106 (0 != (res_thread_create =
4107 create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon))))
4108 {
4109#if HAVE_MESSAGES
4110 MHD_DLOG (daemon,
4111 "Failed to create listen thread: %s\n",
4112 MHD_strerror_ (res_thread_create));
4113#endif
4114 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4115 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4116 if ( (MHD_INVALID_SOCKET != socket_fd) &&
4117 (0 != MHD_socket_close_ (socket_fd)) )
4118 MHD_PANIC ("close failed\n");
4119 goto free_and_fail;
4120 }
4121 if ( (daemon->worker_pool_size > 0) &&
4122 (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
4123 {
4124#if !defined(WINDOWS) || defined(CYGWIN)
4125 int sk_flags;
4126#else
4127 unsigned long sk_flags;
4128#endif
4129
4130 /* Coarse-grained count of connections per thread (note error
4131 * due to integer division). Also keep track of how many
4132 * connections are leftover after an equal split. */
4133 unsigned int conns_per_thread = daemon->connection_limit
4134 / daemon->worker_pool_size;
4135 unsigned int leftover_conns = daemon->connection_limit
4136 % daemon->worker_pool_size;
4137
4138 i = 0; /* we need this in case fcntl or malloc fails */
4139
4140 /* Accept must be non-blocking. Multiple children may wake up
4141 * to handle a new connection, but only one will win the race.
4142 * The others must immediately return. */
4143#if !defined(WINDOWS) || defined(CYGWIN)
4144 sk_flags = fcntl (socket_fd, F_GETFL);
4145 if (sk_flags < 0)
4146 goto thread_failed;
4147 if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
4148 goto thread_failed;
4149#else
4150 sk_flags = 1;
4151 if (SOCKET_ERROR == ioctlsocket (socket_fd, FIONBIO, &sk_flags))
4152 goto thread_failed;
4153#endif /* WINDOWS && !CYGWIN */
4154
4155 /* Allocate memory for pooled objects */
4156 daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
4157 * daemon->worker_pool_size);
4158 if (NULL == daemon->worker_pool)
4159 goto thread_failed;
4160
4161 /* Start the workers in the pool */
4162 for (i = 0; i < daemon->worker_pool_size; ++i)
4163 {
4164 /* Create copy of the Daemon object for each worker */
4165 struct MHD_Daemon *d = &daemon->worker_pool[i];
4166
4167 memcpy (d, daemon, sizeof (struct MHD_Daemon));
4168 /* Adjust pooling params for worker daemons; note that memcpy()
4169 has already copied MHD_USE_SELECT_INTERNALLY thread model into
4170 the worker threads. */
4171 d->master = daemon;
4172 d->worker_pool_size = 0;
4173 d->worker_pool = NULL;
4174
4175 if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
4176 (0 != MHD_pipe_ (d->wpipe)) )
4177 {
4178#if HAVE_MESSAGES
4179 MHD_DLOG (daemon,
4180 "Failed to create worker control pipe: %s\n",
4181 MHD_pipe_last_strerror_() );
4182#endif
4183 goto thread_failed;
4184 }
4185#ifndef WINDOWS
4186 if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) &&
4187 (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
4188 (d->wpipe[0] >= FD_SETSIZE) )
4189 {
4190#if HAVE_MESSAGES
4191 MHD_DLOG (daemon,
4192 "file descriptor for worker control pipe exceeds maximum value\n");
4193#endif
4194 if (0 != MHD_pipe_close_ (d->wpipe[0]))
4195 MHD_PANIC ("close failed\n");
4196 if (0 != MHD_pipe_close_ (d->wpipe[1]))
4197 MHD_PANIC ("close failed\n");
4198 goto thread_failed;
4199 }
4200#endif
4201
4202 /* Divide available connections evenly amongst the threads.
4203 * Thread indexes in [0, leftover_conns) each get one of the
4204 * leftover connections. */
4205 d->connection_limit = conns_per_thread;
4206 if (i < leftover_conns)
4207 ++d->connection_limit;
4208#if EPOLL_SUPPORT
4209 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4210 (MHD_YES != setup_epoll_to_listen (d)) )
4211 goto thread_failed;
4212#endif
4213 /* Must init cleanup connection mutex for each worker */
4214 if (MHD_YES != MHD_mutex_create_ (&d->cleanup_connection_mutex))
4215 {
4216#if HAVE_MESSAGES
4217 MHD_DLOG (daemon,
4218 "MHD failed to initialize cleanup connection mutex for thread worker %d\n", i);
4219#endif
4220 goto thread_failed;
4221 }
4222
4223 /* Spawn the worker thread */
4224 if (0 != (res_thread_create =
4225 create_thread (&d->pid, daemon, &MHD_select_thread, d)))
4226 {
4227#if HAVE_MESSAGES
4228 MHD_DLOG (daemon,
4229 "Failed to create pool thread: %s\n",
4230 MHD_strerror_ (res_thread_create));
4231#endif
4232 /* Free memory for this worker; cleanup below handles
4233 * all previously-created workers. */
4234 (void) MHD_mutex_destroy_ (&d->cleanup_connection_mutex);
4235 goto thread_failed;
4236 }
4237 }
4238 }
4239#if HTTPS_SUPPORT
4240 /* API promises to never use the password after initialization,
4241 so we additionally NULL it here to not deref a dangling pointer. */
4242 daemon->https_key_password = NULL;
4243#endif /* HTTPS_SUPPORT */
4244
4245 return daemon;
4246
4247thread_failed:
4248 /* If no worker threads created, then shut down normally. Calling
4249 MHD_stop_daemon (as we do below) doesn't work here since it
4250 assumes a 0-sized thread pool means we had been in the default
4251 MHD_USE_SELECT_INTERNALLY mode. */
4252 if (0 == i)
4253 {
4254 if ( (MHD_INVALID_SOCKET != socket_fd) &&
4255 (0 != MHD_socket_close_ (socket_fd)) )
4256 MHD_PANIC ("close failed\n");
4257 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4258 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4259 if (NULL != daemon->worker_pool)
4260 free (daemon->worker_pool);
4261 goto free_and_fail;
4262 }
4263
4264 /* Shutdown worker threads we've already created. Pretend
4265 as though we had fully initialized our daemon, but
4266 with a smaller number of threads than had been
4267 requested. */
4268 daemon->worker_pool_size = i;
4269 MHD_stop_daemon (daemon);
4270 return NULL;
4271
4272 free_and_fail:
4273 /* clean up basic memory state in 'daemon' and return NULL to
4274 indicate failure */
4275#if EPOLL_SUPPORT
4276 if (-1 != daemon->epoll_fd)
4277 close (daemon->epoll_fd);
4278#endif
4279#ifdef DAUTH_SUPPORT
4280 free (daemon->nnc);
4281 (void) MHD_mutex_destroy_ (&daemon->nnc_lock);
4282#endif
4283#if HTTPS_SUPPORT
4284 if (0 != (flags & MHD_USE_SSL))
4285 gnutls_priority_deinit (daemon->priority_cache);
4286#endif
4287 free (daemon);
4288 return NULL;
4289}
4290
4291
4292/**
4293 * Close the given connection, remove it from all of its
4294 * DLLs and move it into the cleanup queue.
4295 *
4296 * @param pos connection to move to cleanup
4297 */
4298static void
4299close_connection (struct MHD_Connection *pos)
4300{
4301 struct MHD_Daemon *daemon = pos->daemon;
4302
4303 MHD_connection_close (pos,
4304 MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN);
4305 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4306 return; /* must let thread to the rest */
4307 if (pos->connection_timeout == pos->daemon->connection_timeout)
4308 XDLL_remove (daemon->normal_timeout_head,
4309 daemon->normal_timeout_tail,
4310 pos);
4311 else
4312 XDLL_remove (daemon->manual_timeout_head,
4313 daemon->manual_timeout_tail,
4314 pos);
4315 DLL_remove (daemon->connections_head,
4316 daemon->connections_tail,
4317 pos);
4318 pos->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
4319 DLL_insert (daemon->cleanup_head,
4320 daemon->cleanup_tail,
4321 pos);
4322}
4323
4324
4325/**
4326 * Close all connections for the daemon; must only be called after
4327 * all of the threads have been joined and there is no more concurrent
4328 * activity on the connection lists.
4329 *
4330 * @param daemon daemon to close down
4331 */
4332static void
4333close_all_connections (struct MHD_Daemon *daemon)
4334{
4335 struct MHD_Connection *pos;
4336
4337 /* first, make sure all threads are aware of shutdown; need to
4338 traverse DLLs in peace... */
4339 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4340 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
4341 MHD_PANIC ("Failed to acquire cleanup mutex\n");
4342 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
4343 {
4344 shutdown (pos->socket_fd,
4345 (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
4346#if WINDOWS
4347 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4348 (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
4349 (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1)) )
4350 MHD_PANIC ("failed to signal shutdown via pipe");
4351#endif
4352 }
4353 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4354 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
4355 MHD_PANIC ("Failed to release cleanup mutex\n");
4356
4357 /* now, collect threads from thread pool */
4358 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4359 {
4360 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
4361 {
4362 if (0 != MHD_join_thread_ (pos->pid))
4363 MHD_PANIC ("Failed to join a thread\n");
4364 pos->thread_joined = MHD_YES;
4365 }
4366 }
4367
4368 /* now that we're alone, move everyone to cleanup */
4369 while (NULL != (pos = daemon->connections_head))
4370 close_connection (pos);
4371 MHD_cleanup_connections (daemon);
4372}
4373
4374
4375#if EPOLL_SUPPORT
4376/**
4377 * Shutdown epoll()-event loop by adding 'wpipe' to its event set.
4378 *
4379 * @param daemon daemon of which the epoll() instance must be signalled
4380 */
4381static void
4382epoll_shutdown (struct MHD_Daemon *daemon)
4383{
4384 struct epoll_event event;
4385
4386 if (MHD_INVALID_PIPE_ == daemon->wpipe[1])
4387 {
4388 /* wpipe was required in this mode, how could this happen? */
4389 MHD_PANIC ("Internal error\n");
4390 }
4391 event.events = EPOLLOUT;
4392 event.data.ptr = NULL;
4393 if (0 != epoll_ctl (daemon->epoll_fd,
4394 EPOLL_CTL_ADD,
4395 daemon->wpipe[1],
4396 &event))
4397 MHD_PANIC ("Failed to add wpipe to epoll set to signal termination\n");
4398}
4399#endif
4400
4401
4402/**
4403 * Shutdown an HTTP daemon.
4404 *
4405 * @param daemon daemon to stop
4406 * @ingroup event
4407 */
4408void
4409MHD_stop_daemon (struct MHD_Daemon *daemon)
4410{
4411 MHD_socket fd;
4412 unsigned int i;
4413
4414 if (NULL == daemon)
4415 return;
4416 daemon->shutdown = MHD_YES;
4417 fd = daemon->socket_fd;
4418 daemon->socket_fd = MHD_INVALID_SOCKET;
4419 /* Prepare workers for shutdown */
4420 if (NULL != daemon->worker_pool)
4421 {
4422 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
4423 for (i = 0; i < daemon->worker_pool_size; ++i)
4424 {
4425 daemon->worker_pool[i].shutdown = MHD_YES;
4426 daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET;
4427#if EPOLL_SUPPORT
4428 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4429 (-1 != daemon->worker_pool[i].epoll_fd) &&
4430 (MHD_INVALID_SOCKET == fd) )
4431 epoll_shutdown (&daemon->worker_pool[i]);
4432#endif
4433 }
4434 }
4435 if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
4436 {
4437 if (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1))
4438 MHD_PANIC ("failed to signal shutdown via pipe");
4439 }
4440#ifdef HAVE_LISTEN_SHUTDOWN
4441 else
4442 {
4443 /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
4444 if (MHD_INVALID_SOCKET != fd)
4445 (void) shutdown (fd, SHUT_RDWR);
4446 }
4447#endif
4448#if EPOLL_SUPPORT
4449 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4450 (-1 != daemon->epoll_fd) &&
4451 (MHD_INVALID_SOCKET == fd) )
4452 epoll_shutdown (daemon);
4453#endif
4454
4455#if DEBUG_CLOSE
4456#if HAVE_MESSAGES
4457 MHD_DLOG (daemon,
4458 "MHD listen socket shutdown\n");
4459#endif
4460#endif
4461
4462
4463 /* Signal workers to stop and clean them up */
4464 if (NULL != daemon->worker_pool)
4465 {
4466 /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
4467 for (i = 0; i < daemon->worker_pool_size; ++i)
4468 {
4469 if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4470 {
4471 if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 1))
4472 MHD_PANIC ("failed to signal shutdown via pipe");
4473 }
4474 if (0 != MHD_join_thread_ (daemon->worker_pool[i].pid))
4475 MHD_PANIC ("Failed to join a thread\n");
4476 close_all_connections (&daemon->worker_pool[i]);
4477 (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex);
4478#if EPOLL_SUPPORT
4479 if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
4480 (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) )
4481 MHD_PANIC ("close failed\n");
4482#endif
4483 if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) )
4484 {
4485 if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4486 {
4487 if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[0]))
4488 MHD_PANIC ("close failed\n");
4489 if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[1]))
4490 MHD_PANIC ("close failed\n");
4491 }
4492 }
4493 }
4494 free (daemon->worker_pool);
4495 }
4496 else
4497 {
4498 /* clean up master threads */
4499 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
4500 ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
4501 && (0 == daemon->worker_pool_size)))
4502 {
4503 if (0 != MHD_join_thread_ (daemon->pid))
4504 {
4505 MHD_PANIC ("Failed to join a thread\n");
4506 }
4507 }
4508 }
4509 close_all_connections (daemon);
4510 if ( (MHD_INVALID_SOCKET != fd) &&
4511 (0 != MHD_socket_close_ (fd)) )
4512 MHD_PANIC ("close failed\n");
4513
4514 /* TLS clean up */
4515#if HTTPS_SUPPORT
4516 if (MHD_YES == daemon->have_dhparams)
4517 {
4518 gnutls_dh_params_deinit (daemon->https_mem_dhparams);
4519 daemon->have_dhparams = MHD_NO;
4520 }
4521 if (0 != (daemon->options & MHD_USE_SSL))
4522 {
4523 gnutls_priority_deinit (daemon->priority_cache);
4524 if (daemon->x509_cred)
4525 gnutls_certificate_free_credentials (daemon->x509_cred);
4526 }
4527#endif
4528#if EPOLL_SUPPORT
4529 if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4530 (-1 != daemon->epoll_fd) &&
4531 (0 != MHD_socket_close_ (daemon->epoll_fd)) )
4532 MHD_PANIC ("close failed\n");
4533#endif
4534
4535#ifdef DAUTH_SUPPORT
4536 free (daemon->nnc);
4537 (void) MHD_mutex_destroy_ (&daemon->nnc_lock);
4538#endif
4539 (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4540 (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4541
4542 if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
4543 {
4544 if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
4545 MHD_PANIC ("close failed\n");
4546 if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
4547 MHD_PANIC ("close failed\n");
4548 }
4549 free (daemon);
4550}
4551
4552
4553/**
4554 * Obtain information about the given daemon
4555 * (not fully implemented!).
4556 *
4557 * @param daemon what daemon to get information about
4558 * @param info_type what information is desired?
4559 * @param ... depends on @a info_type
4560 * @return NULL if this information is not available
4561 * (or if the @a info_type is unknown)
4562 * @ingroup specialized
4563 */
4564const union MHD_DaemonInfo *
4565MHD_get_daemon_info (struct MHD_Daemon *daemon,
4566 enum MHD_DaemonInfoType info_type,
4567 ...)
4568{
4569 switch (info_type)
4570 {
4571 case MHD_DAEMON_INFO_KEY_SIZE:
4572 return NULL; /* no longer supported */
4573 case MHD_DAEMON_INFO_MAC_KEY_SIZE:
4574 return NULL; /* no longer supported */
4575 case MHD_DAEMON_INFO_LISTEN_FD:
4576 return (const union MHD_DaemonInfo *) &daemon->socket_fd;
4577#if EPOLL_SUPPORT
4578 case MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY:
4579 return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
4580#endif
4581 case MHD_DAEMON_INFO_CURRENT_CONNECTIONS:
4582 MHD_cleanup_connections (daemon);
4583 if (daemon->worker_pool)
4584 {
4585 /* Collect the connection information stored in the workers. */
4586 unsigned int i;
4587
4588 daemon->connections = 0;
4589 for (i=0;i<daemon->worker_pool_size;i++)
4590 {
4591 MHD_cleanup_connections (&daemon->worker_pool[i]);
4592 daemon->connections += daemon->worker_pool[i].connections;
4593 }
4594 }
4595 return (const union MHD_DaemonInfo *) &daemon->connections;
4596 default:
4597 return NULL;
4598 };
4599}
4600
4601
4602/**
4603 * Sets the global error handler to a different implementation. @a cb
4604 * will only be called in the case of typically fatal, serious
4605 * internal consistency issues. These issues should only arise in the
4606 * case of serious memory corruption or similar problems with the
4607 * architecture. While @a cb is allowed to return and MHD will then
4608 * try to continue, this is never safe.
4609 *
4610 * The default implementation that is used if no panic function is set
4611 * simply prints an error message and calls `abort()`. Alternative
4612 * implementations might call `exit()` or other similar functions.
4613 *
4614 * @param cb new error handler
4615 * @param cls passed to @a cb
4616 * @ingroup logging
4617 */
4618void
4619MHD_set_panic_func (MHD_PanicCallback cb, void *cls)
4620{
4621 mhd_panic = cb;
4622 mhd_panic_cls = cls;
4623}
4624
4625
4626/**
4627 * Obtain the version of this library
4628 *
4629 * @return static version string, e.g. "0.9.9"
4630 * @ingroup specialized
4631 */
4632const char *
4633MHD_get_version (void)
4634{
4635#ifdef PACKAGE_VERSION
4636 return PACKAGE_VERSION;
4637#else /* !PACKAGE_VERSION */
4638 static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
4639 if (0 == ver[0])
4640 {
4641 int res = MHD_snprintf_(ver, sizeof(ver), "%x.%x.%x",
4642 (((int)MHD_VERSION >> 24) & 0xFF),
4643 (((int)MHD_VERSION >> 16) & 0xFF),
4644 (((int)MHD_VERSION >> 8) & 0xFF));
4645 if (0 >= res || sizeof(ver) <= res)
4646 return "0.0.0"; /* Can't return real version*/
4647 }
4648 return ver;
4649#endif /* !PACKAGE_VERSION */
4650}
4651
4652
4653/**
4654 * Get information about supported MHD features.
4655 * Indicate that MHD was compiled with or without support for
4656 * particular feature. Some features require additional support
4657 * by kernel. Kernel support is not checked by this function.
4658 *
4659 * @param feature type of requested information
4660 * @return #MHD_YES if feature is supported by MHD, #MHD_NO if
4661 * feature is not supported or feature is unknown.
4662 * @ingroup specialized
4663 */
4664_MHD_EXTERN int
4665MHD_is_feature_supported(enum MHD_FEATURE feature)
4666{
4667 switch(feature)
4668 {
4669 case MHD_FEATURE_MESSGES:
4670#if HAVE_MESSAGES
4671 return MHD_YES;
4672#else
4673 return MHD_NO;
4674#endif
4675 case MHD_FEATURE_SSL:
4676#if HTTPS_SUPPORT
4677 return MHD_YES;
4678#else
4679 return MHD_NO;
4680#endif
4681 case MHD_FEATURE_HTTPS_CERT_CALLBACK:
4682#if HTTPS_SUPPORT && GNUTLS_VERSION_MAJOR >= 3
4683 return MHD_YES;
4684#else
4685 return MHD_NO;
4686#endif
4687 case MHD_FEATURE_IPv6:
4688#ifdef HAVE_INET6
4689 return MHD_YES;
4690#else
4691 return MHD_NO;
4692#endif
4693 case MHD_FEATURE_IPv6_ONLY:
4694#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
4695 return MHD_YES;
4696#else
4697 return MHD_NO;
4698#endif
4699 case MHD_FEATURE_POLL:
4700#ifdef HAVE_POLL
4701 return MHD_YES;
4702#else
4703 return MHD_NO;
4704#endif
4705 case MHD_FEATURE_EPOLL:
4706#if EPOLL_SUPPORT
4707 return MHD_YES;
4708#else
4709 return MHD_NO;
4710#endif
4711 case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET:
4712#ifdef HAVE_LISTEN_SHUTDOWN
4713 return MHD_YES;
4714#else
4715 return MHD_NO;
4716#endif
4717 case MHD_FEATURE_SOCKETPAIR:
4718#ifdef MHD_DONT_USE_PIPES
4719 return MHD_YES;
4720#else
4721 return MHD_NO;
4722#endif
4723 case MHD_FEATURE_TCP_FASTOPEN:
4724#ifdef TCP_FASTOPEN
4725 return MHD_YES;
4726#else
4727 return MHD_NO;
4728#endif
4729 case MHD_FEATURE_BASIC_AUTH:
4730#if BAUTH_SUPPORT
4731 return MHD_YES;
4732#else
4733 return MHD_NO;
4734#endif
4735 case MHD_FEATURE_DIGEST_AUTH:
4736#if DAUTH_SUPPORT
4737 return MHD_YES;
4738#else
4739 return MHD_NO;
4740#endif
4741 case MHD_FEATURE_POSTPROCESSOR:
4742#if HAVE_POSTPROCESSOR
4743 return MHD_YES;
4744#else
4745 return MHD_NO;
4746#endif
4747 case MHD_FEATURE_HTTPS_KEY_PASSWORD:
4748#if HTTPS_SUPPORT && GNUTLS_VERSION_NUMBER >= 0x030111
4749 return MHD_YES;
4750#else
4751 return MHD_NO;
4752#endif
4753 }
4754 return MHD_NO;
4755}
4756
4757
4758#if HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600
4759#if defined(MHD_USE_POSIX_THREADS)
4760GCRY_THREAD_OPTION_PTHREAD_IMPL;
4761#elif defined(MHD_W32_MUTEX_)
4762static int gcry_w32_mutex_init (void **ppmtx)
4763{
4764 *ppmtx = malloc (sizeof (MHD_mutex_));
4765
4766 if (NULL == *ppmtx)
4767 return ENOMEM;
4768
4769 if (MHD_YES != MHD_mutex_create_ ((MHD_mutex_*)*ppmtx))
4770 {
4771 free (*ppmtx);
4772 *ppmtx = NULL;
4773 return EPERM;
4774 }
4775
4776 return 0;
4777}
4778static int gcry_w32_mutex_destroy (void **ppmtx)
4779 { int res = (MHD_YES == MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1;
4780 free (*ppmtx); return res; }
4781static int gcry_w32_mutex_lock (void **ppmtx)
4782 { return (MHD_YES == MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1; }
4783static int gcry_w32_mutex_unlock (void **ppmtx)
4784 { return (MHD_YES == MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1; }
4785
4786static struct gcry_thread_cbs gcry_threads_w32 = {
4787 (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
4788 NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
4789 gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
4790 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
4791
4792#endif // defined(MHD_W32_MUTEX_)
4793#endif // HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600
4794
4795
4796/**
4797 * Initialize do setup work.
4798 */
4799void MHD_init(void)
4800{
4801 mhd_panic = &mhd_panic_std;
4802 mhd_panic_cls = NULL;
4803
4804#ifdef _WIN32
4805 WSADATA wsd;
4806 if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
4807 MHD_PANIC ("Failed to initialize winsock\n");
4808 mhd_winsock_inited_ = 1;
4809 if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
4810 MHD_PANIC ("Winsock version 2.2 is not available\n");
4811#endif
4812#if HTTPS_SUPPORT
4813#if GCRYPT_VERSION_NUMBER < 0x010600
4814#if defined(MHD_USE_POSIX_THREADS)
4815 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
4816 MHD_PANIC ("Failed to initialise multithreading in libgcrypt\n");
4817#elif defined(MHD_W32_MUTEX_)
4818 if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_w32))
4819 MHD_PANIC ("Failed to initialise multithreading in libgcrypt\n");
4820#endif // defined(MHD_W32_MUTEX_)
4821 gcry_check_version (NULL);
4822#else
4823 if (NULL == gcry_check_version ("1.6.0"))
4824 MHD_PANIC ("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n");
4825#endif
4826 gnutls_global_init ();
4827#endif
4828}
4829
4830
4831void MHD_fini(void)
4832{
4833#if HTTPS_SUPPORT
4834 gnutls_global_deinit ();
4835#endif
4836#ifdef _WIN32
4837 if (mhd_winsock_inited_)
4838 WSACleanup();
4839#endif
4840}
4841
4842_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini);
4843
4844/* end of daemon.c */