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