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