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