GNU libmicrohttpd  0.9.73
daemon.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007-2018 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 
28 #include "platform.h"
29 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
30 #include "mhd_threads.h"
31 #endif
32 #include "internal.h"
33 #include "response.h"
34 #include "connection.h"
35 #include "memorypool.h"
36 #include "mhd_limits.h"
37 #include "autoinit_funcs.h"
38 #include "mhd_mono_clock.h"
39 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
40 #include "mhd_locks.h"
41 #endif
42 #include "mhd_sockets.h"
43 #include "mhd_itc.h"
44 #include "mhd_compat.h"
45 #include "mhd_send.h"
46 
47 #if HAVE_SEARCH_H
48 #include <search.h>
49 #else
50 #include "tsearch.h"
51 #endif
52 
53 #ifdef HTTPS_SUPPORT
54 #include "connection_https.h"
55 #ifdef MHD_HTTPS_REQUIRE_GRYPT
56 #include <gcrypt.h>
57 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
58 #endif /* HTTPS_SUPPORT */
59 
60 #if defined(_WIN32) && ! defined(__CYGWIN__)
61 #ifndef WIN32_LEAN_AND_MEAN
62 #define WIN32_LEAN_AND_MEAN 1
63 #endif /* !WIN32_LEAN_AND_MEAN */
64 #include <windows.h>
65 #endif
66 
67 #ifdef MHD_USE_POSIX_THREADS
68 #ifdef HAVE_SIGNAL_H
69 #include <signal.h>
70 #endif /* HAVE_SIGNAL_H */
71 #endif /* MHD_USE_POSIX_THREADS */
72 
76 #ifdef MHD_POSIX_SOCKETS
77 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
78 #else
79 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
80 #endif
81 
85 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
86 
87 
88 /* Forward declarations. */
89 
98 static void
99 close_all_connections (struct MHD_Daemon *daemon);
100 
101 #ifdef EPOLL_SUPPORT
102 
112 static enum MHD_Result
113 MHD_epoll (struct MHD_Daemon *daemon,
114  int32_t millisec);
115 
116 #endif /* EPOLL_SUPPORT */
117 
127 static void
128 mhd_panic_std (void *cls,
129  const char *file,
130  unsigned int line,
131  const char *reason)
132 {
133  (void) cls; /* Mute compiler warning. */
134 #ifdef HAVE_MESSAGES
135  fprintf (stderr,
136  _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
137  file,
138  line,
139  reason);
140 #else /* ! HAVE_MESSAGES */
141  (void) file; /* Mute compiler warning. */
142  (void) line; /* Mute compiler warning. */
143  (void) reason; /* Mute compiler warning. */
144 #endif
145  abort ();
146 }
147 
148 
153 
158 
162 void
163 MHD_init (void);
164 
165 
166 #if defined(MHD_WINSOCK_SOCKETS)
170 static int mhd_winsock_inited_ = 0;
171 #endif /* MHD_WINSOCK_SOCKETS */
172 
173 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
178 #define MHD_check_global_init_() (void) 0
179 #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
183 volatile int global_init_count = 0;
184 
185 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
186 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
190 MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
191 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
192 #endif
193 
194 
199 void
201 {
202 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
203 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
204  MHD_mutex_lock_chk_ (&global_init_mutex_);
205 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
206 #endif
207  if (0 == global_init_count++)
208  MHD_init ();
209 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
210 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
211  MHD_mutex_unlock_chk_ (&global_init_mutex_);
212 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
213 #endif
214 }
215 
216 
217 #endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
218 
219 #ifdef HAVE_MESSAGES
223 static void
224 MHD_default_logger_ (void *cls,
225  const char *fm,
226  va_list ap)
227 {
228  vfprintf ((FILE*) cls, fm, ap);
229 #ifdef _DEBUG
230  fflush ((FILE*) cls);
231 #endif /* _DEBUG */
232 }
233 
234 
235 #endif /* HAVE_MESSAGES */
236 
237 
245 _MHD_EXTERN void
246 MHD_free (void *ptr)
247 {
248  free (ptr);
249 }
250 
251 
259 static struct MHD_Daemon*
260 MHD_get_master (struct MHD_Daemon *daemon)
261 {
262  while (NULL != daemon->master)
263  daemon = daemon->master;
264  return daemon;
265 }
266 
267 
271 struct MHD_IPCount
272 {
276  int family;
277 
281  union
282  {
286  struct in_addr ipv4;
287 #if HAVE_INET6
291  struct in6_addr ipv6;
292 #endif
293  } addr;
294 
298  unsigned int count;
299 };
300 
301 
307 static void
309 {
310 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
312 #else
313  (void) daemon;
314 #endif
315 }
316 
317 
323 static void
325 {
326 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
328 #else
329  (void) daemon;
330 #endif
331 }
332 
333 
343 static int
344 MHD_ip_addr_compare (const void *a1,
345  const void *a2)
346 {
347  return memcmp (a1,
348  a2,
349  offsetof (struct MHD_IPCount,
350  count));
351 }
352 
353 
362 static enum MHD_Result
363 MHD_ip_addr_to_key (const struct sockaddr *addr,
364  socklen_t addrlen,
365  struct MHD_IPCount *key)
366 {
367  memset (key,
368  0,
369  sizeof(*key));
370 
371  /* IPv4 addresses */
372  if (sizeof (struct sockaddr_in) == addrlen)
373  {
374  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
375 
376  key->family = AF_INET;
377  memcpy (&key->addr.ipv4,
378  &addr4->sin_addr,
379  sizeof(addr4->sin_addr));
380  return MHD_YES;
381  }
382 
383 #if HAVE_INET6
384  /* IPv6 addresses */
385  if (sizeof (struct sockaddr_in6) == addrlen)
386  {
387  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
388 
389  key->family = AF_INET6;
390  memcpy (&key->addr.ipv6,
391  &addr6->sin6_addr,
392  sizeof(addr6->sin6_addr));
393  return MHD_YES;
394  }
395 #endif
396 
397  /* Some other address */
398  return MHD_NO;
399 }
400 
401 
413 static enum MHD_Result
414 MHD_ip_limit_add (struct MHD_Daemon *daemon,
415  const struct sockaddr *addr,
416  socklen_t addrlen)
417 {
418  struct MHD_IPCount *key;
419  void **nodep;
420  void *node;
421  enum MHD_Result result;
422 
423  daemon = MHD_get_master (daemon);
424  /* Ignore if no connection limit assigned */
425  if (0 == daemon->per_ip_connection_limit)
426  return MHD_YES;
427 
428  if (NULL == (key = malloc (sizeof(*key))))
429  return MHD_NO;
430 
431  /* Initialize key */
432  if (MHD_NO == MHD_ip_addr_to_key (addr,
433  addrlen,
434  key))
435  {
436  /* Allow unhandled address types through */
437  free (key);
438  return MHD_YES;
439  }
440  MHD_ip_count_lock (daemon);
441 
442  /* Search for the IP address */
443  if (NULL == (nodep = tsearch (key,
444  &daemon->per_ip_connection_count,
446  {
447 #ifdef HAVE_MESSAGES
448  MHD_DLOG (daemon,
449  _ ("Failed to add IP connection count node.\n"));
450 #endif
451  MHD_ip_count_unlock (daemon);
452  free (key);
453  return MHD_NO;
454  }
455  node = *nodep;
456  /* If we got an existing node back, free the one we created */
457  if (node != key)
458  free (key);
459  key = (struct MHD_IPCount *) node;
460  /* Test if there is room for another connection; if so,
461  * increment count */
462  result = (key->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO;
463  if (MHD_NO != result)
464  ++key->count;
465 
466  MHD_ip_count_unlock (daemon);
467  return result;
468 }
469 
470 
479 static void
480 MHD_ip_limit_del (struct MHD_Daemon *daemon,
481  const struct sockaddr *addr,
482  socklen_t addrlen)
483 {
484  struct MHD_IPCount search_key;
485  struct MHD_IPCount *found_key;
486  void **nodep;
487 
488  daemon = MHD_get_master (daemon);
489  /* Ignore if no connection limit assigned */
490  if (0 == daemon->per_ip_connection_limit)
491  return;
492  /* Initialize search key */
493  if (MHD_NO == MHD_ip_addr_to_key (addr,
494  addrlen,
495  &search_key))
496  return;
497 
498  MHD_ip_count_lock (daemon);
499 
500  /* Search for the IP address */
501  if (NULL == (nodep = tfind (&search_key,
502  &daemon->per_ip_connection_count,
504  {
505  /* Something's wrong if we couldn't find an IP address
506  * that was previously added */
507  MHD_PANIC (_ ("Failed to find previously-added IP address.\n"));
508  }
509  found_key = (struct MHD_IPCount *) *nodep;
510  /* Validate existing count for IP address */
511  if (0 == found_key->count)
512  {
513  MHD_PANIC (_ ("Previously-added IP address had counter of zero.\n"));
514  }
515  /* Remove the node entirely if count reduces to 0 */
516  if (0 == --found_key->count)
517  {
518  tdelete (found_key,
519  &daemon->per_ip_connection_count,
521  free (found_key);
522  }
523 
524  MHD_ip_count_unlock (daemon);
525 }
526 
527 
528 #ifdef HTTPS_SUPPORT
535 static int
536 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
537 {
538  gnutls_datum_t key;
539  gnutls_datum_t cert;
540  int ret;
541 
542 #if GNUTLS_VERSION_MAJOR >= 3
543  if (NULL != daemon->cert_callback)
544  {
545  gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
546  daemon->cert_callback);
547  }
548 #endif
549 #if GNUTLS_VERSION_NUMBER >= 0x030603
550  else if (NULL != daemon->cert_callback2)
551  {
552  gnutls_certificate_set_retrieve_function3 (daemon->x509_cred,
553  daemon->cert_callback2);
554  }
555 #endif
556 
557  if (NULL != daemon->https_mem_trust)
558  {
559  size_t paramlen;
560  paramlen = strlen (daemon->https_mem_trust);
561  if (UINT_MAX < paramlen)
562  {
563 #ifdef HAVE_MESSAGES
564  MHD_DLOG (daemon,
565  _ ("Too long trust certificate.\n"));
566 #endif
567  return -1;
568  }
569  cert.data = (unsigned char *) daemon->https_mem_trust;
570  cert.size = (unsigned int) paramlen;
571  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
572  &cert,
573  GNUTLS_X509_FMT_PEM) < 0)
574  {
575 #ifdef HAVE_MESSAGES
576  MHD_DLOG (daemon,
577  _ ("Bad trust certificate format.\n"));
578 #endif
579  return -1;
580  }
581  }
582 
583  if (daemon->have_dhparams)
584  {
585  gnutls_certificate_set_dh_params (daemon->x509_cred,
586  daemon->https_mem_dhparams);
587  }
588  /* certificate & key loaded from memory */
589  if ( (NULL != daemon->https_mem_cert) &&
590  (NULL != daemon->https_mem_key) )
591  {
592  size_t param1len;
593  size_t param2len;
594 
595  param1len = strlen (daemon->https_mem_key);
596  param2len = strlen (daemon->https_mem_cert);
597  if ( (UINT_MAX < param1len) ||
598  (UINT_MAX < param2len) )
599  {
600 #ifdef HAVE_MESSAGES
601  MHD_DLOG (daemon,
602  _ ("Too long key or certificate.\n"));
603 #endif
604  return -1;
605  }
606  key.data = (unsigned char *) daemon->https_mem_key;
607  key.size = (unsigned int) param1len;
608  cert.data = (unsigned char *) daemon->https_mem_cert;
609  cert.size = (unsigned int) param2len;
610 
611  if (NULL != daemon->https_key_password)
612  {
613 #if GNUTLS_VERSION_NUMBER >= 0x030111
614  ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
615  &cert,
616  &key,
617  GNUTLS_X509_FMT_PEM,
618  daemon->https_key_password,
619  0);
620 #else
621 #ifdef HAVE_MESSAGES
622  MHD_DLOG (daemon,
623  _ ("Failed to setup x509 certificate/key: pre 3.X.X version " \
624  "of GnuTLS does not support setting key password.\n"));
625 #endif
626  return -1;
627 #endif
628  }
629  else
630  ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
631  &cert,
632  &key,
633  GNUTLS_X509_FMT_PEM);
634 #ifdef HAVE_MESSAGES
635  if (0 != ret)
636  MHD_DLOG (daemon,
637  _ ("GnuTLS failed to setup x509 certificate/key: %s\n"),
638  gnutls_strerror (ret));
639 #endif
640  return ret;
641  }
642 #if GNUTLS_VERSION_MAJOR >= 3
643  if (NULL != daemon->cert_callback)
644  return 0;
645 #endif
646 #if GNUTLS_VERSION_NUMBER >= 0x030603
647  else if (NULL != daemon->cert_callback2)
648  return 0;
649 #endif
650 #ifdef HAVE_MESSAGES
651  MHD_DLOG (daemon,
652  _ ("You need to specify a certificate and key location.\n"));
653 #endif
654  return -1;
655 }
656 
657 
664 static int
665 MHD_TLS_init (struct MHD_Daemon *daemon)
666 {
667  switch (daemon->cred_type)
668  {
669  case GNUTLS_CRD_CERTIFICATE:
670  if (0 !=
671  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
672  return GNUTLS_E_MEMORY_ERROR;
673  return MHD_init_daemon_certificate (daemon);
674  case GNUTLS_CRD_PSK:
675  if (0 !=
676  gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
677  return GNUTLS_E_MEMORY_ERROR;
678  return 0;
679  default:
680 #ifdef HAVE_MESSAGES
681  MHD_DLOG (daemon,
682  _ ("Error: invalid credentials type %d specified.\n"),
683  daemon->cred_type);
684 #endif
685  return -1;
686  }
687 }
688 
689 
690 #endif /* HTTPS_SUPPORT */
691 
692 
693 #undef MHD_get_fdset
694 
724 enum MHD_Result
725 MHD_get_fdset (struct MHD_Daemon *daemon,
726  fd_set *read_fd_set,
727  fd_set *write_fd_set,
728  fd_set *except_fd_set,
729  MHD_socket *max_fd)
730 {
731  return MHD_get_fdset2 (daemon,
732  read_fd_set,
733  write_fd_set,
734  except_fd_set,
735  max_fd,
737 }
738 
739 
740 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
753 static bool
754 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
755  fd_set *rs,
756  fd_set *ws,
757  fd_set *es,
758  MHD_socket *max_fd,
759  unsigned int fd_setsize)
760 {
761  const MHD_socket conn_sckt = urh->connection->socket_fd;
762  const MHD_socket mhd_sckt = urh->mhd.socket;
763  bool res = true;
764 
765  /* Do not add to 'es' only if socket is closed
766  * or not used anymore. */
767  if (MHD_INVALID_SOCKET != conn_sckt)
768  {
769  if ( (urh->in_buffer_used < urh->in_buffer_size) &&
770  (! MHD_add_to_fd_set_ (conn_sckt,
771  rs,
772  max_fd,
773  fd_setsize)) )
774  res = false;
775  if ( (0 != urh->out_buffer_used) &&
776  (! MHD_add_to_fd_set_ (conn_sckt,
777  ws,
778  max_fd,
779  fd_setsize)) )
780  res = false;
781  /* Do not monitor again for errors if error was detected before as
782  * error state is remembered. */
783  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
784  ((0 != urh->in_buffer_size) ||
785  (0 != urh->out_buffer_size) ||
786  (0 != urh->out_buffer_used)))
787  MHD_add_to_fd_set_ (conn_sckt,
788  es,
789  max_fd,
790  fd_setsize);
791  }
792  if (MHD_INVALID_SOCKET != mhd_sckt)
793  {
794  if ( (urh->out_buffer_used < urh->out_buffer_size) &&
795  (! MHD_add_to_fd_set_ (mhd_sckt,
796  rs,
797  max_fd,
798  fd_setsize)) )
799  res = false;
800  if ( (0 != urh->in_buffer_used) &&
801  (! MHD_add_to_fd_set_ (mhd_sckt,
802  ws,
803  max_fd,
804  fd_setsize)) )
805  res = false;
806  /* Do not monitor again for errors if error was detected before as
807  * error state is remembered. */
808  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
809  ((0 != urh->out_buffer_size) ||
810  (0 != urh->in_buffer_size) ||
811  (0 != urh->in_buffer_used)))
812  MHD_add_to_fd_set_ (mhd_sckt,
813  es,
814  max_fd,
815  fd_setsize);
816  }
817 
818  return res;
819 }
820 
821 
831 static void
832 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
833  const fd_set *rs,
834  const fd_set *ws,
835  const fd_set *es)
836 {
837  const MHD_socket conn_sckt = urh->connection->socket_fd;
838  const MHD_socket mhd_sckt = urh->mhd.socket;
839 
840  /* Reset read/write ready, preserve error state. */
843 
844  if (MHD_INVALID_SOCKET != conn_sckt)
845  {
846  if (FD_ISSET (conn_sckt, rs))
847  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
848  if (FD_ISSET (conn_sckt, ws))
849  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
850  if (FD_ISSET (conn_sckt, es))
851  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
852  }
853  if ((MHD_INVALID_SOCKET != mhd_sckt))
854  {
855  if (FD_ISSET (mhd_sckt, rs))
856  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
857  if (FD_ISSET (mhd_sckt, ws))
858  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
859  if (FD_ISSET (mhd_sckt, es))
860  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
861  }
862 }
863 
864 
865 #ifdef HAVE_POLL
866 
875 static void
876 urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
877  struct pollfd p[2])
878 {
879  p[0].events = 0;
880  p[1].events = 0;
881 
882  if (urh->in_buffer_used < urh->in_buffer_size)
883  p[0].events |= POLLIN;
884  if (0 != urh->out_buffer_used)
885  p[0].events |= POLLOUT;
886 
887  /* Do not monitor again for errors if error was detected before as
888  * error state is remembered. */
889  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
890  ((0 != urh->in_buffer_size) ||
891  (0 != urh->out_buffer_size) ||
892  (0 != urh->out_buffer_used)))
893  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
894 
895  if (urh->out_buffer_used < urh->out_buffer_size)
896  p[1].events |= POLLIN;
897  if (0 != urh->in_buffer_used)
898  p[1].events |= POLLOUT;
899 
900  /* Do not monitor again for errors if error was detected before as
901  * error state is remembered. */
902  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
903  ((0 != urh->out_buffer_size) ||
904  (0 != urh->in_buffer_size) ||
905  (0 != urh->in_buffer_used)))
906  p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
907 }
908 
909 
916 static void
917 urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
918  struct pollfd p[2])
919 {
920  p[0].fd = urh->connection->socket_fd;
921  p[1].fd = urh->mhd.socket;
922  urh_update_pollfd (urh,
923  p);
924 }
925 
926 
932 static void
933 urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
934  struct pollfd p[2])
935 {
936  /* Reset read/write ready, preserve error state. */
939 
940  if (0 != (p[0].revents & POLLIN))
941  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
942  if (0 != (p[0].revents & POLLOUT))
943  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
944  if (0 != (p[0].revents & POLLHUP))
946  if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
947  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
948  if (0 != (p[1].revents & POLLIN))
949  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
950  if (0 != (p[1].revents & POLLOUT))
951  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
952  if (0 != (p[1].revents & POLLHUP))
953  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
954  if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
956 }
957 
958 
959 #endif /* HAVE_POLL */
960 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
961 
962 
977 static enum MHD_Result
978 internal_get_fdset2 (struct MHD_Daemon *daemon,
979  fd_set *read_fd_set,
980  fd_set *write_fd_set,
981  fd_set *except_fd_set,
982  MHD_socket *max_fd,
983  unsigned int fd_setsize)
984 
985 {
986  struct MHD_Connection *pos;
987  struct MHD_Connection *posn;
988  enum MHD_Result result = MHD_YES;
989  MHD_socket ls;
990 
991  if (daemon->shutdown)
992  return MHD_NO;
993 
994  ls = daemon->listen_fd;
995  if ( (MHD_INVALID_SOCKET != ls) &&
996  (! daemon->was_quiesced) &&
997  (! MHD_add_to_fd_set_ (ls,
998  read_fd_set,
999  max_fd,
1000  fd_setsize)) )
1001  result = MHD_NO;
1002 
1003  /* Add all sockets to 'except_fd_set' as well to watch for
1004  * out-of-band data. However, ignore errors if INFO_READ
1005  * or INFO_WRITE sockets will not fit 'except_fd_set'. */
1006  /* Start from oldest connections. Make sense for W32 FDSETs. */
1007  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
1008  {
1009  posn = pos->prev;
1010 
1011  switch (pos->event_loop_info)
1012  {
1014  if (! MHD_add_to_fd_set_ (pos->socket_fd,
1015  read_fd_set,
1016  max_fd,
1017  fd_setsize))
1018  result = MHD_NO;
1019 #ifdef MHD_POSIX_SOCKETS
1021  except_fd_set,
1022  max_fd,
1023  fd_setsize);
1024 #endif /* MHD_POSIX_SOCKETS */
1025  break;
1027  if (! MHD_add_to_fd_set_ (pos->socket_fd,
1028  write_fd_set,
1029  max_fd,
1030  fd_setsize))
1031  result = MHD_NO;
1032 #ifdef MHD_POSIX_SOCKETS
1034  except_fd_set,
1035  max_fd,
1036  fd_setsize);
1037 #endif /* MHD_POSIX_SOCKETS */
1038  break;
1040  if ( (NULL == except_fd_set) ||
1041  ! MHD_add_to_fd_set_ (pos->socket_fd,
1042  except_fd_set,
1043  max_fd,
1044  fd_setsize))
1045  result = MHD_NO;
1046  break;
1048  /* this should never happen */
1049  break;
1050  }
1051  }
1052 #ifdef MHD_WINSOCK_SOCKETS
1053  /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
1054  * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
1055  * not be pushed out. */
1056  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
1057  {
1058  posn = pos->prev;
1060  except_fd_set,
1061  max_fd,
1062  fd_setsize);
1063  }
1064 #endif /* MHD_WINSOCK_SOCKETS */
1065 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1066  {
1067  struct MHD_UpgradeResponseHandle *urh;
1068 
1069  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
1070  {
1071  if (MHD_NO ==
1072  urh_to_fdset (urh,
1073  read_fd_set,
1074  write_fd_set,
1075  except_fd_set,
1076  max_fd,
1077  fd_setsize))
1078  result = MHD_NO;
1079  }
1080  }
1081 #endif
1082 #if _MHD_DEBUG_CONNECT
1083 #ifdef HAVE_MESSAGES
1084  if (NULL != max_fd)
1085  MHD_DLOG (daemon,
1086  _ ("Maximum socket in select set: %d\n"),
1087  *max_fd);
1088 #endif
1089 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1090  return result;
1091 }
1092 
1093 
1126 enum MHD_Result
1127 MHD_get_fdset2 (struct MHD_Daemon *daemon,
1128  fd_set *read_fd_set,
1129  fd_set *write_fd_set,
1130  fd_set *except_fd_set,
1131  MHD_socket *max_fd,
1132  unsigned int fd_setsize)
1133 {
1134  fd_set es;
1135 
1136  if ( (NULL == daemon) ||
1137  (NULL == read_fd_set) ||
1138  (NULL == write_fd_set) ||
1139  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ||
1140  (0 != (daemon->options & MHD_USE_POLL)))
1141  return MHD_NO;
1142 
1143  if (NULL == except_fd_set)
1144  { /* Workaround to maintain backward compatibility. */
1145 #ifdef HAVE_MESSAGES
1146  MHD_DLOG (daemon,
1147  _ ("MHD_get_fdset2() called with except_fd_set "
1148  "set to NULL. Such behavior is unsupported.\n"));
1149 #endif
1150  FD_ZERO (&es);
1151  except_fd_set = &es;
1152  }
1153 
1154 #ifdef EPOLL_SUPPORT
1155  if (0 != (daemon->options & MHD_USE_EPOLL))
1156  {
1157  if (daemon->shutdown)
1158  return MHD_NO;
1159 
1160  /* we're in epoll mode, use the epoll FD as a stand-in for
1161  the entire event set */
1162 
1163  return MHD_add_to_fd_set_ (daemon->epoll_fd,
1164  read_fd_set,
1165  max_fd,
1166  fd_setsize) ? MHD_YES : MHD_NO;
1167  }
1168 #endif
1169 
1170  return internal_get_fdset2 (daemon,
1171  read_fd_set,
1172  write_fd_set,
1173  except_fd_set,
1174  max_fd,
1175  fd_setsize);
1176 }
1177 
1178 
1192 static enum MHD_Result
1193 call_handlers (struct MHD_Connection *con,
1194  bool read_ready,
1195  bool write_ready,
1196  bool force_close)
1197 {
1198  enum MHD_Result ret;
1199  bool states_info_processed = false;
1200  /* Fast track flag */
1201  bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
1202 
1203 #ifdef HTTPS_SUPPORT
1204  if (con->tls_read_ready)
1205  read_ready = true;
1206 #endif /* HTTPS_SUPPORT */
1207  if (! force_close)
1208  {
1209  if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) &&
1210  read_ready)
1211  {
1213  ret = MHD_connection_handle_idle (con);
1214  states_info_processed = true;
1215  }
1216  /* No need to check value of 'ret' here as closed connection
1217  * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
1218  if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
1219  write_ready)
1220  {
1222  ret = MHD_connection_handle_idle (con);
1223  states_info_processed = true;
1224  }
1225  }
1226  else
1227  {
1228  MHD_connection_close_ (con,
1230  return MHD_connection_handle_idle (con);
1231  }
1232 
1233  if (! states_info_processed)
1234  { /* Connection is not read or write ready, but external conditions
1235  * may be changed and need to be processed. */
1236  ret = MHD_connection_handle_idle (con);
1237  }
1238  /* Fast track for fast connections. */
1239  /* If full request was read by single read_handler() invocation
1240  and headers were completely prepared by single MHD_connection_handle_idle()
1241  then try not to wait for next sockets polling and send response
1242  immediately.
1243  As writeability of socket was not checked and it may have
1244  some data pending in system buffers, use this optimization
1245  only for non-blocking sockets. */
1246  /* No need to check 'ret' as connection is always in
1247  * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
1248  else if (on_fasttrack && con->sk_nonblck)
1249  {
1251  {
1253  /* Always call 'MHD_connection_handle_idle()' after each read/write. */
1254  ret = MHD_connection_handle_idle (con);
1255  }
1256  /* If all headers were sent by single write_handler() and
1257  * response body is prepared by single MHD_connection_handle_idle()
1258  * call - continue. */
1259  if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
1261  {
1263  ret = MHD_connection_handle_idle (con);
1264  }
1265  }
1266 
1267  /* All connection's data and states are processed for this turn.
1268  * If connection already has more data to be processed - use
1269  * zero timeout for next select()/poll(). */
1270  /* Thread-per-connection do not need global zero timeout as
1271  * connections are processed individually. */
1272  /* Note: no need to check for read buffer availability for
1273  * TLS read-ready connection in 'read info' state as connection
1274  * without space in read buffer will be marked as 'info block'. */
1275  if ( (! con->daemon->data_already_pending) &&
1276  (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1277  {
1279  con->daemon->data_already_pending = true;
1280 #ifdef HTTPS_SUPPORT
1281  else if ( (con->tls_read_ready) &&
1283  con->daemon->data_already_pending = true;
1284 #endif /* HTTPS_SUPPORT */
1285  }
1286  return ret;
1287 }
1288 
1289 
1290 #ifdef UPGRADE_SUPPORT
1298 static void
1299 cleanup_upgraded_connection (struct MHD_Connection *connection)
1300 {
1301  struct MHD_UpgradeResponseHandle *urh = connection->urh;
1302 
1303  if (NULL == urh)
1304  return;
1305 #ifdef HTTPS_SUPPORT
1306  /* Signal remote client the end of TLS connection by
1307  * gracefully closing TLS session. */
1308  if (0 != (connection->daemon->options & MHD_USE_TLS))
1309  gnutls_bye (connection->tls_session,
1310  GNUTLS_SHUT_WR);
1311 
1312  if (MHD_INVALID_SOCKET != urh->mhd.socket)
1313  MHD_socket_close_chk_ (urh->mhd.socket);
1314 
1315  if (MHD_INVALID_SOCKET != urh->app.socket)
1316  MHD_socket_close_chk_ (urh->app.socket);
1317 #endif /* HTTPS_SUPPORT */
1318  connection->urh = NULL;
1319  free (urh);
1320 }
1321 
1322 
1323 #endif /* UPGRADE_SUPPORT */
1324 
1325 
1326 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1335 static void
1336 process_urh (struct MHD_UpgradeResponseHandle *urh)
1337 {
1338  /* Help compiler to optimize:
1339  * pointers to 'connection' and 'daemon' are not changed
1340  * during this processing, so no need to chain dereference
1341  * each time. */
1342  struct MHD_Connection *const connection = urh->connection;
1343  struct MHD_Daemon *const daemon = connection->daemon;
1344  /* Prevent data races: use same value of 'was_closed' throughout
1345  * this function. If 'was_closed' changed externally in the middle
1346  * of processing - it will be processed on next iteration. */
1347  bool was_closed;
1348 
1349 #ifdef MHD_USE_THREADS
1350  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
1351  MHD_thread_ID_match_current_ (connection->pid) );
1352 #endif /* MHD_USE_THREADS */
1353  if (daemon->shutdown)
1354  {
1355  /* Daemon shutting down, application will not receive any more data. */
1356 #ifdef HAVE_MESSAGES
1357  if (! urh->was_closed)
1358  {
1359  MHD_DLOG (daemon,
1360  _ (
1361  "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1362  }
1363 #endif
1364  urh->was_closed = true;
1365  }
1366  was_closed = urh->was_closed;
1367  if (was_closed)
1368  {
1369  /* Application was closed connections: no more data
1370  * can be forwarded to application socket. */
1371  if (0 < urh->in_buffer_used)
1372  {
1373 #ifdef HAVE_MESSAGES
1374  MHD_DLOG (daemon,
1375  _ ("Failed to forward to application "
1377  " bytes of data received from remote side: application shut down socket.\n"),
1378  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
1379 #endif
1380 
1381  }
1382  /* If application signaled MHD about socket closure then
1383  * check for any pending data even if socket is not marked
1384  * as 'ready' (signal may arrive after poll()/select()).
1385  * Socketpair for forwarding is always in non-blocking mode
1386  * so no risk that recv() will block the thread. */
1387  if (0 != urh->out_buffer_size)
1388  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1389  /* Discard any data received form remote. */
1390  urh->in_buffer_used = 0;
1391  /* Do not try to push data to application. */
1392  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1393  /* Reading from remote client is not required anymore. */
1394  urh->in_buffer_size = 0;
1395  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1396  connection->tls_read_ready = false;
1397  }
1398 
1399  /* On some platforms (W32, possibly Darwin) failed send() (send() will
1400  * always fail after remote disconnect was detected) may discard data in
1401  * system buffers received by system but not yet read by recv(). So, before
1402  * trying send() on any socket, recv() must be performed at first otherwise
1403  * last part of incoming data may be lost. If disconnect or error was
1404  * detected - try to read from socket to dry data possibly pending is system
1405  * buffers. */
1406  if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
1407  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
1408  if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
1409  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1410 
1411  /*
1412  * handle reading from remote TLS client
1413  */
1414  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
1415  (connection->tls_read_ready) ) &&
1416  (urh->in_buffer_used < urh->in_buffer_size) )
1417  {
1418  ssize_t res;
1419  size_t buf_size;
1420 
1421  buf_size = urh->in_buffer_size - urh->in_buffer_used;
1422  if (buf_size > SSIZE_MAX)
1423  buf_size = SSIZE_MAX;
1424 
1425  connection->tls_read_ready = false;
1426  res = gnutls_record_recv (connection->tls_session,
1427  &urh->in_buffer[urh->in_buffer_used],
1428  buf_size);
1429  if (0 >= res)
1430  {
1431  if (GNUTLS_E_INTERRUPTED != res)
1432  {
1433  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1434  if (GNUTLS_E_AGAIN != res)
1435  {
1436  /* Unrecoverable error on socket was detected or
1437  * socket was disconnected/shut down. */
1438  /* Stop trying to read from this TLS socket. */
1439  urh->in_buffer_size = 0;
1440  }
1441  }
1442  }
1443  else /* 0 < res */
1444  {
1445  urh->in_buffer_used += res;
1446  if (0 < gnutls_record_check_pending (connection->tls_session))
1447  {
1448  connection->tls_read_ready = true;
1449  }
1450  }
1451  if (MHD_EPOLL_STATE_ERROR ==
1452  ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
1453  {
1454  /* Unrecoverable error on socket was detected and all
1455  * pending data was read from system buffers. */
1456  /* Stop trying to read from this TLS socket. */
1457  urh->in_buffer_size = 0;
1458  }
1459  }
1460 
1461  /*
1462  * handle reading from application
1463  */
1464  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1465  (urh->out_buffer_used < urh->out_buffer_size) )
1466  {
1467  ssize_t res;
1468  size_t buf_size;
1469 
1470  buf_size = urh->out_buffer_size - urh->out_buffer_used;
1471  if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
1472  buf_size = MHD_SCKT_SEND_MAX_SIZE_;
1473 
1474  res = MHD_recv_ (urh->mhd.socket,
1475  &urh->out_buffer[urh->out_buffer_used],
1476  buf_size);
1477  if (0 >= res)
1478  {
1479  const int err = MHD_socket_get_error_ ();
1480  if ((0 == res) ||
1481  ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1482  (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))))
1483  {
1484  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1485  if ((0 == res) ||
1486  (was_closed) ||
1487  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1488  (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
1489  {
1490  /* Socket disconnect/shutdown was detected;
1491  * Application signaled about closure of 'upgraded' socket;
1492  * or persistent / unrecoverable error. */
1493  /* Do not try to pull more data from application. */
1494  urh->out_buffer_size = 0;
1495  }
1496  }
1497  }
1498  else /* 0 < res */
1499  {
1500  urh->out_buffer_used += res;
1501  if (buf_size > (size_t) res)
1502  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1503  }
1504  if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1505  ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1506  (was_closed) ) )
1507  {
1508  /* Unrecoverable error on socket was detected and all
1509  * pending data was read from system buffers. */
1510  /* Do not try to pull more data from application. */
1511  urh->out_buffer_size = 0;
1512  }
1513  }
1514 
1515  /*
1516  * handle writing to remote HTTPS client
1517  */
1518  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
1519  (urh->out_buffer_used > 0) )
1520  {
1521  ssize_t res;
1522  size_t data_size;
1523 
1524  data_size = urh->out_buffer_used;
1525  if (data_size > SSIZE_MAX)
1526  data_size = SSIZE_MAX;
1527 
1528  res = gnutls_record_send (connection->tls_session,
1529  urh->out_buffer,
1530  data_size);
1531  if (0 >= res)
1532  {
1533  if (GNUTLS_E_INTERRUPTED != res)
1534  {
1535  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1536  if (GNUTLS_E_AGAIN != res)
1537  {
1538  /* TLS connection shut down or
1539  * persistent / unrecoverable error. */
1540 #ifdef HAVE_MESSAGES
1541  MHD_DLOG (daemon,
1542  _ (
1543  "Failed to forward to remote client "
1545  " bytes of data received from application: %s\n"),
1546  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
1547  gnutls_strerror (res));
1548 #endif
1549  /* Discard any data unsent to remote. */
1550  urh->out_buffer_used = 0;
1551  /* Do not try to pull more data from application. */
1552  urh->out_buffer_size = 0;
1553  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1554  }
1555  }
1556  }
1557  else /* 0 < res */
1558  {
1559  const size_t next_out_buffer_used = urh->out_buffer_used - res;
1560  if (0 != next_out_buffer_used)
1561  {
1562  memmove (urh->out_buffer,
1563  &urh->out_buffer[res],
1564  next_out_buffer_used);
1565  if (data_size > (size_t) res)
1566  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1567  }
1568  urh->out_buffer_used = next_out_buffer_used;
1569  }
1570  if ( (0 == urh->out_buffer_used) &&
1571  (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
1572  {
1573  /* Unrecoverable error on socket was detected and all
1574  * pending data was sent to remote. */
1575  /* Do not try to send to remote anymore. */
1576  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1577  /* Do not try to pull more data from application. */
1578  urh->out_buffer_size = 0;
1579  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1580  }
1581  }
1582 
1583  /*
1584  * handle writing to application
1585  */
1586  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
1587  (urh->in_buffer_used > 0) )
1588  {
1589  ssize_t res;
1590  size_t data_size;
1591 
1592  data_size = urh->in_buffer_used;
1593  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
1594  data_size = MHD_SCKT_SEND_MAX_SIZE_;
1595 
1596  res = MHD_send_ (urh->mhd.socket,
1597  urh->in_buffer,
1598  data_size);
1599  if (0 >= res)
1600  {
1601  const int err = MHD_socket_get_error_ ();
1602  if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1603  (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) )
1604  {
1605  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1606  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
1607  {
1608  /* Socketpair connection shut down or
1609  * persistent / unrecoverable error. */
1610 #ifdef HAVE_MESSAGES
1611  MHD_DLOG (daemon,
1612  _ (
1613  "Failed to forward to application "
1615  " bytes of data received from remote side: %s\n"),
1616  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
1617  MHD_socket_strerr_ (err));
1618 #endif
1619  /* Discard any data received form remote. */
1620  urh->in_buffer_used = 0;
1621  /* Reading from remote client is not required anymore. */
1622  urh->in_buffer_size = 0;
1623  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1624  connection->tls_read_ready = false;
1625  }
1626  }
1627  }
1628  else /* 0 < res */
1629  {
1630  const size_t next_in_buffer_used = urh->in_buffer_used - res;
1631  if (0 != next_in_buffer_used)
1632  {
1633  memmove (urh->in_buffer,
1634  &urh->in_buffer[res],
1635  next_in_buffer_used);
1636  if (data_size > (size_t) res)
1637  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1638  }
1639  urh->in_buffer_used = next_in_buffer_used;
1640  }
1641  if ( (0 == urh->in_buffer_used) &&
1642  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
1643  {
1644  /* Do not try to push data to application. */
1645  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1646  /* Reading from remote client is not required anymore. */
1647  urh->in_buffer_size = 0;
1648  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1649  connection->tls_read_ready = false;
1650  }
1651  }
1652 
1653  /* Check whether data is present in TLS buffers
1654  * and incoming forward buffer have some space. */
1655  if ( (connection->tls_read_ready) &&
1656  (urh->in_buffer_used < urh->in_buffer_size) &&
1657  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1658  daemon->data_already_pending = true;
1659 
1660  if ( (daemon->shutdown) &&
1661  ( (0 != urh->out_buffer_size) ||
1662  (0 != urh->out_buffer_used) ) )
1663  {
1664  /* Daemon shutting down, discard any remaining forward data. */
1665 #ifdef HAVE_MESSAGES
1666  if (0 < urh->out_buffer_used)
1667  MHD_DLOG (daemon,
1668  _ (
1669  "Failed to forward to remote client "
1671  " bytes of data received from application: daemon shut down.\n"),
1672  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
1673 #endif
1674  /* Discard any data unsent to remote. */
1675  urh->out_buffer_used = 0;
1676  /* Do not try to sent to remote anymore. */
1677  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1678  /* Do not try to pull more data from application. */
1679  urh->out_buffer_size = 0;
1680  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1681  }
1682 }
1683 
1684 
1685 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1686 
1687 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1688 #ifdef UPGRADE_SUPPORT
1697 static void
1698 thread_main_connection_upgrade (struct MHD_Connection *con)
1699 {
1700 #ifdef HTTPS_SUPPORT
1701  struct MHD_UpgradeResponseHandle *urh = con->urh;
1702  struct MHD_Daemon *daemon = con->daemon;
1703 
1704  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
1705  MHD_thread_ID_match_current_ (con->pid) );
1706  /* Here, we need to bi-directionally forward
1707  until the application tells us that it is done
1708  with the socket; */
1709  if ( (0 != (daemon->options & MHD_USE_TLS)) &&
1710  (0 == (daemon->options & MHD_USE_POLL)))
1711  {
1712  while ( (0 != urh->in_buffer_size) ||
1713  (0 != urh->out_buffer_size) ||
1714  (0 != urh->in_buffer_used) ||
1715  (0 != urh->out_buffer_used) )
1716  {
1717  /* use select */
1718  fd_set rs;
1719  fd_set ws;
1720  fd_set es;
1721  MHD_socket max_fd;
1722  int num_ready;
1723  bool result;
1724 
1725  FD_ZERO (&rs);
1726  FD_ZERO (&ws);
1727  FD_ZERO (&es);
1728  max_fd = MHD_INVALID_SOCKET;
1729  result = urh_to_fdset (urh,
1730  &rs,
1731  &ws,
1732  &es,
1733  &max_fd,
1734  FD_SETSIZE);
1735  if (! result)
1736  {
1737 #ifdef HAVE_MESSAGES
1738  MHD_DLOG (con->daemon,
1739  _ ("Error preparing select.\n"));
1740 #endif
1741  break;
1742  }
1743  /* FIXME: does this check really needed? */
1744  if (MHD_INVALID_SOCKET != max_fd)
1745  {
1746  struct timeval*tvp;
1747  struct timeval tv;
1748  if (((con->tls_read_ready) &&
1749  (urh->in_buffer_used < urh->in_buffer_size)) ||
1750  (daemon->shutdown))
1751  { /* No need to wait if incoming data is already pending in TLS buffers. */
1752  tv.tv_sec = 0;
1753  tv.tv_usec = 0;
1754  tvp = &tv;
1755  }
1756  else
1757  tvp = NULL;
1758  num_ready = MHD_SYS_select_ (max_fd + 1,
1759  &rs,
1760  &ws,
1761  &es,
1762  tvp);
1763  }
1764  else
1765  num_ready = 0;
1766  if (num_ready < 0)
1767  {
1768  const int err = MHD_socket_get_error_ ();
1769 
1770  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1771  continue;
1772 #ifdef HAVE_MESSAGES
1773  MHD_DLOG (con->daemon,
1774  _ ("Error during select (%d): `%s'\n"),
1775  err,
1776  MHD_socket_strerr_ (err));
1777 #endif
1778  break;
1779  }
1780  urh_from_fdset (urh,
1781  &rs,
1782  &ws,
1783  &es);
1784  process_urh (urh);
1785  }
1786  }
1787 #ifdef HAVE_POLL
1788  else if (0 != (daemon->options & MHD_USE_TLS))
1789  {
1790  /* use poll() */
1791  struct pollfd p[2];
1792  memset (p,
1793  0,
1794  sizeof (p));
1795  p[0].fd = urh->connection->socket_fd;
1796  p[1].fd = urh->mhd.socket;
1797 
1798  while ( (0 != urh->in_buffer_size) ||
1799  (0 != urh->out_buffer_size) ||
1800  (0 != urh->in_buffer_used) ||
1801  (0 != urh->out_buffer_used) )
1802  {
1803  int timeout;
1804 
1805  urh_update_pollfd (urh, p);
1806 
1807  if (((con->tls_read_ready) &&
1808  (urh->in_buffer_used < urh->in_buffer_size)) ||
1809  (daemon->shutdown))
1810  timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
1811  else
1812  timeout = -1;
1813 
1814  if (MHD_sys_poll_ (p,
1815  2,
1816  timeout) < 0)
1817  {
1818  const int err = MHD_socket_get_error_ ();
1819 
1820  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1821  continue;
1822 #ifdef HAVE_MESSAGES
1823  MHD_DLOG (con->daemon,
1824  _ ("Error during poll: `%s'\n"),
1825  MHD_socket_strerr_ (err));
1826 #endif
1827  break;
1828  }
1829  urh_from_pollfd (urh,
1830  p);
1831  process_urh (urh);
1832  }
1833  }
1834  /* end POLL */
1835 #endif
1836  /* end HTTPS */
1837 #endif /* HTTPS_SUPPORT */
1838  /* TLS forwarding was finished. Cleanup socketpair. */
1840  /* Do not set 'urh->clean_ready' yet as 'urh' will be used
1841  * in connection thread for a little while. */
1842 }
1843 
1844 
1845 #endif /* UPGRADE_SUPPORT */
1846 
1847 
1855 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1857 {
1858  struct MHD_Connection *con = data;
1859  struct MHD_Daemon *daemon = con->daemon;
1860  int num_ready;
1861  fd_set rs;
1862  fd_set ws;
1863  fd_set es;
1864  MHD_socket maxsock;
1865  struct timeval tv;
1866  struct timeval *tvp;
1867  time_t now;
1868 #if WINDOWS
1869 #ifdef HAVE_POLL
1870  int extra_slot;
1871 #endif /* HAVE_POLL */
1872 #define EXTRA_SLOTS 1
1873 #else /* !WINDOWS */
1874 #define EXTRA_SLOTS 0
1875 #endif /* !WINDOWS */
1876 #ifdef HAVE_POLL
1877  struct pollfd p[1 + EXTRA_SLOTS];
1878 #endif
1879 #undef EXTRA_SLOTS
1880 #ifdef HAVE_POLL
1881  const bool use_poll = (0 != (daemon->options & MHD_USE_POLL));
1882 #else /* ! HAVE_POLL */
1883  const bool use_poll = 0;
1884 #endif /* ! HAVE_POLL */
1885  bool was_suspended = false;
1886  MHD_thread_init_ (&(con->pid));
1887 
1888  while ( (! daemon->shutdown) &&
1889  (MHD_CONNECTION_CLOSED != con->state) )
1890  {
1891  const time_t timeout = daemon->connection_timeout;
1892 #ifdef UPGRADE_SUPPORT
1893  struct MHD_UpgradeResponseHandle *const urh = con->urh;
1894 #else /* ! UPGRADE_SUPPORT */
1895  static const void *const urh = NULL;
1896 #endif /* ! UPGRADE_SUPPORT */
1897 
1898  if ( (con->suspended) &&
1899  (NULL == urh) )
1900  {
1901  /* Connection was suspended, wait for resume. */
1902  was_suspended = true;
1903  if (! use_poll)
1904  {
1905  FD_ZERO (&rs);
1906  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
1907  &rs,
1908  NULL,
1909  FD_SETSIZE))
1910  {
1911  #ifdef HAVE_MESSAGES
1912  MHD_DLOG (con->daemon,
1913  _ ("Failed to add FD to fd_set.\n"));
1914  #endif
1915  goto exit;
1916  }
1917  if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
1918  &rs,
1919  NULL,
1920  NULL,
1921  NULL))
1922  {
1923  const int err = MHD_socket_get_error_ ();
1924 
1925  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1926  continue;
1927 #ifdef HAVE_MESSAGES
1928  MHD_DLOG (con->daemon,
1929  _ ("Error during select (%d): `%s'\n"),
1930  err,
1931  MHD_socket_strerr_ (err));
1932 #endif
1933  break;
1934  }
1935  }
1936 #ifdef HAVE_POLL
1937  else /* use_poll */
1938  {
1939  p[0].events = POLLIN;
1940  p[0].fd = MHD_itc_r_fd_ (daemon->itc);
1941  p[0].revents = 0;
1942  if (0 > MHD_sys_poll_ (p,
1943  1,
1944  -1))
1945  {
1947  continue;
1948 #ifdef HAVE_MESSAGES
1949  MHD_DLOG (con->daemon,
1950  _ ("Error during poll: `%s'\n"),
1952 #endif
1953  break;
1954  }
1955  }
1956 #endif /* HAVE_POLL */
1957  MHD_itc_clear_ (daemon->itc);
1958  continue; /* Check again for resume. */
1959  } /* End of "suspended" branch. */
1960 
1961  if (was_suspended)
1962  {
1963  MHD_update_last_activity_ (con); /* Reset timeout timer. */
1964  /* Process response queued during suspend and update states. */
1966  was_suspended = false;
1967  }
1968 
1969  tvp = NULL;
1970 
1972 #ifdef HTTPS_SUPPORT
1973  || ( (con->tls_read_ready) &&
1975 #endif /* HTTPS_SUPPORT */
1976  )
1977  {
1978  /* do not block: more data may be inside of TLS buffers waiting or
1979  * application must provide response data */
1980  tv.tv_sec = 0;
1981  tv.tv_usec = 0;
1982  tvp = &tv;
1983  }
1984  if ( (NULL == tvp) &&
1985  (timeout > 0) )
1986  {
1987  now = MHD_monotonic_sec_counter ();
1988  if (now - con->last_activity > timeout)
1989  tv.tv_sec = 0;
1990  else
1991  {
1992  const time_t seconds_left = timeout - (now - con->last_activity);
1993 #if ! defined(_WIN32) || defined(__CYGWIN__)
1994  tv.tv_sec = seconds_left;
1995 #else /* _WIN32 && !__CYGWIN__ */
1996  if (seconds_left > TIMEVAL_TV_SEC_MAX)
1997  tv.tv_sec = TIMEVAL_TV_SEC_MAX;
1998  else
1999  tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
2000 #endif /* _WIN32 && ! __CYGWIN__ */
2001  }
2002  tv.tv_usec = 0;
2003  tvp = &tv;
2004  }
2005  if (! use_poll)
2006  {
2007  /* use select */
2008  bool err_state = false;
2009 
2010  FD_ZERO (&rs);
2011  FD_ZERO (&ws);
2012  FD_ZERO (&es);
2013  maxsock = MHD_INVALID_SOCKET;
2014  switch (con->event_loop_info)
2015  {
2017  if (! MHD_add_to_fd_set_ (con->socket_fd,
2018  &rs,
2019  &maxsock,
2020  FD_SETSIZE))
2021  err_state = true;
2022  break;
2024  if (! MHD_add_to_fd_set_ (con->socket_fd,
2025  &ws,
2026  &maxsock,
2027  FD_SETSIZE))
2028  err_state = true;
2029  break;
2031  if (! MHD_add_to_fd_set_ (con->socket_fd,
2032  &es,
2033  &maxsock,
2034  FD_SETSIZE))
2035  err_state = true;
2036  break;
2038  /* how did we get here!? */
2039  goto exit;
2040  }
2041 #if WINDOWS
2042  if (MHD_ITC_IS_VALID_ (daemon->itc) )
2043  {
2044  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
2045  &rs,
2046  &maxsock,
2047  FD_SETSIZE))
2048  err_state = 1;
2049  }
2050 #endif
2051  if (err_state)
2052  {
2053 #ifdef HAVE_MESSAGES
2054  MHD_DLOG (con->daemon,
2055  _ ("Failed to add FD to fd_set.\n"));
2056 #endif
2057  goto exit;
2058  }
2059 
2060  num_ready = MHD_SYS_select_ (maxsock + 1,
2061  &rs,
2062  &ws,
2063  &es,
2064  tvp);
2065  if (num_ready < 0)
2066  {
2067  const int err = MHD_socket_get_error_ ();
2068 
2069  if (MHD_SCKT_ERR_IS_EINTR_ (err))
2070  continue;
2071 #ifdef HAVE_MESSAGES
2072  MHD_DLOG (con->daemon,
2073  _ ("Error during select (%d): `%s'\n"),
2074  err,
2075  MHD_socket_strerr_ (err));
2076 #endif
2077  break;
2078  }
2079 #if WINDOWS
2080  /* Clear ITC before other processing so additional
2081  * signals will trigger select() again */
2082  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2083  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
2084  &rs)) )
2085  MHD_itc_clear_ (daemon->itc);
2086 #endif
2087  if (MHD_NO ==
2088  call_handlers (con,
2089  FD_ISSET (con->socket_fd,
2090  &rs),
2091  FD_ISSET (con->socket_fd,
2092  &ws),
2093  FD_ISSET (con->socket_fd,
2094  &es)) )
2095  goto exit;
2096  }
2097 #ifdef HAVE_POLL
2098  else
2099  {
2100  /* use poll */
2101  memset (&p,
2102  0,
2103  sizeof (p));
2104  p[0].fd = con->socket_fd;
2105  switch (con->event_loop_info)
2106  {
2108  p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2109  break;
2111  p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2112  break;
2114  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2115  break;
2117  /* how did we get here!? */
2118  goto exit;
2119  }
2120 #if WINDOWS
2121  extra_slot = 0;
2122  if (MHD_ITC_IS_VALID_ (daemon->itc))
2123  {
2124  p[1].events |= POLLIN;
2125  p[1].fd = MHD_itc_r_fd_ (daemon->itc);
2126  p[1].revents = 0;
2127  extra_slot = 1;
2128  }
2129 #endif
2130  if (MHD_sys_poll_ (p,
2131 #if WINDOWS
2132  1 + extra_slot,
2133 #else
2134  1,
2135 #endif
2136  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2137  {
2139  continue;
2140 #ifdef HAVE_MESSAGES
2141  MHD_DLOG (con->daemon,
2142  _ ("Error during poll: `%s'\n"),
2144 #endif
2145  break;
2146  }
2147 #if WINDOWS
2148  /* Clear ITC before other processing so additional
2149  * signals will trigger poll() again */
2150  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2151  (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2152  MHD_itc_clear_ (daemon->itc);
2153 #endif
2154  if (MHD_NO ==
2155  call_handlers (con,
2156  (0 != (p[0].revents & POLLIN)),
2157  (0 != (p[0].revents & POLLOUT)),
2158  (0 != (p[0].revents & (POLLERR
2159  | MHD_POLL_REVENTS_ERR_DISC))) ))
2160  goto exit;
2161  }
2162 #endif
2163 #ifdef UPGRADE_SUPPORT
2164  if (MHD_CONNECTION_UPGRADE == con->state)
2165  {
2166  /* Normal HTTP processing is finished,
2167  * notify application. */
2168  if ( (NULL != daemon->notify_completed) &&
2169  (con->client_aware) )
2170  daemon->notify_completed (daemon->notify_completed_cls,
2171  con,
2172  &con->client_context,
2174  con->client_aware = false;
2175 
2176  thread_main_connection_upgrade (con);
2177  /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
2178 
2179  /* "Upgraded" data will not be used in this thread from this point. */
2180  con->urh->clean_ready = true;
2181  /* If 'urh->was_closed' set to true, connection will be
2182  * moved immediately to cleanup list. Otherwise connection
2183  * will stay in suspended list until 'urh' will be marked
2184  * with 'was_closed' by application. */
2185  MHD_resume_connection (con);
2186 
2187  /* skip usual clean up */
2188  return (MHD_THRD_RTRN_TYPE_) 0;
2189  }
2190 #endif /* UPGRADE_SUPPORT */
2191  }
2192 #if _MHD_DEBUG_CLOSE
2193 #ifdef HAVE_MESSAGES
2194  MHD_DLOG (con->daemon,
2195  _ ("Processing thread terminating. Closing connection.\n"));
2196 #endif
2197 #endif
2198  if (MHD_CONNECTION_CLOSED != con->state)
2199  MHD_connection_close_ (con,
2200  (daemon->shutdown) ?
2204 exit:
2205  if (NULL != con->response)
2206  {
2208  con->response = NULL;
2209  }
2210 
2211  if (MHD_INVALID_SOCKET != con->socket_fd)
2212  {
2213  shutdown (con->socket_fd,
2214  SHUT_WR);
2215  /* 'socket_fd' can be used in other thread to signal shutdown.
2216  * To avoid data races, do not close socket here. Daemon will
2217  * use more connections only after cleanup anyway. */
2218  }
2219  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2220  (! MHD_itc_activate_ (daemon->itc, "t")) )
2221  {
2222 #ifdef HAVE_MESSAGES
2223  MHD_DLOG (daemon,
2224  _ (
2225  "Failed to signal thread termination via inter-thread communication channel.\n"));
2226 #endif
2227  }
2228  return (MHD_THRD_RTRN_TYPE_) 0;
2229 }
2230 
2231 
2232 #endif
2233 
2234 
2242 static void
2243 MHD_cleanup_connections (struct MHD_Daemon *daemon);
2244 
2245 #if defined(HTTPS_SUPPORT)
2246 #if defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED) && \
2247  defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \
2248  ! defined(MHD_socket_nosignal_) && \
2249  (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL)
2255 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2256 #endif /* MHD_SEND_SPIPE_SUPPRESS_NEEDED &&
2257  MHD_SEND_SPIPE_SUPPRESS_POSSIBLE &&
2258  ! MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) &&
2259  MSG_NOSIGNAL */
2260 
2261 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2266 static ssize_t
2267 MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
2268  const void *data,
2269  size_t data_size)
2270 {
2271 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2272  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
2273  data_size = MHD_SCKT_SEND_MAX_SIZE_;
2274 #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */
2275  return MHD_send_ ((MHD_socket) (intptr_t) (trnsp), data, data_size);
2276 }
2277 
2278 
2279 #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
2280 
2281 
2290 static int
2291 psk_gnutls_adapter (gnutls_session_t session,
2292  const char *username,
2293  gnutls_datum_t *key)
2294 {
2295  struct MHD_Connection *connection;
2296  struct MHD_Daemon *daemon;
2297  void *app_psk;
2298  size_t app_psk_size;
2299 
2300  connection = gnutls_session_get_ptr (session);
2301  if (NULL == connection)
2302  {
2303 #ifdef HAVE_MESSAGES
2304  /* Cannot use our logger, we don't even have "daemon" */
2305  MHD_PANIC (_ ("Internal server error. This should be impossible.\n"));
2306 #endif
2307  return -1;
2308  }
2309  daemon = connection->daemon;
2310 #if GNUTLS_VERSION_MAJOR >= 3
2311  if (NULL == daemon->cred_callback)
2312  {
2313 #ifdef HAVE_MESSAGES
2314  MHD_DLOG (daemon,
2315  _ ("PSK not supported by this server.\n"));
2316 #endif
2317  return -1;
2318  }
2319  if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2320  connection,
2321  username,
2322  &app_psk,
2323  &app_psk_size))
2324  return -1;
2325  if (NULL == (key->data = gnutls_malloc (app_psk_size)))
2326  {
2327 #ifdef HAVE_MESSAGES
2328  MHD_DLOG (daemon,
2329  _ (
2330  "PSK authentication failed: gnutls_malloc failed to allocate memory.\n"));
2331 #endif
2332  free (app_psk);
2333  return -1;
2334  }
2335  if (UINT_MAX < app_psk_size)
2336  {
2337 #ifdef HAVE_MESSAGES
2338  MHD_DLOG (daemon,
2339  _ ("PSK authentication failed: PSK too long.\n"));
2340 #endif
2341  free (app_psk);
2342  return -1;
2343  }
2344  key->size = (unsigned int) app_psk_size;
2345  memcpy (key->data,
2346  app_psk,
2347  app_psk_size);
2348  free (app_psk);
2349  return 0;
2350 #else
2351 #ifdef HAVE_MESSAGES
2352  MHD_DLOG (daemon,
2353  _ ("PSK not supported by this server.\n"));
2354 #endif
2355  return -1;
2356 #endif
2357 }
2358 
2359 
2360 #endif /* HTTPS_SUPPORT */
2361 
2362 
2385 static struct MHD_Connection *
2387  MHD_socket client_socket,
2388  const struct sockaddr *addr,
2389  socklen_t addrlen,
2390  bool external_add,
2391  bool non_blck,
2392  bool sk_spipe_supprs,
2393  enum MHD_tristate sk_is_nonip)
2394 {
2395  struct MHD_Connection *connection;
2396  int eno = 0;
2397 
2398 #ifdef HAVE_MESSAGES
2399 #if _MHD_DEBUG_CONNECT
2400  MHD_DLOG (daemon,
2401  _ ("Accepted connection on socket %d.\n"),
2402  client_socket);
2403 #endif
2404 #endif
2405  if ( (daemon->connections == daemon->connection_limit) ||
2407  addr,
2408  addrlen)) )
2409  {
2410  /* above connection limit - reject */
2411 #ifdef HAVE_MESSAGES
2412  MHD_DLOG (daemon,
2413  _ (
2414  "Server reached connection limit. Closing inbound connection.\n"));
2415 #endif
2416  MHD_socket_close_chk_ (client_socket);
2417 #if ENFILE
2418  errno = ENFILE;
2419 #endif
2420  return NULL;
2421  }
2422 
2423  /* apply connection acceptance policy if present */
2424  if ( (NULL != daemon->apc) &&
2425  (MHD_NO == daemon->apc (daemon->apc_cls,
2426  addr,
2427  addrlen)) )
2428  {
2429 #if _MHD_DEBUG_CLOSE
2430 #ifdef HAVE_MESSAGES
2431  MHD_DLOG (daemon,
2432  _ ("Connection rejected by application. Closing connection.\n"));
2433 #endif
2434 #endif
2435  MHD_socket_close_chk_ (client_socket);
2437  addr,
2438  addrlen);
2439 #if EACCESS
2440  errno = EACCESS;
2441 #endif
2442  return NULL;
2443  }
2444 
2445  if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection))))
2446  {
2447  eno = errno;
2448 #ifdef HAVE_MESSAGES
2449  MHD_DLOG (daemon,
2450  _ ("Error allocating memory: %s\n"),
2451  MHD_strerror_ (errno));
2452 #endif
2453  MHD_socket_close_chk_ (client_socket);
2455  addr,
2456  addrlen);
2457  errno = eno;
2458  return NULL;
2459  }
2460 
2461  if (! external_add)
2462  {
2463  connection->sk_corked = _MHD_OFF;
2464  connection->sk_nodelay = _MHD_OFF;
2465  }
2466  else
2467  {
2468  connection->sk_corked = _MHD_UNKNOWN;
2469  connection->sk_nodelay = _MHD_UNKNOWN;
2470  }
2471 
2473  if (NULL == (connection->addr = malloc (addrlen)))
2474  {
2475  eno = errno;
2476 #ifdef HAVE_MESSAGES
2477  MHD_DLOG (daemon,
2478  _ ("Error allocating memory: %s\n"),
2479  MHD_strerror_ (errno));
2480 #endif
2481  MHD_socket_close_chk_ (client_socket);
2483  addr,
2484  addrlen);
2485  free (connection);
2486  errno = eno;
2487  return NULL;
2488  }
2489  memcpy (connection->addr,
2490  addr,
2491  addrlen);
2492  connection->addr_len = addrlen;
2493  connection->socket_fd = client_socket;
2494  connection->sk_nonblck = non_blck;
2495  connection->is_nonip = sk_is_nonip;
2496  connection->sk_spipe_suppress = sk_spipe_supprs;
2497  connection->daemon = daemon;
2498  connection->last_activity = MHD_monotonic_sec_counter ();
2499 
2500  if (0 == (daemon->options & MHD_USE_TLS))
2501  {
2502  /* set default connection handlers */
2503  MHD_set_http_callbacks_ (connection);
2504  }
2505  else
2506  {
2507 #ifdef HTTPS_SUPPORT
2508 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500)
2509  gnutls_init_flags_t
2510 #else
2511  unsigned int
2512 #endif
2513  flags;
2514 
2515  flags = GNUTLS_SERVER;
2516 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
2517  flags |= GNUTLS_NO_SIGNAL;
2518 #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
2519 #if GNUTLS_VERSION_MAJOR >= 3
2520  flags |= GNUTLS_NONBLOCK;
2521 #endif /* GNUTLS_VERSION_MAJOR >= 3*/
2522 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603)
2524  flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2525 #endif
2526 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605)
2528  flags |= GNUTLS_ENABLE_EARLY_DATA;
2529 #endif
2530  connection->tls_state = MHD_TLS_CONN_INIT;
2531  MHD_set_https_callbacks (connection);
2532  if ((GNUTLS_E_SUCCESS != gnutls_init (&connection->tls_session, flags)) ||
2533  (GNUTLS_E_SUCCESS != gnutls_priority_set (connection->tls_session,
2534  daemon->priority_cache)))
2535  {
2536  if (NULL != connection->tls_session)
2537  gnutls_deinit (connection->tls_session);
2538  MHD_socket_close_chk_ (client_socket);
2540  addr,
2541  addrlen);
2542  free (connection->addr);
2543  free (connection);
2544 #ifdef HAVE_MESSAGES
2545  MHD_DLOG (daemon,
2546  _ ("Failed to initialise TLS session.\n"));
2547 #endif
2548 #if EPROTO
2549  errno = EPROTO;
2550 #endif
2551  return NULL;
2552  }
2553 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030200)
2554  if (! daemon->disable_alpn)
2555  {
2556  gnutls_datum_t prts[2];
2557  const char prt1[] = "http/1.1"; /* Registered code for HTTP/1.1 */
2558  const char prt2[] = "http/1.0"; /* Registered code for HTTP/1.0 */
2559 
2560  prts[0].data = (void*) prt1;
2561  prts[0].size = MHD_STATICSTR_LEN_ (prt1);
2562  prts[1].data = (void*) prt2;
2563  prts[1].size = MHD_STATICSTR_LEN_ (prt2);
2564  if (GNUTLS_E_SUCCESS !=
2565  gnutls_alpn_set_protocols (connection->tls_session,
2566  prts,
2567  sizeof(prts) / sizeof(prts[0]),
2568  0 /* || GNUTLS_ALPN_SERVER_PRECEDENCE */))
2569  {
2570 #ifdef HAVE_MESSAGES
2571  MHD_DLOG (daemon,
2572  _ ("Failed to set ALPN protocols.\n"));
2573 #else /* ! HAVE_MESSAGES */
2574  (void) 0; /* Mute compiler warning */
2575 #endif /* ! HAVE_MESSAGES */
2576  }
2577  }
2578 #endif /* GNUTLS_VERSION_NUMBER >= 0x030200 */
2579  gnutls_session_set_ptr (connection->tls_session,
2580  connection);
2581  switch (daemon->cred_type)
2582  {
2583  /* set needed credentials for certificate authentication. */
2584  case GNUTLS_CRD_CERTIFICATE:
2585  gnutls_credentials_set (connection->tls_session,
2586  GNUTLS_CRD_CERTIFICATE,
2587  daemon->x509_cred);
2588  break;
2589  case GNUTLS_CRD_PSK:
2590  gnutls_credentials_set (connection->tls_session,
2591  GNUTLS_CRD_PSK,
2592  daemon->psk_cred);
2593  gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2594  &psk_gnutls_adapter);
2595  break;
2596  default:
2597 #ifdef HAVE_MESSAGES
2598  MHD_DLOG (daemon,
2599  _ (
2600  "Failed to setup TLS credentials: unknown credential type %d.\n"),
2601  daemon->cred_type);
2602 #endif
2603  gnutls_deinit (connection->tls_session);
2604  MHD_socket_close_chk_ (client_socket);
2606  addr,
2607  addrlen);
2608  free (connection->addr);
2609  free (connection);
2610  MHD_PANIC (_ ("Unknown credential type.\n"));
2611 #if EINVAL
2612  errno = EINVAL;
2613 #endif
2614  return NULL;
2615  }
2616 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
2617  gnutls_transport_set_int (connection->tls_session,
2618  (int) (client_socket));
2619 #else /* GnuTLS before 3.1.9 or Win x64 */
2620  gnutls_transport_set_ptr (connection->tls_session,
2621  (gnutls_transport_ptr_t) (intptr_t) (client_socket));
2622 #endif /* GnuTLS before 3.1.9 */
2623 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2624  gnutls_transport_set_push_function (connection->tls_session,
2625  MHD_tls_push_func_);
2626 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
2627  if (daemon->https_mem_trust)
2628  gnutls_certificate_server_set_request (connection->tls_session,
2629  GNUTLS_CERT_REQUEST);
2630 #else /* ! HTTPS_SUPPORT */
2631  MHD_socket_close_chk_ (client_socket);
2633  addr,
2634  addrlen);
2635  free (connection->addr);
2636  free (connection);
2637  MHD_PANIC (_ ("TLS connection on non-TLS daemon.\n"));
2638  eno = EINVAL;
2639  return NULL;
2640 #endif /* ! HTTPS_SUPPORT */
2641  }
2642 
2643  return connection;
2644 }
2645 
2646 
2647 #ifdef MHD_USE_THREADS
2653 static void
2654 new_connection_close_ (struct MHD_Daemon *daemon,
2655  struct MHD_Connection *connection)
2656 {
2657  mhd_assert (connection->daemon == daemon);
2658  mhd_assert (! connection->in_cleanup);
2659  mhd_assert (NULL == connection->next);
2660  mhd_assert (NULL == connection->nextX);
2661 #ifdef EPOLL_SUPPORT
2662  mhd_assert (NULL == connection->nextE);
2663 #endif /* EPOLL_SUPPORT */
2664 
2665 #ifdef HTTPS_SUPPORT
2666  if (NULL != connection->tls_session)
2667  {
2668  mhd_assert (0 != (daemon->options & MHD_USE_TLS));
2669  gnutls_deinit (connection->tls_session);
2670  }
2671 #endif /* HTTPS_SUPPORT */
2672  MHD_socket_close_chk_ (connection->socket_fd);
2674  connection->addr,
2675  connection->addr_len);
2676  free (connection->addr);
2677  free (connection);
2678 }
2679 
2680 
2681 #endif /* MHD_USE_THREADS */
2682 
2683 
2694 static enum MHD_Result
2696  struct MHD_Connection *connection)
2697 {
2698  int eno = 0;
2699 
2700  mhd_assert (connection->daemon == daemon);
2701 
2702 #ifdef MHD_USE_THREADS
2703  /* Function manipulate connection and timeout DL-lists,
2704  * must be called only within daemon thread. */
2706  MHD_thread_ID_match_current_ (daemon->pid) );
2707 #endif /* MHD_USE_THREADS */
2708 
2709  /* Allocate memory pool in the processing thread so
2710  * intensively used memory area is allocated in "good"
2711  * (for the thread) memory region. It is important with
2712  * NUMA and/or complex cache hierarchy. */
2713  connection->pool = MHD_pool_create (daemon->pool_size);
2714  if (NULL == connection->pool)
2715  {
2716 #ifdef HAVE_MESSAGES
2717  MHD_DLOG (daemon,
2718  _ ("Error allocating memory: %s\n"),
2719  MHD_strerror_ (errno));
2720 #endif
2721  MHD_socket_close_chk_ (connection->socket_fd);
2723  connection->addr,
2724  connection->addr_len);
2725  free (connection);
2726 #if ENOMEM
2727  errno = ENOMEM;
2728 #endif
2729  return MHD_NO;
2730  }
2731 
2732 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2734 #endif
2735  /* Firm check under lock. */
2737  {
2738 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2740 #endif
2741  /* above connection limit - reject */
2742 #ifdef HAVE_MESSAGES
2743  MHD_DLOG (daemon,
2744  _ (
2745  "Server reached connection limit. Closing inbound connection.\n"));
2746 #endif
2747 #if ENFILE
2748  eno = ENFILE;
2749 #endif
2750  goto cleanup;
2751  }
2752  daemon->connections++;
2754  {
2757  connection);
2758  }
2761  connection);
2762 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2764 #endif
2765  if (NULL != daemon->notify_connection)
2767  connection,
2768  &connection->socket_context,
2770 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2771  /* attempt to create handler thread */
2773  {
2774  if (! MHD_create_named_thread_ (&connection->pid,
2775  "MHD-connection",
2776  daemon->thread_stack_size,
2778  connection))
2779  {
2780  eno = errno;
2781 #ifdef HAVE_MESSAGES
2782  MHD_DLOG (daemon,
2783  _ ("Failed to create a thread: %s\n"),
2784  MHD_strerror_ (eno));
2785 #endif
2786  goto cleanup;
2787  }
2788  }
2789  else
2790  connection->pid = daemon->pid;
2791 #endif
2792 #ifdef EPOLL_SUPPORT
2793  if (0 != (daemon->options & MHD_USE_EPOLL))
2794  {
2795  if (0 == (daemon->options & MHD_USE_TURBO))
2796  {
2797  struct epoll_event event;
2798 
2799  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2800  event.data.ptr = connection;
2801  if (0 != epoll_ctl (daemon->epoll_fd,
2802  EPOLL_CTL_ADD,
2803  connection->socket_fd,
2804  &event))
2805  {
2806  eno = errno;
2807 #ifdef HAVE_MESSAGES
2808  MHD_DLOG (daemon,
2809  _ ("Call to epoll_ctl failed: %s\n"),
2811 #endif
2812  goto cleanup;
2813  }
2814  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2815  }
2816  else
2817  {
2818  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY
2821  EDLL_insert (daemon->eready_head,
2822  daemon->eready_tail,
2823  connection);
2824  }
2825  }
2826 #endif
2827 
2828  return MHD_YES;
2829 
2830 cleanup:
2831  if (NULL != daemon->notify_connection)
2832  daemon->notify_connection (daemon->notify_connection_cls,
2833  connection,
2834  &connection->socket_context,
2836 #ifdef HTTPS_SUPPORT
2837  if (NULL != connection->tls_session)
2838  gnutls_deinit (connection->tls_session);
2839 #endif /* HTTPS_SUPPORT */
2840  MHD_socket_close_chk_ (connection->socket_fd);
2841  MHD_ip_limit_del (daemon,
2842  connection->addr,
2843  connection->addr_len);
2844 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2846 #endif
2847  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2848  {
2850  daemon->normal_timeout_tail,
2851  connection);
2852  }
2853  DLL_remove (daemon->connections_head,
2854  daemon->connections_tail,
2855  connection);
2856 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2858 #endif
2859  MHD_pool_destroy (connection->pool);
2860  free (connection->addr);
2861  free (connection);
2862  if (0 != eno)
2863  errno = eno;
2864  else
2865  errno = EINVAL;
2866  return MHD_NO;
2867 }
2868 
2869 
2898 static enum MHD_Result
2899 internal_add_connection (struct MHD_Daemon *daemon,
2900  MHD_socket client_socket,
2901  const struct sockaddr *addr,
2902  socklen_t addrlen,
2903  bool external_add,
2904  bool non_blck,
2905  bool sk_spipe_supprs,
2906  enum MHD_tristate sk_is_nonip)
2907 {
2908  struct MHD_Connection *connection;
2909 
2910 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2911  /* Direct add to master daemon could never happen. */
2913 #endif
2914 
2915  if ( (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
2916  (! MHD_SCKT_FD_FITS_FDSET_ (client_socket, NULL)) )
2917  {
2918 #ifdef HAVE_MESSAGES
2919  MHD_DLOG (daemon,
2920  _ ("New connection socket descriptor (%d) is not less " \
2921  "than FD_SETSIZE (%d).\n"),
2922  (int) client_socket,
2923  (int) FD_SETSIZE);
2924 #endif
2925  MHD_socket_close_chk_ (client_socket);
2926 #if ENFILE
2927  errno = ENFILE;
2928 #endif
2929  return MHD_NO;
2930  }
2931 
2932  if ( (0 == (daemon->options & MHD_USE_EPOLL)) &&
2933  (! non_blck) )
2934  {
2935 #ifdef HAVE_MESSAGES
2936  MHD_DLOG (daemon,
2937  _ ("Epoll mode supports only non-blocking sockets\n"));
2938 #endif
2939  MHD_socket_close_chk_ (client_socket);
2940 #if EINVAL
2941  errno = EINVAL;
2942 #endif
2943  return MHD_NO;
2944  }
2945 
2946  connection = new_connection_prepare_ (daemon,
2947  client_socket,
2948  addr, addrlen,
2949  external_add,
2950  non_blck,
2951  sk_spipe_supprs,
2952  sk_is_nonip);
2953  if (NULL == connection)
2954  return MHD_NO;
2955 
2956  if ((external_add) &&
2958  {
2959  /* Connection is added externally and MHD is handling its own threads. */
2960  MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
2963  connection);
2964  daemon->have_new = true;
2965  MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
2966 
2967  /* The rest of connection processing must be handled in
2968  * the daemon thread. */
2969  if ((MHD_ITC_IS_VALID_ (daemon->itc)) &&
2970  (! MHD_itc_activate_ (daemon->itc, "n")))
2971  {
2972  #ifdef HAVE_MESSAGES
2973  MHD_DLOG (daemon,
2974  _ ("Failed to signal new connection via inter-thread " \
2975  "communication channel.\n"));
2976  #endif
2977  }
2978  return MHD_YES;
2979  }
2980 
2981  return new_connection_process_ (daemon, connection);
2982 }
2983 
2984 
2985 static void
2987 {
2988  struct MHD_Connection *local_head;
2989  struct MHD_Connection *local_tail;
2992 
2993  /* Detach DL-list of new connections from the daemon for
2994  * following local processing. */
2995  MHD_mutex_lock_chk_ (&daemon->new_connections_mutex);
2997  local_head = daemon->new_connections_head;
2998  local_tail = daemon->new_connections_tail;
3001  daemon->have_new = false;
3002  MHD_mutex_unlock_chk_ (&daemon->new_connections_mutex);
3003  (void) local_head; /* Mute compiler warning */
3004 
3005  /* Process new connections in FIFO order. */
3006  do
3007  {
3008  struct MHD_Connection *c;
3010  c = local_tail;
3011  DLL_remove (local_head,
3012  local_tail,
3013  c);
3014  mhd_assert (daemon == c->daemon);
3016  {
3017 #ifdef HAVE_MESSAGES
3018  MHD_DLOG (daemon,
3019  _ ("Failed to start serving new connection.\n"));
3020 #endif
3021  (void) 0;
3022  }
3023  } while (NULL != local_tail);
3024 
3025 }
3026 
3027 
3037 void
3039 {
3040  struct MHD_Daemon *daemon = connection->daemon;
3041 
3042 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3043  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
3044  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
3045  MHD_thread_ID_match_current_ (daemon->pid) );
3047 #endif
3048  if (connection->resuming)
3049  {
3050  /* suspending again while we didn't even complete resuming yet */
3051  connection->resuming = false;
3052 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3054 #endif
3055  return;
3056  }
3057  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3058  {
3059  if (connection->connection_timeout == daemon->connection_timeout)
3061  daemon->normal_timeout_tail,
3062  connection);
3063  else
3065  daemon->manual_timeout_tail,
3066  connection);
3067  }
3068  DLL_remove (daemon->connections_head,
3069  daemon->connections_tail,
3070  connection);
3071  mhd_assert (! connection->suspended);
3074  connection);
3075  connection->suspended = true;
3076 #ifdef EPOLL_SUPPORT
3077  if (0 != (daemon->options & MHD_USE_EPOLL))
3078  {
3079  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3080  {
3081  EDLL_remove (daemon->eready_head,
3082  daemon->eready_tail,
3083  connection);
3084  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3085  }
3086  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
3087  {
3088  if (0 != epoll_ctl (daemon->epoll_fd,
3089  EPOLL_CTL_DEL,
3090  connection->socket_fd,
3091  NULL))
3092  MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
3093  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
3094  }
3095  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
3096  }
3097 #endif
3098 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3100 #endif
3101 }
3102 
3103 
3135 void
3137 {
3138  struct MHD_Daemon *const daemon = connection->daemon;
3139 
3140 #ifdef MHD_USE_THREADS
3141  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
3142  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
3143  MHD_thread_ID_match_current_ (daemon->pid) );
3144 #endif /* MHD_USE_THREADS */
3145 
3146  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3147  MHD_PANIC (_ (
3148  "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
3149 #ifdef UPGRADE_SUPPORT
3150  if (NULL != connection->urh)
3151  {
3152 #ifdef HAVE_MESSAGES
3153  MHD_DLOG (daemon,
3154  _ (
3155  "Error: connection scheduled for \"upgrade\" cannot be suspended.\n"));
3156 #endif /* HAVE_MESSAGES */
3157  return;
3158  }
3159 #endif /* UPGRADE_SUPPORT */
3160  internal_suspend_connection_ (connection);
3161 }
3162 
3163 
3172 void
3174 {
3175  struct MHD_Daemon *daemon = connection->daemon;
3176 
3177  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3178  MHD_PANIC (_ (
3179  "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
3180 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3182 #endif
3183  connection->resuming = true;
3184  daemon->resuming = true;
3185 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3187 #endif
3188  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
3189  (! MHD_itc_activate_ (daemon->itc, "r")) )
3190  {
3191 #ifdef HAVE_MESSAGES
3192  MHD_DLOG (daemon,
3193  _ (
3194  "Failed to signal resume via inter-thread communication channel.\n"));
3195 #endif
3196  }
3197 }
3198 
3199 
3209 static enum MHD_Result
3211 {
3212  struct MHD_Connection *pos;
3213  struct MHD_Connection *prev = NULL;
3214  enum MHD_Result ret;
3215  const bool used_thr_p_c = (0 != (daemon->options
3217 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3220  MHD_thread_ID_match_current_ (daemon->pid) );
3221 #endif
3222 
3223  ret = MHD_NO;
3224 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3226 #endif
3227 
3228  if (daemon->resuming)
3229  {
3231  /* During shutdown check for resuming is forced. */
3232  mhd_assert ((NULL != prev) || (daemon->shutdown) || \
3233  (0 != (daemon->options & MHD_ALLOW_UPGRADE)));
3234  }
3235 
3236  daemon->resuming = false;
3237 
3238  while (NULL != (pos = prev))
3239  {
3240 #ifdef UPGRADE_SUPPORT
3241  struct MHD_UpgradeResponseHandle *const urh = pos->urh;
3242 #else /* ! UPGRADE_SUPPORT */
3243  static const void *const urh = NULL;
3244 #endif /* ! UPGRADE_SUPPORT */
3245  prev = pos->prev;
3246  if ( (! pos->resuming)
3247 #ifdef UPGRADE_SUPPORT
3248  || ( (NULL != urh) &&
3249  ( (! urh->was_closed) ||
3250  (! urh->clean_ready) ) )
3251 #endif /* UPGRADE_SUPPORT */
3252  )
3253  continue;
3254  ret = MHD_YES;
3255  mhd_assert (pos->suspended);
3258  pos);
3259  pos->suspended = false;
3260  if (NULL == urh)
3261  {
3262  DLL_insert (daemon->connections_head,
3263  daemon->connections_tail,
3264  pos);
3265  if (! used_thr_p_c)
3266  {
3267  /* Reset timeout timer on resume. */
3268  if (0 != pos->connection_timeout)
3270 
3271  if (pos->connection_timeout == daemon->connection_timeout)
3273  daemon->normal_timeout_tail,
3274  pos);
3275  else
3277  daemon->manual_timeout_tail,
3278  pos);
3279  }
3280 #ifdef EPOLL_SUPPORT
3281  if (0 != (daemon->options & MHD_USE_EPOLL))
3282  {
3283  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3284  MHD_PANIC ("Resumed connection was already in EREADY set.\n");
3285  /* we always mark resumed connections as ready, as we
3286  might have missed the edge poll event during suspension */
3287  EDLL_insert (daemon->eready_head,
3288  daemon->eready_tail,
3289  pos);
3290  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \
3293  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
3294  }
3295 #endif
3296  }
3297 #ifdef UPGRADE_SUPPORT
3298  else
3299  {
3300  /* Data forwarding was finished (for TLS connections) AND
3301  * application was closed upgraded connection.
3302  * Insert connection into cleanup list. */
3303 
3304  if ( (NULL != daemon->notify_completed) &&
3305  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3306  (pos->client_aware) )
3307  {
3308  daemon->notify_completed (daemon->notify_completed_cls,
3309  pos,
3310  &pos->client_context,
3312  pos->client_aware = false;
3313  }
3314  DLL_insert (daemon->cleanup_head,
3315  daemon->cleanup_tail,
3316  pos);
3317  daemon->data_already_pending = true;
3318  }
3319 #endif /* UPGRADE_SUPPORT */
3320  pos->resuming = false;
3321  }
3322 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3324 #endif
3325  if ( (used_thr_p_c) &&
3326  (MHD_NO != ret) )
3327  { /* Wake up suspended connections. */
3328  if (! MHD_itc_activate_ (daemon->itc,
3329  "w"))
3330  {
3331 #ifdef HAVE_MESSAGES
3332  MHD_DLOG (daemon,
3333  _ (
3334  "Failed to signal resume of connection via inter-thread communication channel.\n"));
3335 #endif
3336  }
3337  }
3338  return ret;
3339 }
3340 
3341 
3369 enum MHD_Result
3370 MHD_add_connection (struct MHD_Daemon *daemon,
3371  MHD_socket client_socket,
3372  const struct sockaddr *addr,
3373  socklen_t addrlen)
3374 {
3375  bool sk_nonbl;
3376  bool sk_spipe_supprs;
3377 
3378  /* NOT thread safe with internal thread. TODO: fix thread safety. */
3379  if ((0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
3380  (daemon->connection_limit <= daemon->connections))
3381  MHD_cleanup_connections (daemon);
3382 
3383 #ifdef HAVE_MESSAGES
3384  if ((0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) &&
3385  (0 == (daemon->options & MHD_USE_ITC)))
3386  {
3387  MHD_DLOG (daemon,
3388  _ ("MHD_add_connection() has been called for daemon started"
3389  " without MHD_USE_ITC flag.\nDaemon will not process newly"
3390  " added connection until any activity occurs in already"
3391  " added sockets.\n"));
3392  }
3393 #endif /* HAVE_MESSAGES */
3394 
3395  if (! MHD_socket_nonblocking_ (client_socket))
3396  {
3397 #ifdef HAVE_MESSAGES
3398  MHD_DLOG (daemon,
3399  _ ("Failed to set nonblocking mode on new client socket: %s\n"),
3401 #endif
3402  sk_nonbl = false;
3403  }
3404  else
3405  sk_nonbl = true;
3406 
3407 #ifndef MHD_WINSOCK_SOCKETS
3408  sk_spipe_supprs = false;
3409 #else /* MHD_WINSOCK_SOCKETS */
3410  sk_spipe_supprs = true; /* Nothing to suppress on W32 */
3411 #endif /* MHD_WINSOCK_SOCKETS */
3412 #if defined(MHD_socket_nosignal_)
3413  if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (client_socket))
3414  {
3415 #ifdef HAVE_MESSAGES
3416  MHD_DLOG (daemon,
3417  _ (
3418  "Failed to suppress SIGPIPE on new client socket: %s\n"),
3420 #else /* ! HAVE_MESSAGES */
3421  (void) 0; /* Mute compiler warning */
3422 #endif /* ! HAVE_MESSAGES */
3423 #ifndef MSG_NOSIGNAL
3424  /* Application expects that SIGPIPE will be suppressed,
3425  * but suppression failed and SIGPIPE cannot be suppressed with send(). */
3426  if (! daemon->sigpipe_blocked)
3427  {
3428  int err = MHD_socket_get_error_ ();
3429  MHD_socket_close_ (client_socket);
3430  MHD_socket_fset_error_ (err);
3431  return MHD_NO;
3432  }
3433 #endif /* MSG_NOSIGNAL */
3434  }
3435  else
3436  sk_spipe_supprs = true;
3437 #endif /* MHD_socket_nosignal_ */
3438 
3439  if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
3440  (! MHD_socket_noninheritable_ (client_socket)) )
3441  {
3442 #ifdef HAVE_MESSAGES
3443  MHD_DLOG (daemon,
3444  _ ("Failed to set noninheritable mode on new client socket.\n"));
3445 #endif
3446  }
3447 
3448 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3449  if (NULL != daemon->worker_pool)
3450  {
3451  unsigned int i;
3452  /* have a pool, try to find a pool with capacity; we use the
3453  socket as the initial offset into the pool for load
3454  balancing */
3455  for (i = 0; i < daemon->worker_pool_size; ++i)
3456  {
3457  struct MHD_Daemon *const worker =
3458  &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
3459  if (worker->connections < worker->connection_limit)
3460  return internal_add_connection (worker,
3461  client_socket,
3462  addr,
3463  addrlen,
3464  true,
3465  sk_nonbl,
3466  sk_spipe_supprs,
3467  _MHD_UNKNOWN);
3468  }
3469  /* all pools are at their connection limit, must refuse */
3470  MHD_socket_close_chk_ (client_socket);
3471 #if ENFILE
3472  errno = ENFILE;
3473 #endif
3474  return MHD_NO;
3475  }
3476 #endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */
3477 
3478  return internal_add_connection (daemon,
3479  client_socket,
3480  addr,
3481  addrlen,
3482  true,
3483  sk_nonbl,
3484  sk_spipe_supprs,
3485  _MHD_UNKNOWN);
3486 }
3487 
3488 
3503 static enum MHD_Result
3504 MHD_accept_connection (struct MHD_Daemon *daemon)
3505 {
3506 #if HAVE_INET6
3507  struct sockaddr_in6 addrstorage;
3508 #else
3509  struct sockaddr_in addrstorage;
3510 #endif
3511  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
3512  socklen_t addrlen;
3513  MHD_socket s;
3514  MHD_socket fd;
3515  bool sk_nonbl;
3516  bool sk_spipe_supprs;
3517 
3518 #ifdef MHD_USE_THREADS
3519  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
3520  MHD_thread_ID_match_current_ (daemon->pid) );
3521 #endif /* MHD_USE_THREADS */
3522 
3523  addrlen = sizeof (addrstorage);
3524  memset (addr,
3525  0,
3526  sizeof (addrstorage));
3527  if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) ||
3528  (daemon->was_quiesced) )
3529  return MHD_NO;
3530 #ifdef USE_ACCEPT4
3531  s = accept4 (fd,
3532  addr,
3533  &addrlen,
3536  sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0);
3537 #ifndef MHD_WINSOCK_SOCKETS
3538  sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0);
3539 #else /* MHD_WINSOCK_SOCKETS */
3540  sk_spipe_supprs = true; /* Nothing to suppress on W32 */
3541 #endif /* MHD_WINSOCK_SOCKETS */
3542 #else /* ! USE_ACCEPT4 */
3543  s = accept (fd,
3544  addr,
3545  &addrlen);
3546  sk_nonbl = false;
3547 #ifndef MHD_WINSOCK_SOCKETS
3548  sk_spipe_supprs = false;
3549 #else /* MHD_WINSOCK_SOCKETS */
3550  sk_spipe_supprs = true; /* Nothing to suppress on W32 */
3551 #endif /* MHD_WINSOCK_SOCKETS */
3552 #endif /* ! USE_ACCEPT4 */
3553  if ( (MHD_INVALID_SOCKET == s) ||
3554  (addrlen <= 0) )
3555  {
3556  const int err = MHD_socket_get_error_ ();
3557 
3558  /* This could be a common occurrence with multiple worker threads */
3559  if (MHD_SCKT_ERR_IS_ (err,
3561  return MHD_NO; /* can happen during shutdown */
3563  return MHD_NO; /* do not print error if client just disconnected early */
3564 #ifdef HAVE_MESSAGES
3565  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
3566  MHD_DLOG (daemon,
3567  _ ("Error accepting connection: %s\n"),
3568  MHD_socket_strerr_ (err));
3569 #endif
3570  if (MHD_INVALID_SOCKET != s)
3571  {
3573  }
3574  if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
3575  {
3576  /* system/process out of resources */
3577  if (0 == daemon->connections)
3578  {
3579 #ifdef HAVE_MESSAGES
3580  /* Not setting 'at_limit' flag, as there is no way it
3581  would ever be cleared. Instead trying to produce
3582  bit fat ugly warning. */
3583  MHD_DLOG (daemon,
3584  _ (
3585  "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n"));
3586 #endif
3587  }
3588  else
3589  {
3590 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3592 #endif
3593  daemon->at_limit = true;
3594 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3596 #endif
3597 #ifdef HAVE_MESSAGES
3598  MHD_DLOG (daemon,
3599  _ (
3600  "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3601  (unsigned int) daemon->connections);
3602 #endif
3603  }
3604  }
3605  return MHD_NO;
3606  }
3607 #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
3608  if (! MHD_socket_nonblocking_ (s))
3609  {
3610 #ifdef HAVE_MESSAGES
3611  MHD_DLOG (daemon,
3612  _ (
3613  "Failed to set nonblocking mode on incoming connection socket: %s\n"),
3615 #endif
3616  }
3617  else
3618  sk_nonbl = true;
3619 #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
3620 #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
3621  if (! MHD_socket_noninheritable_ (s))
3622  {
3623 #ifdef HAVE_MESSAGES
3624  MHD_DLOG (daemon,
3625  _ (
3626  "Failed to set noninheritable mode on incoming connection socket.\n"));
3627 #endif
3628  }
3629 #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
3630 #if defined(MHD_socket_nosignal_)
3631  if (! sk_spipe_supprs && ! MHD_socket_nosignal_ (s))
3632  {
3633 #ifdef HAVE_MESSAGES
3634  MHD_DLOG (daemon,
3635  _ (
3636  "Failed to suppress SIGPIPE on incoming connection socket: %s\n"),
3638 #else /* ! HAVE_MESSAGES */
3639  (void) 0; /* Mute compiler warning */
3640 #endif /* ! HAVE_MESSAGES */
3641 #ifndef MSG_NOSIGNAL
3642  /* Application expects that SIGPIPE will be suppressed,
3643  * but suppression failed and SIGPIPE cannot be suppressed with send(). */
3644  if (! daemon->sigpipe_blocked)
3645  {
3646  MHD_socket_close_ (s);
3647  return MHD_NO;
3648  }
3649 #endif /* MSG_NOSIGNAL */
3650  }
3651  else
3652  sk_spipe_supprs = true;
3653 #endif /* MHD_socket_nosignal_ */
3654 #ifdef HAVE_MESSAGES
3655 #if _MHD_DEBUG_CONNECT
3656  MHD_DLOG (daemon,
3657  _ ("Accepted connection on socket %d\n"),
3658  s);
3659 #endif
3660 #endif
3661  (void) internal_add_connection (daemon,
3662  s,
3663  addr,
3664  addrlen,
3665  false,
3666  sk_nonbl,
3667  sk_spipe_supprs,
3668  daemon->listen_is_unix);
3669  return MHD_YES;
3670 }
3671 
3672 
3682 static void
3684 {
3685  struct MHD_Connection *pos;
3686 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3688  MHD_thread_ID_match_current_ (daemon->pid) );
3689 
3691 #endif
3692  while (NULL != (pos = daemon->cleanup_tail))
3693  {
3696  pos);
3697 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3699  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3700  (! pos->thread_joined) &&
3701  (! MHD_join_thread_ (pos->pid.handle)) )
3702  MHD_PANIC (_ ("Failed to join a thread.\n"));
3703 #endif
3704 #ifdef UPGRADE_SUPPORT
3705  cleanup_upgraded_connection (pos);
3706 #endif /* UPGRADE_SUPPORT */
3707  MHD_pool_destroy (pos->pool);
3708 #ifdef HTTPS_SUPPORT
3709  if (NULL != pos->tls_session)
3710  gnutls_deinit (pos->tls_session);
3711 #endif /* HTTPS_SUPPORT */
3712 
3713  /* clean up the connection */
3714  if (NULL != daemon->notify_connection)
3716  pos,
3717  &pos->socket_context,
3720  pos->addr,
3721  pos->addr_len);
3722 #ifdef EPOLL_SUPPORT
3723  if (0 != (daemon->options & MHD_USE_EPOLL))
3724  {
3725  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3726  {
3727  EDLL_remove (daemon->eready_head,
3728  daemon->eready_tail,
3729  pos);
3730  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3731  }
3732  if ( (-1 != daemon->epoll_fd) &&
3733  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
3734  {
3735  /* epoll documentation suggests that closing a FD
3736  automatically removes it from the epoll set; however,
3737  this is not true as if we fail to do manually remove it,
3738  we are still seeing an event for this fd in epoll,
3739  causing grief (use-after-free...) --- at least on my
3740  system. */
3741  if (0 != epoll_ctl (daemon->epoll_fd,
3742  EPOLL_CTL_DEL,
3743  pos->socket_fd,
3744  NULL))
3745  MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
3746  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
3747  }
3748  }
3749 #endif
3750  if (NULL != pos->response)
3751  {
3753  pos->response = NULL;
3754  }
3755  if (MHD_INVALID_SOCKET != pos->socket_fd)
3757  if (NULL != pos->addr)
3758  free (pos->addr);
3759  free (pos);
3760 
3761 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3763 #endif
3764  daemon->connections--;
3765  daemon->at_limit = false;
3766  }
3767 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3769 #endif
3770 }
3771 
3772 
3793 enum MHD_Result
3795  MHD_UNSIGNED_LONG_LONG *timeout)
3796 {
3797  time_t earliest_deadline;
3798  time_t now;
3799  struct MHD_Connection *pos;
3800  bool have_timeout;
3801 
3802 #ifdef MHD_USE_THREADS
3804  MHD_thread_ID_match_current_ (daemon->pid) );
3805 #endif /* MHD_USE_THREADS */
3806 
3808  {
3809 #ifdef HAVE_MESSAGES
3810  MHD_DLOG (daemon,
3811  _ ("Illegal call to MHD_get_timeout.\n"));
3812 #endif
3813  return MHD_NO;
3814  }
3816  {
3817  /* Some data already waiting to be processed. */
3818  *timeout = 0;
3819  return MHD_YES;
3820  }
3821 #ifdef EPOLL_SUPPORT
3822  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
3823  ((NULL != daemon->eready_head)
3824 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3825  || (NULL != daemon->eready_urh_head)
3826 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
3827  ) )
3828  {
3829  /* Some connection(s) already have some data pending. */
3830  *timeout = 0;
3831  return MHD_YES;
3832  }
3833 #endif /* EPOLL_SUPPORT */
3834 
3835  have_timeout = false;
3836  earliest_deadline = 0; /* avoid compiler warnings */
3837  for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
3838  {
3839  if (0 != pos->connection_timeout)
3840  {
3841  if ( (! have_timeout) ||
3842  (earliest_deadline - pos->last_activity > pos->connection_timeout) )
3843  earliest_deadline = pos->last_activity + pos->connection_timeout;
3844  have_timeout = true;
3845  }
3846  }
3847  /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
3848  pos = daemon->normal_timeout_tail;
3849  if ( (NULL != pos) &&
3850  (0 != pos->connection_timeout) )
3851  {
3852  if ( (! have_timeout) ||
3853  (earliest_deadline - pos->connection_timeout > pos->last_activity) )
3854  earliest_deadline = pos->last_activity + pos->connection_timeout;
3855  have_timeout = true;
3856  }
3857 
3858  if (! have_timeout)
3859  return MHD_NO;
3860  now = MHD_monotonic_sec_counter ();
3861  if (earliest_deadline < now)
3862  *timeout = 0;
3863  else
3864  {
3865  const time_t second_left = earliest_deadline - now;
3866 
3867  if (((unsigned long long) second_left) > ULLONG_MAX / 1000)
3868  *timeout = ULLONG_MAX;
3869  else
3870  *timeout = 1000LLU * (unsigned long long) second_left;
3871  }
3872  return MHD_YES;
3873 }
3874 
3875 
3886 static int
3888  int32_t max_timeout)
3889 {
3890  MHD_UNSIGNED_LONG_LONG ulltimeout;
3891  if (0 == max_timeout)
3892  return 0;
3893 
3894  if (MHD_NO == MHD_get_timeout (daemon, &ulltimeout))
3895  return (INT_MAX < max_timeout) ? INT_MAX : (int) max_timeout;
3896 
3897  if ( (0 > max_timeout) ||
3898  ((uint32_t) max_timeout > ulltimeout) )
3899  return (INT_MAX < ulltimeout) ? INT_MAX : (int) ulltimeout;
3900 
3901  return (INT_MAX < max_timeout) ? INT_MAX : (int) max_timeout;
3902 }
3903 
3904 
3915 static enum MHD_Result
3917  const fd_set *read_fd_set,
3918  const fd_set *write_fd_set,
3919  const fd_set *except_fd_set)
3920 {
3921  MHD_socket ds;
3922  struct MHD_Connection *pos;
3923  struct MHD_Connection *prev;
3924 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3925  struct MHD_UpgradeResponseHandle *urh;
3926  struct MHD_UpgradeResponseHandle *urhn;
3927 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3928  /* Reset. New value will be set when connections are processed. */
3929  /* Note: no-op for thread-per-connection as it is always false in that mode. */
3930  daemon->data_already_pending = false;
3931 
3932  /* Clear ITC to avoid spinning select */
3933  /* Do it before any other processing so new signals
3934  will trigger select again and will be processed */
3935  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
3936  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
3937  read_fd_set)) )
3938  MHD_itc_clear_ (daemon->itc);
3939 
3940  /* Process externally added connection if any */
3941  if (daemon->have_new)
3943 
3944  /* select connection thread handling type */
3945  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
3946  (! daemon->was_quiesced) &&
3947  (FD_ISSET (ds,
3948  read_fd_set)) )
3949  (void) MHD_accept_connection (daemon);
3950 
3951  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3952  {
3953  /* do not have a thread per connection, process all connections now */
3954  prev = daemon->connections_tail;
3955  while (NULL != (pos = prev))
3956  {
3957  prev = pos->prev;
3958  ds = pos->socket_fd;
3959  if (MHD_INVALID_SOCKET == ds)
3960  continue;
3961  call_handlers (pos,
3962  FD_ISSET (ds,
3963  read_fd_set),
3964  FD_ISSET (ds,
3965  write_fd_set),
3966  FD_ISSET (ds,
3967  except_fd_set));
3968  }
3969  }
3970 
3971 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3972  /* handle upgraded HTTPS connections */
3973  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3974  {
3975  urhn = urh->prev;
3976  /* update urh state based on select() output */
3977  urh_from_fdset (urh,
3978  read_fd_set,
3979  write_fd_set,
3980  except_fd_set);
3981  /* call generic forwarding function for passing data */
3982  process_urh (urh);
3983  /* Finished forwarding? */
3984  if ( (0 == urh->in_buffer_size) &&
3985  (0 == urh->out_buffer_size) &&
3986  (0 == urh->in_buffer_used) &&
3987  (0 == urh->out_buffer_used) )
3988  {
3989  MHD_connection_finish_forward_ (urh->connection);
3990  urh->clean_ready = true;
3991  /* Resuming will move connection to cleanup list. */
3992  MHD_resume_connection (urh->connection);
3993  }
3994  }
3995 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3996  MHD_cleanup_connections (daemon);
3997  return MHD_YES;
3998 }
3999 
4000 
4023 enum MHD_Result
4024 MHD_run_from_select (struct MHD_Daemon *daemon,
4025  const fd_set *read_fd_set,
4026  const fd_set *write_fd_set,
4027  const fd_set *except_fd_set)
4028 {
4029  fd_set es;
4030  if (0 != (daemon->options
4032  return MHD_NO;
4033  if ((NULL == read_fd_set) || (NULL == write_fd_set))
4034  return MHD_NO;
4035  if (NULL == except_fd_set)
4036  { /* Workaround to maintain backward compatibility. */
4037 #ifdef HAVE_MESSAGES
4038  MHD_DLOG (daemon,
4039  _ ("MHD_run_from_select() called with except_fd_set "
4040  "set to NULL. Such behavior is deprecated.\n"));
4041 #endif
4042  FD_ZERO (&es);
4043  except_fd_set = &es;
4044  }
4045  if (0 != (daemon->options & MHD_USE_EPOLL))
4046  {
4047 #ifdef EPOLL_SUPPORT
4048  enum MHD_Result ret = MHD_epoll (daemon,
4049  0);
4050 
4051  MHD_cleanup_connections (daemon);
4052  return ret;
4053 #else /* ! EPOLL_SUPPORT */
4054  return MHD_NO;
4055 #endif /* ! EPOLL_SUPPORT */
4056  }
4057 
4058  /* Resuming external connections when using an extern mainloop */
4059  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
4061 
4062  return internal_run_from_select (daemon,
4063  read_fd_set,
4064  write_fd_set,
4065  except_fd_set);
4066 }
4067 
4068 
4079 static enum MHD_Result
4080 MHD_select (struct MHD_Daemon *daemon,
4081  int32_t millisec)
4082 {
4083  int num_ready;
4084  fd_set rs;
4085  fd_set ws;
4086  fd_set es;
4087  MHD_socket maxsock;
4088  struct timeval timeout;
4089  struct timeval *tv;
4090  int err_state;
4091  MHD_socket ls;
4092 
4093  timeout.tv_sec = 0;
4094  timeout.tv_usec = 0;
4095  if (daemon->shutdown)
4096  return MHD_NO;
4097  FD_ZERO (&rs);
4098  FD_ZERO (&ws);
4099  FD_ZERO (&es);
4100  maxsock = MHD_INVALID_SOCKET;
4101  err_state = MHD_NO;
4102  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
4103  (MHD_NO != resume_suspended_connections (daemon)) &&
4104  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
4105  millisec = 0;
4106 
4107  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4108  {
4109  /* single-threaded, go over everything */
4110  if (MHD_NO ==
4111  internal_get_fdset2 (daemon,
4112  &rs,
4113  &ws,
4114  &es,
4115  &maxsock,
4116  FD_SETSIZE))
4117  {
4118 #ifdef HAVE_MESSAGES
4119  MHD_DLOG (daemon,
4120  _ ("Could not obtain daemon fdsets.\n"));
4121 #endif
4122  err_state = MHD_YES;
4123  }
4124  }
4125  else
4126  {
4127  /* accept only, have one thread per connection */
4128  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4129  (! daemon->was_quiesced) &&
4130  (! MHD_add_to_fd_set_ (ls,
4131  &rs,
4132  &maxsock,
4133  FD_SETSIZE)) )
4134  {
4135 #ifdef HAVE_MESSAGES
4136  MHD_DLOG (daemon,
4137  _ ("Could not add listen socket to fdset.\n"));
4138 #endif
4139  return MHD_NO;
4140  }
4141  }
4142  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
4143  (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
4144  &rs,
4145  &maxsock,
4146  FD_SETSIZE)) )
4147  {
4148 #if defined(MHD_WINSOCK_SOCKETS)
4149  /* fdset limit reached, new connections
4150  cannot be handled. Remove listen socket FD
4151  from fdset and retry to add ITC FD. */
4152  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4153  (! daemon->was_quiesced) )
4154  {
4155  FD_CLR (ls,
4156  &rs);
4157  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
4158  &rs,
4159  &maxsock,
4160  FD_SETSIZE))
4161  {
4162 #endif /* MHD_WINSOCK_SOCKETS */
4163 #ifdef HAVE_MESSAGES
4164  MHD_DLOG (daemon,
4165  _ (
4166  "Could not add control inter-thread communication channel FD to fdset.\n"));
4167 #endif
4168  err_state = MHD_YES;
4169 #if defined(MHD_WINSOCK_SOCKETS)
4170  }
4171 }
4172 
4173 
4174 #endif /* MHD_WINSOCK_SOCKETS */
4175  }
4176  /* Stop listening if we are at the configured connection limit */
4177  /* If we're at the connection limit, no point in really
4178  accepting new connections; however, make sure we do not miss
4179  the shutdown OR the termination of an existing connection; so
4180  only do this optimization if we have a signaling ITC in
4181  place. */
4182  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4183  (MHD_ITC_IS_VALID_ (daemon->itc)) &&
4184  ( (daemon->connections == daemon->connection_limit) ||
4185  (daemon->at_limit) ) )
4186  {
4187  FD_CLR (ls,
4188  &rs);
4189  }
4190 
4191  if (MHD_NO != err_state)
4192  millisec = 0;
4193  tv = NULL;
4194  if (0 == millisec)
4195  {
4196  timeout.tv_usec = 0;
4197  timeout.tv_sec = 0;
4198  tv = &timeout;
4199  }
4200  else
4201  {
4202  MHD_UNSIGNED_LONG_LONG ltimeout;
4203 
4204  if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4205  (MHD_NO != MHD_get_timeout (daemon, &ltimeout)) )
4206  {
4207  tv = &timeout; /* have timeout value */
4208  if ( (0 < millisec) &&
4209  (ltimeout > (MHD_UNSIGNED_LONG_LONG) millisec) )
4210  ltimeout = (MHD_UNSIGNED_LONG_LONG) millisec;
4211  }
4212  else if (0 < millisec)
4213  {
4214  tv = &timeout; /* have timeout value */
4215  ltimeout = (MHD_UNSIGNED_LONG_LONG) millisec;
4216  }
4217 
4218  if (NULL != tv)
4219  { /* have timeout value */
4220  if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
4221  {
4222  timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
4223  timeout.tv_usec = 0;
4224  }
4225  else
4226  {
4227  timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
4228  timeout.tv_usec = (ltimeout % 1000) * 1000;
4229  }
4230  }
4231  }
4232  num_ready = MHD_SYS_select_ (maxsock + 1,
4233  &rs,
4234  &ws,
4235  &es,
4236  tv);
4237  if (daemon->shutdown)
4238  return MHD_NO;
4239  if (num_ready < 0)
4240  {
4241  const int err = MHD_socket_get_error_ ();
4242  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4243  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
4244 #ifdef HAVE_MESSAGES
4245  MHD_DLOG (daemon,
4246  _ ("select failed: %s\n"),
4247  MHD_socket_strerr_ (err));
4248 #endif
4249  return MHD_NO;
4250  }
4251  if (MHD_NO != internal_run_from_select (daemon,
4252  &rs,
4253  &ws,
4254  &es))
4255  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
4256  return MHD_NO;
4257 }
4258 
4259 
4260 #ifdef HAVE_POLL
4271 static enum MHD_Result
4272 MHD_poll_all (struct MHD_Daemon *daemon,
4273  int32_t millisec)
4274 {
4275  unsigned int num_connections;
4276  struct MHD_Connection *pos;
4277  struct MHD_Connection *prev;
4278 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4279  struct MHD_UpgradeResponseHandle *urh;
4280  struct MHD_UpgradeResponseHandle *urhn;
4281 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4282 
4283  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
4284  (MHD_NO != resume_suspended_connections (daemon)) )
4285  millisec = 0;
4286 
4287  /* count number of connections and thus determine poll set size */
4288  num_connections = 0;
4289  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
4290  num_connections++;
4291 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4292  for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
4293  num_connections += 2;
4294 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4295  {
4296  unsigned int i;
4297  int timeout;
4298  unsigned int poll_server;
4299  int poll_listen;
4300  int poll_itc_idx;
4301  struct pollfd *p;
4302  MHD_socket ls;
4303 
4304  p = MHD_calloc_ ((2 + (size_t) num_connections),
4305  sizeof (struct pollfd));
4306  if (NULL == p)
4307  {
4308 #ifdef HAVE_MESSAGES
4309  MHD_DLOG (daemon,
4310  _ ("Error allocating memory: %s\n"),
4311  MHD_strerror_ (errno));
4312 #endif
4313  return MHD_NO;
4314  }
4315  poll_server = 0;
4316  poll_listen = -1;
4317  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4318  (! daemon->was_quiesced) &&
4319  (daemon->connections < daemon->connection_limit) &&
4320  (! daemon->at_limit) )
4321  {
4322  /* only listen if we are not at the connection limit */
4323  p[poll_server].fd = ls;
4324  p[poll_server].events = POLLIN;
4325  p[poll_server].revents = 0;
4326  poll_listen = (int) poll_server;
4327  poll_server++;
4328  }
4329  poll_itc_idx = -1;
4330  if (MHD_ITC_IS_VALID_ (daemon->itc))
4331  {
4332  p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
4333  p[poll_server].events = POLLIN;
4334  p[poll_server].revents = 0;
4335  poll_itc_idx = (int) poll_server;
4336  poll_server++;
4337  }
4338 
4339  timeout = get_timeout_millisec_ (daemon, millisec);
4340 
4341  i = 0;
4342  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
4343  {
4344  p[poll_server + i].fd = pos->socket_fd;
4345  switch (pos->event_loop_info)
4346  {
4348  p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
4349  break;
4351  p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
4352  break;
4354  p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
4355  break;
4357  timeout = 0; /* clean up "pos" immediately */
4358  break;
4359  }
4360  i++;
4361  }
4362 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4363  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
4364  {
4365  urh_to_pollfd (urh, &(p[poll_server + i]));
4366  i += 2;
4367  }
4368 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4369  if (0 == poll_server + num_connections)
4370  {
4371  free (p);
4372  return MHD_YES;
4373  }
4374  if (MHD_sys_poll_ (p,
4375  poll_server + num_connections,
4376  timeout) < 0)
4377  {
4378  const int err = MHD_socket_get_error_ ();
4379  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4380  {
4381  free (p);
4382  return MHD_YES;
4383  }
4384 #ifdef HAVE_MESSAGES
4385  MHD_DLOG (daemon,
4386  _ ("poll failed: %s\n"),
4387  MHD_socket_strerr_ (err));
4388 #endif
4389  free (p);
4390  return MHD_NO;
4391  }
4392 
4393  /* handle ITC FD */
4394  /* do it before any other processing so
4395  new signals will be processed in next loop */
4396  if ( (-1 != poll_itc_idx) &&
4397  (0 != (p[poll_itc_idx].revents & POLLIN)) )
4398  MHD_itc_clear_ (daemon->itc);
4399 
4400  /* handle shutdown */
4401  if (daemon->shutdown)
4402  {
4403  free (p);
4404  return MHD_NO;
4405  }
4406 
4407  /* Process externally added connection if any */
4408  if (daemon->have_new)
4410 
4411  /* handle 'listen' FD */
4412  if ( (-1 != poll_listen) &&
4413  (0 != (p[poll_listen].revents & POLLIN)) )
4414  (void) MHD_accept_connection (daemon);
4415 
4416  /* Reset. New value will be set when connections are processed. */
4417  daemon->data_already_pending = false;
4418 
4419  i = 0;
4420  prev = daemon->connections_tail;
4421  while (NULL != (pos = prev))
4422  {
4423  prev = pos->prev;
4424  /* first, sanity checks */
4425  if (i >= num_connections)
4426  break; /* connection list changed somehow, retry later ... */
4427  if (p[poll_server + i].fd != pos->socket_fd)
4428  continue; /* fd mismatch, something else happened, retry later ... */
4429  call_handlers (pos,
4430  0 != (p[poll_server + i].revents & POLLIN),
4431  0 != (p[poll_server + i].revents & POLLOUT),
4432  0 != (p[poll_server + i].revents
4433  & MHD_POLL_REVENTS_ERR_DISC));
4434  i++;
4435  }
4436 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4437  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
4438  {
4439  if (i >= num_connections)
4440  break; /* connection list changed somehow, retry later ... */
4441 
4442  /* Get next connection here as connection can be removed
4443  * from 'daemon->urh_head' list. */
4444  urhn = urh->prev;
4445  /* Check for fd mismatch. FIXME: required for safety? */
4446  if ((p[poll_server + i].fd != urh->connection->socket_fd) ||
4447  (p[poll_server + i + 1].fd != urh->mhd.socket))
4448  break;
4449  urh_from_pollfd (urh,
4450  &p[poll_server + i]);
4451  i += 2;
4452  process_urh (urh);
4453  /* Finished forwarding? */
4454  if ( (0 == urh->in_buffer_size) &&
4455  (0 == urh->out_buffer_size) &&
4456  (0 == urh->in_buffer_used) &&
4457  (0 == urh->out_buffer_used) )
4458  {
4459  /* MHD_connection_finish_forward_() will remove connection from
4460  * 'daemon->urh_head' list. */
4461  MHD_connection_finish_forward_ (urh->connection);
4462  urh->clean_ready = true;
4463  /* If 'urh->was_closed' already was set to true, connection will be
4464  * moved immediately to cleanup list. Otherwise connection
4465  * will stay in suspended list until 'urh' will be marked
4466  * with 'was_closed' by application. */
4467  MHD_resume_connection (urh->connection);
4468  }
4469  }
4470 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4471 
4472  free (p);
4473  }
4474  return MHD_YES;
4475 }
4476 
4477 
4485 static enum MHD_Result
4486 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
4487  int may_block)
4488 {
4489  struct pollfd p[2];
4490  int timeout;
4491  unsigned int poll_count;
4492  int poll_listen;
4493  int poll_itc_idx;
4494  MHD_socket ls;
4495 
4496  memset (&p,
4497  0,
4498  sizeof (p));
4499  poll_count = 0;
4500  poll_listen = -1;
4501  poll_itc_idx = -1;
4502  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4503  (! daemon->was_quiesced) )
4504 
4505  {
4506  p[poll_count].fd = ls;
4507  p[poll_count].events = POLLIN;
4508  p[poll_count].revents = 0;
4509  poll_listen = poll_count;
4510  poll_count++;
4511  }
4512  if (MHD_ITC_IS_VALID_ (daemon->itc))
4513  {
4514  p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
4515  p[poll_count].events = POLLIN;
4516  p[poll_count].revents = 0;
4517  poll_itc_idx = poll_count;
4518  poll_count++;
4519  }
4520 
4521  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
4522  (void) resume_suspended_connections (daemon);
4523 
4524  if (MHD_NO == may_block)
4525  timeout = 0;
4526  else
4527  timeout = -1;
4528  if (0 == poll_count)
4529  return MHD_YES;
4530  if (MHD_sys_poll_ (p,
4531  poll_count,
4532  timeout) < 0)
4533  {
4534  const int err = MHD_socket_get_error_ ();
4535 
4536  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4537  return MHD_YES;
4538 #ifdef HAVE_MESSAGES
4539  MHD_DLOG (daemon,
4540  _ ("poll failed: %s\n"),
4541  MHD_socket_strerr_ (err));
4542 #endif
4543  return MHD_NO;
4544  }
4545  if ( (-1 != poll_itc_idx) &&
4546  (0 != (p[poll_itc_idx].revents & POLLIN)) )
4547  MHD_itc_clear_ (daemon->itc);
4548 
4549  /* handle shutdown */
4550  if (daemon->shutdown)
4551  return MHD_NO;
4552 
4553  /* Process externally added connection if any */
4554  if (daemon->have_new)
4556 
4557  if ( (-1 != poll_listen) &&
4558  (0 != (p[poll_listen].revents & POLLIN)) )
4559  (void) MHD_accept_connection (daemon);
4560  return MHD_YES;
4561 }
4562 
4563 
4564 #endif
4565 
4566 
4574 static enum MHD_Result
4575 MHD_poll (struct MHD_Daemon *daemon,
4576  int may_block)
4577 {
4578 #ifdef HAVE_POLL
4579  if (daemon->shutdown)
4580  return MHD_NO;
4581  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4582  return MHD_poll_all (daemon,
4583  may_block ? -1 : 0);
4584  return MHD_poll_listen_socket (daemon,
4585  may_block);
4586 #else
4587  (void) daemon;
4588  (void) may_block;
4589  return MHD_NO;
4590 #endif
4591 }
4592 
4593 
4594 #ifdef EPOLL_SUPPORT
4595 
4604 #define MAX_EVENTS 128
4605 
4606 
4607 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4608 
4616 static bool
4617 is_urh_ready (struct MHD_UpgradeResponseHandle *const urh)
4618 {
4619  const struct MHD_Connection *const connection = urh->connection;
4620 
4621  if ( (0 == urh->in_buffer_size) &&
4622  (0 == urh->out_buffer_size) &&
4623  (0 == urh->in_buffer_used) &&
4624  (0 == urh->out_buffer_used) )
4625  return false;
4626  if (connection->daemon->shutdown)
4627  return true;
4628  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
4629  (connection->tls_read_ready) ) &&
4630  (urh->in_buffer_used < urh->in_buffer_size) )
4631  return true;
4632  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
4633  (urh->out_buffer_used < urh->out_buffer_size) )
4634  return true;
4635  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
4636  (urh->out_buffer_used > 0) )
4637  return true;
4638  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
4639  (urh->in_buffer_used > 0) )
4640  return true;
4641  return false;
4642 }
4643 
4644 
4653 static enum MHD_Result
4654 run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4655 {
4656  struct epoll_event events[MAX_EVENTS];
4657  int num_events;
4658  struct MHD_UpgradeResponseHandle *pos;
4659  struct MHD_UpgradeResponseHandle *prev;
4660 
4661 #ifdef MHD_USE_THREADS
4662  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
4663  MHD_thread_ID_match_current_ (daemon->pid) );
4664 #endif /* MHD_USE_THREADS */
4665 
4666  num_events = MAX_EVENTS;
4667  while (0 != num_events)
4668  {
4669  unsigned int i;
4670  /* update event masks */
4671  num_events = epoll_wait (daemon->epoll_upgrade_fd,
4672  events,
4673  MAX_EVENTS,
4674  0);
4675  if (-1 == num_events)
4676  {
4677  const int err = MHD_socket_get_error_ ();
4678 
4679  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4680  return MHD_YES;
4681 #ifdef HAVE_MESSAGES
4682  MHD_DLOG (daemon,
4683  _ ("Call to epoll_wait failed: %s\n"),
4684  MHD_socket_strerr_ (err));
4685 #endif
4686  return MHD_NO;
4687  }
4688  for (i = 0; i < (unsigned int) num_events; i++)
4689  {
4690  struct UpgradeEpollHandle *const ueh = events[i].data.ptr;
4691  struct MHD_UpgradeResponseHandle *const urh = ueh->urh;
4692  bool new_err_state = false;
4693 
4694  if (urh->clean_ready)
4695  continue;
4696 
4697  /* Update ueh state based on what is ready according to epoll() */
4698  if (0 != (events[i].events & EPOLLIN))
4699  {
4700  ueh->celi |= MHD_EPOLL_STATE_READ_READY;
4701  }
4702  if (0 != (events[i].events & EPOLLOUT))
4703  {
4704  ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
4705  }
4706  if (0 != (events[i].events & EPOLLHUP))
4707  {
4709  }
4710 
4711  if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
4712  (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4713  {
4714  /* Process new error state only one time and avoid continuously
4715  * marking this connection as 'ready'. */
4716  ueh->celi |= MHD_EPOLL_STATE_ERROR;
4717  new_err_state = true;
4718  }
4719  if (! urh->in_eready_list)
4720  {
4721  if (new_err_state ||
4722  is_urh_ready (urh))
4723  {
4724  EDLL_insert (daemon->eready_urh_head,
4725  daemon->eready_urh_tail,
4726  urh);
4727  urh->in_eready_list = true;
4728  }
4729  }
4730  }
4731  }
4732  prev = daemon->eready_urh_tail;
4733  while (NULL != (pos = prev))
4734  {
4735  prev = pos->prevE;
4736  process_urh (pos);
4737  if (! is_urh_ready (pos))
4738  {
4739  EDLL_remove (daemon->eready_urh_head,
4740  daemon->eready_urh_tail,
4741  pos);
4742  pos->in_eready_list = false;
4743  }
4744  /* Finished forwarding? */
4745  if ( (0 == pos->in_buffer_size) &&
4746  (0 == pos->out_buffer_size) &&
4747  (0 == pos->in_buffer_used) &&
4748  (0 == pos->out_buffer_used) )
4749  {
4750  MHD_connection_finish_forward_ (pos->connection);
4751  pos->clean_ready = true;
4752  /* If 'pos->was_closed' already was set to true, connection
4753  * will be moved immediately to cleanup list. Otherwise
4754  * connection will stay in suspended list until 'pos' will
4755  * be marked with 'was_closed' by application. */
4756  MHD_resume_connection (pos->connection);
4757  }
4758  }
4759 
4760  return MHD_YES;
4761 }
4762 
4763 
4764 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4765 
4766 
4770 static const char *const epoll_itc_marker = "itc_marker";
4771 
4772 
4782 static enum MHD_Result
4783 MHD_epoll (struct MHD_Daemon *daemon,
4784  int32_t millisec)
4785 {
4786 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4787  static const char *const upgrade_marker = "upgrade_ptr";
4788 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4789  struct MHD_Connection *pos;
4790  struct MHD_Connection *prev;
4791  struct epoll_event events[MAX_EVENTS];
4792  struct epoll_event event;
4793  int timeout_ms;
4794  int num_events;
4795  unsigned int i;
4796  MHD_socket ls;
4797 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4798  bool run_upgraded = false;
4799 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4800  bool need_to_accept;
4801 
4802  if (-1 == daemon->epoll_fd)
4803  return MHD_NO; /* we're down! */
4804  if (daemon->shutdown)
4805  return MHD_NO;
4806  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4807  (! daemon->was_quiesced) &&
4808  (daemon->connections < daemon->connection_limit) &&
4809  (! daemon->listen_socket_in_epoll) &&
4810  (! daemon->at_limit) )
4811  {
4812  event.events = EPOLLIN;
4813  event.data.ptr = daemon;
4814  if (0 != epoll_ctl (daemon->epoll_fd,
4815  EPOLL_CTL_ADD,
4816  ls,
4817  &event))
4818  {
4819 #ifdef HAVE_MESSAGES
4820  MHD_DLOG (daemon,
4821  _ ("Call to epoll_ctl failed: %s\n"),
4823 #endif
4824  return MHD_NO;
4825  }
4826  daemon->listen_socket_in_epoll = true;
4827  }
4828  if ( (daemon->was_quiesced) &&
4829  (daemon->listen_socket_in_epoll) )
4830  {
4831  if ( (0 != epoll_ctl (daemon->epoll_fd,
4832  EPOLL_CTL_DEL,
4833  ls,
4834  NULL)) &&
4835  (ENOENT != errno) ) /* ENOENT can happen due to race with
4836  #MHD_quiesce_daemon() */
4837  MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
4838  daemon->listen_socket_in_epoll = false;
4839  }
4840 
4841 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4842  if ( ( (! daemon->upgrade_fd_in_epoll) &&
4843  (-1 != daemon->epoll_upgrade_fd) ) )
4844  {
4845  event.events = EPOLLIN | EPOLLOUT;
4846  event.data.ptr = (void *) upgrade_marker;
4847  if (0 != epoll_ctl (daemon->epoll_fd,
4848  EPOLL_CTL_ADD,
4849  daemon->epoll_upgrade_fd,
4850  &event))
4851  {
4852 #ifdef HAVE_MESSAGES
4853  MHD_DLOG (daemon,
4854  _ ("Call to epoll_ctl failed: %s\n"),
4856 #endif
4857  return MHD_NO;
4858  }
4859  daemon->upgrade_fd_in_epoll = true;
4860  }
4861 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4862  if ( (daemon->listen_socket_in_epoll) &&
4863  ( (daemon->connections == daemon->connection_limit) ||
4864  (daemon->at_limit) ||
4865  (daemon->was_quiesced) ) )
4866  {
4867  /* we're at the connection limit, disable listen socket
4868  for event loop for now */
4869  if (0 != epoll_ctl (daemon->epoll_fd,
4870  EPOLL_CTL_DEL,
4871  ls,
4872  NULL))
4873  MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
4874  daemon->listen_socket_in_epoll = false;
4875  }
4876 
4877  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
4878  (MHD_NO != resume_suspended_connections (daemon)) )
4879  millisec = 0;
4880 
4881  timeout_ms = get_timeout_millisec_ (daemon, millisec);
4882 
4883  /* Reset. New value will be set when connections are processed. */
4884  /* Note: Used mostly for uniformity here as same situation is
4885  * signaled in epoll mode by non-empty eready DLL. */
4886  daemon->data_already_pending = false;
4887 
4888  need_to_accept = false;
4889  /* drain 'epoll' event queue; need to iterate as we get at most
4890  MAX_EVENTS in one system call here; in practice this should
4891  pretty much mean only one round, but better an extra loop here
4892  than unfair behavior... */
4893  num_events = MAX_EVENTS;
4894  while (MAX_EVENTS == num_events)
4895  {
4896  /* update event masks */
4897  num_events = epoll_wait (daemon->epoll_fd,
4898  events,
4899  MAX_EVENTS,
4900  timeout_ms);
4901  if (-1 == num_events)
4902  {
4903  const int err = MHD_socket_get_error_ ();
4904  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4905  return MHD_YES;
4906 #ifdef HAVE_MESSAGES
4907  MHD_DLOG (daemon,
4908  _ ("Call to epoll_wait failed: %s\n"),
4909  MHD_socket_strerr_ (err));
4910 #endif
4911  return MHD_NO;
4912  }
4913  for (i = 0; i<(unsigned int) num_events; i++)
4914  {
4915  /* First, check for the values of `ptr` that would indicate
4916  that this event is not about a normal connection. */
4917  if (NULL == events[i].data.ptr)
4918  continue; /* shutdown signal! */
4919 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4920  if (upgrade_marker == events[i].data.ptr)
4921  {
4922  /* activity on an upgraded connection, we process
4923  those in a separate epoll() */
4924  run_upgraded = true;
4925  continue;
4926  }
4927 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4928  if (epoll_itc_marker == events[i].data.ptr)
4929  {
4930  /* It's OK to clear ITC here as all external
4931  conditions will be processed later. */
4932  MHD_itc_clear_ (daemon->itc);
4933  continue;
4934  }
4935  if (daemon == events[i].data.ptr)
4936  {
4937  /* Check for error conditions on listen socket. */
4938  /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
4939  if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4940  need_to_accept = true;
4941  continue;
4942  }
4943  /* this is an event relating to a 'normal' connection,
4944  remember the event and if appropriate mark the
4945  connection as 'eready'. */
4946  pos = events[i].data.ptr;
4947  /* normal processing: update read/write data */
4948  if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4949  {
4950  pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
4951  if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
4952  {
4953  EDLL_insert (daemon->eready_head,
4954  daemon->eready_tail,
4955  pos);
4956  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4957  }
4958  }
4959  else
4960  {
4961  if (0 != (events[i].events & EPOLLIN))
4962  {
4963  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
4964  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
4965  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
4966  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4967  {
4968  EDLL_insert (daemon->eready_head,
4969  daemon->eready_tail,
4970  pos);
4971  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4972  }
4973  }
4974  if (0 != (events[i].events & EPOLLOUT))
4975  {
4976  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
4977  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
4978  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4979  {
4980  EDLL_insert (daemon->eready_head,
4981  daemon->eready_tail,
4982  pos);
4983  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4984  }
4985  }
4986  }
4987  }
4988  }
4989 
4990  /* Process externally added connection if any */
4991  if (daemon->have_new)
4993 
4994  if (need_to_accept)
4995  {
4996  unsigned int series_length = 0;
4997 
4998  /* Run 'accept' until it fails or daemon at limit of connections.
4999  * Do not accept more then 10 connections at once. The rest will
5000  * be accepted on next turn (level trigger is used for listen
5001  * socket). */
5002  while ( (MHD_NO != MHD_accept_connection (daemon)) &&
5003  (series_length < 10) &&
5004  (daemon->connections < daemon->connection_limit) &&
5005  (! daemon->at_limit) )
5006  series_length++;
5007  }
5008 
5009  /* Handle timed-out connections; we need to do this here
5010  as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
5011  as the other event loops do. As timeouts do not get an explicit
5012  event, we need to find those connections that might have timed out
5013  here.
5014 
5015  Connections with custom timeouts must all be looked at, as we
5016  do not bother to sort that (presumably very short) list. */
5017  prev = daemon->manual_timeout_tail;
5018  while (NULL != (pos = prev))
5019  {
5020  prev = pos->prevX;
5022  }
5023  /* Connections with the default timeout are sorted by prepending
5024  them to the head of the list whenever we touch the connection;
5025  thus it suffices to iterate from the tail until the first
5026  connection is NOT timed out */
5027  prev = daemon->normal_timeout_tail;
5028  while (NULL != (pos = prev))
5029  {
5030  prev = pos->prevX;
5032  if (MHD_CONNECTION_CLOSED != pos->state)
5033  break; /* sorted by timeout, no need to visit the rest! */
5034  }
5035 
5036 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5037  if (run_upgraded || (NULL != daemon->eready_urh_head))
5038  run_epoll_for_upgrade (daemon);
5039 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5040 
5041  /* process events for connections */
5042  prev = daemon->eready_tail;
5043  while (NULL != (pos = prev))
5044  {
5045  prev = pos->prevE;
5046  call_handlers (pos,
5047  0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
5048  0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
5049  0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
5051  (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED
5053  {
5054  if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) &&
5055  (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ||
5057  (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) ||
5059  {
5060  EDLL_remove (daemon->eready_head,
5061  daemon->eready_tail,
5062  pos);
5063  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
5064  }
5065  }
5066  }
5067 
5068  return MHD_YES;
5069 }
5070 
5071 
5072 #endif
5073 
5074 
5095 enum MHD_Result
5096 MHD_run (struct MHD_Daemon *daemon)
5097 {
5098  if ( (daemon->shutdown) ||
5099  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
5100  return MHD_NO;
5101 
5102  (void) MHD_run_wait (daemon, 0);
5103  return MHD_YES;
5104 }
5105 
5106 
5136 MHD_run_wait (struct MHD_Daemon *daemon,
5137  int32_t millisec)
5138 {
5139  enum MHD_Result res;
5140  if ( (daemon->shutdown) ||
5141  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
5142  return MHD_NO;
5143 
5144  if (0 > millisec)
5145  millisec = -1;
5146  if (false)
5147  {
5148  (void) 0; /* Mute compiler warning */
5149  }
5150 #ifdef HAVE_POLL
5151  else if (0 != (daemon->options & MHD_USE_POLL))
5152  {
5153  res = MHD_poll_all (daemon, millisec);
5154  MHD_cleanup_connections (daemon);
5155  }
5156 #endif /* HAVE_POLL */
5157 #ifdef EPOLL_SUPPORT
5158  else if (0 != (daemon->options & MHD_USE_EPOLL))
5159  {
5160  res = MHD_epoll (daemon, millisec);
5161  MHD_cleanup_connections (daemon);
5162  }
5163 #endif
5164  else
5165  {
5166  res = MHD_select (daemon, millisec);
5167  /* MHD_select does MHD_cleanup_connections already */
5168  }
5169  return res;
5170 }
5171 
5172 
5181 static void
5183 {
5184  struct MHD_Daemon *daemon = pos->daemon;
5185 
5186 #ifdef MHD_USE_THREADS
5187  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
5188  MHD_thread_ID_match_current_ (daemon->pid) );
5189 #endif /* MHD_USE_THREADS */
5190 
5191  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
5192  {
5194  return; /* must let thread to do the rest */
5195  }
5196  MHD_connection_close_ (pos,
5198 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5200 #endif
5201  mhd_assert (! pos->suspended);
5202  mhd_assert (! pos->resuming);
5203  if (pos->connection_timeout == daemon->connection_timeout)
5205  daemon->normal_timeout_tail,
5206  pos);
5207  else
5209  daemon->manual_timeout_tail,
5210  pos);
5211  DLL_remove (daemon->connections_head,
5212  daemon->connections_tail,
5213  pos);
5214  DLL_insert (daemon->cleanup_head,
5215  daemon->cleanup_tail,
5216  pos);
5217  daemon->data_already_pending = true;
5218 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5220 #endif
5221 }
5222 
5223 
5224 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5232 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
5233 MHD_polling_thread (void *cls)
5234 {
5235  struct MHD_Daemon *daemon = cls;
5236 #ifdef HAVE_PTHREAD_SIGMASK
5237  sigset_t s_mask;
5238  int err;
5239 #endif /* HAVE_PTHREAD_SIGMASK */
5240 
5241  MHD_thread_init_ (&(daemon->pid));
5242 #ifdef HAVE_PTHREAD_SIGMASK
5243  if ((0 == sigemptyset (&s_mask)) &&
5244  (0 == sigaddset (&s_mask, SIGPIPE)))
5245  {
5246  err = pthread_sigmask (SIG_BLOCK, &s_mask, NULL);
5247  }
5248  else
5249  err = errno;
5250  if (0 == err)
5251  daemon->sigpipe_blocked = true;
5252 #ifdef HAVE_MESSAGES
5253  else
5254  MHD_DLOG (daemon,
5255  _ ("Failed to block SIGPIPE on daemon thread: %s\n"),
5256  MHD_strerror_ (errno));
5257 #endif /* HAVE_MESSAGES */
5258 #endif /* HAVE_PTHREAD_SIGMASK */
5259  while (! daemon->shutdown)
5260  {
5261  if (0 != (daemon->options & MHD_USE_POLL))
5262  MHD_poll (daemon, MHD_YES);
5263 #ifdef EPOLL_SUPPORT
5264  else if (0 != (daemon->options & MHD_USE_EPOLL))
5265  MHD_epoll (daemon, -1);
5266 #endif
5267  else
5268  MHD_select (daemon, -1);
5269  MHD_cleanup_connections (daemon);
5270  }
5271 
5272  /* Resume any pending for resume connections, join
5273  * all connection's threads (if any) and finally cleanup
5274  * everything. */
5275  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
5277  close_all_connections (daemon);
5278 
5279  return (MHD_THRD_RTRN_TYPE_) 0;
5280 }
5281 
5282 
5283 #endif
5284 
5285 
5297 static size_t
5298 unescape_wrapper (void *cls,
5299  struct MHD_Connection *connection,
5300  char *val)
5301 {
5302  (void) cls; /* Mute compiler warning. */
5303 
5304  (void) connection; /* Mute compiler warning. */
5305  return MHD_http_unescape (val);
5306 }
5307 
5308 
5329 struct MHD_Daemon *
5330 MHD_start_daemon (unsigned int flags,
5331  uint16_t port,
5333  void *apc_cls,
5335  void *dh_cls,
5336  ...)
5337 {
5338  struct MHD_Daemon *daemon;
5339  va_list ap;
5340 
5341  va_start (ap,
5342  dh_cls);
5343  daemon = MHD_start_daemon_va (flags,
5344  port,
5345  apc,
5346  apc_cls,
5347  dh,
5348  dh_cls,
5349  ap);
5350  va_end (ap);
5351  return daemon;
5352 }
5353 
5354 
5374 MHD_socket
5376 {
5377 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5378  unsigned int i;
5379 #endif
5380  MHD_socket ret;
5381 
5382  ret = daemon->listen_fd;
5383  if (MHD_INVALID_SOCKET == ret)
5384  return MHD_INVALID_SOCKET;
5385  if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
5386  (0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) )
5387  {
5388 #ifdef HAVE_MESSAGES
5389  MHD_DLOG (daemon,
5390  _ (
5391  "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC.\n"));
5392 #endif
5393  return MHD_INVALID_SOCKET;
5394  }
5395 
5396 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5397  if (NULL != daemon->worker_pool)
5398  for (i = 0; i < daemon->worker_pool_size; i++)
5399  {
5400  daemon->worker_pool[i].was_quiesced = true;
5401 #ifdef EPOLL_SUPPORT
5402  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5403  (-1 != daemon->worker_pool[i].epoll_fd) &&
5404  (daemon->worker_pool[i].listen_socket_in_epoll) )
5405  {
5406  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
5407  EPOLL_CTL_DEL,
5408  ret,
5409  NULL))
5410  MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
5411  daemon->worker_pool[i].listen_socket_in_epoll = false;
5412  }
5413  else
5414 #endif
5415  if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
5416  {
5417  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
5418  MHD_PANIC (_ (
5419  "Failed to signal quiesce via inter-thread communication channel.\n"));
5420  }
5421  }
5422 #endif
5423  daemon->was_quiesced = true;
5424 #ifdef EPOLL_SUPPORT
5425  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
5426  (-1 != daemon->epoll_fd) &&
5427  (daemon->listen_socket_in_epoll) )
5428  {
5429  if ( (0 != epoll_ctl (daemon->epoll_fd,
5430  EPOLL_CTL_DEL,
5431  ret,
5432  NULL)) &&
5433  (ENOENT != errno) ) /* ENOENT can happen due to race with
5434  #MHD_epoll() */
5435  MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
5436  daemon->listen_socket_in_epoll = false;
5437  }
5438 #endif
5439  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
5440  (! MHD_itc_activate_ (daemon->itc, "q")) )
5441  MHD_PANIC (_ (
5442  "failed to signal quiesce via inter-thread communication channel.\n"));
5443  return ret;
5444 }
5445 
5446 
5454 typedef void
5455 (*VfprintfFunctionPointerType)(void *cls,
5456  const char *format,
5457  va_list va);
5458 
5459 
5468 static enum MHD_Result
5469 parse_options_va (struct MHD_Daemon *daemon,
5470  const struct sockaddr **servaddr,
5471  va_list ap);
5472 
5473 
5482 static enum MHD_Result
5483 parse_options (struct MHD_Daemon *daemon,
5484  const struct sockaddr **servaddr,
5485  ...)
5486 {
5487  va_list ap;
5488  enum MHD_Result ret;
5489 
5490  va_start (ap, servaddr);
5491  ret = parse_options_va (daemon,
5492  servaddr,
5493  ap);
5494  va_end (ap);
5495  return ret;
5496 }
5497 
5498 
5507 static enum MHD_Result
5508 parse_options_va (struct MHD_Daemon *daemon,
5509  const struct sockaddr **servaddr,
5510  va_list ap)
5511 {
5512  enum MHD_OPTION opt;
5513  struct MHD_OptionItem *oa;
5514  unsigned int i;
5515  unsigned int uv;
5516 #ifdef HTTPS_SUPPORT
5517  enum MHD_Result ret;
5518  const char *pstr;
5519 #if GNUTLS_VERSION_MAJOR >= 3
5520  gnutls_certificate_retrieve_function2 *pgcrf;
5521 #endif
5522 #if GNUTLS_VERSION_NUMBER >= 0x030603
5523  gnutls_certificate_retrieve_function3 *pgcrf2;
5524 #endif
5525 #endif /* HTTPS_SUPPORT */
5526 
5527  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
5528  {
5529  /* Increase counter at start, so resulting value is number of
5530  * processed options, including any failed ones. */
5531  daemon->num_opts++;
5532  switch (opt)
5533  {
5535  daemon->pool_size = va_arg (ap,
5536  size_t);
5537  break;
5539  daemon->pool_increment = va_arg (ap,
5540  size_t);
5541  break;
5543  daemon->connection_limit = va_arg (ap,
5544  unsigned int);
5545  break;
5547  uv = va_arg (ap,
5548  unsigned int);
5549  daemon->connection_timeout = (time_t) uv;
5550  /* Next comparison could be always false on some platforms and whole branch will
5551  * be optimized out on those platforms. On others it will be compiled into real
5552  * check. */
5553  if ( ( (MHD_TYPE_IS_SIGNED_ (time_t)) &&
5554  (daemon->connection_timeout < 0) ) || /* Compiler may warn on some platforms, ignore warning. */
5555  (uv != (unsigned int) daemon->connection_timeout) )
5556  {
5557 #ifdef HAVE_MESSAGES
5558  MHD_DLOG (daemon,
5559  _ ("Warning: Too large timeout value, ignored.\n"));
5560 #endif
5561  daemon->connection_timeout = 0;
5562  }
5563  break;
5565  daemon->notify_completed = va_arg (ap,
5567  daemon->notify_completed_cls = va_arg (ap,
5568  void *);
5569  break;
5571  daemon->notify_connection = va_arg (ap,
5573  daemon->notify_connection_cls = va_arg (ap,
5574  void *);
5575  break;
5577  daemon->per_ip_connection_limit = va_arg (ap,
5578  unsigned int);
5579  break;
5580  case MHD_OPTION_SOCK_ADDR:
5581  *servaddr = va_arg (ap,
5582  const struct sockaddr *);
5583  break;
5585  daemon->uri_log_callback = va_arg (ap,
5586  LogCallback);
5587  daemon->uri_log_callback_cls = va_arg (ap,
5588  void *);
5589  break;
5591  daemon->insanity_level = (enum MHD_DisableSanityCheck)
5592  va_arg (ap,
5593  unsigned int);
5594  break;
5595 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5597  daemon->worker_pool_size = va_arg (ap,
5598  unsigned int);
5599  if (0 == daemon->worker_pool_size)
5600  {
5601 #ifdef HAVE_MESSAGES
5602  MHD_DLOG (daemon,
5603  _ (
5604  "Warning: Zero size, specified for thread pool size, is ignored. "
5605  "Thread pool is not used.\n"));
5606 #endif
5607  }
5608  else if (1 == daemon->worker_pool_size)
5609  {
5610 #ifdef HAVE_MESSAGES
5611  MHD_DLOG (daemon,
5612  _ (
5613  "Warning: \"1\", specified for thread pool size, is ignored. "
5614  "Thread pool is not used.\n"));
5615 #endif
5616  daemon->worker_pool_size = 0;
5617  }
5618 #if (0 == (UINT_MAX + 0)) || (UINT_MAX >= (SIZE_MAX / (64 * 1024)))
5619  /* Next comparison could be always false on some platforms and whole branch will
5620  * be optimized out on these platforms. On others it will be compiled into real
5621  * check. */
5622  else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct
5623  MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */
5624  {
5625 #ifdef HAVE_MESSAGES
5626  MHD_DLOG (daemon,
5627  _ ("Specified thread pool size (%u) too big.\n"),
5628  daemon->worker_pool_size);
5629 #endif
5630  return MHD_NO;
5631  }
5632 #endif /* (UINT_MAX >= (SIZE_MAX/(64*1024))) */
5633  else
5634  {
5635  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
5636  {
5637 #ifdef HAVE_MESSAGES
5638  MHD_DLOG (daemon,
5639  _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
5640  "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5641 #endif
5642  return MHD_NO;
5643  }
5644  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
5645  {
5646 #ifdef HAVE_MESSAGES
5647  MHD_DLOG (daemon,
5648  _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and "
5649  "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5650 #endif
5651  return MHD_NO;
5652  }
5653  }
5654  break;
5655 #endif
5656 #ifdef HTTPS_SUPPORT
5658  pstr = va_arg (ap,
5659  const char *);
5660  if (0 != (daemon->options & MHD_USE_TLS))
5661  daemon->https_mem_key = pstr;
5662 #ifdef HAVE_MESSAGES
5663  else
5664  MHD_DLOG (daemon,
5665  _ (
5666  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5667  opt);
5668 #endif
5669  break;
5671  pstr = va_arg (ap,
5672  const char *);
5673  if (0 != (daemon->options & MHD_USE_TLS))
5674  daemon->https_key_password = pstr;
5675 #ifdef HAVE_MESSAGES
5676  else
5677  MHD_DLOG (daemon,
5678  _ (
5679  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5680  opt);
5681 #endif
5682  break;
5684  pstr = va_arg (ap,
5685  const char *);
5686  if (0 != (daemon->options & MHD_USE_TLS))
5687  daemon->https_mem_cert = pstr;
5688 #ifdef HAVE_MESSAGES
5689  else
5690  MHD_DLOG (daemon,
5691  _ (
5692  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5693  opt);
5694 #endif
5695  break;
5697  pstr = va_arg (ap,
5698  const char *);
5699  if (0 != (daemon->options & MHD_USE_TLS))
5700  daemon->https_mem_trust = pstr;
5701 #ifdef HAVE_MESSAGES
5702  else
5703  MHD_DLOG (daemon,
5704  _ (
5705  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5706  opt);
5707 #endif
5708  break;
5710  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5711  int);
5712  break;
5714  pstr = va_arg (ap,
5715  const char *);
5716  if (0 != (daemon->options & MHD_USE_TLS))
5717  {
5718  gnutls_datum_t dhpar;
5719  size_t pstr_len;
5720 
5721  if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5722  {
5723 #ifdef HAVE_MESSAGES
5724  MHD_DLOG (daemon,
5725  _ ("Error initializing DH parameters.\n"));
5726 #endif
5727  return MHD_NO;
5728  }
5729  dhpar.data = (unsigned char *) pstr;
5730  pstr_len = strlen (pstr);
5731  if (UINT_MAX < pstr_len)
5732  {
5733 #ifdef HAVE_MESSAGES
5734  MHD_DLOG (daemon,
5735  _ ("Diffie-Hellman parameters string too long.\n"));
5736 #endif
5737  return MHD_NO;
5738  }
5739  dhpar.size = (unsigned int) pstr_len;
5740  if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5741  &dhpar,
5742  GNUTLS_X509_FMT_PEM) < 0)
5743  {
5744 #ifdef HAVE_MESSAGES
5745  MHD_DLOG (daemon,
5746  _ ("Bad Diffie-Hellman parameters format.\n"));
5747 #endif
5748  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5749  return MHD_NO;
5750  }
5751  daemon->have_dhparams = true;
5752  }
5753 #ifdef HAVE_MESSAGES
5754  else
5755  MHD_DLOG (daemon,
5756  _ (
5757  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5758  opt);
5759 #endif
5760  break;
5762  pstr = va_arg (ap,
5763  const char *);
5764  if (0 != (daemon->options & MHD_USE_TLS))
5765  {
5766  gnutls_priority_deinit (daemon->priority_cache);
5767  ret = gnutls_priority_init (&daemon->priority_cache,
5768  pstr,
5769  NULL);
5770  if (GNUTLS_E_SUCCESS != ret)
5771  {
5772 #ifdef HAVE_MESSAGES
5773  MHD_DLOG (daemon,
5774  _ ("Setting priorities to `%s' failed: %s\n"),
5775  pstr,
5776  gnutls_strerror (ret));
5777 #endif
5778  daemon->priority_cache = NULL;
5779  return MHD_NO;
5780  }
5781  }
5782 #ifdef HAVE_MESSAGES
5783  else
5784  MHD_DLOG (daemon,
5785  _ (
5786  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5787  opt);
5788 #endif
5789  break;
5791 #if GNUTLS_VERSION_MAJOR < 3
5792 #ifdef HAVE_MESSAGES
5793  MHD_DLOG (daemon,
5794  _ (
5795  "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0.\n"));
5796 #endif
5797  return MHD_NO;
5798 #else
5799  pgcrf = va_arg (ap,
5800  gnutls_certificate_retrieve_function2 *);
5801  if (0 != (daemon->options & MHD_USE_TLS))
5802  daemon->cert_callback = pgcrf;
5803 #ifdef HAVE_MESSAGES
5804  else
5805  MHD_DLOG (daemon,
5806  _ (
5807  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5808  opt);
5809 #endif /* HAVE_MESSAGES */
5810  break;
5811 #endif
5813 #if GNUTLS_VERSION_NUMBER < 0x030603
5814 #ifdef HAVE_MESSAGES
5815  MHD_DLOG (daemon,
5816  _ (
5817  "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3.\n"));
5818 #endif
5819  return MHD_NO;
5820 #else
5821  pgcrf2 = va_arg (ap,
5822  gnutls_certificate_retrieve_function3 *);
5823  if (0 != (daemon->options & MHD_USE_TLS))
5824  daemon->cert_callback2 = pgcrf2;
5825 #ifdef HAVE_MESSAGES
5826  else
5827  MHD_DLOG (daemon,
5828  _ (
5829  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set.\n"),
5830  opt);
5831 #endif /* HAVE_MESSAGES */
5832  break;
5833 #endif
5834 #endif /* HTTPS_SUPPORT */
5835 #ifdef DAUTH_SUPPORT
5837  daemon->digest_auth_rand_size = va_arg (ap,
5838  size_t);
5839  daemon->digest_auth_random = va_arg (ap,
5840  const char *);
5841  break;
5843  daemon->nonce_nc_size = va_arg (ap,
5844  unsigned int);
5845  break;
5846 #endif
5848  if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET))
5849  {
5850 #ifdef HAVE_MESSAGES
5851  MHD_DLOG (daemon,
5852  _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon "
5853  "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5854 #endif
5855  return MHD_NO;
5856  }
5857  else
5858  {
5859  daemon->listen_fd = va_arg (ap,
5860  MHD_socket);
5861 #if defined(SO_DOMAIN) && defined(AF_UNIX)
5862  {
5863  int af;
5864  socklen_t len = sizeof (af);
5865 
5866  if (0 == getsockopt (daemon->listen_fd,
5867  SOL_SOCKET,
5868  SO_DOMAIN,
5869  &af,
5870  &len))
5871  {
5872  daemon->listen_is_unix = (AF_UNIX == af) ? _MHD_YES : _MHD_NO;
5873  }
5874  else
5875  daemon->listen_is_unix = _MHD_UNKNOWN;
5876  }
5877 #else /* ! SO_DOMAIN || ! AF_UNIX */
5878  daemon->listen_is_unix = _MHD_UNKNOWN;
5879 #endif /* ! SO_DOMAIN || ! AF_UNIX */
5880  }
5881  break;
5883 #ifdef HAVE_MESSAGES
5884  daemon->custom_error_log = va_arg (ap,
5886  daemon->custom_error_log_cls = va_arg (ap,
5887  void *);
5888  if (1 != daemon->num_opts)
5889  MHD_DLOG (daemon,
5890  _ ("MHD_OPTION_EXTERNAL_LOGGER is not the first option "
5891  "specified for the daemon. Some messages may be "
5892  "printed by the standard MHD logger.\n"));
5893 
5894 #else
5895  va_arg (ap,
5897  va_arg (ap,
5898  void *);
5899 #endif
5900  break;
5901 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5903  daemon->thread_stack_size = va_arg (ap,
5904  size_t);
5905  break;
5906 #endif
5908 #ifdef TCP_FASTOPEN
5909  daemon->fastopen_queue_size = va_arg (ap,
5910  unsigned int);
5911  break;
5912 #else /* ! TCP_FASTOPEN */
5913 #ifdef HAVE_MESSAGES
5914  MHD_DLOG (daemon,
5915  _ ("TCP fastopen is not supported on this platform.\n"));
5916 #endif /* HAVE_MESSAGES */
5917  return MHD_NO;
5918 #endif /* ! TCP_FASTOPEN */
5920  daemon->listening_address_reuse = va_arg (ap,
5921  unsigned int) ? 1 : -1;
5922  break;
5924  daemon->listen_backlog_size = va_arg (ap,
5925  unsigned int);
5926  break;
5928  daemon->strict_for_client = va_arg (ap, int);
5929 #ifdef HAVE_MESSAGES
5930  if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
5931  (1 != daemon->strict_for_client) )
5932  {
5933  MHD_DLOG (daemon,
5934  _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5935  "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5936  }
5937 #endif /* HAVE_MESSAGES */
5938  break;
5939  case MHD_OPTION_ARRAY:
5940  daemon->num_opts--; /* Do not count MHD_OPTION_ARRAY */
5941  oa = va_arg (ap, struct MHD_OptionItem*);
5942  i = 0;
5943  while (MHD_OPTION_END != (opt = oa[i].option))
5944  {
5945  switch (opt)
5946  {
5947  /* all options taking 'size_t' */
5951  if (MHD_NO == parse_options (daemon,
5952  servaddr,
5953  opt,
5954  (size_t) oa[i].value,
5955  MHD_OPTION_END))
5956  return MHD_NO;
5957  break;
5958  /* all options taking 'unsigned int' */
5968  if (MHD_NO == parse_options (daemon,
5969  servaddr,
5970  opt,
5971  (unsigned int) oa[i].value,
5972  MHD_OPTION_END))
5973  return MHD_NO;
5974  break;
5975  /* all options taking 'enum' */
5976 #ifdef HTTPS_SUPPORT
5978  if (MHD_NO == parse_options (daemon,
5979  servaddr,
5980  opt,
5981  (gnutls_credentials_type_t) oa[i].value,
5982  MHD_OPTION_END))
5983  return MHD_NO;
5984  break;
5985 #endif /* HTTPS_SUPPORT */
5986  /* all options taking 'MHD_socket' */
5988  if (MHD_NO == parse_options (daemon,
5989  servaddr,
5990  opt,
5991  (MHD_socket) oa[i].value,
5992  MHD_OPTION_END))
5993  return MHD_NO;
5994  break;
5995  /* all options taking 'int' */
5999  if (MHD_NO == parse_options (daemon,
6000  servaddr,
6001  opt,
6002  (int) oa[i].value,
6003  MHD_OPTION_END))
6004  return MHD_NO;
6005  break;
6006  /* all options taking one pointer */
6007  case MHD_OPTION_SOCK_ADDR:
6014  case MHD_OPTION_ARRAY:
6017  if (MHD_NO == parse_options (daemon,
6018  servaddr,
6019  opt,
6020  oa[i].ptr_value,
6021  MHD_OPTION_END))
6022  return MHD_NO;
6023  break;
6024  /* all options taking two pointers */
6031  if (MHD_NO == parse_options (daemon,
6032  servaddr,
6033  opt,
6034  (void *) oa[i].value,
6035  oa[i].ptr_value,
6036  MHD_OPTION_END))
6037  return MHD_NO;
6038  break;
6039  /* options taking size_t-number followed by pointer */
6041  if (MHD_NO == parse_options (daemon,
6042  servaddr,
6043  opt,
6044  (size_t) oa[i].value,
6045  oa[i].ptr_value,
6046  MHD_OPTION_END))
6047  return MHD_NO;
6048  break;
6049  default:
6050  return MHD_NO;
6051  }
6052  i++;
6053  }
6054  break;
6056  daemon->unescape_callback = va_arg (ap,
6058  daemon->unescape_callback_cls = va_arg (ap,
6059  void *);
6060  break;
6061 #ifdef HTTPS_SUPPORT
6063 #if GNUTLS_VERSION_MAJOR >= 3
6064  daemon->cred_callback = va_arg (ap,
6066  daemon->cred_callback_cls = va_arg (ap,
6067  void *);
6068  break;
6069 #else
6070  MHD_DLOG (daemon,
6071  _ (
6072  "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3.\n"),
6073  opt);
6074  return MHD_NO;
6075 #endif
6076 #endif /* HTTPS_SUPPORT */
6078  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
6079  daemon->sigpipe_blocked = ( (va_arg (ap,
6080  int)) != 0);
6081  else
6082  {
6083  (void) va_arg (ap,
6084  int);
6085  }
6086  break;
6088 #ifdef HTTPS_SUPPORT
6089  daemon->disable_alpn = (va_arg (ap,
6090  int) != 0);
6091 #else /* ! HTTPS_SUPPORT */
6092  (void) va_arg (ap, int);
6093 #endif /* ! HTTPS_SUPPORT */
6094 #ifdef HAVE_MESSAGES
6095  if (0 == (daemon->options & MHD_USE_TLS))
6096  MHD_DLOG (daemon,
6097  _ ("MHD HTTPS option %d passed to MHD " \
6098  "but MHD_USE_TLS not set.\n"),
6099  (int) opt);
6100 #endif /* HAVE_MESSAGES */
6101  break;
6102  default:
6103 #ifdef HAVE_MESSAGES
6104  if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
6105  (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) ||
6106  (opt == MHD_OPTION_HTTPS_MEM_TRUST) ||
6108  {
6109  MHD_DLOG (daemon,
6110  _ (
6111  "MHD HTTPS option %d passed to MHD compiled without HTTPS support.\n"),
6112  opt);
6113  }
6114  else
6115  {
6116  MHD_DLOG (daemon,
6117  _ (
6118  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?).\n"),
6119  opt);
6120  }
6121 #endif
6122  return MHD_NO;
6123  }
6124  }
6125  return MHD_YES;
6126 }
6127 
6128 
6129 #ifdef EPOLL_SUPPORT
6130 static int
6131 setup_epoll_fd (struct MHD_Daemon *daemon)
6132 {
6133  int fd;
6134 
6135 #ifndef HAVE_MESSAGES
6136  (void) daemon; /* Mute compiler warning. */
6137 #endif /* ! HAVE_MESSAGES */
6138 
6139 #ifdef USE_EPOLL_CREATE1
6140  fd = epoll_create1 (EPOLL_CLOEXEC);
6141 #else /* ! USE_EPOLL_CREATE1 */
6142  fd = epoll_create (MAX_EVENTS);
6143 #endif /* ! USE_EPOLL_CREATE1 */
6144  if (MHD_INVALID_SOCKET == fd)
6145  {
6146 #ifdef HAVE_MESSAGES
6147  MHD_DLOG (daemon,
6148  _ ("Call to epoll_create1 failed: %s\n"),
6150 #endif
6151  return MHD_INVALID_SOCKET;
6152  }
6153 #if ! defined(USE_EPOLL_CREATE1)
6155  {
6156 #ifdef HAVE_MESSAGES
6157  MHD_DLOG (daemon,
6158  _ ("Failed to set noninheritable mode on epoll FD.\n"));
6159 #endif
6160  }
6161 #endif /* ! USE_EPOLL_CREATE1 */
6162  return fd;
6163 }
6164 
6165 
6174 static enum MHD_Result
6175 setup_epoll_to_listen (struct MHD_Daemon *daemon)
6176 {
6177  struct epoll_event event;
6178  MHD_socket ls;
6179 
6180  mhd_assert (0 != (daemon->options & MHD_USE_EPOLL));
6182  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
6183  (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) || \
6184  MHD_ITC_IS_VALID_ (daemon->itc) );
6185  daemon->epoll_fd = setup_epoll_fd (daemon);
6186  if (-1 == daemon->epoll_fd)
6187  return MHD_NO;
6188 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6189  if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
6190  {
6191  daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
6192  if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
6193  return MHD_NO;
6194  }
6195 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6196  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
6197  (! daemon->was_quiesced) )
6198  {
6199  event.events = EPOLLIN;
6200  event.data.ptr = daemon;
6201  if (0 != epoll_ctl (daemon->epoll_fd,
6202  EPOLL_CTL_ADD,
6203  ls,
6204  &event))
6205  {
6206 #ifdef HAVE_MESSAGES
6207  MHD_DLOG (daemon,
6208  _ ("Call to epoll_ctl failed: %s\n"),
6210 #endif
6211  return MHD_NO;
6212  }
6213  daemon->listen_socket_in_epoll = true;
6214  }
6215 
6216  if (MHD_ITC_IS_VALID_ (daemon->itc))
6217  {
6218  event.events = EPOLLIN;
6219  event.data.ptr = (void *) epoll_itc_marker;
6220  if (0 != epoll_ctl (daemon->epoll_fd,
6221  EPOLL_CTL_ADD,
6222  MHD_itc_r_fd_ (daemon->itc),
6223  &event))
6224  {
6225 #ifdef HAVE_MESSAGES
6226  MHD_DLOG (daemon,
6227  _ ("Call to epoll_ctl failed: %s\n"),
6229 #endif
6230  return MHD_NO;
6231  }
6232  }
6233  return MHD_YES;
6234 }
6235 
6236 
6237 #endif
6238 
6239 
6261 struct MHD_Daemon *
6262 MHD_start_daemon_va (unsigned int flags,
6263  uint16_t port,
6265  void *apc_cls,
6267  void *dh_cls,
6268  va_list ap)
6269 {
6270  const MHD_SCKT_OPT_BOOL_ on = 1;
6271  struct MHD_Daemon *daemon;
6273  struct sockaddr_in servaddr4;
6274 #if HAVE_INET6
6275  struct sockaddr_in6 servaddr6;
6276 #endif
6277  const struct sockaddr *servaddr = NULL;
6278  socklen_t addrlen;
6279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6280  unsigned int i;
6281 #endif
6282  enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
6283  enum MHD_FLAG *pflags;
6284 
6286  eflags = (enum MHD_FLAG) flags;
6287  pflags = &eflags;
6288 #ifndef HAVE_INET6
6289  if (0 != (*pflags & MHD_USE_IPv6))
6290  return NULL;
6291 #endif
6292 #ifndef HAVE_POLL
6293  if (0 != (*pflags & MHD_USE_POLL))
6294  return NULL;
6295 #endif
6296 #ifndef EPOLL_SUPPORT
6297  if (0 != (*pflags & MHD_USE_EPOLL))
6298  return NULL;
6299 #endif /* ! EPOLL_SUPPORT */
6300 #ifndef HTTPS_SUPPORT
6301  if (0 != (*pflags & MHD_USE_TLS))
6302  return NULL;
6303 #endif /* ! HTTPS_SUPPORT */
6304 #ifndef TCP_FASTOPEN
6305  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
6306  return NULL;
6307 #endif
6308  if (0 != (*pflags & MHD_ALLOW_UPGRADE))
6309  {
6310 #ifdef UPGRADE_SUPPORT
6311  *pflags |= MHD_ALLOW_SUSPEND_RESUME;
6312 #else /* ! UPGRADE_SUPPORT */
6313  return NULL;
6314 #endif /* ! UPGRADE_SUPPORT */
6315  }
6316  if (NULL == dh)
6317  return NULL;
6318 
6319  /* Check for invalid combinations of flags. */
6320  if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) ||
6321  ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags
6322  &
6324  ||
6325  ((0 != (*pflags & MHD_USE_POLL)) &&
6326  (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD
6328  ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL
6329  | MHD_USE_EPOLL)))) )
6330  return NULL;
6331 
6332  if (0 != (*pflags & MHD_USE_AUTO))
6333  {
6334  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6335  {
6336  /* Thread per connection with internal polling thread. */
6337 #ifdef HAVE_POLL
6338  *pflags |= MHD_USE_POLL;
6339 #else /* ! HAVE_POLL */
6340  /* use select() - do not modify flags */
6341 #endif /* ! HAVE_POLL */
6342  }
6343  else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
6344  {
6345  /* Internal polling thread. */
6346 #if defined(EPOLL_SUPPORT)
6347  *pflags |= MHD_USE_EPOLL;
6348 #elif defined(HAVE_POLL)
6349  *pflags |= MHD_USE_POLL;
6350 #else /* !HAVE_POLL && !EPOLL_SUPPORT */
6351  /* use select() - do not modify flags */
6352 #endif /* !HAVE_POLL && !EPOLL_SUPPORT */
6353  }
6354  else
6355  {
6356  /* Internal threads are not used - "external" polling mode. */
6357 #if defined(EPOLL_SUPPORT)
6358  *pflags |= MHD_USE_EPOLL;
6359 #else /* ! EPOLL_SUPPORT */
6360  /* use select() - do not modify flags */
6361 #endif /* ! EPOLL_SUPPORT */
6362  }
6363  }
6364 
6365  if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
6366  return NULL;
6367 #ifdef EPOLL_SUPPORT
6368  daemon->epoll_fd = -1;
6369 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6370  daemon->epoll_upgrade_fd = -1;
6371 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6372 #endif
6373  /* try to open listen socket */
6374 #ifdef HTTPS_SUPPORT
6375  daemon->priority_cache = NULL;
6376  if (0 != (*pflags & MHD_USE_TLS))
6377  {
6378  gnutls_priority_init (&daemon->priority_cache,
6379  "@SYSTEM",
6380  NULL);
6381  }
6382 #endif /* HTTPS_SUPPORT */
6383  daemon->listen_fd = MHD_INVALID_SOCKET;
6384  daemon->listen_is_unix = _MHD_NO;
6385  daemon->listening_address_reuse = 0;
6386  daemon->options = *pflags;
6387  pflags = &daemon->options;
6388  daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 :
6389  0;
6390  daemon->port = port;
6391  daemon->apc = apc;
6392  daemon->apc_cls = apc_cls;
6393  daemon->default_handler = dh;
6394  daemon->default_handler_cls = dh_cls;
6395  daemon->connections = 0;
6397  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
6398  daemon->pool_increment = MHD_BUF_INC_SIZE;
6400  daemon->connection_timeout = 0; /* no timeout */
6401  MHD_itc_set_invalid_ (daemon->itc);
6402 #ifdef SOMAXCONN
6403  daemon->listen_backlog_size = SOMAXCONN;
6404 #else /* !SOMAXCONN */
6405  daemon->listen_backlog_size = 511; /* should be safe value */
6406 #endif /* !SOMAXCONN */
6407 #ifdef HAVE_MESSAGES
6408  daemon->custom_error_log = &MHD_default_logger_;
6409  daemon->custom_error_log_cls = stderr;
6410 #endif
6411 #ifndef MHD_WINSOCK_SOCKETS
6412  daemon->sigpipe_blocked = false;
6413 #else /* MHD_WINSOCK_SOCKETS */
6414  /* There is no SIGPIPE on W32, nothing to block. */
6415  daemon->sigpipe_blocked = true;
6416 #endif /* _WIN32 && ! __CYGWIN__ */
6417 
6418  if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
6419  (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
6420  {
6421  /* Log warning message later, when log parameters are processes */
6423  }
6424  if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
6425  *pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */
6426  else
6427  {
6428 #ifdef HAVE_LISTEN_SHUTDOWN
6429  if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
6430 #endif
6431  *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */
6432  }
6433 #ifdef DAUTH_SUPPORT
6434  daemon->digest_auth_rand_size = 0;
6435  daemon->digest_auth_random = NULL;
6436  daemon->nonce_nc_size = 4; /* tiny */
6437 #endif
6438 #ifdef HTTPS_SUPPORT
6439  if (0 != (*pflags & MHD_USE_TLS))
6440  {
6441  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
6442  }
6443 #endif /* HTTPS_SUPPORT */
6444 
6445 
6446  if (MHD_NO == parse_options_va (daemon,
6447  &servaddr,
6448  ap))
6449  {
6450 #ifdef HTTPS_SUPPORT
6451  if ( (0 != (*pflags & MHD_USE_TLS)) &&
6452  (NULL != daemon->priority_cache) )
6453  gnutls_priority_deinit (daemon->priority_cache);
6454 #endif /* HTTPS_SUPPORT */
6455  free (daemon);
6456  return NULL;
6457  }
6458 
6459 #ifdef HAVE_MESSAGES
6460  if ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) &&
6461  (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD)) )
6462  {
6463  MHD_DLOG (daemon,
6464  _ (
6465  "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
6466  "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
6467  "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
6468  }
6469 #endif
6470 
6471  if ( (NULL != daemon->notify_completed) &&
6472  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
6473  *pflags |= MHD_USE_ITC; /* requires ITC */
6474 
6475 #ifndef NDEBUG
6476 #ifdef HAVE_MESSAGES
6477  MHD_DLOG (daemon,
6478  _ ("Using debug build of libmicrohttpd.\n") );
6479 #endif /* HAVE_MESSAGES */
6480 #endif /* ! NDEBUG */
6481 
6482  if ( (0 != (*pflags & MHD_USE_ITC))
6483 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6484  && (0 == daemon->worker_pool_size)
6485 #endif
6486  )
6487  {
6488  if (! MHD_itc_init_ (daemon->itc))
6489  {
6490 #ifdef HAVE_MESSAGES
6491  MHD_DLOG (daemon,
6492  _ ("Failed to create inter-thread communication channel: %s\n"),
6493  MHD_itc_last_strerror_ ());
6494 #endif
6495 #ifdef HTTPS_SUPPORT
6496  if (NULL != daemon->priority_cache)
6497  gnutls_priority_deinit (daemon->priority_cache);
6498 #endif /* HTTPS_SUPPORT */
6499  free (daemon);
6500  return NULL;
6501  }
6502  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
6503  (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (daemon->itc),
6504  NULL)) )
6505  {
6506 #ifdef HAVE_MESSAGES
6507  MHD_DLOG (daemon,
6508  _ (
6509  "file descriptor for inter-thread communication channel exceeds maximum value.\n"));
6510 #endif
6511  MHD_itc_destroy_chk_ (daemon->itc);
6512 #ifdef HTTPS_SUPPORT
6513  if (NULL != daemon->priority_cache)
6514  gnutls_priority_deinit (daemon->priority_cache);
6515 #endif /* HTTPS_SUPPORT */
6516  free (daemon);
6517  return NULL;
6518  }
6519  }
6520 
6521 #ifdef DAUTH_SUPPORT
6522  if (daemon->nonce_nc_size > 0)
6523  {
6524  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)))
6525  / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
6526  {
6527 #ifdef HAVE_MESSAGES
6528  MHD_DLOG (daemon,
6529  _ ("Specified value for NC_SIZE too large.\n"));
6530 #endif
6531 #ifdef HTTPS_SUPPORT
6532  if (0 != (*pflags & MHD_USE_TLS))
6533  gnutls_priority_deinit (daemon->priority_cache);
6534 #endif /* HTTPS_SUPPORT */
6535  free (daemon);
6536  return NULL;
6537  }
6538  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
6539  if (NULL == daemon->nnc)
6540  {
6541 #ifdef HAVE_MESSAGES
6542  MHD_DLOG (daemon,
6543  _ ("Failed to allocate memory for nonce-nc map: %s\n"),
6544  MHD_strerror_ (errno));
6545 #endif
6546 #ifdef HTTPS_SUPPORT
6547  if (0 != (*pflags & MHD_USE_TLS))
6548  gnutls_priority_deinit (daemon->priority_cache);
6549 #endif /* HTTPS_SUPPORT */
6550  free (daemon);
6551  return NULL;
6552  }
6553  }
6554 
6555 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6556  if (! MHD_mutex_init_ (&daemon->nnc_lock))
6557  {
6558 #ifdef HAVE_MESSAGES
6559  MHD_DLOG (daemon,
6560  _ ("MHD failed to initialize nonce-nc mutex.\n"));
6561 #endif
6562 #ifdef HTTPS_SUPPORT
6563  if (0 != (*pflags & MHD_USE_TLS))
6564  gnutls_priority_deinit (daemon->priority_cache);
6565 #endif /* HTTPS_SUPPORT */
6566  free (daemon->nnc);
6567  free (daemon);
6568  return NULL;
6569  }
6570 #endif
6571 #endif
6572 
6573  /* Thread polling currently works only with internal select thread mode */
6574 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6575  if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
6576  (daemon->worker_pool_size > 0) )
6577  {
6578 #ifdef HAVE_MESSAGES
6579  MHD_DLOG (daemon,
6580  _ (
6581  "MHD thread polling only works with MHD_USE_INTERNAL_POLLING_THREAD.\n"));
6582 #endif
6583  goto free_and_fail;
6584  }
6585 #endif
6586  if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
6587  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6588  {
6589  /* try to open listen socket */
6590  int domain;
6591 
6592 #ifdef HAVE_INET6
6593  domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET;
6594 #else /* ! HAVE_INET6 */
6595  if (*pflags & MHD_USE_IPv6)
6596  goto free_and_fail;
6597  domain = PF_INET;
6598 #endif /* ! HAVE_INET6 */
6599 
6600  listen_fd = MHD_socket_create_listen_ (domain);
6601  if (MHD_INVALID_SOCKET == listen_fd)
6602  {
6603 #ifdef HAVE_MESSAGES
6604  MHD_DLOG (daemon,
6605  _ ("Failed to create socket for listening: %s\n"),
6607 #endif
6608  goto free_and_fail;
6609  }
6610 
6611  /* Apply the socket options according to listening_address_reuse. */
6612  if (0 == daemon->listening_address_reuse)
6613  {
6614 #ifndef MHD_WINSOCK_SOCKETS
6615  /* No user requirement, use "traditional" default SO_REUSEADDR
6616  * on non-W32 platforms, and do not fail if it doesn't work.
6617  * Don't use it on W32, because on W32 it will allow multiple
6618  * bind to the same address:port, like SO_REUSEPORT on others. */
6619  if (0 > setsockopt (listen_fd,
6620  SOL_SOCKET,
6621  SO_REUSEADDR,
6622  (void*) &on, sizeof (on)))
6623  {
6624 #ifdef HAVE_MESSAGES
6625  MHD_DLOG (daemon,
6626  _ ("setsockopt failed: %s\n"),
6628 #endif
6629  }
6630 #endif /* ! MHD_WINSOCK_SOCKETS */
6631  }
6632  else if (daemon->listening_address_reuse > 0)
6633  {
6634  /* User requested to allow reusing listening address:port. */
6635 #ifndef MHD_WINSOCK_SOCKETS
6636  /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
6637  * it doesn't work. */
6638  if (0 > setsockopt (listen_fd,
6639  SOL_SOCKET,
6640  SO_REUSEADDR,
6641  (void*) &on, sizeof (on)))
6642  {
6643 #ifdef HAVE_MESSAGES
6644  MHD_DLOG (daemon,
6645  _ ("setsockopt failed: %s\n"),
6647 #endif
6648  }
6649 #endif /* ! MHD_WINSOCK_SOCKETS */
6650  /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
6651  * Fail if SO_REUSEPORT is not defined or setsockopt fails.
6652  */
6653  /* SO_REUSEADDR on W32 has the same semantics
6654  as SO_REUSEPORT on BSD/Linux */
6655 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
6656  if (0 > setsockopt (listen_fd,
6657  SOL_SOCKET,
6658 #ifndef MHD_WINSOCK_SOCKETS
6659  SO_REUSEPORT,
6660 #else /* MHD_WINSOCK_SOCKETS */
6661  SO_REUSEADDR,
6662 #endif /* MHD_WINSOCK_SOCKETS */
6663  (void *) &on,
6664  sizeof (on)))
6665  {
6666 #ifdef HAVE_MESSAGES
6667  MHD_DLOG (daemon,
6668  _ ("setsockopt failed: %s\n"),
6670 #endif
6671  goto free_and_fail;
6672  }
6673 #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
6674  /* we're supposed to allow address:port re-use, but
6675  on this platform we cannot; fail hard */
6676 #ifdef HAVE_MESSAGES
6677  MHD_DLOG (daemon,
6678  _ (
6679  "Cannot allow listening address reuse: SO_REUSEPORT not defined.\n"));
6680 #endif
6681  goto free_and_fail;
6682 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
6683  }
6684  else /* if (daemon->listening_address_reuse < 0) */
6685  {
6686  /* User requested to disallow reusing listening address:port.
6687  * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
6688  * is used and Solaris with SO_EXCLBIND.
6689  * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
6690  * or setsockopt fails.
6691  */
6692 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
6693  (defined(__sun) && defined(SO_EXCLBIND))
6694  if (0 > setsockopt (listen_fd,
6695  SOL_SOCKET,
6696 #ifdef SO_EXCLUSIVEADDRUSE
6697  SO_EXCLUSIVEADDRUSE,
6698 #else /* SO_EXCLBIND */
6699  SO_EXCLBIND,
6700 #endif /* SO_EXCLBIND */
6701  (void *) &on,
6702  sizeof (on)))
6703  {
6704 #ifdef HAVE_MESSAGES
6705  MHD_DLOG (daemon,
6706  _ ("setsockopt failed: %s\n"),
6708 #endif
6709  goto free_and_fail;
6710  }
6711 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
6712 #ifdef HAVE_MESSAGES
6713  MHD_DLOG (daemon,
6714  _ (
6715  "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined.\n"));
6716 #endif
6717  goto free_and_fail;
6718 #endif /* MHD_WINSOCK_SOCKETS */
6719  }
6720 
6721  /* check for user supplied sockaddr */
6722 #if HAVE_INET6
6723  if (0 != (*pflags & MHD_USE_IPv6))
6724  addrlen = sizeof (struct sockaddr_in6);
6725  else
6726 #endif
6727  addrlen = sizeof (struct sockaddr_in);
6728  if (NULL == servaddr)
6729  {
6730 #if HAVE_INET6
6731  if (0 != (*pflags & MHD_USE_IPv6))
6732  {
6733 #ifdef IN6ADDR_ANY_INIT
6734  static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6735 #endif
6736  memset (&servaddr6,
6737  0,
6738  sizeof (struct sockaddr_in6));
6739  servaddr6.sin6_family = AF_INET6;
6740  servaddr6.sin6_port = htons (port);
6741 #ifdef IN6ADDR_ANY_INIT
6742  servaddr6.sin6_addr = static_in6any;
6743 #endif
6744 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
6745  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
6746 #endif
6747  servaddr = (struct sockaddr *) &servaddr6;
6748  }
6749  else
6750 #endif
6751  {
6752  memset (&servaddr4,
6753  0,
6754  sizeof (struct sockaddr_in));
6755  servaddr4.sin_family = AF_INET;
6756  servaddr4.sin_port = htons (port);
6757  if (0 != INADDR_ANY)
6758  servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6759 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
6760  servaddr4.sin_len = sizeof (struct sockaddr_in);
6761 #endif
6762  servaddr = (struct sockaddr *) &servaddr4;
6763  }
6764  }
6765  daemon->listen_fd = listen_fd;
6766  if (0 != (*pflags & MHD_USE_IPv6))
6767  {
6768 #ifdef IPPROTO_IPV6
6769 #ifdef IPV6_V6ONLY
6770  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
6771  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
6772  and may also be missing on older POSIX systems; good luck if you have any of those,
6773  your IPv6 socket may then also bind against IPv4 anyway... */
6774  const MHD_SCKT_OPT_BOOL_ v6_only =
6775  (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
6776  if (0 > setsockopt (listen_fd,
6777  IPPROTO_IPV6, IPV6_V6ONLY,
6778  (const void *) &v6_only,
6779  sizeof (v6_only)))
6780  {
6781 #ifdef HAVE_MESSAGES
6782  MHD_DLOG (daemon,
6783  _ ("setsockopt failed: %s\n"),
6785 #endif
6786  }
6787 #endif
6788 #endif
6789  }
6790  if (-1 == bind (listen_fd, servaddr, addrlen))
6791  {
6792 #ifdef HAVE_MESSAGES
6793  MHD_DLOG (daemon,
6794  _ ("Failed to bind to port %u: %s\n"),
6795  (unsigned int) port,
6797 #endif
6798  MHD_socket_close_chk_ (listen_fd);
6799  goto free_and_fail;
6800  }
6801 #ifdef TCP_FASTOPEN
6802  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
6803  {
6804  if (0 == daemon->fastopen_queue_size)
6805  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6806  if (0 != setsockopt (listen_fd,
6807  IPPROTO_TCP,
6808  TCP_FASTOPEN,
6809  (const void*) &daemon->fastopen_queue_size,
6810  sizeof (daemon->fastopen_queue_size)))
6811  {
6812 #ifdef HAVE_MESSAGES
6813  MHD_DLOG (daemon,
6814  _ ("setsockopt failed: %s\n"),
6816 #endif
6817  }
6818  }
6819 #endif
6820  if (listen (listen_fd,
6821  daemon->listen_backlog_size) < 0)
6822  {
6823 #ifdef HAVE_MESSAGES
6824  MHD_DLOG (daemon,
6825  _ ("Failed to listen for connections: %s\n"),
6827 #endif
6828  MHD_socket_close_chk_ (listen_fd);
6829  goto free_and_fail;
6830  }
6831  }
6832  else
6833  {
6834  listen_fd = daemon->listen_fd;
6835  }
6836 
6837 #ifdef HAVE_GETSOCKNAME
6838  if ( (0 == daemon->port) &&
6839  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6840  { /* Get port number. */
6841  struct sockaddr_storage bindaddr;
6842 
6843  memset (&bindaddr,
6844  0,
6845  sizeof (struct sockaddr_storage));
6846  addrlen = sizeof (struct sockaddr_storage);
6847 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
6848  bindaddr.ss_len = addrlen;
6849 #endif
6850  if (0 != getsockname (listen_fd,
6851  (struct sockaddr *) &bindaddr,
6852  &addrlen))
6853  {
6854 #ifdef HAVE_MESSAGES
6855  MHD_DLOG (daemon,
6856  _ ("Failed to get listen port number: %s\n"),
6858 #endif /* HAVE_MESSAGES */
6859  }
6860 #ifdef MHD_POSIX_SOCKETS
6861  else if (sizeof (bindaddr) < addrlen)
6862  {
6863  /* should be impossible with `struct sockaddr_storage` */
6864 #ifdef HAVE_MESSAGES
6865  MHD_DLOG (daemon,
6866  _ (
6867  "Failed to get listen port number (`struct sockaddr_storage` too small!?).\n"));
6868 #endif /* HAVE_MESSAGES */
6869  }
6870 #ifndef __linux__
6871  else if (0 == addrlen)
6872  {
6873  /* Many non-Linux-based platforms return zero addrlen
6874  * for AF_UNIX sockets */
6875  daemon->port = 0; /* special value for UNIX domain sockets */
6876  }
6877 #endif /* __linux__ */
6878 #endif /* MHD_POSIX_SOCKETS */
6879  else
6880  {
6881  switch (bindaddr.ss_family)
6882  {
6883  case AF_INET:
6884  {
6885  struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr;
6886 
6887  daemon->port = ntohs (s4->sin_port);
6888  break;
6889  }
6890 #ifdef HAVE_INET6
6891  case AF_INET6:
6892  {
6893  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr;
6894 
6895  daemon->port = ntohs (s6->sin6_port);
6896  mhd_assert (0 != (*pflags & MHD_USE_IPv6));
6897  break;
6898  }
6899 #endif /* HAVE_INET6 */
6900 #ifdef AF_UNIX
6901  case AF_UNIX:
6902  daemon->port = 0; /* special value for UNIX domain sockets */
6903  break;
6904 #endif
6905  default:
6906 #ifdef HAVE_MESSAGES
6907  MHD_DLOG (daemon,
6908  _ ("Unknown address family!\n"));
6909 #endif
6910  daemon->port = 0; /* ugh */
6911  break;
6912  }
6913  }
6914  }
6915 #endif /* HAVE_GETSOCKNAME */
6916  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6917  (! MHD_socket_nonblocking_ (listen_fd)) )
6918  {
6919 #ifdef HAVE_MESSAGES
6920  MHD_DLOG (daemon,
6921  _ ("Failed to set nonblocking mode on listening socket: %s\n"),
6923 #endif
6924  if (0 != (*pflags & MHD_USE_EPOLL)
6925 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6926  || (daemon->worker_pool_size > 0)
6927 #endif
6928  )
6929  {
6930  /* Accept must be non-blocking. Multiple children may wake up
6931  * to handle a new connection, but only one will win the race.
6932  * The others must immediately return. */
6933  MHD_socket_close_chk_ (listen_fd);
6934  goto free_and_fail;
6935  }
6936  }
6937  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6938  (! MHD_SCKT_FD_FITS_FDSET_ (listen_fd,
6939  NULL)) &&
6940  (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
6941  {
6942 #ifdef HAVE_MESSAGES
6943  MHD_DLOG (daemon,
6944  _ ("Listen socket descriptor (%d) is not " \
6945  "less than FD_SETSIZE (%d).\n"),
6946  (int) listen_fd,
6947  (int) FD_SETSIZE);
6948 #endif
6949  MHD_socket_close_chk_ (listen_fd);
6950  goto free_and_fail;
6951  }
6952 
6953 #ifdef EPOLL_SUPPORT
6954  if ( (0 != (*pflags & MHD_USE_EPOLL))
6955 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6956  && (0 == daemon->worker_pool_size)
6957 #endif
6958  )
6959  {
6960  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6961  {
6962 #ifdef HAVE_MESSAGES
6963  MHD_DLOG (daemon,
6964  _ (
6965  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6966 #endif
6967  goto free_and_fail;
6968  }
6969  if (MHD_NO == setup_epoll_to_listen (daemon))
6970  goto free_and_fail;
6971  }
6972 #endif /* EPOLL_SUPPORT */
6973 
6974 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6975  if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
6976  {
6977 #ifdef HAVE_MESSAGES
6978  MHD_DLOG (daemon,
6979  _ ("MHD failed to initialize IP connection limit mutex.\n"));
6980 #endif
6981  if (MHD_INVALID_SOCKET != listen_fd)
6982  MHD_socket_close_chk_ (listen_fd);
6983  goto free_and_fail;
6984  }
6985  if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
6986  {
6987 #ifdef HAVE_MESSAGES
6988  MHD_DLOG (daemon,
6989  _ ("MHD failed to initialize IP connection limit mutex.\n"));
6990 #endif
6991 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6993 #endif
6994  if (MHD_INVALID_SOCKET != listen_fd)
6995  MHD_socket_close_chk_ (listen_fd);
6996  goto free_and_fail;
6997  }
6998 #endif
6999 
7000 #ifdef HTTPS_SUPPORT
7001  /* initialize HTTPS daemon certificate aspects & send / recv functions */
7002  if ( (0 != (*pflags & MHD_USE_TLS)) &&
7003  (0 != MHD_TLS_init (daemon)) )
7004  {
7005 #ifdef HAVE_MESSAGES
7006  MHD_DLOG (daemon,
7007  _ ("Failed to initialize TLS support.\n"));
7008 #endif
7009  if (MHD_INVALID_SOCKET != listen_fd)
7010  MHD_socket_close_chk_ (listen_fd);
7011 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7014 #endif
7015  goto free_and_fail;
7016  }
7017 #endif /* HTTPS_SUPPORT */
7018 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7019  /* Start threads if requested by parameters */
7020  if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
7021  {
7022  /* Internal thread (or threads) is used.
7023  * Make sure that MHD will be able to communicate with threads. */
7024  /* If using a thread pool ITC will be initialised later
7025  * for each individual worker thread. */
7026 #ifdef HAVE_LISTEN_SHUTDOWN
7027  mhd_assert ((1 < daemon->worker_pool_size) || \
7028  (MHD_ITC_IS_VALID_ (daemon->itc)) || \
7029  (MHD_INVALID_SOCKET != daemon->listen_fd));
7030 #else /* ! HAVE_LISTEN_SHUTDOWN */
7031  mhd_assert ((1 < daemon->worker_pool_size) || \
7032  (MHD_ITC_IS_VALID_ (daemon->itc)));
7033 #endif /* ! HAVE_LISTEN_SHUTDOWN */
7034  if (0 == daemon->worker_pool_size)
7035  {
7036  if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
7037  {
7038 #ifdef HAVE_MESSAGES
7039  MHD_DLOG (daemon,
7040  _ ("Failed to initialise mutex.\n"));
7041 #endif
7044  if (MHD_INVALID_SOCKET != listen_fd)
7045  MHD_socket_close_chk_ (listen_fd);
7046  goto free_and_fail;
7047  }
7048  if (! MHD_create_named_thread_ (&daemon->pid,
7049  (*pflags
7051  "MHD-listen" : "MHD-single",
7052  daemon->thread_stack_size,
7054  daemon) )
7055  {
7056 #ifdef HAVE_MESSAGES
7057  MHD_DLOG (daemon,
7058  _ ("Failed to create listen thread: %s\n"),
7059  MHD_strerror_ (errno));
7060 #endif
7061  MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
7064  if (MHD_INVALID_SOCKET != listen_fd)
7065  MHD_socket_close_chk_ (listen_fd);
7066  goto free_and_fail;
7067  }
7068  }
7069  else /* 0 < daemon->worker_pool_size */
7070  {
7071  /* Coarse-grained count of connections per thread (note error
7072  * due to integer division). Also keep track of how many
7073  * connections are leftover after an equal split. */
7074  unsigned int conns_per_thread = daemon->connection_limit
7075  / daemon->worker_pool_size;
7076  unsigned int leftover_conns = daemon->connection_limit
7077  % daemon->worker_pool_size;
7078 
7079  mhd_assert (2 <= daemon->worker_pool_size);
7080  i = 0; /* we need this in case fcntl or malloc fails */
7081 
7082  /* Allocate memory for pooled objects */
7083  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
7084  * daemon->worker_pool_size);
7085  if (NULL == daemon->worker_pool)
7086  goto thread_failed;
7087 
7088  /* Start the workers in the pool */
7089  for (i = 0; i < daemon->worker_pool_size; ++i)
7090  {
7091  /* Create copy of the Daemon object for each worker */
7092  struct MHD_Daemon *d = &daemon->worker_pool[i];
7093 
7094  memcpy (d, daemon, sizeof (struct MHD_Daemon));
7095  /* Adjust polling params for worker daemons; note that memcpy()
7096  has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
7097  the worker threads. */
7098  d->master = daemon;
7099  d->worker_pool_size = 0;
7100  d->worker_pool = NULL;
7101  if (! MHD_mutex_init_ (&d->new_connections_mutex))
7102  {
7103  #ifdef HAVE_MESSAGES
7104  MHD_DLOG (daemon,
7105  _ ("Failed to initialise mutex.\n"));
7106  #endif
7107  goto thread_failed;
7108  }
7109  if (0 != (*pflags & MHD_USE_ITC))
7110  {
7111  if (! MHD_itc_init_ (d->itc))
7112  {
7113 #ifdef HAVE_MESSAGES
7114  MHD_DLOG (daemon,
7115  _ (
7116  "Failed to create worker inter-thread communication channel: %s\n"),
7117  MHD_itc_last_strerror_ () );
7118 #endif
7119  MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
7120  goto thread_failed;
7121  }
7122  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
7123  (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (d->itc),
7124  NULL)) )
7125  {
7126 #ifdef HAVE_MESSAGES
7127  MHD_DLOG (daemon,
7128  _ (
7129  "File descriptor for worker inter-thread communication channel exceeds maximum value.\n"));
7130 #endif
7131  MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
7133  goto thread_failed;
7134  }
7135  }
7136  else
7137  MHD_itc_set_invalid_ (d->itc);
7138 
7139 #ifdef HAVE_LISTEN_SHUTDOWN
7140  mhd_assert ((MHD_ITC_IS_VALID_ (d->itc)) || \
7141  (MHD_INVALID_SOCKET != d->listen_fd));
7142 #else /* ! HAVE_LISTEN_SHUTDOWN */
7143  mhd_assert (MHD_ITC_IS_VALID_ (d->itc));
7144 #endif /* ! HAVE_LISTEN_SHUTDOWN */
7145 
7146  /* Divide available connections evenly amongst the threads.
7147  * Thread indexes in [0, leftover_conns) each get one of the
7148  * leftover connections. */
7149  d->connection_limit = conns_per_thread;
7150  if (i < leftover_conns)
7151  ++d->connection_limit;
7152 #ifdef EPOLL_SUPPORT
7153  if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
7154  (MHD_NO == setup_epoll_to_listen (d)) )
7155  {
7156  if (MHD_ITC_IS_VALID_ (d->itc))
7158  MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
7159  goto thread_failed;
7160  }
7161 #endif
7162  /* Must init cleanup connection mutex for each worker */
7164  {
7165 #ifdef HAVE_MESSAGES
7166  MHD_DLOG (daemon,
7167  _ ("MHD failed to initialize cleanup connection mutex.\n"));
7168 #endif
7169  if (MHD_ITC_IS_VALID_ (d->itc))
7171  MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
7172  goto thread_failed;
7173  }
7174 
7175  /* Spawn the worker thread */
7176  if (! MHD_create_named_thread_ (&d->pid,
7177  "MHD-worker",
7178  daemon->thread_stack_size,
7180  d))
7181  {
7182 #ifdef HAVE_MESSAGES
7183  MHD_DLOG (daemon,
7184  _ ("Failed to create pool thread: %s\n"),
7185  MHD_strerror_ (errno));
7186 #endif
7187  /* Free memory for this worker; cleanup below handles
7188  * all previously-created workers. */
7190  if (MHD_ITC_IS_VALID_ (d->itc))
7192  MHD_mutex_destroy_chk_ (&d->new_connections_mutex);
7193  goto thread_failed;
7194  }
7195  }
7196  }
7197  }
7198  else
7199  { /* Daemon without internal threads */
7200  if (! MHD_mutex_init_ (&daemon->new_connections_mutex))
7201  {
7202 #ifdef HAVE_MESSAGES
7203  MHD_DLOG (daemon,
7204  _ ("Failed to initialise mutex.\n"));
7205 #endif
7206  goto free_and_fail;
7207  }
7208  }
7209 #endif
7210 #ifdef HTTPS_SUPPORT
7211  /* API promises to never use the password after initialization,
7212  so we additionally NULL it here to not deref a dangling pointer. */
7213  daemon->https_key_password = NULL;
7214 #endif /* HTTPS_SUPPORT */
7215 
7216  return daemon;
7217 
7218 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7219 thread_failed:
7220  /* If no worker threads created, then shut down normally. Calling
7221  MHD_stop_daemon (as we do below) doesn't work here since it
7222  assumes a 0-sized thread pool means we had been in the default
7223  MHD_USE_INTERNAL_POLLING_THREAD mode. */
7224  if (0 == i)
7225  {
7229  if (NULL != daemon->worker_pool)
7230  free (daemon->worker_pool);
7231  goto free_and_fail;
7232  }
7233 
7234  /* Shutdown worker threads we've already created. Pretend
7235  as though we had fully initialized our daemon, but
7236  with a smaller number of threads than had been
7237  requested. */
7238  daemon->worker_pool_size = i;
7239  MHD_stop_daemon (daemon);
7240  return NULL;
7241 #endif
7242 
7243 free_and_fail:
7244  /* clean up basic memory state in 'daemon' and return NULL to
7245  indicate failure */
7246 #ifdef EPOLL_SUPPORT
7247 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7248  if (daemon->upgrade_fd_in_epoll)
7249  {
7250  if (0 != epoll_ctl (daemon->epoll_fd,
7251  EPOLL_CTL_DEL,
7252  daemon->epoll_upgrade_fd,
7253  NULL))
7254  MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
7255  daemon->upgrade_fd_in_epoll = false;
7256  }
7257 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
7258  if (-1 != daemon->epoll_fd)
7259  close (daemon->epoll_fd);
7260 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7261  if (-1 != daemon->epoll_upgrade_fd)
7262  close (daemon->epoll_upgrade_fd);
7263 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
7264 #endif /* EPOLL_SUPPORT */
7265 #ifdef DAUTH_SUPPORT
7266  free (daemon->nnc);
7267 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7268  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
7269 #endif
7270 #endif
7271 #ifdef HTTPS_SUPPORT
7272  if (0 != (*pflags & MHD_USE_TLS))
7273  {
7274  gnutls_priority_deinit (daemon->priority_cache);
7275  if (daemon->x509_cred)
7276  gnutls_certificate_free_credentials (daemon->x509_cred);
7277  if (daemon->psk_cred)
7278  gnutls_psk_free_server_credentials (daemon->psk_cred);
7279  }
7280 #endif /* HTTPS_SUPPORT */
7281  if (MHD_ITC_IS_VALID_ (daemon->itc))
7282  MHD_itc_destroy_chk_ (daemon->itc);
7283  free (daemon);
7284  return NULL;
7285 }
7286 
7287 
7296 static void
7298 {
7299  struct MHD_Connection *pos;
7300  const bool used_thr_p_c = (0 != (daemon->options
7302 #ifdef UPGRADE_SUPPORT
7303  const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
7304 #endif /* UPGRADE_SUPPORT */
7305 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7306  struct MHD_UpgradeResponseHandle *urh;
7307  struct MHD_UpgradeResponseHandle *urhn;
7308  const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
7309 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
7310 
7311 #ifdef MHD_USE_THREADS
7312  mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \
7313  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || \
7314  MHD_thread_ID_match_current_ (daemon->pid) );
7315  mhd_assert (NULL == daemon->worker_pool);
7316 #endif /* MHD_USE_THREADS */
7317  mhd_assert (daemon->shutdown);
7318 
7319 #ifdef MHD_USE_THREADS
7320 /* Remove externally added new connections that are
7321  * not processed by the daemon thread. */
7322  while (NULL != (pos = daemon->new_connections_tail))
7323  {
7326  daemon->new_connections_tail,
7327  pos);
7328  new_connection_close_ (daemon, pos);
7329  }
7330 #endif /* MHD_USE_THREADS */
7331 
7332 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7333  /* give upgraded HTTPS connections a chance to finish */
7334  /* 'daemon->urh_head' is not used in thread-per-connection mode. */
7335  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
7336  {
7337  mhd_assert (! used_thr_p_c);
7338  urhn = urh->prev;
7339  /* call generic forwarding function for passing data
7340  with chance to detect that application is done. */
7341  process_urh (urh);
7342  MHD_connection_finish_forward_ (urh->connection);
7343  urh->clean_ready = true;
7344  /* Resuming will move connection to cleanup list. */
7345  MHD_resume_connection (urh->connection);
7346  }
7347 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
7348 
7349  /* Give suspended connections a chance to resume to avoid
7350  running into the check for there not being any suspended
7351  connections left in case of a tight race with a recently
7352  resumed connection. */
7353  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
7354  {
7355  daemon->resuming = true; /* Force check for pending resume. */
7357  }
7358  /* first, make sure all threads are aware of shutdown; need to
7359  traverse DLLs in peace... */
7360 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7362 #endif
7363 #ifdef UPGRADE_SUPPORT
7364  if (upg_allowed)
7365  {
7366  struct MHD_Connection *susp;
7367 
7369  while (NULL != susp)
7370  {
7371  if (NULL == susp->urh) /* "Upgraded" connection? */
7372  MHD_PANIC (_ (
7373  "MHD_stop_daemon() called while we have suspended connections.\n"));
7374 #ifdef HTTPS_SUPPORT
7375  else if (used_tls &&
7376  used_thr_p_c &&
7377  (! susp->urh->clean_ready) )
7378  shutdown (susp->urh->app.socket,
7379  SHUT_RDWR); /* Wake thread by shutdown of app socket. */
7380 #endif /* HTTPS_SUPPORT */
7381  else
7382  {
7383 #ifdef HAVE_MESSAGES
7384  if (! susp->urh->was_closed)
7385  MHD_DLOG (daemon,
7386  _ (
7387  "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
7388 #endif
7389  susp->urh->was_closed = true;
7390  /* If thread-per-connection is used, connection's thread
7391  * may still processing "upgrade" (exiting). */
7392  if (! used_thr_p_c)
7394  /* Do not use MHD_resume_connection() as mutex is
7395  * already locked. */
7396  susp->resuming = true;
7397  daemon->resuming = true;
7398  }
7399  susp = susp->prev;
7400  }
7401  }
7402  else /* This 'else' is combined with next 'if' */
7403 #endif /* UPGRADE_SUPPORT */
7405  MHD_PANIC (_ (
7406  "MHD_stop_daemon() called while we have suspended connections.\n"));
7407 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
7408 #ifdef MHD_USE_THREADS
7409  if (upg_allowed && used_tls && used_thr_p_c)
7410  {
7411  /* "Upgraded" threads may be running in parallel. Connection will not be
7412  * moved to the "cleanup list" until connection's thread finishes.
7413  * We must ensure that all "upgraded" connections are finished otherwise
7414  * connection may stay in "suspended" list and will not be cleaned. */
7415  for (pos = daemon->suspended_connections_tail; NULL != pos; pos = pos->prev)
7416  {
7417  /* Any connection found here is "upgraded" connection, normal suspended
7418  * connections are already removed from this list. */
7419  mhd_assert (NULL != pos->urh);
7420  if (! pos->thread_joined)
7421  {
7422  /* While "cleanup" list is not manipulated by "upgraded"
7423  * connection, "cleanup" mutex is required for call of
7424  * MHD_resume_connection() during finishing of "upgraded"
7425  * thread. */
7427  if (! MHD_join_thread_ (pos->pid.handle))
7428  MHD_PANIC (_ ("Failed to join a thread.\n"));
7429  pos->thread_joined = true;
7431  }
7432  }
7433  }
7434 #endif /* MHD_USE_THREADS */
7435 #endif
7436  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
7437  {
7438  shutdown (pos->socket_fd,
7439  SHUT_RDWR);
7440 #if MHD_WINSOCK_SOCKETS
7441  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
7442  (MHD_ITC_IS_VALID_ (daemon->itc)) &&
7443  (! MHD_itc_activate_ (daemon->itc, "e")) )
7444  MHD_PANIC (_ (
7445  "Failed to signal shutdown via inter-thread communication channel.\n"));
7446 #endif
7447  }
7448 
7449 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7450  /* now, collect per-connection threads */
7451  if (used_thr_p_c)
7452  {
7453  pos = daemon->connections_tail;
7454  while (NULL != pos)
7455  {
7456  if (! pos->thread_joined)
7457  {
7459  if (! MHD_join_thread_ (pos->pid.handle))
7460  MHD_PANIC (_ ("Failed to join a thread.\n"));
7462  pos->thread_joined = true;
7463  /* The thread may have concurrently modified the DLL,
7464  need to restart from the beginning */
7465  pos = daemon->connections_tail;
7466  continue;
7467  }
7468  pos = pos->prev;
7469  }
7470  }
7472 #endif
7473 
7474 #ifdef UPGRADE_SUPPORT
7475  /* Finished threads with "upgraded" connections need to be moved
7476  * to cleanup list by resume_suspended_connections(). */
7477  /* "Upgraded" connections that were not closed explicitly by
7478  * application should be moved to cleanup list too. */
7479  if (upg_allowed)
7480  {
7481  daemon->resuming = true; /* Force check for pending resume. */
7483  }
7484 #endif /* UPGRADE_SUPPORT */
7485 
7487  /* now that we're alone, move everyone to cleanup */
7488  while (NULL != (pos = daemon->connections_tail))
7489  {
7490 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7491  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
7492  (! pos->thread_joined) )
7493  MHD_PANIC (_ ("Failed to join a thread.\n"));
7494 #endif
7495  close_connection (pos);
7496  }
7498 }
7499 
7500 
7507 void
7509 {
7510  MHD_socket fd;
7511 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7512  unsigned int i;
7513 #endif
7514 
7515  if (NULL == daemon)
7516  return;
7517  if ( (daemon->shutdown) && (NULL == daemon->master) )
7518  MHD_PANIC (_ ("MHD_stop_daemon() was called twice."));
7519  /* Slave daemons must be stopped by master daemon. */
7520  mhd_assert ( (NULL == daemon->master) || (daemon->shutdown) );
7521 
7522  daemon->shutdown = true;
7523  if (daemon->was_quiesced)
7524  fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
7525  else
7526  fd = daemon->listen_fd;
7527 
7528 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7529  if (NULL != daemon->worker_pool)
7530  { /* Master daemon with worker pool. */
7533 
7534  /* Let workers shutdown in parallel. */
7535  for (i = 0; i < daemon->worker_pool_size; ++i)
7536  {
7537  daemon->worker_pool[i].shutdown = true;
7538  if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
7539  {
7540  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
7541  "e"))
7542  MHD_PANIC (_ (
7543  "Failed to signal shutdown via inter-thread communication channel.\n"));
7544  }
7545  else
7547  }
7548 #ifdef HAVE_LISTEN_SHUTDOWN
7549  if (MHD_INVALID_SOCKET != fd)
7550  {
7551  (void) shutdown (fd,
7552  SHUT_RDWR);
7553  }
7554 #endif /* HAVE_LISTEN_SHUTDOWN */
7555  for (i = 0; i < daemon->worker_pool_size; ++i)
7556  {
7558  }
7559  free (daemon->worker_pool);
7561 #ifdef EPOLL_SUPPORT
7562  mhd_assert (-1 == daemon->epoll_fd);
7563 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7564  mhd_assert (-1 == daemon->epoll_upgrade_fd);
7565 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
7566 #endif /* EPOLL_SUPPORT */
7567  }
7568  else
7569 #endif
7570  { /* Worker daemon or single daemon. */
7571 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7573  { /* Worker daemon or single daemon with internal thread(s). */
7575  /* Separate thread(s) is used for polling sockets. */
7576  if (MHD_ITC_IS_VALID_ (daemon->itc))
7577  {
7578  if (! MHD_itc_activate_ (daemon->itc,
7579  "e"))
7580  MHD_PANIC (_ (
7581  "Failed to signal shutdown via inter-thread communication channel.\n"));
7582  }
7583  else
7584  {
7585 #ifdef HAVE_LISTEN_SHUTDOWN
7586  if (MHD_INVALID_SOCKET != fd)
7587  {
7588  if (NULL == daemon->master)
7589  (void) shutdown (fd,
7590  SHUT_RDWR);
7591  }
7592  else
7593 #endif /* HAVE_LISTEN_SHUTDOWN */
7594  mhd_assert (false); /* Should never happen */
7595  }
7596 
7597  if (! MHD_join_thread_ (daemon->pid.handle))
7598  {
7599  MHD_PANIC (_ ("Failed to join a thread.\n"));
7600  }
7601  /* close_all_connections() was called in daemon thread. */
7602  MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
7603  }
7604  else
7605 #endif
7606  {
7607  /* No internal threads are used for polling sockets. */
7609 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7610  MHD_mutex_destroy_chk_ (&daemon->new_connections_mutex);
7611 #endif /* MHD_USE_POSIX_THREADS || MHD_USE_W32_THREADS */
7612  }
7617 #if defined(UPGRADE_SUPPORT) && defined (HTTPS_SUPPORT)
7618  mhd_assert (NULL == daemon->urh_head);
7619 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
7620 
7621  if (MHD_ITC_IS_VALID_ (daemon->itc))
7623 
7624 #ifdef EPOLL_SUPPORT
7625  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
7626  (-1 != daemon->epoll_fd) )
7627  MHD_socket_close_chk_ (daemon->epoll_fd);
7628 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
7629  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
7630  (-1 != daemon->epoll_upgrade_fd) )
7631  MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
7632 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
7633 #endif /* EPOLL_SUPPORT */
7634 
7635 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7637 #endif
7638  }
7639 
7640  if (NULL == daemon->master)
7641  { /* Cleanup that should be done only one time in master/single daemon.
7642  * Do not perform this cleanup in worker daemons. */
7643 
7644  if (MHD_INVALID_SOCKET != fd)
7646 
7647  /* TLS clean up */
7648 #ifdef HTTPS_SUPPORT
7649  if (daemon->have_dhparams)
7650  {
7651  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
7652  daemon->have_dhparams = false;
7653  }
7654  if (0 != (daemon->options & MHD_USE_TLS))
7655  {
7656  gnutls_priority_deinit (daemon->priority_cache);
7657  if (daemon->x509_cred)
7658  gnutls_certificate_free_credentials (daemon->x509_cred);
7659  if (daemon->psk_cred)
7660  gnutls_psk_free_server_credentials (daemon->psk_cred);
7661  }
7662 #endif /* HTTPS_SUPPORT */
7663 
7664 #ifdef DAUTH_SUPPORT
7665  free (daemon->nnc);
7666 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7667  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
7668 #endif
7669 #endif
7670 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7672 #endif
7673  free (daemon);
7674  }
7675 }
7676 
7677 
7689 const union MHD_DaemonInfo *
7691  enum MHD_DaemonInfoType info_type,
7692  ...)
7693 {
7694  if (NULL == daemon)
7695  return NULL;
7696  switch (info_type)
7697  {
7699  return NULL; /* no longer supported */
7701  return NULL; /* no longer supported */
7703  return (const union MHD_DaemonInfo *) &daemon->listen_fd;
7704 #ifdef EPOLL_SUPPORT
7706  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
7707 #endif
7709  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
7710  {
7711  /* Assume that MHD_run() in not called in other thread
7712  * at the same time. */
7713  MHD_cleanup_connections (daemon);
7714  }
7715 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7716  else if (daemon->worker_pool)
7717  {
7718  unsigned int i;
7719  /* Collect the connection information stored in the workers. */
7720  daemon->connections = 0;
7721  for (i = 0; i < daemon->worker_pool_size; i++)
7722  {
7723  /* FIXME: next line is thread-safe only if read is atomic. */
7724  daemon->connections += daemon->worker_pool[i].connections;
7725  }
7726  }
7727 #endif
7728  return (const union MHD_DaemonInfo *) &daemon->connections;
7729  case MHD_DAEMON_INFO_FLAGS:
7730  return (const union MHD_DaemonInfo *) &daemon->options;
7732  return (const union MHD_DaemonInfo *) &daemon->port;
7733  default:
7734  return NULL;
7735  }
7736 }
7737 
7738 
7755 void
7757  void *cls)
7758 {
7759  mhd_panic = cb;
7760  mhd_panic_cls = cls;
7761 }
7762 
7763 
7770 const char *
7772 {
7773 #ifdef PACKAGE_VERSION
7774  return PACKAGE_VERSION;
7775 #else /* !PACKAGE_VERSION */
7776  static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
7777  if (0 == ver[0])
7778  {
7779  int res = MHD_snprintf_ (ver,
7780  sizeof(ver),
7781  "%x.%x.%x",
7782  (((int) MHD_VERSION >> 24) & 0xFF),
7783  (((int) MHD_VERSION >> 16) & 0xFF),
7784  (((int) MHD_VERSION >> 8) & 0xFF));
7785  if ((0 >= res) || (sizeof(ver) <= res))
7786  return "0.0.0"; /* Can't return real version*/
7787  }
7788  return ver;
7789 #endif /* !PACKAGE_VERSION */
7790 }
7791 
7792 
7804 enum MHD_Result
7806 {
7807  switch (feature)
7808  {
7809  case MHD_FEATURE_MESSAGES:
7810 #ifdef HAVE_MESSAGES
7811  return MHD_YES;
7812 #else
7813  return MHD_NO;
7814 #endif
7815  case MHD_FEATURE_TLS:
7816 #ifdef HTTPS_SUPPORT
7817  return MHD_YES;
7818 #else /* ! HTTPS_SUPPORT */
7819  return MHD_NO;
7820 #endif /* ! HTTPS_SUPPORT */
7822 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
7823  return MHD_YES;
7824 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
7825  return MHD_NO;
7826 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
7828 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
7829  return MHD_YES;
7830 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
7831  return MHD_NO;
7832 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
7833  case MHD_FEATURE_IPv6:
7834 #ifdef HAVE_INET6
7835  return MHD_YES;
7836 #else
7837  return MHD_NO;
7838 #endif
7839  case MHD_FEATURE_IPv6_ONLY:
7840 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
7841  return MHD_YES;
7842 #else
7843  return MHD_NO;
7844 #endif
7845  case MHD_FEATURE_POLL:
7846 #ifdef HAVE_POLL
7847  return MHD_YES;
7848 #else
7849  return MHD_NO;
7850 #endif
7851  case MHD_FEATURE_EPOLL:
7852 #ifdef EPOLL_SUPPORT
7853  return MHD_YES;
7854 #else
7855  return MHD_NO;
7856 #endif
7858 #ifdef HAVE_LISTEN_SHUTDOWN
7859  return MHD_YES;
7860 #else
7861  return MHD_NO;
7862 #endif
7864 #ifdef _MHD_ITC_SOCKETPAIR
7865  return MHD_YES;
7866 #else
7867  return MHD_NO;
7868 #endif
7870 #ifdef TCP_FASTOPEN
7871  return MHD_YES;
7872 #else
7873  return MHD_NO;
7874 #endif
7876 #ifdef BAUTH_SUPPORT
7877  return MHD_YES;
7878 #else
7879  return MHD_NO;
7880 #endif
7882 #ifdef DAUTH_SUPPORT
7883  return MHD_YES;
7884 #else
7885  return MHD_NO;
7886 #endif
7888 #ifdef HAVE_POSTPROCESSOR
7889  return MHD_YES;
7890 #else
7891  return MHD_NO;
7892 #endif
7894 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
7895  return MHD_YES;
7896 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
7897  return MHD_NO;
7898 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
7900 #if defined(HAVE_PREAD64) || defined(_WIN32)
7901  return MHD_YES;
7902 #elif defined(HAVE_PREAD)
7903  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
7904 #elif defined(HAVE_LSEEK64)
7905  return MHD_YES;
7906 #else
7907  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
7908 #endif
7910 #if defined(MHD_USE_THREAD_NAME_)
7911  return MHD_YES;
7912 #else
7913  return MHD_NO;
7914 #endif
7915  case MHD_FEATURE_UPGRADE:
7916 #if defined(UPGRADE_SUPPORT)
7917  return MHD_YES;
7918 #else
7919  return MHD_NO;
7920 #endif
7922 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
7923  return MHD_YES;
7924 #else
7925  return MHD_NO;
7926 #endif
7928 #ifdef MHD_USE_GETSOCKNAME
7929  return MHD_YES;
7930 #else
7931  return MHD_NO;
7932 #endif
7934 #if defined(MHD_SEND_SPIPE_SUPPRESS_POSSIBLE) && \
7935  defined(MHD_SEND_SPIPE_SUPPRESS_NEEDED)
7936  return MHD_YES;
7937 #else
7938  return MHD_NO;
7939 #endif
7940  case MHD_FEATURE_SENDFILE:
7941 #ifdef _MHD_HAVE_SENDFILE
7942  return MHD_YES;
7943 #else
7944  return MHD_NO;
7945 #endif
7946  case MHD_FEATURE_THREADS:
7947 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7948  return MHD_YES;
7949 #else
7950  return MHD_NO;
7951 #endif
7952 
7953  }
7954  return MHD_NO;
7955 }
7956 
7957 
7958 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7959 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
7960 #if defined(MHD_USE_POSIX_THREADS)
7961 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7962 #elif defined(MHD_W32_MUTEX_)
7963 
7964 static int
7965 gcry_w32_mutex_init (void **ppmtx)
7966 {
7967  *ppmtx = malloc (sizeof (MHD_mutex_));
7968 
7969  if (NULL == *ppmtx)
7970  return ENOMEM;
7971  if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx))
7972  {
7973  free (*ppmtx);
7974  *ppmtx = NULL;
7975  return EPERM;
7976  }
7977 
7978  return 0;
7979 }
7980 
7981 
7982 static int
7983 gcry_w32_mutex_destroy (void **ppmtx)
7984 {
7985  int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL;
7986  free (*ppmtx);
7987  return res;
7988 }
7989 
7990 
7991 static int
7992 gcry_w32_mutex_lock (void **ppmtx)
7993 {
7994  return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7995 }
7996 
7997 
7998 static int
7999 gcry_w32_mutex_unlock (void **ppmtx)
8000 {
8001  return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
8002 }
8003 
8004 
8005 static struct gcry_thread_cbs gcry_threads_w32 = {
8006  (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
8007  NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
8008  gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
8009  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
8010 };
8011 
8012 #endif /* defined(MHD_W32_MUTEX_) */
8013 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
8014 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
8015 
8019 void
8020 MHD_init (void)
8021 {
8022 #if defined(MHD_WINSOCK_SOCKETS)
8023  WSADATA wsd;
8024 #endif /* MHD_WINSOCK_SOCKETS */
8025 
8026  if (NULL == mhd_panic)
8028 
8029 #if defined(MHD_WINSOCK_SOCKETS)
8030  if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
8031  MHD_PANIC (_ ("Failed to initialize winsock.\n"));
8032  mhd_winsock_inited_ = 1;
8033  if ((2 != LOBYTE (wsd.wVersion)) && (2 != HIBYTE (wsd.wVersion)))
8034  MHD_PANIC (_ ("Winsock version 2.2 is not available.\n"));
8035 #endif /* MHD_WINSOCK_SOCKETS */
8036 #ifdef HTTPS_SUPPORT
8037 #ifdef MHD_HTTPS_REQUIRE_GRYPT
8038 #if GCRYPT_VERSION_NUMBER < 0x010600
8039 #if defined(MHD_USE_POSIX_THREADS)
8040  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
8041  &gcry_threads_pthread))
8042  MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
8043 #elif defined(MHD_W32_MUTEX_)
8044  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
8045  &gcry_threads_w32))
8046  MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt.\n"));
8047 #endif /* defined(MHD_W32_MUTEX_) */
8048  gcry_check_version (NULL);
8049 #else
8050  if (NULL == gcry_check_version ("1.6.0"))
8051  MHD_PANIC (_ (
8052  "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer.\n"));
8053 #endif
8054 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
8055  gnutls_global_init ();
8056 #endif /* HTTPS_SUPPORT */
8060 }
8061 
8062 
8063 void
8064 MHD_fini (void)
8065 {
8066 #ifdef HTTPS_SUPPORT
8067  gnutls_global_deinit ();
8068 #endif /* HTTPS_SUPPORT */
8069 #if defined(MHD_WINSOCK_SOCKETS)
8070  if (mhd_winsock_inited_)
8071  WSACleanup ();
8072 #endif /* MHD_WINSOCK_SOCKETS */
8074 }
8075 
8076 
8077 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
8079 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
8080 
8081 /* end of daemon.c */
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
void MHD_connection_handle_read(struct MHD_Connection *connection)
Definition: connection.c:2818
void MHD_connection_handle_write(struct MHD_Connection *connection)
Definition: connection.c:2936
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:3892
enum MHD_Result MHD_connection_handle_idle(struct MHD_Connection *connection)
Definition: connection.c:3348
Methods for managing connections.
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
#define EXTRA_SLOTS
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
void MHD_set_https_callbacks(struct MHD_Connection *connection)
Methods for managing connections.
void MHD_update_last_activity_(struct MHD_Connection *connection)
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:3136
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:7297
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:260
MHD_PanicCallback mhd_panic
Definition: daemon.c:152
static int get_timeout_millisec_(struct MHD_Daemon *daemon, int32_t max_timeout)
Definition: daemon.c:3887
static enum MHD_Result MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:414
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:3173
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:3038
void MHD_fini(void)
Definition: daemon.c:8064
static enum MHD_Result parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:5508
static enum MHD_Result call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
Definition: daemon.c:1193
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:324
static struct MHD_Connection * new_connection_prepare_(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs, enum MHD_tristate sk_is_nonip)
Definition: daemon.c:2386
volatile int global_init_count
Definition: daemon.c:183
static enum MHD_Result MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:4575
void MHD_check_global_init_(void)
Definition: daemon.c:200
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:5182
static enum MHD_Result MHD_select(struct MHD_Daemon *daemon, int32_t millisec)
Definition: daemon.c:4080
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:344
static void new_connections_list_process_(struct MHD_Daemon *daemon)
Definition: daemon.c:2986
void MHD_init(void)
Definition: daemon.c:8020
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3683
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:5455
static enum MHD_Result MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:3504
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:480
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:77
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
Definition: daemon.c:5298
static enum MHD_Result new_connection_process_(struct MHD_Daemon *daemon, struct MHD_Connection *connection)
Definition: daemon.c:2695
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:308
static enum MHD_Result MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:363
static enum MHD_Result parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:5483
void * mhd_panic_cls
Definition: daemon.c:157
static enum MHD_Result resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3210
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:85
static enum MHD_Result internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck, bool sk_spipe_supprs, enum MHD_tristate sk_is_nonip)
Definition: daemon.c:2899
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:128
_MHD_EXTERN void MHD_free(void *ptr)
Definition: daemon.c:246
static enum MHD_Result internal_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: daemon.c:978
static enum MHD_Result internal_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
Definition: daemon.c:3916
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
Definition: daemon_start.c:619
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
Definition: daemon.c:5330
_MHD_EXTERN enum MHD_Result MHD_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd)
Definition: daemon.c:725
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:7508
_MHD_EXTERN enum MHD_Result MHD_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
Definition: daemon.c:4024
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon_va(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls, va_list ap)
Definition: daemon.c:6262
_MHD_EXTERN enum MHD_Result MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:5096
_MHD_EXTERN enum MHD_Result MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:3794
_MHD_EXTERN enum MHD_Result MHD_run_wait(struct MHD_Daemon *daemon, int32_t millisec)
Definition: daemon.c:5136
_MHD_EXTERN enum MHD_Result MHD_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: daemon.c:1127
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
Definition: microhttpd.h:2168
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
Definition: panic.c:56
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
Definition: microhttpd.h:2276
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:2250
@ MHD_CONNECTION_NOTIFY_STARTED
Definition: microhttpd.h:1915
@ MHD_CONNECTION_NOTIFY_CLOSED
Definition: microhttpd.h:1921
@ MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN
Definition: microhttpd.h:1880
@ MHD_REQUEST_TERMINATED_COMPLETED_OK
Definition: microhttpd.h:1857
@ MHD_REQUEST_TERMINATED_WITH_ERROR
Definition: microhttpd.h:1865
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1397
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:7690
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:5375
_MHD_EXTERN enum MHD_Result MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:3370
_MHD_EXTERN enum MHD_Result MHD_is_feature_supported(enum MHD_FEATURE feature)
Definition: daemon.c:7805
_MHD_EXTERN const char * MHD_get_version(void)
Definition: version.c:35
#define XDLL_insert(head, tail, element)
Definition: internal.h:1786
@ MHD_EPOLL_STATE_SUSPENDED
Definition: internal.h:621
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
Definition: internal.h:611
@ MHD_EPOLL_STATE_READ_READY
Definition: internal.h:600
@ MHD_EPOLL_STATE_IN_EPOLL_SET
Definition: internal.h:616
@ MHD_EPOLL_STATE_WRITE_READY
Definition: internal.h:606
@ MHD_EPOLL_STATE_ERROR
Definition: internal.h:626
#define DLL_insert(head, tail, element)
Definition: internal.h:1743
#define EDLL_insert(head, tail, element)
Definition: internal.h:1829
#define MHD_PANIC(msg)
Definition: internal.h:69
#define MHD_BUF_INC_SIZE
Definition: internal.h:120
#define EDLL_remove(head, tail, element)
Definition: internal.h:1847
#define XDLL_remove(head, tail, element)
Definition: internal.h:1806
#define DLL_remove(head, tail, element)
Definition: internal.h:1763
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:157
struct MemoryPool * MHD_pool_create(size_t max)
Definition: memorypool.c:102
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
void * MHD_calloc_(size_t nelem, size_t elsize)
Definition: mhd_compat.c:98
#define MHD_strerror_(errnum)
Definition: mhd_compat.h:44
#define MHD_ITC_IS_INVALID_(itc)
Definition: mhd_itc.h:367
#define MHD_itc_destroy_chk_(itc)
Definition: mhd_itc.h:353
#define MHD_TYPE_IS_SIGNED_(type)
Definition: mhd_limits.h:39
#define SIZE_MAX
Definition: mhd_limits.h:99
#define ULLONG_MAX
Definition: mhd_limits.h:58
#define TIMEVAL_TV_SEC_MAX
Definition: mhd_limits.h:140
#define UINT_MAX
Definition: mhd_limits.h:45
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:180
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:121
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:154
void MHD_monotonic_sec_counter_finish(void)
time_t MHD_monotonic_sec_counter(void)
void MHD_monotonic_sec_counter_init(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: mhd_sockets.c:377
int MHD_socket_noninheritable_(MHD_socket sock)
Definition: mhd_sockets.c:442
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:407
MHD_socket MHD_socket_create_listen_(int pf)
Definition: mhd_sockets.c:474
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
Definition: mhd_sockets.h:675
#define MHD_SCKT_ERR_IS_(err, code)
Definition: mhd_sockets.h:611
int MHD_SCKT_OPT_BOOL_
Definition: mhd_sockets.h:203
#define MHD_socket_close_(fd)
Definition: mhd_sockets.h:238
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
Definition: mhd_sockets.h:643
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
Definition: mhd_sockets.h:656
#define MHD_SCKT_EINTR_
Definition: mhd_sockets.h:414
#define _MHD_SYS_DEFAULT_FD_SETSIZE
Definition: mhd_sockets.h:126
#define MHD_socket_strerr_(err)
Definition: mhd_sockets.h:542
#define MHD_socket_last_strerr_()
Definition: mhd_sockets.h:549
#define MHD_socket_get_error_()
Definition: mhd_sockets.h:523
#define MHD_SCKT_EINVAL_
Definition: mhd_sockets.h:464
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:248
#define MHD_SCKT_ERR_IS_EINTR_(err)
Definition: mhd_sockets.h:634
#define MHD_socket_fset_error_(err)
Definition: mhd_sockets.h:555
#define MHD_SCKT_SEND_MAX_SIZE_
Definition: mhd_sockets.h:222
#define MHD_recv_(s, b, l)
Definition: mhd_sockets.h:273
#define MHD_send_(s, b, l)
Definition: mhd_sockets.h:261
#define MHD_SCKT_LAST_ERR_IS_(code)
Definition: mhd_sockets.h:623
#define MHD_SYS_select_(n, r, w, e, t)
Definition: mhd_sockets.h:336
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
Definition: mhd_sockets.h:309
#define MHD_STATICSTR_LEN_(macro)
Definition: mhd_str.h:45
#define MHD_create_named_thread_(t, n, s, r, a)
Definition: mhd_threads.h:216
#define NULL
Definition: reason_phrase.c:30
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:27
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:63
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:95
#define _(String)
Definition: mhd_options.h:42
#define _MHD_EXTERN
Definition: mhd_options.h:50
void MHD_send_init_static_vars_(void)
Definition: mhd_send.c:153
Declarations of send() wrappers.
internal shared structures
@ MHD_CONNECTION_HEADERS_SENDING
Definition: internal.h:596
@ MHD_CONNECTION_INIT
Definition: internal.h:543
@ MHD_CONNECTION_CLOSED
Definition: internal.h:642
@ MHD_CONNECTION_NORMAL_BODY_READY
Definition: internal.h:606
@ MHD_CONNECTION_CHUNKED_BODY_READY
Definition: internal.h:617
@ MHD_TLS_CONN_INIT
Definition: internal.h:661
@ MHD_EVENT_LOOP_INFO_READ
Definition: internal.h:237
@ MHD_EVENT_LOOP_INFO_WRITE
Definition: internal.h:242
@ MHD_EVENT_LOOP_INFO_CLEANUP
Definition: internal.h:252
@ MHD_EVENT_LOOP_INFO_BLOCK
Definition: internal.h:247
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:1366
#define MHD_TEST_ALLOW_SUSPEND_RESUME
Definition: internal.h:260
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:1380
MHD_tristate
Definition: internal.h:174
@ _MHD_UNKNOWN
Definition: internal.h:175
@ _MHD_YES
Definition: internal.h:179
@ _MHD_OFF
Definition: internal.h:176
@ _MHD_NO
Definition: internal.h:177
void MHD_init_mem_pools_(void)
Definition: memorypool.c:85
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...
Header for platform missing functions.
Header for platform-independent inter-thread communication.
limits values definitions
#define SSIZE_MAX
Definition: mhd_limits.h:111
#define MHD_mutex_destroy_(ignore)
Definition: mhd_locks.h:190
#define MHD_mutex_unlock_(ignore)
Definition: mhd_locks.h:194
#define MHD_mutex_lock_(ignore)
Definition: mhd_locks.h:192
#define MHD_mutex_init_(ignore)
Definition: mhd_locks.h:189
internal monotonic clock functions implementations
#define SOCK_NONBLOCK_OR_ZERO
Definition: mhd_sockets.h:172
#define SOCK_NOSIGPIPE_OR_ZERO
Definition: mhd_sockets.h:178
#define SOCK_CLOEXEC_OR_ZERO
Definition: mhd_sockets.h:166
int MHD_socket
Definition: microhttpd.h:193
MHD_FEATURE
Definition: microhttpd.h:4003
@ MHD_FEATURE_POSTPROCESSOR
Definition: microhttpd.h:4094
@ MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET
Definition: microhttpd.h:4058
@ MHD_FEATURE_THREADS
Definition: microhttpd.h:4162
@ MHD_FEATURE_SENDFILE
Definition: microhttpd.h:4157
@ MHD_FEATURE_AUTODETECT_BIND_PORT
Definition: microhttpd.h:4143
@ MHD_FEATURE_LARGE_FILE
Definition: microhttpd.h:4111
@ MHD_FEATURE_HTTPS_CERT_CALLBACK
Definition: microhttpd.h:4024
@ MHD_FEATURE_BASIC_AUTH
Definition: microhttpd.h:4078
@ MHD_FEATURE_DIGEST_AUTH
Definition: microhttpd.h:4086
@ MHD_FEATURE_IPv6
Definition: microhttpd.h:4030
@ MHD_FEATURE_POLL
Definition: microhttpd.h:4044
@ MHD_FEATURE_THREAD_NAMES
Definition: microhttpd.h:4116
@ MHD_FEATURE_EPOLL
Definition: microhttpd.h:4051
@ MHD_FEATURE_TLS
Definition: microhttpd.h:4017
@ MHD_FEATURE_HTTPS_KEY_PASSWORD
Definition: microhttpd.h:4101
@ MHD_FEATURE_AUTOSUPPRESS_SIGPIPE
Definition: microhttpd.h:4150
@ MHD_FEATURE_RESPONSES_SHARED_FD
Definition: microhttpd.h:4137
@ MHD_FEATURE_MESSAGES
Definition: microhttpd.h:4008
@ MHD_FEATURE_IPv6_ONLY
Definition: microhttpd.h:4038
@ MHD_FEATURE_UPGRADE
Definition: microhttpd.h:4124
@ MHD_FEATURE_SOCKETPAIR
Definition: microhttpd.h:4064
@ MHD_FEATURE_TCP_FASTOPEN
Definition: microhttpd.h:4071
@ MHD_FEATURE_HTTPS_CERT_CALLBACK2
Definition: microhttpd.h:4168
MHD_OPTION
MHD options.
Definition: microhttpd.h:1379
@ MHD_OPTION_CONNECTION_MEMORY_INCREMENT
Definition: microhttpd.h:1615
@ MHD_OPTION_HTTPS_CRED_TYPE
Definition: microhttpd.h:1496
@ MHD_OPTION_URI_LOG_CALLBACK
Definition: microhttpd.h:1473
@ MHD_OPTION_HTTPS_CERT_CALLBACK2
Definition: microhttpd.h:1719
@ MHD_OPTION_SIGPIPE_HANDLED_BY_APP
Definition: microhttpd.h:1741
@ MHD_OPTION_UNESCAPE_CALLBACK
Definition: microhttpd.h:1578
@ MHD_OPTION_EXTERNAL_LOGGER
Definition: microhttpd.h:1525
@ MHD_OPTION_TLS_NO_ALPN
Definition: microhttpd.h:1750
@ MHD_OPTION_LISTEN_BACKLOG_SIZE
Definition: microhttpd.h:1684
@ MHD_OPTION_HTTPS_PRIORITIES
Definition: microhttpd.h:1502
@ MHD_OPTION_HTTPS_MEM_DHPARAMS
Definition: microhttpd.h:1647
@ MHD_OPTION_NOTIFY_CONNECTION
Definition: microhttpd.h:1676
@ MHD_OPTION_LISTENING_ADDRESS_REUSE
Definition: microhttpd.h:1656
@ MHD_OPTION_THREAD_POOL_SIZE
Definition: microhttpd.h:1535
@ MHD_OPTION_CONNECTION_LIMIT
Definition: microhttpd.h:1400
@ MHD_OPTION_PER_IP_CONNECTION_LIMIT
Definition: microhttpd.h:1433
@ MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE
Definition: microhttpd.h:1640
@ MHD_OPTION_HTTPS_MEM_CERT
Definition: microhttpd.h:1489
@ MHD_OPTION_SERVER_INSANITY
Definition: microhttpd.h:1730
@ MHD_OPTION_LISTEN_SOCKET
Definition: microhttpd.h:1510
@ MHD_OPTION_HTTPS_MEM_KEY
Definition: microhttpd.h:1481
@ MHD_OPTION_DIGEST_AUTH_RANDOM
Definition: microhttpd.h:1589
@ MHD_OPTION_HTTPS_KEY_PASSWORD
Definition: microhttpd.h:1665
@ MHD_OPTION_NONCE_NC_SIZE
Definition: microhttpd.h:1596
@ MHD_OPTION_CONNECTION_MEMORY_LIMIT
Definition: microhttpd.h:1394
@ MHD_OPTION_THREAD_STACK_SIZE
Definition: microhttpd.h:1602
@ MHD_OPTION_ARRAY
Definition: microhttpd.h:1556
@ MHD_OPTION_STRICT_FOR_CLIENT
Definition: microhttpd.h:1700
@ MHD_OPTION_SOCK_ADDR
Definition: microhttpd.h:1441
@ MHD_OPTION_CONNECTION_TIMEOUT
Definition: microhttpd.h:1407
@ MHD_OPTION_GNUTLS_PSK_CRED_HANDLER
Definition: microhttpd.h:1708
@ MHD_OPTION_END
Definition: microhttpd.h:1385
@ MHD_OPTION_HTTPS_MEM_TRUST
Definition: microhttpd.h:1609
@ MHD_OPTION_HTTPS_CERT_CALLBACK
Definition: microhttpd.h:1631
@ MHD_OPTION_NOTIFY_COMPLETED
Definition: microhttpd.h:1421
MHD_DisableSanityCheck
Definition: microhttpd.h:1759
MHD_Result
Definition: microhttpd.h:139
@ MHD_YES
Definition: microhttpd.h:148
@ MHD_NO
Definition: microhttpd.h:143
enum MHD_Result(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Definition: microhttpd.h:2182
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:296
#define MHD_UNSIGNED_LONG_LONG_PRINTF
Definition: microhttpd.h:310
int fd
Definition: microhttpd.h:3269
void * data
Definition: microhttpd.h:3125
_MHD_EXTERN size_t MHD_http_unescape(char *val)
Definition: internal.c:142
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:194
enum MHD_Result(* MHD_AccessHandlerCallback)(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
Definition: microhttpd.h:2227
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
Definition: microhttpd.h:1367
#define MHD_VERSION
Definition: microhttpd.h:133
MHD_DaemonInfoType
Definition: microhttpd.h:2104
@ MHD_DAEMON_INFO_MAC_KEY_SIZE
Definition: microhttpd.h:2113
@ MHD_DAEMON_INFO_BIND_PORT
Definition: microhttpd.h:2153
@ MHD_DAEMON_INFO_EPOLL_FD
Definition: microhttpd.h:2128
@ MHD_DAEMON_INFO_FLAGS
Definition: microhttpd.h:2145
@ MHD_DAEMON_INFO_KEY_SIZE
Definition: microhttpd.h:2108
@ MHD_DAEMON_INFO_CURRENT_CONNECTIONS
Definition: microhttpd.h:2137
@ MHD_DAEMON_INFO_LISTEN_FD
Definition: microhttpd.h:2119
MHD_FLAG
Flags for the struct MHD_Daemon.
Definition: microhttpd.h:1050
@ MHD_USE_EPOLL
Definition: microhttpd.h:1193
@ MHD_ALLOW_SUSPEND_RESUME
Definition: microhttpd.h:1279
@ MHD_USE_TCP_FASTOPEN
Definition: microhttpd.h:1295
@ MHD_USE_THREAD_PER_CONNECTION
Definition: microhttpd.h:1087
@ MHD_USE_AUTO
Definition: microhttpd.h:1315
@ MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT
Definition: microhttpd.h:1329
@ MHD_USE_TURBO
Definition: microhttpd.h:1264
@ MHD_USE_IPv6
Definition: microhttpd.h:1116
@ MHD_USE_DUAL_STACK
Definition: microhttpd.h:1256
@ MHD_USE_POLL
Definition: microhttpd.h:1143
@ MHD_USE_TLS
Definition: microhttpd.h:1072
@ MHD_USE_INSECURE_TLS_EARLY_DATA
Definition: microhttpd.h:1335
@ MHD_ALLOW_UPGRADE
Definition: microhttpd.h:1302
@ MHD_USE_NO_LISTEN_SOCKET
Definition: microhttpd.h:1184
@ MHD_USE_PEDANTIC_CHECKS
Definition: microhttpd.h:1127
@ MHD_USE_INTERNAL_POLLING_THREAD
Definition: microhttpd.h:1098
@ MHD_USE_ITC
Definition: microhttpd.h:1242
platform-specific includes for libmicrohttpd
time_t _MHD_TIMEVAL_TV_SEC_TYPE
Definition: platform.h:122
Methods for managing response objects.
MHD_socket socket_fd
Definition: internal.h:752
enum MHD_tristate sk_nodelay
Definition: internal.h:1025
struct MHD_Connection * prevX
Definition: internal.h:670
socklen_t addr_len
Definition: internal.h:733
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:1069
enum MHD_tristate is_nonip
Definition: internal.h:1005
bool tls_read_ready
Definition: internal.h:769
void * socket_context
Definition: internal.h:694
bool suspended
Definition: internal.h:764
struct MHD_Response * response
Definition: internal.h:796
bool sk_nonblck
Definition: internal.h:784
struct MHD_Connection * next
Definition: internal.h:651
time_t connection_timeout
Definition: internal.h:745
struct sockaddr_storage addr
Definition: internal.h:728
struct MemoryPool * pool
Definition: internal.h:685
size_t read_buffer_offset
Definition: internal.h:905
struct MHD_Connection * prev
Definition: internal.h:656
bool client_aware
Definition: internal.h:992
MHD_thread_handle_ID_ pid
Definition: internal.h:723
struct MHD_Connection * nextX
Definition: internal.h:665
time_t last_activity
Definition: internal.h:739
void * client_context
Definition: internal.h:814
enum MHD_CONNECTION_STATE state
Definition: internal.h:1064
struct MHD_Daemon * daemon
Definition: internal.h:675
bool sk_spipe_suppress
Definition: internal.h:1015
size_t read_buffer_size
Definition: internal.h:899
enum MHD_tristate sk_corked
Definition: internal.h:1020
bool thread_joined
Definition: internal.h:779
size_t pool_size
Definition: internal.h:1662
MHD_NotifyConnectionCallback notify_connection
Definition: internal.h:1574
MHD_AccessHandlerCallback default_handler
Definition: internal.h:1398
LogCallback uri_log_callback
Definition: internal.h:1588
bool data_already_pending
Definition: internal.h:1500
MHD_mutex_ per_ip_connection_mutex
Definition: internal.h:1259
void * per_ip_connection_count
Definition: internal.h:1187
bool at_limit
Definition: internal.h:1483
struct MHD_Connection * new_connections_tail
Definition: internal.h:1421
uint16_t port
Definition: internal.h:1611
bool was_quiesced
Definition: internal.h:1505
unsigned int connection_limit
Definition: internal.h:1772
void * unescape_callback_cls
Definition: internal.h:1603
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1265
enum MHD_DisableSanityCheck insanity_level
Definition: internal.h:1706
struct MHD_Connection * connections_head
Definition: internal.h:1155
unsigned int listen_backlog_size
Definition: internal.h:1943
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:1563
unsigned int worker_pool_size
Definition: internal.h:1366
unsigned int connections
Definition: internal.h:1361
struct MHD_itc_ itc
Definition: internal.h:1410
int listening_address_reuse
Definition: internal.h:1717
void * apc_cls
Definition: internal.h:1557
unsigned int per_ip_connection_limit
Definition: internal.h:1784
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:1150
volatile bool shutdown
Definition: internal.h:1526
enum MHD_FLAG options
Definition: internal.h:1411
void * notify_connection_cls
Definition: internal.h:1579
bool sigpipe_blocked
Definition: internal.h:1794
UnescapeCallback unescape_callback
Definition: internal.h:1598
void * notify_completed_cls
Definition: internal.h:1568
struct MHD_Connection * cleanup_tail
Definition: internal.h:1182
size_t num_opts
Definition: internal.h:1952
bool resuming
Definition: internal.h:1510
struct MHD_Daemon * worker_pool
Definition: internal.h:1073
struct MHD_Connection * new_connections_head
Definition: internal.h:1416
MHD_thread_handle_ID_ pid
Definition: internal.h:1249
struct MHD_Connection * manual_timeout_head
Definition: internal.h:1143
enum MHD_tristate listen_is_unix
Definition: internal.h:1456
void * default_handler_cls
Definition: internal.h:1403
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:1172
time_t connection_timeout
Definition: internal.h:1778
MHD_AcceptPolicyCallback apc
Definition: internal.h:1552
struct MHD_Connection * cleanup_head
Definition: internal.h:1177
struct MHD_Daemon * master
Definition: internal.h:1068
struct MHD_Connection * normal_timeout_head
Definition: internal.h:1128
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:1135
volatile bool have_new
Definition: internal.h:1756
size_t pool_increment
Definition: internal.h:1667
MHD_socket listen_fd
Definition: internal.h:1637
void * uri_log_callback_cls
Definition: internal.h:1593
struct MHD_Connection * suspended_connections_head
Definition: internal.h:1166
struct MHD_Connection * connections_tail
Definition: internal.h:1160
int strict_for_client
Definition: internal.h:1789
intptr_t value
Definition: microhttpd.h:1784
enum MHD_OPTION option
Definition: microhttpd.h:1777
void * ptr_value
Definition: microhttpd.h:1790