GNU libmicrohttpd  0.9.63
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 
46 #if HAVE_SEARCH_H
47 #include <search.h>
48 #else
49 #include "tsearch.h"
50 #endif
51 
52 #ifdef HTTPS_SUPPORT
53 #include "connection_https.h"
54 #ifdef MHD_HTTPS_REQUIRE_GRYPT
55 #include <gcrypt.h>
56 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
57 #endif /* HTTPS_SUPPORT */
58 
59 #if defined(_WIN32) && ! defined(__CYGWIN__)
60 #ifndef WIN32_LEAN_AND_MEAN
61 #define WIN32_LEAN_AND_MEAN 1
62 #endif /* !WIN32_LEAN_AND_MEAN */
63 #include <windows.h>
64 #endif
65 
69 #ifdef MHD_POSIX_SOCKETS
70 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
71 #else
72 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
73 #endif
74 
78 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
79 
84 #define DEBUG_CLOSE MHD_NO
85 
90 #define DEBUG_CONNECT MHD_NO
91 
92 
93 /* Forward declarations. */
94 
103 static void
104 close_all_connections (struct MHD_Daemon *daemon);
105 
106 #ifdef EPOLL_SUPPORT
107 
116 static int
117 MHD_epoll (struct MHD_Daemon *daemon,
118  int may_block);
119 
120 #endif /* EPOLL_SUPPORT */
121 
131 static void
132 mhd_panic_std (void *cls,
133  const char *file,
134  unsigned int line,
135  const char *reason)
136 {
137  (void)cls; /* Mute compiler warning. */
138 #ifdef HAVE_MESSAGES
139  fprintf (stderr,
140  _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
141  file,
142  line,
143  reason);
144 #else /* ! HAVE_MESSAGES */
145  (void)file; /* Mute compiler warning. */
146  (void)line; /* Mute compiler warning. */
147  (void)reason; /* Mute compiler warning. */
148 #endif
149  abort ();
150 }
151 
152 
157 
162 
166 void
167 MHD_init(void);
168 
169 
170 #if defined(_WIN32) && ! defined(__CYGWIN__)
171 
174 static int mhd_winsock_inited_ = 0;
175 #endif
176 
177 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
178 
182 #define MHD_check_global_init_() (void)0
183 #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
184 
187 volatile int global_init_count = 0;
188 
189 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
190 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
191 
194 MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
195 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
196 #endif
197 
198 
203 void
205 {
206 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
207 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
208  MHD_mutex_lock_chk_(&global_init_mutex_);
209 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
210 #endif
211  if (0 == global_init_count++)
212  MHD_init ();
213 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
214 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
215  MHD_mutex_unlock_chk_(&global_init_mutex_);
216 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
217 #endif
218 }
219 #endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
220 
228 static struct MHD_Daemon*
229 MHD_get_master (struct MHD_Daemon *daemon)
230 {
231  while (NULL != daemon->master)
232  daemon = daemon->master;
233  return daemon;
234 }
235 
236 
240 struct MHD_IPCount
241 {
245  int family;
246 
250  union
251  {
255  struct in_addr ipv4;
256 #if HAVE_INET6
257 
260  struct in6_addr ipv6;
261 #endif
262  } addr;
263 
267  unsigned int count;
268 };
269 
270 
276 static void
278 {
279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
281 #else
282  (void) daemon;
283 #endif
284 }
285 
286 
292 static void
294 {
295 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
297 #else
298  (void) daemon;
299 #endif
300 }
301 
302 
312 static int
313 MHD_ip_addr_compare (const void *a1,
314  const void *a2)
315 {
316  return memcmp (a1,
317  a2,
318  offsetof (struct MHD_IPCount,
319  count));
320 }
321 
322 
331 static int
332 MHD_ip_addr_to_key (const struct sockaddr *addr,
333  socklen_t addrlen,
334  struct MHD_IPCount *key)
335 {
336  memset(key,
337  0,
338  sizeof(*key));
339 
340  /* IPv4 addresses */
341  if (sizeof (struct sockaddr_in) == addrlen)
342  {
343  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
344 
345  key->family = AF_INET;
346  memcpy (&key->addr.ipv4,
347  &addr4->sin_addr,
348  sizeof(addr4->sin_addr));
349  return MHD_YES;
350  }
351 
352 #if HAVE_INET6
353  /* IPv6 addresses */
354  if (sizeof (struct sockaddr_in6) == addrlen)
355  {
356  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
357 
358  key->family = AF_INET6;
359  memcpy (&key->addr.ipv6,
360  &addr6->sin6_addr,
361  sizeof(addr6->sin6_addr));
362  return MHD_YES;
363  }
364 #endif
365 
366  /* Some other address */
367  return MHD_NO;
368 }
369 
370 
382 static int
383 MHD_ip_limit_add (struct MHD_Daemon *daemon,
384  const struct sockaddr *addr,
385  socklen_t addrlen)
386 {
387  struct MHD_IPCount *key;
388  void **nodep;
389  void *node;
390  int result;
391 
392  daemon = MHD_get_master (daemon);
393  /* Ignore if no connection limit assigned */
394  if (0 == daemon->per_ip_connection_limit)
395  return MHD_YES;
396 
397  if (NULL == (key = malloc (sizeof(*key))))
398  return MHD_NO;
399 
400  /* Initialize key */
401  if (MHD_NO == MHD_ip_addr_to_key (addr,
402  addrlen,
403  key))
404  {
405  /* Allow unhandled address types through */
406  free (key);
407  return MHD_YES;
408  }
409  MHD_ip_count_lock (daemon);
410 
411  /* Search for the IP address */
412  if (NULL == (nodep = tsearch (key,
413  &daemon->per_ip_connection_count,
415  {
416 #ifdef HAVE_MESSAGES
417  MHD_DLOG (daemon,
418  _("Failed to add IP connection count node\n"));
419 #endif
420  MHD_ip_count_unlock (daemon);
421  free (key);
422  return MHD_NO;
423  }
424  node = *nodep;
425  /* If we got an existing node back, free the one we created */
426  if (node != key)
427  free(key);
428  key = (struct MHD_IPCount *) node;
429  /* Test if there is room for another connection; if so,
430  * increment count */
431  result = (key->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO;
432  if (MHD_YES == result)
433  ++key->count;
434 
435  MHD_ip_count_unlock (daemon);
436  return result;
437 }
438 
439 
448 static void
449 MHD_ip_limit_del (struct MHD_Daemon *daemon,
450  const struct sockaddr *addr,
451  socklen_t addrlen)
452 {
453  struct MHD_IPCount search_key;
454  struct MHD_IPCount *found_key;
455  void **nodep;
456 
457  daemon = MHD_get_master (daemon);
458  /* Ignore if no connection limit assigned */
459  if (0 == daemon->per_ip_connection_limit)
460  return;
461  /* Initialize search key */
462  if (MHD_NO == MHD_ip_addr_to_key (addr,
463  addrlen,
464  &search_key))
465  return;
466 
467  MHD_ip_count_lock (daemon);
468 
469  /* Search for the IP address */
470  if (NULL == (nodep = tfind (&search_key,
471  &daemon->per_ip_connection_count,
473  {
474  /* Something's wrong if we couldn't find an IP address
475  * that was previously added */
476  MHD_PANIC (_("Failed to find previously-added IP address\n"));
477  }
478  found_key = (struct MHD_IPCount *) *nodep;
479  /* Validate existing count for IP address */
480  if (0 == found_key->count)
481  {
482  MHD_PANIC (_("Previously-added IP address had counter of zero\n"));
483  }
484  /* Remove the node entirely if count reduces to 0 */
485  if (0 == --found_key->count)
486  {
487  tdelete (found_key,
488  &daemon->per_ip_connection_count,
490  free (found_key);
491  }
492 
493  MHD_ip_count_unlock (daemon);
494 }
495 
496 
497 #ifdef HTTPS_SUPPORT
498 
504 static int
505 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
506 {
507  gnutls_datum_t key;
508  gnutls_datum_t cert;
509  int ret;
510 
511 #if GNUTLS_VERSION_MAJOR >= 3
512  if (NULL != daemon->cert_callback)
513  {
514  gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
515  daemon->cert_callback);
516  }
517 #endif
518  if (NULL != daemon->https_mem_trust)
519  {
520  cert.data = (unsigned char *) daemon->https_mem_trust;
521  cert.size = strlen (daemon->https_mem_trust);
522  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
523  &cert,
524  GNUTLS_X509_FMT_PEM) < 0)
525  {
526 #ifdef HAVE_MESSAGES
527  MHD_DLOG(daemon,
528  "Bad trust certificate format\n");
529 #endif
530  return -1;
531  }
532  }
533 
534  if (daemon->have_dhparams)
535  {
536  gnutls_certificate_set_dh_params (daemon->x509_cred,
537  daemon->https_mem_dhparams);
538  }
539  /* certificate & key loaded from memory */
540  if ( (NULL != daemon->https_mem_cert) &&
541  (NULL != daemon->https_mem_key) )
542  {
543  key.data = (unsigned char *) daemon->https_mem_key;
544  key.size = strlen (daemon->https_mem_key);
545  cert.data = (unsigned char *) daemon->https_mem_cert;
546  cert.size = strlen (daemon->https_mem_cert);
547 
548  if (NULL != daemon->https_key_password) {
549 #if GNUTLS_VERSION_NUMBER >= 0x030111
550  ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
551  &cert,
552  &key,
553  GNUTLS_X509_FMT_PEM,
554  daemon->https_key_password,
555  0);
556 #else
557 #ifdef HAVE_MESSAGES
558  MHD_DLOG (daemon,
559  _("Failed to setup x509 certificate/key: pre 3.X.X version " \
560  "of GnuTLS does not support setting key password"));
561 #endif
562  return -1;
563 #endif
564  }
565  else
566  ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
567  &cert,
568  &key,
569  GNUTLS_X509_FMT_PEM);
570 #ifdef HAVE_MESSAGES
571  if (0 != ret)
572  MHD_DLOG (daemon,
573  "GnuTLS failed to setup x509 certificate/key: %s\n",
574  gnutls_strerror (ret));
575 #endif
576  return ret;
577  }
578 #if GNUTLS_VERSION_MAJOR >= 3
579  if (NULL != daemon->cert_callback)
580  return 0;
581 #endif
582 #ifdef HAVE_MESSAGES
583  MHD_DLOG (daemon,
584  "You need to specify a certificate and key location\n");
585 #endif
586  return -1;
587 }
588 
595 static int
596 MHD_TLS_init (struct MHD_Daemon *daemon)
597 {
598  switch (daemon->cred_type)
599  {
600  case GNUTLS_CRD_CERTIFICATE:
601  if (0 !=
602  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
603  return GNUTLS_E_MEMORY_ERROR;
604  return MHD_init_daemon_certificate (daemon);
605  case GNUTLS_CRD_PSK:
606  if (0 !=
607  gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
608  return GNUTLS_E_MEMORY_ERROR;
609  return 0;
610  default:
611 #ifdef HAVE_MESSAGES
612  MHD_DLOG (daemon,
613  _("Error: invalid credentials type %d specified.\n"),
614  daemon->cred_type);
615 #endif
616  return -1;
617  }
618 }
619 #endif /* HTTPS_SUPPORT */
620 
621 
622 #undef MHD_get_fdset
623 
653 int
654 MHD_get_fdset (struct MHD_Daemon *daemon,
655  fd_set *read_fd_set,
656  fd_set *write_fd_set,
657  fd_set *except_fd_set,
658  MHD_socket *max_fd)
659 {
660  return MHD_get_fdset2 (daemon,
661  read_fd_set,
662  write_fd_set,
663  except_fd_set,
664  max_fd,
666 }
667 
668 
669 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
670 
682 static bool
683 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
684  fd_set *rs,
685  fd_set *ws,
686  fd_set *es,
687  MHD_socket *max_fd,
688  unsigned int fd_setsize)
689 {
690  const MHD_socket conn_sckt = urh->connection->socket_fd;
691  const MHD_socket mhd_sckt = urh->mhd.socket;
692  bool res = true;
693 
694  /* Do not add to 'es' only if socket is closed
695  * or not used anymore. */
696  if (MHD_INVALID_SOCKET != conn_sckt)
697  {
698  if ( (urh->in_buffer_used < urh->in_buffer_size) &&
699  (! MHD_add_to_fd_set_ (conn_sckt,
700  rs,
701  max_fd,
702  fd_setsize)) )
703  res = false;
704  if ( (0 != urh->out_buffer_used) &&
705  (! MHD_add_to_fd_set_ (conn_sckt,
706  ws,
707  max_fd,
708  fd_setsize)) )
709  res = false;
710  /* Do not monitor again for errors if error was detected before as
711  * error state is remembered. */
712  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
713  ((0 != urh->in_buffer_size) ||
714  (0 != urh->out_buffer_size) ||
715  (0 != urh->out_buffer_used)))
716  MHD_add_to_fd_set_ (conn_sckt,
717  es,
718  max_fd,
719  fd_setsize);
720  }
721  if (MHD_INVALID_SOCKET != mhd_sckt)
722  {
723  if ( (urh->out_buffer_used < urh->out_buffer_size) &&
724  (! MHD_add_to_fd_set_ (mhd_sckt,
725  rs,
726  max_fd,
727  fd_setsize)) )
728  res = false;
729  if ( (0 != urh->in_buffer_used) &&
730  (! MHD_add_to_fd_set_ (mhd_sckt,
731  ws,
732  max_fd,
733  fd_setsize)) )
734  res = false;
735  /* Do not monitor again for errors if error was detected before as
736  * error state is remembered. */
737  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
738  ((0 != urh->out_buffer_size) ||
739  (0 != urh->in_buffer_size) ||
740  (0 != urh->in_buffer_used)))
741  MHD_add_to_fd_set_ (mhd_sckt,
742  es,
743  max_fd,
744  fd_setsize);
745  }
746 
747  return res;
748 }
749 
750 
760 static void
761 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
762  const fd_set *rs,
763  const fd_set *ws,
764  const fd_set *es)
765 {
766  const MHD_socket conn_sckt = urh->connection->socket_fd;
767  const MHD_socket mhd_sckt = urh->mhd.socket;
768 
769  /* Reset read/write ready, preserve error state. */
772 
773  if (MHD_INVALID_SOCKET != conn_sckt)
774  {
775  if (FD_ISSET (conn_sckt, rs))
776  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
777  if (FD_ISSET (conn_sckt, ws))
778  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
779  if (FD_ISSET (conn_sckt, es))
780  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
781  }
782  if ((MHD_INVALID_SOCKET != mhd_sckt))
783  {
784  if (FD_ISSET (mhd_sckt, rs))
785  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
786  if (FD_ISSET (mhd_sckt, ws))
787  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
788  if (FD_ISSET (mhd_sckt, es))
789  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
790  }
791 }
792 
793 #ifdef HAVE_POLL
794 
803 static void
804 urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
805  struct pollfd p[2])
806 {
807  p[0].events = 0;
808  p[1].events = 0;
809 
810  if (urh->in_buffer_used < urh->in_buffer_size)
811  p[0].events |= POLLIN;
812  if (0 != urh->out_buffer_used)
813  p[0].events |= POLLOUT;
814 
815  /* Do not monitor again for errors if error was detected before as
816  * error state is remembered. */
817  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
818  ((0 != urh->in_buffer_size) ||
819  (0 != urh->out_buffer_size) ||
820  (0 != urh->out_buffer_used)))
821  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
822 
823  if (urh->out_buffer_used < urh->out_buffer_size)
824  p[1].events |= POLLIN;
825  if (0 != urh->in_buffer_used)
826  p[1].events |= POLLOUT;
827 
828  /* Do not monitor again for errors if error was detected before as
829  * error state is remembered. */
830  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
831  ((0 != urh->out_buffer_size) ||
832  (0 != urh->in_buffer_size) ||
833  (0 != urh->in_buffer_used)))
834  p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
835 }
836 
837 
844 static void
845 urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
846  struct pollfd p[2])
847 {
848  p[0].fd = urh->connection->socket_fd;
849  p[1].fd = urh->mhd.socket;
850  urh_update_pollfd (urh,
851  p);
852 }
853 
854 
860 static void
861 urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
862  struct pollfd p[2])
863 {
864  /* Reset read/write ready, preserve error state. */
867 
868  if (0 != (p[0].revents & POLLIN))
869  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
870  if (0 != (p[0].revents & POLLOUT))
871  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
872  if (0 != (p[0].revents & POLLHUP))
874  if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
875  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
876  if (0 != (p[1].revents & POLLIN))
877  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
878  if (0 != (p[1].revents & POLLOUT))
879  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
880  if (0 != (p[1].revents & POLLHUP))
881  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
882  if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
884 }
885 #endif /* HAVE_POLL */
886 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
887 
888 
903 static int
905  fd_set *read_fd_set,
906  fd_set *write_fd_set,
907  fd_set *except_fd_set,
908  MHD_socket *max_fd,
909  unsigned int fd_setsize)
910 
911 {
912  struct MHD_Connection *pos;
913  struct MHD_Connection *posn;
914  int result = MHD_YES;
915  MHD_socket ls;
916 
917  if (daemon->shutdown)
918  return MHD_NO;
919 
920  ls = daemon->listen_fd;
921  if ( (MHD_INVALID_SOCKET != ls) &&
922  (! daemon->was_quiesced) &&
923  (! MHD_add_to_fd_set_ (ls,
924  read_fd_set,
925  max_fd,
926  fd_setsize)) )
927  result = MHD_NO;
928 
929  /* Add all sockets to 'except_fd_set' as well to watch for
930  * out-of-band data. However, ignore errors if INFO_READ
931  * or INFO_WRITE sockets will not fit 'except_fd_set'. */
932  /* Start from oldest connections. Make sense for W32 FDSETs. */
933  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
934  {
935  posn = pos->prev;
936 
937  switch (pos->event_loop_info)
938  {
940  if (! MHD_add_to_fd_set_ (pos->socket_fd,
941  read_fd_set,
942  max_fd,
943  fd_setsize))
944  result = MHD_NO;
945 #ifdef MHD_POSIX_SOCKETS
947  except_fd_set,
948  max_fd,
949  fd_setsize);
950 #endif /* MHD_POSIX_SOCKETS */
951  break;
953  if (! MHD_add_to_fd_set_ (pos->socket_fd,
954  write_fd_set,
955  max_fd,
956  fd_setsize))
957  result = MHD_NO;
958 #ifdef MHD_POSIX_SOCKETS
960  except_fd_set,
961  max_fd,
962  fd_setsize);
963 #endif /* MHD_POSIX_SOCKETS */
964  break;
966  if ( (NULL == except_fd_set) ||
968  except_fd_set,
969  max_fd,
970  fd_setsize))
971  result = MHD_NO;
972  break;
974  /* this should never happen */
975  break;
976  }
977  }
978 #ifdef MHD_WINSOCK_SOCKETS
979  /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
980  * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
981  * not be pushed out. */
982  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
983  {
984  posn = pos->prev;
986  except_fd_set,
987  max_fd,
988  fd_setsize);
989  }
990 #endif /* MHD_WINSOCK_SOCKETS */
991 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
992  {
993  struct MHD_UpgradeResponseHandle *urh;
994 
995  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
996  {
997  if (MHD_NO ==
998  urh_to_fdset (urh,
999  read_fd_set,
1000  write_fd_set,
1001  except_fd_set,
1002  max_fd,
1003  fd_setsize))
1004  result = MHD_NO;
1005  }
1006  }
1007 #endif
1008 #if DEBUG_CONNECT
1009 #ifdef HAVE_MESSAGES
1010  if (NULL != max_fd)
1011  MHD_DLOG (daemon,
1012  _("Maximum socket in select set: %d\n"),
1013  *max_fd);
1014 #endif
1015 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1016  return result;
1017 }
1018 
1019 
1052 int
1053 MHD_get_fdset2 (struct MHD_Daemon *daemon,
1054  fd_set *read_fd_set,
1055  fd_set *write_fd_set,
1056  fd_set *except_fd_set,
1057  MHD_socket *max_fd,
1058  unsigned int fd_setsize)
1059 {
1060  fd_set es;
1061 
1062  if ( (NULL == daemon) ||
1063  (NULL == read_fd_set) ||
1064  (NULL == write_fd_set) ||
1065  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ||
1066  (0 != (daemon->options & MHD_USE_POLL)))
1067  return MHD_NO;
1068 
1069  if (NULL == except_fd_set)
1070  { /* Workaround to maintain backward compatibility. */
1071 #ifdef HAVE_MESSAGES
1072  MHD_DLOG (daemon,
1073  _("MHD_get_fdset2() called with except_fd_set "
1074  "set to NULL. Such behavior is unsupported.\n"));
1075 #endif
1076  FD_ZERO (&es);
1077  except_fd_set = &es;
1078  }
1079 
1080 #ifdef EPOLL_SUPPORT
1081  if (0 != (daemon->options & MHD_USE_EPOLL))
1082  {
1083  if (daemon->shutdown)
1084  return MHD_NO;
1085 
1086  /* we're in epoll mode, use the epoll FD as a stand-in for
1087  the entire event set */
1088 
1089  return MHD_add_to_fd_set_ (daemon->epoll_fd,
1090  read_fd_set,
1091  max_fd,
1092  fd_setsize) ? MHD_YES : MHD_NO;
1093  }
1094 #endif
1095 
1096  return internal_get_fdset2 (daemon,
1097  read_fd_set,
1098  write_fd_set,
1099  except_fd_set,
1100  max_fd,
1101  fd_setsize);
1102 }
1103 
1104 
1118 static int
1120  bool read_ready,
1121  bool write_ready,
1122  bool force_close)
1123 {
1124  int ret;
1125  bool states_info_processed = false;
1126  /* Fast track flag */
1127  bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
1128 
1129 #ifdef HTTPS_SUPPORT
1130  if (con->tls_read_ready)
1131  read_ready = true;
1132 #endif /* HTTPS_SUPPORT */
1133  if (!force_close)
1134  {
1135  if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) &&
1136  read_ready)
1137  {
1139  ret = MHD_connection_handle_idle (con);
1140  states_info_processed = true;
1141  }
1142  /* No need to check value of 'ret' here as closed connection
1143  * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
1144  if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
1145  write_ready)
1146  {
1148  ret = MHD_connection_handle_idle (con);
1149  states_info_processed = true;
1150  }
1151  }
1152  else
1153  {
1154  MHD_connection_close_ (con,
1156  return MHD_connection_handle_idle (con);
1157  }
1158 
1159  if (!states_info_processed)
1160  { /* Connection is not read or write ready, but external conditions
1161  * may be changed and need to be processed. */
1162  ret = MHD_connection_handle_idle (con);
1163  }
1164  /* Fast track for fast connections. */
1165  /* If full request was read by single read_handler() invocation
1166  and headers were completely prepared by single MHD_connection_handle_idle()
1167  then try not to wait for next sockets polling and send response
1168  immediately.
1169  As writeability of socket was not checked and it may have
1170  some data pending in system buffers, use this optimization
1171  only for non-blocking sockets. */
1172  /* No need to check 'ret' as connection is always in
1173  * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
1174  else if (on_fasttrack && con->sk_nonblck)
1175  {
1177  {
1179  /* Always call 'MHD_connection_handle_idle()' after each read/write. */
1180  ret = MHD_connection_handle_idle (con);
1181  }
1182  /* If all headers were sent by single write_handler() and
1183  * response body is prepared by single MHD_connection_handle_idle()
1184  * call - continue. */
1185  if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
1187  {
1189  ret = MHD_connection_handle_idle (con);
1190  }
1191  }
1192 
1193  /* All connection's data and states are processed for this turn.
1194  * If connection already has more data to be processed - use
1195  * zero timeout for next select()/poll(). */
1196  /* Thread-per-connection do not need global zero timeout as
1197  * connections are processed individually. */
1198  /* Note: no need to check for read buffer availability for
1199  * TLS read-ready connection in 'read info' state as connection
1200  * without space in read buffer will be market as 'info block'. */
1201  if ( (! con->daemon->data_already_pending) &&
1202  (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1203  {
1205  con->daemon->data_already_pending = true;
1206 #ifdef HTTPS_SUPPORT
1207  else if ( (con->tls_read_ready) &&
1209  con->daemon->data_already_pending = true;
1210 #endif /* HTTPS_SUPPORT */
1211  }
1212  return ret;
1213 }
1214 
1215 
1216 #ifdef UPGRADE_SUPPORT
1217 
1224 static void
1225 cleanup_upgraded_connection (struct MHD_Connection *connection)
1226 {
1227  struct MHD_UpgradeResponseHandle *urh = connection->urh;
1228 
1229  if (NULL == urh)
1230  return;
1231 #ifdef HTTPS_SUPPORT
1232  /* Signal remote client the end of TLS connection by
1233  * gracefully closing TLS session. */
1234  if (0 != (connection->daemon->options & MHD_USE_TLS))
1235  gnutls_bye (connection->tls_session,
1236  GNUTLS_SHUT_WR);
1237 
1238  if (MHD_INVALID_SOCKET != urh->mhd.socket)
1239  MHD_socket_close_chk_ (urh->mhd.socket);
1240 
1241  if (MHD_INVALID_SOCKET != urh->app.socket)
1242  MHD_socket_close_chk_ (urh->app.socket);
1243 #endif /* HTTPS_SUPPORT */
1244  connection->urh = NULL;
1245  free (urh);
1246 }
1247 #endif /* UPGRADE_SUPPORT */
1248 
1249 
1250 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1251 
1259 static void
1260 process_urh (struct MHD_UpgradeResponseHandle *urh)
1261 {
1262  /* Help compiler to optimize:
1263  * pointers to 'connection' and 'daemon' are not changed
1264  * during this processing, so no need to chain dereference
1265  * each time. */
1266  struct MHD_Connection * const connection = urh->connection;
1267  struct MHD_Daemon * const daemon = connection->daemon;
1268  /* Prevent data races: use same value of 'was_closed' throughout
1269  * this function. If 'was_closed' changed externally in the middle
1270  * of processing - it will be processed on next iteration. */
1271  bool was_closed;
1272  if (daemon->shutdown)
1273  {
1274  /* Daemon shutting down, application will not receive any more data. */
1275 #ifdef HAVE_MESSAGES
1276  if (! urh->was_closed)
1277  {
1278  MHD_DLOG (daemon,
1279  _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1280  }
1281 #endif
1282  urh->was_closed = true;
1283  }
1284  was_closed = urh->was_closed;
1285  if (was_closed)
1286  {
1287  /* Application was closed connections: no more data
1288  * can be forwarded to application socket. */
1289  if (0 < urh->in_buffer_used)
1290  {
1291 #ifdef HAVE_MESSAGES
1292  MHD_DLOG (daemon,
1293  _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
1294  " bytes of data received from remote side: application shut down socket\n"),
1295  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
1296 #endif
1297 
1298  }
1299  /* If application signaled MHD about socket closure then
1300  * check for any pending data even if socket is not marked
1301  * as 'ready' (signal may arrive after poll()/select()).
1302  * Socketpair for forwarding is always in non-blocking mode
1303  * so no risk that recv() will block the thread. */
1304  if (0 != urh->out_buffer_size)
1305  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1306  /* Discard any data received form remote. */
1307  urh->in_buffer_used = 0;
1308  /* Do not try to push data to application. */
1309  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1310  /* Reading from remote client is not required anymore. */
1311  urh->in_buffer_size = 0;
1312  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1313  connection->tls_read_ready = false;
1314  }
1315 
1316  /* On some platforms (W32, possibly Darwin) failed send() (send() will always
1317  * fail after remote disconnect was detected) may discard data in system
1318  * buffers received by system but not yet read by recv().
1319  * So, before trying send() on any socket, recv() must be performed at first
1320  * otherwise last part of incoming data may be lost. */
1321 
1322  /* If disconnect or error was detected - try to read from socket
1323  * to dry data possibly pending is system buffers. */
1324  if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
1325  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
1326  if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
1327  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1328 
1329  /*
1330  * handle reading from remote TLS client
1331  */
1332  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
1333  (connection->tls_read_ready) ) &&
1334  (urh->in_buffer_used < urh->in_buffer_size) )
1335  {
1336  ssize_t res;
1337  size_t buf_size;
1338 
1339  buf_size = urh->in_buffer_size - urh->in_buffer_used;
1340  if (buf_size > SSIZE_MAX)
1341  buf_size = SSIZE_MAX;
1342 
1343  connection->tls_read_ready = false;
1344  res = gnutls_record_recv (connection->tls_session,
1345  &urh->in_buffer[urh->in_buffer_used],
1346  buf_size);
1347  if (0 >= res)
1348  {
1349  if (GNUTLS_E_INTERRUPTED != res)
1350  {
1351  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1352  if (GNUTLS_E_AGAIN != res)
1353  {
1354  /* Unrecoverable error on socket was detected or
1355  * socket was disconnected/shut down. */
1356  /* Stop trying to read from this TLS socket. */
1357  urh->in_buffer_size = 0;
1358  }
1359  }
1360  }
1361  else /* 0 < res */
1362  {
1363  urh->in_buffer_used += res;
1364  if (buf_size > (size_t)res)
1365  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1366  else if (0 < gnutls_record_check_pending (connection->tls_session))
1367  connection->tls_read_ready = true;
1368  }
1369  if (MHD_EPOLL_STATE_ERROR ==
1370  ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
1371  {
1372  /* Unrecoverable error on socket was detected and all
1373  * pending data was read from system buffers. */
1374  /* Stop trying to read from this TLS socket. */
1375  urh->in_buffer_size = 0;
1376  }
1377  }
1378 
1379  /*
1380  * handle reading from application
1381  */
1382  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1383  (urh->out_buffer_used < urh->out_buffer_size) )
1384  {
1385  ssize_t res;
1386  size_t buf_size;
1387 
1388  buf_size = urh->out_buffer_size - urh->out_buffer_used;
1389  if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
1390  buf_size = MHD_SCKT_SEND_MAX_SIZE_;
1391 
1392  res = MHD_recv_ (urh->mhd.socket,
1393  &urh->out_buffer[urh->out_buffer_used],
1394  buf_size);
1395  if (0 >= res)
1396  {
1397  const int err = MHD_socket_get_error_ ();
1398  if ((0 == res) ||
1399  ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1401  {
1402  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1403  if ((0 == res) ||
1404  (was_closed) ||
1405  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1406  (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
1407  {
1408  /* Socket disconnect/shutdown was detected;
1409  * Application signaled about closure of 'upgraded' socket;
1410  * or persistent / unrecoverable error. */
1411  /* Do not try to pull more data from application. */
1412  urh->out_buffer_size = 0;
1413  }
1414  }
1415  }
1416  else /* 0 < res */
1417  {
1418  urh->out_buffer_used += res;
1419  if (buf_size > (size_t)res)
1420  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1421  }
1422  if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1423  ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1424  (was_closed) ) )
1425  {
1426  /* Unrecoverable error on socket was detected and all
1427  * pending data was read from system buffers. */
1428  /* Do not try to pull more data from application. */
1429  urh->out_buffer_size = 0;
1430  }
1431  }
1432 
1433  /*
1434  * handle writing to remote HTTPS client
1435  */
1436  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
1437  (urh->out_buffer_used > 0) )
1438  {
1439  ssize_t res;
1440  size_t data_size;
1441 
1442  data_size = urh->out_buffer_used;
1443  if (data_size > SSIZE_MAX)
1444  data_size = SSIZE_MAX;
1445 
1446  res = gnutls_record_send (connection->tls_session,
1447  urh->out_buffer,
1448  data_size);
1449  if (0 >= res)
1450  {
1451  if (GNUTLS_E_INTERRUPTED != res)
1452  {
1453  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1454  if (GNUTLS_E_AGAIN != res)
1455  {
1456  /* TLS connection shut down or
1457  * persistent / unrecoverable error. */
1458 #ifdef HAVE_MESSAGES
1459  MHD_DLOG (daemon,
1460  _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
1461  " bytes of data received from application: %s\n"),
1462  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
1463  gnutls_strerror(res));
1464 #endif
1465  /* Discard any data unsent to remote. */
1466  urh->out_buffer_used = 0;
1467  /* Do not try to pull more data from application. */
1468  urh->out_buffer_size = 0;
1469  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1470  }
1471  }
1472  }
1473  else /* 0 < res */
1474  {
1475  const size_t next_out_buffer_used = urh->out_buffer_used - res;
1476  if (0 != next_out_buffer_used)
1477  {
1478  memmove (urh->out_buffer,
1479  &urh->out_buffer[res],
1480  next_out_buffer_used);
1481  if (data_size > (size_t)res)
1482  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1483  }
1484  urh->out_buffer_used = next_out_buffer_used;
1485  }
1486  if ( (0 == urh->out_buffer_used) &&
1487  (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
1488  {
1489  /* Unrecoverable error on socket was detected and all
1490  * pending data was sent to remote. */
1491  /* Do not try to send to remote anymore. */
1492  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1493  /* Do not try to pull more data from application. */
1494  urh->out_buffer_size = 0;
1495  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1496  }
1497  }
1498 
1499  /*
1500  * handle writing to application
1501  */
1502  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
1503  (urh->in_buffer_used > 0) )
1504  {
1505  ssize_t res;
1506  size_t data_size;
1507 
1508  data_size = urh->in_buffer_used;
1509  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
1510  data_size = MHD_SCKT_SEND_MAX_SIZE_;
1511 
1512  res = MHD_send_ (urh->mhd.socket,
1513  urh->in_buffer,
1514  data_size);
1515  if (0 >= res)
1516  {
1517  const int err = MHD_socket_get_error_ ();
1518  if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1520  {
1521  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1522  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
1523  {
1524  /* Socketpair connection shut down or
1525  * persistent / unrecoverable error. */
1526 #ifdef HAVE_MESSAGES
1527  MHD_DLOG (daemon,
1528  _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
1529  " bytes of data received from remote side: %s\n"),
1530  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
1531  MHD_socket_strerr_ (err));
1532 #endif
1533  /* Discard any data received form remote. */
1534  urh->in_buffer_used = 0;
1535  /* Reading from remote client is not required anymore. */
1536  urh->in_buffer_size = 0;
1537  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1538  connection->tls_read_ready = false;
1539  }
1540  }
1541  }
1542  else /* 0 < res */
1543  {
1544  const size_t next_in_buffer_used = urh->in_buffer_used - res;
1545  if (0 != next_in_buffer_used)
1546  {
1547  memmove (urh->in_buffer,
1548  &urh->in_buffer[res],
1549  next_in_buffer_used);
1550  if (data_size > (size_t)res)
1551  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1552  }
1553  urh->in_buffer_used = next_in_buffer_used;
1554  }
1555  if ( (0 == urh->in_buffer_used) &&
1556  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
1557  {
1558  /* Do not try to push data to application. */
1559  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1560  /* Reading from remote client is not required anymore. */
1561  urh->in_buffer_size = 0;
1562  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1563  connection->tls_read_ready = false;
1564  }
1565  }
1566 
1567  /* Check whether data is present in TLS buffers
1568  * and incoming forward buffer have some space. */
1569  if ( (connection->tls_read_ready) &&
1570  (urh->in_buffer_used < urh->in_buffer_size) &&
1571  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1572  daemon->data_already_pending = true;
1573 
1574  if ( (daemon->shutdown) &&
1575  ( (0 != urh->out_buffer_size) ||
1576  (0 != urh->out_buffer_used) ) )
1577  {
1578  /* Daemon shutting down, discard any remaining forward data. */
1579 #ifdef HAVE_MESSAGES
1580  if (0 < urh->out_buffer_used)
1581  MHD_DLOG (daemon,
1582  _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
1583  " bytes of data received from application: daemon shut down\n"),
1584  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
1585 #endif
1586  /* Discard any data unsent to remote. */
1587  urh->out_buffer_used = 0;
1588  /* Do not try to sent to remote anymore. */
1589  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1590  /* Do not try to pull more data from application. */
1591  urh->out_buffer_size = 0;
1592  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1593  }
1594 }
1595 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1596 
1597 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1598 #ifdef UPGRADE_SUPPORT
1599 
1607 static void
1608 thread_main_connection_upgrade (struct MHD_Connection *con)
1609 {
1610 #ifdef HTTPS_SUPPORT
1611  struct MHD_UpgradeResponseHandle *urh = con->urh;
1612  struct MHD_Daemon *daemon = con->daemon;
1613 
1614  /* Here, we need to bi-directionally forward
1615  until the application tells us that it is done
1616  with the socket; */
1617  if ( (0 != (daemon->options & MHD_USE_TLS)) &&
1618  (0 == (daemon->options & MHD_USE_POLL)))
1619  {
1620  while ( (0 != urh->in_buffer_size) ||
1621  (0 != urh->out_buffer_size) ||
1622  (0 != urh->in_buffer_used) ||
1623  (0 != urh->out_buffer_used) )
1624  {
1625  /* use select */
1626  fd_set rs;
1627  fd_set ws;
1628  fd_set es;
1629  MHD_socket max_fd;
1630  int num_ready;
1631  bool result;
1632 
1633  FD_ZERO (&rs);
1634  FD_ZERO (&ws);
1635  FD_ZERO (&es);
1636  max_fd = MHD_INVALID_SOCKET;
1637  result = urh_to_fdset (urh,
1638  &rs,
1639  &ws,
1640  &es,
1641  &max_fd,
1642  FD_SETSIZE);
1643  if (! result)
1644  {
1645 #ifdef HAVE_MESSAGES
1646  MHD_DLOG (con->daemon,
1647  _("Error preparing select\n"));
1648 #endif
1649  break;
1650  }
1651  /* FIXME: does this check really needed? */
1652  if (MHD_INVALID_SOCKET != max_fd)
1653  {
1654  struct timeval* tvp;
1655  struct timeval tv;
1656  if ( (con->tls_read_ready) &&
1657  (urh->in_buffer_used < urh->in_buffer_size))
1658  { /* No need to wait if incoming data is already pending in TLS buffers. */
1659  tv.tv_sec = 0;
1660  tv.tv_usec = 0;
1661  tvp = &tv;
1662  }
1663  else
1664  tvp = NULL;
1665  num_ready = MHD_SYS_select_ (max_fd + 1,
1666  &rs,
1667  &ws,
1668  &es,
1669  tvp);
1670  }
1671  else
1672  num_ready = 0;
1673  if (num_ready < 0)
1674  {
1675  const int err = MHD_socket_get_error_();
1676 
1677  if (MHD_SCKT_ERR_IS_EINTR_(err))
1678  continue;
1679 #ifdef HAVE_MESSAGES
1680  MHD_DLOG (con->daemon,
1681  _("Error during select (%d): `%s'\n"),
1682  err,
1683  MHD_socket_strerr_ (err));
1684 #endif
1685  break;
1686  }
1687  urh_from_fdset (urh,
1688  &rs,
1689  &ws,
1690  &es);
1691  process_urh (urh);
1692  }
1693  }
1694 #ifdef HAVE_POLL
1695  else if (0 != (daemon->options & MHD_USE_TLS))
1696  {
1697  /* use poll() */
1698  struct pollfd p[2];
1699  memset (p,
1700  0,
1701  sizeof (p));
1702  p[0].fd = urh->connection->socket_fd;
1703  p[1].fd = urh->mhd.socket;
1704 
1705  while ( (0 != urh->in_buffer_size) ||
1706  (0 != urh->out_buffer_size) ||
1707  (0 != urh->in_buffer_used) ||
1708  (0 != urh->out_buffer_used) )
1709  {
1710  int timeout;
1711 
1712  urh_update_pollfd(urh, p);
1713 
1714  if ( (con->tls_read_ready) &&
1715  (urh->in_buffer_used < urh->in_buffer_size))
1716  timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
1717  else
1718  timeout = -1;
1719 
1720  if (MHD_sys_poll_ (p,
1721  2,
1722  timeout) < 0)
1723  {
1724  const int err = MHD_socket_get_error_ ();
1725 
1726  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1727  continue;
1728 #ifdef HAVE_MESSAGES
1729  MHD_DLOG (con->daemon,
1730  _("Error during poll: `%s'\n"),
1731  MHD_socket_strerr_ (err));
1732 #endif
1733  break;
1734  }
1735  urh_from_pollfd (urh,
1736  p);
1737  process_urh (urh);
1738  }
1739  }
1740  /* end POLL */
1741 #endif
1742  /* end HTTPS */
1743 #endif /* HTTPS_SUPPORT */
1744  /* TLS forwarding was finished. Cleanup socketpair. */
1746  /* Do not set 'urh->clean_ready' yet as 'urh' will be used
1747  * in connection thread for a little while. */
1748 }
1749 #endif /* UPGRADE_SUPPORT */
1750 
1751 
1759 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1761 {
1762  struct MHD_Connection *con = data;
1763  struct MHD_Daemon *daemon = con->daemon;
1764  int num_ready;
1765  fd_set rs;
1766  fd_set ws;
1767  fd_set es;
1768  MHD_socket maxsock;
1769  struct timeval tv;
1770  struct timeval *tvp;
1771  time_t now;
1772 #if WINDOWS
1773 #ifdef HAVE_POLL
1774  int extra_slot;
1775 #endif /* HAVE_POLL */
1776 #define EXTRA_SLOTS 1
1777 #else /* !WINDOWS */
1778 #define EXTRA_SLOTS 0
1779 #endif /* !WINDOWS */
1780 #ifdef HAVE_POLL
1781  struct pollfd p[1 + EXTRA_SLOTS];
1782 #endif
1783 #undef EXTRA_SLOTS
1784 #ifdef HAVE_POLL
1785  const bool use_poll = (0 != (daemon->options & MHD_USE_POLL));
1786 #else /* ! HAVE_POLL */
1787  const bool use_poll = 0;
1788 #endif /* ! HAVE_POLL */
1789  bool was_suspended = false;
1790  MHD_thread_init_(&(con->pid));
1791 
1792  while ( (! daemon->shutdown) &&
1793  (MHD_CONNECTION_CLOSED != con->state) )
1794  {
1795  const time_t timeout = daemon->connection_timeout;
1796 #ifdef UPGRADE_SUPPORT
1797  struct MHD_UpgradeResponseHandle * const urh = con->urh;
1798 #else /* ! UPGRADE_SUPPORT */
1799  static const void * const urh = NULL;
1800 #endif /* ! UPGRADE_SUPPORT */
1801 
1802  if ( (con->suspended) &&
1803  (NULL == urh) )
1804  {
1805  /* Connection was suspended, wait for resume. */
1806  was_suspended = true;
1807  if (! use_poll)
1808  {
1809  FD_ZERO (&rs);
1810  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
1811  &rs,
1812  NULL,
1813  FD_SETSIZE))
1814  {
1815  #ifdef HAVE_MESSAGES
1816  MHD_DLOG (con->daemon,
1817  _("Failed to add FD to fd_set\n"));
1818  #endif
1819  goto exit;
1820  }
1821  if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
1822  &rs,
1823  NULL,
1824  NULL,
1825  NULL))
1826  {
1827  const int err = MHD_socket_get_error_();
1828 
1829  if (MHD_SCKT_ERR_IS_EINTR_(err))
1830  continue;
1831 #ifdef HAVE_MESSAGES
1832  MHD_DLOG (con->daemon,
1833  _("Error during select (%d): `%s'\n"),
1834  err,
1835  MHD_socket_strerr_ (err));
1836 #endif
1837  break;
1838  }
1839  }
1840 #ifdef HAVE_POLL
1841  else /* use_poll */
1842  {
1843  p[0].events = POLLIN;
1844  p[0].fd = MHD_itc_r_fd_ (daemon->itc);
1845  p[0].revents = 0;
1846  if (0 > MHD_sys_poll_ (p,
1847  1,
1848  -1))
1849  {
1851  continue;
1852 #ifdef HAVE_MESSAGES
1853  MHD_DLOG (con->daemon,
1854  _("Error during poll: `%s'\n"),
1856 #endif
1857  break;
1858  }
1859  }
1860 #endif /* HAVE_POLL */
1861  MHD_itc_clear_ (daemon->itc);
1862  continue; /* Check again for resume. */
1863  } /* End of "suspended" branch. */
1864 
1865  if (was_suspended)
1866  {
1867  MHD_update_last_activity_ (con); /* Reset timeout timer. */
1868  /* Process response queued during suspend and update states. */
1870  was_suspended = false;
1871  }
1872 
1873  tvp = NULL;
1874 
1876 #ifdef HTTPS_SUPPORT
1877  || ( (con->tls_read_ready) &&
1879 #endif /* HTTPS_SUPPORT */
1880  )
1881  {
1882  /* do not block: more data may be inside of TLS buffers waiting or
1883  * application must provide response data */
1884  tv.tv_sec = 0;
1885  tv.tv_usec = 0;
1886  tvp = &tv;
1887  }
1888  if ( (NULL == tvp) &&
1889  (timeout > 0) )
1890  {
1891  now = MHD_monotonic_sec_counter();
1892  if (now - con->last_activity > timeout)
1893  tv.tv_sec = 0;
1894  else
1895  {
1896  const time_t seconds_left = timeout - (now - con->last_activity);
1897 #if !defined(_WIN32) || defined(__CYGWIN__)
1898  tv.tv_sec = seconds_left;
1899 #else /* _WIN32 && !__CYGWIN__ */
1900  if (seconds_left > TIMEVAL_TV_SEC_MAX)
1901  tv.tv_sec = TIMEVAL_TV_SEC_MAX;
1902  else
1903  tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
1904 #endif /* _WIN32 && ! __CYGWIN__ */
1905  }
1906  tv.tv_usec = 0;
1907  tvp = &tv;
1908  }
1909  if (! use_poll)
1910  {
1911  /* use select */
1912  bool err_state = false;
1913 
1914  FD_ZERO (&rs);
1915  FD_ZERO (&ws);
1916  FD_ZERO (&es);
1917  maxsock = MHD_INVALID_SOCKET;
1918  switch (con->event_loop_info)
1919  {
1921  if (! MHD_add_to_fd_set_ (con->socket_fd,
1922  &rs,
1923  &maxsock,
1924  FD_SETSIZE))
1925  err_state = true;
1926  break;
1928  if (! MHD_add_to_fd_set_ (con->socket_fd,
1929  &ws,
1930  &maxsock,
1931  FD_SETSIZE))
1932  err_state = true;
1933  break;
1935  if (! MHD_add_to_fd_set_ (con->socket_fd,
1936  &es,
1937  &maxsock,
1938  FD_SETSIZE))
1939  err_state = true;
1940  break;
1942  /* how did we get here!? */
1943  goto exit;
1944  }
1945 #if WINDOWS
1946  if (MHD_ITC_IS_VALID_(daemon->itc) )
1947  {
1948  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
1949  &rs,
1950  &maxsock,
1951  FD_SETSIZE))
1952  err_state = 1;
1953  }
1954 #endif
1955  if (err_state)
1956  {
1957 #ifdef HAVE_MESSAGES
1958  MHD_DLOG (con->daemon,
1959  _("Failed to add FD to fd_set\n"));
1960 #endif
1961  goto exit;
1962  }
1963 
1964  num_ready = MHD_SYS_select_ (maxsock + 1,
1965  &rs,
1966  &ws,
1967  &es,
1968  tvp);
1969  if (num_ready < 0)
1970  {
1971  const int err = MHD_socket_get_error_();
1972 
1973  if (MHD_SCKT_ERR_IS_EINTR_(err))
1974  continue;
1975 #ifdef HAVE_MESSAGES
1976  MHD_DLOG (con->daemon,
1977  _("Error during select (%d): `%s'\n"),
1978  err,
1979  MHD_socket_strerr_ (err));
1980 #endif
1981  break;
1982  }
1983 #if WINDOWS
1984  /* Clear ITC before other processing so additional
1985  * signals will trigger select() again */
1986  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
1987  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
1988  &rs)) )
1989  MHD_itc_clear_ (daemon->itc);
1990 #endif
1991  if (MHD_NO ==
1992  call_handlers (con,
1993  FD_ISSET (con->socket_fd,
1994  &rs),
1995  FD_ISSET (con->socket_fd,
1996  &ws),
1997  FD_ISSET (con->socket_fd,
1998  &es)) )
1999  goto exit;
2000  }
2001 #ifdef HAVE_POLL
2002  else
2003  {
2004  /* use poll */
2005  memset (&p,
2006  0,
2007  sizeof (p));
2008  p[0].fd = con->socket_fd;
2009  switch (con->event_loop_info)
2010  {
2012  p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2013  break;
2015  p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2016  break;
2018  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2019  break;
2021  /* how did we get here!? */
2022  goto exit;
2023  }
2024 #if WINDOWS
2025  extra_slot = 0;
2026  if (MHD_ITC_IS_VALID_(daemon->itc))
2027  {
2028  p[1].events |= POLLIN;
2029  p[1].fd = MHD_itc_r_fd_ (daemon->itc);
2030  p[1].revents = 0;
2031  extra_slot = 1;
2032  }
2033 #endif
2034  if (MHD_sys_poll_ (p,
2035 #if WINDOWS
2036  1 + extra_slot,
2037 #else
2038  1,
2039 #endif
2040  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2041  {
2043  continue;
2044 #ifdef HAVE_MESSAGES
2045  MHD_DLOG (con->daemon,
2046  _("Error during poll: `%s'\n"),
2048 #endif
2049  break;
2050  }
2051 #if WINDOWS
2052  /* Clear ITC before other processing so additional
2053  * signals will trigger poll() again */
2054  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2055  (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2056  MHD_itc_clear_ (daemon->itc);
2057 #endif
2058  if (MHD_NO ==
2059  call_handlers (con,
2060  0 != (p[0].revents & POLLIN),
2061  0 != (p[0].revents & POLLOUT),
2062  0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2063  goto exit;
2064  }
2065 #endif
2066 #ifdef UPGRADE_SUPPORT
2067  if (MHD_CONNECTION_UPGRADE == con->state)
2068  {
2069  /* Normal HTTP processing is finished,
2070  * notify application. */
2071  if ( (NULL != daemon->notify_completed) &&
2072  (con->client_aware) )
2073  daemon->notify_completed (daemon->notify_completed_cls,
2074  con,
2075  &con->client_context,
2077  con->client_aware = false;
2078 
2079  thread_main_connection_upgrade (con);
2080  /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
2081 
2082  /* "Upgraded" data will not be used in this thread from this point. */
2083  con->urh->clean_ready = true;
2084  /* If 'urh->was_closed' set to true, connection will be
2085  * moved immediately to cleanup list. Otherwise connection
2086  * will stay in suspended list until 'urh' will be marked
2087  * with 'was_closed' by application. */
2088  MHD_resume_connection(con);
2089 
2090  /* skip usual clean up */
2091  return (MHD_THRD_RTRN_TYPE_) 0;
2092  }
2093 #endif /* UPGRADE_SUPPORT */
2094  }
2095 #if DEBUG_CLOSE
2096 #ifdef HAVE_MESSAGES
2097  MHD_DLOG (con->daemon,
2098  _("Processing thread terminating. Closing connection\n"));
2099 #endif
2100 #endif
2101  if (MHD_CONNECTION_CLOSED != con->state)
2102  MHD_connection_close_ (con,
2103  (daemon->shutdown) ?
2107 exit:
2108  if (NULL != con->response)
2109  {
2111  con->response = NULL;
2112  }
2113 
2114  if (MHD_INVALID_SOCKET != con->socket_fd)
2115  {
2116  shutdown (con->socket_fd,
2117  SHUT_WR);
2118  /* 'socket_fd' can be used in other thread to signal shutdown.
2119  * To avoid data races, do not close socket here. Daemon will
2120  * use more connections only after cleanup anyway. */
2121  }
2122  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2123  (! MHD_itc_activate_ (daemon->itc, "t")) )
2124  {
2125 #ifdef HAVE_MESSAGES
2126  MHD_DLOG (daemon,
2127  _("Failed to signal thread termination via inter-thread communication channel."));
2128 #endif
2129  }
2130  return (MHD_THRD_RTRN_TYPE_) 0;
2131 }
2132 #endif
2133 
2134 
2142 static void
2143 MHD_cleanup_connections (struct MHD_Daemon *daemon);
2144 
2145 #if defined(HTTPS_SUPPORT)
2146 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \
2147  (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL)
2148 
2153 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2154 #endif /* !MHD_WINSOCK_SOCKETS && !MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) */
2155 
2156 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2157 
2161 static ssize_t
2162 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2163  const void *data,
2164  size_t data_size)
2165 {
2166 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2167  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
2168  data_size = MHD_SCKT_SEND_MAX_SIZE_;
2169 #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */
2170  return MHD_send_ ((MHD_socket)(intptr_t)(trnsp), data, data_size);
2171 }
2172 #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
2173 
2174 
2183 static int
2184 psk_gnutls_adapter (gnutls_session_t session,
2185  const char *username,
2186  gnutls_datum_t *key)
2187 {
2188  struct MHD_Connection *connection;
2189  struct MHD_Daemon *daemon;
2190  void *app_psk;
2191  size_t app_psk_size;
2192 
2193  connection = gnutls_session_get_ptr (session);
2194  if (NULL == connection)
2195  {
2196 #ifdef HAVE_MESSAGES
2197  /* Cannot use our logger, we don't even have "daemon" */
2198  MHD_PANIC (_("Internal server error. This should be impossible.\n"));
2199 #endif
2200  return -1;
2201  }
2202  daemon = connection->daemon;
2203 #if GNUTLS_VERSION_MAJOR >= 3
2204  if (NULL == daemon->cred_callback)
2205  {
2206 #ifdef HAVE_MESSAGES
2207  MHD_DLOG (daemon,
2208  _("PSK not supported by this server.\n"));
2209 #endif
2210  return -1;
2211  }
2212  if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2213  connection,
2214  username,
2215  &app_psk,
2216  &app_psk_size))
2217  return -1;
2218  if (NULL == (key->data = gnutls_malloc (app_psk_size)))
2219  {
2220 #ifdef HAVE_MESSAGES
2221  MHD_DLOG (daemon,
2222  _("PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2223 #endif
2224  free (app_psk);
2225  return -1;
2226  }
2227  key->size = app_psk_size;
2228  memcpy (key->data,
2229  app_psk,
2230  app_psk_size);
2231  free (app_psk);
2232  return 0;
2233 #else
2234 #ifdef HAVE_MESSAGES
2235  MHD_DLOG (daemon,
2236  _("PSK not supported by this server.\n"));
2237 #endif
2238  return -1;
2239 #endif
2240 }
2241 #endif /* HTTPS_SUPPORT */
2242 
2243 
2269 static int
2271  MHD_socket client_socket,
2272  const struct sockaddr *addr,
2273  socklen_t addrlen,
2274  bool external_add,
2275  bool non_blck)
2276 {
2277  struct MHD_Connection *connection;
2278 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2279  unsigned int i;
2280 #endif
2281  int eno = 0;
2282 
2283  /* Direct add to master daemon could happen only with "external" add mode. */
2284 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2285  mhd_assert ((NULL == daemon->worker_pool) || (external_add));
2286  if ((external_add) && (NULL != daemon->worker_pool))
2287  {
2288  /* have a pool, try to find a pool with capacity; we use the
2289  socket as the initial offset into the pool for load
2290  balancing */
2291  for (i = 0; i < daemon->worker_pool_size; ++i)
2292  {
2293  struct MHD_Daemon * const worker =
2294  &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
2295  if (worker->connections < worker->connection_limit)
2296  return internal_add_connection (worker,
2297  client_socket,
2298  addr,
2299  addrlen,
2300  true,
2301  non_blck);
2302  }
2303  /* all pools are at their connection limit, must refuse */
2304  MHD_socket_close_chk_ (client_socket);
2305 #if ENFILE
2306  errno = ENFILE;
2307 #endif
2308  return MHD_NO;
2309  }
2310 #endif
2311 
2312  if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket,
2313  NULL)) &&
2314  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
2315  {
2316 #ifdef HAVE_MESSAGES
2317  MHD_DLOG (daemon,
2318  _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2319  (int) client_socket,
2320  (int) FD_SETSIZE);
2321 #endif
2322  MHD_socket_close_chk_ (client_socket);
2323 #if EINVAL
2324  errno = EINVAL;
2325 #endif
2326  return MHD_NO;
2327  }
2328 
2329 #ifdef MHD_socket_nosignal_
2330  if (! MHD_socket_nosignal_ (client_socket))
2331  {
2332 #ifdef HAVE_MESSAGES
2333  MHD_DLOG (daemon,
2334  _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2336 #endif
2337 #ifndef MSG_NOSIGNAL
2338  /* Cannot use socket as it can produce SIGPIPE. */
2339 #ifdef ENOTSOCK
2340  errno = ENOTSOCK;
2341 #endif /* ENOTSOCK */
2342  return MHD_NO;
2343 #endif /* ! MSG_NOSIGNAL */
2344  }
2345 #endif /* MHD_socket_nosignal_ */
2346 
2347 
2348 #ifdef HAVE_MESSAGES
2349 #if DEBUG_CONNECT
2350  MHD_DLOG (daemon,
2351  _("Accepted connection on socket %d\n"),
2352  client_socket);
2353 #endif
2354 #endif
2355  if ( (daemon->connections == daemon->connection_limit) ||
2356  (MHD_NO == MHD_ip_limit_add (daemon,
2357  addr,
2358  addrlen)) )
2359  {
2360  /* above connection limit - reject */
2361 #ifdef HAVE_MESSAGES
2362  MHD_DLOG (daemon,
2363  _("Server reached connection limit. Closing inbound connection.\n"));
2364 #endif
2365  MHD_socket_close_chk_ (client_socket);
2366 #if ENFILE
2367  errno = ENFILE;
2368 #endif
2369  return MHD_NO;
2370  }
2371 
2372  /* apply connection acceptance policy if present */
2373  if ( (NULL != daemon->apc) &&
2374  (MHD_NO == daemon->apc (daemon->apc_cls,
2375  addr,
2376  addrlen)) )
2377  {
2378 #if DEBUG_CLOSE
2379 #ifdef HAVE_MESSAGES
2380  MHD_DLOG (daemon,
2381  _("Connection rejected by application. Closing connection.\n"));
2382 #endif
2383 #endif
2384  MHD_socket_close_chk_ (client_socket);
2385  MHD_ip_limit_del (daemon,
2386  addr,
2387  addrlen);
2388 #if EACCESS
2389  errno = EACCESS;
2390 #endif
2391  return MHD_NO;
2392  }
2393 
2394  if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection))))
2395  {
2396  eno = errno;
2397 #ifdef HAVE_MESSAGES
2398  MHD_DLOG (daemon,
2399  "Error allocating memory: %s\n",
2400  MHD_strerror_ (errno));
2401 #endif
2402  MHD_socket_close_chk_ (client_socket);
2403  MHD_ip_limit_del (daemon,
2404  addr,
2405  addrlen);
2406  errno = eno;
2407  return MHD_NO;
2408  }
2409  connection->pool = MHD_pool_create (daemon->pool_size);
2410  if (NULL == connection->pool)
2411  {
2412 #ifdef HAVE_MESSAGES
2413  MHD_DLOG (daemon,
2414  _("Error allocating memory: %s\n"),
2415  MHD_strerror_ (errno));
2416 #endif
2417  MHD_socket_close_chk_ (client_socket);
2418  MHD_ip_limit_del (daemon,
2419  addr,
2420  addrlen);
2421  free (connection);
2422 #if ENOMEM
2423  errno = ENOMEM;
2424 #endif
2425  return MHD_NO;
2426  }
2427 
2428  connection->connection_timeout = daemon->connection_timeout;
2429  if (NULL == (connection->addr = malloc (addrlen)))
2430  {
2431  eno = errno;
2432 #ifdef HAVE_MESSAGES
2433  MHD_DLOG (daemon,
2434  _("Error allocating memory: %s\n"),
2435  MHD_strerror_ (errno));
2436 #endif
2437  MHD_socket_close_chk_ (client_socket);
2438  MHD_ip_limit_del (daemon,
2439  addr,
2440  addrlen);
2441  MHD_pool_destroy (connection->pool);
2442  free (connection);
2443  errno = eno;
2444  return MHD_NO;
2445  }
2446  memcpy (connection->addr,
2447  addr,
2448  addrlen);
2449  connection->addr_len = addrlen;
2450  connection->socket_fd = client_socket;
2451  connection->sk_nonblck = non_blck;
2452  connection->daemon = daemon;
2453  connection->last_activity = MHD_monotonic_sec_counter();
2454 
2455  if (0 == (daemon->options & MHD_USE_TLS))
2456  {
2457  /* set default connection handlers */
2458  MHD_set_http_callbacks_ (connection);
2459  }
2460  else
2461  {
2462 #ifdef HTTPS_SUPPORT
2463  connection->tls_state = MHD_TLS_CONN_INIT;
2464  MHD_set_https_callbacks (connection);
2465  gnutls_init (&connection->tls_session,
2466  GNUTLS_SERVER
2467 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402)
2468  | GNUTLS_NO_SIGNAL
2469 #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
2470 #if GNUTLS_VERSION_MAJOR >= 3
2471  | GNUTLS_NONBLOCK
2472 #endif /* GNUTLS_VERSION_MAJOR >= 3*/
2473  );
2474  gnutls_priority_set (connection->tls_session,
2475  daemon->priority_cache);
2476  gnutls_session_set_ptr (connection->tls_session,
2477  connection);
2478  switch (daemon->cred_type)
2479  {
2480  /* set needed credentials for certificate authentication. */
2481  case GNUTLS_CRD_CERTIFICATE:
2482  gnutls_credentials_set (connection->tls_session,
2483  GNUTLS_CRD_CERTIFICATE,
2484  daemon->x509_cred);
2485  break;
2486  case GNUTLS_CRD_PSK:
2487  gnutls_credentials_set (connection->tls_session,
2488  GNUTLS_CRD_PSK,
2489  daemon->psk_cred);
2490  gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2491  &psk_gnutls_adapter);
2492  break;
2493  default:
2494 #ifdef HAVE_MESSAGES
2495  MHD_DLOG (connection->daemon,
2496  _("Failed to setup TLS credentials: unknown credential type %d\n"),
2497  daemon->cred_type);
2498 #endif
2499  MHD_socket_close_chk_ (client_socket);
2500  MHD_ip_limit_del (daemon,
2501  addr,
2502  addrlen);
2503  free (connection->addr);
2504  free (connection);
2505  MHD_PANIC (_("Unknown credential type"));
2506 #if EINVAL
2507  errno = EINVAL;
2508 #endif
2509  return MHD_NO;
2510  }
2511 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
2512  gnutls_transport_set_int (connection->tls_session,
2513  (int)(client_socket));
2514 #else /* GnuTLS before 3.1.9 or Win x64 */
2515  gnutls_transport_set_ptr (connection->tls_session,
2516  (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2517 #endif /* GnuTLS before 3.1.9 */
2518 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2519  gnutls_transport_set_push_function (connection->tls_session,
2520  MHD_tls_push_func_);
2521 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
2522  if (daemon->https_mem_trust)
2523  gnutls_certificate_server_set_request (connection->tls_session,
2524  GNUTLS_CERT_REQUEST);
2525 #else /* ! HTTPS_SUPPORT */
2526  eno = EINVAL;
2527  goto cleanup;
2528 #endif /* ! HTTPS_SUPPORT */
2529  }
2530 
2531 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2533 #endif
2534  /* Firm check under lock. */
2535  if (daemon->connections >= daemon->connection_limit)
2536  {
2537 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2539 #endif
2540  /* above connection limit - reject */
2541 #ifdef HAVE_MESSAGES
2542  MHD_DLOG (daemon,
2543  _("Server reached connection limit. Closing inbound connection.\n"));
2544 #endif
2545 #if ENFILE
2546  eno = ENFILE;
2547 #endif
2548  goto cleanup;
2549  }
2550  daemon->connections++;
2551  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2552  {
2554  daemon->normal_timeout_tail,
2555  connection);
2556  }
2557  DLL_insert (daemon->connections_head,
2558  daemon->connections_tail,
2559  connection);
2560 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2562 #endif
2563  if (NULL != daemon->notify_connection)
2564  daemon->notify_connection (daemon->notify_connection_cls,
2565  connection,
2566  &connection->socket_context,
2568 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2569  /* attempt to create handler thread */
2570  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2571  {
2572  if (! MHD_create_named_thread_ (&connection->pid,
2573  "MHD-connection",
2574  daemon->thread_stack_size,
2576  connection))
2577  {
2578  eno = errno;
2579 #ifdef HAVE_MESSAGES
2580  MHD_DLOG (daemon,
2581  "Failed to create a thread: %s\n",
2582  MHD_strerror_ (eno));
2583 #endif
2584  goto cleanup;
2585  }
2586  }
2587  else
2588  connection->pid = daemon->pid;
2589 #endif
2590 #ifdef EPOLL_SUPPORT
2591  if (0 != (daemon->options & MHD_USE_EPOLL))
2592  {
2593  if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add))
2594  { /* Do not manipulate EReady DL-list in 'external_add' mode. */
2595  struct epoll_event event;
2596 
2597  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2598  event.data.ptr = connection;
2599  if (0 != epoll_ctl (daemon->epoll_fd,
2600  EPOLL_CTL_ADD,
2601  client_socket,
2602  &event))
2603  {
2604  eno = errno;
2605 #ifdef HAVE_MESSAGES
2606  MHD_DLOG (daemon,
2607  _("Call to epoll_ctl failed: %s\n"),
2609 #endif
2610  goto cleanup;
2611  }
2612  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2613  }
2614  else
2615  {
2616  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
2618  EDLL_insert (daemon->eready_head,
2619  daemon->eready_tail,
2620  connection);
2621  }
2622  }
2623  else /* This 'else' is combined with next 'if'. */
2624 #endif
2625  if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2626  (external_add) &&
2627  (MHD_ITC_IS_VALID_(daemon->itc)) &&
2628  (! MHD_itc_activate_ (daemon->itc, "n")) )
2629  {
2630 #ifdef HAVE_MESSAGES
2631  MHD_DLOG (daemon,
2632  _("Failed to signal new connection via inter-thread communication channel."));
2633 #endif
2634  }
2635  return MHD_YES;
2636  cleanup:
2637  if (NULL != daemon->notify_connection)
2638  daemon->notify_connection (daemon->notify_connection_cls,
2639  connection,
2640  &connection->socket_context,
2642 #ifdef HTTPS_SUPPORT
2643  if (NULL != connection->tls_session)
2644  gnutls_deinit (connection->tls_session);
2645 #endif /* HTTPS_SUPPORT */
2646  MHD_socket_close_chk_ (client_socket);
2647  MHD_ip_limit_del (daemon,
2648  addr,
2649  addrlen);
2650 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2652 #endif
2653  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2654  {
2656  daemon->normal_timeout_tail,
2657  connection);
2658  }
2659  DLL_remove (daemon->connections_head,
2660  daemon->connections_tail,
2661  connection);
2662 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2664 #endif
2665  MHD_pool_destroy (connection->pool);
2666  free (connection->addr);
2667  free (connection);
2668  if (0 != eno)
2669  errno = eno;
2670  else
2671  errno = EINVAL;
2672  return MHD_NO;
2673 }
2674 
2675 
2685 void
2687 {
2688  struct MHD_Daemon *daemon = connection->daemon;
2689 
2690 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2692 #endif
2693  if (connection->resuming)
2694  {
2695  /* suspending again while we didn't even complete resuming yet */
2696  connection->resuming = false;
2697 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2699 #endif
2700  return;
2701  }
2702  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2703  {
2704  if (connection->connection_timeout == daemon->connection_timeout)
2706  daemon->normal_timeout_tail,
2707  connection);
2708  else
2710  daemon->manual_timeout_tail,
2711  connection);
2712  }
2713  DLL_remove (daemon->connections_head,
2714  daemon->connections_tail,
2715  connection);
2716  mhd_assert (! connection->suspended);
2719  connection);
2720  connection->suspended = true;
2721 #ifdef EPOLL_SUPPORT
2722  if (0 != (daemon->options & MHD_USE_EPOLL))
2723  {
2724  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2725  {
2726  EDLL_remove (daemon->eready_head,
2727  daemon->eready_tail,
2728  connection);
2729  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2730  }
2731  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
2732  {
2733  if (0 != epoll_ctl (daemon->epoll_fd,
2734  EPOLL_CTL_DEL,
2735  connection->socket_fd,
2736  NULL))
2737  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
2738  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
2739  }
2740  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
2741  }
2742 #endif
2743 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2745 #endif
2746 }
2747 
2748 
2780 void
2782 {
2783  struct MHD_Daemon * const daemon = connection->daemon;
2784 
2785  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2786  MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2787 #ifdef UPGRADE_SUPPORT
2788  if (NULL != connection->urh)
2789  {
2790 #ifdef HAVE_MESSAGES
2791  MHD_DLOG (daemon,
2792  _("Error: connection scheduled for \"upgrade\" cannot be suspended"));
2793 #endif /* HAVE_MESSAGES */
2794  return;
2795  }
2796 #endif /* UPGRADE_SUPPORT */
2797  internal_suspend_connection_ (connection);
2798 }
2799 
2800 
2809 void
2811 {
2812  struct MHD_Daemon *daemon = connection->daemon;
2813 
2814  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2815  MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2816 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2818 #endif
2819  connection->resuming = true;
2820  daemon->resuming = true;
2821 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2823 #endif
2824  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2825  (! MHD_itc_activate_ (daemon->itc, "r")) )
2826  {
2827 #ifdef HAVE_MESSAGES
2828  MHD_DLOG (daemon,
2829  _("Failed to signal resume via inter-thread communication channel."));
2830 #endif
2831  }
2832 }
2833 
2834 
2844 static int
2846 {
2847  struct MHD_Connection *pos;
2848  struct MHD_Connection *prev = NULL;
2849  int ret;
2850  const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
2851 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2853 #endif
2854  ret = MHD_NO;
2855 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2857 #endif
2858  if (daemon->resuming)
2859  {
2861  /* During shutdown check for resuming is forced. */
2862  mhd_assert((NULL != prev) || (daemon->shutdown));
2863  }
2864 
2865  daemon->resuming = false;
2866 
2867  while (NULL != (pos = prev))
2868  {
2869 #ifdef UPGRADE_SUPPORT
2870  struct MHD_UpgradeResponseHandle * const urh = pos->urh;
2871 #else /* ! UPGRADE_SUPPORT */
2872  static const void * const urh = NULL;
2873 #endif /* ! UPGRADE_SUPPORT */
2874  prev = pos->prev;
2875  if ( (! pos->resuming)
2876 #ifdef UPGRADE_SUPPORT
2877  || ( (NULL != urh) &&
2878  ( (! urh->was_closed) ||
2879  (! urh->clean_ready) ) )
2880 #endif /* UPGRADE_SUPPORT */
2881  )
2882  continue;
2883  ret = MHD_YES;
2884  mhd_assert (pos->suspended);
2887  pos);
2888  pos->suspended = false;
2889  if (NULL == urh)
2890  {
2891  DLL_insert (daemon->connections_head,
2892  daemon->connections_tail,
2893  pos);
2894  if (! used_thr_p_c)
2895  {
2896  /* Reset timeout timer on resume. */
2897  if (0 != pos->connection_timeout)
2899 
2900  if (pos->connection_timeout == daemon->connection_timeout)
2902  daemon->normal_timeout_tail,
2903  pos);
2904  else
2906  daemon->manual_timeout_tail,
2907  pos);
2908  }
2909 #ifdef EPOLL_SUPPORT
2910  if (0 != (daemon->options & MHD_USE_EPOLL))
2911  {
2912  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2913  MHD_PANIC ("Resumed connection was already in EREADY set\n");
2914  /* we always mark resumed connections as ready, as we
2915  might have missed the edge poll event during suspension */
2916  EDLL_insert (daemon->eready_head,
2917  daemon->eready_tail,
2918  pos);
2919  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \
2920  MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
2921  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
2922  }
2923 #endif
2924  }
2925 #ifdef UPGRADE_SUPPORT
2926  else
2927  {
2928  /* Data forwarding was finished (for TLS connections) AND
2929  * application was closed upgraded connection.
2930  * Insert connection into cleanup list. */
2931 
2932  if ( (NULL != daemon->notify_completed) &&
2933  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2934  (pos->client_aware) )
2935  {
2936  daemon->notify_completed (daemon->notify_completed_cls,
2937  pos,
2938  &pos->client_context,
2940  pos->client_aware = false;
2941  }
2942  DLL_insert (daemon->cleanup_head,
2943  daemon->cleanup_tail,
2944  pos);
2945 
2946  }
2947 #endif /* UPGRADE_SUPPORT */
2948  pos->resuming = false;
2949  }
2950 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2952 #endif
2953  if ( (used_thr_p_c) &&
2954  (MHD_NO != ret) )
2955  { /* Wake up suspended connections. */
2956  if (! MHD_itc_activate_(daemon->itc,
2957  "w"))
2958  {
2959 #ifdef HAVE_MESSAGES
2960  MHD_DLOG (daemon,
2961  _("Failed to signal resume of connection via inter-thread communication channel."));
2962 #endif
2963  }
2964  }
2965  return ret;
2966 }
2967 
2968 
2996 int
2998  MHD_socket client_socket,
2999  const struct sockaddr *addr,
3000  socklen_t addrlen)
3001 {
3002  bool sk_nonbl;
3003  if (! MHD_socket_nonblocking_ (client_socket))
3004  {
3005 #ifdef HAVE_MESSAGES
3006  MHD_DLOG (daemon,
3007  _("Failed to set nonblocking mode on new client socket: %s\n"),
3009 #endif
3010  sk_nonbl = 0;
3011  }
3012  else
3013  sk_nonbl = !0;
3014 
3015  if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
3016  (! MHD_socket_noninheritable_ (client_socket)) )
3017  {
3018 #ifdef HAVE_MESSAGES
3019  MHD_DLOG (daemon,
3020  _("Failed to set noninheritable mode on new client socket.\n"));
3021 #endif
3022  }
3023 
3024  if ( (0 == (daemon->options & MHD_USE_TURBO)) &&
3025  (! MHD_socket_buffering_reset_ (client_socket)) )
3026  {
3027 #ifdef HAVE_MESSAGES
3028  MHD_DLOG (daemon,
3029  _("Failed to reset buffering mode on new client socket.\n"));
3030 #endif
3031  }
3032  return internal_add_connection (daemon,
3033  client_socket,
3034  addr,
3035  addrlen,
3036  true,
3037  sk_nonbl);
3038 }
3039 
3040 
3055 static int
3057 {
3058 #if HAVE_INET6
3059  struct sockaddr_in6 addrstorage;
3060 #else
3061  struct sockaddr_in addrstorage;
3062 #endif
3063  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
3064  socklen_t addrlen;
3065  MHD_socket s;
3066  MHD_socket fd;
3067  bool sk_nonbl;
3068 
3069  addrlen = sizeof (addrstorage);
3070  memset (addr,
3071  0,
3072  sizeof (addrstorage));
3073  if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) ||
3074  (daemon->was_quiesced) )
3075  return MHD_NO;
3076 #ifdef USE_ACCEPT4
3077  s = accept4 (fd,
3078  addr,
3079  &addrlen,
3081  sk_nonbl = (MAYBE_SOCK_NONBLOCK != 0);
3082 #else /* ! USE_ACCEPT4 */
3083  s = accept (fd,
3084  addr,
3085  &addrlen);
3086  sk_nonbl = 0;
3087 #endif /* ! USE_ACCEPT4 */
3088  if ( (MHD_INVALID_SOCKET == s) ||
3089  (addrlen <= 0) )
3090  {
3091  const int err = MHD_socket_get_error_ ();
3092 
3093  /* This could be a common occurance with multiple worker threads */
3094  if (MHD_SCKT_ERR_IS_ (err,
3096  return MHD_NO; /* can happen during shutdown */
3098  return MHD_NO; /* do not print error if client just disconnected early */
3099 #ifdef HAVE_MESSAGES
3100  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
3101  MHD_DLOG (daemon,
3102  _("Error accepting connection: %s\n"),
3103  MHD_socket_strerr_(err));
3104 #endif
3105  if (MHD_INVALID_SOCKET != s)
3106  {
3108  }
3109  if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
3110  {
3111  /* system/process out of resources */
3112  if (0 == daemon->connections)
3113  {
3114 #ifdef HAVE_MESSAGES
3115  /* Not setting 'at_limit' flag, as there is no way it
3116  would ever be cleared. Instead trying to produce
3117  bit fat ugly warning. */
3118  MHD_DLOG (daemon,
3119  _("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"));
3120 #endif
3121  }
3122  else
3123  {
3124 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3126 #endif
3127  daemon->at_limit = true;
3128 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3130 #endif
3131 #ifdef HAVE_MESSAGES
3132  MHD_DLOG (daemon,
3133  _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3134  (unsigned int) daemon->connections);
3135 #endif
3136  }
3137  }
3138  return MHD_NO;
3139  }
3140 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK)
3141  if (! MHD_socket_nonblocking_ (s))
3142  {
3143 #ifdef HAVE_MESSAGES
3144  MHD_DLOG (daemon,
3145  _("Failed to set nonblocking mode on incoming connection socket: %s\n"),
3147 #endif
3148  }
3149  else
3150  sk_nonbl = !0;
3151 #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
3152 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
3153  if (! MHD_socket_noninheritable_ (s))
3154  {
3155 #ifdef HAVE_MESSAGES
3156  MHD_DLOG (daemon,
3157  _("Failed to set noninheritable mode on incoming connection socket.\n"));
3158 #endif
3159  }
3160 #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
3161 #ifdef HAVE_MESSAGES
3162 #if DEBUG_CONNECT
3163  MHD_DLOG (daemon,
3164  _("Accepted connection on socket %d\n"),
3165  s);
3166 #endif
3167 #endif
3168  (void) internal_add_connection (daemon,
3169  s,
3170  addr,
3171  addrlen,
3172  false,
3173  sk_nonbl);
3174  return MHD_YES;
3175 }
3176 
3177 
3187 static void
3189 {
3190  struct MHD_Connection *pos;
3191 
3192 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3194 #endif
3195  while (NULL != (pos = daemon->cleanup_tail))
3196  {
3199  pos);
3200 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3202  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3203  (! pos->thread_joined) &&
3204  (! MHD_join_thread_ (pos->pid.handle)) )
3205  MHD_PANIC (_("Failed to join a thread\n"));
3206 #endif
3207 #ifdef UPGRADE_SUPPORT
3208  cleanup_upgraded_connection (pos);
3209 #endif /* UPGRADE_SUPPORT */
3210  MHD_pool_destroy (pos->pool);
3211 #ifdef HTTPS_SUPPORT
3212  if (NULL != pos->tls_session)
3213  gnutls_deinit (pos->tls_session);
3214 #endif /* HTTPS_SUPPORT */
3215 
3216  /* clean up the connection */
3217  if (NULL != daemon->notify_connection)
3219  pos,
3220  &pos->socket_context,
3223  pos->addr,
3224  pos->addr_len);
3225 #ifdef EPOLL_SUPPORT
3226  if (0 != (daemon->options & MHD_USE_EPOLL))
3227  {
3228  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3229  {
3230  EDLL_remove (daemon->eready_head,
3231  daemon->eready_tail,
3232  pos);
3233  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3234  }
3235  if ( (-1 != daemon->epoll_fd) &&
3236  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
3237  {
3238  /* epoll documentation suggests that closing a FD
3239  automatically removes it from the epoll set; however,
3240  this is not true as if we fail to do manually remove it,
3241  we are still seeing an event for this fd in epoll,
3242  causing grief (use-after-free...) --- at least on my
3243  system. */
3244  if (0 != epoll_ctl (daemon->epoll_fd,
3245  EPOLL_CTL_DEL,
3246  pos->socket_fd,
3247  NULL))
3248  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
3249  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
3250  }
3251  }
3252 #endif
3253  if (NULL != pos->response)
3254  {
3256  pos->response = NULL;
3257  }
3258  if (MHD_INVALID_SOCKET != pos->socket_fd)
3260  if (NULL != pos->addr)
3261  free (pos->addr);
3262  free (pos);
3263 
3264 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3266 #endif
3267  daemon->connections--;
3268  daemon->at_limit = false;
3269  }
3270 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3272 #endif
3273 }
3274 
3275 
3296 int
3298  MHD_UNSIGNED_LONG_LONG *timeout)
3299 {
3300  time_t earliest_deadline;
3301  time_t now;
3302  struct MHD_Connection *pos;
3303  bool have_timeout;
3304 
3306  {
3307 #ifdef HAVE_MESSAGES
3308  MHD_DLOG (daemon,
3309  _("Illegal call to MHD_get_timeout\n"));
3310 #endif
3311  return MHD_NO;
3312  }
3313 
3315  {
3316  /* Some data already waiting to be processed. */
3317  *timeout = 0;
3318  return MHD_YES;
3319  }
3320 
3321 #ifdef EPOLL_SUPPORT
3322  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
3323  ((NULL != daemon->eready_head)
3324 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3325  || (NULL != daemon->eready_urh_head)
3326 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
3327  ) )
3328  {
3329  /* Some connection(s) already have some data pending. */
3330  *timeout = 0;
3331  return MHD_YES;
3332  }
3333 #endif /* EPOLL_SUPPORT */
3334 
3335  have_timeout = false;
3336  earliest_deadline = 0; /* avoid compiler warnings */
3337  for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
3338  {
3339  if (0 != pos->connection_timeout)
3340  {
3341  if ( (! have_timeout) ||
3342  (earliest_deadline - pos->last_activity > pos->connection_timeout) )
3343  earliest_deadline = pos->last_activity + pos->connection_timeout;
3344  have_timeout = true;
3345  }
3346  }
3347  /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
3348  pos = daemon->normal_timeout_tail;
3349  if ( (NULL != pos) &&
3350  (0 != pos->connection_timeout) )
3351  {
3352  if ( (! have_timeout) ||
3353  (earliest_deadline - pos->connection_timeout > pos->last_activity) )
3354  earliest_deadline = pos->last_activity + pos->connection_timeout;
3355  have_timeout = true;
3356  }
3357 
3358  if (! have_timeout)
3359  return MHD_NO;
3360  now = MHD_monotonic_sec_counter();
3361  if (earliest_deadline < now)
3362  *timeout = 0;
3363  else
3364  {
3365  const time_t second_left = earliest_deadline - now;
3366 
3367  if (((unsigned long long)second_left) > ULLONG_MAX / 1000)
3368  *timeout = ULLONG_MAX;
3369  else
3370  *timeout = 1000LLU * (unsigned long long) second_left;
3371  }
3372  return MHD_YES;
3373 }
3374 
3375 
3386 static int
3388  const fd_set *read_fd_set,
3389  const fd_set *write_fd_set,
3390  const fd_set *except_fd_set)
3391 {
3392  MHD_socket ds;
3393  struct MHD_Connection *pos;
3394  struct MHD_Connection *prev;
3395 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3396  struct MHD_UpgradeResponseHandle *urh;
3397  struct MHD_UpgradeResponseHandle *urhn;
3398 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3399  /* Reset. New value will be set when connections are processed. */
3400  /* Note: no-op for thread-per-connection as it is always false in that mode. */
3401  daemon->data_already_pending = false;
3402 
3403  /* Clear ITC to avoid spinning select */
3404  /* Do it before any other processing so new signals
3405  will trigger select again and will be processed */
3406  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
3407  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
3408  read_fd_set)) )
3409  MHD_itc_clear_ (daemon->itc);
3410 
3411  /* select connection thread handling type */
3412  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
3413  (! daemon->was_quiesced) &&
3414  (FD_ISSET (ds,
3415  read_fd_set)) )
3416  (void) MHD_accept_connection (daemon);
3417 
3418  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3419  {
3420  /* do not have a thread per connection, process all connections now */
3421  prev = daemon->connections_tail;
3422  while (NULL != (pos = prev))
3423  {
3424  prev = pos->prev;
3425  ds = pos->socket_fd;
3426  if (MHD_INVALID_SOCKET == ds)
3427  continue;
3428  call_handlers (pos,
3429  FD_ISSET (ds,
3430  read_fd_set),
3431  FD_ISSET (ds,
3432  write_fd_set),
3433  FD_ISSET (ds,
3434  except_fd_set));
3435  }
3436  }
3437 
3438 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3439  /* handle upgraded HTTPS connections */
3440  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3441  {
3442  urhn = urh->prev;
3443  /* update urh state based on select() output */
3444  urh_from_fdset (urh,
3445  read_fd_set,
3446  write_fd_set,
3447  except_fd_set);
3448  /* call generic forwarding function for passing data */
3449  process_urh (urh);
3450  /* Finished forwarding? */
3451  if ( (0 == urh->in_buffer_size) &&
3452  (0 == urh->out_buffer_size) &&
3453  (0 == urh->in_buffer_used) &&
3454  (0 == urh->out_buffer_used) )
3455  {
3456  MHD_connection_finish_forward_ (urh->connection);
3457  urh->clean_ready = true;
3458  /* Resuming will move connection to cleanup list. */
3459  MHD_resume_connection(urh->connection);
3460  }
3461  }
3462 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3463  MHD_cleanup_connections (daemon);
3464  return MHD_YES;
3465 }
3466 
3467 
3490 int
3492  const fd_set *read_fd_set,
3493  const fd_set *write_fd_set,
3494  const fd_set *except_fd_set)
3495 {
3496  fd_set es;
3497  if (0 != (daemon->options &
3499  return MHD_NO;
3500  if (NULL == read_fd_set || NULL == write_fd_set)
3501  return MHD_NO;
3502  if (NULL == except_fd_set)
3503  { /* Workaround to maintain backward compatibility. */
3504 #ifdef HAVE_MESSAGES
3505  MHD_DLOG (daemon,
3506  _("MHD_run_from_select() called with except_fd_set "
3507  "set to NULL. Such behavior is deprecated.\n"));
3508 #endif
3509  FD_ZERO (&es);
3510  except_fd_set = &es;
3511  }
3512  if (0 != (daemon->options & MHD_USE_EPOLL))
3513  {
3514 #ifdef EPOLL_SUPPORT
3515  int ret = MHD_epoll (daemon,
3516  MHD_NO);
3517 
3518  MHD_cleanup_connections (daemon);
3519  return ret;
3520 #else /* ! EPOLL_SUPPORT */
3521  return MHD_NO;
3522 #endif /* ! EPOLL_SUPPORT */
3523  }
3524 
3525  /* Resuming external connections when using an extern mainloop */
3526  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3528 
3529  return internal_run_from_select (daemon,
3530  read_fd_set,
3531  write_fd_set,
3532  except_fd_set);
3533 }
3534 
3535 
3544 static int
3545 MHD_select (struct MHD_Daemon *daemon,
3546  int may_block)
3547 {
3548  int num_ready;
3549  fd_set rs;
3550  fd_set ws;
3551  fd_set es;
3552  MHD_socket maxsock;
3553  struct timeval timeout;
3554  struct timeval *tv;
3555  MHD_UNSIGNED_LONG_LONG ltimeout;
3556  int err_state;
3557  MHD_socket ls;
3558 
3559  timeout.tv_sec = 0;
3560  timeout.tv_usec = 0;
3561  if (daemon->shutdown)
3562  return MHD_NO;
3563  FD_ZERO (&rs);
3564  FD_ZERO (&ws);
3565  FD_ZERO (&es);
3566  maxsock = MHD_INVALID_SOCKET;
3567  err_state = MHD_NO;
3568  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3569  (MHD_YES == resume_suspended_connections (daemon)) &&
3570  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
3571  may_block = MHD_NO;
3572 
3573  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3574  {
3575  /* single-threaded, go over everything */
3576  if (MHD_NO ==
3577  internal_get_fdset2 (daemon,
3578  &rs,
3579  &ws,
3580  &es,
3581  &maxsock,
3582  FD_SETSIZE))
3583  {
3584 #ifdef HAVE_MESSAGES
3585  MHD_DLOG (daemon,
3586  _("Could not obtain daemon fdsets"));
3587 #endif
3588  err_state = MHD_YES;
3589  }
3590  }
3591  else
3592  {
3593  /* accept only, have one thread per connection */
3594  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3595  (! daemon->was_quiesced) &&
3596  (! MHD_add_to_fd_set_ (ls,
3597  &rs,
3598  &maxsock,
3599  FD_SETSIZE)) )
3600  {
3601 #ifdef HAVE_MESSAGES
3602  MHD_DLOG (daemon,
3603  _("Could not add listen socket to fdset"));
3604 #endif
3605  return MHD_NO;
3606  }
3607  }
3608  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
3609  (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
3610  &rs,
3611  &maxsock,
3612  FD_SETSIZE)) )
3613  {
3614 #if defined(MHD_WINSOCK_SOCKETS)
3615  /* fdset limit reached, new connections
3616  cannot be handled. Remove listen socket FD
3617  from fdset and retry to add ITC FD. */
3618  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3619  (! daemon->was_quiesced) )
3620  {
3621  FD_CLR (ls,
3622  &rs);
3623  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc),
3624  &rs,
3625  &maxsock,
3626  FD_SETSIZE))
3627  {
3628 #endif /* MHD_WINSOCK_SOCKETS */
3629 #ifdef HAVE_MESSAGES
3630  MHD_DLOG (daemon,
3631  _("Could not add control inter-thread communication channel FD to fdset"));
3632 #endif
3633  err_state = MHD_YES;
3634 #if defined(MHD_WINSOCK_SOCKETS)
3635  }
3636  }
3637 #endif /* MHD_WINSOCK_SOCKETS */
3638  }
3639  /* Stop listening if we are at the configured connection limit */
3640  /* If we're at the connection limit, no point in really
3641  accepting new connections; however, make sure we do not miss
3642  the shutdown OR the termination of an existing connection; so
3643  only do this optimization if we have a signaling ITC in
3644  place. */
3645  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3646  (MHD_ITC_IS_VALID_(daemon->itc)) &&
3647  ( (daemon->connections == daemon->connection_limit) ||
3648  (daemon->at_limit) ) )
3649  {
3650  FD_CLR (ls,
3651  &rs);
3652  }
3653  tv = NULL;
3654  if (MHD_YES == err_state)
3655  may_block = MHD_NO;
3656  if (MHD_NO == may_block)
3657  {
3658  timeout.tv_usec = 0;
3659  timeout.tv_sec = 0;
3660  tv = &timeout;
3661  }
3662  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3663  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
3664  {
3665  /* ltimeout is in ms */
3666  timeout.tv_usec = (ltimeout % 1000) * 1000;
3667  if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
3668  timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
3669  else
3670  timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000);
3671  tv = &timeout;
3672  }
3673  num_ready = MHD_SYS_select_ (maxsock + 1,
3674  &rs,
3675  &ws,
3676  &es,
3677  tv);
3678  if (daemon->shutdown)
3679  return MHD_NO;
3680  if (num_ready < 0)
3681  {
3682  const int err = MHD_socket_get_error_ ();
3683  if (MHD_SCKT_ERR_IS_EINTR_(err))
3684  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3685 #ifdef HAVE_MESSAGES
3686  MHD_DLOG (daemon,
3687  _("select failed: %s\n"),
3688  MHD_socket_strerr_ (err));
3689 #endif
3690  return MHD_NO;
3691  }
3692  if (MHD_YES == internal_run_from_select (daemon,
3693  &rs,
3694  &ws,
3695  &es))
3696  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3697  return MHD_NO;
3698 }
3699 
3700 
3701 #ifdef HAVE_POLL
3702 
3710 static int
3711 MHD_poll_all (struct MHD_Daemon *daemon,
3712  int may_block)
3713 {
3714  unsigned int num_connections;
3715  struct MHD_Connection *pos;
3716  struct MHD_Connection *prev;
3717 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3718  struct MHD_UpgradeResponseHandle *urh;
3719  struct MHD_UpgradeResponseHandle *urhn;
3720 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3721 
3722  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3723  (MHD_YES == resume_suspended_connections (daemon)) )
3724  may_block = MHD_NO;
3725 
3726  /* count number of connections and thus determine poll set size */
3727  num_connections = 0;
3728  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
3729  num_connections++;
3730 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3731  for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
3732  num_connections += 2;
3733 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3734  {
3735  MHD_UNSIGNED_LONG_LONG ltimeout;
3736  unsigned int i;
3737  int timeout;
3738  unsigned int poll_server;
3739  int poll_listen;
3740  int poll_itc_idx;
3741  struct pollfd *p;
3742  MHD_socket ls;
3743 
3744  p = MHD_calloc_ ((2 + num_connections),
3745  sizeof (struct pollfd));
3746  if (NULL == p)
3747  {
3748 #ifdef HAVE_MESSAGES
3749  MHD_DLOG (daemon,
3750  _("Error allocating memory: %s\n"),
3751  MHD_strerror_(errno));
3752 #endif
3753  return MHD_NO;
3754  }
3755  poll_server = 0;
3756  poll_listen = -1;
3757  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3758  (! daemon->was_quiesced) &&
3759  (daemon->connections < daemon->connection_limit) &&
3760  (! daemon->at_limit) )
3761  {
3762  /* only listen if we are not at the connection limit */
3763  p[poll_server].fd = ls;
3764  p[poll_server].events = POLLIN;
3765  p[poll_server].revents = 0;
3766  poll_listen = (int) poll_server;
3767  poll_server++;
3768  }
3769  poll_itc_idx = -1;
3770  if (MHD_ITC_IS_VALID_(daemon->itc))
3771  {
3772  p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
3773  p[poll_server].events = POLLIN;
3774  p[poll_server].revents = 0;
3775  poll_itc_idx = (int) poll_server;
3776  poll_server++;
3777  }
3778  if (may_block == MHD_NO)
3779  timeout = 0;
3780  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
3781  (MHD_YES != MHD_get_timeout (daemon,
3782  &ltimeout)) )
3783  timeout = -1;
3784  else
3785  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
3786 
3787  i = 0;
3788  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
3789  {
3790  p[poll_server+i].fd = pos->socket_fd;
3791  switch (pos->event_loop_info)
3792  {
3794  p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3795  break;
3797  p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3798  break;
3800  p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3801  break;
3803  timeout = 0; /* clean up "pos" immediately */
3804  break;
3805  }
3806  i++;
3807  }
3808 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3809  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
3810  {
3811  urh_to_pollfd(urh, &(p[poll_server+i]));
3812  i += 2;
3813  }
3814 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3815  if (0 == poll_server + num_connections)
3816  {
3817  free(p);
3818  return MHD_YES;
3819  }
3820  if (MHD_sys_poll_(p,
3821  poll_server + num_connections,
3822  timeout) < 0)
3823  {
3824  const int err = MHD_socket_get_error_ ();
3825  if (MHD_SCKT_ERR_IS_EINTR_ (err))
3826  {
3827  free(p);
3828  return MHD_YES;
3829  }
3830 #ifdef HAVE_MESSAGES
3831  MHD_DLOG (daemon,
3832  _("poll failed: %s\n"),
3833  MHD_socket_strerr_ (err));
3834 #endif
3835  free(p);
3836  return MHD_NO;
3837  }
3838 
3839  /* Reset. New value will be set when connections are processed. */
3840  daemon->data_already_pending = false;
3841 
3842  /* handle ITC FD */
3843  /* do it before any other processing so
3844  new signals will be processed in next loop */
3845  if ( (-1 != poll_itc_idx) &&
3846  (0 != (p[poll_itc_idx].revents & POLLIN)) )
3847  MHD_itc_clear_ (daemon->itc);
3848 
3849  /* handle shutdown */
3850  if (daemon->shutdown)
3851  {
3852  free(p);
3853  return MHD_NO;
3854  }
3855  i = 0;
3856  prev = daemon->connections_tail;
3857  while (NULL != (pos = prev))
3858  {
3859  prev = pos->prev;
3860  /* first, sanity checks */
3861  if (i >= num_connections)
3862  break; /* connection list changed somehow, retry later ... */
3863  if (p[poll_server+i].fd != pos->socket_fd)
3864  continue; /* fd mismatch, something else happened, retry later ... */
3865  call_handlers (pos,
3866  0 != (p[poll_server+i].revents & POLLIN),
3867  0 != (p[poll_server+i].revents & POLLOUT),
3868  0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3869  i++;
3870  }
3871 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3872  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3873  {
3874  if (i >= num_connections)
3875  break; /* connection list changed somehow, retry later ... */
3876 
3877  /* Get next connection here as connection can be removed
3878  * from 'daemon->urh_head' list. */
3879  urhn = urh->prev;
3880  /* Check for fd mismatch. FIXME: required for safety? */
3881  if ((p[poll_server+i].fd != urh->connection->socket_fd) ||
3882  (p[poll_server+i+1].fd != urh->mhd.socket))
3883  break;
3884  urh_from_pollfd (urh,
3885  &p[poll_server+i]);
3886  i += 2;
3887  process_urh (urh);
3888  /* Finished forwarding? */
3889  if ( (0 == urh->in_buffer_size) &&
3890  (0 == urh->out_buffer_size) &&
3891  (0 == urh->in_buffer_used) &&
3892  (0 == urh->out_buffer_used) )
3893  {
3894  /* MHD_connection_finish_forward_() will remove connection from
3895  * 'daemon->urh_head' list. */
3896  MHD_connection_finish_forward_ (urh->connection);
3897  urh->clean_ready = true;
3898  /* If 'urh->was_closed' already was set to true, connection will be
3899  * moved immediately to cleanup list. Otherwise connection
3900  * will stay in suspended list until 'urh' will be marked
3901  * with 'was_closed' by application. */
3902  MHD_resume_connection(urh->connection);
3903  }
3904  }
3905 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3906  /* handle 'listen' FD */
3907  if ( (-1 != poll_listen) &&
3908  (0 != (p[poll_listen].revents & POLLIN)) )
3909  (void) MHD_accept_connection (daemon);
3910 
3911  free(p);
3912  }
3913  return MHD_YES;
3914 }
3915 
3916 
3924 static int
3925 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
3926  int may_block)
3927 {
3928  struct pollfd p[2];
3929  int timeout;
3930  unsigned int poll_count;
3931  int poll_listen;
3932  int poll_itc_idx;
3933  MHD_socket ls;
3934 
3935  memset (&p,
3936  0,
3937  sizeof (p));
3938  poll_count = 0;
3939  poll_listen = -1;
3940  poll_itc_idx = -1;
3941  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3942  (! daemon->was_quiesced) )
3943 
3944  {
3945  p[poll_count].fd = ls;
3946  p[poll_count].events = POLLIN;
3947  p[poll_count].revents = 0;
3948  poll_listen = poll_count;
3949  poll_count++;
3950  }
3951  if (MHD_ITC_IS_VALID_(daemon->itc))
3952  {
3953  p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
3954  p[poll_count].events = POLLIN;
3955  p[poll_count].revents = 0;
3956  poll_itc_idx = poll_count;
3957  poll_count++;
3958  }
3959 
3960  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3961  (void) resume_suspended_connections (daemon);
3962 
3963  if (MHD_NO == may_block)
3964  timeout = 0;
3965  else
3966  timeout = -1;
3967  if (0 == poll_count)
3968  return MHD_YES;
3969  if (MHD_sys_poll_(p,
3970  poll_count,
3971  timeout) < 0)
3972  {
3973  const int err = MHD_socket_get_error_ ();
3974 
3975  if (MHD_SCKT_ERR_IS_EINTR_ (err))
3976  return MHD_YES;
3977 #ifdef HAVE_MESSAGES
3978  MHD_DLOG (daemon,
3979  _("poll failed: %s\n"),
3980  MHD_socket_strerr_ (err));
3981 #endif
3982  return MHD_NO;
3983  }
3984  if ( (-1 != poll_itc_idx) &&
3985  (0 != (p[poll_itc_idx].revents & POLLIN)) )
3986  MHD_itc_clear_ (daemon->itc);
3987 
3988  /* handle shutdown */
3989  if (daemon->shutdown)
3990  return MHD_NO;
3991  if ( (-1 != poll_listen) &&
3992  (0 != (p[poll_listen].revents & POLLIN)) )
3993  (void) MHD_accept_connection (daemon);
3994  return MHD_YES;
3995 }
3996 #endif
3997 
3998 
4006 static int
4007 MHD_poll (struct MHD_Daemon *daemon,
4008  int may_block)
4009 {
4010 #ifdef HAVE_POLL
4011  if (daemon->shutdown)
4012  return MHD_NO;
4013  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4014  return MHD_poll_all (daemon,
4015  may_block);
4016  return MHD_poll_listen_socket (daemon,
4017  may_block);
4018 #else
4019  (void) daemon;
4020  (void) may_block;
4021  return MHD_NO;
4022 #endif
4023 }
4024 
4025 
4026 #ifdef EPOLL_SUPPORT
4027 
4036 #define MAX_EVENTS 128
4037 
4038 
4039 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4040 
4048 static bool
4049 is_urh_ready(struct MHD_UpgradeResponseHandle * const urh)
4050 {
4051  const struct MHD_Connection * const connection = urh->connection;
4052 
4053  if ( (0 == urh->in_buffer_size) &&
4054  (0 == urh->out_buffer_size) &&
4055  (0 == urh->in_buffer_used) &&
4056  (0 == urh->out_buffer_used) )
4057  return false;
4058  if (connection->daemon->shutdown)
4059  return true;
4060  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
4061  (connection->tls_read_ready) ) &&
4062  (urh->in_buffer_used < urh->in_buffer_size) )
4063  return true;
4064  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
4065  (urh->out_buffer_used < urh->out_buffer_size) )
4066  return true;
4067  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
4068  (urh->out_buffer_used > 0) )
4069  return true;
4070  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
4071  (urh->in_buffer_used > 0) )
4072  return true;
4073  return false;
4074 }
4075 
4076 
4085 static int
4086 run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4087 {
4088  struct epoll_event events[MAX_EVENTS];
4089  int num_events;
4090  struct MHD_UpgradeResponseHandle * pos;
4091  struct MHD_UpgradeResponseHandle * prev;
4092 
4093  num_events = MAX_EVENTS;
4094  while (MAX_EVENTS == num_events)
4095  {
4096  unsigned int i;
4097  /* update event masks */
4098  num_events = epoll_wait (daemon->epoll_upgrade_fd,
4099  events,
4100  MAX_EVENTS,
4101  0);
4102  if (-1 == num_events)
4103  {
4104  const int err = MHD_socket_get_error_ ();
4105  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4106  return MHD_YES;
4107 #ifdef HAVE_MESSAGES
4108  MHD_DLOG (daemon,
4109  _("Call to epoll_wait failed: %s\n"),
4110  MHD_socket_strerr_ (err));
4111 #endif
4112  return MHD_NO;
4113  }
4114  for (i = 0; i < (unsigned int) num_events; i++)
4115  {
4116  struct UpgradeEpollHandle * const ueh = events[i].data.ptr;
4117  struct MHD_UpgradeResponseHandle * const urh = ueh->urh;
4118  bool new_err_state = false;
4119 
4120  if (urh->clean_ready)
4121  continue;
4122 
4123  /* Update ueh state based on what is ready according to epoll() */
4124  if (0 != (events[i].events & EPOLLIN))
4125  ueh->celi |= MHD_EPOLL_STATE_READ_READY;
4126  if (0 != (events[i].events & EPOLLOUT))
4127  ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
4128  if (0 != (events[i].events & EPOLLHUP))
4130 
4131  if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
4132  (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4133  {
4134  /* Process new error state only one time
4135  * and avoid continuously marking this connection
4136  * as 'ready'. */
4137  ueh->celi |= MHD_EPOLL_STATE_ERROR;
4138  new_err_state = true;
4139  }
4140 
4141  if (! urh->in_eready_list)
4142  {
4143  if (new_err_state ||
4144  is_urh_ready(urh))
4145  {
4146  EDLL_insert (daemon->eready_urh_head,
4147  daemon->eready_urh_tail,
4148  urh);
4149  urh->in_eready_list = true;
4150  }
4151  }
4152  }
4153  }
4154  prev = daemon->eready_urh_tail;
4155  while (NULL != (pos = prev))
4156  {
4157  prev = pos->prevE;
4158  process_urh (pos);
4159  if (! is_urh_ready(pos))
4160  {
4161  EDLL_remove (daemon->eready_urh_head,
4162  daemon->eready_urh_tail,
4163  pos);
4164  pos->in_eready_list = false;
4165  }
4166  /* Finished forwarding? */
4167  if ( (0 == pos->in_buffer_size) &&
4168  (0 == pos->out_buffer_size) &&
4169  (0 == pos->in_buffer_used) &&
4170  (0 == pos->out_buffer_used) )
4171  {
4172  MHD_connection_finish_forward_ (pos->connection);
4173  pos->clean_ready = true;
4174  /* If 'pos->was_closed' already was set to true, connection
4175  * will be moved immediately to cleanup list. Otherwise
4176  * connection will stay in suspended list until 'pos' will
4177  * be marked with 'was_closed' by application. */
4178  MHD_resume_connection(pos->connection);
4179  }
4180  }
4181 
4182  return MHD_YES;
4183 }
4184 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4185 
4186 
4190 static const char * const epoll_itc_marker = "itc_marker";
4191 
4192 
4201 static int
4202 MHD_epoll (struct MHD_Daemon *daemon,
4203  int may_block)
4204 {
4205 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4206  static const char * const upgrade_marker = "upgrade_ptr";
4207 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4208  struct MHD_Connection *pos;
4209  struct MHD_Connection *prev;
4210  struct epoll_event events[MAX_EVENTS];
4211  struct epoll_event event;
4212  int timeout_ms;
4213  MHD_UNSIGNED_LONG_LONG timeout_ll;
4214  int num_events;
4215  unsigned int i;
4216  MHD_socket ls;
4217 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4218  int run_upgraded = MHD_NO;
4219 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4220 
4221  if (-1 == daemon->epoll_fd)
4222  return MHD_NO; /* we're down! */
4223  if (daemon->shutdown)
4224  return MHD_NO;
4225  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4226  (! daemon->was_quiesced) &&
4227  (daemon->connections < daemon->connection_limit) &&
4228  (! daemon->listen_socket_in_epoll) &&
4229  (! daemon->at_limit) )
4230  {
4231  event.events = EPOLLIN;
4232  event.data.ptr = daemon;
4233  if (0 != epoll_ctl (daemon->epoll_fd,
4234  EPOLL_CTL_ADD,
4235  ls,
4236  &event))
4237  {
4238 #ifdef HAVE_MESSAGES
4239  MHD_DLOG (daemon,
4240  _("Call to epoll_ctl failed: %s\n"),
4242 #endif
4243  return MHD_NO;
4244  }
4245  daemon->listen_socket_in_epoll = true;
4246  }
4247  if ( (daemon->was_quiesced) &&
4248  (daemon->listen_socket_in_epoll) )
4249  {
4250  if ( (0 != epoll_ctl (daemon->epoll_fd,
4251  EPOLL_CTL_DEL,
4252  ls,
4253  NULL)) &&
4254  (ENOENT != errno) ) /* ENOENT can happen due to race with
4255  #MHD_quiesce_daemon() */
4256  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4257  daemon->listen_socket_in_epoll = false;
4258  }
4259 
4260 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4261  if ( (! daemon->upgrade_fd_in_epoll) &&
4262  (-1 != daemon->epoll_upgrade_fd) )
4263  {
4264  event.events = EPOLLIN | EPOLLOUT;
4265  event.data.ptr = (void *) upgrade_marker;
4266  if (0 != epoll_ctl (daemon->epoll_fd,
4267  EPOLL_CTL_ADD,
4268  daemon->epoll_upgrade_fd,
4269  &event))
4270  {
4271 #ifdef HAVE_MESSAGES
4272  MHD_DLOG (daemon,
4273  _("Call to epoll_ctl failed: %s\n"),
4275 #endif
4276  return MHD_NO;
4277  }
4278  daemon->upgrade_fd_in_epoll = true;
4279  }
4280 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4281  if ( (daemon->listen_socket_in_epoll) &&
4282  ( (daemon->connections == daemon->connection_limit) ||
4283  (daemon->at_limit) ||
4284  (daemon->was_quiesced) ) )
4285  {
4286  /* we're at the connection limit, disable listen socket
4287  for event loop for now */
4288  if (0 != epoll_ctl (daemon->epoll_fd,
4289  EPOLL_CTL_DEL,
4290  ls,
4291  NULL))
4292  MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4293  daemon->listen_socket_in_epoll = false;
4294  }
4295 
4296  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
4297  (MHD_YES == resume_suspended_connections (daemon)) )
4298  may_block = MHD_NO;
4299 
4300  if (MHD_YES == may_block)
4301  {
4302  if (MHD_YES == MHD_get_timeout (daemon,
4303  &timeout_ll))
4304  {
4305  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
4306  timeout_ms = INT_MAX;
4307  else
4308  timeout_ms = (int) timeout_ll;
4309  }
4310  else
4311  timeout_ms = -1;
4312  }
4313  else
4314  timeout_ms = 0;
4315 
4316  /* Reset. New value will be set when connections are processed. */
4317  /* Note: Used mostly for uniformity here as same situation is
4318  * signaled in epoll mode by non-empty eready DLL. */
4319  daemon->data_already_pending = false;
4320 
4321  /* drain 'epoll' event queue; need to iterate as we get at most
4322  MAX_EVENTS in one system call here; in practice this should
4323  pretty much mean only one round, but better an extra loop here
4324  than unfair behavior... */
4325  num_events = MAX_EVENTS;
4326  while (MAX_EVENTS == num_events)
4327  {
4328  /* update event masks */
4329  num_events = epoll_wait (daemon->epoll_fd,
4330  events,
4331  MAX_EVENTS,
4332  timeout_ms);
4333  if (-1 == num_events)
4334  {
4335  const int err = MHD_socket_get_error_ ();
4336  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4337  return MHD_YES;
4338 #ifdef HAVE_MESSAGES
4339  MHD_DLOG (daemon,
4340  _("Call to epoll_wait failed: %s\n"),
4341  MHD_socket_strerr_ (err));
4342 #endif
4343  return MHD_NO;
4344  }
4345  for (i=0;i<(unsigned int) num_events;i++)
4346  {
4347  /* First, check for the values of `ptr` that would indicate
4348  that this event is not about a normal connection. */
4349  if (NULL == events[i].data.ptr)
4350  continue; /* shutdown signal! */
4351 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4352  if (upgrade_marker == events[i].data.ptr)
4353  {
4354  /* activity on an upgraded connection, we process
4355  those in a separate epoll() */
4356  run_upgraded = MHD_YES;
4357  continue;
4358  }
4359 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4360  if (epoll_itc_marker == events[i].data.ptr)
4361  {
4362  /* It's OK to clear ITC here as all external
4363  conditions will be processed later. */
4364  MHD_itc_clear_ (daemon->itc);
4365  continue;
4366  }
4367  if (daemon == events[i].data.ptr)
4368  {
4369  /* Check for error conditions on listen socket. */
4370  /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
4371  if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4372  {
4373  unsigned int series_length = 0;
4374  /* Run 'accept' until it fails or daemon at limit of connections.
4375  * Do not accept more then 10 connections at once. The rest will
4376  * be accepted on next turn (level trigger is used for listen
4377  * socket). */
4378  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
4379  (series_length < 10) &&
4380  (daemon->connections < daemon->connection_limit) &&
4381  (! daemon->at_limit) )
4382  series_length++;
4383  }
4384  continue;
4385  }
4386  /* this is an event relating to a 'normal' connection,
4387  remember the event and if appropriate mark the
4388  connection as 'eready'. */
4389  pos = events[i].data.ptr;
4390  /* normal processing: update read/write data */
4391  if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4392  {
4393  pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
4394  if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
4395  {
4396  EDLL_insert (daemon->eready_head,
4397  daemon->eready_tail,
4398  pos);
4399  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4400  }
4401  }
4402  else
4403  {
4404  if (0 != (events[i].events & EPOLLIN))
4405  {
4406  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
4407  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
4408  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
4409  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4410  {
4411  EDLL_insert (daemon->eready_head,
4412  daemon->eready_tail,
4413  pos);
4414  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4415  }
4416  }
4417  if (0 != (events[i].events & EPOLLOUT))
4418  {
4419  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
4420  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
4421  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4422  {
4423  EDLL_insert (daemon->eready_head,
4424  daemon->eready_tail,
4425  pos);
4426  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4427  }
4428  }
4429  }
4430  }
4431  }
4432 
4433 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4434  if (MHD_YES == run_upgraded)
4435  run_epoll_for_upgrade (daemon);
4436 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4437 
4438  /* process events for connections */
4439  prev = daemon->eready_tail;
4440  while (NULL != (pos = prev))
4441  {
4442  prev = pos->prevE;
4443  call_handlers (pos,
4444  0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
4445  0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
4446  0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
4449  {
4450  if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info &&
4451  0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) ||
4453  0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) ||
4455  {
4456  EDLL_remove (daemon->eready_head,
4457  daemon->eready_tail,
4458  pos);
4459  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
4460  }
4461  }
4462  }
4463 
4464  /* Finally, handle timed-out connections; we need to do this here
4465  as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
4466  as the other event loops do. As timeouts do not get an explicit
4467  event, we need to find those connections that might have timed out
4468  here.
4469 
4470  Connections with custom timeouts must all be looked at, as we
4471  do not bother to sort that (presumably very short) list. */
4472  prev = daemon->manual_timeout_tail;
4473  while (NULL != (pos = prev))
4474  {
4475  prev = pos->prevX;
4477  }
4478  /* Connections with the default timeout are sorted by prepending
4479  them to the head of the list whenever we touch the connection;
4480  thus it suffices to iterate from the tail until the first
4481  connection is NOT timed out */
4482  prev = daemon->normal_timeout_tail;
4483  while (NULL != (pos = prev))
4484  {
4485  prev = pos->prevX;
4487  if (MHD_CONNECTION_CLOSED != pos->state)
4488  break; /* sorted by timeout, no need to visit the rest! */
4489  }
4490  return MHD_YES;
4491 }
4492 #endif
4493 
4494 
4515 int
4516 MHD_run (struct MHD_Daemon *daemon)
4517 {
4518  if ( (daemon->shutdown) ||
4519  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
4520  return MHD_NO;
4521  if (0 != (daemon->options & MHD_USE_POLL))
4522  {
4523  MHD_poll (daemon, MHD_NO);
4524  MHD_cleanup_connections (daemon);
4525  }
4526 #ifdef EPOLL_SUPPORT
4527  else if (0 != (daemon->options & MHD_USE_EPOLL))
4528  {
4529  MHD_epoll (daemon, MHD_NO);
4530  MHD_cleanup_connections (daemon);
4531  }
4532 #endif
4533  else
4534  {
4535  MHD_select (daemon, MHD_NO);
4536  /* MHD_select does MHD_cleanup_connections already */
4537  }
4538  return MHD_YES;
4539 }
4540 
4541 
4550 static void
4552 {
4553  struct MHD_Daemon *daemon = pos->daemon;
4554 
4555  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4556  {
4558  return; /* must let thread to do the rest */
4559  }
4560  MHD_connection_close_ (pos,
4562 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4564 #endif
4565  mhd_assert (! pos->suspended);
4566  mhd_assert (! pos->resuming);
4567  if (pos->connection_timeout == daemon->connection_timeout)
4569  daemon->normal_timeout_tail,
4570  pos);
4571  else
4573  daemon->manual_timeout_tail,
4574  pos);
4575  DLL_remove (daemon->connections_head,
4576  daemon->connections_tail,
4577  pos);
4578  DLL_insert (daemon->cleanup_head,
4579  daemon->cleanup_tail,
4580  pos);
4581 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4583 #endif
4584 }
4585 
4586 
4587 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4588 
4595 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4596 MHD_polling_thread (void *cls)
4597 {
4598  struct MHD_Daemon *daemon = cls;
4599 
4600  MHD_thread_init_(&(daemon->pid));
4601  while (! daemon->shutdown)
4602  {
4603  if (0 != (daemon->options & MHD_USE_POLL))
4604  MHD_poll (daemon, MHD_YES);
4605 #ifdef EPOLL_SUPPORT
4606  else if (0 != (daemon->options & MHD_USE_EPOLL))
4607  MHD_epoll (daemon, MHD_YES);
4608 #endif
4609  else
4610  MHD_select (daemon, MHD_YES);
4611  MHD_cleanup_connections (daemon);
4612  }
4613 
4614  /* Resume any pending for resume connections, join
4615  * all connection's threads (if any) and finally cleanup
4616  * everything. */
4617  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
4619  close_all_connections (daemon);
4620 
4621  return (MHD_THRD_RTRN_TYPE_)0;
4622 }
4623 #endif
4624 
4625 
4637 static size_t
4638 unescape_wrapper (void *cls,
4639  struct MHD_Connection *connection,
4640  char *val)
4641 {
4642  (void) cls; /* Mute compiler warning. */
4643 
4644  (void) connection; /* Mute compiler warning. */
4645  return MHD_http_unescape (val);
4646 }
4647 
4648 
4669 struct MHD_Daemon *
4670 MHD_start_daemon (unsigned int flags,
4671  uint16_t port,
4673  void *apc_cls,
4675  void *dh_cls,
4676  ...)
4677 {
4678  struct MHD_Daemon *daemon;
4679  va_list ap;
4680 
4681  va_start (ap,
4682  dh_cls);
4683  daemon = MHD_start_daemon_va (flags,
4684  port,
4685  apc,
4686  apc_cls,
4687  dh,
4688  dh_cls,
4689  ap);
4690  va_end (ap);
4691  return daemon;
4692 }
4693 
4694 
4714 MHD_socket
4716 {
4717 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4718  unsigned int i;
4719 #endif
4720  MHD_socket ret;
4721 
4722  ret = daemon->listen_fd;
4723  if (MHD_INVALID_SOCKET == ret)
4724  return MHD_INVALID_SOCKET;
4725  if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
4726  (0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) )
4727  {
4728 #ifdef HAVE_MESSAGES
4729  MHD_DLOG (daemon,
4730  "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4731 #endif
4732  return MHD_INVALID_SOCKET;
4733  }
4734 
4735 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4736  if (NULL != daemon->worker_pool)
4737  for (i = 0; i < daemon->worker_pool_size; i++)
4738  {
4739  daemon->worker_pool[i].was_quiesced = true;
4740 #ifdef EPOLL_SUPPORT
4741  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4742  (-1 != daemon->worker_pool[i].epoll_fd) &&
4743  (daemon->worker_pool[i].listen_socket_in_epoll) )
4744  {
4745  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
4746  EPOLL_CTL_DEL,
4747  ret,
4748  NULL))
4749  MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4750  daemon->worker_pool[i].listen_socket_in_epoll = false;
4751  }
4752  else
4753 #endif
4754  if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
4755  {
4756  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
4757  MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
4758  }
4759  }
4760 #endif
4761  daemon->was_quiesced = true;
4762 #ifdef EPOLL_SUPPORT
4763  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4764  (-1 != daemon->epoll_fd) &&
4765  (daemon->listen_socket_in_epoll) )
4766  {
4767  if ( (0 != epoll_ctl (daemon->epoll_fd,
4768  EPOLL_CTL_DEL,
4769  ret,
4770  NULL)) &&
4771  (ENOENT != errno) ) /* ENOENT can happen due to race with
4772  #MHD_epoll() */
4773  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4774  daemon->listen_socket_in_epoll = false;
4775  }
4776 #endif
4777  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
4778  (! MHD_itc_activate_ (daemon->itc, "q")) )
4779  MHD_PANIC (_("failed to signal quiesce via inter-thread communication channel"));
4780  return ret;
4781 }
4782 
4783 
4791 typedef void
4793  const char *format,
4794  va_list va);
4795 
4796 
4805 static int
4806 parse_options_va (struct MHD_Daemon *daemon,
4807  const struct sockaddr **servaddr,
4808  va_list ap);
4809 
4810 
4819 static int
4820 parse_options (struct MHD_Daemon *daemon,
4821  const struct sockaddr **servaddr,
4822  ...)
4823 {
4824  va_list ap;
4825  int ret;
4826 
4827  va_start (ap, servaddr);
4828  ret = parse_options_va (daemon,
4829  servaddr,
4830  ap);
4831  va_end (ap);
4832  return ret;
4833 }
4834 
4835 
4844 static int
4846  const struct sockaddr **servaddr,
4847  va_list ap)
4848 {
4849  enum MHD_OPTION opt;
4850  struct MHD_OptionItem *oa;
4851  unsigned int i;
4852  unsigned int uv;
4853 #ifdef HTTPS_SUPPORT
4854  int ret;
4855  const char *pstr;
4856 #if GNUTLS_VERSION_MAJOR >= 3
4857  gnutls_certificate_retrieve_function2 *pgcrf;
4858 #endif
4859 #endif /* HTTPS_SUPPORT */
4860 
4861  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
4862  {
4863  switch (opt)
4864  {
4866  daemon->pool_size = va_arg (ap,
4867  size_t);
4868  break;
4870  daemon->pool_increment= va_arg (ap,
4871  size_t);
4872  break;
4874  daemon->connection_limit = va_arg (ap,
4875  unsigned int);
4876  break;
4878  uv = va_arg (ap,
4879  unsigned int);
4880  /* Next comparison could be always false on some platforms and whole branch will
4881  * be optimized out on those platforms. On others it will be compiled into real
4882  * check. */
4883  if (TIME_T_MAX < uv) /* Compiler may warn on some platforms, ignore warning. */
4884  {
4885 #ifdef HAVE_MESSAGES
4886  MHD_DLOG (daemon,
4887  _("Warning: Too large timeout value, ignored.\n"));
4888 #endif
4889  daemon->connection_timeout = 0;
4890  }
4891  else
4892  daemon->connection_timeout = (time_t)uv;
4893  break;
4895  daemon->notify_completed = va_arg (ap,
4897  daemon->notify_completed_cls = va_arg (ap,
4898  void *);
4899  break;
4901  daemon->notify_connection = va_arg (ap,
4903  daemon->notify_connection_cls = va_arg (ap,
4904  void *);
4905  break;
4907  daemon->per_ip_connection_limit = va_arg (ap,
4908  unsigned int);
4909  break;
4910  case MHD_OPTION_SOCK_ADDR:
4911  *servaddr = va_arg (ap,
4912  const struct sockaddr *);
4913  break;
4915  daemon->uri_log_callback = va_arg (ap,
4916  LogCallback);
4917  daemon->uri_log_callback_cls = va_arg (ap,
4918  void *);
4919  break;
4920 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4922  daemon->worker_pool_size = va_arg (ap,
4923  unsigned int);
4924  if (0 == daemon->worker_pool_size)
4925  {
4926 #ifdef HAVE_MESSAGES
4927  MHD_DLOG (daemon,
4928  _("Warning: Zero size, specified for thread pool size, is ignored. "
4929  "Thread pool is not used.\n"));
4930 #endif
4931  }
4932  else if (1 == daemon->worker_pool_size)
4933  {
4934 #ifdef HAVE_MESSAGES
4935  MHD_DLOG (daemon,
4936  _("Warning: \"1\", specified for thread pool size, is ignored. "
4937  "Thread pool is not used.\n"));
4938 #endif
4939  daemon->worker_pool_size = 0;
4940  }
4941  /* Next comparison could be always false on some platforms and whole branch will
4942  * be optimized out on those platforms. On others it will be compiled into real
4943  * check. */
4944  else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */
4945  {
4946 #ifdef HAVE_MESSAGES
4947  MHD_DLOG (daemon,
4948  _("Specified thread pool size (%u) too big\n"),
4949  daemon->worker_pool_size);
4950 #endif
4951  return MHD_NO;
4952  }
4953  else
4954  {
4955  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
4956  {
4957 #ifdef HAVE_MESSAGES
4958  MHD_DLOG (daemon,
4959  _("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
4960  "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
4961 #endif
4962  return MHD_NO;
4963  }
4964  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4965  {
4966 #ifdef HAVE_MESSAGES
4967  MHD_DLOG (daemon,
4968  _("Both MHD_OPTION_THREAD_POOL_SIZE option and "
4969  "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
4970 #endif
4971  return MHD_NO;
4972  }
4973  }
4974  break;
4975 #endif
4976 #ifdef HTTPS_SUPPORT
4978  pstr = va_arg (ap,
4979  const char *);
4980  if (0 != (daemon->options & MHD_USE_TLS))
4981  daemon->https_mem_key = pstr;
4982 #ifdef HAVE_MESSAGES
4983  else
4984  MHD_DLOG (daemon,
4985  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4986  opt);
4987 #endif
4988  break;
4990  pstr = va_arg (ap,
4991  const char *);
4992  if (0 != (daemon->options & MHD_USE_TLS))
4993  daemon->https_key_password = pstr;
4994 #ifdef HAVE_MESSAGES
4995  else
4996  MHD_DLOG (daemon,
4997  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4998  opt);
4999 #endif
5000  break;
5002  pstr = va_arg (ap,
5003  const char *);
5004  if (0 != (daemon->options & MHD_USE_TLS))
5005  daemon->https_mem_cert = pstr;
5006 #ifdef HAVE_MESSAGES
5007  else
5008  MHD_DLOG (daemon,
5009  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5010  opt);
5011 #endif
5012  break;
5014  pstr = va_arg (ap,
5015  const char *);
5016  if (0 != (daemon->options & MHD_USE_TLS))
5017  daemon->https_mem_trust = pstr;
5018 #ifdef HAVE_MESSAGES
5019  else
5020  MHD_DLOG (daemon,
5021  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5022  opt);
5023 #endif
5024  break;
5026  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5027  int);
5028  break;
5030  pstr = va_arg (ap,
5031  const char *);
5032  if (0 != (daemon->options & MHD_USE_TLS))
5033  {
5034  gnutls_datum_t dhpar;
5035 
5036  if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5037  {
5038 #ifdef HAVE_MESSAGES
5039  MHD_DLOG (daemon,
5040  _("Error initializing DH parameters\n"));
5041 #endif
5042  return MHD_NO;
5043  }
5044  dhpar.data = (unsigned char *) pstr;
5045  dhpar.size = strlen (pstr);
5046  if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5047  &dhpar,
5048  GNUTLS_X509_FMT_PEM) < 0)
5049  {
5050 #ifdef HAVE_MESSAGES
5051  MHD_DLOG (daemon,
5052  _("Bad Diffie-Hellman parameters format\n"));
5053 #endif
5054  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5055  return MHD_NO;
5056  }
5057  daemon->have_dhparams = true;
5058  }
5059 #ifdef HAVE_MESSAGES
5060  else
5061  MHD_DLOG (daemon,
5062  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5063  opt);
5064 #endif
5065  break;
5067  pstr = va_arg (ap,
5068  const char *);
5069  if (0 != (daemon->options & MHD_USE_TLS))
5070  {
5071  gnutls_priority_deinit (daemon->priority_cache);
5072  ret = gnutls_priority_init (&daemon->priority_cache,
5073  pstr,
5074  NULL);
5075  if (GNUTLS_E_SUCCESS != ret)
5076  {
5077 #ifdef HAVE_MESSAGES
5078  MHD_DLOG (daemon,
5079  _("Setting priorities to `%s' failed: %s\n"),
5080  pstr,
5081  gnutls_strerror (ret));
5082 #endif
5083  daemon->priority_cache = NULL;
5084  return MHD_NO;
5085  }
5086  }
5087 #ifdef HAVE_MESSAGES
5088  else
5089  MHD_DLOG (daemon,
5090  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5091  opt);
5092 #endif
5093  break;
5095 #if GNUTLS_VERSION_MAJOR < 3
5096 #ifdef HAVE_MESSAGES
5097  MHD_DLOG (daemon,
5098  _("MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5099 #endif
5100  return MHD_NO;
5101 #else
5102  pgcrf = va_arg (ap,
5103  gnutls_certificate_retrieve_function2 *);
5104  if (0 != (daemon->options & MHD_USE_TLS))
5105  daemon->cert_callback = pgcrf;
5106  else
5107 #ifdef HAVE_MESSAGES
5108  MHD_DLOG (daemon,
5109  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5110  opt);
5111 #endif
5112  break;
5113 #endif
5114 #endif /* HTTPS_SUPPORT */
5115 #ifdef DAUTH_SUPPORT
5117  daemon->digest_auth_rand_size = va_arg (ap,
5118  size_t);
5119  daemon->digest_auth_random = va_arg (ap,
5120  const char *);
5121  break;
5123  daemon->nonce_nc_size = va_arg (ap,
5124  unsigned int);
5125  break;
5126 #endif
5128  if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET))
5129  {
5130 #ifdef HAVE_MESSAGES
5131  MHD_DLOG (daemon,
5132  _("MHD_OPTION_LISTEN_SOCKET specified for daemon "
5133  "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5134 #endif
5135  return MHD_NO;
5136  }
5137  else
5138  daemon->listen_fd = va_arg (ap,
5139  MHD_socket);
5140  break;
5142 #ifdef HAVE_MESSAGES
5143  daemon->custom_error_log = va_arg (ap,
5145  daemon->custom_error_log_cls = va_arg (ap,
5146  void *);
5147 #else
5148  va_arg (ap,
5150  va_arg (ap,
5151  void *);
5152 #endif
5153  break;
5154 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5156  daemon->thread_stack_size = va_arg (ap,
5157  size_t);
5158  break;
5159 #endif
5160 #ifdef TCP_FASTOPEN
5162  daemon->fastopen_queue_size = va_arg (ap,
5163  unsigned int);
5164  break;
5165 #endif
5167  daemon->listening_address_reuse = va_arg (ap,
5168  unsigned int) ? 1 : -1;
5169  break;
5171  daemon->listen_backlog_size = va_arg (ap,
5172  unsigned int);
5173  break;
5175  daemon->strict_for_client = va_arg (ap, int);;
5176 #ifdef HAVE_MESSAGES
5177  if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
5178  (1 != daemon->strict_for_client) )
5179  {
5180  MHD_DLOG (daemon,
5181  _("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5182  "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5183  }
5184 #endif /* HAVE_MESSAGES */
5185  break;
5186  case MHD_OPTION_ARRAY:
5187  oa = va_arg (ap, struct MHD_OptionItem*);
5188  i = 0;
5189  while (MHD_OPTION_END != (opt = oa[i].option))
5190  {
5191  switch (opt)
5192  {
5193  /* all options taking 'size_t' */
5197  if (MHD_YES != parse_options (daemon,
5198  servaddr,
5199  opt,
5200  (size_t) oa[i].value,
5201  MHD_OPTION_END))
5202  return MHD_NO;
5203  break;
5204  /* all options taking 'unsigned int' */
5213  if (MHD_YES != parse_options (daemon,
5214  servaddr,
5215  opt,
5216  (unsigned int) oa[i].value,
5217  MHD_OPTION_END))
5218  return MHD_NO;
5219  break;
5220  /* all options taking 'enum' */
5221 #ifdef HTTPS_SUPPORT
5223  if (MHD_YES != parse_options (daemon,
5224  servaddr,
5225  opt,
5226  (gnutls_credentials_type_t) oa[i].value,
5227  MHD_OPTION_END))
5228  return MHD_NO;
5229  break;
5230 #endif /* HTTPS_SUPPORT */
5231  /* all options taking 'MHD_socket' */
5233  if (MHD_YES != parse_options (daemon,
5234  servaddr,
5235  opt,
5236  (MHD_socket) oa[i].value,
5237  MHD_OPTION_END))
5238  return MHD_NO;
5239  break;
5240  /* all options taking 'int' */
5242  if (MHD_YES != parse_options (daemon,
5243  servaddr,
5244  opt,
5245  (int) oa[i].value,
5246  MHD_OPTION_END))
5247  return MHD_NO;
5248  break;
5249  /* all options taking one pointer */
5250  case MHD_OPTION_SOCK_ADDR:
5257  case MHD_OPTION_ARRAY:
5259  if (MHD_YES != parse_options (daemon,
5260  servaddr,
5261  opt,
5262  oa[i].ptr_value,
5263  MHD_OPTION_END))
5264  return MHD_NO;
5265  break;
5266  /* all options taking two pointers */
5273  if (MHD_YES != parse_options (daemon,
5274  servaddr,
5275  opt,
5276  (void *) oa[i].value,
5277  oa[i].ptr_value,
5278  MHD_OPTION_END))
5279  return MHD_NO;
5280  break;
5281  /* options taking size_t-number followed by pointer */
5283  if (MHD_YES != parse_options (daemon,
5284  servaddr,
5285  opt,
5286  (size_t) oa[i].value,
5287  oa[i].ptr_value,
5288  MHD_OPTION_END))
5289  return MHD_NO;
5290  break;
5291  default:
5292  return MHD_NO;
5293  }
5294  i++;
5295  }
5296  break;
5298  daemon->unescape_callback = va_arg (ap,
5300  daemon->unescape_callback_cls = va_arg (ap,
5301  void *);
5302  break;
5303 #ifdef HTTPS_SUPPORT
5305 #if GNUTLS_VERSION_MAJOR >= 3
5306  daemon->cred_callback = va_arg (ap,
5308  daemon->cred_callback_cls = va_arg (ap,
5309  void *);
5310  break;
5311 #else
5312  MHD_DLOG (daemon,
5313  _("MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5314  opt);
5315  return MHD_NO;
5316 #endif
5317 #endif /* HTTPS_SUPPORT */
5318  default:
5319 #ifdef HAVE_MESSAGES
5320  if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
5321  (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) ||
5322  (opt == MHD_OPTION_HTTPS_MEM_TRUST) ||
5324  {
5325  MHD_DLOG (daemon,
5326  _("MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5327  opt);
5328  }
5329  else
5330  {
5331  MHD_DLOG (daemon,
5332  _("Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5333  opt);
5334  }
5335 #endif
5336  return MHD_NO;
5337  }
5338  }
5339  return MHD_YES;
5340 }
5341 
5342 
5343 #ifdef EPOLL_SUPPORT
5344 static int
5345 setup_epoll_fd (struct MHD_Daemon *daemon)
5346 {
5347  int fd;
5348 
5349 #ifndef HAVE_MESSAGES
5350  (void)daemon; /* Mute compiler warning. */
5351 #endif /* ! HAVE_MESSAGES */
5352 
5353 #ifdef USE_EPOLL_CREATE1
5354  fd = epoll_create1 (EPOLL_CLOEXEC);
5355 #else /* ! USE_EPOLL_CREATE1 */
5356  fd = epoll_create (MAX_EVENTS);
5357 #endif /* ! USE_EPOLL_CREATE1 */
5358  if (MHD_INVALID_SOCKET == fd)
5359  {
5360 #ifdef HAVE_MESSAGES
5361  MHD_DLOG (daemon,
5362  _("Call to epoll_create1 failed: %s\n"),
5364 #endif
5365  return MHD_INVALID_SOCKET;
5366  }
5367 #if !defined(USE_EPOLL_CREATE1)
5369  {
5370 #ifdef HAVE_MESSAGES
5371  MHD_DLOG (daemon,
5372  _("Failed to set noninheritable mode on epoll FD.\n"));
5373 #endif
5374  }
5375 #endif /* ! USE_EPOLL_CREATE1 */
5376  return fd;
5377 }
5378 
5379 
5389 static int
5390 setup_epoll_to_listen (struct MHD_Daemon *daemon)
5391 {
5392  struct epoll_event event;
5393  MHD_socket ls;
5394 
5395  daemon->epoll_fd = setup_epoll_fd (daemon);
5396  if (-1 == daemon->epoll_fd)
5397  return MHD_NO;
5398 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5399  if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
5400  {
5401  daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5402  if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
5403  return MHD_NO;
5404  }
5405 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5406  if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) ||
5407  (daemon->was_quiesced) )
5408  return MHD_YES; /* non-listening daemon */
5409  event.events = EPOLLIN;
5410  event.data.ptr = daemon;
5411  if (0 != epoll_ctl (daemon->epoll_fd,
5412  EPOLL_CTL_ADD,
5413  ls,
5414  &event))
5415  {
5416 #ifdef HAVE_MESSAGES
5417  MHD_DLOG (daemon,
5418  _("Call to epoll_ctl failed: %s\n"),
5420 #endif
5421  return MHD_NO;
5422  }
5423  daemon->listen_socket_in_epoll = true;
5424  if (MHD_ITC_IS_VALID_(daemon->itc))
5425  {
5426  event.events = EPOLLIN;
5427  event.data.ptr = (void *) epoll_itc_marker;
5428  if (0 != epoll_ctl (daemon->epoll_fd,
5429  EPOLL_CTL_ADD,
5430  MHD_itc_r_fd_ (daemon->itc),
5431  &event))
5432  {
5433 #ifdef HAVE_MESSAGES
5434  MHD_DLOG (daemon,
5435  _("Call to epoll_ctl failed: %s\n"),
5437 #endif
5438  return MHD_NO;
5439  }
5440  }
5441  return MHD_YES;
5442 }
5443 #endif
5444 
5445 
5467 struct MHD_Daemon *
5468 MHD_start_daemon_va (unsigned int flags,
5469  uint16_t port,
5471  void *apc_cls,
5473  void *dh_cls,
5474  va_list ap)
5475 {
5476  const MHD_SCKT_OPT_BOOL_ on = 1;
5477  struct MHD_Daemon *daemon;
5479  struct sockaddr_in servaddr4;
5480 #if HAVE_INET6
5481  struct sockaddr_in6 servaddr6;
5482 #endif
5483  const struct sockaddr *servaddr = NULL;
5484  socklen_t addrlen;
5485 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5486  unsigned int i;
5487 #endif
5488  enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
5489  enum MHD_FLAG *pflags;
5490 
5492  eflags = (enum MHD_FLAG) flags;
5493  pflags = &eflags;
5494 #ifndef HAVE_INET6
5495  if (0 != (*pflags & MHD_USE_IPv6))
5496  return NULL;
5497 #endif
5498 #ifndef HAVE_POLL
5499  if (0 != (*pflags & MHD_USE_POLL))
5500  return NULL;
5501 #endif
5502 #ifndef EPOLL_SUPPORT
5503  if (0 != (*pflags & MHD_USE_EPOLL))
5504  return NULL;
5505 #endif /* ! EPOLL_SUPPORT */
5506 #ifndef HTTPS_SUPPORT
5507  if (0 != (*pflags & MHD_USE_TLS))
5508  return NULL;
5509 #endif /* ! HTTPS_SUPPORT */
5510 #ifndef TCP_FASTOPEN
5511  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
5512  return NULL;
5513 #endif
5514  if (0 != (*pflags & MHD_ALLOW_UPGRADE))
5515  {
5516 #ifdef UPGRADE_SUPPORT
5517  *pflags |= MHD_ALLOW_SUSPEND_RESUME;
5518 #else /* ! UPGRADE_SUPPORT */
5519  return NULL;
5520 #endif /* ! UPGRADE_SUPPORT */
5521  }
5522  if (NULL == dh)
5523  return NULL;
5524 
5525  /* Check for invalid combinations of flags. */
5526  if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) ||
5527  ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))) ||
5528  ((0 != (*pflags & MHD_USE_POLL)) &&
5530  ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) )
5531  return NULL;
5532 
5533  if (0 != (*pflags & MHD_USE_AUTO))
5534  {
5535  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
5536  {
5537  /* Thread per connection with internal polling thread. */
5538 #ifdef HAVE_POLL
5539  *pflags |= MHD_USE_POLL;
5540 #else /* ! HAVE_POLL */
5541  /* use select() - do not modify flags */
5542 #endif /* ! HAVE_POLL */
5543  }
5544  else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5545  {
5546  /* Internal polling thread. */
5547 #if defined(EPOLL_SUPPORT)
5548  *pflags |= MHD_USE_EPOLL;
5549 #elif defined(HAVE_POLL)
5550  *pflags |= MHD_USE_POLL;
5551 #else /* !HAVE_POLL && !EPOLL_SUPPORT */
5552  /* use select() - do not modify flags */
5553 #endif /* !HAVE_POLL && !EPOLL_SUPPORT */
5554  }
5555  else
5556  {
5557  /* Internal threads are not used - "external" polling mode. */
5558 #if defined(EPOLL_SUPPORT)
5559  *pflags |= MHD_USE_EPOLL;
5560 #else /* ! EPOLL_SUPPORT */
5561  /* use select() - do not modify flags */
5562 #endif /* ! EPOLL_SUPPORT */
5563  }
5564  }
5565 
5566  if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
5567  return NULL;
5568 #ifdef EPOLL_SUPPORT
5569  daemon->epoll_fd = -1;
5570 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5571  daemon->epoll_upgrade_fd = -1;
5572 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5573 #endif
5574  /* try to open listen socket */
5575 #ifdef HTTPS_SUPPORT
5576  daemon->priority_cache = NULL;
5577  if (0 != (*pflags & MHD_USE_TLS))
5578  {
5579  gnutls_priority_init (&daemon->priority_cache,
5580  "@SYSTEM",
5581  NULL);
5582  }
5583 #endif /* HTTPS_SUPPORT */
5584  daemon->listen_fd = MHD_INVALID_SOCKET;
5585  daemon->listening_address_reuse = 0;
5586  daemon->options = *pflags;
5587  pflags = &daemon->options;
5588  daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 : 0;
5589  daemon->port = port;
5590  daemon->apc = apc;
5591  daemon->apc_cls = apc_cls;
5592  daemon->default_handler = dh;
5593  daemon->default_handler_cls = dh_cls;
5594  daemon->connections = 0;
5596  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
5597  daemon->pool_increment = MHD_BUF_INC_SIZE;
5599  daemon->connection_timeout = 0; /* no timeout */
5600  MHD_itc_set_invalid_ (daemon->itc);
5601 #ifdef SOMAXCONN
5602  daemon->listen_backlog_size = SOMAXCONN;
5603 #else /* !SOMAXCONN */
5604  daemon->listen_backlog_size = 511; /* should be safe value */
5605 #endif /* !SOMAXCONN */
5606 #ifdef HAVE_MESSAGES
5607  daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
5608  daemon->custom_error_log_cls = stderr;
5609 #endif
5610  if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
5611  (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
5612  {
5613 #ifdef HAVE_MESSAGES
5614  MHD_DLOG (daemon,
5615  _("Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
5616  "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
5617  "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5618 #endif
5620  }
5621  if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5622  *pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */
5623  else
5624  {
5625 #ifdef HAVE_LISTEN_SHUTDOWN
5626  if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
5627 #endif
5628  *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */
5629  }
5630 #ifdef DAUTH_SUPPORT
5631  daemon->digest_auth_rand_size = 0;
5632  daemon->digest_auth_random = NULL;
5633  daemon->nonce_nc_size = 4; /* tiny */
5634 #endif
5635 #ifdef HTTPS_SUPPORT
5636  if (0 != (*pflags & MHD_USE_TLS))
5637  {
5638  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5639  }
5640 #endif /* HTTPS_SUPPORT */
5641 
5642 
5643  if (MHD_YES != parse_options_va (daemon,
5644  &servaddr,
5645  ap))
5646  {
5647 #ifdef HTTPS_SUPPORT
5648  if ( (0 != (*pflags & MHD_USE_TLS)) &&
5649  (NULL != daemon->priority_cache) )
5650  gnutls_priority_deinit (daemon->priority_cache);
5651 #endif /* HTTPS_SUPPORT */
5652  free (daemon);
5653  return NULL;
5654  }
5655 
5656  if ( (NULL != daemon->notify_completed) &&
5657  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
5658  *pflags |= MHD_USE_ITC; /* requires ITC */
5659 
5660 #ifndef NDEBUG
5661 #ifdef HAVE_MESSAGES
5662  MHD_DLOG (daemon,
5663  _("Using debug build of libmicrohttpd.\n") );
5664 #endif /* HAVE_MESSAGES */
5665 #endif /* ! NDEBUG */
5666 
5667  if ( (0 != (*pflags & MHD_USE_ITC))
5668 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5669  && (0 == daemon->worker_pool_size)
5670 #endif
5671  )
5672  {
5673  if (! MHD_itc_init_ (daemon->itc))
5674  {
5675 #ifdef HAVE_MESSAGES
5676  MHD_DLOG (daemon,
5677  _("Failed to create inter-thread communication channel: %s\n"),
5678  MHD_itc_last_strerror_ ());
5679 #endif
5680 #ifdef HTTPS_SUPPORT
5681  if (NULL != daemon->priority_cache)
5682  gnutls_priority_deinit (daemon->priority_cache);
5683 #endif /* HTTPS_SUPPORT */
5684  free (daemon);
5685  return NULL;
5686  }
5687  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
5688  (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc),
5689  NULL)) )
5690  {
5691 #ifdef HAVE_MESSAGES
5692  MHD_DLOG (daemon,
5693  _("file descriptor for inter-thread communication channel exceeds maximum value\n"));
5694 #endif
5695  MHD_itc_destroy_chk_ (daemon->itc);
5696 #ifdef HTTPS_SUPPORT
5697  if (NULL != daemon->priority_cache)
5698  gnutls_priority_deinit (daemon->priority_cache);
5699 #endif /* HTTPS_SUPPORT */
5700  free (daemon);
5701  return NULL;
5702  }
5703  }
5704 
5705 #ifdef DAUTH_SUPPORT
5706  if (daemon->nonce_nc_size > 0)
5707  {
5708  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
5709  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
5710  {
5711 #ifdef HAVE_MESSAGES
5712  MHD_DLOG (daemon,
5713  _("Specified value for NC_SIZE too large\n"));
5714 #endif
5715 #ifdef HTTPS_SUPPORT
5716  if (0 != (*pflags & MHD_USE_TLS))
5717  gnutls_priority_deinit (daemon->priority_cache);
5718 #endif /* HTTPS_SUPPORT */
5719  free (daemon);
5720  return NULL;
5721  }
5722  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
5723  if (NULL == daemon->nnc)
5724  {
5725 #ifdef HAVE_MESSAGES
5726  MHD_DLOG (daemon,
5727  _("Failed to allocate memory for nonce-nc map: %s\n"),
5728  MHD_strerror_ (errno));
5729 #endif
5730 #ifdef HTTPS_SUPPORT
5731  if (0 != (*pflags & MHD_USE_TLS))
5732  gnutls_priority_deinit (daemon->priority_cache);
5733 #endif /* HTTPS_SUPPORT */
5734  free (daemon);
5735  return NULL;
5736  }
5737  }
5738 
5739 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5740  if (! MHD_mutex_init_ (&daemon->nnc_lock))
5741  {
5742 #ifdef HAVE_MESSAGES
5743  MHD_DLOG (daemon,
5744  _("MHD failed to initialize nonce-nc mutex\n"));
5745 #endif
5746 #ifdef HTTPS_SUPPORT
5747  if (0 != (*pflags & MHD_USE_TLS))
5748  gnutls_priority_deinit (daemon->priority_cache);
5749 #endif /* HTTPS_SUPPORT */
5750  free (daemon->nnc);
5751  free (daemon);
5752  return NULL;
5753  }
5754 #endif
5755 #endif
5756 
5757  /* Thread pooling currently works only with internal select thread mode */
5758 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5759  if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
5760  (daemon->worker_pool_size > 0) )
5761  {
5762 #ifdef HAVE_MESSAGES
5763  MHD_DLOG (daemon,
5764  _("MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5765 #endif
5766  goto free_and_fail;
5767  }
5768 #endif
5769  if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
5770  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
5771  {
5772  /* try to open listen socket */
5773  int domain;
5774 
5775 #ifdef HAVE_INET6
5776  domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5777 #else /* ! HAVE_INET6 */
5778  if (*pflags & MHD_USE_IPv6)
5779  goto free_and_fail;
5780  domain = PF_INET;
5781 #endif /* ! HAVE_INET6 */
5782 
5783  listen_fd = MHD_socket_create_listen_(domain);
5784  if (MHD_INVALID_SOCKET == listen_fd)
5785  {
5786 #ifdef HAVE_MESSAGES
5787  MHD_DLOG (daemon,
5788  _("Failed to create socket for listening: %s\n"),
5790 #endif
5791  goto free_and_fail;
5792  }
5793 
5794  /* Apply the socket options according to listening_address_reuse. */
5795  if (0 == daemon->listening_address_reuse)
5796  {
5797 #ifndef MHD_WINSOCK_SOCKETS
5798  /* No user requirement, use "traditional" default SO_REUSEADDR
5799  * on non-W32 platforms, and do not fail if it doesn't work.
5800  * Don't use it on W32, because on W32 it will allow multiple
5801  * bind to the same address:port, like SO_REUSEPORT on others. */
5802  if (0 > setsockopt (listen_fd,
5803  SOL_SOCKET,
5804  SO_REUSEADDR,
5805  (void*)&on, sizeof (on)))
5806  {
5807 #ifdef HAVE_MESSAGES
5808  MHD_DLOG (daemon,
5809  _("setsockopt failed: %s\n"),
5811 #endif
5812  }
5813 #endif /* ! MHD_WINSOCK_SOCKETS */
5814  }
5815  else if (daemon->listening_address_reuse > 0)
5816  {
5817  /* User requested to allow reusing listening address:port. */
5818 #ifndef MHD_WINSOCK_SOCKETS
5819  /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
5820  * it doesn't work. */
5821  if (0 > setsockopt (listen_fd,
5822  SOL_SOCKET,
5823  SO_REUSEADDR,
5824  (void*)&on, sizeof (on)))
5825  {
5826 #ifdef HAVE_MESSAGES
5827  MHD_DLOG (daemon,
5828  _("setsockopt failed: %s\n"),
5830 #endif
5831  }
5832 #endif /* ! MHD_WINSOCK_SOCKETS */
5833  /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
5834  * Fail if SO_REUSEPORT is not defined or setsockopt fails.
5835  */
5836  /* SO_REUSEADDR on W32 has the same semantics
5837  as SO_REUSEPORT on BSD/Linux */
5838 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
5839  if (0 > setsockopt (listen_fd,
5840  SOL_SOCKET,
5841 #ifndef MHD_WINSOCK_SOCKETS
5842  SO_REUSEPORT,
5843 #else /* MHD_WINSOCK_SOCKETS */
5844  SO_REUSEADDR,
5845 #endif /* MHD_WINSOCK_SOCKETS */
5846  (void *) &on,
5847  sizeof (on)))
5848  {
5849 #ifdef HAVE_MESSAGES
5850  MHD_DLOG (daemon,
5851  _("setsockopt failed: %s\n"),
5853 #endif
5854  goto free_and_fail;
5855  }
5856 #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
5857  /* we're supposed to allow address:port re-use, but
5858  on this platform we cannot; fail hard */
5859 #ifdef HAVE_MESSAGES
5860  MHD_DLOG (daemon,
5861  _("Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5862 #endif
5863  goto free_and_fail;
5864 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
5865  }
5866  else /* if (daemon->listening_address_reuse < 0) */
5867  {
5868  /* User requested to disallow reusing listening address:port.
5869  * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
5870  * is used and Solaris with SO_EXCLBIND.
5871  * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
5872  * or setsockopt fails.
5873  */
5874 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
5875  (defined(__sun) && defined(SO_EXCLBIND))
5876  if (0 > setsockopt (listen_fd,
5877  SOL_SOCKET,
5878 #ifdef SO_EXCLUSIVEADDRUSE
5879  SO_EXCLUSIVEADDRUSE,
5880 #else /* SO_EXCLBIND */
5881  SO_EXCLBIND,
5882 #endif /* SO_EXCLBIND */
5883  (void *) &on,
5884  sizeof (on)))
5885  {
5886 #ifdef HAVE_MESSAGES
5887  MHD_DLOG (daemon,
5888  _("setsockopt failed: %s\n"),
5890 #endif
5891  goto free_and_fail;
5892  }
5893 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
5894 #ifdef HAVE_MESSAGES
5895  MHD_DLOG (daemon,
5896  _("Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
5897 #endif
5898  goto free_and_fail;
5899 #endif /* MHD_WINSOCK_SOCKETS */
5900  }
5901 
5902  /* check for user supplied sockaddr */
5903 #if HAVE_INET6
5904  if (0 != (*pflags & MHD_USE_IPv6))
5905  addrlen = sizeof (struct sockaddr_in6);
5906  else
5907 #endif
5908  addrlen = sizeof (struct sockaddr_in);
5909  if (NULL == servaddr)
5910  {
5911 #if HAVE_INET6
5912  if (0 != (*pflags & MHD_USE_IPv6))
5913  {
5914 #ifdef IN6ADDR_ANY_INIT
5915  static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
5916 #endif
5917  memset (&servaddr6,
5918  0,
5919  sizeof (struct sockaddr_in6));
5920  servaddr6.sin6_family = AF_INET6;
5921  servaddr6.sin6_port = htons (port);
5922 #ifdef IN6ADDR_ANY_INIT
5923  servaddr6.sin6_addr = static_in6any;
5924 #endif
5925 #if HAVE_SOCKADDR_IN_SIN_LEN
5926  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
5927 #endif
5928  servaddr = (struct sockaddr *) &servaddr6;
5929  }
5930  else
5931 #endif
5932  {
5933  memset (&servaddr4,
5934  0,
5935  sizeof (struct sockaddr_in));
5936  servaddr4.sin_family = AF_INET;
5937  servaddr4.sin_port = htons (port);
5938  if (0 != INADDR_ANY)
5939  servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
5940 #if HAVE_SOCKADDR_IN_SIN_LEN
5941  servaddr4.sin_len = sizeof (struct sockaddr_in);
5942 #endif
5943  servaddr = (struct sockaddr *) &servaddr4;
5944  }
5945  }
5946  daemon->listen_fd = listen_fd;
5947 
5948  if (0 != (*pflags & MHD_USE_IPv6))
5949  {
5950 #ifdef IPPROTO_IPV6
5951 #ifdef IPV6_V6ONLY
5952  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
5953  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
5954  and may also be missing on older POSIX systems; good luck if you have any of those,
5955  your IPv6 socket may then also bind against IPv4 anyway... */
5956  const MHD_SCKT_OPT_BOOL_ v6_only =
5957  (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
5958  if (0 > setsockopt (listen_fd,
5959  IPPROTO_IPV6, IPV6_V6ONLY,
5960  (const void *) &v6_only,
5961  sizeof (v6_only)))
5962  {
5963 #ifdef HAVE_MESSAGES
5964  MHD_DLOG (daemon,
5965  _("setsockopt failed: %s\n"),
5967 #endif
5968  }
5969 #endif
5970 #endif
5971  }
5972  if (-1 == bind (listen_fd, servaddr, addrlen))
5973  {
5974 #ifdef HAVE_MESSAGES
5975  MHD_DLOG (daemon,
5976  _("Failed to bind to port %u: %s\n"),
5977  (unsigned int) port,
5979 #endif
5980  MHD_socket_close_chk_ (listen_fd);
5981  goto free_and_fail;
5982  }
5983 #ifdef TCP_FASTOPEN
5984  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
5985  {
5986  if (0 == daemon->fastopen_queue_size)
5987  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
5988  if (0 != setsockopt (listen_fd,
5989  IPPROTO_TCP,
5990  TCP_FASTOPEN,
5991  (const void*)&daemon->fastopen_queue_size,
5992  sizeof (daemon->fastopen_queue_size)))
5993  {
5994 #ifdef HAVE_MESSAGES
5995  MHD_DLOG (daemon,
5996  _("setsockopt failed: %s\n"),
5998 #endif
5999  }
6000  }
6001 #endif
6002  if (listen (listen_fd,
6003  daemon->listen_backlog_size) < 0)
6004  {
6005 #ifdef HAVE_MESSAGES
6006  MHD_DLOG (daemon,
6007  _("Failed to listen for connections: %s\n"),
6009 #endif
6010  MHD_socket_close_chk_ (listen_fd);
6011  goto free_and_fail;
6012  }
6013  }
6014  else
6015  {
6016  listen_fd = daemon->listen_fd;
6017  }
6018 
6019  if ( (0 == daemon->port) &&
6020  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6021  { /* Get port number. */
6022  struct sockaddr_storage servaddr;
6023 
6024  memset (&servaddr,
6025  0,
6026  sizeof (struct sockaddr_storage));
6027  addrlen = sizeof (servaddr);
6028  if (0 != getsockname (listen_fd,
6029  (struct sockaddr *) &servaddr,
6030  &addrlen))
6031  {
6032 #ifdef HAVE_MESSAGES
6033  MHD_DLOG (daemon,
6034  _("Failed to get listen port number: %s\n"),
6036 #endif /* HAVE_MESSAGES */
6037  }
6038 #ifdef MHD_POSIX_SOCKETS
6039  else if (sizeof (servaddr) < addrlen)
6040  {
6041  /* should be impossible with `struct sockaddr_storage` */
6042 #ifdef HAVE_MESSAGES
6043  MHD_DLOG (daemon,
6044  _("Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6045 #endif /* HAVE_MESSAGES */
6046  }
6047 #endif /* MHD_POSIX_SOCKETS */
6048  else
6049  {
6050  switch (servaddr.ss_family)
6051  {
6052  case AF_INET:
6053  {
6054  struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
6055 
6056  daemon->port = ntohs (s4->sin_port);
6057  break;
6058  }
6059 #ifdef HAVE_INET6
6060  case AF_INET6:
6061  {
6062  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr;
6063 
6064  daemon->port = ntohs(s6->sin6_port);
6065  mhd_assert (0 != (*pflags & MHD_USE_IPv6));
6066  break;
6067  }
6068 #endif /* HAVE_INET6 */
6069 #ifdef AF_UNIX
6070  case AF_UNIX:
6071  daemon->port = 0; /* special value for UNIX domain sockets */
6072  break;
6073 #endif
6074  default:
6075 #ifdef HAVE_MESSAGES
6076  MHD_DLOG (daemon,
6077  _("Unknown address family!\n"));
6078 #endif
6079  daemon->port = 0; /* ugh */
6080  break;
6081  }
6082  }
6083  }
6084 
6085  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6086  (! MHD_socket_nonblocking_ (listen_fd)) )
6087  {
6088 #ifdef HAVE_MESSAGES
6089  MHD_DLOG (daemon,
6090  _("Failed to set nonblocking mode on listening socket: %s\n"),
6092 #endif
6093  if (0 != (*pflags & MHD_USE_EPOLL)
6094 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6095  || (daemon->worker_pool_size > 0)
6096 #endif
6097  )
6098  {
6099  /* Accept must be non-blocking. Multiple children may wake up
6100  * to handle a new connection, but only one will win the race.
6101  * The others must immediately return. */
6102  MHD_socket_close_chk_ (listen_fd);
6103  goto free_and_fail;
6104  }
6105  }
6106  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6107  (! MHD_SCKT_FD_FITS_FDSET_(listen_fd,
6108  NULL)) &&
6109  (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
6110  {
6111 #ifdef HAVE_MESSAGES
6112  MHD_DLOG (daemon,
6113  _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6114  listen_fd,
6115  FD_SETSIZE);
6116 #endif
6117  MHD_socket_close_chk_ (listen_fd);
6118  goto free_and_fail;
6119  }
6120 
6121 #ifdef EPOLL_SUPPORT
6122  if ( (0 != (*pflags & MHD_USE_EPOLL))
6123 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6124  && (0 == daemon->worker_pool_size)
6125 #endif
6126  )
6127  {
6128  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6129  {
6130 #ifdef HAVE_MESSAGES
6131  MHD_DLOG (daemon,
6132  _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6133 #endif
6134  goto free_and_fail;
6135  }
6136  if (MHD_YES != setup_epoll_to_listen (daemon))
6137  goto free_and_fail;
6138  }
6139 #endif /* EPOLL_SUPPORT */
6140 
6141 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6142  if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
6143  {
6144 #ifdef HAVE_MESSAGES
6145  MHD_DLOG (daemon,
6146  _("MHD failed to initialize IP connection limit mutex\n"));
6147 #endif
6148  if (MHD_INVALID_SOCKET != listen_fd)
6149  MHD_socket_close_chk_ (listen_fd);
6150  goto free_and_fail;
6151  }
6152  if (0 == daemon->worker_pool_size)
6153  { /* Initialise connection mutex only if this daemon will handle
6154  * any connections by itself. */
6155  if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
6156  {
6157 #ifdef HAVE_MESSAGES
6158  MHD_DLOG (daemon,
6159  _("MHD failed to initialize IP connection limit mutex\n"));
6160 #endif
6161 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6163 #endif
6164  if (MHD_INVALID_SOCKET != listen_fd)
6165  MHD_socket_close_chk_ (listen_fd);
6166  goto free_and_fail;
6167  }
6168  }
6169 #endif
6170 
6171 #ifdef HTTPS_SUPPORT
6172  /* initialize HTTPS daemon certificate aspects & send / recv functions */
6173  if ( (0 != (*pflags & MHD_USE_TLS)) &&
6174  (0 != MHD_TLS_init (daemon)) )
6175  {
6176 #ifdef HAVE_MESSAGES
6177  MHD_DLOG (daemon,
6178  _("Failed to initialize TLS support\n"));
6179 #endif
6180  if (MHD_INVALID_SOCKET != listen_fd)
6181  MHD_socket_close_chk_ (listen_fd);
6182 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6183  if (0 == daemon->worker_pool_size)
6186 #endif
6187  goto free_and_fail;
6188  }
6189 #endif /* HTTPS_SUPPORT */
6190 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6191  if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
6192  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6193  {
6194  if (0 == daemon->worker_pool_size)
6195  {
6196  if (! MHD_create_named_thread_ (&daemon->pid,
6197  (*pflags & MHD_USE_THREAD_PER_CONNECTION) ?
6198  "MHD-listen" : "MHD-single",
6199  daemon->thread_stack_size,
6201  daemon) )
6202  {
6203 #ifdef HAVE_MESSAGES
6204  MHD_DLOG (daemon,
6205  _("Failed to create listen thread: %s\n"),
6206  MHD_strerror_ (errno));
6207 #endif
6210  if (MHD_INVALID_SOCKET != listen_fd)
6211  MHD_socket_close_chk_ (listen_fd);
6212  goto free_and_fail;
6213  }
6214  }
6215  else /* 0 < daemon->worker_pool_size */
6216  {
6217  /* Coarse-grained count of connections per thread (note error
6218  * due to integer division). Also keep track of how many
6219  * connections are leftover after an equal split. */
6220  unsigned int conns_per_thread = daemon->connection_limit
6221  / daemon->worker_pool_size;
6222  unsigned int leftover_conns = daemon->connection_limit
6223  % daemon->worker_pool_size;
6224 
6225  i = 0; /* we need this in case fcntl or malloc fails */
6226 
6227  /* Allocate memory for pooled objects */
6228  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
6229  * daemon->worker_pool_size);
6230  if (NULL == daemon->worker_pool)
6231  goto thread_failed;
6232 
6233  /* Start the workers in the pool */
6234  for (i = 0; i < daemon->worker_pool_size; ++i)
6235  {
6236  /* Create copy of the Daemon object for each worker */
6237  struct MHD_Daemon *d = &daemon->worker_pool[i];
6238 
6239  memcpy (d, daemon, sizeof (struct MHD_Daemon));
6240  /* Adjust pooling params for worker daemons; note that memcpy()
6241  has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
6242  the worker threads. */
6243  d->master = daemon;
6244  d->worker_pool_size = 0;
6245  d->worker_pool = NULL;
6246 
6247  if (0 != (*pflags & MHD_USE_ITC))
6248  {
6249  if (! MHD_itc_init_ (d->itc))
6250  {
6251 #ifdef HAVE_MESSAGES
6252  MHD_DLOG (daemon,
6253  _("Failed to create worker inter-thread communication channel: %s\n"),
6254  MHD_itc_last_strerror_() );
6255 #endif
6256  goto thread_failed;
6257  }
6258  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
6259  (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (d->itc),
6260  NULL)) )
6261  {
6262 #ifdef HAVE_MESSAGES
6263  MHD_DLOG (daemon,
6264  _("File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6265 #endif
6267  goto thread_failed;
6268  }
6269  }
6270  else
6271  MHD_itc_set_invalid_ (d->itc);
6272 
6273  /* Divide available connections evenly amongst the threads.
6274  * Thread indexes in [0, leftover_conns) each get one of the
6275  * leftover connections. */
6276  d->connection_limit = conns_per_thread;
6277  if (i < leftover_conns)
6278  ++d->connection_limit;
6279 #ifdef EPOLL_SUPPORT
6280  if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
6281  (MHD_YES != setup_epoll_to_listen (d)) )
6282  goto thread_failed;
6283 #endif
6284  /* Must init cleanup connection mutex for each worker */
6285  if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
6286  {
6287 #ifdef HAVE_MESSAGES
6288  MHD_DLOG (daemon,
6289  _("MHD failed to initialize cleanup connection mutex\n"));
6290 #endif
6291  goto thread_failed;
6292  }
6293 
6294  /* Spawn the worker thread */
6295  if (! MHD_create_named_thread_ (&d->pid,
6296  "MHD-worker",
6297  daemon->thread_stack_size,
6299  d))
6300  {
6301 #ifdef HAVE_MESSAGES
6302  MHD_DLOG (daemon,
6303  _("Failed to create pool thread: %s\n"),
6304  MHD_strerror_ (errno));
6305 #endif
6306  /* Free memory for this worker; cleanup below handles
6307  * all previously-created workers. */
6309  goto thread_failed;
6310  }
6311  }
6312  }
6313  }
6314 #endif
6315 #ifdef HTTPS_SUPPORT
6316  /* API promises to never use the password after initialization,
6317  so we additionally NULL it here to not deref a dangling pointer. */
6318  daemon->https_key_password = NULL;
6319 #endif /* HTTPS_SUPPORT */
6320 
6321  return daemon;
6322 
6323 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6324 thread_failed:
6325  /* If no worker threads created, then shut down normally. Calling
6326  MHD_stop_daemon (as we do below) doesn't work here since it
6327  assumes a 0-sized thread pool means we had been in the default
6328  MHD_USE_INTERNAL_POLLING_THREAD mode. */
6329  if (0 == i)
6330  {
6334  if (NULL != daemon->worker_pool)
6335  free (daemon->worker_pool);
6336  goto free_and_fail;
6337  }
6338 
6339  /* Shutdown worker threads we've already created. Pretend
6340  as though we had fully initialized our daemon, but
6341  with a smaller number of threads than had been
6342  requested. */
6343  daemon->worker_pool_size = i;
6344  MHD_stop_daemon (daemon);
6345  return NULL;
6346 #endif
6347 
6348  free_and_fail:
6349  /* clean up basic memory state in 'daemon' and return NULL to
6350  indicate failure */
6351 #ifdef EPOLL_SUPPORT
6352 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6353  if (daemon->upgrade_fd_in_epoll)
6354  {
6355  if (0 != epoll_ctl (daemon->epoll_fd,
6356  EPOLL_CTL_DEL,
6357  daemon->epoll_upgrade_fd,
6358  NULL))
6359  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
6360  daemon->upgrade_fd_in_epoll = false;
6361  }
6362 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6363  if (-1 != daemon->epoll_fd)
6364  close (daemon->epoll_fd);
6365 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6366  if (-1 != daemon->epoll_upgrade_fd)
6367  close (daemon->epoll_upgrade_fd);
6368 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6369 #endif /* EPOLL_SUPPORT */
6370 #ifdef DAUTH_SUPPORT
6371  free (daemon->nnc);
6372 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6373  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6374 #endif
6375 #endif
6376 #ifdef HTTPS_SUPPORT
6377  if (0 != (*pflags & MHD_USE_TLS))
6378  {
6379  gnutls_priority_deinit (daemon->priority_cache);
6380  if (daemon->x509_cred)
6381  gnutls_certificate_free_credentials (daemon->x509_cred);
6382  if (daemon->psk_cred)
6383  gnutls_psk_free_server_credentials (daemon->psk_cred);
6384  }
6385 #endif /* HTTPS_SUPPORT */
6386  if (MHD_ITC_IS_VALID_(daemon->itc))
6387  MHD_itc_destroy_chk_ (daemon->itc);
6388  free (daemon);
6389  return NULL;
6390 }
6391 
6392 
6401 static void
6403 {
6404  struct MHD_Connection *pos;
6405  const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
6406 #ifdef UPGRADE_SUPPORT
6407  const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
6408 #endif /* UPGRADE_SUPPORT */
6409 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6410  struct MHD_UpgradeResponseHandle *urh;
6411  struct MHD_UpgradeResponseHandle *urhn;
6412  const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
6413 
6414 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6415  mhd_assert (NULL == daemon->worker_pool);
6416 #endif
6417  mhd_assert (daemon->shutdown);
6418  /* give upgraded HTTPS connections a chance to finish */
6419  /* 'daemon->urh_head' is not used in thread-per-connection mode. */
6420  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
6421  {
6422  urhn = urh->prev;
6423  /* call generic forwarding function for passing data
6424  with chance to detect that application is done. */
6425  process_urh (urh);
6426  MHD_connection_finish_forward_ (urh->connection);
6427  urh->clean_ready = true;
6428  /* Resuming will move connection to cleanup list. */
6429  MHD_resume_connection(urh->connection);
6430  }
6431 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6432 
6433  /* Give suspended connections a chance to resume to avoid
6434  running into the check for there not being any suspended
6435  connections left in case of a tight race with a recently
6436  resumed connection. */
6437  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
6438  {
6439  daemon->resuming = true; /* Force check for pending resume. */
6441  }
6442  /* first, make sure all threads are aware of shutdown; need to
6443  traverse DLLs in peace... */
6444 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6446 #endif
6447 #ifdef UPGRADE_SUPPORT
6448  if (upg_allowed)
6449  {
6450  struct MHD_Connection * susp;
6451 
6453  while (NULL != susp)
6454  {
6455  if (NULL == susp->urh) /* "Upgraded" connection? */
6456  MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
6457 #ifdef HTTPS_SUPPORT
6458  else if (used_tls &&
6459  used_thr_p_c &&
6460  (! susp->urh->clean_ready) )
6461  shutdown (susp->urh->app.socket,
6462  SHUT_RDWR); /* Wake thread by shutdown of app socket. */
6463 #endif /* HTTPS_SUPPORT */
6464  else
6465  {
6466 #ifdef HAVE_MESSAGES
6467  if (! susp->urh->was_closed)
6468  MHD_DLOG (daemon,
6469  _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6470 #endif
6471  susp->urh->was_closed = true;
6472  /* If thread-per-connection is used, connection's thread
6473  * may still processing "upgrade" (exiting). */
6474  if (! used_thr_p_c)
6476  /* Do not use MHD_resume_connection() as mutex is
6477  * already locked. */
6478  susp->resuming = true;
6479  daemon->resuming = true;
6480  }
6481  susp = susp->prev;
6482  }
6483  }
6484  else /* This 'else' is combined with next 'if' */
6485 #endif /* UPGRADE_SUPPORT */
6487  MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
6488  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
6489  {
6490  shutdown (pos->socket_fd,
6491  SHUT_RDWR);
6492 #if MHD_WINSOCK_SOCKETS
6493  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6494  (MHD_ITC_IS_VALID_(daemon->itc)) &&
6495  (! MHD_itc_activate_ (daemon->itc, "e")) )
6496  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
6497 #endif
6498  }
6499 
6500 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6501  /* now, collect per-connection threads */
6502  if (used_thr_p_c)
6503  {
6504  pos = daemon->connections_tail;
6505  while (NULL != pos)
6506  {
6507  if (! pos->thread_joined)
6508  {
6510  if (! MHD_join_thread_ (pos->pid.handle))
6511  MHD_PANIC (_("Failed to join a thread\n"));
6513  pos->thread_joined = true;
6514  /* The thread may have concurrently modified the DLL,
6515  need to restart from the beginning */
6516  pos = daemon->connections_tail;
6517  continue;
6518  }
6519  pos = pos->prev;
6520  }
6521  }
6523 #endif
6524 
6525 #ifdef UPGRADE_SUPPORT
6526  /* Finished threads with "upgraded" connections need to be moved
6527  * to cleanup list by resume_suspended_connections(). */
6528  /* "Upgraded" connections that were not closed explicitly by
6529  * application should be moved to cleanup list too. */
6530  if (upg_allowed)
6531  {
6532  daemon->resuming = true; /* Force check for pending resume. */
6534  }
6535 #endif /* UPGRADE_SUPPORT */
6536 
6537  /* now that we're alone, move everyone to cleanup */
6538  while (NULL != (pos = daemon->connections_tail))
6539  {
6540 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6541  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6542  (! pos->thread_joined) )
6543  MHD_PANIC (_("Failed to join a thread\n"));
6544 #endif
6545  close_connection (pos);
6546  }
6548 }
6549 
6550 
6557 void
6559 {
6560  MHD_socket fd;
6561 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6562  unsigned int i;
6563 #endif
6564 
6565  if (NULL == daemon)
6566  return;
6567 
6568  daemon->shutdown = true;
6569  if (daemon->was_quiesced)
6570  fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
6571  else
6572  fd = daemon->listen_fd;
6573 
6574 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6575  if (NULL != daemon->worker_pool)
6576  { /* Master daemon with worker pool. */
6579 
6580  /* Let workers shutdown in parallel. */
6581  for (i = 0; i < daemon->worker_pool_size; ++i)
6582  {
6583  daemon->worker_pool[i].shutdown = true;
6584  if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
6585  {
6586  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
6587  "e"))
6588  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
6589  }
6590  else
6592  }
6593 #ifdef HAVE_LISTEN_SHUTDOWN
6594  if (MHD_INVALID_SOCKET != fd)
6595  {
6596  (void) shutdown (fd,
6597  SHUT_RDWR);
6598  }
6599 #endif /* HAVE_LISTEN_SHUTDOWN */
6600  for (i = 0; i < daemon->worker_pool_size; ++i)
6601  {
6603  }
6604  free (daemon->worker_pool);
6606 #ifdef EPOLL_SUPPORT
6607  mhd_assert (-1 == daemon->epoll_fd);
6608 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6609  mhd_assert (-1 == daemon->epoll_upgrade_fd);
6610 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6611 #endif /* EPOLL_SUPPORT */
6612  }
6613  else
6614 #endif
6615  { /* Worker daemon or single daemon. */
6616 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6618  { /* Worker daemon or single daemon with internal thread(s). */
6620  /* Separate thread(s) is used for polling sockets. */
6621  if (MHD_ITC_IS_VALID_ (daemon->itc))
6622  {
6623  if (! MHD_itc_activate_ (daemon->itc,
6624  "e"))
6625  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
6626  }
6627  else
6628  {
6629 #ifdef HAVE_LISTEN_SHUTDOWN
6630  if (MHD_INVALID_SOCKET != fd)
6631  {
6632  if (NULL == daemon->master)
6633  (void) shutdown (fd,
6634  SHUT_RDWR);
6635  }
6636  else
6637 #endif /* HAVE_LISTEN_SHUTDOWN */
6638  mhd_assert (false); /* Should never happen */
6639  }
6640 
6641  if (! MHD_join_thread_ (daemon->pid.handle))
6642  {
6643  MHD_PANIC (_("Failed to join a thread\n"));
6644  }
6645  /* close_all_connections() was called in daemon thread. */
6646  }
6647  else
6648 #endif
6649  {
6650  /* No internal threads are used for polling sockets. */
6652  }
6653  if (MHD_ITC_IS_VALID_ (daemon->itc))
6655 
6656 #ifdef EPOLL_SUPPORT
6657  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6658  (-1 != daemon->epoll_fd) )
6659  MHD_socket_close_chk_ (daemon->epoll_fd);
6660 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6661  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6662  (-1 != daemon->epoll_upgrade_fd) )
6663  MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
6664 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6665 #endif /* EPOLL_SUPPORT */
6666 
6667 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6669 #endif
6670  }
6671 
6672  if (NULL == daemon->master)
6673  { /* Cleanup that should be done only one time in master/single daemon.
6674  * Do not perform this cleanup in worker daemons. */
6675 
6676  if (MHD_INVALID_SOCKET != fd)
6678 
6679  /* TLS clean up */
6680 #ifdef HTTPS_SUPPORT
6681  if (daemon->have_dhparams)
6682  {
6683  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
6684  daemon->have_dhparams = false;
6685  }
6686  if (0 != (daemon->options & MHD_USE_TLS))
6687  {
6688  gnutls_priority_deinit (daemon->priority_cache);
6689  if (daemon->x509_cred)
6690  gnutls_certificate_free_credentials (daemon->x509_cred);
6691  if (daemon->psk_cred)
6692  gnutls_psk_free_server_credentials (daemon->psk_cred);
6693  }
6694 #endif /* HTTPS_SUPPORT */
6695 
6696 #ifdef DAUTH_SUPPORT
6697  free (daemon->nnc);
6698 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6699  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6700 #endif
6701 #endif
6702 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6704 #endif
6705  free (daemon);
6706  }
6707 }
6708 
6709 
6721 const union MHD_DaemonInfo *
6723  enum MHD_DaemonInfoType info_type,
6724  ...)
6725 {
6726  if (NULL == daemon)
6727  return NULL;
6728  switch (info_type)
6729  {
6731  return NULL; /* no longer supported */
6733  return NULL; /* no longer supported */
6735  return (const union MHD_DaemonInfo *) &daemon->listen_fd;
6736 #ifdef EPOLL_SUPPORT
6738  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
6739 #endif
6741  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
6742  {
6743  /* Assume that MHD_run() in not called in other thread
6744  * at the same time. */
6745  MHD_cleanup_connections (daemon);
6746  }
6747 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6748  else if (daemon->worker_pool)
6749  {
6750  unsigned int i;
6751  /* Collect the connection information stored in the workers. */
6752  daemon->connections = 0;
6753  for (i = 0; i < daemon->worker_pool_size; i++)
6754  {
6755  /* FIXME: next line is thread-safe only if read is atomic. */
6756  daemon->connections += daemon->worker_pool[i].connections;
6757  }
6758  }
6759 #endif
6760  return (const union MHD_DaemonInfo *) &daemon->connections;
6761  case MHD_DAEMON_INFO_FLAGS:
6762  return (const union MHD_DaemonInfo *) &daemon->options;
6764  return (const union MHD_DaemonInfo *) &daemon->port;
6765  default:
6766  return NULL;
6767  }
6768 }
6769 
6770 
6787 void
6789  void *cls)
6790 {
6791  mhd_panic = cb;
6792  mhd_panic_cls = cls;
6793 }
6794 
6795 
6802 const char *
6803 MHD_get_version (void)
6804 {
6805 #ifdef PACKAGE_VERSION
6806  return PACKAGE_VERSION;
6807 #else /* !PACKAGE_VERSION */
6808  static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
6809  if (0 == ver[0])
6810  {
6811  int res = MHD_snprintf_(ver,
6812  sizeof(ver),
6813  "%x.%x.%x",
6814  (((int)MHD_VERSION >> 24) & 0xFF),
6815  (((int)MHD_VERSION >> 16) & 0xFF),
6816  (((int)MHD_VERSION >> 8) & 0xFF));
6817  if (0 >= res || sizeof(ver) <= res)
6818  return "0.0.0"; /* Can't return real version*/
6819  }
6820  return ver;
6821 #endif /* !PACKAGE_VERSION */
6822 }
6823 
6824 
6836 _MHD_EXTERN int
6838 {
6839  switch(feature)
6840  {
6841  case MHD_FEATURE_MESSAGES:
6842 #ifdef HAVE_MESSAGES
6843  return MHD_YES;
6844 #else
6845  return MHD_NO;
6846 #endif
6847  case MHD_FEATURE_TLS:
6848 #ifdef HTTPS_SUPPORT
6849  return MHD_YES;
6850 #else /* ! HTTPS_SUPPORT */
6851  return MHD_NO;
6852 #endif /* ! HTTPS_SUPPORT */
6854 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
6855  return MHD_YES;
6856 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
6857  return MHD_NO;
6858 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
6859  case MHD_FEATURE_IPv6:
6860 #ifdef HAVE_INET6
6861  return MHD_YES;
6862 #else
6863  return MHD_NO;
6864 #endif
6865  case MHD_FEATURE_IPv6_ONLY:
6866 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
6867  return MHD_YES;
6868 #else
6869  return MHD_NO;
6870 #endif
6871  case MHD_FEATURE_POLL:
6872 #ifdef HAVE_POLL
6873  return MHD_YES;
6874 #else
6875  return MHD_NO;
6876 #endif
6877  case MHD_FEATURE_EPOLL:
6878 #ifdef EPOLL_SUPPORT
6879  return MHD_YES;
6880 #else
6881  return MHD_NO;
6882 #endif
6884 #ifdef HAVE_LISTEN_SHUTDOWN
6885  return MHD_YES;
6886 #else
6887  return MHD_NO;
6888 #endif
6890 #ifdef _MHD_ITC_SOCKETPAIR
6891  return MHD_YES;
6892 #else
6893  return MHD_NO;
6894 #endif
6896 #ifdef TCP_FASTOPEN
6897  return MHD_YES;
6898 #else
6899  return MHD_NO;
6900 #endif
6902 #ifdef BAUTH_SUPPORT
6903  return MHD_YES;
6904 #else
6905  return MHD_NO;
6906 #endif
6908 #ifdef DAUTH_SUPPORT
6909  return MHD_YES;
6910 #else
6911  return MHD_NO;
6912 #endif
6914 #ifdef HAVE_POSTPROCESSOR
6915  return MHD_YES;
6916 #else
6917  return MHD_NO;
6918 #endif
6920 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
6921  return MHD_YES;
6922 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
6923  return MHD_NO;
6924 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
6926 #if defined(HAVE_PREAD64) || defined(_WIN32)
6927  return MHD_YES;
6928 #elif defined(HAVE_PREAD)
6929  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
6930 #elif defined(HAVE_LSEEK64)
6931  return MHD_YES;
6932 #else
6933  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
6934 #endif
6936 #if defined(MHD_USE_THREAD_NAME_)
6937  return MHD_YES;
6938 #else
6939  return MHD_NO;
6940 #endif
6941  case MHD_FEATURE_UPGRADE:
6942 #if defined(UPGRADE_SUPPORT)
6943  return MHD_YES;
6944 #else
6945  return MHD_NO;
6946 #endif
6948 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
6949  return MHD_YES;
6950 #else
6951  return MHD_NO;
6952 #endif
6954 #ifdef MHD_USE_GETSOCKNAME
6955  return MHD_YES;
6956 #else
6957  return MHD_NO;
6958 #endif
6960 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL)
6961  return MHD_YES;
6962 #else
6963  return MHD_NO;
6964 #endif
6965  case MHD_FEATURE_SENDFILE:
6966 #ifdef _MHD_HAVE_SENDFILE
6967  return MHD_YES;
6968 #else
6969  return MHD_NO;
6970 #endif
6971  case MHD_FEATURE_THREADS:
6972 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6973  return MHD_YES;
6974 #else
6975  return MHD_NO;
6976 #endif
6977 
6978  }
6979  return MHD_NO;
6980 }
6981 
6982 
6983 #ifdef MHD_HTTPS_REQUIRE_GRYPT
6984 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
6985 #if defined(MHD_USE_POSIX_THREADS)
6986 GCRY_THREAD_OPTION_PTHREAD_IMPL;
6987 #elif defined(MHD_W32_MUTEX_)
6988 
6989 static int
6990 gcry_w32_mutex_init (void **ppmtx)
6991 {
6992  *ppmtx = malloc (sizeof (MHD_mutex_));
6993 
6994  if (NULL == *ppmtx)
6995  return ENOMEM;
6996  if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
6997  {
6998  free (*ppmtx);
6999  *ppmtx = NULL;
7000  return EPERM;
7001  }
7002 
7003  return 0;
7004 }
7005 
7006 
7007 static int
7008 gcry_w32_mutex_destroy (void **ppmtx)
7009 {
7010  int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
7011  free (*ppmtx);
7012  return res;
7013 }
7014 
7015 
7016 static int
7017 gcry_w32_mutex_lock (void **ppmtx)
7018 {
7019  return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7020 }
7021 
7022 
7023 static int
7024 gcry_w32_mutex_unlock (void **ppmtx)
7025 {
7026  return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7027 }
7028 
7029 
7030 static struct gcry_thread_cbs gcry_threads_w32 = {
7031  (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7032  NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7033  gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7034  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
7035 
7036 #endif /* defined(MHD_W32_MUTEX_) */
7037 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
7038 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
7039 
7043 void
7045 {
7046 #if defined(_WIN32) && ! defined(__CYGWIN__)
7047  WSADATA wsd;
7048 #endif /* _WIN32 && ! __CYGWIN__ */
7049 
7050  if (NULL == mhd_panic)
7052 
7053 #if defined(_WIN32) && ! defined(__CYGWIN__)
7054  if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
7055  MHD_PANIC (_("Failed to initialize winsock\n"));
7056  mhd_winsock_inited_ = 1;
7057  if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
7058  MHD_PANIC (_("Winsock version 2.2 is not available\n"));
7059 #endif
7060 #ifdef HTTPS_SUPPORT
7061 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7062 #if GCRYPT_VERSION_NUMBER < 0x010600
7063 #if defined(MHD_USE_POSIX_THREADS)
7064  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7065  &gcry_threads_pthread))
7066  MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
7067 #elif defined(MHD_W32_MUTEX_)
7068  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7069  &gcry_threads_w32))
7070  MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
7071 #endif /* defined(MHD_W32_MUTEX_) */
7072  gcry_check_version (NULL);
7073 #else
7074  if (NULL == gcry_check_version ("1.6.0"))
7075  MHD_PANIC (_("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7076 #endif
7077 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
7078  gnutls_global_init ();
7079 #endif /* HTTPS_SUPPORT */
7081 #ifdef HAVE_FREEBSD_SENDFILE
7082  MHD_conn_init_static_ ();
7083 #endif /* HAVE_FREEBSD_SENDFILE */
7084 }
7085 
7086 
7087 void
7089 {
7090 #ifdef HTTPS_SUPPORT
7091  gnutls_global_deinit ();
7092 #endif /* HTTPS_SUPPORT */
7093 #if defined(_WIN32) && ! defined(__CYGWIN__)
7094  if (mhd_winsock_inited_)
7095  WSACleanup();
7096 #endif
7098 }
7099 
7100 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
7102 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
7103 
7104 /* end of daemon.c */
bool thread_joined
Definition: internal.h:776
#define MHD_send_(s, b, l)
Definition: mhd_sockets.h:259
unsigned int per_ip_connection_limit
Definition: internal.h:1585
void * unescape_callback_cls
Definition: internal.h:1408
volatile int global_init_count
Definition: daemon.c:187
#define MHD_PANIC(msg)
Definition: internal.h:68
void MHD_connection_handle_write(struct MHD_Connection *connection)
Definition: connection.c:2998
_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:5468
Header for platform missing functions.
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:4820
_MHD_EXTERN const char * MHD_get_version(void)
Definition: version.c:35
bool data_already_pending
Definition: internal.h:1497
void MHD_update_last_activity_(struct MHD_Connection *connection)
socklen_t addr_len
Definition: internal.h:730
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
Definition: microhttpd.h:1182
#define MHD_SYS_select_(n, r, w, e, t)
Definition: mhd_sockets.h:323
struct sockaddr_storage addr
Definition: internal.h:725
struct MHD_Connection * cleanup_head
Definition: internal.h:1174
enum MHD_CONNECTION_STATE state
Definition: internal.h:915
void * data
Definition: microhttpd.h:2709
static int call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
Definition: daemon.c:1119
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:920
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:4792
#define MHD_ITC_IS_INVALID_(itc)
Definition: mhd_itc.h:359
struct MHD_Connection * prevX
Definition: internal.h:667
MHD_thread_handle_ID_ pid
Definition: internal.h:1246
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:177
time_t connection_timeout
Definition: internal.h:1579
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:3297
#define MHD_socket_get_error_()
Definition: mhd_sockets.h:507
internal monotonic clock functions implementations
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:118
void * MHD_calloc_(size_t nelem, size_t elsize)
Definition: mhd_compat.c:96
#define MHD_socket_strerr_(err)
Definition: mhd_sockets.h:525
MHD_socket MHD_socket_create_listen_(int pf)
Definition: mhd_sockets.c:471
#define EDLL_insert(head, tail, element)
Definition: internal.h:1829
#define MHD_YES
Definition: microhttpd.h:134
_MHD_EXTERN int MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:2997
#define SIZE_MAX
Definition: mhd_limits.h:99
struct MHD_Response * response
Definition: internal.h:665
struct MHD_Connection * manual_timeout_head
Definition: internal.h:1140
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:1222
#define EXTRA_SLOTS
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:70
MHD_thread_handle_ID_ pid
Definition: internal.h:720
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:95
#define TIME_T_MAX
Definition: mhd_limits.h:132
time_t MHD_monotonic_sec_counter(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:374
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:132
MHD_AccessHandlerCallback default_handler
Definition: internal.h:1254
int MHD_socket
Definition: microhttpd.h:181
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:277
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:2781
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
Definition: daemon.c:4638
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
Definition: mhd_sockets.h:622
_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:4670
intptr_t value
Definition: microhttpd.h:1539
#define MHD_SCKT_LAST_ERR_IS_(code)
Definition: mhd_sockets.h:603
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:4845
platform-specific includes for libmicrohttpd
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
Definition: panic.c:56
void MHD_fini(void)
Definition: daemon.c:7088
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:277
void * uri_log_callback_cls
Definition: internal.h:1398
struct MHD_Daemon * daemon
Definition: internal.h:672
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:229
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
Definition: microhttpd.h:1903
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
Definition: microhttpd.h:1164
#define MHD_TEST_ALLOW_SUSPEND_RESUME
Definition: internal.h:209
int listening_address_reuse
Definition: internal.h:1492
MHD_mutex_ per_ip_connection_mutex
Definition: internal.h:1256
MHD_NotifyConnectionCallback notify_connection
Definition: internal.h:1379
Header for platform-independent inter-thread communication.
void MHD_init(void)
Definition: daemon.c:7044
struct MHD_Connection * next
Definition: internal.h:648
bool client_aware
Definition: internal.h:852
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:27
#define DLL_insert(head, tail, element)
Definition: internal.h:1742
int strict_for_client
Definition: internal.h:1600
void * socket_context
Definition: internal.h:691
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:313
#define MHD_VERSION
Definition: microhttpd.h:129
#define MHD_socket_last_strerr_()
Definition: mhd_sockets.h:532
bool was_quiesced
Definition: internal.h:1502
struct MHD_Connection * connections_tail
Definition: internal.h:1157
struct MHD_Daemon * worker_pool
Definition: internal.h:1070
void * mhd_panic_cls
Definition: daemon.c:161
size_t read_buffer_size
Definition: internal.h:768
int fd
Definition: microhttpd.h:2837
void * client_context
Definition: internal.h:683
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:6558
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:332
struct MemoryPool * MHD_pool_create(size_t max)
Definition: memorypool.c:102
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:182
MHD_socket socket_fd
Definition: internal.h:749
internal shared structures
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:3545
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:78
void MHD_set_https_callbacks(struct MHD_Connection *connection)
#define MHD_SCKT_SEND_MAX_SIZE_
Definition: mhd_sockets.h:220
unsigned int connection_limit
Definition: internal.h:1573
unsigned int worker_pool_size
Definition: internal.h:1363
enum MHD_FLAG options
Definition: internal.h:1590
struct MHD_Connection * connections_head
Definition: internal.h:1152
_MHD_EXTERN int 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:3491
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:246
LogCallback uri_log_callback
Definition: internal.h:1393
void MHD_connection_handle_read(struct MHD_Connection *connection)
Definition: connection.c:2889
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1127
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
Definition: internal.h:742
#define _MHD_EXTERN
Definition: mhd_options.h:51
#define MHD_SCKT_ERR_IS_(err, code)
Definition: mhd_sockets.h:591
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:383
Methods for managing connections.
time_t _MHD_TIMEVAL_TV_SEC_TYPE
Definition: platform.h:122
struct MHD_Daemon * master
Definition: internal.h:1065
#define EDLL_remove(head, tail, element)
Definition: internal.h:1847
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:1147
uint16_t port
Definition: internal.h:1595
#define NULL
Definition: reason_phrase.c:30
unsigned int connections
Definition: internal.h:1358
#define ULLONG_MAX
Definition: mhd_limits.h:58
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:449
struct MHD_Connection * prev
Definition: internal.h:653
#define TIMEVAL_TV_SEC_MAX
Definition: mhd_limits.h:140
#define DLL_remove(head, tail, element)
Definition: internal.h:1762
#define MHD_SCKT_EINVAL_
Definition: mhd_sockets.h:448
#define MHD_strerror_(errnum)
Definition: mhd_compat.h:44
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:63
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
MHD_FEATURE
Definition: microhttpd.h:3530
static int 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:904
struct MHD_Connection * normal_timeout_head
Definition: internal.h:1125
#define _MHD_SYS_DEFAULT_FD_SETSIZE
Definition: mhd_sockets.h:126
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:157
UnescapeCallback unescape_callback
Definition: internal.h:1403
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:2686
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
Definition: internal.h:1736
#define XDLL_remove(head, tail, element)
Definition: internal.h:1806
void MHD_monotonic_sec_counter_finish(void)
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
static int 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:3387
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:1169
#define MHD_create_named_thread_(t, n, s, r, a)
Definition: mhd_threads.h:208
int MHD_SCKT_OPT_BOOL_
Definition: mhd_sockets.h:201
size_t pool_size
Definition: internal.h:1443
bool tls_read_ready
Definition: internal.h:766
struct MHD_itc_ itc
Definition: internal.h:1407
MHD_AcceptPolicyCallback apc
Definition: internal.h:1357
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
time_t last_activity
Definition: internal.h:736
struct MHD_Connection * cleanup_tail
Definition: internal.h:1179
int MHD_connection_handle_idle(struct MHD_Connection *connection)
Definition: connection.c:3314
static int resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:2845
#define MHD_itc_destroy_chk_(itc)
Definition: mhd_itc.h:345
static int internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck)
Definition: daemon.c:2270
int(* 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:1962
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:4007
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3188
bool sk_nonblck
Definition: internal.h:781
void MHD_monotonic_sec_counter_init(void)
#define MHD_recv_(s, b, l)
Definition: mhd_sockets.h:270
static int MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:3056
_MHD_EXTERN int 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:654
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:293
void * ptr_value
Definition: microhttpd.h:1545
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:1985
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:1132
void MHD_check_global_init_(void)
Definition: daemon.c:204
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:1368
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
Definition: mhd_sockets.h:645
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:151
#define MHD_BUF_INC_SIZE
Definition: internal.h:117
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
Definition: mhd_sockets.h:299
bool resuming
Definition: internal.h:1507
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:4551
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:3877
void * notify_completed_cls
Definition: internal.h:1373
MHD_socket listen_fd
Definition: internal.h:1481
struct MemoryPool * pool
Definition: internal.h:682
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:4516
MHD_OPTION
MHD options.
Definition: microhttpd.h:1193
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:404
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:1236
void * notify_connection_cls
Definition: internal.h:1384
void * apc_cls
Definition: internal.h:1362
bool at_limit
Definition: internal.h:1480
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
Definition: daemon_start.c:613
MHD_PanicCallback mhd_panic
Definition: daemon.c:156
#define XDLL_insert(head, tail, element)
Definition: internal.h:1786
MHD_DaemonInfoType
Definition: microhttpd.h:1838
#define _(String)
Definition: mhd_options.h:42
#define MHD_UNSIGNED_LONG_LONG_PRINTF
Definition: microhttpd.h:290
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:2810
bool suspended
Definition: internal.h:761
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
Definition: daemon.c:6837
struct MHD_Connection * suspended_connections_head
Definition: internal.h:1163
void * per_ip_connection_count
Definition: internal.h:1184
size_t read_buffer_offset
Definition: internal.h:774
_MHD_EXTERN int 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:1053
void * default_handler_cls
Definition: internal.h:1259
#define MHD_NO
Definition: microhttpd.h:139
volatile bool shutdown
Definition: internal.h:1523
#define MHD_SCKT_ERR_IS_EINTR_(err)
Definition: mhd_sockets.h:613
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1262
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:4715
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Definition: microhttpd.h:1917
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
Definition: microhttpd.h:2011
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:6722
_MHD_EXTERN size_t MHD_http_unescape(char *val)
Definition: internal.c:138
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
Definition: mhd_sockets.h:633
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:6402
limits values definitions
enum MHD_OPTION option
Definition: microhttpd.h:1532
int MHD_socket_noninheritable_(MHD_socket sock)
Definition: mhd_sockets.c:439
#define MAYBE_SOCK_NONBLOCK
Definition: mhd_sockets.h:162
MHD_FLAG
Flags for the struct MHD_Daemon.
Definition: microhttpd.h:888
size_t pool_increment
Definition: internal.h:1448
int MHD_socket_buffering_reset_(MHD_socket sock)
Definition: mhd_sockets.c:471
#define MAYBE_SOCK_CLOEXEC
Definition: mhd_sockets.h:156
#define MHD_SCKT_EINTR_
Definition: mhd_sockets.h:398