GNU libmicrohttpd  0.9.61
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 #include "mhd_threads.h"
30 #include "internal.h"
31 #include "response.h"
32 #include "connection.h"
33 #include "memorypool.h"
34 #include "mhd_limits.h"
35 #include "autoinit_funcs.h"
36 #include "mhd_mono_clock.h"
37 #include "mhd_locks.h"
38 #include "mhd_sockets.h"
39 #include "mhd_itc.h"
40 #include "mhd_compat.h"
41 
42 #if HAVE_SEARCH_H
43 #include <search.h>
44 #else
45 #include "tsearch.h"
46 #endif
47 
48 #ifdef HTTPS_SUPPORT
49 #include "connection_https.h"
50 #ifdef MHD_HTTPS_REQUIRE_GRYPT
51 #include <gcrypt.h>
52 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
53 #endif /* HTTPS_SUPPORT */
54 
55 #if defined(_WIN32) && ! defined(__CYGWIN__)
56 #ifndef WIN32_LEAN_AND_MEAN
57 #define WIN32_LEAN_AND_MEAN 1
58 #endif /* !WIN32_LEAN_AND_MEAN */
59 #include <windows.h>
60 #endif
61 
65 #ifdef MHD_POSIX_SOCKETS
66 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
67 #else
68 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
69 #endif
70 
74 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
75 
80 #define DEBUG_CLOSE MHD_NO
81 
86 #define DEBUG_CONNECT MHD_NO
87 
88 
89 /* Forward declarations. */
90 
99 static void
100 close_all_connections (struct MHD_Daemon *daemon);
101 
102 #ifdef EPOLL_SUPPORT
103 
112 static int
113 MHD_epoll (struct MHD_Daemon *daemon,
114  int may_block);
115 
116 #endif /* EPOLL_SUPPORT */
117 
127 static void
128 mhd_panic_std (void *cls,
129  const char *file,
130  unsigned int line,
131  const char *reason)
132 {
133  (void)cls; /* Mute compiler warning. */
134 #ifdef HAVE_MESSAGES
135  fprintf (stderr,
136  _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
137  file,
138  line,
139  reason);
140 #else /* ! HAVE_MESSAGES */
141  (void)file; /* Mute compiler warning. */
142  (void)line; /* Mute compiler warning. */
143  (void)reason; /* Mute compiler warning. */
144 #endif
145  abort ();
146 }
147 
148 
153 
158 
162 void
163 MHD_init(void);
164 
165 
166 #if defined(_WIN32) && ! defined(__CYGWIN__)
167 
170 static int mhd_winsock_inited_ = 0;
171 #endif
172 
173 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
174 
178 #define MHD_check_global_init_() (void)0
179 #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
180 
183 volatile int global_init_count = 0;
184 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
185 
188 MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_);
189 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
190 
194 void
196 {
197 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
198  MHD_mutex_lock_chk_(&global_init_mutex_);
199 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
200  if (0 == global_init_count++)
201  MHD_init ();
202 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
203  MHD_mutex_unlock_chk_(&global_init_mutex_);
204 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
205 }
206 #endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
207 
215 static struct MHD_Daemon*
216 MHD_get_master (struct MHD_Daemon *daemon)
217 {
218  while (NULL != daemon->master)
219  daemon = daemon->master;
220  return daemon;
221 }
222 
223 
227 struct MHD_IPCount
228 {
232  int family;
233 
237  union
238  {
242  struct in_addr ipv4;
243 #if HAVE_INET6
244 
247  struct in6_addr ipv6;
248 #endif
249  } addr;
250 
254  unsigned int count;
255 };
256 
257 
263 static void
265 {
267 }
268 
269 
275 static void
277 {
279 }
280 
281 
291 static int
292 MHD_ip_addr_compare (const void *a1,
293  const void *a2)
294 {
295  return memcmp (a1,
296  a2,
297  offsetof (struct MHD_IPCount,
298  count));
299 }
300 
301 
310 static int
311 MHD_ip_addr_to_key (const struct sockaddr *addr,
312  socklen_t addrlen,
313  struct MHD_IPCount *key)
314 {
315  memset(key,
316  0,
317  sizeof(*key));
318 
319  /* IPv4 addresses */
320  if (sizeof (struct sockaddr_in) == addrlen)
321  {
322  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
323 
324  key->family = AF_INET;
325  memcpy (&key->addr.ipv4,
326  &addr4->sin_addr,
327  sizeof(addr4->sin_addr));
328  return MHD_YES;
329  }
330 
331 #if HAVE_INET6
332  /* IPv6 addresses */
333  if (sizeof (struct sockaddr_in6) == addrlen)
334  {
335  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
336 
337  key->family = AF_INET6;
338  memcpy (&key->addr.ipv6,
339  &addr6->sin6_addr,
340  sizeof(addr6->sin6_addr));
341  return MHD_YES;
342  }
343 #endif
344 
345  /* Some other address */
346  return MHD_NO;
347 }
348 
349 
361 static int
362 MHD_ip_limit_add (struct MHD_Daemon *daemon,
363  const struct sockaddr *addr,
364  socklen_t addrlen)
365 {
366  struct MHD_IPCount *key;
367  void **nodep;
368  void *node;
369  int result;
370 
371  daemon = MHD_get_master (daemon);
372  /* Ignore if no connection limit assigned */
373  if (0 == daemon->per_ip_connection_limit)
374  return MHD_YES;
375 
376  if (NULL == (key = malloc (sizeof(*key))))
377  return MHD_NO;
378 
379  /* Initialize key */
380  if (MHD_NO == MHD_ip_addr_to_key (addr,
381  addrlen,
382  key))
383  {
384  /* Allow unhandled address types through */
385  free (key);
386  return MHD_YES;
387  }
388  MHD_ip_count_lock (daemon);
389 
390  /* Search for the IP address */
391  if (NULL == (nodep = tsearch (key,
392  &daemon->per_ip_connection_count,
394  {
395 #ifdef HAVE_MESSAGES
396  MHD_DLOG (daemon,
397  _("Failed to add IP connection count node\n"));
398 #endif
399  MHD_ip_count_unlock (daemon);
400  free (key);
401  return MHD_NO;
402  }
403  node = *nodep;
404  /* If we got an existing node back, free the one we created */
405  if (node != key)
406  free(key);
407  key = (struct MHD_IPCount *) node;
408  /* Test if there is room for another connection; if so,
409  * increment count */
410  result = (key->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO;
411  if (MHD_YES == result)
412  ++key->count;
413 
414  MHD_ip_count_unlock (daemon);
415  return result;
416 }
417 
418 
427 static void
428 MHD_ip_limit_del (struct MHD_Daemon *daemon,
429  const struct sockaddr *addr,
430  socklen_t addrlen)
431 {
432  struct MHD_IPCount search_key;
433  struct MHD_IPCount *found_key;
434  void **nodep;
435 
436  daemon = MHD_get_master (daemon);
437  /* Ignore if no connection limit assigned */
438  if (0 == daemon->per_ip_connection_limit)
439  return;
440  /* Initialize search key */
441  if (MHD_NO == MHD_ip_addr_to_key (addr,
442  addrlen,
443  &search_key))
444  return;
445 
446  MHD_ip_count_lock (daemon);
447 
448  /* Search for the IP address */
449  if (NULL == (nodep = tfind (&search_key,
450  &daemon->per_ip_connection_count,
452  {
453  /* Something's wrong if we couldn't find an IP address
454  * that was previously added */
455  MHD_PANIC (_("Failed to find previously-added IP address\n"));
456  }
457  found_key = (struct MHD_IPCount *) *nodep;
458  /* Validate existing count for IP address */
459  if (0 == found_key->count)
460  {
461  MHD_PANIC (_("Previously-added IP address had counter of zero\n"));
462  }
463  /* Remove the node entirely if count reduces to 0 */
464  if (0 == --found_key->count)
465  {
466  tdelete (found_key,
467  &daemon->per_ip_connection_count,
469  free (found_key);
470  }
471 
472  MHD_ip_count_unlock (daemon);
473 }
474 
475 
476 #ifdef HTTPS_SUPPORT
477 
483 static int
484 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
485 {
486  gnutls_datum_t key;
487  gnutls_datum_t cert;
488  int ret;
489 
490 #if GNUTLS_VERSION_MAJOR >= 3
491  if (NULL != daemon->cert_callback)
492  {
493  gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
494  daemon->cert_callback);
495  }
496 #endif
497  if (NULL != daemon->https_mem_trust)
498  {
499  cert.data = (unsigned char *) daemon->https_mem_trust;
500  cert.size = strlen (daemon->https_mem_trust);
501  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred,
502  &cert,
503  GNUTLS_X509_FMT_PEM) < 0)
504  {
505 #ifdef HAVE_MESSAGES
506  MHD_DLOG(daemon,
507  "Bad trust certificate format\n");
508 #endif
509  return -1;
510  }
511  }
512 
513  if (daemon->have_dhparams)
514  {
515  gnutls_certificate_set_dh_params (daemon->x509_cred,
516  daemon->https_mem_dhparams);
517  }
518  /* certificate & key loaded from memory */
519  if ( (NULL != daemon->https_mem_cert) &&
520  (NULL != daemon->https_mem_key) )
521  {
522  key.data = (unsigned char *) daemon->https_mem_key;
523  key.size = strlen (daemon->https_mem_key);
524  cert.data = (unsigned char *) daemon->https_mem_cert;
525  cert.size = strlen (daemon->https_mem_cert);
526 
527  if (NULL != daemon->https_key_password) {
528 #if GNUTLS_VERSION_NUMBER >= 0x030111
529  ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
530  &cert,
531  &key,
532  GNUTLS_X509_FMT_PEM,
533  daemon->https_key_password,
534  0);
535 #else
536 #ifdef HAVE_MESSAGES
537  MHD_DLOG (daemon,
538  _("Failed to setup x509 certificate/key: pre 3.X.X version " \
539  "of GnuTLS does not support setting key password"));
540 #endif
541  return -1;
542 #endif
543  }
544  else
545  ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
546  &cert,
547  &key,
548  GNUTLS_X509_FMT_PEM);
549 #ifdef HAVE_MESSAGES
550  if (0 != ret)
551  MHD_DLOG (daemon,
552  "GnuTLS failed to setup x509 certificate/key: %s\n",
553  gnutls_strerror (ret));
554 #endif
555  return ret;
556  }
557 #if GNUTLS_VERSION_MAJOR >= 3
558  if (NULL != daemon->cert_callback)
559  return 0;
560 #endif
561 #ifdef HAVE_MESSAGES
562  MHD_DLOG (daemon,
563  "You need to specify a certificate and key location\n");
564 #endif
565  return -1;
566 }
567 
574 static int
575 MHD_TLS_init (struct MHD_Daemon *daemon)
576 {
577  switch (daemon->cred_type)
578  {
579  case GNUTLS_CRD_CERTIFICATE:
580  if (0 !=
581  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
582  return GNUTLS_E_MEMORY_ERROR;
583  return MHD_init_daemon_certificate (daemon);
584  case GNUTLS_CRD_PSK:
585  if (0 !=
586  gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
587  return GNUTLS_E_MEMORY_ERROR;
588  return 0;
589  default:
590 #ifdef HAVE_MESSAGES
591  MHD_DLOG (daemon,
592  _("Error: invalid credentials type %d specified.\n"),
593  daemon->cred_type);
594 #endif
595  return -1;
596  }
597 }
598 #endif /* HTTPS_SUPPORT */
599 
600 
601 #undef MHD_get_fdset
602 
632 int
633 MHD_get_fdset (struct MHD_Daemon *daemon,
634  fd_set *read_fd_set,
635  fd_set *write_fd_set,
636  fd_set *except_fd_set,
637  MHD_socket *max_fd)
638 {
639  return MHD_get_fdset2 (daemon,
640  read_fd_set,
641  write_fd_set,
642  except_fd_set,
643  max_fd,
645 }
646 
647 
648 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
649 
661 static bool
662 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
663  fd_set *rs,
664  fd_set *ws,
665  fd_set *es,
666  MHD_socket *max_fd,
667  unsigned int fd_setsize)
668 {
669  const MHD_socket conn_sckt = urh->connection->socket_fd;
670  const MHD_socket mhd_sckt = urh->mhd.socket;
671  bool res = true;
672 
673  /* Do not add to 'es' only if socket is closed
674  * or not used anymore. */
675  if (MHD_INVALID_SOCKET != conn_sckt)
676  {
677  if ( (urh->in_buffer_used < urh->in_buffer_size) &&
678  (! MHD_add_to_fd_set_ (conn_sckt,
679  rs,
680  max_fd,
681  fd_setsize)) )
682  res = false;
683  if ( (0 != urh->out_buffer_used) &&
684  (! MHD_add_to_fd_set_ (conn_sckt,
685  ws,
686  max_fd,
687  fd_setsize)) )
688  res = false;
689  /* Do not monitor again for errors if error was detected before as
690  * error state is remembered. */
691  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
692  ((0 != urh->in_buffer_size) ||
693  (0 != urh->out_buffer_size) ||
694  (0 != urh->out_buffer_used)))
695  MHD_add_to_fd_set_ (conn_sckt,
696  es,
697  max_fd,
698  fd_setsize);
699  }
700  if (MHD_INVALID_SOCKET != mhd_sckt)
701  {
702  if ( (urh->out_buffer_used < urh->out_buffer_size) &&
703  (! MHD_add_to_fd_set_ (mhd_sckt,
704  rs,
705  max_fd,
706  fd_setsize)) )
707  res = false;
708  if ( (0 != urh->in_buffer_used) &&
709  (! MHD_add_to_fd_set_ (mhd_sckt,
710  ws,
711  max_fd,
712  fd_setsize)) )
713  res = false;
714  /* Do not monitor again for errors if error was detected before as
715  * error state is remembered. */
716  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
717  ((0 != urh->out_buffer_size) ||
718  (0 != urh->in_buffer_size) ||
719  (0 != urh->in_buffer_used)))
720  MHD_add_to_fd_set_ (mhd_sckt,
721  es,
722  max_fd,
723  fd_setsize);
724  }
725 
726  return res;
727 }
728 
729 
739 static void
740 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
741  const fd_set *rs,
742  const fd_set *ws,
743  const fd_set *es)
744 {
745  const MHD_socket conn_sckt = urh->connection->socket_fd;
746  const MHD_socket mhd_sckt = urh->mhd.socket;
747 
748  /* Reset read/write ready, preserve error state. */
751 
752  if (MHD_INVALID_SOCKET != conn_sckt)
753  {
754  if (FD_ISSET (conn_sckt, rs))
755  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
756  if (FD_ISSET (conn_sckt, ws))
757  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
758  if (FD_ISSET (conn_sckt, es))
759  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
760  }
761  if ((MHD_INVALID_SOCKET != mhd_sckt))
762  {
763  if (FD_ISSET (mhd_sckt, rs))
764  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
765  if (FD_ISSET (mhd_sckt, ws))
766  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
767  if (FD_ISSET (mhd_sckt, es))
768  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
769  }
770 }
771 
772 #ifdef HAVE_POLL
773 
782 static void
783 urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
784  struct pollfd p[2])
785 {
786  p[0].events = 0;
787  p[1].events = 0;
788 
789  if (urh->in_buffer_used < urh->in_buffer_size)
790  p[0].events |= POLLIN;
791  if (0 != urh->out_buffer_used)
792  p[0].events |= POLLOUT;
793 
794  /* Do not monitor again for errors if error was detected before as
795  * error state is remembered. */
796  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
797  ((0 != urh->in_buffer_size) ||
798  (0 != urh->out_buffer_size) ||
799  (0 != urh->out_buffer_used)))
800  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
801 
802  if (urh->out_buffer_used < urh->out_buffer_size)
803  p[1].events |= POLLIN;
804  if (0 != urh->in_buffer_used)
805  p[1].events |= POLLOUT;
806 
807  /* Do not monitor again for errors if error was detected before as
808  * error state is remembered. */
809  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
810  ((0 != urh->out_buffer_size) ||
811  (0 != urh->in_buffer_size) ||
812  (0 != urh->in_buffer_used)))
813  p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
814 }
815 
816 
823 static void
824 urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
825  struct pollfd p[2])
826 {
827  p[0].fd = urh->connection->socket_fd;
828  p[1].fd = urh->mhd.socket;
829  urh_update_pollfd (urh,
830  p);
831 }
832 
833 
839 static void
840 urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
841  struct pollfd p[2])
842 {
843  /* Reset read/write ready, preserve error state. */
846 
847  if (0 != (p[0].revents & POLLIN))
848  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
849  if (0 != (p[0].revents & POLLOUT))
850  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
851  if (0 != (p[0].revents & POLLHUP))
853  if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
854  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
855  if (0 != (p[1].revents & POLLIN))
856  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
857  if (0 != (p[1].revents & POLLOUT))
858  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
859  if (0 != (p[1].revents & POLLHUP))
860  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
861  if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
863 }
864 #endif /* HAVE_POLL */
865 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
866 
867 
882 static int
884  fd_set *read_fd_set,
885  fd_set *write_fd_set,
886  fd_set *except_fd_set,
887  MHD_socket *max_fd,
888  unsigned int fd_setsize)
889 
890 {
891  struct MHD_Connection *pos;
892  struct MHD_Connection *posn;
893  int result = MHD_YES;
894  MHD_socket ls;
895 
896  if (daemon->shutdown)
897  return MHD_NO;
898 
899  ls = daemon->listen_fd;
900  if ( (MHD_INVALID_SOCKET != ls) &&
901  (! daemon->was_quiesced) &&
902  (! MHD_add_to_fd_set_ (ls,
903  read_fd_set,
904  max_fd,
905  fd_setsize)) )
906  result = MHD_NO;
907 
908  /* Add all sockets to 'except_fd_set' as well to watch for
909  * out-of-band data. However, ignore errors if INFO_READ
910  * or INFO_WRITE sockets will not fit 'except_fd_set'. */
911  /* Start from oldest connections. Make sense for W32 FDSETs. */
912  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
913  {
914  posn = pos->prev;
915 
916  switch (pos->event_loop_info)
917  {
919  if (! MHD_add_to_fd_set_ (pos->socket_fd,
920  read_fd_set,
921  max_fd,
922  fd_setsize))
923  result = MHD_NO;
924 #ifdef MHD_POSIX_SOCKETS
926  except_fd_set,
927  max_fd,
928  fd_setsize);
929 #endif /* MHD_POSIX_SOCKETS */
930  break;
932  if (! MHD_add_to_fd_set_ (pos->socket_fd,
933  write_fd_set,
934  max_fd,
935  fd_setsize))
936  result = MHD_NO;
937 #ifdef MHD_POSIX_SOCKETS
939  except_fd_set,
940  max_fd,
941  fd_setsize);
942 #endif /* MHD_POSIX_SOCKETS */
943  break;
945  if ( (NULL == except_fd_set) ||
947  except_fd_set,
948  max_fd,
949  fd_setsize))
950  result = MHD_NO;
951  break;
953  /* this should never happen */
954  break;
955  }
956  }
957 #ifdef MHD_WINSOCK_SOCKETS
958  /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
959  * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
960  * not be pushed out. */
961  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
962  {
963  posn = pos->prev;
965  except_fd_set,
966  max_fd,
967  fd_setsize);
968  }
969 #endif /* MHD_WINSOCK_SOCKETS */
970 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
971  {
972  struct MHD_UpgradeResponseHandle *urh;
973 
974  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
975  {
976  if (MHD_NO ==
977  urh_to_fdset (urh,
978  read_fd_set,
979  write_fd_set,
980  except_fd_set,
981  max_fd,
982  fd_setsize))
983  result = MHD_NO;
984  }
985  }
986 #endif
987 #if DEBUG_CONNECT
988 #ifdef HAVE_MESSAGES
989  if (NULL != max_fd)
990  MHD_DLOG (daemon,
991  _("Maximum socket in select set: %d\n"),
992  *max_fd);
993 #endif
994 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
995  return result;
996 }
997 
998 
1031 int
1032 MHD_get_fdset2 (struct MHD_Daemon *daemon,
1033  fd_set *read_fd_set,
1034  fd_set *write_fd_set,
1035  fd_set *except_fd_set,
1036  MHD_socket *max_fd,
1037  unsigned int fd_setsize)
1038 {
1039  fd_set es;
1040 
1041  if ( (NULL == daemon) ||
1042  (NULL == read_fd_set) ||
1043  (NULL == write_fd_set) ||
1044  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ||
1045  (0 != (daemon->options & MHD_USE_POLL)))
1046  return MHD_NO;
1047 
1048  if (NULL == except_fd_set)
1049  { /* Workaround to maintain backward compatibility. */
1050 #ifdef HAVE_MESSAGES
1051  MHD_DLOG (daemon,
1052  _("MHD_get_fdset2() called with except_fd_set "
1053  "set to NULL. Such behavior is unsupported.\n"));
1054 #endif
1055  FD_ZERO (&es);
1056  except_fd_set = &es;
1057  }
1058 
1059 #ifdef EPOLL_SUPPORT
1060  if (0 != (daemon->options & MHD_USE_EPOLL))
1061  {
1062  if (daemon->shutdown)
1063  return MHD_NO;
1064 
1065  /* we're in epoll mode, use the epoll FD as a stand-in for
1066  the entire event set */
1067 
1068  return MHD_add_to_fd_set_ (daemon->epoll_fd,
1069  read_fd_set,
1070  max_fd,
1071  fd_setsize) ? MHD_YES : MHD_NO;
1072  }
1073 #endif
1074 
1075  return internal_get_fdset2 (daemon,
1076  read_fd_set,
1077  write_fd_set,
1078  except_fd_set,
1079  max_fd,
1080  fd_setsize);
1081 }
1082 
1083 
1097 static int
1099  bool read_ready,
1100  bool write_ready,
1101  bool force_close)
1102 {
1103  int ret;
1104  bool states_info_processed = false;
1105  /* Fast track flag */
1106  bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
1107 
1108 #ifdef HTTPS_SUPPORT
1109  if (con->tls_read_ready)
1110  read_ready = true;
1111 #endif /* HTTPS_SUPPORT */
1112  if (!force_close)
1113  {
1114  if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) &&
1115  read_ready)
1116  {
1118  ret = MHD_connection_handle_idle (con);
1119  states_info_processed = true;
1120  }
1121  /* No need to check value of 'ret' here as closed connection
1122  * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
1123  if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
1124  write_ready)
1125  {
1127  ret = MHD_connection_handle_idle (con);
1128  states_info_processed = true;
1129  }
1130  }
1131  else
1132  {
1133  MHD_connection_close_ (con,
1135  return MHD_connection_handle_idle (con);
1136  }
1137 
1138  if (!states_info_processed)
1139  { /* Connection is not read or write ready, but external conditions
1140  * may be changed and need to be processed. */
1141  ret = MHD_connection_handle_idle (con);
1142  }
1143  /* Fast track for fast connections. */
1144  /* If full request was read by single read_handler() invocation
1145  and headers were completely prepared by single MHD_connection_handle_idle()
1146  then try not to wait for next sockets polling and send response
1147  immediately.
1148  As writeability of socket was not checked and it may have
1149  some data pending in system buffers, use this optimization
1150  only for non-blocking sockets. */
1151  /* No need to check 'ret' as connection is always in
1152  * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
1153  else if (on_fasttrack && con->sk_nonblck)
1154  {
1156  {
1158  /* Always call 'MHD_connection_handle_idle()' after each read/write. */
1159  ret = MHD_connection_handle_idle (con);
1160  }
1161  /* If all headers were sent by single write_handler() and
1162  * response body is prepared by single MHD_connection_handle_idle()
1163  * call - continue. */
1164  if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
1166  {
1168  ret = MHD_connection_handle_idle (con);
1169  }
1170  }
1171 
1172  /* All connection's data and states are processed for this turn.
1173  * If connection already has more data to be processed - use
1174  * zero timeout for next select()/poll(). */
1175  /* Thread-per-connection do not need global zero timeout as
1176  * connections are processed individually. */
1177  /* Note: no need to check for read buffer availability for
1178  * TLS read-ready connection in 'read info' state as connection
1179  * without space in read buffer will be market as 'info block'. */
1180  if ( (!con->daemon->data_already_pending) &&
1181  (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1182  {
1184  con->daemon->data_already_pending = true;
1185 #ifdef HTTPS_SUPPORT
1186  else if ( (con->tls_read_ready) &&
1188  con->daemon->data_already_pending = true;
1189 #endif /* HTTPS_SUPPORT */
1190  }
1191  return ret;
1192 }
1193 
1194 
1195 #ifdef UPGRADE_SUPPORT
1196 
1203 static void
1204 cleanup_upgraded_connection (struct MHD_Connection *connection)
1205 {
1206  struct MHD_UpgradeResponseHandle *urh = connection->urh;
1207 
1208  if (NULL == urh)
1209  return;
1210 #ifdef HTTPS_SUPPORT
1211  /* Signal remote client the end of TLS connection by
1212  * gracefully closing TLS session. */
1213  if (0 != (connection->daemon->options & MHD_USE_TLS))
1214  gnutls_bye (connection->tls_session,
1215  GNUTLS_SHUT_WR);
1216 
1217  if (MHD_INVALID_SOCKET != urh->mhd.socket)
1218  MHD_socket_close_chk_ (urh->mhd.socket);
1219 
1220  if (MHD_INVALID_SOCKET != urh->app.socket)
1221  MHD_socket_close_chk_ (urh->app.socket);
1222 #endif /* HTTPS_SUPPORT */
1223  connection->urh = NULL;
1224  free (urh);
1225 }
1226 #endif /* UPGRADE_SUPPORT */
1227 
1228 
1229 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1230 
1238 static void
1239 process_urh (struct MHD_UpgradeResponseHandle *urh)
1240 {
1241  /* Help compiler to optimize:
1242  * pointers to 'connection' and 'daemon' are not changed
1243  * during this processing, so no need to chain dereference
1244  * each time. */
1245  struct MHD_Connection * const connection = urh->connection;
1246  struct MHD_Daemon * const daemon = connection->daemon;
1247  /* Prevent data races: use same value of 'was_closed' throughout
1248  * this function. If 'was_closed' changed externally in the middle
1249  * of processing - it will be processed on next iteration. */
1250  bool was_closed;
1251  if (daemon->shutdown)
1252  {
1253  /* Daemon shutting down, application will not receive any more data. */
1254 #ifdef HAVE_MESSAGES
1255  if (! urh->was_closed)
1256  {
1257  MHD_DLOG (daemon,
1258  _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1259  }
1260 #endif
1261  urh->was_closed = true;
1262  }
1263  was_closed = urh->was_closed;
1264  if (was_closed)
1265  {
1266  /* Application was closed connections: no more data
1267  * can be forwarded to application socket. */
1268  if (0 < urh->in_buffer_used)
1269  {
1270 #ifdef HAVE_MESSAGES
1271  MHD_DLOG (daemon,
1272  _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
1273  " bytes of data received from remote side: application shut down socket\n"),
1274  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
1275 #endif
1276 
1277  }
1278  /* If application signaled MHD about socket closure then
1279  * check for any pending data even if socket is not marked
1280  * as 'ready' (signal may arrive after poll()/select()).
1281  * Socketpair for forwarding is always in non-blocking mode
1282  * so no risk that recv() will block the thread. */
1283  if (0 != urh->out_buffer_size)
1284  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1285  /* Discard any data received form remote. */
1286  urh->in_buffer_used = 0;
1287  /* Do not try to push data to application. */
1288  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1289  /* Reading from remote client is not required anymore. */
1290  urh->in_buffer_size = 0;
1291  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1292  connection->tls_read_ready = false;
1293  }
1294 
1295  /* On some platforms (W32, possibly Darwin) failed send() (send() will always
1296  * fail after remote disconnect was detected) may discard data in system
1297  * buffers received by system but not yet read by recv().
1298  * So, before trying send() on any socket, recv() must be performed at first
1299  * otherwise last part of incoming data may be lost. */
1300 
1301  /* If disconnect or error was detected - try to read from socket
1302  * to dry data possibly pending is system buffers. */
1303  if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
1304  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
1305  if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
1306  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1307 
1308  /*
1309  * handle reading from remote TLS client
1310  */
1311  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
1312  (connection->tls_read_ready) ) &&
1313  (urh->in_buffer_used < urh->in_buffer_size) )
1314  {
1315  ssize_t res;
1316  size_t buf_size;
1317 
1318  buf_size = urh->in_buffer_size - urh->in_buffer_used;
1319  if (buf_size > SSIZE_MAX)
1320  buf_size = SSIZE_MAX;
1321 
1322  connection->tls_read_ready = false;
1323  res = gnutls_record_recv (connection->tls_session,
1324  &urh->in_buffer[urh->in_buffer_used],
1325  buf_size);
1326  if (0 >= res)
1327  {
1328  if (GNUTLS_E_INTERRUPTED != res)
1329  {
1330  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1331  if (GNUTLS_E_AGAIN != res)
1332  {
1333  /* Unrecoverable error on socket was detected or
1334  * socket was disconnected/shut down. */
1335  /* Stop trying to read from this TLS socket. */
1336  urh->in_buffer_size = 0;
1337  }
1338  }
1339  }
1340  else /* 0 < res */
1341  {
1342  urh->in_buffer_used += res;
1343  if (buf_size > (size_t)res)
1344  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1345  else if (0 < gnutls_record_check_pending (connection->tls_session))
1346  connection->tls_read_ready = true;
1347  }
1348  if (MHD_EPOLL_STATE_ERROR ==
1349  ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
1350  {
1351  /* Unrecoverable error on socket was detected and all
1352  * pending data was read from system buffers. */
1353  /* Stop trying to read from this TLS socket. */
1354  urh->in_buffer_size = 0;
1355  }
1356  }
1357 
1358  /*
1359  * handle reading from application
1360  */
1361  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1362  (urh->out_buffer_used < urh->out_buffer_size) )
1363  {
1364  ssize_t res;
1365  size_t buf_size;
1366 
1367  buf_size = urh->out_buffer_size - urh->out_buffer_used;
1368  if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
1369  buf_size = MHD_SCKT_SEND_MAX_SIZE_;
1370 
1371  res = MHD_recv_ (urh->mhd.socket,
1372  &urh->out_buffer[urh->out_buffer_used],
1373  buf_size);
1374  if (0 >= res)
1375  {
1376  const int err = MHD_socket_get_error_ ();
1377  if ((0 == res) ||
1378  ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1380  {
1381  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1382  if ((0 == res) ||
1383  (was_closed) ||
1384  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1385  (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
1386  {
1387  /* Socket disconnect/shutdown was detected;
1388  * Application signaled about closure of 'upgraded' socket;
1389  * or persistent / unrecoverable error. */
1390  /* Do not try to pull more data from application. */
1391  urh->out_buffer_size = 0;
1392  }
1393  }
1394  }
1395  else /* 0 < res */
1396  {
1397  urh->out_buffer_used += res;
1398  if (buf_size > (size_t)res)
1399  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1400  }
1401  if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1402  ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1403  (was_closed) ) )
1404  {
1405  /* Unrecoverable error on socket was detected and all
1406  * pending data was read from system buffers. */
1407  /* Do not try to pull more data from application. */
1408  urh->out_buffer_size = 0;
1409  }
1410  }
1411 
1412  /*
1413  * handle writing to remote HTTPS client
1414  */
1415  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
1416  (urh->out_buffer_used > 0) )
1417  {
1418  ssize_t res;
1419  size_t data_size;
1420 
1421  data_size = urh->out_buffer_used;
1422  if (data_size > SSIZE_MAX)
1423  data_size = SSIZE_MAX;
1424 
1425  res = gnutls_record_send (connection->tls_session,
1426  urh->out_buffer,
1427  data_size);
1428  if (0 >= res)
1429  {
1430  if (GNUTLS_E_INTERRUPTED != res)
1431  {
1432  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1433  if (GNUTLS_E_INTERRUPTED != res)
1434  {
1435  /* TLS connection shut down or
1436  * persistent / unrecoverable error. */
1437 #ifdef HAVE_MESSAGES
1438  MHD_DLOG (daemon,
1439  _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
1440  " bytes of data received from application: %s\n"),
1441  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
1442  gnutls_strerror(res));
1443 #endif
1444  /* Discard any data unsent to remote. */
1445  urh->out_buffer_used = 0;
1446  /* Do not try to pull more data from application. */
1447  urh->out_buffer_size = 0;
1448  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1449  }
1450  }
1451  }
1452  else /* 0 < res */
1453  {
1454  const size_t next_out_buffer_used = urh->out_buffer_used - res;
1455  if (0 != next_out_buffer_used)
1456  {
1457  memmove (urh->out_buffer,
1458  &urh->out_buffer[res],
1459  next_out_buffer_used);
1460  if (data_size > (size_t)res)
1461  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1462  }
1463  urh->out_buffer_used = next_out_buffer_used;
1464  }
1465  if ( (0 == urh->out_buffer_used) &&
1466  (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
1467  {
1468  /* Unrecoverable error on socket was detected and all
1469  * pending data was sent to remote. */
1470  /* Do not try to send to remote anymore. */
1471  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1472  /* Do not try to pull more data from application. */
1473  urh->out_buffer_size = 0;
1474  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1475  }
1476  }
1477 
1478  /*
1479  * handle writing to application
1480  */
1481  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
1482  (urh->in_buffer_used > 0) )
1483  {
1484  ssize_t res;
1485  size_t data_size;
1486 
1487  data_size = urh->in_buffer_used;
1488  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
1489  data_size = MHD_SCKT_SEND_MAX_SIZE_;
1490 
1491  res = MHD_send_ (urh->mhd.socket,
1492  urh->in_buffer,
1493  data_size);
1494  if (0 >= res)
1495  {
1496  const int err = MHD_socket_get_error_ ();
1497  if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1499  {
1500  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1501  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
1502  {
1503  /* Socketpair connection shut down or
1504  * persistent / unrecoverable error. */
1505 #ifdef HAVE_MESSAGES
1506  MHD_DLOG (daemon,
1507  _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
1508  " bytes of data received from remote side: %s\n"),
1509  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
1510  MHD_socket_strerr_ (err));
1511 #endif
1512  /* Discard any data received form remote. */
1513  urh->in_buffer_used = 0;
1514  /* Reading from remote client is not required anymore. */
1515  urh->in_buffer_size = 0;
1516  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1517  connection->tls_read_ready = false;
1518  }
1519  }
1520  }
1521  else /* 0 < res */
1522  {
1523  const size_t next_in_buffer_used = urh->in_buffer_used - res;
1524  if (0 != next_in_buffer_used)
1525  {
1526  memmove (urh->in_buffer,
1527  &urh->in_buffer[res],
1528  next_in_buffer_used);
1529  if (data_size > (size_t)res)
1530  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1531  }
1532  urh->in_buffer_used = next_in_buffer_used;
1533  }
1534  if ( (0 == urh->in_buffer_used) &&
1535  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
1536  {
1537  /* Do not try to push data to application. */
1538  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1539  /* Reading from remote client is not required anymore. */
1540  urh->in_buffer_size = 0;
1541  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1542  connection->tls_read_ready = false;
1543  }
1544  }
1545 
1546  /* Check whether data is present in TLS buffers
1547  * and incoming forward buffer have some space. */
1548  if ( (connection->tls_read_ready) &&
1549  (urh->in_buffer_used < urh->in_buffer_size) &&
1550  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1551  daemon->data_already_pending = true;
1552 
1553  if ( (daemon->shutdown) &&
1554  ( (0 != urh->out_buffer_size) ||
1555  (0 != urh->out_buffer_used) ) )
1556  {
1557  /* Daemon shutting down, discard any remaining forward data. */
1558 #ifdef HAVE_MESSAGES
1559  if (0 < urh->out_buffer_used)
1560  MHD_DLOG (daemon,
1561  _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
1562  " bytes of data received from application: daemon shut down\n"),
1563  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
1564 #endif
1565  /* Discard any data unsent to remote. */
1566  urh->out_buffer_used = 0;
1567  /* Do not try to sent to remote anymore. */
1568  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1569  /* Do not try to pull more data from application. */
1570  urh->out_buffer_size = 0;
1571  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1572  }
1573 }
1574 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1575 
1576 
1577 #ifdef UPGRADE_SUPPORT
1578 
1586 static void
1587 thread_main_connection_upgrade (struct MHD_Connection *con)
1588 {
1589 #ifdef HTTPS_SUPPORT
1590  struct MHD_UpgradeResponseHandle *urh = con->urh;
1591  struct MHD_Daemon *daemon = con->daemon;
1592 
1593  /* Here, we need to bi-directionally forward
1594  until the application tells us that it is done
1595  with the socket; */
1596  if ( (0 != (daemon->options & MHD_USE_TLS)) &&
1597  (0 == (daemon->options & MHD_USE_POLL)))
1598  {
1599  while ( (0 != urh->in_buffer_size) ||
1600  (0 != urh->out_buffer_size) ||
1601  (0 != urh->in_buffer_used) ||
1602  (0 != urh->out_buffer_used) )
1603  {
1604  /* use select */
1605  fd_set rs;
1606  fd_set ws;
1607  fd_set es;
1608  MHD_socket max_fd;
1609  int num_ready;
1610  bool result;
1611 
1612  FD_ZERO (&rs);
1613  FD_ZERO (&ws);
1614  FD_ZERO (&es);
1615  max_fd = MHD_INVALID_SOCKET;
1616  result = urh_to_fdset (urh,
1617  &rs,
1618  &ws,
1619  &es,
1620  &max_fd,
1621  FD_SETSIZE);
1622  if (! result)
1623  {
1624 #ifdef HAVE_MESSAGES
1625  MHD_DLOG (con->daemon,
1626  _("Error preparing select\n"));
1627 #endif
1628  break;
1629  }
1630  /* FIXME: does this check really needed? */
1631  if (MHD_INVALID_SOCKET != max_fd)
1632  {
1633  struct timeval* tvp;
1634  struct timeval tv;
1635  if ( (con->tls_read_ready) &&
1636  (urh->in_buffer_used < urh->in_buffer_size))
1637  { /* No need to wait if incoming data is already pending in TLS buffers. */
1638  tv.tv_sec = 0;
1639  tv.tv_usec = 0;
1640  tvp = &tv;
1641  }
1642  else
1643  tvp = NULL;
1644  num_ready = MHD_SYS_select_ (max_fd + 1,
1645  &rs,
1646  &ws,
1647  &es,
1648  tvp);
1649  }
1650  else
1651  num_ready = 0;
1652  if (num_ready < 0)
1653  {
1654  const int err = MHD_socket_get_error_();
1655 
1656  if (MHD_SCKT_ERR_IS_EINTR_(err))
1657  continue;
1658 #ifdef HAVE_MESSAGES
1659  MHD_DLOG (con->daemon,
1660  _("Error during select (%d): `%s'\n"),
1661  err,
1662  MHD_socket_strerr_ (err));
1663 #endif
1664  break;
1665  }
1666  urh_from_fdset (urh,
1667  &rs,
1668  &ws,
1669  &es);
1670  process_urh (urh);
1671  }
1672  }
1673 #ifdef HAVE_POLL
1674  else if (0 != (daemon->options & MHD_USE_TLS))
1675  {
1676  /* use poll() */
1677  struct pollfd p[2];
1678  memset (p,
1679  0,
1680  sizeof (p));
1681  p[0].fd = urh->connection->socket_fd;
1682  p[1].fd = urh->mhd.socket;
1683 
1684  while ( (0 != urh->in_buffer_size) ||
1685  (0 != urh->out_buffer_size) ||
1686  (0 != urh->in_buffer_used) ||
1687  (0 != urh->out_buffer_used) )
1688  {
1689  int timeout;
1690 
1691  urh_update_pollfd(urh, p);
1692 
1693  if ( (con->tls_read_ready) &&
1694  (urh->in_buffer_used < urh->in_buffer_size))
1695  timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
1696  else
1697  timeout = -1;
1698 
1699  if (MHD_sys_poll_ (p,
1700  2,
1701  timeout) < 0)
1702  {
1703  const int err = MHD_socket_get_error_ ();
1704 
1705  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1706  continue;
1707 #ifdef HAVE_MESSAGES
1708  MHD_DLOG (con->daemon,
1709  _("Error during poll: `%s'\n"),
1710  MHD_socket_strerr_ (err));
1711 #endif
1712  break;
1713  }
1714  urh_from_pollfd (urh,
1715  p);
1716  process_urh (urh);
1717  }
1718  }
1719  /* end POLL */
1720 #endif
1721  /* end HTTPS */
1722 #endif /* HTTPS_SUPPORT */
1723  /* TLS forwarding was finished. Cleanup socketpair. */
1725  /* Do not set 'urh->clean_ready' yet as 'urh' will be used
1726  * in connection thread for a little while. */
1727 }
1728 #endif /* UPGRADE_SUPPORT */
1729 
1730 
1738 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1740 {
1741  struct MHD_Connection *con = data;
1742  struct MHD_Daemon *daemon = con->daemon;
1743  int num_ready;
1744  fd_set rs;
1745  fd_set ws;
1746  fd_set es;
1747  MHD_socket maxsock;
1748  struct timeval tv;
1749  struct timeval *tvp;
1750  time_t now;
1751 #if WINDOWS
1752 #ifdef HAVE_POLL
1753  int extra_slot;
1754 #endif /* HAVE_POLL */
1755 #define EXTRA_SLOTS 1
1756 #else /* !WINDOWS */
1757 #define EXTRA_SLOTS 0
1758 #endif /* !WINDOWS */
1759 #ifdef HAVE_POLL
1760  struct pollfd p[1 + EXTRA_SLOTS];
1761 #endif
1762 #undef EXTRA_SLOTS
1763 #ifdef HAVE_POLL
1764  const bool use_poll = (0 != (daemon->options & MHD_USE_POLL));
1765 #else /* ! HAVE_POLL */
1766  const bool use_poll = 0;
1767 #endif /* ! HAVE_POLL */
1768  bool was_suspended = false;
1769  MHD_thread_init_(&(con->pid));
1770 
1771  while ( (! daemon->shutdown) &&
1772  (MHD_CONNECTION_CLOSED != con->state) )
1773  {
1774  const time_t timeout = daemon->connection_timeout;
1775 #ifdef UPGRADE_SUPPORT
1776  struct MHD_UpgradeResponseHandle * const urh = con->urh;
1777 #else /* ! UPGRADE_SUPPORT */
1778  static const void * const urh = NULL;
1779 #endif /* ! UPGRADE_SUPPORT */
1780 
1781  if ( (con->suspended) &&
1782  (NULL == urh) )
1783  {
1784  /* Connection was suspended, wait for resume. */
1785  was_suspended = true;
1786  if (! use_poll)
1787  {
1788  FD_ZERO (&rs);
1789  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
1790  &rs,
1791  NULL,
1792  FD_SETSIZE))
1793  {
1794  #ifdef HAVE_MESSAGES
1795  MHD_DLOG (con->daemon,
1796  _("Failed to add FD to fd_set\n"));
1797  #endif
1798  goto exit;
1799  }
1800  if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
1801  &rs,
1802  NULL,
1803  NULL,
1804  NULL))
1805  {
1806  const int err = MHD_socket_get_error_();
1807 
1808  if (MHD_SCKT_ERR_IS_EINTR_(err))
1809  continue;
1810 #ifdef HAVE_MESSAGES
1811  MHD_DLOG (con->daemon,
1812  _("Error during select (%d): `%s'\n"),
1813  err,
1814  MHD_socket_strerr_ (err));
1815 #endif
1816  break;
1817  }
1818  }
1819 #ifdef HAVE_POLL
1820  else /* use_poll */
1821  {
1822  p[0].events = POLLIN;
1823  p[0].fd = MHD_itc_r_fd_ (daemon->itc);
1824  p[0].revents = 0;
1825  if (0 > MHD_sys_poll_ (p,
1826  1,
1827  -1))
1828  {
1830  continue;
1831 #ifdef HAVE_MESSAGES
1832  MHD_DLOG (con->daemon,
1833  _("Error during poll: `%s'\n"),
1835 #endif
1836  break;
1837  }
1838  }
1839 #endif /* HAVE_POLL */
1840  MHD_itc_clear_ (daemon->itc);
1841  continue; /* Check again for resume. */
1842  } /* End of "suspended" branch. */
1843 
1844  if (was_suspended)
1845  {
1846  MHD_update_last_activity_ (con); /* Reset timeout timer. */
1847  /* Process response queued during suspend and update states. */
1849  was_suspended = false;
1850  }
1851 
1852  tvp = NULL;
1853 
1855 #ifdef HTTPS_SUPPORT
1856  || ( (con->tls_read_ready) &&
1858 #endif /* HTTPS_SUPPORT */
1859  )
1860  {
1861  /* do not block: more data may be inside of TLS buffers waiting or
1862  * application must provide response data */
1863  tv.tv_sec = 0;
1864  tv.tv_usec = 0;
1865  tvp = &tv;
1866  }
1867  if ( (NULL == tvp) &&
1868  (timeout > 0) )
1869  {
1870  now = MHD_monotonic_sec_counter();
1871  if (now - con->last_activity > timeout)
1872  tv.tv_sec = 0;
1873  else
1874  {
1875  const time_t seconds_left = timeout - (now - con->last_activity);
1876 #if !defined(_WIN32) || defined(__CYGWIN__)
1877  tv.tv_sec = seconds_left;
1878 #else /* _WIN32 && !__CYGWIN__ */
1879  if (seconds_left > TIMEVAL_TV_SEC_MAX)
1880  tv.tv_sec = TIMEVAL_TV_SEC_MAX;
1881  else
1882  tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
1883 #endif /* _WIN32 && ! __CYGWIN__ */
1884  }
1885  tv.tv_usec = 0;
1886  tvp = &tv;
1887  }
1888  if (! use_poll)
1889  {
1890  /* use select */
1891  bool err_state = false;
1892 
1893  FD_ZERO (&rs);
1894  FD_ZERO (&ws);
1895  FD_ZERO (&es);
1896  maxsock = MHD_INVALID_SOCKET;
1897  switch (con->event_loop_info)
1898  {
1900  if (! MHD_add_to_fd_set_ (con->socket_fd,
1901  &rs,
1902  &maxsock,
1903  FD_SETSIZE))
1904  err_state = true;
1905  break;
1907  if (! MHD_add_to_fd_set_ (con->socket_fd,
1908  &ws,
1909  &maxsock,
1910  FD_SETSIZE))
1911  err_state = true;
1912  break;
1914  if (! MHD_add_to_fd_set_ (con->socket_fd,
1915  &es,
1916  &maxsock,
1917  FD_SETSIZE))
1918  err_state = true;
1919  break;
1921  /* how did we get here!? */
1922  goto exit;
1923  }
1924 #if WINDOWS
1925  if (MHD_ITC_IS_VALID_(daemon->itc) )
1926  {
1927  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
1928  &rs,
1929  &maxsock,
1930  FD_SETSIZE))
1931  err_state = 1;
1932  }
1933 #endif
1934  if (err_state)
1935  {
1936 #ifdef HAVE_MESSAGES
1937  MHD_DLOG (con->daemon,
1938  _("Failed to add FD to fd_set\n"));
1939 #endif
1940  goto exit;
1941  }
1942 
1943  num_ready = MHD_SYS_select_ (maxsock + 1,
1944  &rs,
1945  &ws,
1946  &es,
1947  tvp);
1948  if (num_ready < 0)
1949  {
1950  const int err = MHD_socket_get_error_();
1951 
1952  if (MHD_SCKT_ERR_IS_EINTR_(err))
1953  continue;
1954 #ifdef HAVE_MESSAGES
1955  MHD_DLOG (con->daemon,
1956  _("Error during select (%d): `%s'\n"),
1957  err,
1958  MHD_socket_strerr_ (err));
1959 #endif
1960  break;
1961  }
1962 #if WINDOWS
1963  /* Clear ITC before other processing so additional
1964  * signals will trigger select() again */
1965  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
1966  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
1967  &rs)) )
1968  MHD_itc_clear_ (daemon->itc);
1969 #endif
1970  if (MHD_NO ==
1971  call_handlers (con,
1972  FD_ISSET (con->socket_fd,
1973  &rs),
1974  FD_ISSET (con->socket_fd,
1975  &ws),
1976  FD_ISSET (con->socket_fd,
1977  &es)) )
1978  goto exit;
1979  }
1980 #ifdef HAVE_POLL
1981  else
1982  {
1983  /* use poll */
1984  memset (&p,
1985  0,
1986  sizeof (p));
1987  p[0].fd = con->socket_fd;
1988  switch (con->event_loop_info)
1989  {
1991  p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
1992  break;
1994  p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
1995  break;
1997  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
1998  break;
2000  /* how did we get here!? */
2001  goto exit;
2002  }
2003 #if WINDOWS
2004  extra_slot = 0;
2005  if (MHD_ITC_IS_VALID_(daemon->itc))
2006  {
2007  p[1].events |= POLLIN;
2008  p[1].fd = MHD_itc_r_fd_ (daemon->itc);
2009  p[1].revents = 0;
2010  extra_slot = 1;
2011  }
2012 #endif
2013  if (MHD_sys_poll_ (p,
2014 #if WINDOWS
2015  1 + extra_slot,
2016 #else
2017  1,
2018 #endif
2019  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2020  {
2022  continue;
2023 #ifdef HAVE_MESSAGES
2024  MHD_DLOG (con->daemon,
2025  _("Error during poll: `%s'\n"),
2027 #endif
2028  break;
2029  }
2030 #if WINDOWS
2031  /* Clear ITC before other processing so additional
2032  * signals will trigger poll() again */
2033  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2034  (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2035  MHD_itc_clear_ (daemon->itc);
2036 #endif
2037  if (MHD_NO ==
2038  call_handlers (con,
2039  0 != (p[0].revents & POLLIN),
2040  0 != (p[0].revents & POLLOUT),
2041  0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2042  goto exit;
2043  }
2044 #endif
2045 #ifdef UPGRADE_SUPPORT
2046  if (MHD_CONNECTION_UPGRADE == con->state)
2047  {
2048  /* Normal HTTP processing is finished,
2049  * notify application. */
2050  if ( (NULL != daemon->notify_completed) &&
2051  (con->client_aware) )
2052  daemon->notify_completed (daemon->notify_completed_cls,
2053  con,
2054  &con->client_context,
2056  con->client_aware = false;
2057 
2058  thread_main_connection_upgrade (con);
2059  /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
2060 
2061  /* "Upgraded" data will not be used in this thread from this point. */
2062  con->urh->clean_ready = true;
2063  /* If 'urh->was_closed' set to true, connection will be
2064  * moved immediately to cleanup list. Otherwise connection
2065  * will stay in suspended list until 'urh' will be marked
2066  * with 'was_closed' by application. */
2067  MHD_resume_connection(con);
2068 
2069  /* skip usual clean up */
2070  return (MHD_THRD_RTRN_TYPE_) 0;
2071  }
2072 #endif /* UPGRADE_SUPPORT */
2073  }
2074 #if DEBUG_CLOSE
2075 #ifdef HAVE_MESSAGES
2076  MHD_DLOG (con->daemon,
2077  _("Processing thread terminating. Closing connection\n"));
2078 #endif
2079 #endif
2080  if (MHD_CONNECTION_CLOSED != con->state)
2081  MHD_connection_close_ (con,
2082  (daemon->shutdown) ?
2086 exit:
2087  if (NULL != con->response)
2088  {
2090  con->response = NULL;
2091  }
2092 
2093  if (MHD_INVALID_SOCKET != con->socket_fd)
2094  {
2095  shutdown (con->socket_fd,
2096  SHUT_WR);
2097  /* 'socket_fd' can be used in other thread to signal shutdown.
2098  * To avoid data races, do not close socket here. Daemon will
2099  * use more connections only after cleanup anyway. */
2100  }
2101  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2102  (! MHD_itc_activate_ (daemon->itc, "t")) )
2103  {
2104 #ifdef HAVE_MESSAGES
2105  MHD_DLOG (daemon,
2106  _("Failed to signal thread termination via inter-thread communication channel."));
2107 #endif
2108  }
2109  return (MHD_THRD_RTRN_TYPE_) 0;
2110 }
2111 
2112 
2120 static void
2121 MHD_cleanup_connections (struct MHD_Daemon *daemon);
2122 
2123 #if defined(HTTPS_SUPPORT)
2124 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \
2125  (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL)
2126 
2131 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2132 #endif /* !MHD_WINSOCK_SOCKETS && !MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) */
2133 
2134 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2135 
2139 static ssize_t
2140 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2141  const void *data,
2142  size_t data_size)
2143 {
2144 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2145  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
2146  data_size = MHD_SCKT_SEND_MAX_SIZE_;
2147 #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */
2148  return MHD_send_ ((MHD_socket)(intptr_t)(trnsp), data, data_size);
2149 }
2150 #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
2151 
2152 
2161 static int
2162 psk_gnutls_adapter (gnutls_session_t session,
2163  const char *username,
2164  gnutls_datum_t *key)
2165 {
2166  struct MHD_Connection *connection;
2167  struct MHD_Daemon *daemon;
2168  void *app_psk;
2169  size_t app_psk_size;
2170 
2171  connection = gnutls_session_get_ptr (session);
2172  if (NULL == connection)
2173  {
2174 #ifdef HAVE_MESSAGES
2175  /* Cannot use our logger, we don't even have "daemon" */
2176  MHD_PANIC (_("Internal server error. This should be impossible.\n"));
2177 #endif
2178  return -1;
2179  }
2180  daemon = connection->daemon;
2181 #if GNUTLS_VERSION_MAJOR >= 3
2182  if (NULL == daemon->cred_callback)
2183  {
2184 #ifdef HAVE_MESSAGES
2185  MHD_DLOG (daemon,
2186  _("PSK not supported by this server.\n"));
2187 #endif
2188  return -1;
2189  }
2190  if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2191  connection,
2192  username,
2193  &app_psk,
2194  &app_psk_size))
2195  return -1;
2196  if (NULL == (key->data = gnutls_malloc (app_psk_size)))
2197  {
2198 #ifdef HAVE_MESSAGES
2199  MHD_DLOG (daemon,
2200  _("PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2201 #endif
2202  free (app_psk);
2203  return -1;
2204  }
2205  key->size = app_psk_size;
2206  memcpy (key->data,
2207  app_psk,
2208  app_psk_size);
2209  free (app_psk);
2210  return 0;
2211 #else
2212 #ifdef HAVE_MESSAGES
2213  MHD_DLOG (daemon,
2214  _("PSK not supported by this server.\n"));
2215 #endif
2216  return -1;
2217 #endif
2218 }
2219 #endif /* HTTPS_SUPPORT */
2220 
2221 
2247 static int
2249  MHD_socket client_socket,
2250  const struct sockaddr *addr,
2251  socklen_t addrlen,
2252  bool external_add,
2253  bool non_blck)
2254 {
2255  struct MHD_Connection *connection;
2256  unsigned int i;
2257  int eno = 0;
2258 
2259  /* Direct add to master daemon could happen only with "external" add mode. */
2260  mhd_assert ((NULL == daemon->worker_pool) || (external_add));
2261  if ((external_add) && (NULL != daemon->worker_pool))
2262  {
2263  /* have a pool, try to find a pool with capacity; we use the
2264  socket as the initial offset into the pool for load
2265  balancing */
2266  for (i = 0; i < daemon->worker_pool_size; ++i)
2267  {
2268  struct MHD_Daemon * const worker =
2269  &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
2270  if (worker->connections < worker->connection_limit)
2271  return internal_add_connection (worker,
2272  client_socket,
2273  addr,
2274  addrlen,
2275  true,
2276  non_blck);
2277  }
2278  /* all pools are at their connection limit, must refuse */
2279  MHD_socket_close_chk_ (client_socket);
2280 #if ENFILE
2281  errno = ENFILE;
2282 #endif
2283  return MHD_NO;
2284  }
2285 
2286  if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket,
2287  NULL)) &&
2288  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
2289  {
2290 #ifdef HAVE_MESSAGES
2291  MHD_DLOG (daemon,
2292  _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2293  (int) client_socket,
2294  (int) FD_SETSIZE);
2295 #endif
2296  MHD_socket_close_chk_ (client_socket);
2297 #if EINVAL
2298  errno = EINVAL;
2299 #endif
2300  return MHD_NO;
2301  }
2302 
2303 #ifdef MHD_socket_nosignal_
2304  if (! MHD_socket_nosignal_ (client_socket))
2305  {
2306 #ifdef HAVE_MESSAGES
2307  MHD_DLOG (daemon,
2308  _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2310 #endif
2311 #ifndef MSG_NOSIGNAL
2312  /* Cannot use socket as it can produce SIGPIPE. */
2313 #ifdef ENOTSOCK
2314  errno = ENOTSOCK;
2315 #endif /* ENOTSOCK */
2316  return MHD_NO;
2317 #endif /* ! MSG_NOSIGNAL */
2318  }
2319 #endif /* MHD_socket_nosignal_ */
2320 
2321 
2322 #ifdef HAVE_MESSAGES
2323 #if DEBUG_CONNECT
2324  MHD_DLOG (daemon,
2325  _("Accepted connection on socket %d\n"),
2326  client_socket);
2327 #endif
2328 #endif
2329  if ( (daemon->connections == daemon->connection_limit) ||
2330  (MHD_NO == MHD_ip_limit_add (daemon,
2331  addr,
2332  addrlen)) )
2333  {
2334  /* above connection limit - reject */
2335 #ifdef HAVE_MESSAGES
2336  MHD_DLOG (daemon,
2337  _("Server reached connection limit. Closing inbound connection.\n"));
2338 #endif
2339  MHD_socket_close_chk_ (client_socket);
2340 #if ENFILE
2341  errno = ENFILE;
2342 #endif
2343  return MHD_NO;
2344  }
2345 
2346  /* apply connection acceptance policy if present */
2347  if ( (NULL != daemon->apc) &&
2348  (MHD_NO == daemon->apc (daemon->apc_cls,
2349  addr,
2350  addrlen)) )
2351  {
2352 #if DEBUG_CLOSE
2353 #ifdef HAVE_MESSAGES
2354  MHD_DLOG (daemon,
2355  _("Connection rejected by application. Closing connection.\n"));
2356 #endif
2357 #endif
2358  MHD_socket_close_chk_ (client_socket);
2359  MHD_ip_limit_del (daemon,
2360  addr,
2361  addrlen);
2362 #if EACCESS
2363  errno = EACCESS;
2364 #endif
2365  return MHD_NO;
2366  }
2367 
2368  if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection))))
2369  {
2370  eno = errno;
2371 #ifdef HAVE_MESSAGES
2372  MHD_DLOG (daemon,
2373  "Error allocating memory: %s\n",
2374  MHD_strerror_ (errno));
2375 #endif
2376  MHD_socket_close_chk_ (client_socket);
2377  MHD_ip_limit_del (daemon,
2378  addr,
2379  addrlen);
2380  errno = eno;
2381  return MHD_NO;
2382  }
2383  connection->pool = MHD_pool_create (daemon->pool_size);
2384  if (NULL == connection->pool)
2385  {
2386 #ifdef HAVE_MESSAGES
2387  MHD_DLOG (daemon,
2388  _("Error allocating memory: %s\n"),
2389  MHD_strerror_ (errno));
2390 #endif
2391  MHD_socket_close_chk_ (client_socket);
2392  MHD_ip_limit_del (daemon,
2393  addr,
2394  addrlen);
2395  free (connection);
2396 #if ENOMEM
2397  errno = ENOMEM;
2398 #endif
2399  return MHD_NO;
2400  }
2401 
2402  connection->connection_timeout = daemon->connection_timeout;
2403  if (NULL == (connection->addr = malloc (addrlen)))
2404  {
2405  eno = errno;
2406 #ifdef HAVE_MESSAGES
2407  MHD_DLOG (daemon,
2408  _("Error allocating memory: %s\n"),
2409  MHD_strerror_ (errno));
2410 #endif
2411  MHD_socket_close_chk_ (client_socket);
2412  MHD_ip_limit_del (daemon,
2413  addr,
2414  addrlen);
2415  MHD_pool_destroy (connection->pool);
2416  free (connection);
2417  errno = eno;
2418  return MHD_NO;
2419  }
2420  memcpy (connection->addr,
2421  addr,
2422  addrlen);
2423  connection->addr_len = addrlen;
2424  connection->socket_fd = client_socket;
2425  connection->sk_nonblck = non_blck;
2426  connection->daemon = daemon;
2427  connection->last_activity = MHD_monotonic_sec_counter();
2428 
2429  if (0 == (daemon->options & MHD_USE_TLS))
2430  {
2431  /* set default connection handlers */
2432  MHD_set_http_callbacks_ (connection);
2433  }
2434  else
2435  {
2436 #ifdef HTTPS_SUPPORT
2437  connection->tls_state = MHD_TLS_CONN_INIT;
2438  MHD_set_https_callbacks (connection);
2439  gnutls_init (&connection->tls_session,
2440  GNUTLS_SERVER
2441 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402)
2442  | GNUTLS_NO_SIGNAL
2443 #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
2444 #if GNUTLS_VERSION_MAJOR >= 3
2445  | GNUTLS_NONBLOCK
2446 #endif /* GNUTLS_VERSION_MAJOR >= 3*/
2447  );
2448  gnutls_priority_set (connection->tls_session,
2449  daemon->priority_cache);
2450  gnutls_session_set_ptr (connection->tls_session,
2451  connection);
2452  switch (daemon->cred_type)
2453  {
2454  /* set needed credentials for certificate authentication. */
2455  case GNUTLS_CRD_CERTIFICATE:
2456  gnutls_credentials_set (connection->tls_session,
2457  GNUTLS_CRD_CERTIFICATE,
2458  daemon->x509_cred);
2459  break;
2460  case GNUTLS_CRD_PSK:
2461  gnutls_credentials_set (connection->tls_session,
2462  GNUTLS_CRD_PSK,
2463  daemon->psk_cred);
2464  gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2465  &psk_gnutls_adapter);
2466  break;
2467  default:
2468 #ifdef HAVE_MESSAGES
2469  MHD_DLOG (connection->daemon,
2470  _("Failed to setup TLS credentials: unknown credential type %d\n"),
2471  daemon->cred_type);
2472 #endif
2473  MHD_socket_close_chk_ (client_socket);
2474  MHD_ip_limit_del (daemon,
2475  addr,
2476  addrlen);
2477  free (connection->addr);
2478  free (connection);
2479  MHD_PANIC (_("Unknown credential type"));
2480 #if EINVAL
2481  errno = EINVAL;
2482 #endif
2483  return MHD_NO;
2484  }
2485 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
2486  gnutls_transport_set_int (connection->tls_session,
2487  (int)(client_socket));
2488 #else /* GnuTLS before 3.1.9 or Win x64 */
2489  gnutls_transport_set_ptr (connection->tls_session,
2490  (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2491 #endif /* GnuTLS before 3.1.9 */
2492 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2493  gnutls_transport_set_push_function (connection->tls_session,
2494  MHD_tls_push_func_);
2495 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
2496  if (daemon->https_mem_trust)
2497  gnutls_certificate_server_set_request (connection->tls_session,
2498  GNUTLS_CERT_REQUEST);
2499 #else /* ! HTTPS_SUPPORT */
2500  eno = EINVAL;
2501  goto cleanup;
2502 #endif /* ! HTTPS_SUPPORT */
2503  }
2504 
2506  /* Firm check under lock. */
2507  if (daemon->connections >= daemon->connection_limit)
2508  {
2510  /* above connection limit - reject */
2511 #ifdef HAVE_MESSAGES
2512  MHD_DLOG (daemon,
2513  _("Server reached connection limit. Closing inbound connection.\n"));
2514 #endif
2515 #if ENFILE
2516  eno = ENFILE;
2517 #endif
2518  goto cleanup;
2519  }
2520  daemon->connections++;
2521  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2522  {
2524  daemon->normal_timeout_tail,
2525  connection);
2526  }
2527  DLL_insert (daemon->connections_head,
2528  daemon->connections_tail,
2529  connection);
2531 
2532  if (NULL != daemon->notify_connection)
2533  daemon->notify_connection (daemon->notify_connection_cls,
2534  connection,
2535  &connection->socket_context,
2537 
2538  /* attempt to create handler thread */
2539  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2540  {
2541  if (! MHD_create_named_thread_ (&connection->pid,
2542  "MHD-connection",
2543  daemon->thread_stack_size,
2545  connection))
2546  {
2547  eno = errno;
2548 #ifdef HAVE_MESSAGES
2549  MHD_DLOG (daemon,
2550  "Failed to create a thread: %s\n",
2551  MHD_strerror_ (eno));
2552 #endif
2553  goto cleanup;
2554  }
2555  }
2556  else
2557  connection->pid = daemon->pid;
2558 #ifdef EPOLL_SUPPORT
2559  if (0 != (daemon->options & MHD_USE_EPOLL))
2560  {
2561  if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add))
2562  { /* Do not manipulate EReady DL-list in 'external_add' mode. */
2563  struct epoll_event event;
2564 
2565  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2566  event.data.ptr = connection;
2567  if (0 != epoll_ctl (daemon->epoll_fd,
2568  EPOLL_CTL_ADD,
2569  client_socket,
2570  &event))
2571  {
2572  eno = errno;
2573 #ifdef HAVE_MESSAGES
2574  MHD_DLOG (daemon,
2575  _("Call to epoll_ctl failed: %s\n"),
2577 #endif
2578  goto cleanup;
2579  }
2580  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2581  }
2582  else
2583  {
2584  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
2586  EDLL_insert (daemon->eready_head,
2587  daemon->eready_tail,
2588  connection);
2589  }
2590  }
2591  else /* This 'else' is combined with next 'if'. */
2592 #endif
2593  if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2594  (external_add) &&
2595  (MHD_ITC_IS_VALID_(daemon->itc)) &&
2596  (! MHD_itc_activate_ (daemon->itc, "n")) )
2597  {
2598 #ifdef HAVE_MESSAGES
2599  MHD_DLOG (daemon,
2600  _("Failed to signal new connection via inter-thread communication channel."));
2601 #endif
2602  }
2603  return MHD_YES;
2604  cleanup:
2605  if (NULL != daemon->notify_connection)
2606  daemon->notify_connection (daemon->notify_connection_cls,
2607  connection,
2608  &connection->socket_context,
2610 #ifdef HTTPS_SUPPORT
2611  if (NULL != connection->tls_session)
2612  gnutls_deinit (connection->tls_session);
2613 #endif /* HTTPS_SUPPORT */
2614  MHD_socket_close_chk_ (client_socket);
2615  MHD_ip_limit_del (daemon,
2616  addr,
2617  addrlen);
2619  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2620  {
2622  daemon->normal_timeout_tail,
2623  connection);
2624  }
2625  DLL_remove (daemon->connections_head,
2626  daemon->connections_tail,
2627  connection);
2629  MHD_pool_destroy (connection->pool);
2630  free (connection->addr);
2631  free (connection);
2632  if (0 != eno)
2633  errno = eno;
2634  else
2635  errno = EINVAL;
2636  return MHD_NO;
2637 }
2638 
2639 
2649 void
2651 {
2652  struct MHD_Daemon *daemon = connection->daemon;
2653 
2655  if (connection->resuming)
2656  {
2657  /* suspending again while we didn't even complete resuming yet */
2658  connection->resuming = false;
2660  return;
2661  }
2662  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2663  {
2664  if (connection->connection_timeout == daemon->connection_timeout)
2666  daemon->normal_timeout_tail,
2667  connection);
2668  else
2670  daemon->manual_timeout_tail,
2671  connection);
2672  }
2673  DLL_remove (daemon->connections_head,
2674  daemon->connections_tail,
2675  connection);
2676  mhd_assert (! connection->suspended);
2679  connection);
2680  connection->suspended = true;
2681 #ifdef EPOLL_SUPPORT
2682  if (0 != (daemon->options & MHD_USE_EPOLL))
2683  {
2684  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2685  {
2686  EDLL_remove (daemon->eready_head,
2687  daemon->eready_tail,
2688  connection);
2689  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2690  }
2691  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
2692  {
2693  if (0 != epoll_ctl (daemon->epoll_fd,
2694  EPOLL_CTL_DEL,
2695  connection->socket_fd,
2696  NULL))
2697  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
2698  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
2699  }
2700  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
2701  }
2702 #endif
2704 }
2705 
2706 
2738 void
2740 {
2741  struct MHD_Daemon * const daemon = connection->daemon;
2742 
2743  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2744  MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2745 #ifdef UPGRADE_SUPPORT
2746  if (NULL != connection->urh)
2747  {
2748 #ifdef HAVE_MESSAGES
2749  MHD_DLOG (daemon,
2750  _("Error: connection scheduled for \"upgrade\" cannot be suspended"));
2751 #endif /* HAVE_MESSAGES */
2752  return;
2753  }
2754 #endif /* UPGRADE_SUPPORT */
2755  internal_suspend_connection_ (connection);
2756 }
2757 
2758 
2767 void
2769 {
2770  struct MHD_Daemon *daemon = connection->daemon;
2771 
2772  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2773  MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2775  connection->resuming = true;
2776  daemon->resuming = true;
2778  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2779  (! MHD_itc_activate_ (daemon->itc, "r")) )
2780  {
2781 #ifdef HAVE_MESSAGES
2782  MHD_DLOG (daemon,
2783  _("Failed to signal resume via inter-thread communication channel."));
2784 #endif
2785  }
2786 }
2787 
2788 
2798 static int
2800 {
2801  struct MHD_Connection *pos;
2802  struct MHD_Connection *prev = NULL;
2803  int ret;
2804  const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
2806 
2807  ret = MHD_NO;
2809 
2810  if (daemon->resuming)
2811  {
2813  /* During shutdown check for resuming is forced. */
2814  mhd_assert((NULL != prev) || (daemon->shutdown));
2815  }
2816 
2817  daemon->resuming = false;
2818 
2819  while (NULL != (pos = prev))
2820  {
2821 #ifdef UPGRADE_SUPPORT
2822  struct MHD_UpgradeResponseHandle * const urh = pos->urh;
2823 #else /* ! UPGRADE_SUPPORT */
2824  static const void * const urh = NULL;
2825 #endif /* ! UPGRADE_SUPPORT */
2826  prev = pos->prev;
2827  if ( (! pos->resuming)
2828 #ifdef UPGRADE_SUPPORT
2829  || ( (NULL != urh) &&
2830  ( (! urh->was_closed) ||
2831  (! urh->clean_ready) ) )
2832 #endif /* UPGRADE_SUPPORT */
2833  )
2834  continue;
2835  ret = MHD_YES;
2836  mhd_assert (pos->suspended);
2839  pos);
2840  pos->suspended = false;
2841  if (NULL == urh)
2842  {
2843  DLL_insert (daemon->connections_head,
2844  daemon->connections_tail,
2845  pos);
2846  if (! used_thr_p_c)
2847  {
2848  /* Reset timeout timer on resume. */
2849  if (0 != pos->connection_timeout)
2851 
2852  if (pos->connection_timeout == daemon->connection_timeout)
2854  daemon->normal_timeout_tail,
2855  pos);
2856  else
2858  daemon->manual_timeout_tail,
2859  pos);
2860  }
2861 #ifdef EPOLL_SUPPORT
2862  if (0 != (daemon->options & MHD_USE_EPOLL))
2863  {
2864  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2865  MHD_PANIC ("Resumed connection was already in EREADY set\n");
2866  /* we always mark resumed connections as ready, as we
2867  might have missed the edge poll event during suspension */
2868  EDLL_insert (daemon->eready_head,
2869  daemon->eready_tail,
2870  pos);
2871  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \
2872  MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
2873  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
2874  }
2875 #endif
2876  }
2877 #ifdef UPGRADE_SUPPORT
2878  else
2879  {
2880  /* Data forwarding was finished (for TLS connections) AND
2881  * application was closed upgraded connection.
2882  * Insert connection into cleanup list. */
2883 
2884  if ( (NULL != daemon->notify_completed) &&
2885  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2886  (pos->client_aware) )
2887  {
2888  daemon->notify_completed (daemon->notify_completed_cls,
2889  pos,
2890  &pos->client_context,
2892  pos->client_aware = false;
2893  }
2894  DLL_insert (daemon->cleanup_head,
2895  daemon->cleanup_tail,
2896  pos);
2897 
2898  }
2899 #endif /* UPGRADE_SUPPORT */
2900  pos->resuming = false;
2901  }
2903  if ( (used_thr_p_c) &&
2904  (MHD_NO != ret) )
2905  { /* Wake up suspended connections. */
2906  if (! MHD_itc_activate_(daemon->itc,
2907  "w"))
2908  {
2909 #ifdef HAVE_MESSAGES
2910  MHD_DLOG (daemon,
2911  _("Failed to signal resume of connection via inter-thread communication channel."));
2912 #endif
2913  }
2914  }
2915  return ret;
2916 }
2917 
2918 
2946 int
2948  MHD_socket client_socket,
2949  const struct sockaddr *addr,
2950  socklen_t addrlen)
2951 {
2952  bool sk_nonbl;
2953  if (! MHD_socket_nonblocking_ (client_socket))
2954  {
2955 #ifdef HAVE_MESSAGES
2956  MHD_DLOG (daemon,
2957  _("Failed to set nonblocking mode on new client socket: %s\n"),
2959 #endif
2960  sk_nonbl = 0;
2961  }
2962  else
2963  sk_nonbl = !0;
2964 
2965  if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
2966  (! MHD_socket_noninheritable_ (client_socket)) )
2967  {
2968 #ifdef HAVE_MESSAGES
2969  MHD_DLOG (daemon,
2970  _("Failed to set noninheritable mode on new client socket.\n"));
2971 #endif
2972  }
2973  return internal_add_connection (daemon,
2974  client_socket,
2975  addr,
2976  addrlen,
2977  true,
2978  sk_nonbl);
2979 }
2980 
2981 
2996 static int
2998 {
2999 #if HAVE_INET6
3000  struct sockaddr_in6 addrstorage;
3001 #else
3002  struct sockaddr_in addrstorage;
3003 #endif
3004  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
3005  socklen_t addrlen;
3006  MHD_socket s;
3007  MHD_socket fd;
3008  bool sk_nonbl;
3009 
3010  addrlen = sizeof (addrstorage);
3011  memset (addr,
3012  0,
3013  sizeof (addrstorage));
3014  if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) ||
3015  (daemon->was_quiesced) )
3016  return MHD_NO;
3017 #ifdef USE_ACCEPT4
3018  s = accept4 (fd,
3019  addr,
3020  &addrlen,
3022  sk_nonbl = (MAYBE_SOCK_NONBLOCK != 0);
3023 #else /* ! USE_ACCEPT4 */
3024  s = accept (fd,
3025  addr,
3026  &addrlen);
3027  sk_nonbl = 0;
3028 #endif /* ! USE_ACCEPT4 */
3029  if ( (MHD_INVALID_SOCKET == s) ||
3030  (addrlen <= 0) )
3031  {
3032  const int err = MHD_socket_get_error_ ();
3033 
3034  /* This could be a common occurance with multiple worker threads */
3035  if (MHD_SCKT_ERR_IS_ (err,
3037  return MHD_NO; /* can happen during shutdown */
3039  return MHD_NO; /* do not print error if client just disconnected early */
3040 #ifdef HAVE_MESSAGES
3041  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
3042  MHD_DLOG (daemon,
3043  _("Error accepting connection: %s\n"),
3044  MHD_socket_strerr_(err));
3045 #endif
3046  if (MHD_INVALID_SOCKET != s)
3047  {
3049  }
3050  if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
3051  {
3052  /* system/process out of resources */
3053  if (0 == daemon->connections)
3054  {
3055 #ifdef HAVE_MESSAGES
3056  /* Not setting 'at_limit' flag, as there is no way it
3057  would ever be cleared. Instead trying to produce
3058  bit fat ugly warning. */
3059  MHD_DLOG (daemon,
3060  _("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"));
3061 #endif
3062  }
3063  else
3064  {
3066  daemon->at_limit = true;
3068 #ifdef HAVE_MESSAGES
3069  MHD_DLOG (daemon,
3070  _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3071  (unsigned int) daemon->connections);
3072 #endif
3073  }
3074  }
3075  return MHD_NO;
3076  }
3077 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK)
3078  if (! MHD_socket_nonblocking_ (s))
3079  {
3080 #ifdef HAVE_MESSAGES
3081  MHD_DLOG (daemon,
3082  _("Failed to set nonblocking mode on incoming connection socket: %s\n"),
3084 #endif
3085  }
3086  else
3087  sk_nonbl = !0;
3088 #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
3089 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
3090  if (! MHD_socket_noninheritable_ (s))
3091  {
3092 #ifdef HAVE_MESSAGES
3093  MHD_DLOG (daemon,
3094  _("Failed to set noninheritable mode on incoming connection socket.\n"));
3095 #endif
3096  }
3097 #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
3098 #ifdef HAVE_MESSAGES
3099 #if DEBUG_CONNECT
3100  MHD_DLOG (daemon,
3101  _("Accepted connection on socket %d\n"),
3102  s);
3103 #endif
3104 #endif
3105  (void) internal_add_connection (daemon,
3106  s,
3107  addr,
3108  addrlen,
3109  false,
3110  sk_nonbl);
3111  return MHD_YES;
3112 }
3113 
3114 
3124 static void
3126 {
3127  struct MHD_Connection *pos;
3128 
3130  while (NULL != (pos = daemon->cleanup_tail))
3131  {
3134  pos);
3136 
3137  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3138  (! pos->thread_joined) &&
3139  (! MHD_join_thread_ (pos->pid.handle)) )
3140  MHD_PANIC (_("Failed to join a thread\n"));
3141 #ifdef UPGRADE_SUPPORT
3142  cleanup_upgraded_connection (pos);
3143 #endif /* UPGRADE_SUPPORT */
3144  MHD_pool_destroy (pos->pool);
3145 #ifdef HTTPS_SUPPORT
3146  if (NULL != pos->tls_session)
3147  gnutls_deinit (pos->tls_session);
3148 #endif /* HTTPS_SUPPORT */
3149 
3150  /* clean up the connection */
3151  if (NULL != daemon->notify_connection)
3153  pos,
3154  &pos->socket_context,
3157  pos->addr,
3158  pos->addr_len);
3159 #ifdef EPOLL_SUPPORT
3160  if (0 != (daemon->options & MHD_USE_EPOLL))
3161  {
3162  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3163  {
3164  EDLL_remove (daemon->eready_head,
3165  daemon->eready_tail,
3166  pos);
3167  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3168  }
3169  if ( (-1 != daemon->epoll_fd) &&
3170  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
3171  {
3172  /* epoll documentation suggests that closing a FD
3173  automatically removes it from the epoll set; however,
3174  this is not true as if we fail to do manually remove it,
3175  we are still seeing an event for this fd in epoll,
3176  causing grief (use-after-free...) --- at least on my
3177  system. */
3178  if (0 != epoll_ctl (daemon->epoll_fd,
3179  EPOLL_CTL_DEL,
3180  pos->socket_fd,
3181  NULL))
3182  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
3183  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
3184  }
3185  }
3186 #endif
3187  if (NULL != pos->response)
3188  {
3190  pos->response = NULL;
3191  }
3192  if (MHD_INVALID_SOCKET != pos->socket_fd)
3194  if (NULL != pos->addr)
3195  free (pos->addr);
3196  free (pos);
3197 
3199  daemon->connections--;
3200  daemon->at_limit = false;
3201  }
3203 }
3204 
3205 
3226 int
3228  MHD_UNSIGNED_LONG_LONG *timeout)
3229 {
3230  time_t earliest_deadline;
3231  time_t now;
3232  struct MHD_Connection *pos;
3233  bool have_timeout;
3234 
3236  {
3237 #ifdef HAVE_MESSAGES
3238  MHD_DLOG (daemon,
3239  _("Illegal call to MHD_get_timeout\n"));
3240 #endif
3241  return MHD_NO;
3242  }
3243 
3245  {
3246  /* Some data already waiting to be processed. */
3247  *timeout = 0;
3248  return MHD_YES;
3249  }
3250 
3251 #ifdef EPOLL_SUPPORT
3252  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
3253  ((NULL != daemon->eready_head)
3254 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3255  || (NULL != daemon->eready_urh_head)
3256 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
3257  ) )
3258  {
3259  /* Some connection(s) already have some data pending. */
3260  *timeout = 0;
3261  return MHD_YES;
3262  }
3263 #endif /* EPOLL_SUPPORT */
3264 
3265  have_timeout = false;
3266  earliest_deadline = 0; /* avoid compiler warnings */
3267  for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
3268  {
3269  if (0 != pos->connection_timeout)
3270  {
3271  if ( (! have_timeout) ||
3272  (earliest_deadline - pos->last_activity > pos->connection_timeout) )
3273  earliest_deadline = pos->last_activity + pos->connection_timeout;
3274  have_timeout = true;
3275  }
3276  }
3277  /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
3278  pos = daemon->normal_timeout_tail;
3279  if ( (NULL != pos) &&
3280  (0 != pos->connection_timeout) )
3281  {
3282  if ( (! have_timeout) ||
3283  (earliest_deadline - pos->connection_timeout > pos->last_activity) )
3284  earliest_deadline = pos->last_activity + pos->connection_timeout;
3285  have_timeout = true;
3286  }
3287 
3288  if (! have_timeout)
3289  return MHD_NO;
3290  now = MHD_monotonic_sec_counter();
3291  if (earliest_deadline < now)
3292  *timeout = 0;
3293  else
3294  {
3295  const time_t second_left = earliest_deadline - now;
3296 
3297  if (((unsigned long long)second_left) > ULLONG_MAX / 1000)
3298  *timeout = ULLONG_MAX;
3299  else
3300  *timeout = 1000LLU * (unsigned long long) second_left;
3301  }
3302  return MHD_YES;
3303 }
3304 
3305 
3316 static int
3318  const fd_set *read_fd_set,
3319  const fd_set *write_fd_set,
3320  const fd_set *except_fd_set)
3321 {
3322  MHD_socket ds;
3323  struct MHD_Connection *pos;
3324  struct MHD_Connection *prev;
3325 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3326  struct MHD_UpgradeResponseHandle *urh;
3327  struct MHD_UpgradeResponseHandle *urhn;
3328 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3329  /* Reset. New value will be set when connections are processed. */
3330  /* Note: no-op for thread-per-connection as it is always false in that mode. */
3331  daemon->data_already_pending = false;
3332 
3333  /* Clear ITC to avoid spinning select */
3334  /* Do it before any other processing so new signals
3335  will trigger select again and will be processed */
3336  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
3337  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
3338  read_fd_set)) )
3339  MHD_itc_clear_ (daemon->itc);
3340 
3341  /* select connection thread handling type */
3342  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
3343  (! daemon->was_quiesced) &&
3344  (FD_ISSET (ds,
3345  read_fd_set)) )
3346  (void) MHD_accept_connection (daemon);
3347 
3348  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3349  {
3350  /* do not have a thread per connection, process all connections now */
3351  prev = daemon->connections_tail;
3352  while (NULL != (pos = prev))
3353  {
3354  prev = pos->prev;
3355  ds = pos->socket_fd;
3356  if (MHD_INVALID_SOCKET == ds)
3357  continue;
3358  call_handlers (pos,
3359  FD_ISSET (ds,
3360  read_fd_set),
3361  FD_ISSET (ds,
3362  write_fd_set),
3363  FD_ISSET (ds,
3364  except_fd_set));
3365  }
3366  }
3367 
3368 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3369  /* handle upgraded HTTPS connections */
3370  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3371  {
3372  urhn = urh->prev;
3373  /* update urh state based on select() output */
3374  urh_from_fdset (urh,
3375  read_fd_set,
3376  write_fd_set,
3377  except_fd_set);
3378  /* call generic forwarding function for passing data */
3379  process_urh (urh);
3380  /* Finished forwarding? */
3381  if ( (0 == urh->in_buffer_size) &&
3382  (0 == urh->out_buffer_size) &&
3383  (0 == urh->in_buffer_used) &&
3384  (0 == urh->out_buffer_used) )
3385  {
3386  MHD_connection_finish_forward_ (urh->connection);
3387  urh->clean_ready = true;
3388  /* Resuming will move connection to cleanup list. */
3389  MHD_resume_connection(urh->connection);
3390  }
3391  }
3392 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3393  MHD_cleanup_connections (daemon);
3394  return MHD_YES;
3395 }
3396 
3397 
3420 int
3422  const fd_set *read_fd_set,
3423  const fd_set *write_fd_set,
3424  const fd_set *except_fd_set)
3425 {
3426  fd_set es;
3427  if (0 != (daemon->options &
3429  return MHD_NO;
3430  if (NULL == read_fd_set || NULL == write_fd_set)
3431  return MHD_NO;
3432  if (NULL == except_fd_set)
3433  { /* Workaround to maintain backward compatibility. */
3434 #ifdef HAVE_MESSAGES
3435  MHD_DLOG (daemon,
3436  _("MHD_run_from_select() called with except_fd_set "
3437  "set to NULL. Such behavior is deprecated.\n"));
3438 #endif
3439  FD_ZERO (&es);
3440  except_fd_set = &es;
3441  }
3442  if (0 != (daemon->options & MHD_USE_EPOLL))
3443  {
3444 #ifdef EPOLL_SUPPORT
3445  int ret = MHD_epoll (daemon,
3446  MHD_NO);
3447 
3448  MHD_cleanup_connections (daemon);
3449  return ret;
3450 #else /* ! EPOLL_SUPPORT */
3451  return MHD_NO;
3452 #endif /* ! EPOLL_SUPPORT */
3453  }
3454 
3455  /* Resuming external connections when using an extern mainloop */
3456  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3458 
3459  return internal_run_from_select (daemon,
3460  read_fd_set,
3461  write_fd_set,
3462  except_fd_set);
3463 }
3464 
3465 
3474 static int
3475 MHD_select (struct MHD_Daemon *daemon,
3476  int may_block)
3477 {
3478  int num_ready;
3479  fd_set rs;
3480  fd_set ws;
3481  fd_set es;
3482  MHD_socket maxsock;
3483  struct timeval timeout;
3484  struct timeval *tv;
3485  MHD_UNSIGNED_LONG_LONG ltimeout;
3486  int err_state;
3487  MHD_socket ls;
3488 
3489  timeout.tv_sec = 0;
3490  timeout.tv_usec = 0;
3491  if (daemon->shutdown)
3492  return MHD_NO;
3493  FD_ZERO (&rs);
3494  FD_ZERO (&ws);
3495  FD_ZERO (&es);
3496  maxsock = MHD_INVALID_SOCKET;
3497  err_state = MHD_NO;
3498  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3499  (MHD_YES == resume_suspended_connections (daemon)) &&
3500  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
3501  may_block = MHD_NO;
3502 
3503  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3504  {
3505  /* single-threaded, go over everything */
3506  if (MHD_NO ==
3507  internal_get_fdset2 (daemon,
3508  &rs,
3509  &ws,
3510  &es,
3511  &maxsock,
3512  FD_SETSIZE))
3513  {
3514 #ifdef HAVE_MESSAGES
3515  MHD_DLOG (daemon,
3516  _("Could not obtain daemon fdsets"));
3517 #endif
3518  err_state = MHD_YES;
3519  }
3520  }
3521  else
3522  {
3523  /* accept only, have one thread per connection */
3524  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3525  (! daemon->was_quiesced) &&
3526  (! MHD_add_to_fd_set_ (ls,
3527  &rs,
3528  &maxsock,
3529  FD_SETSIZE)) )
3530  {
3531 #ifdef HAVE_MESSAGES
3532  MHD_DLOG (daemon,
3533  _("Could not add listen socket to fdset"));
3534 #endif
3535  return MHD_NO;
3536  }
3537  }
3538  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
3539  (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
3540  &rs,
3541  &maxsock,
3542  FD_SETSIZE)) )
3543  {
3544 #if defined(MHD_WINSOCK_SOCKETS)
3545  /* fdset limit reached, new connections
3546  cannot be handled. Remove listen socket FD
3547  from fdset and retry to add ITC FD. */
3548  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3549  (! daemon->was_quiesced) )
3550  {
3551  FD_CLR (ls,
3552  &rs);
3553  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc),
3554  &rs,
3555  &maxsock,
3556  FD_SETSIZE))
3557  {
3558 #endif /* MHD_WINSOCK_SOCKETS */
3559 #ifdef HAVE_MESSAGES
3560  MHD_DLOG (daemon,
3561  _("Could not add control inter-thread communication channel FD to fdset"));
3562 #endif
3563  err_state = MHD_YES;
3564 #if defined(MHD_WINSOCK_SOCKETS)
3565  }
3566  }
3567 #endif /* MHD_WINSOCK_SOCKETS */
3568  }
3569  /* Stop listening if we are at the configured connection limit */
3570  /* If we're at the connection limit, no point in really
3571  accepting new connections; however, make sure we do not miss
3572  the shutdown OR the termination of an existing connection; so
3573  only do this optimization if we have a signaling ITC in
3574  place. */
3575  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3576  (MHD_ITC_IS_VALID_(daemon->itc)) &&
3577  ( (daemon->connections == daemon->connection_limit) ||
3578  (daemon->at_limit) ) )
3579  {
3580  FD_CLR (ls,
3581  &rs);
3582  }
3583  tv = NULL;
3584  if (MHD_YES == err_state)
3585  may_block = MHD_NO;
3586  if (MHD_NO == may_block)
3587  {
3588  timeout.tv_usec = 0;
3589  timeout.tv_sec = 0;
3590  tv = &timeout;
3591  }
3592  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3593  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
3594  {
3595  /* ltimeout is in ms */
3596  timeout.tv_usec = (ltimeout % 1000) * 1000;
3597  if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
3598  timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
3599  else
3600  timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000);
3601  tv = &timeout;
3602  }
3603  num_ready = MHD_SYS_select_ (maxsock + 1,
3604  &rs,
3605  &ws,
3606  &es,
3607  tv);
3608  if (daemon->shutdown)
3609  return MHD_NO;
3610  if (num_ready < 0)
3611  {
3612  const int err = MHD_socket_get_error_ ();
3613  if (MHD_SCKT_ERR_IS_EINTR_(err))
3614  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3615 #ifdef HAVE_MESSAGES
3616  MHD_DLOG (daemon,
3617  _("select failed: %s\n"),
3618  MHD_socket_strerr_ (err));
3619 #endif
3620  return MHD_NO;
3621  }
3622  if (MHD_YES == internal_run_from_select (daemon,
3623  &rs,
3624  &ws,
3625  &es))
3626  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3627  return MHD_NO;
3628 }
3629 
3630 
3631 #ifdef HAVE_POLL
3632 
3640 static int
3641 MHD_poll_all (struct MHD_Daemon *daemon,
3642  int may_block)
3643 {
3644  unsigned int num_connections;
3645  struct MHD_Connection *pos;
3646  struct MHD_Connection *prev;
3647 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3648  struct MHD_UpgradeResponseHandle *urh;
3649  struct MHD_UpgradeResponseHandle *urhn;
3650 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3651 
3652  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3653  (MHD_YES == resume_suspended_connections (daemon)) )
3654  may_block = MHD_NO;
3655 
3656  /* count number of connections and thus determine poll set size */
3657  num_connections = 0;
3658  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
3659  num_connections++;
3660 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3661  for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
3662  num_connections += 2;
3663 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3664  {
3665  MHD_UNSIGNED_LONG_LONG ltimeout;
3666  unsigned int i;
3667  int timeout;
3668  unsigned int poll_server;
3669  int poll_listen;
3670  int poll_itc_idx;
3671  struct pollfd *p;
3672  MHD_socket ls;
3673 
3674  p = MHD_calloc_ ((2 + num_connections),
3675  sizeof (struct pollfd));
3676  if (NULL == p)
3677  {
3678 #ifdef HAVE_MESSAGES
3679  MHD_DLOG (daemon,
3680  _("Error allocating memory: %s\n"),
3681  MHD_strerror_(errno));
3682 #endif
3683  return MHD_NO;
3684  }
3685  poll_server = 0;
3686  poll_listen = -1;
3687  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3688  (! daemon->was_quiesced) &&
3689  (daemon->connections < daemon->connection_limit) &&
3690  (! daemon->at_limit) )
3691  {
3692  /* only listen if we are not at the connection limit */
3693  p[poll_server].fd = ls;
3694  p[poll_server].events = POLLIN;
3695  p[poll_server].revents = 0;
3696  poll_listen = (int) poll_server;
3697  poll_server++;
3698  }
3699  poll_itc_idx = -1;
3700  if (MHD_ITC_IS_VALID_(daemon->itc))
3701  {
3702  p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
3703  p[poll_server].events = POLLIN;
3704  p[poll_server].revents = 0;
3705  poll_itc_idx = (int) poll_server;
3706  poll_server++;
3707  }
3708  if (may_block == MHD_NO)
3709  timeout = 0;
3710  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
3711  (MHD_YES != MHD_get_timeout (daemon,
3712  &ltimeout)) )
3713  timeout = -1;
3714  else
3715  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
3716 
3717  i = 0;
3718  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
3719  {
3720  p[poll_server+i].fd = pos->socket_fd;
3721  switch (pos->event_loop_info)
3722  {
3724  p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3725  break;
3727  p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3728  break;
3730  p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3731  break;
3733  timeout = 0; /* clean up "pos" immediately */
3734  break;
3735  }
3736  i++;
3737  }
3738 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3739  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
3740  {
3741  urh_to_pollfd(urh, &(p[poll_server+i]));
3742  i += 2;
3743  }
3744 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3745  if (0 == poll_server + num_connections)
3746  {
3747  free(p);
3748  return MHD_YES;
3749  }
3750  if (MHD_sys_poll_(p,
3751  poll_server + num_connections,
3752  timeout) < 0)
3753  {
3754  const int err = MHD_socket_get_error_ ();
3755  if (MHD_SCKT_ERR_IS_EINTR_ (err))
3756  {
3757  free(p);
3758  return MHD_YES;
3759  }
3760 #ifdef HAVE_MESSAGES
3761  MHD_DLOG (daemon,
3762  _("poll failed: %s\n"),
3763  MHD_socket_strerr_ (err));
3764 #endif
3765  free(p);
3766  return MHD_NO;
3767  }
3768 
3769  /* Reset. New value will be set when connections are processed. */
3770  daemon->data_already_pending = false;
3771 
3772  /* handle ITC FD */
3773  /* do it before any other processing so
3774  new signals will be processed in next loop */
3775  if ( (-1 != poll_itc_idx) &&
3776  (0 != (p[poll_itc_idx].revents & POLLIN)) )
3777  MHD_itc_clear_ (daemon->itc);
3778 
3779  /* handle shutdown */
3780  if (daemon->shutdown)
3781  {
3782  free(p);
3783  return MHD_NO;
3784  }
3785  i = 0;
3786  prev = daemon->connections_tail;
3787  while (NULL != (pos = prev))
3788  {
3789  prev = pos->prev;
3790  /* first, sanity checks */
3791  if (i >= num_connections)
3792  break; /* connection list changed somehow, retry later ... */
3793  if (p[poll_server+i].fd != pos->socket_fd)
3794  continue; /* fd mismatch, something else happened, retry later ... */
3795  call_handlers (pos,
3796  0 != (p[poll_server+i].revents & POLLIN),
3797  0 != (p[poll_server+i].revents & POLLOUT),
3798  0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3799  i++;
3800  }
3801 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3802  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3803  {
3804  if (i >= num_connections)
3805  break; /* connection list changed somehow, retry later ... */
3806 
3807  /* Get next connection here as connection can be removed
3808  * from 'daemon->urh_head' list. */
3809  urhn = urh->prev;
3810  /* Check for fd mismatch. FIXME: required for safety? */
3811  if ((p[poll_server+i].fd != urh->connection->socket_fd) ||
3812  (p[poll_server+i+1].fd != urh->mhd.socket))
3813  break;
3814  urh_from_pollfd (urh,
3815  &p[poll_server+i]);
3816  i += 2;
3817  process_urh (urh);
3818  /* Finished forwarding? */
3819  if ( (0 == urh->in_buffer_size) &&
3820  (0 == urh->out_buffer_size) &&
3821  (0 == urh->in_buffer_used) &&
3822  (0 == urh->out_buffer_used) )
3823  {
3824  /* MHD_connection_finish_forward_() will remove connection from
3825  * 'daemon->urh_head' list. */
3826  MHD_connection_finish_forward_ (urh->connection);
3827  urh->clean_ready = true;
3828  /* If 'urh->was_closed' already was set to true, connection will be
3829  * moved immediately to cleanup list. Otherwise connection
3830  * will stay in suspended list until 'urh' will be marked
3831  * with 'was_closed' by application. */
3832  MHD_resume_connection(urh->connection);
3833  }
3834  }
3835 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3836  /* handle 'listen' FD */
3837  if ( (-1 != poll_listen) &&
3838  (0 != (p[poll_listen].revents & POLLIN)) )
3839  (void) MHD_accept_connection (daemon);
3840 
3841  free(p);
3842  }
3843  return MHD_YES;
3844 }
3845 
3846 
3854 static int
3855 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
3856  int may_block)
3857 {
3858  struct pollfd p[2];
3859  int timeout;
3860  unsigned int poll_count;
3861  int poll_listen;
3862  int poll_itc_idx;
3863  MHD_socket ls;
3864 
3865  memset (&p,
3866  0,
3867  sizeof (p));
3868  poll_count = 0;
3869  poll_listen = -1;
3870  poll_itc_idx = -1;
3871  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3872  (! daemon->was_quiesced) )
3873 
3874  {
3875  p[poll_count].fd = ls;
3876  p[poll_count].events = POLLIN;
3877  p[poll_count].revents = 0;
3878  poll_listen = poll_count;
3879  poll_count++;
3880  }
3881  if (MHD_ITC_IS_VALID_(daemon->itc))
3882  {
3883  p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
3884  p[poll_count].events = POLLIN;
3885  p[poll_count].revents = 0;
3886  poll_itc_idx = poll_count;
3887  poll_count++;
3888  }
3889 
3890  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3891  (void) resume_suspended_connections (daemon);
3892 
3893  if (MHD_NO == may_block)
3894  timeout = 0;
3895  else
3896  timeout = -1;
3897  if (0 == poll_count)
3898  return MHD_YES;
3899  if (MHD_sys_poll_(p,
3900  poll_count,
3901  timeout) < 0)
3902  {
3903  const int err = MHD_socket_get_error_ ();
3904 
3905  if (MHD_SCKT_ERR_IS_EINTR_ (err))
3906  return MHD_YES;
3907 #ifdef HAVE_MESSAGES
3908  MHD_DLOG (daemon,
3909  _("poll failed: %s\n"),
3910  MHD_socket_strerr_ (err));
3911 #endif
3912  return MHD_NO;
3913  }
3914  if ( (-1 != poll_itc_idx) &&
3915  (0 != (p[poll_itc_idx].revents & POLLIN)) )
3916  MHD_itc_clear_ (daemon->itc);
3917 
3918  /* handle shutdown */
3919  if (daemon->shutdown)
3920  return MHD_NO;
3921  if ( (-1 != poll_listen) &&
3922  (0 != (p[poll_listen].revents & POLLIN)) )
3923  (void) MHD_accept_connection (daemon);
3924  return MHD_YES;
3925 }
3926 #endif
3927 
3928 
3936 static int
3937 MHD_poll (struct MHD_Daemon *daemon,
3938  int may_block)
3939 {
3940 #ifdef HAVE_POLL
3941  if (daemon->shutdown)
3942  return MHD_NO;
3943  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3944  return MHD_poll_all (daemon,
3945  may_block);
3946  return MHD_poll_listen_socket (daemon,
3947  may_block);
3948 #else
3949  (void) daemon;
3950  (void) may_block;
3951  return MHD_NO;
3952 #endif
3953 }
3954 
3955 
3956 #ifdef EPOLL_SUPPORT
3957 
3966 #define MAX_EVENTS 128
3967 
3968 
3969 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3970 
3978 static bool
3979 is_urh_ready(struct MHD_UpgradeResponseHandle * const urh)
3980 {
3981  const struct MHD_Connection * const connection = urh->connection;
3982 
3983  if ( (0 == urh->in_buffer_size) &&
3984  (0 == urh->out_buffer_size) &&
3985  (0 == urh->in_buffer_used) &&
3986  (0 == urh->out_buffer_used) )
3987  return false;
3988  if (connection->daemon->shutdown)
3989  return true;
3990  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
3991  (connection->tls_read_ready) ) &&
3992  (urh->in_buffer_used < urh->in_buffer_size) )
3993  return true;
3994  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
3995  (urh->out_buffer_used < urh->out_buffer_size) )
3996  return true;
3997  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
3998  (urh->out_buffer_used > 0) )
3999  return true;
4000  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
4001  (urh->in_buffer_used > 0) )
4002  return true;
4003  return false;
4004 }
4005 
4006 
4015 static int
4016 run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4017 {
4018  struct epoll_event events[MAX_EVENTS];
4019  int num_events;
4020  struct MHD_UpgradeResponseHandle * pos;
4021  struct MHD_UpgradeResponseHandle * prev;
4022 
4023  num_events = MAX_EVENTS;
4024  while (MAX_EVENTS == num_events)
4025  {
4026  unsigned int i;
4027  /* update event masks */
4028  num_events = epoll_wait (daemon->epoll_upgrade_fd,
4029  events,
4030  MAX_EVENTS,
4031  0);
4032  if (-1 == num_events)
4033  {
4034  const int err = MHD_socket_get_error_ ();
4035  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4036  return MHD_YES;
4037 #ifdef HAVE_MESSAGES
4038  MHD_DLOG (daemon,
4039  _("Call to epoll_wait failed: %s\n"),
4040  MHD_socket_strerr_ (err));
4041 #endif
4042  return MHD_NO;
4043  }
4044  for (i = 0; i < (unsigned int) num_events; i++)
4045  {
4046  struct UpgradeEpollHandle * const ueh = events[i].data.ptr;
4047  struct MHD_UpgradeResponseHandle * const urh = ueh->urh;
4048  bool new_err_state = false;
4049 
4050  if (urh->clean_ready)
4051  continue;
4052 
4053  /* Update ueh state based on what is ready according to epoll() */
4054  if (0 != (events[i].events & EPOLLIN))
4055  ueh->celi |= MHD_EPOLL_STATE_READ_READY;
4056  if (0 != (events[i].events & EPOLLOUT))
4057  ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
4058  if (0 != (events[i].events & EPOLLHUP))
4060 
4061  if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
4062  (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4063  {
4064  /* Process new error state only one time
4065  * and avoid continuously marking this connection
4066  * as 'ready'. */
4067  ueh->celi |= MHD_EPOLL_STATE_ERROR;
4068  new_err_state = true;
4069  }
4070 
4071  if (! urh->in_eready_list)
4072  {
4073  if (new_err_state ||
4074  is_urh_ready(urh))
4075  {
4076  EDLL_insert (daemon->eready_urh_head,
4077  daemon->eready_urh_tail,
4078  urh);
4079  urh->in_eready_list = true;
4080  }
4081  }
4082  }
4083  }
4084  prev = daemon->eready_urh_tail;
4085  while (NULL != (pos = prev))
4086  {
4087  prev = pos->prevE;
4088  process_urh (pos);
4089  if (! is_urh_ready(pos))
4090  {
4091  EDLL_remove (daemon->eready_urh_head,
4092  daemon->eready_urh_tail,
4093  pos);
4094  pos->in_eready_list = false;
4095  }
4096  /* Finished forwarding? */
4097  if ( (0 == pos->in_buffer_size) &&
4098  (0 == pos->out_buffer_size) &&
4099  (0 == pos->in_buffer_used) &&
4100  (0 == pos->out_buffer_used) )
4101  {
4102  MHD_connection_finish_forward_ (pos->connection);
4103  pos->clean_ready = true;
4104  /* If 'pos->was_closed' already was set to true, connection
4105  * will be moved immediately to cleanup list. Otherwise
4106  * connection will stay in suspended list until 'pos' will
4107  * be marked with 'was_closed' by application. */
4108  MHD_resume_connection(pos->connection);
4109  }
4110  }
4111 
4112  return MHD_YES;
4113 }
4114 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4115 
4116 
4120 static const char * const epoll_itc_marker = "itc_marker";
4121 
4122 
4131 static int
4132 MHD_epoll (struct MHD_Daemon *daemon,
4133  int may_block)
4134 {
4135 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4136  static const char * const upgrade_marker = "upgrade_ptr";
4137 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4138  struct MHD_Connection *pos;
4139  struct MHD_Connection *prev;
4140  struct epoll_event events[MAX_EVENTS];
4141  struct epoll_event event;
4142  int timeout_ms;
4143  MHD_UNSIGNED_LONG_LONG timeout_ll;
4144  int num_events;
4145  unsigned int i;
4146  MHD_socket ls;
4147 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4148  int run_upgraded = MHD_NO;
4149 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4150 
4151  if (-1 == daemon->epoll_fd)
4152  return MHD_NO; /* we're down! */
4153  if (daemon->shutdown)
4154  return MHD_NO;
4155  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4156  (! daemon->was_quiesced) &&
4157  (daemon->connections < daemon->connection_limit) &&
4158  (! daemon->listen_socket_in_epoll) &&
4159  (! daemon->at_limit) )
4160  {
4161  event.events = EPOLLIN;
4162  event.data.ptr = daemon;
4163  if (0 != epoll_ctl (daemon->epoll_fd,
4164  EPOLL_CTL_ADD,
4165  ls,
4166  &event))
4167  {
4168 #ifdef HAVE_MESSAGES
4169  MHD_DLOG (daemon,
4170  _("Call to epoll_ctl failed: %s\n"),
4172 #endif
4173  return MHD_NO;
4174  }
4175  daemon->listen_socket_in_epoll = true;
4176  }
4177  if ( (daemon->was_quiesced) &&
4178  (daemon->listen_socket_in_epoll) )
4179  {
4180  if ( (0 != epoll_ctl (daemon->epoll_fd,
4181  EPOLL_CTL_DEL,
4182  ls,
4183  NULL)) &&
4184  (ENOENT != errno) ) /* ENOENT can happen due to race with
4185  #MHD_quiesce_daemon() */
4186  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4187  daemon->listen_socket_in_epoll = false;
4188  }
4189 
4190 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4191  if ( (! daemon->upgrade_fd_in_epoll) &&
4192  (-1 != daemon->epoll_upgrade_fd) )
4193  {
4194  event.events = EPOLLIN | EPOLLOUT;
4195  event.data.ptr = (void *) upgrade_marker;
4196  if (0 != epoll_ctl (daemon->epoll_fd,
4197  EPOLL_CTL_ADD,
4198  daemon->epoll_upgrade_fd,
4199  &event))
4200  {
4201 #ifdef HAVE_MESSAGES
4202  MHD_DLOG (daemon,
4203  _("Call to epoll_ctl failed: %s\n"),
4205 #endif
4206  return MHD_NO;
4207  }
4208  daemon->upgrade_fd_in_epoll = true;
4209  }
4210 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4211  if ( (daemon->listen_socket_in_epoll) &&
4212  ( (daemon->connections == daemon->connection_limit) ||
4213  (daemon->at_limit) ||
4214  (daemon->was_quiesced) ) )
4215  {
4216  /* we're at the connection limit, disable listen socket
4217  for event loop for now */
4218  if (0 != epoll_ctl (daemon->epoll_fd,
4219  EPOLL_CTL_DEL,
4220  ls,
4221  NULL))
4222  MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4223  daemon->listen_socket_in_epoll = false;
4224  }
4225 
4226  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
4227  (MHD_YES == resume_suspended_connections (daemon)) )
4228  may_block = MHD_NO;
4229 
4230  if (MHD_YES == may_block)
4231  {
4232  if (MHD_YES == MHD_get_timeout (daemon,
4233  &timeout_ll))
4234  {
4235  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
4236  timeout_ms = INT_MAX;
4237  else
4238  timeout_ms = (int) timeout_ll;
4239  }
4240  else
4241  timeout_ms = -1;
4242  }
4243  else
4244  timeout_ms = 0;
4245 
4246  /* Reset. New value will be set when connections are processed. */
4247  /* Note: Used mostly for uniformity here as same situation is
4248  * signaled in epoll mode by non-empty eready DLL. */
4249  daemon->data_already_pending = false;
4250 
4251  /* drain 'epoll' event queue; need to iterate as we get at most
4252  MAX_EVENTS in one system call here; in practice this should
4253  pretty much mean only one round, but better an extra loop here
4254  than unfair behavior... */
4255  num_events = MAX_EVENTS;
4256  while (MAX_EVENTS == num_events)
4257  {
4258  /* update event masks */
4259  num_events = epoll_wait (daemon->epoll_fd,
4260  events,
4261  MAX_EVENTS,
4262  timeout_ms);
4263  if (-1 == num_events)
4264  {
4265  const int err = MHD_socket_get_error_ ();
4266  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4267  return MHD_YES;
4268 #ifdef HAVE_MESSAGES
4269  MHD_DLOG (daemon,
4270  _("Call to epoll_wait failed: %s\n"),
4271  MHD_socket_strerr_ (err));
4272 #endif
4273  return MHD_NO;
4274  }
4275  for (i=0;i<(unsigned int) num_events;i++)
4276  {
4277  /* First, check for the values of `ptr` that would indicate
4278  that this event is not about a normal connection. */
4279  if (NULL == events[i].data.ptr)
4280  continue; /* shutdown signal! */
4281 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4282  if (upgrade_marker == events[i].data.ptr)
4283  {
4284  /* activity on an upgraded connection, we process
4285  those in a separate epoll() */
4286  run_upgraded = MHD_YES;
4287  continue;
4288  }
4289 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4290  if (epoll_itc_marker == events[i].data.ptr)
4291  {
4292  /* It's OK to clear ITC here as all external
4293  conditions will be processed later. */
4294  MHD_itc_clear_ (daemon->itc);
4295  continue;
4296  }
4297  if (daemon == events[i].data.ptr)
4298  {
4299  /* Check for error conditions on listen socket. */
4300  /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
4301  if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4302  {
4303  unsigned int series_length = 0;
4304  /* Run 'accept' until it fails or daemon at limit of connections.
4305  * Do not accept more then 10 connections at once. The rest will
4306  * be accepted on next turn (level trigger is used for listen
4307  * socket). */
4308  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
4309  (series_length < 10) &&
4310  (daemon->connections < daemon->connection_limit) &&
4311  (! daemon->at_limit) )
4312  series_length++;
4313  }
4314  continue;
4315  }
4316  /* this is an event relating to a 'normal' connection,
4317  remember the event and if appropriate mark the
4318  connection as 'eready'. */
4319  pos = events[i].data.ptr;
4320  /* normal processing: update read/write data */
4321  if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4322  {
4323  pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
4324  if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
4325  {
4326  EDLL_insert (daemon->eready_head,
4327  daemon->eready_tail,
4328  pos);
4329  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4330  }
4331  }
4332  else
4333  {
4334  if (0 != (events[i].events & EPOLLIN))
4335  {
4336  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
4337  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
4338  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
4339  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4340  {
4341  EDLL_insert (daemon->eready_head,
4342  daemon->eready_tail,
4343  pos);
4344  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4345  }
4346  }
4347  if (0 != (events[i].events & EPOLLOUT))
4348  {
4349  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
4350  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
4351  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4352  {
4353  EDLL_insert (daemon->eready_head,
4354  daemon->eready_tail,
4355  pos);
4356  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4357  }
4358  }
4359  }
4360  }
4361  }
4362 
4363 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4364  if (MHD_YES == run_upgraded)
4365  run_epoll_for_upgrade (daemon);
4366 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4367 
4368  /* process events for connections */
4369  prev = daemon->eready_tail;
4370  while (NULL != (pos = prev))
4371  {
4372  prev = pos->prevE;
4373  call_handlers (pos,
4374  0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
4375  0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
4376  0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
4379  {
4380  if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info &&
4381  0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) ||
4383  0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) ||
4385  {
4386  EDLL_remove (daemon->eready_head,
4387  daemon->eready_tail,
4388  pos);
4389  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
4390  }
4391  }
4392  }
4393 
4394  /* Finally, handle timed-out connections; we need to do this here
4395  as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
4396  as the other event loops do. As timeouts do not get an explicit
4397  event, we need to find those connections that might have timed out
4398  here.
4399 
4400  Connections with custom timeouts must all be looked at, as we
4401  do not bother to sort that (presumably very short) list. */
4402  prev = daemon->manual_timeout_tail;
4403  while (NULL != (pos = prev))
4404  {
4405  prev = pos->prevX;
4407  }
4408  /* Connections with the default timeout are sorted by prepending
4409  them to the head of the list whenever we touch the connection;
4410  thus it suffices to iterate from the tail until the first
4411  connection is NOT timed out */
4412  prev = daemon->normal_timeout_tail;
4413  while (NULL != (pos = prev))
4414  {
4415  prev = pos->prevX;
4417  if (MHD_CONNECTION_CLOSED != pos->state)
4418  break; /* sorted by timeout, no need to visit the rest! */
4419  }
4420  return MHD_YES;
4421 }
4422 #endif
4423 
4424 
4445 int
4446 MHD_run (struct MHD_Daemon *daemon)
4447 {
4448  if ( (daemon->shutdown) ||
4449  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
4450  return MHD_NO;
4451  if (0 != (daemon->options & MHD_USE_POLL))
4452  {
4453  MHD_poll (daemon, MHD_NO);
4454  MHD_cleanup_connections (daemon);
4455  }
4456 #ifdef EPOLL_SUPPORT
4457  else if (0 != (daemon->options & MHD_USE_EPOLL))
4458  {
4459  MHD_epoll (daemon, MHD_NO);
4460  MHD_cleanup_connections (daemon);
4461  }
4462 #endif
4463  else
4464  {
4465  MHD_select (daemon, MHD_NO);
4466  /* MHD_select does MHD_cleanup_connections already */
4467  }
4468  return MHD_YES;
4469 }
4470 
4471 
4480 static void
4482 {
4483  struct MHD_Daemon *daemon = pos->daemon;
4484 
4485  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4486  {
4488  return; /* must let thread to do the rest */
4489  }
4490  MHD_connection_close_ (pos,
4492 
4494 
4495  mhd_assert (! pos->suspended);
4496  mhd_assert (! pos->resuming);
4497  if (pos->connection_timeout == daemon->connection_timeout)
4499  daemon->normal_timeout_tail,
4500  pos);
4501  else
4503  daemon->manual_timeout_tail,
4504  pos);
4505  DLL_remove (daemon->connections_head,
4506  daemon->connections_tail,
4507  pos);
4508  DLL_insert (daemon->cleanup_head,
4509  daemon->cleanup_tail,
4510  pos);
4511 
4513 }
4514 
4515 
4523 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4525 {
4526  struct MHD_Daemon *daemon = cls;
4527 
4528  MHD_thread_init_(&(daemon->pid));
4529  while (! daemon->shutdown)
4530  {
4531  if (0 != (daemon->options & MHD_USE_POLL))
4532  MHD_poll (daemon, MHD_YES);
4533 #ifdef EPOLL_SUPPORT
4534  else if (0 != (daemon->options & MHD_USE_EPOLL))
4535  MHD_epoll (daemon, MHD_YES);
4536 #endif
4537  else
4538  MHD_select (daemon, MHD_YES);
4539  MHD_cleanup_connections (daemon);
4540  }
4541 
4542  /* Resume any pending for resume connections, join
4543  * all connection's threads (if any) and finally cleanup
4544  * everything. */
4545  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
4547  close_all_connections (daemon);
4548 
4549  return (MHD_THRD_RTRN_TYPE_)0;
4550 }
4551 
4552 
4564 static size_t
4565 unescape_wrapper (void *cls,
4566  struct MHD_Connection *connection,
4567  char *val)
4568 {
4569  (void) cls; /* Mute compiler warning. */
4570  (void) connection; /* Mute compiler warning. */
4571  return MHD_http_unescape (val);
4572 }
4573 
4574 
4595 struct MHD_Daemon *
4596 MHD_start_daemon (unsigned int flags,
4597  uint16_t port,
4599  void *apc_cls,
4601  void *dh_cls,
4602  ...)
4603 {
4604  struct MHD_Daemon *daemon;
4605  va_list ap;
4606 
4607  va_start (ap,
4608  dh_cls);
4609  daemon = MHD_start_daemon_va (flags,
4610  port,
4611  apc,
4612  apc_cls,
4613  dh,
4614  dh_cls,
4615  ap);
4616  va_end (ap);
4617  return daemon;
4618 }
4619 
4620 
4640 MHD_socket
4642 {
4643  unsigned int i;
4644  MHD_socket ret;
4645 
4646  ret = daemon->listen_fd;
4647  if (MHD_INVALID_SOCKET == ret)
4648  return MHD_INVALID_SOCKET;
4649  if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
4650  (0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) )
4651  {
4652 #ifdef HAVE_MESSAGES
4653  MHD_DLOG (daemon,
4654  "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4655 #endif
4656  return MHD_INVALID_SOCKET;
4657  }
4658 
4659  if (NULL != daemon->worker_pool)
4660  for (i = 0; i < daemon->worker_pool_size; i++)
4661  {
4662  daemon->worker_pool[i].was_quiesced = true;
4663 #ifdef EPOLL_SUPPORT
4664  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4665  (-1 != daemon->worker_pool[i].epoll_fd) &&
4666  (daemon->worker_pool[i].listen_socket_in_epoll) )
4667  {
4668  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
4669  EPOLL_CTL_DEL,
4670  ret,
4671  NULL))
4672  MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4673  daemon->worker_pool[i].listen_socket_in_epoll = false;
4674  }
4675  else
4676 #endif
4677  if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
4678  {
4679  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
4680  MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
4681  }
4682  }
4683  daemon->was_quiesced = true;
4684 #ifdef EPOLL_SUPPORT
4685  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4686  (-1 != daemon->epoll_fd) &&
4687  (daemon->listen_socket_in_epoll) )
4688  {
4689  if ( (0 != epoll_ctl (daemon->epoll_fd,
4690  EPOLL_CTL_DEL,
4691  ret,
4692  NULL)) &&
4693  (ENOENT != errno) ) /* ENOENT can happen due to race with
4694  #MHD_epoll() */
4695  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4696  daemon->listen_socket_in_epoll = false;
4697  }
4698 #endif
4699  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
4700  (! MHD_itc_activate_ (daemon->itc, "q")) )
4701  MHD_PANIC (_("failed to signal quiesce via inter-thread communication channel"));
4702  return ret;
4703 }
4704 
4705 
4713 typedef void
4715  const char *format,
4716  va_list va);
4717 
4718 
4727 static int
4728 parse_options_va (struct MHD_Daemon *daemon,
4729  const struct sockaddr **servaddr,
4730  va_list ap);
4731 
4732 
4741 static int
4742 parse_options (struct MHD_Daemon *daemon,
4743  const struct sockaddr **servaddr,
4744  ...)
4745 {
4746  va_list ap;
4747  int ret;
4748 
4749  va_start (ap, servaddr);
4750  ret = parse_options_va (daemon,
4751  servaddr,
4752  ap);
4753  va_end (ap);
4754  return ret;
4755 }
4756 
4757 
4766 static int
4768  const struct sockaddr **servaddr,
4769  va_list ap)
4770 {
4771  enum MHD_OPTION opt;
4772  struct MHD_OptionItem *oa;
4773  unsigned int i;
4774  unsigned int uv;
4775 #ifdef HTTPS_SUPPORT
4776  int ret;
4777  const char *pstr;
4778 #endif /* HTTPS_SUPPORT */
4779 
4780  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
4781  {
4782  switch (opt)
4783  {
4785  daemon->pool_size = va_arg (ap,
4786  size_t);
4787  break;
4789  daemon->pool_increment= va_arg (ap,
4790  size_t);
4791  break;
4793  daemon->connection_limit = va_arg (ap,
4794  unsigned int);
4795  break;
4797  uv = va_arg (ap,
4798  unsigned int);
4799  /* Next comparison could be always false on some platforms and whole branch will
4800  * be optimized out on those platforms. On others it will be compiled into real
4801  * check. */
4802  if (TIME_T_MAX < uv) /* Compiler may warn on some platforms, ignore warning. */
4803  {
4804 #ifdef HAVE_MESSAGES
4805  MHD_DLOG (daemon,
4806  _("Warning: Too large timeout value, ignored.\n"));
4807 #endif
4808  daemon->connection_timeout = 0;
4809  }
4810  else
4811  daemon->connection_timeout = (time_t)uv;
4812  break;
4814  daemon->notify_completed = va_arg (ap,
4816  daemon->notify_completed_cls = va_arg (ap,
4817  void *);
4818  break;
4820  daemon->notify_connection = va_arg (ap,
4822  daemon->notify_connection_cls = va_arg (ap,
4823  void *);
4824  break;
4826  daemon->per_ip_connection_limit = va_arg (ap,
4827  unsigned int);
4828  break;
4829  case MHD_OPTION_SOCK_ADDR:
4830  *servaddr = va_arg (ap,
4831  const struct sockaddr *);
4832  break;
4834  daemon->uri_log_callback = va_arg (ap,
4835  LogCallback);
4836  daemon->uri_log_callback_cls = va_arg (ap,
4837  void *);
4838  break;
4840  daemon->worker_pool_size = va_arg (ap,
4841  unsigned int);
4842  if (0 == daemon->worker_pool_size)
4843  {
4844 #ifdef HAVE_MESSAGES
4845  MHD_DLOG (daemon,
4846  _("Warning: Zero size, specified for thread pool size, is ignored. "
4847  "Thread pool is not used.\n"));
4848 #endif
4849  }
4850  else if (1 == daemon->worker_pool_size)
4851  {
4852 #ifdef HAVE_MESSAGES
4853  MHD_DLOG (daemon,
4854  _("Warning: \"1\", specified for thread pool size, is ignored. "
4855  "Thread pool is not used.\n"));
4856 #endif
4857  daemon->worker_pool_size = 0;
4858  }
4859  /* Next comparison could be always false on some platforms and whole branch will
4860  * be optimized out on those platforms. On others it will be compiled into real
4861  * check. */
4862  else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */
4863  {
4864 #ifdef HAVE_MESSAGES
4865  MHD_DLOG (daemon,
4866  _("Specified thread pool size (%u) too big\n"),
4867  daemon->worker_pool_size);
4868 #endif
4869  return MHD_NO;
4870  }
4871  else
4872  {
4873  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
4874  {
4875 #ifdef HAVE_MESSAGES
4876  MHD_DLOG (daemon,
4877  _("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
4878  "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
4879 #endif
4880  return MHD_NO;
4881  }
4882  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4883  {
4884 #ifdef HAVE_MESSAGES
4885  MHD_DLOG (daemon,
4886  _("Both MHD_OPTION_THREAD_POOL_SIZE option and "
4887  "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
4888 #endif
4889  return MHD_NO;
4890  }
4891  }
4892  break;
4893 #ifdef HTTPS_SUPPORT
4895  if (0 != (daemon->options & MHD_USE_TLS))
4896  daemon->https_mem_key = va_arg (ap,
4897  const char *);
4898 #ifdef HAVE_MESSAGES
4899  else
4900  MHD_DLOG (daemon,
4901  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4902  opt);
4903 #endif
4904  break;
4906  if (0 != (daemon->options & MHD_USE_TLS))
4907  daemon->https_key_password = va_arg (ap,
4908  const char *);
4909 #ifdef HAVE_MESSAGES
4910  else
4911  MHD_DLOG (daemon,
4912  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4913  opt);
4914 #endif
4915  break;
4917  if (0 != (daemon->options & MHD_USE_TLS))
4918  daemon->https_mem_cert = va_arg (ap,
4919  const char *);
4920 #ifdef HAVE_MESSAGES
4921  else
4922  MHD_DLOG (daemon,
4923  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4924  opt);
4925 #endif
4926  break;
4928  if (0 != (daemon->options & MHD_USE_TLS))
4929  daemon->https_mem_trust = va_arg (ap,
4930  const char *);
4931 #ifdef HAVE_MESSAGES
4932  else
4933  MHD_DLOG (daemon,
4934  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4935  opt);
4936 #endif
4937  break;
4939  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
4940  int);
4941  break;
4943  if (0 != (daemon->options & MHD_USE_TLS))
4944  {
4945  const char *arg = va_arg (ap,
4946  const char *);
4947  gnutls_datum_t dhpar;
4948 
4949  if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
4950  {
4951 #ifdef HAVE_MESSAGES
4952  MHD_DLOG (daemon,
4953  _("Error initializing DH parameters\n"));
4954 #endif
4955  return MHD_NO;
4956  }
4957  dhpar.data = (unsigned char *) arg;
4958  dhpar.size = strlen (arg);
4959  if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
4960  &dhpar,
4961  GNUTLS_X509_FMT_PEM) < 0)
4962  {
4963 #ifdef HAVE_MESSAGES
4964  MHD_DLOG (daemon,
4965  _("Bad Diffie-Hellman parameters format\n"));
4966 #endif
4967  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
4968  return MHD_NO;
4969  }
4970  daemon->have_dhparams = true;
4971  }
4972  else
4973  {
4974 #ifdef HAVE_MESSAGES
4975  MHD_DLOG (daemon,
4976  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
4977  opt);
4978 #endif
4979  return MHD_NO;
4980  }
4981  break;
4983  if (0 != (daemon->options & MHD_USE_TLS))
4984  {
4985  gnutls_priority_deinit (daemon->priority_cache);
4986  ret = gnutls_priority_init (&daemon->priority_cache,
4987  pstr = va_arg (ap, const char*),
4988  NULL);
4989  if (GNUTLS_E_SUCCESS != ret)
4990  {
4991 #ifdef HAVE_MESSAGES
4992  MHD_DLOG (daemon,
4993  _("Setting priorities to `%s' failed: %s\n"),
4994  pstr,
4995  gnutls_strerror (ret));
4996 #endif
4997  daemon->priority_cache = NULL;
4998  return MHD_NO;
4999  }
5000  }
5001  break;
5003 #if GNUTLS_VERSION_MAJOR < 3
5004 #ifdef HAVE_MESSAGES
5005  MHD_DLOG (daemon,
5006  _("MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5007 #endif
5008  return MHD_NO;
5009 #else
5010  if (0 != (daemon->options & MHD_USE_TLS))
5011  daemon->cert_callback = va_arg (ap,
5012  gnutls_certificate_retrieve_function2 *);
5013  break;
5014 #endif
5015 #endif /* HTTPS_SUPPORT */
5016 #ifdef DAUTH_SUPPORT
5018  daemon->digest_auth_rand_size = va_arg (ap,
5019  size_t);
5020  daemon->digest_auth_random = va_arg (ap,
5021  const char *);
5022  break;
5024  daemon->nonce_nc_size = va_arg (ap,
5025  unsigned int);
5026  break;
5027 #endif
5029  if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET))
5030  {
5031 #ifdef HAVE_MESSAGES
5032  MHD_DLOG (daemon,
5033  _("MHD_OPTION_LISTEN_SOCKET specified for daemon "
5034  "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5035 #endif
5036  return MHD_NO;
5037  }
5038  else
5039  daemon->listen_fd = va_arg (ap,
5040  MHD_socket);
5041  break;
5043 #ifdef HAVE_MESSAGES
5044  daemon->custom_error_log = va_arg (ap,
5046  daemon->custom_error_log_cls = va_arg (ap,
5047  void *);
5048 #else
5049  va_arg (ap,
5051  va_arg (ap,
5052  void *);
5053 #endif
5054  break;
5056  daemon->thread_stack_size = va_arg (ap,
5057  size_t);
5058  break;
5059 #ifdef TCP_FASTOPEN
5061  daemon->fastopen_queue_size = va_arg (ap,
5062  unsigned int);
5063  break;
5064 #endif
5066  daemon->listening_address_reuse = va_arg (ap,
5067  unsigned int) ? 1 : -1;
5068  break;
5070  daemon->listen_backlog_size = va_arg (ap,
5071  unsigned int);
5072  break;
5074  daemon->strict_for_client = va_arg (ap, int);;
5075 #ifdef HAVE_MESSAGES
5076  if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
5077  (1 != daemon->strict_for_client) )
5078  {
5079  MHD_DLOG (daemon,
5080  _("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5081  "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5082  }
5083 #endif /* HAVE_MESSAGES */
5084  break;
5085  case MHD_OPTION_ARRAY:
5086  oa = va_arg (ap, struct MHD_OptionItem*);
5087  i = 0;
5088  while (MHD_OPTION_END != (opt = oa[i].option))
5089  {
5090  switch (opt)
5091  {
5092  /* all options taking 'size_t' */
5096  if (MHD_YES != parse_options (daemon,
5097  servaddr,
5098  opt,
5099  (size_t) oa[i].value,
5100  MHD_OPTION_END))
5101  return MHD_NO;
5102  break;
5103  /* all options taking 'unsigned int' */
5112  if (MHD_YES != parse_options (daemon,
5113  servaddr,
5114  opt,
5115  (unsigned int) oa[i].value,
5116  MHD_OPTION_END))
5117  return MHD_NO;
5118  break;
5119  /* all options taking 'enum' */
5120 #ifdef HTTPS_SUPPORT
5122  if (MHD_YES != parse_options (daemon,
5123  servaddr,
5124  opt,
5125  (gnutls_credentials_type_t) oa[i].value,
5126  MHD_OPTION_END))
5127  return MHD_NO;
5128  break;
5129 #endif /* HTTPS_SUPPORT */
5130  /* all options taking 'MHD_socket' */
5132  if (MHD_YES != parse_options (daemon,
5133  servaddr,
5134  opt,
5135  (MHD_socket) oa[i].value,
5136  MHD_OPTION_END))
5137  return MHD_NO;
5138  break;
5139  /* all options taking 'int' */
5141  if (MHD_YES != parse_options (daemon,
5142  servaddr,
5143  opt,
5144  (int) oa[i].value,
5145  MHD_OPTION_END))
5146  return MHD_NO;
5147  break;
5148  /* all options taking one pointer */
5149  case MHD_OPTION_SOCK_ADDR:
5156  case MHD_OPTION_ARRAY:
5158  if (MHD_YES != parse_options (daemon,
5159  servaddr,
5160  opt,
5161  oa[i].ptr_value,
5162  MHD_OPTION_END))
5163  return MHD_NO;
5164  break;
5165  /* all options taking two pointers */
5172  if (MHD_YES != parse_options (daemon,
5173  servaddr,
5174  opt,
5175  (void *) oa[i].value,
5176  oa[i].ptr_value,
5177  MHD_OPTION_END))
5178  return MHD_NO;
5179  break;
5180  /* options taking size_t-number followed by pointer */
5182  if (MHD_YES != parse_options (daemon,
5183  servaddr,
5184  opt,
5185  (size_t) oa[i].value,
5186  oa[i].ptr_value,
5187  MHD_OPTION_END))
5188  return MHD_NO;
5189  break;
5190  default:
5191  return MHD_NO;
5192  }
5193  i++;
5194  }
5195  break;
5197  daemon->unescape_callback = va_arg (ap,
5199  daemon->unescape_callback_cls = va_arg (ap,
5200  void *);
5201  break;
5202 #ifdef HTTPS_SUPPORT
5204 #if GNUTLS_VERSION_MAJOR >= 3
5205  daemon->cred_callback = va_arg (ap,
5207  daemon->cred_callback_cls = va_arg (ap,
5208  void *);
5209  break;
5210 #else
5211  MHD_DLOG (daemon,
5212  _("MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5213  opt);
5214  return MHD_NO;
5215 #endif
5216 #endif /* HTTPS_SUPPORT */
5217  default:
5218 #ifdef HAVE_MESSAGES
5219  if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
5220  (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) ||
5221  (opt == MHD_OPTION_HTTPS_MEM_TRUST) ||
5223  {
5224  MHD_DLOG (daemon,
5225  _("MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5226  opt);
5227  }
5228  else
5229  {
5230  MHD_DLOG (daemon,
5231  _("Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5232  opt);
5233  }
5234 #endif
5235  return MHD_NO;
5236  }
5237  }
5238  return MHD_YES;
5239 }
5240 
5241 
5242 #ifdef EPOLL_SUPPORT
5243 static int
5244 setup_epoll_fd (struct MHD_Daemon *daemon)
5245 {
5246  int fd;
5247 
5248 #ifndef HAVE_MESSAGES
5249  (void)daemon; /* Mute compiler warning. */
5250 #endif /* ! HAVE_MESSAGES */
5251 
5252 #ifdef USE_EPOLL_CREATE1
5253  fd = epoll_create1 (EPOLL_CLOEXEC);
5254 #else /* ! USE_EPOLL_CREATE1 */
5255  fd = epoll_create (MAX_EVENTS);
5256 #endif /* ! USE_EPOLL_CREATE1 */
5257  if (MHD_INVALID_SOCKET == fd)
5258  {
5259 #ifdef HAVE_MESSAGES
5260  MHD_DLOG (daemon,
5261  _("Call to epoll_create1 failed: %s\n"),
5263 #endif
5264  return MHD_INVALID_SOCKET;
5265  }
5266 #if !defined(USE_EPOLL_CREATE1)
5268  {
5269 #ifdef HAVE_MESSAGES
5270  MHD_DLOG (daemon,
5271  _("Failed to set noninheritable mode on epoll FD.\n"));
5272 #endif
5273  }
5274 #endif /* ! USE_EPOLL_CREATE1 */
5275  return fd;
5276 }
5277 
5278 
5288 static int
5289 setup_epoll_to_listen (struct MHD_Daemon *daemon)
5290 {
5291  struct epoll_event event;
5292  MHD_socket ls;
5293 
5294  daemon->epoll_fd = setup_epoll_fd (daemon);
5295  if (-1 == daemon->epoll_fd)
5296  return MHD_NO;
5297 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5298  if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
5299  {
5300  daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5301  if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
5302  return MHD_NO;
5303  }
5304 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5305  if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) ||
5306  (daemon->was_quiesced) )
5307  return MHD_YES; /* non-listening daemon */
5308  event.events = EPOLLIN;
5309  event.data.ptr = daemon;
5310  if (0 != epoll_ctl (daemon->epoll_fd,
5311  EPOLL_CTL_ADD,
5312  ls,
5313  &event))
5314  {
5315 #ifdef HAVE_MESSAGES
5316  MHD_DLOG (daemon,
5317  _("Call to epoll_ctl failed: %s\n"),
5319 #endif
5320  return MHD_NO;
5321  }
5322  daemon->listen_socket_in_epoll = true;
5323  if (MHD_ITC_IS_VALID_(daemon->itc))
5324  {
5325  event.events = EPOLLIN;
5326  event.data.ptr = (void *) epoll_itc_marker;
5327  if (0 != epoll_ctl (daemon->epoll_fd,
5328  EPOLL_CTL_ADD,
5329  MHD_itc_r_fd_ (daemon->itc),
5330  &event))
5331  {
5332 #ifdef HAVE_MESSAGES
5333  MHD_DLOG (daemon,
5334  _("Call to epoll_ctl failed: %s\n"),
5336 #endif
5337  return MHD_NO;
5338  }
5339  }
5340  return MHD_YES;
5341 }
5342 #endif
5343 
5344 
5366 struct MHD_Daemon *
5367 MHD_start_daemon_va (unsigned int flags,
5368  uint16_t port,
5370  void *apc_cls,
5372  void *dh_cls,
5373  va_list ap)
5374 {
5375  const MHD_SCKT_OPT_BOOL_ on = 1;
5376  struct MHD_Daemon *daemon;
5378  struct sockaddr_in servaddr4;
5379 #if HAVE_INET6
5380  struct sockaddr_in6 servaddr6;
5381 #endif
5382  const struct sockaddr *servaddr = NULL;
5383  socklen_t addrlen;
5384  unsigned int i;
5385  enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
5386  enum MHD_FLAG *pflags;
5387 
5389  eflags = (enum MHD_FLAG) flags;
5390  pflags = &eflags;
5391 #ifndef HAVE_INET6
5392  if (0 != (*pflags & MHD_USE_IPv6))
5393  return NULL;
5394 #endif
5395 #ifndef HAVE_POLL
5396  if (0 != (*pflags & MHD_USE_POLL))
5397  return NULL;
5398 #endif
5399 #ifndef EPOLL_SUPPORT
5400  if (0 != (*pflags & MHD_USE_EPOLL))
5401  return NULL;
5402 #endif /* ! EPOLL_SUPPORT */
5403 #ifndef HTTPS_SUPPORT
5404  if (0 != (*pflags & MHD_USE_TLS))
5405  return NULL;
5406 #endif /* ! HTTPS_SUPPORT */
5407 #ifndef TCP_FASTOPEN
5408  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
5409  return NULL;
5410 #endif
5411  if (0 != (*pflags & MHD_ALLOW_UPGRADE))
5412  {
5413 #ifdef UPGRADE_SUPPORT
5414  *pflags |= MHD_ALLOW_SUSPEND_RESUME;
5415 #else /* ! UPGRADE_SUPPORT */
5416  return NULL;
5417 #endif /* ! UPGRADE_SUPPORT */
5418  }
5419  if (NULL == dh)
5420  return NULL;
5421 
5422  /* Check for invalid combinations of flags. */
5423  if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) ||
5424  ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))) ||
5425  ((0 != (*pflags & MHD_USE_POLL)) &&
5427  ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) )
5428  return NULL;
5429 
5430  if (0 != (*pflags & MHD_USE_AUTO))
5431  {
5432  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
5433  {
5434  /* Thread per connection with internal polling thread. */
5435 #ifdef HAVE_POLL
5436  *pflags |= MHD_USE_POLL;
5437 #else /* ! HAVE_POLL */
5438  /* use select() - do not modify flags */
5439 #endif /* ! HAVE_POLL */
5440  }
5441  else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5442  {
5443  /* Internal polling thread. */
5444 #if defined(EPOLL_SUPPORT)
5445  *pflags |= MHD_USE_EPOLL;
5446 #elif defined(HAVE_POLL)
5447  *pflags |= MHD_USE_POLL;
5448 #else /* !HAVE_POLL && !EPOLL_SUPPORT */
5449  /* use select() - do not modify flags */
5450 #endif /* !HAVE_POLL && !EPOLL_SUPPORT */
5451  }
5452  else
5453  {
5454  /* Internal threads are not used - "external" polling mode. */
5455 #if defined(EPOLL_SUPPORT)
5456  *pflags |= MHD_USE_EPOLL;
5457 #else /* ! EPOLL_SUPPORT */
5458  /* use select() - do not modify flags */
5459 #endif /* ! EPOLL_SUPPORT */
5460  }
5461  }
5462 
5463  if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
5464  return NULL;
5465 #ifdef EPOLL_SUPPORT
5466  daemon->epoll_fd = -1;
5467 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5468  daemon->epoll_upgrade_fd = -1;
5469 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5470 #endif
5471  /* try to open listen socket */
5472 #ifdef HTTPS_SUPPORT
5473  daemon->priority_cache = NULL;
5474  if (0 != (*pflags & MHD_USE_TLS))
5475  {
5476  gnutls_priority_init (&daemon->priority_cache,
5477  "@SYSTEM",
5478  NULL);
5479  }
5480 #endif /* HTTPS_SUPPORT */
5481  daemon->listen_fd = MHD_INVALID_SOCKET;
5482  daemon->listening_address_reuse = 0;
5483  daemon->options = *pflags;
5484  pflags = &daemon->options;
5485  daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 : 0;
5486  daemon->port = port;
5487  daemon->apc = apc;
5488  daemon->apc_cls = apc_cls;
5489  daemon->default_handler = dh;
5490  daemon->default_handler_cls = dh_cls;
5491  daemon->connections = 0;
5493  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
5494  daemon->pool_increment = MHD_BUF_INC_SIZE;
5496  daemon->connection_timeout = 0; /* no timeout */
5497  MHD_itc_set_invalid_ (daemon->itc);
5498 #ifdef SOMAXCONN
5499  daemon->listen_backlog_size = SOMAXCONN;
5500 #else /* !SOMAXCONN */
5501  daemon->listen_backlog_size = 511; /* should be safe value */
5502 #endif /* !SOMAXCONN */
5503 #ifdef HAVE_MESSAGES
5504  daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
5505  daemon->custom_error_log_cls = stderr;
5506 #endif
5507  if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
5508  (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
5509  {
5510 #ifdef HAVE_MESSAGES
5511  MHD_DLOG (daemon,
5512  _("Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
5513  "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
5514  "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5515 #endif
5517  }
5518  if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5519  *pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */
5520  else
5521  {
5522 #ifdef HAVE_LISTEN_SHUTDOWN
5523  if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
5524 #endif
5525  *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */
5526  }
5527 #ifdef DAUTH_SUPPORT
5528  daemon->digest_auth_rand_size = 0;
5529  daemon->digest_auth_random = NULL;
5530  daemon->nonce_nc_size = 4; /* tiny */
5531 #endif
5532 #ifdef HTTPS_SUPPORT
5533  if (0 != (*pflags & MHD_USE_TLS))
5534  {
5535  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5536  }
5537 #endif /* HTTPS_SUPPORT */
5538 
5539 
5540  if (MHD_YES != parse_options_va (daemon,
5541  &servaddr,
5542  ap))
5543  {
5544 #ifdef HTTPS_SUPPORT
5545  if ( (0 != (*pflags & MHD_USE_TLS)) &&
5546  (NULL != daemon->priority_cache) )
5547  gnutls_priority_deinit (daemon->priority_cache);
5548 #endif /* HTTPS_SUPPORT */
5549  free (daemon);
5550  return NULL;
5551  }
5552 
5553  if ( (NULL != daemon->notify_completed) &&
5554  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
5555  *pflags |= MHD_USE_ITC; /* requires ITC */
5556 
5557 #ifndef NDEBUG
5558 #ifdef HAVE_MESSAGES
5559  MHD_DLOG (daemon,
5560  _("Using debug build of libmicrohttpd.\n") );
5561 #endif /* HAVE_MESSAGES */
5562 #endif /* ! NDEBUG */
5563 
5564  if ( (0 != (*pflags & MHD_USE_ITC)) &&
5565  (0 == daemon->worker_pool_size) )
5566  {
5567  if (! MHD_itc_init_ (daemon->itc))
5568  {
5569 #ifdef HAVE_MESSAGES
5570  MHD_DLOG (daemon,
5571  _("Failed to create inter-thread communication channel: %s\n"),
5572  MHD_itc_last_strerror_ ());
5573 #endif
5574 #ifdef HTTPS_SUPPORT
5575  if (NULL != daemon->priority_cache)
5576  gnutls_priority_deinit (daemon->priority_cache);
5577 #endif /* HTTPS_SUPPORT */
5578  free (daemon);
5579  return NULL;
5580  }
5581  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
5582  (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc),
5583  NULL)) )
5584  {
5585 #ifdef HAVE_MESSAGES
5586  MHD_DLOG (daemon,
5587  _("file descriptor for inter-thread communication channel exceeds maximum value\n"));
5588 #endif
5589  MHD_itc_destroy_chk_ (daemon->itc);
5590 #ifdef HTTPS_SUPPORT
5591  if (NULL != daemon->priority_cache)
5592  gnutls_priority_deinit (daemon->priority_cache);
5593 #endif /* HTTPS_SUPPORT */
5594  free (daemon);
5595  return NULL;
5596  }
5597  }
5598 
5599 #ifdef DAUTH_SUPPORT
5600  if (daemon->nonce_nc_size > 0)
5601  {
5602  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
5603  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
5604  {
5605 #ifdef HAVE_MESSAGES
5606  MHD_DLOG (daemon,
5607  _("Specified value for NC_SIZE too large\n"));
5608 #endif
5609 #ifdef HTTPS_SUPPORT
5610  if (0 != (*pflags & MHD_USE_TLS))
5611  gnutls_priority_deinit (daemon->priority_cache);
5612 #endif /* HTTPS_SUPPORT */
5613  free (daemon);
5614  return NULL;
5615  }
5616  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
5617  if (NULL == daemon->nnc)
5618  {
5619 #ifdef HAVE_MESSAGES
5620  MHD_DLOG (daemon,
5621  _("Failed to allocate memory for nonce-nc map: %s\n"),
5622  MHD_strerror_ (errno));
5623 #endif
5624 #ifdef HTTPS_SUPPORT
5625  if (0 != (*pflags & MHD_USE_TLS))
5626  gnutls_priority_deinit (daemon->priority_cache);
5627 #endif /* HTTPS_SUPPORT */
5628  free (daemon);
5629  return NULL;
5630  }
5631  }
5632 
5633  if (! MHD_mutex_init_ (&daemon->nnc_lock))
5634  {
5635 #ifdef HAVE_MESSAGES
5636  MHD_DLOG (daemon,
5637  _("MHD failed to initialize nonce-nc mutex\n"));
5638 #endif
5639 #ifdef HTTPS_SUPPORT
5640  if (0 != (*pflags & MHD_USE_TLS))
5641  gnutls_priority_deinit (daemon->priority_cache);
5642 #endif /* HTTPS_SUPPORT */
5643  free (daemon->nnc);
5644  free (daemon);
5645  return NULL;
5646  }
5647 #endif
5648 
5649  /* Thread pooling currently works only with internal select thread model */
5650  if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
5651  (daemon->worker_pool_size > 0) )
5652  {
5653 #ifdef HAVE_MESSAGES
5654  MHD_DLOG (daemon,
5655  _("MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5656 #endif
5657  goto free_and_fail;
5658  }
5659 
5660  if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
5661  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
5662  {
5663  /* try to open listen socket */
5664  int domain;
5665 
5666 #ifdef HAVE_INET6
5667  domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5668 #else /* ! HAVE_INET6 */
5669  if (*pflags & MHD_USE_IPv6)
5670  goto free_and_fail;
5671  domain = PF_INET;
5672 #endif /* ! HAVE_INET6 */
5673 
5674  listen_fd = MHD_socket_create_listen_(domain);
5675  if (MHD_INVALID_SOCKET == listen_fd)
5676  {
5677 #ifdef HAVE_MESSAGES
5678  MHD_DLOG (daemon,
5679  _("Failed to create socket for listening: %s\n"),
5681 #endif
5682  goto free_and_fail;
5683  }
5684 
5685  /* Apply the socket options according to listening_address_reuse. */
5686  if (0 == daemon->listening_address_reuse)
5687  {
5688 #ifndef MHD_WINSOCK_SOCKETS
5689  /* No user requirement, use "traditional" default SO_REUSEADDR
5690  * on non-W32 platforms, and do not fail if it doesn't work.
5691  * Don't use it on W32, because on W32 it will allow multiple
5692  * bind to the same address:port, like SO_REUSEPORT on others. */
5693  if (0 > setsockopt (listen_fd,
5694  SOL_SOCKET,
5695  SO_REUSEADDR,
5696  (void*)&on, sizeof (on)))
5697  {
5698 #ifdef HAVE_MESSAGES
5699  MHD_DLOG (daemon,
5700  _("setsockopt failed: %s\n"),
5702 #endif
5703  }
5704 #endif /* ! MHD_WINSOCK_SOCKETS */
5705  }
5706  else if (daemon->listening_address_reuse > 0)
5707  {
5708  /* User requested to allow reusing listening address:port. */
5709 #ifndef MHD_WINSOCK_SOCKETS
5710  /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
5711  * it doesn't work. */
5712  if (0 > setsockopt (listen_fd,
5713  SOL_SOCKET,
5714  SO_REUSEADDR,
5715  (void*)&on, sizeof (on)))
5716  {
5717 #ifdef HAVE_MESSAGES
5718  MHD_DLOG (daemon,
5719  _("setsockopt failed: %s\n"),
5721 #endif
5722  }
5723 #endif /* ! MHD_WINSOCK_SOCKETS */
5724  /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
5725  * Fail if SO_REUSEPORT is not defined or setsockopt fails.
5726  */
5727  /* SO_REUSEADDR on W32 has the same semantics
5728  as SO_REUSEPORT on BSD/Linux */
5729 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
5730  if (0 > setsockopt (listen_fd,
5731  SOL_SOCKET,
5732 #ifndef MHD_WINSOCK_SOCKETS
5733  SO_REUSEPORT,
5734 #else /* MHD_WINSOCK_SOCKETS */
5735  SO_REUSEADDR,
5736 #endif /* MHD_WINSOCK_SOCKETS */
5737  (void *) &on,
5738  sizeof (on)))
5739  {
5740 #ifdef HAVE_MESSAGES
5741  MHD_DLOG (daemon,
5742  _("setsockopt failed: %s\n"),
5744 #endif
5745  goto free_and_fail;
5746  }
5747 #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
5748  /* we're supposed to allow address:port re-use, but
5749  on this platform we cannot; fail hard */
5750 #ifdef HAVE_MESSAGES
5751  MHD_DLOG (daemon,
5752  _("Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5753 #endif
5754  goto free_and_fail;
5755 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
5756  }
5757  else /* if (daemon->listening_address_reuse < 0) */
5758  {
5759  /* User requested to disallow reusing listening address:port.
5760  * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
5761  * is used and Solaris with SO_EXCLBIND.
5762  * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
5763  * or setsockopt fails.
5764  */
5765 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
5766  (defined(__sun) && defined(SO_EXCLBIND))
5767  if (0 > setsockopt (listen_fd,
5768  SOL_SOCKET,
5769 #ifdef SO_EXCLUSIVEADDRUSE
5770  SO_EXCLUSIVEADDRUSE,
5771 #else /* SO_EXCLBIND */
5772  SO_EXCLBIND,
5773 #endif /* SO_EXCLBIND */
5774  (void *) &on,
5775  sizeof (on)))
5776  {
5777 #ifdef HAVE_MESSAGES
5778  MHD_DLOG (daemon,
5779  _("setsockopt failed: %s\n"),
5781 #endif
5782  goto free_and_fail;
5783  }
5784 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
5785 #ifdef HAVE_MESSAGES
5786  MHD_DLOG (daemon,
5787  _("Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
5788 #endif
5789  goto free_and_fail;
5790 #endif /* MHD_WINSOCK_SOCKETS */
5791  }
5792 
5793  /* check for user supplied sockaddr */
5794 #if HAVE_INET6
5795  if (0 != (*pflags & MHD_USE_IPv6))
5796  addrlen = sizeof (struct sockaddr_in6);
5797  else
5798 #endif
5799  addrlen = sizeof (struct sockaddr_in);
5800  if (NULL == servaddr)
5801  {
5802 #if HAVE_INET6
5803  if (0 != (*pflags & MHD_USE_IPv6))
5804  {
5805 #ifdef IN6ADDR_ANY_INIT
5806  static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
5807 #endif
5808  memset (&servaddr6,
5809  0,
5810  sizeof (struct sockaddr_in6));
5811  servaddr6.sin6_family = AF_INET6;
5812  servaddr6.sin6_port = htons (port);
5813 #ifdef IN6ADDR_ANY_INIT
5814  servaddr6.sin6_addr = static_in6any;
5815 #endif
5816 #if HAVE_SOCKADDR_IN_SIN_LEN
5817  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
5818 #endif
5819  servaddr = (struct sockaddr *) &servaddr6;
5820  }
5821  else
5822 #endif
5823  {
5824  memset (&servaddr4,
5825  0,
5826  sizeof (struct sockaddr_in));
5827  servaddr4.sin_family = AF_INET;
5828  servaddr4.sin_port = htons (port);
5829  if (0 != INADDR_ANY)
5830  servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
5831 #if HAVE_SOCKADDR_IN_SIN_LEN
5832  servaddr4.sin_len = sizeof (struct sockaddr_in);
5833 #endif
5834  servaddr = (struct sockaddr *) &servaddr4;
5835  }
5836  }
5837  daemon->listen_fd = listen_fd;
5838 
5839  if (0 != (*pflags & MHD_USE_IPv6))
5840  {
5841 #ifdef IPPROTO_IPV6
5842 #ifdef IPV6_V6ONLY
5843  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
5844  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
5845  and may also be missing on older POSIX systems; good luck if you have any of those,
5846  your IPv6 socket may then also bind against IPv4 anyway... */
5847  const MHD_SCKT_OPT_BOOL_ v6_only =
5848  (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
5849  if (0 > setsockopt (listen_fd,
5850  IPPROTO_IPV6, IPV6_V6ONLY,
5851  (const void *) &v6_only,
5852  sizeof (v6_only)))
5853  {
5854 #ifdef HAVE_MESSAGES
5855  MHD_DLOG (daemon,
5856  _("setsockopt failed: %s\n"),
5858 #endif
5859  }
5860 #endif
5861 #endif
5862  }
5863  if (-1 == bind (listen_fd, servaddr, addrlen))
5864  {
5865 #ifdef HAVE_MESSAGES
5866  MHD_DLOG (daemon,
5867  _("Failed to bind to port %u: %s\n"),
5868  (unsigned int) port,
5870 #endif
5871  MHD_socket_close_chk_ (listen_fd);
5872  goto free_and_fail;
5873  }
5874 #ifdef TCP_FASTOPEN
5875  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
5876  {
5877  if (0 == daemon->fastopen_queue_size)
5878  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
5879  if (0 != setsockopt (listen_fd,
5880  IPPROTO_TCP,
5881  TCP_FASTOPEN,
5882  (const void*)&daemon->fastopen_queue_size,
5883  sizeof (daemon->fastopen_queue_size)))
5884  {
5885 #ifdef HAVE_MESSAGES
5886  MHD_DLOG (daemon,
5887  _("setsockopt failed: %s\n"),
5889 #endif
5890  }
5891  }
5892 #endif
5893  if (listen (listen_fd,
5894  daemon->listen_backlog_size) < 0)
5895  {
5896 #ifdef HAVE_MESSAGES
5897  MHD_DLOG (daemon,
5898  _("Failed to listen for connections: %s\n"),
5900 #endif
5901  MHD_socket_close_chk_ (listen_fd);
5902  goto free_and_fail;
5903  }
5904  }
5905  else
5906  {
5907  listen_fd = daemon->listen_fd;
5908  }
5909 
5910  if ( (0 == daemon->port) &&
5911  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
5912  { /* Get port number. */
5913  struct sockaddr_storage servaddr;
5914 
5915  memset (&servaddr,
5916  0,
5917  sizeof (struct sockaddr_storage));
5918  addrlen = sizeof (servaddr);
5919  if (0 != getsockname (listen_fd,
5920  (struct sockaddr *) &servaddr,
5921  &addrlen))
5922  {
5923 #ifdef HAVE_MESSAGES
5924  MHD_DLOG (daemon,
5925  _("Failed to get listen port number: %s\n"),
5927 #endif /* HAVE_MESSAGES */
5928  }
5929 #ifdef MHD_POSIX_SOCKETS
5930  else if (sizeof (servaddr) < addrlen)
5931  {
5932  /* should be impossible with `struct sockaddr_storage` */
5933 #ifdef HAVE_MESSAGES
5934  MHD_DLOG (daemon,
5935  _("Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
5936 #endif /* HAVE_MESSAGES */
5937  }
5938 #endif /* MHD_POSIX_SOCKETS */
5939  else
5940  {
5941  switch (servaddr.ss_family)
5942  {
5943  case AF_INET:
5944  {
5945  struct sockaddr_in *s4 = (struct sockaddr_in *) &servaddr;
5946 
5947  daemon->port = ntohs (s4->sin_port);
5948  break;
5949  }
5950 #ifdef HAVE_INET6
5951  case AF_INET6:
5952  {
5953  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &servaddr;
5954 
5955  daemon->port = ntohs(s6->sin6_port);
5956  mhd_assert (0 != (*pflags & MHD_USE_IPv6));
5957  break;
5958  }
5959 #endif /* HAVE_INET6 */
5960 #ifdef AF_UNIX
5961  case AF_UNIX:
5962  daemon->port = 0; /* special value for UNIX domain sockets */
5963  break;
5964 #endif
5965  default:
5966 #ifdef HAVE_MESSAGES
5967  MHD_DLOG (daemon,
5968  _("Unknown address family!\n"));
5969 #endif
5970  daemon->port = 0; /* ugh */
5971  break;
5972  }
5973  }
5974  }
5975 
5976  if ( (MHD_INVALID_SOCKET != listen_fd) &&
5977  (! MHD_socket_nonblocking_ (listen_fd)) )
5978  {
5979 #ifdef HAVE_MESSAGES
5980  MHD_DLOG (daemon,
5981  _("Failed to set nonblocking mode on listening socket: %s\n"),
5983 #endif
5984  if (0 != (*pflags & MHD_USE_EPOLL) ||
5985  daemon->worker_pool_size > 0)
5986  {
5987  /* Accept must be non-blocking. Multiple children may wake up
5988  * to handle a new connection, but only one will win the race.
5989  * The others must immediately return. */
5990  MHD_socket_close_chk_ (listen_fd);
5991  goto free_and_fail;
5992  }
5993  }
5994  if ( (MHD_INVALID_SOCKET != listen_fd) &&
5995  (! MHD_SCKT_FD_FITS_FDSET_(listen_fd,
5996  NULL)) &&
5997  (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
5998  {
5999 #ifdef HAVE_MESSAGES
6000  MHD_DLOG (daemon,
6001  _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6002  listen_fd,
6003  FD_SETSIZE);
6004 #endif
6005  MHD_socket_close_chk_ (listen_fd);
6006  goto free_and_fail;
6007  }
6008 
6009 #ifdef EPOLL_SUPPORT
6010  if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
6011  (0 == daemon->worker_pool_size) )
6012  {
6013  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6014  {
6015 #ifdef HAVE_MESSAGES
6016  MHD_DLOG (daemon,
6017  _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6018 #endif
6019  goto free_and_fail;
6020  }
6021  if (MHD_YES != setup_epoll_to_listen (daemon))
6022  goto free_and_fail;
6023  }
6024 #endif /* EPOLL_SUPPORT */
6025 
6026  if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
6027  {
6028 #ifdef HAVE_MESSAGES
6029  MHD_DLOG (daemon,
6030  _("MHD failed to initialize IP connection limit mutex\n"));
6031 #endif
6032  if (MHD_INVALID_SOCKET != listen_fd)
6033  MHD_socket_close_chk_ (listen_fd);
6034  goto free_and_fail;
6035  }
6036  if (0 == daemon->worker_pool_size)
6037  { /* Initialise connection mutex only if this daemon will handle
6038  * any connections by itself. */
6039  if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
6040  {
6041 #ifdef HAVE_MESSAGES
6042  MHD_DLOG (daemon,
6043  _("MHD failed to initialize IP connection limit mutex\n"));
6044 #endif
6046  if (MHD_INVALID_SOCKET != listen_fd)
6047  MHD_socket_close_chk_ (listen_fd);
6048  goto free_and_fail;
6049  }
6050  }
6051 
6052 #ifdef HTTPS_SUPPORT
6053  /* initialize HTTPS daemon certificate aspects & send / recv functions */
6054  if ( (0 != (*pflags & MHD_USE_TLS)) &&
6055  (0 != MHD_TLS_init (daemon)) )
6056  {
6057 #ifdef HAVE_MESSAGES
6058  MHD_DLOG (daemon,
6059  _("Failed to initialize TLS support\n"));
6060 #endif
6061  if (MHD_INVALID_SOCKET != listen_fd)
6062  MHD_socket_close_chk_ (listen_fd);
6063  if (0 == daemon->worker_pool_size)
6066  goto free_and_fail;
6067  }
6068 #endif /* HTTPS_SUPPORT */
6069  if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
6070  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6071  {
6072  if (0 == daemon->worker_pool_size)
6073  {
6074  if (! MHD_create_named_thread_ (&daemon->pid,
6075  (*pflags & MHD_USE_THREAD_PER_CONNECTION) ?
6076  "MHD-listen" : "MHD-single",
6077  daemon->thread_stack_size,
6079  daemon) )
6080  {
6081 #ifdef HAVE_MESSAGES
6082  MHD_DLOG (daemon,
6083  _("Failed to create listen thread: %s\n"),
6084  MHD_strerror_ (errno));
6085 #endif
6088  if (MHD_INVALID_SOCKET != listen_fd)
6089  MHD_socket_close_chk_ (listen_fd);
6090  goto free_and_fail;
6091  }
6092  }
6093  else /* 0 < daemon->worker_pool_size */
6094  {
6095  /* Coarse-grained count of connections per thread (note error
6096  * due to integer division). Also keep track of how many
6097  * connections are leftover after an equal split. */
6098  unsigned int conns_per_thread = daemon->connection_limit
6099  / daemon->worker_pool_size;
6100  unsigned int leftover_conns = daemon->connection_limit
6101  % daemon->worker_pool_size;
6102 
6103  i = 0; /* we need this in case fcntl or malloc fails */
6104 
6105  /* Allocate memory for pooled objects */
6106  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
6107  * daemon->worker_pool_size);
6108  if (NULL == daemon->worker_pool)
6109  goto thread_failed;
6110 
6111  /* Start the workers in the pool */
6112  for (i = 0; i < daemon->worker_pool_size; ++i)
6113  {
6114  /* Create copy of the Daemon object for each worker */
6115  struct MHD_Daemon *d = &daemon->worker_pool[i];
6116 
6117  memcpy (d, daemon, sizeof (struct MHD_Daemon));
6118  /* Adjust pooling params for worker daemons; note that memcpy()
6119  has already copied MHD_USE_INTERNAL_POLLING_THREAD thread model into
6120  the worker threads. */
6121  d->master = daemon;
6122  d->worker_pool_size = 0;
6123  d->worker_pool = NULL;
6124 
6125  if (0 != (*pflags & MHD_USE_ITC))
6126  {
6127  if (! MHD_itc_init_ (d->itc))
6128  {
6129 #ifdef HAVE_MESSAGES
6130  MHD_DLOG (daemon,
6131  _("Failed to create worker inter-thread communication channel: %s\n"),
6132  MHD_itc_last_strerror_() );
6133 #endif
6134  goto thread_failed;
6135  }
6136  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
6137  (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (d->itc),
6138  NULL)) )
6139  {
6140 #ifdef HAVE_MESSAGES
6141  MHD_DLOG (daemon,
6142  _("File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6143 #endif
6145  goto thread_failed;
6146  }
6147  }
6148  else
6149  MHD_itc_set_invalid_ (d->itc);
6150 
6151  /* Divide available connections evenly amongst the threads.
6152  * Thread indexes in [0, leftover_conns) each get one of the
6153  * leftover connections. */
6154  d->connection_limit = conns_per_thread;
6155  if (i < leftover_conns)
6156  ++d->connection_limit;
6157 #ifdef EPOLL_SUPPORT
6158  if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
6159  (MHD_YES != setup_epoll_to_listen (d)) )
6160  goto thread_failed;
6161 #endif
6162  /* Must init cleanup connection mutex for each worker */
6163  if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
6164  {
6165 #ifdef HAVE_MESSAGES
6166  MHD_DLOG (daemon,
6167  _("MHD failed to initialize cleanup connection mutex\n"));
6168 #endif
6169  goto thread_failed;
6170  }
6171 
6172  /* Spawn the worker thread */
6173  if (! MHD_create_named_thread_ (&d->pid,
6174  "MHD-worker",
6175  daemon->thread_stack_size,
6177  d))
6178  {
6179 #ifdef HAVE_MESSAGES
6180  MHD_DLOG (daemon,
6181  _("Failed to create pool thread: %s\n"),
6182  MHD_strerror_ (errno));
6183 #endif
6184  /* Free memory for this worker; cleanup below handles
6185  * all previously-created workers. */
6187  goto thread_failed;
6188  }
6189  }
6190  }
6191  }
6192 #ifdef HTTPS_SUPPORT
6193  /* API promises to never use the password after initialization,
6194  so we additionally NULL it here to not deref a dangling pointer. */
6195  daemon->https_key_password = NULL;
6196 #endif /* HTTPS_SUPPORT */
6197 
6198  return daemon;
6199 
6200 thread_failed:
6201  /* If no worker threads created, then shut down normally. Calling
6202  MHD_stop_daemon (as we do below) doesn't work here since it
6203  assumes a 0-sized thread pool means we had been in the default
6204  MHD_USE_INTERNAL_POLLING_THREAD mode. */
6205  if (0 == i)
6206  {
6210  if (NULL != daemon->worker_pool)
6211  free (daemon->worker_pool);
6212  goto free_and_fail;
6213  }
6214 
6215  /* Shutdown worker threads we've already created. Pretend
6216  as though we had fully initialized our daemon, but
6217  with a smaller number of threads than had been
6218  requested. */
6219  daemon->worker_pool_size = i;
6220  MHD_stop_daemon (daemon);
6221  return NULL;
6222 
6223  free_and_fail:
6224  /* clean up basic memory state in 'daemon' and return NULL to
6225  indicate failure */
6226 #ifdef EPOLL_SUPPORT
6227 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6228  if (daemon->upgrade_fd_in_epoll)
6229  {
6230  if (0 != epoll_ctl (daemon->epoll_fd,
6231  EPOLL_CTL_DEL,
6232  daemon->epoll_upgrade_fd,
6233  NULL))
6234  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
6235  daemon->upgrade_fd_in_epoll = false;
6236  }
6237 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6238  if (-1 != daemon->epoll_fd)
6239  close (daemon->epoll_fd);
6240 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6241  if (-1 != daemon->epoll_upgrade_fd)
6242  close (daemon->epoll_upgrade_fd);
6243 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6244 #endif /* EPOLL_SUPPORT */
6245 #ifdef DAUTH_SUPPORT
6246  free (daemon->nnc);
6247  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6248 #endif
6249 #ifdef HTTPS_SUPPORT
6250  if (0 != (*pflags & MHD_USE_TLS))
6251  gnutls_priority_deinit (daemon->priority_cache);
6252 #endif /* HTTPS_SUPPORT */
6253  if (MHD_ITC_IS_VALID_(daemon->itc))
6254  MHD_itc_destroy_chk_ (daemon->itc);
6255  free (daemon);
6256  return NULL;
6257 }
6258 
6259 
6268 static void
6270 {
6271  struct MHD_Connection *pos;
6272  const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
6273 #ifdef UPGRADE_SUPPORT
6274  const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
6275 #endif /* UPGRADE_SUPPORT */
6276 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6277  struct MHD_UpgradeResponseHandle *urh;
6278  struct MHD_UpgradeResponseHandle *urhn;
6279  const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
6280 
6281  mhd_assert (NULL == daemon->worker_pool);
6282  mhd_assert (daemon->shutdown);
6283  /* give upgraded HTTPS connections a chance to finish */
6284  /* 'daemon->urh_head' is not used in thread-per-connection mode. */
6285  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
6286  {
6287  urhn = urh->prev;
6288  /* call generic forwarding function for passing data
6289  with chance to detect that application is done. */
6290  process_urh (urh);
6291  MHD_connection_finish_forward_ (urh->connection);
6292  urh->clean_ready = true;
6293  /* Resuming will move connection to cleanup list. */
6294  MHD_resume_connection(urh->connection);
6295  }
6296 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6297 
6298  /* Give suspended connections a chance to resume to avoid
6299  running into the check for there not being any suspended
6300  connections left in case of a tight race with a recently
6301  resumed connection. */
6302  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
6303  {
6304  daemon->resuming = true; /* Force check for pending resume. */
6306  }
6307  /* first, make sure all threads are aware of shutdown; need to
6308  traverse DLLs in peace... */
6310 #ifdef UPGRADE_SUPPORT
6311  if (upg_allowed)
6312  {
6313  struct MHD_Connection * susp;
6314 
6316  while (NULL != susp)
6317  {
6318  if (NULL == susp->urh) /* "Upgraded" connection? */
6319  MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
6320 #ifdef HTTPS_SUPPORT
6321  else if (used_tls &&
6322  used_thr_p_c &&
6323  (! susp->urh->clean_ready) )
6324  shutdown (susp->urh->app.socket,
6325  SHUT_RDWR); /* Wake thread by shutdown of app socket. */
6326 #endif /* HTTPS_SUPPORT */
6327  else
6328  {
6329 #ifdef HAVE_MESSAGES
6330  if (! susp->urh->was_closed)
6331  MHD_DLOG (daemon,
6332  _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6333 #endif
6334  susp->urh->was_closed = true;
6335  /* If thread-per-connection is used, connection's thread
6336  * may still processing "upgrade" (exiting). */
6337  if (! used_thr_p_c)
6339  /* Do not use MHD_resume_connection() as mutex is
6340  * already locked. */
6341  susp->resuming = true;
6342  daemon->resuming = true;
6343  }
6344  susp = susp->prev;
6345  }
6346  }
6347  else /* This 'else' is combined with next 'if' */
6348 #endif /* UPGRADE_SUPPORT */
6350  MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
6351  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
6352  {
6353  shutdown (pos->socket_fd,
6354  SHUT_RDWR);
6355 #if MHD_WINSOCK_SOCKETS
6356  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6357  (MHD_ITC_IS_VALID_(daemon->itc)) &&
6358  (! MHD_itc_activate_ (daemon->itc, "e")) )
6359  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
6360 #endif
6361  }
6362 
6363  /* now, collect per-connection threads */
6364  if (used_thr_p_c)
6365  {
6366  pos = daemon->connections_tail;
6367  while (NULL != pos)
6368  {
6369  if (! pos->thread_joined)
6370  {
6372  if (! MHD_join_thread_ (pos->pid.handle))
6373  MHD_PANIC (_("Failed to join a thread\n"));
6375  pos->thread_joined = true;
6376  /* The thread may have concurrently modified the DLL,
6377  need to restart from the beginning */
6378  pos = daemon->connections_tail;
6379  continue;
6380  }
6381  pos = pos->prev;
6382  }
6383  }
6385 
6386 #ifdef UPGRADE_SUPPORT
6387  /* Finished threads with "upgraded" connections need to be moved
6388  * to cleanup list by resume_suspended_connections(). */
6389  /* "Upgraded" connections that were not closed explicitly by
6390  * application should be moved to cleanup list too. */
6391  if (upg_allowed)
6392  {
6393  daemon->resuming = true; /* Force check for pending resume. */
6395  }
6396 #endif /* UPGRADE_SUPPORT */
6397 
6398  /* now that we're alone, move everyone to cleanup */
6399  while (NULL != (pos = daemon->connections_tail))
6400  {
6401  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6402  (! pos->thread_joined) )
6403  MHD_PANIC (_("Failed to join a thread\n"));
6404  close_connection (pos);
6405  }
6407 }
6408 
6409 
6416 void
6418 {
6419  MHD_socket fd;
6420  unsigned int i;
6421 
6422  if (NULL == daemon)
6423  return;
6424 
6425  daemon->shutdown = true;
6426  if (daemon->was_quiesced)
6427  fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
6428  else
6429  fd = daemon->listen_fd;
6430 
6431  if (NULL != daemon->worker_pool)
6432  { /* Master daemon with worker pool. */
6435 
6436  /* Let workers shutdown in parallel. */
6437  for (i = 0; i < daemon->worker_pool_size; ++i)
6438  {
6439  daemon->worker_pool[i].shutdown = true;
6440  if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
6441  {
6442  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
6443  "e"))
6444  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
6445  }
6446  else
6448  }
6449 #ifdef HAVE_LISTEN_SHUTDOWN
6450  if (MHD_INVALID_SOCKET != fd)
6451  {
6452  (void) shutdown (fd,
6453  SHUT_RDWR);
6454  }
6455 #endif /* HAVE_LISTEN_SHUTDOWN */
6456  for (i = 0; i < daemon->worker_pool_size; ++i)
6457  {
6459  }
6460  free (daemon->worker_pool);
6462 #ifdef EPOLL_SUPPORT
6463  mhd_assert (-1 == daemon->epoll_fd);
6464 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6465  mhd_assert (-1 == daemon->epoll_upgrade_fd);
6466 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6467 #endif /* EPOLL_SUPPORT */
6468  }
6469  else
6470  { /* Worker daemon or single daemon. */
6472  { /* Worker daemon or single daemon with internal thread(s). */
6474  /* Separate thread(s) is used for polling sockets. */
6475  if (MHD_ITC_IS_VALID_ (daemon->itc))
6476  {
6477  if (! MHD_itc_activate_ (daemon->itc,
6478  "e"))
6479  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
6480  }
6481  else
6482  {
6483 #ifdef HAVE_LISTEN_SHUTDOWN
6484  if (MHD_INVALID_SOCKET != fd)
6485  {
6486  if (NULL == daemon->master)
6487  (void) shutdown (fd,
6488  SHUT_RDWR);
6489  }
6490  else
6491 #endif /* HAVE_LISTEN_SHUTDOWN */
6492  mhd_assert (false); /* Should never happen */
6493  }
6494 
6495  if (! MHD_join_thread_ (daemon->pid.handle))
6496  {
6497  MHD_PANIC (_("Failed to join a thread\n"));
6498  }
6499  /* close_all_connections() was called in daemon thread. */
6500  }
6501  else
6502  {
6503  /* No internal threads are used for polling sockets. */
6505  }
6506  if (MHD_ITC_IS_VALID_ (daemon->itc))
6508 
6509 #ifdef EPOLL_SUPPORT
6510  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6511  (-1 != daemon->epoll_fd) )
6512  MHD_socket_close_chk_ (daemon->epoll_fd);
6513 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6514  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6515  (-1 != daemon->epoll_upgrade_fd) )
6516  MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
6517 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6518 #endif /* EPOLL_SUPPORT */
6519 
6521  }
6522 
6523  if (NULL == daemon->master)
6524  { /* Cleanup that should be done only one time in master/single daemon.
6525  * Do not perform this cleanup in worker daemons. */
6526 
6527  if (MHD_INVALID_SOCKET != fd)
6529 
6530  /* TLS clean up */
6531 #ifdef HTTPS_SUPPORT
6532  if (daemon->have_dhparams)
6533  {
6534  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
6535  daemon->have_dhparams = false;
6536  }
6537  if (0 != (daemon->options & MHD_USE_TLS))
6538  {
6539  gnutls_priority_deinit (daemon->priority_cache);
6540  if (daemon->x509_cred)
6541  gnutls_certificate_free_credentials (daemon->x509_cred);
6542  if (daemon->psk_cred)
6543  gnutls_psk_free_server_credentials (daemon->psk_cred);
6544  }
6545 #endif /* HTTPS_SUPPORT */
6546 
6547 #ifdef DAUTH_SUPPORT
6548  free (daemon->nnc);
6549  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6550 #endif
6552 
6553  free (daemon);
6554  }
6555 }
6556 
6557 
6569 const union MHD_DaemonInfo *
6571  enum MHD_DaemonInfoType info_type,
6572  ...)
6573 {
6574  if (NULL == daemon)
6575  return NULL;
6576  switch (info_type)
6577  {
6579  return NULL; /* no longer supported */
6581  return NULL; /* no longer supported */
6583  return (const union MHD_DaemonInfo *) &daemon->listen_fd;
6584 #ifdef EPOLL_SUPPORT
6586  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
6587 #endif
6589  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
6590  {
6591  /* Assume that MHD_run() in not called in other thread
6592  * at the same time. */
6593  MHD_cleanup_connections (daemon);
6594  }
6595  else if (daemon->worker_pool)
6596  {
6597  unsigned int i;
6598  /* Collect the connection information stored in the workers. */
6599  daemon->connections = 0;
6600  for (i = 0; i < daemon->worker_pool_size; i++)
6601  {
6602  /* FIXME: next line is thread-safe only if read is atomic. */
6603  daemon->connections += daemon->worker_pool[i].connections;
6604  }
6605  }
6606  return (const union MHD_DaemonInfo *) &daemon->connections;
6607  case MHD_DAEMON_INFO_FLAGS:
6608  return (const union MHD_DaemonInfo *) &daemon->options;
6610  return (const union MHD_DaemonInfo *) &daemon->port;
6611  default:
6612  return NULL;
6613  }
6614 }
6615 
6616 
6633 void
6635  void *cls)
6636 {
6637  mhd_panic = cb;
6638  mhd_panic_cls = cls;
6639 }
6640 
6641 
6648 const char *
6649 MHD_get_version (void)
6650 {
6651 #ifdef PACKAGE_VERSION
6652  return PACKAGE_VERSION;
6653 #else /* !PACKAGE_VERSION */
6654  static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
6655  if (0 == ver[0])
6656  {
6657  int res = MHD_snprintf_(ver,
6658  sizeof(ver),
6659  "%x.%x.%x",
6660  (((int)MHD_VERSION >> 24) & 0xFF),
6661  (((int)MHD_VERSION >> 16) & 0xFF),
6662  (((int)MHD_VERSION >> 8) & 0xFF));
6663  if (0 >= res || sizeof(ver) <= res)
6664  return "0.0.0"; /* Can't return real version*/
6665  }
6666  return ver;
6667 #endif /* !PACKAGE_VERSION */
6668 }
6669 
6670 
6682 _MHD_EXTERN int
6684 {
6685  switch(feature)
6686  {
6687  case MHD_FEATURE_MESSAGES:
6688 #ifdef HAVE_MESSAGES
6689  return MHD_YES;
6690 #else
6691  return MHD_NO;
6692 #endif
6693  case MHD_FEATURE_TLS:
6694 #ifdef HTTPS_SUPPORT
6695  return MHD_YES;
6696 #else /* ! HTTPS_SUPPORT */
6697  return MHD_NO;
6698 #endif /* ! HTTPS_SUPPORT */
6700 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
6701  return MHD_YES;
6702 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
6703  return MHD_NO;
6704 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
6705  case MHD_FEATURE_IPv6:
6706 #ifdef HAVE_INET6
6707  return MHD_YES;
6708 #else
6709  return MHD_NO;
6710 #endif
6711  case MHD_FEATURE_IPv6_ONLY:
6712 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
6713  return MHD_YES;
6714 #else
6715  return MHD_NO;
6716 #endif
6717  case MHD_FEATURE_POLL:
6718 #ifdef HAVE_POLL
6719  return MHD_YES;
6720 #else
6721  return MHD_NO;
6722 #endif
6723  case MHD_FEATURE_EPOLL:
6724 #ifdef EPOLL_SUPPORT
6725  return MHD_YES;
6726 #else
6727  return MHD_NO;
6728 #endif
6730 #ifdef HAVE_LISTEN_SHUTDOWN
6731  return MHD_YES;
6732 #else
6733  return MHD_NO;
6734 #endif
6736 #ifdef _MHD_ITC_SOCKETPAIR
6737  return MHD_YES;
6738 #else
6739  return MHD_NO;
6740 #endif
6742 #ifdef TCP_FASTOPEN
6743  return MHD_YES;
6744 #else
6745  return MHD_NO;
6746 #endif
6748 #ifdef BAUTH_SUPPORT
6749  return MHD_YES;
6750 #else
6751  return MHD_NO;
6752 #endif
6754 #ifdef DAUTH_SUPPORT
6755  return MHD_YES;
6756 #else
6757  return MHD_NO;
6758 #endif
6760 #ifdef HAVE_POSTPROCESSOR
6761  return MHD_YES;
6762 #else
6763  return MHD_NO;
6764 #endif
6766 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
6767  return MHD_YES;
6768 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
6769  return MHD_NO;
6770 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
6772 #if defined(HAVE_PREAD64) || defined(_WIN32)
6773  return MHD_YES;
6774 #elif defined(HAVE_PREAD)
6775  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
6776 #elif defined(HAVE_LSEEK64)
6777  return MHD_YES;
6778 #else
6779  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
6780 #endif
6782 #if defined(MHD_USE_THREAD_NAME_)
6783  return MHD_YES;
6784 #else
6785  return MHD_NO;
6786 #endif
6787  case MHD_FEATURE_UPGRADE:
6788 #if defined(UPGRADE_SUPPORT)
6789  return MHD_YES;
6790 #else
6791  return MHD_NO;
6792 #endif
6794 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
6795  return MHD_YES;
6796 #else
6797  return MHD_NO;
6798 #endif
6800 #ifdef MHD_USE_GETSOCKNAME
6801  return MHD_YES;
6802 #else
6803  return MHD_NO;
6804 #endif
6806 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL)
6807  return MHD_YES;
6808 #else
6809  return MHD_NO;
6810 #endif
6811  case MHD_FEATURE_SENDFILE:
6812 #ifdef _MHD_HAVE_SENDFILE
6813  return MHD_YES;
6814 #else
6815  return MHD_NO;
6816 #endif
6817 
6818  }
6819  return MHD_NO;
6820 }
6821 
6822 
6823 #ifdef MHD_HTTPS_REQUIRE_GRYPT
6824 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
6825 #if defined(MHD_USE_POSIX_THREADS)
6826 GCRY_THREAD_OPTION_PTHREAD_IMPL;
6827 #elif defined(MHD_W32_MUTEX_)
6828 
6829 static int
6830 gcry_w32_mutex_init (void **ppmtx)
6831 {
6832  *ppmtx = malloc (sizeof (MHD_mutex_));
6833 
6834  if (NULL == *ppmtx)
6835  return ENOMEM;
6836  if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
6837  {
6838  free (*ppmtx);
6839  *ppmtx = NULL;
6840  return EPERM;
6841  }
6842 
6843  return 0;
6844 }
6845 
6846 
6847 static int
6848 gcry_w32_mutex_destroy (void **ppmtx)
6849 {
6850  int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
6851  free (*ppmtx);
6852  return res;
6853 }
6854 
6855 
6856 static int
6857 gcry_w32_mutex_lock (void **ppmtx)
6858 {
6859  return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
6860 }
6861 
6862 
6863 static int
6864 gcry_w32_mutex_unlock (void **ppmtx)
6865 {
6866  return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
6867 }
6868 
6869 
6870 static struct gcry_thread_cbs gcry_threads_w32 = {
6871  (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
6872  NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
6873  gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
6874  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
6875 
6876 #endif /* defined(MHD_W32_MUTEX_) */
6877 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
6878 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
6879 
6883 void
6885 {
6886 #if defined(_WIN32) && ! defined(__CYGWIN__)
6887  WSADATA wsd;
6888 #endif /* _WIN32 && ! __CYGWIN__ */
6889 
6890  if (NULL == mhd_panic)
6892 
6893 #if defined(_WIN32) && ! defined(__CYGWIN__)
6894  if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
6895  MHD_PANIC (_("Failed to initialize winsock\n"));
6896  mhd_winsock_inited_ = 1;
6897  if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
6898  MHD_PANIC (_("Winsock version 2.2 is not available\n"));
6899 #endif
6900 #ifdef HTTPS_SUPPORT
6901 #ifdef MHD_HTTPS_REQUIRE_GRYPT
6902 #if GCRYPT_VERSION_NUMBER < 0x010600
6903 #if defined(MHD_USE_POSIX_THREADS)
6904  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
6905  &gcry_threads_pthread))
6906  MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
6907 #elif defined(MHD_W32_MUTEX_)
6908  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
6909  &gcry_threads_w32))
6910  MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
6911 #endif /* defined(MHD_W32_MUTEX_) */
6912  gcry_check_version (NULL);
6913 #else
6914  if (NULL == gcry_check_version ("1.6.0"))
6915  MHD_PANIC (_("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
6916 #endif
6917 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
6918  gnutls_global_init ();
6919 #endif /* HTTPS_SUPPORT */
6921 #ifdef HAVE_FREEBSD_SENDFILE
6922  MHD_conn_init_static_ ();
6923 #endif /* HAVE_FREEBSD_SENDFILE */
6924 }
6925 
6926 
6927 void
6929 {
6930 #ifdef HTTPS_SUPPORT
6931  gnutls_global_deinit ();
6932 #endif /* HTTPS_SUPPORT */
6933 #if defined(_WIN32) && ! defined(__CYGWIN__)
6934  if (mhd_winsock_inited_)
6935  WSACleanup();
6936 #endif
6938 }
6939 
6940 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
6942 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
6943 
6944 /* 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:1559
void * unescape_callback_cls
Definition: internal.h:1387
volatile int global_init_count
Definition: daemon.c:183
#define MHD_PANIC(msg)
Definition: internal.h:68
void MHD_connection_handle_write(struct MHD_Connection *connection)
Definition: connection.c:2997
_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:5367
Header for platform missing functions.
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:4742
_MHD_EXTERN const char * MHD_get_version(void)
Definition: version.c:35
#define EXTRA_SLOTS
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:894
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:1098
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:899
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:4714
#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:1553
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:3227
#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:2947
#define SIZE_MAX
Definition: mhd_limits.h:99
struct MHD_Response * response
Definition: internal.h:660
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
Definition: daemon.c:4524
struct MHD_Connection * manual_timeout_head
Definition: internal.h:1140
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:1201
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:66
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:128
MHD_AccessHandlerCallback default_handler
Definition: internal.h:1233
int MHD_socket
Definition: microhttpd.h:181
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:264
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:2739
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
Definition: daemon.c:4565
#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:4596
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:4767
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:6928
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:277
void * uri_log_callback_cls
Definition: internal.h:1377
struct MHD_Daemon * daemon
Definition: internal.h:672
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:216
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:207
int listening_address_reuse
Definition: internal.h:1467
MHD_mutex_ per_ip_connection_mutex
Definition: internal.h:1256
MHD_NotifyConnectionCallback notify_connection
Definition: internal.h:1358
Header for platform-independent inter-thread communication.
void MHD_init(void)
Definition: daemon.c:6884
struct MHD_Connection * next
Definition: internal.h:648
bool client_aware
Definition: internal.h:845
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:1574
void * socket_context
Definition: internal.h:691
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:292
#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
void * mhd_panic_cls
Definition: daemon.c:157
size_t read_buffer_size
Definition: internal.h:761
int fd
Definition: microhttpd.h:2837
void * client_context
Definition: internal.h:678
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:6417
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:311
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:3475
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:74
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:1547
unsigned int worker_pool_size
Definition: internal.h:1363
enum MHD_FLAG options
Definition: internal.h:1564
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:3421
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:246
LogCallback uri_log_callback
Definition: internal.h:1372
void MHD_connection_handle_read(struct MHD_Connection *connection)
Definition: connection.c:2888
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1119
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
Definition: internal.h:742
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
Definition: daemon.c:1739
#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:362
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:1569
#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:428
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
size_t thread_stack_size
Definition: internal.h:1430
MHD_FEATURE
Definition: microhttpd.h:3422
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:883
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:1382
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:2650
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
Definition: internal.h:1708
#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:3317
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:1420
bool tls_read_ready
Definition: internal.h:766
struct MHD_itc_ itc
Definition: internal.h:1407
MHD_AcceptPolicyCallback apc
Definition: internal.h:1336
#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:3305
static int resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:2799
#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:2248
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:3937
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3125
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:2997
_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:633
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:276
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:195
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:1347
#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:4481
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:3856
void * notify_completed_cls
Definition: internal.h:1352
MHD_socket listen_fd
Definition: internal.h:1456
struct MemoryPool * pool
Definition: internal.h:682
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:4446
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:1215
void * notify_connection_cls
Definition: internal.h:1363
Header for platform-independent locks abstraction.
void * apc_cls
Definition: internal.h:1341
bool at_limit
Definition: internal.h:1480
MHD_PanicCallback mhd_panic
Definition: daemon.c:152
#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:2768
bool suspended
Definition: internal.h:761
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
Definition: daemon.c:6683
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:767
_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:1032
void * default_handler_cls
Definition: internal.h:1238
#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:4641
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:6570
_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:6269
limits values definitions
enum MHD_OPTION option
Definition: microhttpd.h:1532
int MHD_socket_noninheritable_(MHD_socket sock)
Definition: mhd_sockets.c:439
struct MHD_Daemon * worker_pool
Definition: internal.h:1070
#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:1425
Header for platform-independent threads abstraction.
#define MAYBE_SOCK_CLOEXEC
Definition: mhd_sockets.h:156
#define MHD_SCKT_EINTR_
Definition: mhd_sockets.h:398