GNU libmicrohttpd  0.9.68
daemon.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 
19 */
20 
28 #include "platform.h"
29 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
30 #include "mhd_threads.h"
31 #endif
32 #include "internal.h"
33 #include "response.h"
34 #include "connection.h"
35 #include "memorypool.h"
36 #include "mhd_limits.h"
37 #include "autoinit_funcs.h"
38 #include "mhd_mono_clock.h"
39 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
40 #include "mhd_locks.h"
41 #endif
42 #include "mhd_sockets.h"
43 #include "mhd_itc.h"
44 #include "mhd_compat.h"
45 
46 #if HAVE_SEARCH_H
47 #include <search.h>
48 #else
49 #include "tsearch.h"
50 #endif
51 
52 #ifdef HTTPS_SUPPORT
53 #include "connection_https.h"
54 #ifdef MHD_HTTPS_REQUIRE_GRYPT
55 #include <gcrypt.h>
56 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
57 #endif /* HTTPS_SUPPORT */
58 
59 #if defined(_WIN32) && ! defined(__CYGWIN__)
60 #ifndef WIN32_LEAN_AND_MEAN
61 #define WIN32_LEAN_AND_MEAN 1
62 #endif /* !WIN32_LEAN_AND_MEAN */
63 #include <windows.h>
64 #endif
65 
69 #ifdef MHD_POSIX_SOCKETS
70 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 4)
71 #else
72 #define MHD_MAX_CONNECTIONS_DEFAULT (FD_SETSIZE - 2)
73 #endif
74 
78 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
79 
84 #define DEBUG_CLOSE MHD_NO
85 
90 #define DEBUG_CONNECT MHD_NO
91 
92 
93 /* Forward declarations. */
94 
103 static void
104 close_all_connections (struct MHD_Daemon *daemon);
105 
106 #ifdef EPOLL_SUPPORT
107 
116 static int
117 MHD_epoll (struct MHD_Daemon *daemon,
118  int may_block);
119 
120 #endif /* EPOLL_SUPPORT */
121 
131 static void
132 mhd_panic_std (void *cls,
133  const char *file,
134  unsigned int line,
135  const char *reason)
136 {
137  (void) cls; /* Mute compiler warning. */
138 #ifdef HAVE_MESSAGES
139  fprintf (stderr,
140  _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"),
141  file,
142  line,
143  reason);
144 #else /* ! HAVE_MESSAGES */
145  (void) file; /* Mute compiler warning. */
146  (void) line; /* Mute compiler warning. */
147  (void) reason; /* Mute compiler warning. */
148 #endif
149  abort ();
150 }
151 
152 
157 
162 
166 void
167 MHD_init (void);
168 
169 
170 #if defined(MHD_WINSOCK_SOCKETS)
171 
174 static int mhd_winsock_inited_ = 0;
175 #endif /* MHD_WINSOCK_SOCKETS */
176 
177 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
178 
182 #define MHD_check_global_init_() (void) 0
183 #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
184 
187 volatile int global_init_count = 0;
188 
189 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
190 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
191 
194 MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_);
195 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
196 #endif
197 
198 
203 void
205 {
206 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
207 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
208  MHD_mutex_lock_chk_ (&global_init_mutex_);
209 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
210 #endif
211  if (0 == global_init_count++)
212  MHD_init ();
213 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
214 #ifdef MHD_MUTEX_STATIC_DEFN_INIT_
215  MHD_mutex_unlock_chk_ (&global_init_mutex_);
216 #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */
217 #endif
218 }
219 #endif /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */
220 
221 
225 static void
227  const char *fm,
228  va_list ap)
229 {
230  vfprintf ((FILE*) cls, fm, ap);
231 #ifdef _DEBUG
232  fflush ((FILE*) cls);
233 #endif /* _DEBUG */
234 }
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
288 
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 int
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 int
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  int 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_YES == 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
529 
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"));
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 
663 static int
664 MHD_TLS_init (struct MHD_Daemon *daemon)
665 {
666  switch (daemon->cred_type)
667  {
668  case GNUTLS_CRD_CERTIFICATE:
669  if (0 !=
670  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
671  return GNUTLS_E_MEMORY_ERROR;
672  return MHD_init_daemon_certificate (daemon);
673  case GNUTLS_CRD_PSK:
674  if (0 !=
675  gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
676  return GNUTLS_E_MEMORY_ERROR;
677  return 0;
678  default:
679 #ifdef HAVE_MESSAGES
680  MHD_DLOG (daemon,
681  _ ("Error: invalid credentials type %d specified.\n"),
682  daemon->cred_type);
683 #endif
684  return -1;
685  }
686 }
687 #endif /* HTTPS_SUPPORT */
688 
689 
690 #undef MHD_get_fdset
691 
721 int
722 MHD_get_fdset (struct MHD_Daemon *daemon,
723  fd_set *read_fd_set,
724  fd_set *write_fd_set,
725  fd_set *except_fd_set,
726  MHD_socket *max_fd)
727 {
728  return MHD_get_fdset2 (daemon,
729  read_fd_set,
730  write_fd_set,
731  except_fd_set,
732  max_fd,
734 }
735 
736 
737 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
738 
750 static bool
751 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
752  fd_set *rs,
753  fd_set *ws,
754  fd_set *es,
755  MHD_socket *max_fd,
756  unsigned int fd_setsize)
757 {
758  const MHD_socket conn_sckt = urh->connection->socket_fd;
759  const MHD_socket mhd_sckt = urh->mhd.socket;
760  bool res = true;
761 
762  /* Do not add to 'es' only if socket is closed
763  * or not used anymore. */
764  if (MHD_INVALID_SOCKET != conn_sckt)
765  {
766  if ( (urh->in_buffer_used < urh->in_buffer_size) &&
767  (! MHD_add_to_fd_set_ (conn_sckt,
768  rs,
769  max_fd,
770  fd_setsize)) )
771  res = false;
772  if ( (0 != urh->out_buffer_used) &&
773  (! MHD_add_to_fd_set_ (conn_sckt,
774  ws,
775  max_fd,
776  fd_setsize)) )
777  res = false;
778  /* Do not monitor again for errors if error was detected before as
779  * error state is remembered. */
780  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
781  ((0 != urh->in_buffer_size) ||
782  (0 != urh->out_buffer_size) ||
783  (0 != urh->out_buffer_used)))
784  MHD_add_to_fd_set_ (conn_sckt,
785  es,
786  max_fd,
787  fd_setsize);
788  }
789  if (MHD_INVALID_SOCKET != mhd_sckt)
790  {
791  if ( (urh->out_buffer_used < urh->out_buffer_size) &&
792  (! MHD_add_to_fd_set_ (mhd_sckt,
793  rs,
794  max_fd,
795  fd_setsize)) )
796  res = false;
797  if ( (0 != urh->in_buffer_used) &&
798  (! MHD_add_to_fd_set_ (mhd_sckt,
799  ws,
800  max_fd,
801  fd_setsize)) )
802  res = false;
803  /* Do not monitor again for errors if error was detected before as
804  * error state is remembered. */
805  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
806  ((0 != urh->out_buffer_size) ||
807  (0 != urh->in_buffer_size) ||
808  (0 != urh->in_buffer_used)))
809  MHD_add_to_fd_set_ (mhd_sckt,
810  es,
811  max_fd,
812  fd_setsize);
813  }
814 
815  return res;
816 }
817 
818 
828 static void
829 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
830  const fd_set *rs,
831  const fd_set *ws,
832  const fd_set *es)
833 {
834  const MHD_socket conn_sckt = urh->connection->socket_fd;
835  const MHD_socket mhd_sckt = urh->mhd.socket;
836 
837  /* Reset read/write ready, preserve error state. */
840 
841  if (MHD_INVALID_SOCKET != conn_sckt)
842  {
843  if (FD_ISSET (conn_sckt, rs))
844  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
845  if (FD_ISSET (conn_sckt, ws))
846  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
847  if (FD_ISSET (conn_sckt, es))
848  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
849  }
850  if ((MHD_INVALID_SOCKET != mhd_sckt))
851  {
852  if (FD_ISSET (mhd_sckt, rs))
853  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
854  if (FD_ISSET (mhd_sckt, ws))
855  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
856  if (FD_ISSET (mhd_sckt, es))
857  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
858  }
859 }
860 
861 #ifdef HAVE_POLL
862 
871 static void
872 urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
873  struct pollfd p[2])
874 {
875  p[0].events = 0;
876  p[1].events = 0;
877 
878  if (urh->in_buffer_used < urh->in_buffer_size)
879  p[0].events |= POLLIN;
880  if (0 != urh->out_buffer_used)
881  p[0].events |= POLLOUT;
882 
883  /* Do not monitor again for errors if error was detected before as
884  * error state is remembered. */
885  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
886  ((0 != urh->in_buffer_size) ||
887  (0 != urh->out_buffer_size) ||
888  (0 != urh->out_buffer_used)))
889  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
890 
891  if (urh->out_buffer_used < urh->out_buffer_size)
892  p[1].events |= POLLIN;
893  if (0 != urh->in_buffer_used)
894  p[1].events |= POLLOUT;
895 
896  /* Do not monitor again for errors if error was detected before as
897  * error state is remembered. */
898  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
899  ((0 != urh->out_buffer_size) ||
900  (0 != urh->in_buffer_size) ||
901  (0 != urh->in_buffer_used)))
902  p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
903 }
904 
905 
912 static void
913 urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
914  struct pollfd p[2])
915 {
916  p[0].fd = urh->connection->socket_fd;
917  p[1].fd = urh->mhd.socket;
918  urh_update_pollfd (urh,
919  p);
920 }
921 
922 
928 static void
929 urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
930  struct pollfd p[2])
931 {
932  /* Reset read/write ready, preserve error state. */
935 
936  if (0 != (p[0].revents & POLLIN))
937  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
938  if (0 != (p[0].revents & POLLOUT))
939  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
940  if (0 != (p[0].revents & POLLHUP))
942  if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
943  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
944  if (0 != (p[1].revents & POLLIN))
945  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
946  if (0 != (p[1].revents & POLLOUT))
947  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
948  if (0 != (p[1].revents & POLLHUP))
949  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
950  if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
952 }
953 #endif /* HAVE_POLL */
954 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
955 
956 
971 static int
973  fd_set *read_fd_set,
974  fd_set *write_fd_set,
975  fd_set *except_fd_set,
976  MHD_socket *max_fd,
977  unsigned int fd_setsize)
978 
979 {
980  struct MHD_Connection *pos;
981  struct MHD_Connection *posn;
982  int result = MHD_YES;
983  MHD_socket ls;
984 
985  if (daemon->shutdown)
986  return MHD_NO;
987 
988  ls = daemon->listen_fd;
989  if ( (MHD_INVALID_SOCKET != ls) &&
990  (! daemon->was_quiesced) &&
991  (! MHD_add_to_fd_set_ (ls,
992  read_fd_set,
993  max_fd,
994  fd_setsize)) )
995  result = MHD_NO;
996 
997  /* Add all sockets to 'except_fd_set' as well to watch for
998  * out-of-band data. However, ignore errors if INFO_READ
999  * or INFO_WRITE sockets will not fit 'except_fd_set'. */
1000  /* Start from oldest connections. Make sense for W32 FDSETs. */
1001  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
1002  {
1003  posn = pos->prev;
1004 
1005  switch (pos->event_loop_info)
1006  {
1008  if (! MHD_add_to_fd_set_ (pos->socket_fd,
1009  read_fd_set,
1010  max_fd,
1011  fd_setsize))
1012  result = MHD_NO;
1013 #ifdef MHD_POSIX_SOCKETS
1015  except_fd_set,
1016  max_fd,
1017  fd_setsize);
1018 #endif /* MHD_POSIX_SOCKETS */
1019  break;
1021  if (! MHD_add_to_fd_set_ (pos->socket_fd,
1022  write_fd_set,
1023  max_fd,
1024  fd_setsize))
1025  result = MHD_NO;
1026 #ifdef MHD_POSIX_SOCKETS
1028  except_fd_set,
1029  max_fd,
1030  fd_setsize);
1031 #endif /* MHD_POSIX_SOCKETS */
1032  break;
1034  if ( (NULL == except_fd_set) ||
1035  ! MHD_add_to_fd_set_ (pos->socket_fd,
1036  except_fd_set,
1037  max_fd,
1038  fd_setsize))
1039  result = MHD_NO;
1040  break;
1042  /* this should never happen */
1043  break;
1044  }
1045  }
1046 #ifdef MHD_WINSOCK_SOCKETS
1047  /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
1048  * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
1049  * not be pushed out. */
1050  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
1051  {
1052  posn = pos->prev;
1054  except_fd_set,
1055  max_fd,
1056  fd_setsize);
1057  }
1058 #endif /* MHD_WINSOCK_SOCKETS */
1059 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1060  {
1061  struct MHD_UpgradeResponseHandle *urh;
1062 
1063  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
1064  {
1065  if (MHD_NO ==
1066  urh_to_fdset (urh,
1067  read_fd_set,
1068  write_fd_set,
1069  except_fd_set,
1070  max_fd,
1071  fd_setsize))
1072  result = MHD_NO;
1073  }
1074  }
1075 #endif
1076 #if DEBUG_CONNECT
1077 #ifdef HAVE_MESSAGES
1078  if (NULL != max_fd)
1079  MHD_DLOG (daemon,
1080  _ ("Maximum socket in select set: %d\n"),
1081  *max_fd);
1082 #endif
1083 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1084  return result;
1085 }
1086 
1087 
1120 int
1121 MHD_get_fdset2 (struct MHD_Daemon *daemon,
1122  fd_set *read_fd_set,
1123  fd_set *write_fd_set,
1124  fd_set *except_fd_set,
1125  MHD_socket *max_fd,
1126  unsigned int fd_setsize)
1127 {
1128  fd_set es;
1129 
1130  if ( (NULL == daemon) ||
1131  (NULL == read_fd_set) ||
1132  (NULL == write_fd_set) ||
1133  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ||
1134  (0 != (daemon->options & MHD_USE_POLL)))
1135  return MHD_NO;
1136 
1137  if (NULL == except_fd_set)
1138  { /* Workaround to maintain backward compatibility. */
1139 #ifdef HAVE_MESSAGES
1140  MHD_DLOG (daemon,
1141  _ ("MHD_get_fdset2() called with except_fd_set "
1142  "set to NULL. Such behavior is unsupported.\n"));
1143 #endif
1144  FD_ZERO (&es);
1145  except_fd_set = &es;
1146  }
1147 
1148 #ifdef EPOLL_SUPPORT
1149  if (0 != (daemon->options & MHD_USE_EPOLL))
1150  {
1151  if (daemon->shutdown)
1152  return MHD_NO;
1153 
1154  /* we're in epoll mode, use the epoll FD as a stand-in for
1155  the entire event set */
1156 
1157  return MHD_add_to_fd_set_ (daemon->epoll_fd,
1158  read_fd_set,
1159  max_fd,
1160  fd_setsize) ? MHD_YES : MHD_NO;
1161  }
1162 #endif
1163 
1164  return internal_get_fdset2 (daemon,
1165  read_fd_set,
1166  write_fd_set,
1167  except_fd_set,
1168  max_fd,
1169  fd_setsize);
1170 }
1171 
1172 
1186 static int
1188  bool read_ready,
1189  bool write_ready,
1190  bool force_close)
1191 {
1192  int ret;
1193  bool states_info_processed = false;
1194  /* Fast track flag */
1195  bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
1196 
1197 #ifdef HTTPS_SUPPORT
1198  if (con->tls_read_ready)
1199  read_ready = true;
1200 #endif /* HTTPS_SUPPORT */
1201  if (! force_close)
1202  {
1203  if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) &&
1204  read_ready)
1205  {
1207  ret = MHD_connection_handle_idle (con);
1208  states_info_processed = true;
1209  }
1210  /* No need to check value of 'ret' here as closed connection
1211  * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
1212  if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
1213  write_ready)
1214  {
1216  ret = MHD_connection_handle_idle (con);
1217  states_info_processed = true;
1218  }
1219  }
1220  else
1221  {
1222  MHD_connection_close_ (con,
1224  return MHD_connection_handle_idle (con);
1225  }
1226 
1227  if (! states_info_processed)
1228  { /* Connection is not read or write ready, but external conditions
1229  * may be changed and need to be processed. */
1230  ret = MHD_connection_handle_idle (con);
1231  }
1232  /* Fast track for fast connections. */
1233  /* If full request was read by single read_handler() invocation
1234  and headers were completely prepared by single MHD_connection_handle_idle()
1235  then try not to wait for next sockets polling and send response
1236  immediately.
1237  As writeability of socket was not checked and it may have
1238  some data pending in system buffers, use this optimization
1239  only for non-blocking sockets. */
1240  /* No need to check 'ret' as connection is always in
1241  * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
1242  else if (on_fasttrack && con->sk_nonblck)
1243  {
1245  {
1247  /* Always call 'MHD_connection_handle_idle()' after each read/write. */
1248  ret = MHD_connection_handle_idle (con);
1249  }
1250  /* If all headers were sent by single write_handler() and
1251  * response body is prepared by single MHD_connection_handle_idle()
1252  * call - continue. */
1253  if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
1255  {
1257  ret = MHD_connection_handle_idle (con);
1258  }
1259  }
1260 
1261  /* All connection's data and states are processed for this turn.
1262  * If connection already has more data to be processed - use
1263  * zero timeout for next select()/poll(). */
1264  /* Thread-per-connection do not need global zero timeout as
1265  * connections are processed individually. */
1266  /* Note: no need to check for read buffer availability for
1267  * TLS read-ready connection in 'read info' state as connection
1268  * without space in read buffer will be marked as 'info block'. */
1269  if ( (! con->daemon->data_already_pending) &&
1270  (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1271  {
1273  con->daemon->data_already_pending = true;
1274 #ifdef HTTPS_SUPPORT
1275  else if ( (con->tls_read_ready) &&
1277  con->daemon->data_already_pending = true;
1278 #endif /* HTTPS_SUPPORT */
1279  }
1280  return ret;
1281 }
1282 
1283 
1284 #ifdef UPGRADE_SUPPORT
1285 
1292 static void
1293 cleanup_upgraded_connection (struct MHD_Connection *connection)
1294 {
1295  struct MHD_UpgradeResponseHandle *urh = connection->urh;
1296 
1297  if (NULL == urh)
1298  return;
1299 #ifdef HTTPS_SUPPORT
1300  /* Signal remote client the end of TLS connection by
1301  * gracefully closing TLS session. */
1302  if (0 != (connection->daemon->options & MHD_USE_TLS))
1303  gnutls_bye (connection->tls_session,
1304  GNUTLS_SHUT_WR);
1305 
1306  if (MHD_INVALID_SOCKET != urh->mhd.socket)
1307  MHD_socket_close_chk_ (urh->mhd.socket);
1308 
1309  if (MHD_INVALID_SOCKET != urh->app.socket)
1310  MHD_socket_close_chk_ (urh->app.socket);
1311 #endif /* HTTPS_SUPPORT */
1312  connection->urh = NULL;
1313  free (urh);
1314 }
1315 #endif /* UPGRADE_SUPPORT */
1316 
1317 
1318 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1319 
1327 static void
1328 process_urh (struct MHD_UpgradeResponseHandle *urh)
1329 {
1330  /* Help compiler to optimize:
1331  * pointers to 'connection' and 'daemon' are not changed
1332  * during this processing, so no need to chain dereference
1333  * each time. */
1334  struct MHD_Connection *const connection = urh->connection;
1335  struct MHD_Daemon *const daemon = connection->daemon;
1336  /* Prevent data races: use same value of 'was_closed' throughout
1337  * this function. If 'was_closed' changed externally in the middle
1338  * of processing - it will be processed on next iteration. */
1339  bool was_closed;
1340  if (daemon->shutdown)
1341  {
1342  /* Daemon shutting down, application will not receive any more data. */
1343 #ifdef HAVE_MESSAGES
1344  if (! urh->was_closed)
1345  {
1346  MHD_DLOG (daemon,
1347  _ (
1348  "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1349  }
1350 #endif
1351  urh->was_closed = true;
1352  }
1353  was_closed = urh->was_closed;
1354  if (was_closed)
1355  {
1356  /* Application was closed connections: no more data
1357  * can be forwarded to application socket. */
1358  if (0 < urh->in_buffer_used)
1359  {
1360 #ifdef HAVE_MESSAGES
1361  MHD_DLOG (daemon,
1362  _ (
1363  "Failed to forward to application "
1365  " bytes of data received from remote side: application shut down socket\n"),
1366  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
1367 #endif
1368 
1369  }
1370  /* If application signaled MHD about socket closure then
1371  * check for any pending data even if socket is not marked
1372  * as 'ready' (signal may arrive after poll()/select()).
1373  * Socketpair for forwarding is always in non-blocking mode
1374  * so no risk that recv() will block the thread. */
1375  if (0 != urh->out_buffer_size)
1376  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1377  /* Discard any data received form remote. */
1378  urh->in_buffer_used = 0;
1379  /* Do not try to push data to application. */
1380  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1381  /* Reading from remote client is not required anymore. */
1382  urh->in_buffer_size = 0;
1383  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1384  connection->tls_read_ready = false;
1385  }
1386 
1387  /* On some platforms (W32, possibly Darwin) failed send() (send() will always
1388  * fail after remote disconnect was detected) may discard data in system
1389  * buffers received by system but not yet read by recv().
1390  * So, before trying send() on any socket, recv() must be performed at first
1391  * otherwise last part of incoming data may be lost. */
1392 
1393  /* If disconnect or error was detected - try to read from socket
1394  * to dry data possibly pending is system buffers. */
1395  if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
1396  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
1397  if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
1398  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1399 
1400  /*
1401  * handle reading from remote TLS client
1402  */
1403  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
1404  (connection->tls_read_ready) ) &&
1405  (urh->in_buffer_used < urh->in_buffer_size) )
1406  {
1407  ssize_t res;
1408  size_t buf_size;
1409 
1410  buf_size = urh->in_buffer_size - urh->in_buffer_used;
1411  if (buf_size > SSIZE_MAX)
1412  buf_size = SSIZE_MAX;
1413 
1414  connection->tls_read_ready = false;
1415  res = gnutls_record_recv (connection->tls_session,
1416  &urh->in_buffer[urh->in_buffer_used],
1417  buf_size);
1418  if (0 >= res)
1419  {
1420  if (GNUTLS_E_INTERRUPTED != res)
1421  {
1422  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1423  if (GNUTLS_E_AGAIN != res)
1424  {
1425  /* Unrecoverable error on socket was detected or
1426  * socket was disconnected/shut down. */
1427  /* Stop trying to read from this TLS socket. */
1428  urh->in_buffer_size = 0;
1429  }
1430  }
1431  }
1432  else /* 0 < res */
1433  {
1434  urh->in_buffer_used += res;
1435  if (buf_size > (size_t) res)
1436  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1437  else if (0 < gnutls_record_check_pending (connection->tls_session))
1438  connection->tls_read_ready = true;
1439  }
1440  if (MHD_EPOLL_STATE_ERROR ==
1441  ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
1442  {
1443  /* Unrecoverable error on socket was detected and all
1444  * pending data was read from system buffers. */
1445  /* Stop trying to read from this TLS socket. */
1446  urh->in_buffer_size = 0;
1447  }
1448  }
1449 
1450  /*
1451  * handle reading from application
1452  */
1453  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1454  (urh->out_buffer_used < urh->out_buffer_size) )
1455  {
1456  ssize_t res;
1457  size_t buf_size;
1458 
1459  buf_size = urh->out_buffer_size - urh->out_buffer_used;
1460  if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
1461  buf_size = MHD_SCKT_SEND_MAX_SIZE_;
1462 
1463  res = MHD_recv_ (urh->mhd.socket,
1464  &urh->out_buffer[urh->out_buffer_used],
1465  buf_size);
1466  if (0 >= res)
1467  {
1468  const int err = MHD_socket_get_error_ ();
1469  if ((0 == res) ||
1470  ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1471  (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err))))
1472  {
1473  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1474  if ((0 == res) ||
1475  (was_closed) ||
1476  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1477  (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
1478  {
1479  /* Socket disconnect/shutdown was detected;
1480  * Application signaled about closure of 'upgraded' socket;
1481  * or persistent / unrecoverable error. */
1482  /* Do not try to pull more data from application. */
1483  urh->out_buffer_size = 0;
1484  }
1485  }
1486  }
1487  else /* 0 < res */
1488  {
1489  urh->out_buffer_used += res;
1490  if (buf_size > (size_t) res)
1491  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1492  }
1493  if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1494  ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1495  (was_closed) ) )
1496  {
1497  /* Unrecoverable error on socket was detected and all
1498  * pending data was read from system buffers. */
1499  /* Do not try to pull more data from application. */
1500  urh->out_buffer_size = 0;
1501  }
1502  }
1503 
1504  /*
1505  * handle writing to remote HTTPS client
1506  */
1507  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
1508  (urh->out_buffer_used > 0) )
1509  {
1510  ssize_t res;
1511  size_t data_size;
1512 
1513  data_size = urh->out_buffer_used;
1514  if (data_size > SSIZE_MAX)
1515  data_size = SSIZE_MAX;
1516 
1517  res = gnutls_record_send (connection->tls_session,
1518  urh->out_buffer,
1519  data_size);
1520  if (0 >= res)
1521  {
1522  if (GNUTLS_E_INTERRUPTED != res)
1523  {
1524  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1525  if (GNUTLS_E_AGAIN != res)
1526  {
1527  /* TLS connection shut down or
1528  * persistent / unrecoverable error. */
1529 #ifdef HAVE_MESSAGES
1530  MHD_DLOG (daemon,
1531  _ (
1532  "Failed to forward to remote client "
1534  " bytes of data received from application: %s\n"),
1535  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
1536  gnutls_strerror (res));
1537 #endif
1538  /* Discard any data unsent to remote. */
1539  urh->out_buffer_used = 0;
1540  /* Do not try to pull more data from application. */
1541  urh->out_buffer_size = 0;
1542  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1543  }
1544  }
1545  }
1546  else /* 0 < res */
1547  {
1548  const size_t next_out_buffer_used = urh->out_buffer_used - res;
1549  if (0 != next_out_buffer_used)
1550  {
1551  memmove (urh->out_buffer,
1552  &urh->out_buffer[res],
1553  next_out_buffer_used);
1554  if (data_size > (size_t) res)
1555  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1556  }
1557  urh->out_buffer_used = next_out_buffer_used;
1558  }
1559  if ( (0 == urh->out_buffer_used) &&
1560  (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
1561  {
1562  /* Unrecoverable error on socket was detected and all
1563  * pending data was sent to remote. */
1564  /* Do not try to send to remote anymore. */
1565  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1566  /* Do not try to pull more data from application. */
1567  urh->out_buffer_size = 0;
1568  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1569  }
1570  }
1571 
1572  /*
1573  * handle writing to application
1574  */
1575  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
1576  (urh->in_buffer_used > 0) )
1577  {
1578  ssize_t res;
1579  size_t data_size;
1580 
1581  data_size = urh->in_buffer_used;
1582  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
1583  data_size = MHD_SCKT_SEND_MAX_SIZE_;
1584 
1585  res = MHD_send_ (urh->mhd.socket,
1586  urh->in_buffer,
1587  data_size);
1588  if (0 >= res)
1589  {
1590  const int err = MHD_socket_get_error_ ();
1591  if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1592  (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) )
1593  {
1594  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1595  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
1596  {
1597  /* Socketpair connection shut down or
1598  * persistent / unrecoverable error. */
1599 #ifdef HAVE_MESSAGES
1600  MHD_DLOG (daemon,
1601  _ (
1602  "Failed to forward to application "
1604  " bytes of data received from remote side: %s\n"),
1605  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
1606  MHD_socket_strerr_ (err));
1607 #endif
1608  /* Discard any data received form remote. */
1609  urh->in_buffer_used = 0;
1610  /* Reading from remote client is not required anymore. */
1611  urh->in_buffer_size = 0;
1612  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1613  connection->tls_read_ready = false;
1614  }
1615  }
1616  }
1617  else /* 0 < res */
1618  {
1619  const size_t next_in_buffer_used = urh->in_buffer_used - res;
1620  if (0 != next_in_buffer_used)
1621  {
1622  memmove (urh->in_buffer,
1623  &urh->in_buffer[res],
1624  next_in_buffer_used);
1625  if (data_size > (size_t) res)
1626  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1627  }
1628  urh->in_buffer_used = next_in_buffer_used;
1629  }
1630  if ( (0 == urh->in_buffer_used) &&
1631  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
1632  {
1633  /* Do not try to push data to application. */
1634  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1635  /* Reading from remote client is not required anymore. */
1636  urh->in_buffer_size = 0;
1637  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1638  connection->tls_read_ready = false;
1639  }
1640  }
1641 
1642  /* Check whether data is present in TLS buffers
1643  * and incoming forward buffer have some space. */
1644  if ( (connection->tls_read_ready) &&
1645  (urh->in_buffer_used < urh->in_buffer_size) &&
1646  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1647  daemon->data_already_pending = true;
1648 
1649  if ( (daemon->shutdown) &&
1650  ( (0 != urh->out_buffer_size) ||
1651  (0 != urh->out_buffer_used) ) )
1652  {
1653  /* Daemon shutting down, discard any remaining forward data. */
1654 #ifdef HAVE_MESSAGES
1655  if (0 < urh->out_buffer_used)
1656  MHD_DLOG (daemon,
1657  _ (
1658  "Failed to forward to remote client "
1660  " bytes of data received from application: daemon shut down\n"),
1661  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
1662 #endif
1663  /* Discard any data unsent to remote. */
1664  urh->out_buffer_used = 0;
1665  /* Do not try to sent to remote anymore. */
1666  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1667  /* Do not try to pull more data from application. */
1668  urh->out_buffer_size = 0;
1669  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1670  }
1671 }
1672 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1673 
1674 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1675 #ifdef UPGRADE_SUPPORT
1676 
1684 static void
1685 thread_main_connection_upgrade (struct MHD_Connection *con)
1686 {
1687 #ifdef HTTPS_SUPPORT
1688  struct MHD_UpgradeResponseHandle *urh = con->urh;
1689  struct MHD_Daemon *daemon = con->daemon;
1690 
1691  /* Here, we need to bi-directionally forward
1692  until the application tells us that it is done
1693  with the socket; */
1694  if ( (0 != (daemon->options & MHD_USE_TLS)) &&
1695  (0 == (daemon->options & MHD_USE_POLL)))
1696  {
1697  while ( (0 != urh->in_buffer_size) ||
1698  (0 != urh->out_buffer_size) ||
1699  (0 != urh->in_buffer_used) ||
1700  (0 != urh->out_buffer_used) )
1701  {
1702  /* use select */
1703  fd_set rs;
1704  fd_set ws;
1705  fd_set es;
1706  MHD_socket max_fd;
1707  int num_ready;
1708  bool result;
1709 
1710  FD_ZERO (&rs);
1711  FD_ZERO (&ws);
1712  FD_ZERO (&es);
1713  max_fd = MHD_INVALID_SOCKET;
1714  result = urh_to_fdset (urh,
1715  &rs,
1716  &ws,
1717  &es,
1718  &max_fd,
1719  FD_SETSIZE);
1720  if (! result)
1721  {
1722 #ifdef HAVE_MESSAGES
1723  MHD_DLOG (con->daemon,
1724  _ ("Error preparing select\n"));
1725 #endif
1726  break;
1727  }
1728  /* FIXME: does this check really needed? */
1729  if (MHD_INVALID_SOCKET != max_fd)
1730  {
1731  struct timeval*tvp;
1732  struct timeval tv;
1733  if ( (con->tls_read_ready) &&
1734  (urh->in_buffer_used < urh->in_buffer_size))
1735  { /* No need to wait if incoming data is already pending in TLS buffers. */
1736  tv.tv_sec = 0;
1737  tv.tv_usec = 0;
1738  tvp = &tv;
1739  }
1740  else
1741  tvp = NULL;
1742  num_ready = MHD_SYS_select_ (max_fd + 1,
1743  &rs,
1744  &ws,
1745  &es,
1746  tvp);
1747  }
1748  else
1749  num_ready = 0;
1750  if (num_ready < 0)
1751  {
1752  const int err = MHD_socket_get_error_ ();
1753 
1754  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1755  continue;
1756 #ifdef HAVE_MESSAGES
1757  MHD_DLOG (con->daemon,
1758  _ ("Error during select (%d): `%s'\n"),
1759  err,
1760  MHD_socket_strerr_ (err));
1761 #endif
1762  break;
1763  }
1764  urh_from_fdset (urh,
1765  &rs,
1766  &ws,
1767  &es);
1768  process_urh (urh);
1769  }
1770  }
1771 #ifdef HAVE_POLL
1772  else if (0 != (daemon->options & MHD_USE_TLS))
1773  {
1774  /* use poll() */
1775  struct pollfd p[2];
1776  memset (p,
1777  0,
1778  sizeof (p));
1779  p[0].fd = urh->connection->socket_fd;
1780  p[1].fd = urh->mhd.socket;
1781 
1782  while ( (0 != urh->in_buffer_size) ||
1783  (0 != urh->out_buffer_size) ||
1784  (0 != urh->in_buffer_used) ||
1785  (0 != urh->out_buffer_used) )
1786  {
1787  int timeout;
1788 
1789  urh_update_pollfd (urh, p);
1790 
1791  if ( (con->tls_read_ready) &&
1792  (urh->in_buffer_used < urh->in_buffer_size))
1793  timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
1794  else
1795  timeout = -1;
1796 
1797  if (MHD_sys_poll_ (p,
1798  2,
1799  timeout) < 0)
1800  {
1801  const int err = MHD_socket_get_error_ ();
1802 
1803  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1804  continue;
1805 #ifdef HAVE_MESSAGES
1806  MHD_DLOG (con->daemon,
1807  _ ("Error during poll: `%s'\n"),
1808  MHD_socket_strerr_ (err));
1809 #endif
1810  break;
1811  }
1812  urh_from_pollfd (urh,
1813  p);
1814  process_urh (urh);
1815  }
1816  }
1817  /* end POLL */
1818 #endif
1819  /* end HTTPS */
1820 #endif /* HTTPS_SUPPORT */
1821  /* TLS forwarding was finished. Cleanup socketpair. */
1823  /* Do not set 'urh->clean_ready' yet as 'urh' will be used
1824  * in connection thread for a little while. */
1825 }
1826 #endif /* UPGRADE_SUPPORT */
1827 
1828 
1836 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1838 {
1839  struct MHD_Connection *con = data;
1840  struct MHD_Daemon *daemon = con->daemon;
1841  int num_ready;
1842  fd_set rs;
1843  fd_set ws;
1844  fd_set es;
1845  MHD_socket maxsock;
1846  struct timeval tv;
1847  struct timeval *tvp;
1848  time_t now;
1849 #if WINDOWS
1850 #ifdef HAVE_POLL
1851  int extra_slot;
1852 #endif /* HAVE_POLL */
1853 #define EXTRA_SLOTS 1
1854 #else /* !WINDOWS */
1855 #define EXTRA_SLOTS 0
1856 #endif /* !WINDOWS */
1857 #ifdef HAVE_POLL
1858  struct pollfd p[1 + EXTRA_SLOTS];
1859 #endif
1860 #undef EXTRA_SLOTS
1861 #ifdef HAVE_POLL
1862  const bool use_poll = (0 != (daemon->options & MHD_USE_POLL));
1863 #else /* ! HAVE_POLL */
1864  const bool use_poll = 0;
1865 #endif /* ! HAVE_POLL */
1866  bool was_suspended = false;
1867  MHD_thread_init_ (&(con->pid));
1868 
1869  while ( (! daemon->shutdown) &&
1870  (MHD_CONNECTION_CLOSED != con->state) )
1871  {
1872  const time_t timeout = daemon->connection_timeout;
1873 #ifdef UPGRADE_SUPPORT
1874  struct MHD_UpgradeResponseHandle *const urh = con->urh;
1875 #else /* ! UPGRADE_SUPPORT */
1876  static const void *const urh = NULL;
1877 #endif /* ! UPGRADE_SUPPORT */
1878 
1879  if ( (con->suspended) &&
1880  (NULL == urh) )
1881  {
1882  /* Connection was suspended, wait for resume. */
1883  was_suspended = true;
1884  if (! use_poll)
1885  {
1886  FD_ZERO (&rs);
1887  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
1888  &rs,
1889  NULL,
1890  FD_SETSIZE))
1891  {
1892  #ifdef HAVE_MESSAGES
1893  MHD_DLOG (con->daemon,
1894  _ ("Failed to add FD to fd_set\n"));
1895  #endif
1896  goto exit;
1897  }
1898  if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
1899  &rs,
1900  NULL,
1901  NULL,
1902  NULL))
1903  {
1904  const int err = MHD_socket_get_error_ ();
1905 
1906  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1907  continue;
1908 #ifdef HAVE_MESSAGES
1909  MHD_DLOG (con->daemon,
1910  _ ("Error during select (%d): `%s'\n"),
1911  err,
1912  MHD_socket_strerr_ (err));
1913 #endif
1914  break;
1915  }
1916  }
1917 #ifdef HAVE_POLL
1918  else /* use_poll */
1919  {
1920  p[0].events = POLLIN;
1921  p[0].fd = MHD_itc_r_fd_ (daemon->itc);
1922  p[0].revents = 0;
1923  if (0 > MHD_sys_poll_ (p,
1924  1,
1925  -1))
1926  {
1928  continue;
1929 #ifdef HAVE_MESSAGES
1930  MHD_DLOG (con->daemon,
1931  _ ("Error during poll: `%s'\n"),
1933 #endif
1934  break;
1935  }
1936  }
1937 #endif /* HAVE_POLL */
1938  MHD_itc_clear_ (daemon->itc);
1939  continue; /* Check again for resume. */
1940  } /* End of "suspended" branch. */
1941 
1942  if (was_suspended)
1943  {
1944  MHD_update_last_activity_ (con); /* Reset timeout timer. */
1945  /* Process response queued during suspend and update states. */
1947  was_suspended = false;
1948  }
1949 
1950  tvp = NULL;
1951 
1953 #ifdef HTTPS_SUPPORT
1954  || ( (con->tls_read_ready) &&
1956 #endif /* HTTPS_SUPPORT */
1957  )
1958  {
1959  /* do not block: more data may be inside of TLS buffers waiting or
1960  * application must provide response data */
1961  tv.tv_sec = 0;
1962  tv.tv_usec = 0;
1963  tvp = &tv;
1964  }
1965  if ( (NULL == tvp) &&
1966  (timeout > 0) )
1967  {
1968  now = MHD_monotonic_sec_counter ();
1969  if (now - con->last_activity > timeout)
1970  tv.tv_sec = 0;
1971  else
1972  {
1973  const time_t seconds_left = timeout - (now - con->last_activity);
1974 #if ! defined(_WIN32) || defined(__CYGWIN__)
1975  tv.tv_sec = seconds_left;
1976 #else /* _WIN32 && !__CYGWIN__ */
1977  if (seconds_left > TIMEVAL_TV_SEC_MAX)
1978  tv.tv_sec = TIMEVAL_TV_SEC_MAX;
1979  else
1980  tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
1981 #endif /* _WIN32 && ! __CYGWIN__ */
1982  }
1983  tv.tv_usec = 0;
1984  tvp = &tv;
1985  }
1986  if (! use_poll)
1987  {
1988  /* use select */
1989  bool err_state = false;
1990 
1991  FD_ZERO (&rs);
1992  FD_ZERO (&ws);
1993  FD_ZERO (&es);
1994  maxsock = MHD_INVALID_SOCKET;
1995  switch (con->event_loop_info)
1996  {
1998  if (! MHD_add_to_fd_set_ (con->socket_fd,
1999  &rs,
2000  &maxsock,
2001  FD_SETSIZE))
2002  err_state = true;
2003  break;
2005  if (! MHD_add_to_fd_set_ (con->socket_fd,
2006  &ws,
2007  &maxsock,
2008  FD_SETSIZE))
2009  err_state = true;
2010  break;
2012  if (! MHD_add_to_fd_set_ (con->socket_fd,
2013  &es,
2014  &maxsock,
2015  FD_SETSIZE))
2016  err_state = true;
2017  break;
2019  /* how did we get here!? */
2020  goto exit;
2021  }
2022 #if WINDOWS
2023  if (MHD_ITC_IS_VALID_ (daemon->itc) )
2024  {
2025  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
2026  &rs,
2027  &maxsock,
2028  FD_SETSIZE))
2029  err_state = 1;
2030  }
2031 #endif
2032  if (err_state)
2033  {
2034 #ifdef HAVE_MESSAGES
2035  MHD_DLOG (con->daemon,
2036  _ ("Failed to add FD to fd_set\n"));
2037 #endif
2038  goto exit;
2039  }
2040 
2041  num_ready = MHD_SYS_select_ (maxsock + 1,
2042  &rs,
2043  &ws,
2044  &es,
2045  tvp);
2046  if (num_ready < 0)
2047  {
2048  const int err = MHD_socket_get_error_ ();
2049 
2050  if (MHD_SCKT_ERR_IS_EINTR_ (err))
2051  continue;
2052 #ifdef HAVE_MESSAGES
2053  MHD_DLOG (con->daemon,
2054  _ ("Error during select (%d): `%s'\n"),
2055  err,
2056  MHD_socket_strerr_ (err));
2057 #endif
2058  break;
2059  }
2060 #if WINDOWS
2061  /* Clear ITC before other processing so additional
2062  * signals will trigger select() again */
2063  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2064  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
2065  &rs)) )
2066  MHD_itc_clear_ (daemon->itc);
2067 #endif
2068  if (MHD_NO ==
2069  call_handlers (con,
2070  FD_ISSET (con->socket_fd,
2071  &rs),
2072  FD_ISSET (con->socket_fd,
2073  &ws),
2074  FD_ISSET (con->socket_fd,
2075  &es)) )
2076  goto exit;
2077  }
2078 #ifdef HAVE_POLL
2079  else
2080  {
2081  /* use poll */
2082  memset (&p,
2083  0,
2084  sizeof (p));
2085  p[0].fd = con->socket_fd;
2086  switch (con->event_loop_info)
2087  {
2089  p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2090  break;
2092  p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2093  break;
2095  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2096  break;
2098  /* how did we get here!? */
2099  goto exit;
2100  }
2101 #if WINDOWS
2102  extra_slot = 0;
2103  if (MHD_ITC_IS_VALID_ (daemon->itc))
2104  {
2105  p[1].events |= POLLIN;
2106  p[1].fd = MHD_itc_r_fd_ (daemon->itc);
2107  p[1].revents = 0;
2108  extra_slot = 1;
2109  }
2110 #endif
2111  if (MHD_sys_poll_ (p,
2112 #if WINDOWS
2113  1 + extra_slot,
2114 #else
2115  1,
2116 #endif
2117  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2118  {
2120  continue;
2121 #ifdef HAVE_MESSAGES
2122  MHD_DLOG (con->daemon,
2123  _ ("Error during poll: `%s'\n"),
2125 #endif
2126  break;
2127  }
2128 #if WINDOWS
2129  /* Clear ITC before other processing so additional
2130  * signals will trigger poll() again */
2131  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2132  (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2133  MHD_itc_clear_ (daemon->itc);
2134 #endif
2135  if (MHD_NO ==
2136  call_handlers (con,
2137  (0 != (p[0].revents & POLLIN)),
2138  (0 != (p[0].revents & POLLOUT)),
2139  (0 != (p[0].revents & (POLLERR
2140  | MHD_POLL_REVENTS_ERR_DISC))) ))
2141  goto exit;
2142  }
2143 #endif
2144 #ifdef UPGRADE_SUPPORT
2145  if (MHD_CONNECTION_UPGRADE == con->state)
2146  {
2147  /* Normal HTTP processing is finished,
2148  * notify application. */
2149  if ( (NULL != daemon->notify_completed) &&
2150  (con->client_aware) )
2151  daemon->notify_completed (daemon->notify_completed_cls,
2152  con,
2153  &con->client_context,
2155  con->client_aware = false;
2156 
2157  thread_main_connection_upgrade (con);
2158  /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
2159 
2160  /* "Upgraded" data will not be used in this thread from this point. */
2161  con->urh->clean_ready = true;
2162  /* If 'urh->was_closed' set to true, connection will be
2163  * moved immediately to cleanup list. Otherwise connection
2164  * will stay in suspended list until 'urh' will be marked
2165  * with 'was_closed' by application. */
2166  MHD_resume_connection (con);
2167 
2168  /* skip usual clean up */
2169  return (MHD_THRD_RTRN_TYPE_) 0;
2170  }
2171 #endif /* UPGRADE_SUPPORT */
2172  }
2173 #if DEBUG_CLOSE
2174 #ifdef HAVE_MESSAGES
2175  MHD_DLOG (con->daemon,
2176  _ ("Processing thread terminating. Closing connection\n"));
2177 #endif
2178 #endif
2179  if (MHD_CONNECTION_CLOSED != con->state)
2180  MHD_connection_close_ (con,
2181  (daemon->shutdown) ?
2185  exit:
2186  if (NULL != con->response)
2187  {
2189  con->response = NULL;
2190  }
2191 
2192  if (MHD_INVALID_SOCKET != con->socket_fd)
2193  {
2194  shutdown (con->socket_fd,
2195  SHUT_WR);
2196  /* 'socket_fd' can be used in other thread to signal shutdown.
2197  * To avoid data races, do not close socket here. Daemon will
2198  * use more connections only after cleanup anyway. */
2199  }
2200  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2201  (! MHD_itc_activate_ (daemon->itc, "t")) )
2202  {
2203 #ifdef HAVE_MESSAGES
2204  MHD_DLOG (daemon,
2205  _ (
2206  "Failed to signal thread termination via inter-thread communication channel."));
2207 #endif
2208  }
2209  return (MHD_THRD_RTRN_TYPE_) 0;
2210 }
2211 #endif
2212 
2213 
2221 static void
2222 MHD_cleanup_connections (struct MHD_Daemon *daemon);
2223 
2224 #if defined(HTTPS_SUPPORT)
2225 #if ! defined(MHD_WINSOCK_SOCKETS) && ! defined(MHD_socket_nosignal_) && \
2226  (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL)
2227 
2232 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2233 #endif /* !MHD_WINSOCK_SOCKETS && !MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) */
2234 
2235 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2236 
2240 static ssize_t
2241 MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp,
2242  const void *data,
2243  size_t data_size)
2244 {
2245 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2246  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
2247  data_size = MHD_SCKT_SEND_MAX_SIZE_;
2248 #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */
2249  return MHD_send_ ((MHD_socket) (intptr_t) (trnsp), data, data_size);
2250 }
2251 #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
2252 
2253 
2262 static int
2263 psk_gnutls_adapter (gnutls_session_t session,
2264  const char *username,
2265  gnutls_datum_t *key)
2266 {
2267  struct MHD_Connection *connection;
2268  struct MHD_Daemon *daemon;
2269  void *app_psk;
2270  size_t app_psk_size;
2271 
2272  connection = gnutls_session_get_ptr (session);
2273  if (NULL == connection)
2274  {
2275 #ifdef HAVE_MESSAGES
2276  /* Cannot use our logger, we don't even have "daemon" */
2277  MHD_PANIC (_ ("Internal server error. This should be impossible.\n"));
2278 #endif
2279  return -1;
2280  }
2281  daemon = connection->daemon;
2282 #if GNUTLS_VERSION_MAJOR >= 3
2283  if (NULL == daemon->cred_callback)
2284  {
2285 #ifdef HAVE_MESSAGES
2286  MHD_DLOG (daemon,
2287  _ ("PSK not supported by this server.\n"));
2288 #endif
2289  return -1;
2290  }
2291  if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2292  connection,
2293  username,
2294  &app_psk,
2295  &app_psk_size))
2296  return -1;
2297  if (NULL == (key->data = gnutls_malloc (app_psk_size)))
2298  {
2299 #ifdef HAVE_MESSAGES
2300  MHD_DLOG (daemon,
2301  _ (
2302  "PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2303 #endif
2304  free (app_psk);
2305  return -1;
2306  }
2307  if (UINT_MAX < app_psk_size)
2308  {
2309 #ifdef HAVE_MESSAGES
2310  MHD_DLOG (daemon,
2311  _ ("PSK authentication failed: PSK too long\n"));
2312 #endif
2313  free (app_psk);
2314  return -1;
2315  }
2316  key->size = (unsigned int) app_psk_size;
2317  memcpy (key->data,
2318  app_psk,
2319  app_psk_size);
2320  free (app_psk);
2321  return 0;
2322 #else
2323 #ifdef HAVE_MESSAGES
2324  MHD_DLOG (daemon,
2325  _ ("PSK not supported by this server.\n"));
2326 #endif
2327  return -1;
2328 #endif
2329 }
2330 #endif /* HTTPS_SUPPORT */
2331 
2332 
2358 static int
2360  MHD_socket client_socket,
2361  const struct sockaddr *addr,
2362  socklen_t addrlen,
2363  bool external_add,
2364  bool non_blck)
2365 {
2366  struct MHD_Connection *connection;
2367 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2368  unsigned int i;
2369 #endif
2370  int eno = 0;
2371 
2372  /* Direct add to master daemon could happen only with "external" add mode. */
2373 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2374  mhd_assert ((NULL == daemon->worker_pool) || (external_add));
2375  if ((external_add) && (NULL != daemon->worker_pool))
2376  {
2377  /* have a pool, try to find a pool with capacity; we use the
2378  socket as the initial offset into the pool for load
2379  balancing */
2380  for (i = 0; i < daemon->worker_pool_size; ++i)
2381  {
2382  struct MHD_Daemon *const worker =
2383  &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
2384  if (worker->connections < worker->connection_limit)
2385  return internal_add_connection (worker,
2386  client_socket,
2387  addr,
2388  addrlen,
2389  true,
2390  non_blck);
2391  }
2392  /* all pools are at their connection limit, must refuse */
2393  MHD_socket_close_chk_ (client_socket);
2394 #if ENFILE
2395  errno = ENFILE;
2396 #endif
2397  return MHD_NO;
2398  }
2399 #endif
2400 
2401  if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket,
2402  NULL)) &&
2403  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
2404  {
2405 #ifdef HAVE_MESSAGES
2406  MHD_DLOG (daemon,
2407  _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2408  (int) client_socket,
2409  (int) FD_SETSIZE);
2410 #endif
2411  MHD_socket_close_chk_ (client_socket);
2412 #if EINVAL
2413  errno = EINVAL;
2414 #endif
2415  return MHD_NO;
2416  }
2417 
2418 #ifdef MHD_socket_nosignal_
2419  if (! MHD_socket_nosignal_ (client_socket))
2420  {
2421 #ifdef HAVE_MESSAGES
2422  MHD_DLOG (daemon,
2423  _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2425 #endif
2426 #ifndef MSG_NOSIGNAL
2427  /* Cannot use socket as it can produce SIGPIPE. */
2428 #ifdef ENOTSOCK
2429  errno = ENOTSOCK;
2430 #endif /* ENOTSOCK */
2431  return MHD_NO;
2432 #endif /* ! MSG_NOSIGNAL */
2433  }
2434 #endif /* MHD_socket_nosignal_ */
2435 
2436 
2437 #ifdef HAVE_MESSAGES
2438 #if DEBUG_CONNECT
2439  MHD_DLOG (daemon,
2440  _ ("Accepted connection on socket %d\n"),
2441  client_socket);
2442 #endif
2443 #endif
2444  if ( (daemon->connections == daemon->connection_limit) ||
2445  (MHD_NO == MHD_ip_limit_add (daemon,
2446  addr,
2447  addrlen)) )
2448  {
2449  /* above connection limit - reject */
2450 #ifdef HAVE_MESSAGES
2451  MHD_DLOG (daemon,
2452  _ (
2453  "Server reached connection limit. Closing inbound connection.\n"));
2454 #endif
2455  MHD_socket_close_chk_ (client_socket);
2456 #if ENFILE
2457  errno = ENFILE;
2458 #endif
2459  return MHD_NO;
2460  }
2461 
2462  /* apply connection acceptance policy if present */
2463  if ( (NULL != daemon->apc) &&
2464  (MHD_NO == daemon->apc (daemon->apc_cls,
2465  addr,
2466  addrlen)) )
2467  {
2468 #if DEBUG_CLOSE
2469 #ifdef HAVE_MESSAGES
2470  MHD_DLOG (daemon,
2471  _ ("Connection rejected by application. Closing connection.\n"));
2472 #endif
2473 #endif
2474  MHD_socket_close_chk_ (client_socket);
2475  MHD_ip_limit_del (daemon,
2476  addr,
2477  addrlen);
2478 #if EACCESS
2479  errno = EACCESS;
2480 #endif
2481  return MHD_NO;
2482  }
2483 
2484  if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection))))
2485  {
2486  eno = errno;
2487 #ifdef HAVE_MESSAGES
2488  MHD_DLOG (daemon,
2489  "Error allocating memory: %s\n",
2490  MHD_strerror_ (errno));
2491 #endif
2492  MHD_socket_close_chk_ (client_socket);
2493  MHD_ip_limit_del (daemon,
2494  addr,
2495  addrlen);
2496  errno = eno;
2497  return MHD_NO;
2498  }
2499  connection->pool = MHD_pool_create (daemon->pool_size);
2500  if (NULL == connection->pool)
2501  {
2502 #ifdef HAVE_MESSAGES
2503  MHD_DLOG (daemon,
2504  _ ("Error allocating memory: %s\n"),
2505  MHD_strerror_ (errno));
2506 #endif
2507  MHD_socket_close_chk_ (client_socket);
2508  MHD_ip_limit_del (daemon,
2509  addr,
2510  addrlen);
2511  free (connection);
2512 #if ENOMEM
2513  errno = ENOMEM;
2514 #endif
2515  return MHD_NO;
2516  }
2517 
2518  connection->connection_timeout = daemon->connection_timeout;
2519  if (NULL == (connection->addr = malloc (addrlen)))
2520  {
2521  eno = errno;
2522 #ifdef HAVE_MESSAGES
2523  MHD_DLOG (daemon,
2524  _ ("Error allocating memory: %s\n"),
2525  MHD_strerror_ (errno));
2526 #endif
2527  MHD_socket_close_chk_ (client_socket);
2528  MHD_ip_limit_del (daemon,
2529  addr,
2530  addrlen);
2531  MHD_pool_destroy (connection->pool);
2532  free (connection);
2533  errno = eno;
2534  return MHD_NO;
2535  }
2536  memcpy (connection->addr,
2537  addr,
2538  addrlen);
2539  connection->addr_len = addrlen;
2540  connection->socket_fd = client_socket;
2541  connection->sk_nonblck = non_blck;
2542  connection->daemon = daemon;
2543  connection->last_activity = MHD_monotonic_sec_counter ();
2544 
2545  if (0 == (daemon->options & MHD_USE_TLS))
2546  {
2547  /* set default connection handlers */
2548  MHD_set_http_callbacks_ (connection);
2549  }
2550  else
2551  {
2552 #ifdef HTTPS_SUPPORT
2553 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500)
2554  gnutls_init_flags_t
2555 #else
2556  unsigned int
2557 #endif
2558  flags;
2559 
2560  flags = GNUTLS_SERVER;
2561 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402)
2562  flags |= GNUTLS_NO_SIGNAL;
2563 #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
2564 #if GNUTLS_VERSION_MAJOR >= 3
2565  flags |= GNUTLS_NONBLOCK;
2566 #endif /* GNUTLS_VERSION_MAJOR >= 3*/
2567 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603)
2568  if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT))
2569  flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2570 #endif
2571 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605)
2572  if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA))
2573  flags |= GNUTLS_ENABLE_EARLY_DATA;
2574 #endif
2575  connection->tls_state = MHD_TLS_CONN_INIT;
2576  MHD_set_https_callbacks (connection);
2577  gnutls_init (&connection->tls_session,
2578  flags);
2579  gnutls_priority_set (connection->tls_session,
2580  daemon->priority_cache);
2581  gnutls_session_set_ptr (connection->tls_session,
2582  connection);
2583  switch (daemon->cred_type)
2584  {
2585  /* set needed credentials for certificate authentication. */
2586  case GNUTLS_CRD_CERTIFICATE:
2587  gnutls_credentials_set (connection->tls_session,
2588  GNUTLS_CRD_CERTIFICATE,
2589  daemon->x509_cred);
2590  break;
2591  case GNUTLS_CRD_PSK:
2592  gnutls_credentials_set (connection->tls_session,
2593  GNUTLS_CRD_PSK,
2594  daemon->psk_cred);
2595  gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2596  &psk_gnutls_adapter);
2597  break;
2598  default:
2599 #ifdef HAVE_MESSAGES
2600  MHD_DLOG (connection->daemon,
2601  _ (
2602  "Failed to setup TLS credentials: unknown credential type %d\n"),
2603  daemon->cred_type);
2604 #endif
2605  MHD_socket_close_chk_ (client_socket);
2606  MHD_ip_limit_del (daemon,
2607  addr,
2608  addrlen);
2609  free (connection->addr);
2610  free (connection);
2611  MHD_PANIC (_ ("Unknown credential type"));
2612 #if EINVAL
2613  errno = EINVAL;
2614 #endif
2615  return MHD_NO;
2616  }
2617 #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64)
2618  gnutls_transport_set_int (connection->tls_session,
2619  (int) (client_socket));
2620 #else /* GnuTLS before 3.1.9 or Win x64 */
2621  gnutls_transport_set_ptr (connection->tls_session,
2622  (gnutls_transport_ptr_t) (intptr_t) (client_socket));
2623 #endif /* GnuTLS before 3.1.9 */
2624 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2625  gnutls_transport_set_push_function (connection->tls_session,
2626  MHD_tls_push_func_);
2627 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
2628  if (daemon->https_mem_trust)
2629  gnutls_certificate_server_set_request (connection->tls_session,
2630  GNUTLS_CERT_REQUEST);
2631 #else /* ! HTTPS_SUPPORT */
2632  eno = EINVAL;
2633  goto cleanup;
2634 #endif /* ! HTTPS_SUPPORT */
2635  }
2636 
2637 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2639 #endif
2640  /* Firm check under lock. */
2641  if (daemon->connections >= daemon->connection_limit)
2642  {
2643 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2645 #endif
2646  /* above connection limit - reject */
2647 #ifdef HAVE_MESSAGES
2648  MHD_DLOG (daemon,
2649  _ (
2650  "Server reached connection limit. Closing inbound connection.\n"));
2651 #endif
2652 #if ENFILE
2653  eno = ENFILE;
2654 #endif
2655  goto cleanup;
2656  }
2657  daemon->connections++;
2658  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2659  {
2661  daemon->normal_timeout_tail,
2662  connection);
2663  }
2664  DLL_insert (daemon->connections_head,
2665  daemon->connections_tail,
2666  connection);
2667 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2669 #endif
2670  if (NULL != daemon->notify_connection)
2671  daemon->notify_connection (daemon->notify_connection_cls,
2672  connection,
2673  &connection->socket_context,
2675 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2676  /* attempt to create handler thread */
2677  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2678  {
2679  if (! MHD_create_named_thread_ (&connection->pid,
2680  "MHD-connection",
2681  daemon->thread_stack_size,
2683  connection))
2684  {
2685  eno = errno;
2686 #ifdef HAVE_MESSAGES
2687  MHD_DLOG (daemon,
2688  "Failed to create a thread: %s\n",
2689  MHD_strerror_ (eno));
2690 #endif
2691  goto cleanup;
2692  }
2693  }
2694  else
2695  connection->pid = daemon->pid;
2696 #endif
2697 #ifdef EPOLL_SUPPORT
2698  if (0 != (daemon->options & MHD_USE_EPOLL))
2699  {
2700  if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add))
2701  { /* Do not manipulate EReady DL-list in 'external_add' mode. */
2702  struct epoll_event event;
2703 
2704  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2705  event.data.ptr = connection;
2706  if (0 != epoll_ctl (daemon->epoll_fd,
2707  EPOLL_CTL_ADD,
2708  client_socket,
2709  &event))
2710  {
2711  eno = errno;
2712 #ifdef HAVE_MESSAGES
2713  MHD_DLOG (daemon,
2714  _ ("Call to epoll_ctl failed: %s\n"),
2716 #endif
2717  goto cleanup;
2718  }
2719  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2720  }
2721  else
2722  {
2723  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY
2726  EDLL_insert (daemon->eready_head,
2727  daemon->eready_tail,
2728  connection);
2729  }
2730  }
2731  else /* This 'else' is combined with next 'if'. */
2732 #endif
2733  if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2734  (external_add) &&
2735  (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2736  (! MHD_itc_activate_ (daemon->itc, "n")) )
2737  {
2738 #ifdef HAVE_MESSAGES
2739  MHD_DLOG (daemon,
2740  _ (
2741  "Failed to signal new connection via inter-thread communication channel."));
2742 #endif
2743  }
2744  return MHD_YES;
2745  cleanup:
2746  if (NULL != daemon->notify_connection)
2747  daemon->notify_connection (daemon->notify_connection_cls,
2748  connection,
2749  &connection->socket_context,
2751 #ifdef HTTPS_SUPPORT
2752  if (NULL != connection->tls_session)
2753  gnutls_deinit (connection->tls_session);
2754 #endif /* HTTPS_SUPPORT */
2755  MHD_socket_close_chk_ (client_socket);
2756  MHD_ip_limit_del (daemon,
2757  addr,
2758  addrlen);
2759 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2761 #endif
2762  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2763  {
2765  daemon->normal_timeout_tail,
2766  connection);
2767  }
2768  DLL_remove (daemon->connections_head,
2769  daemon->connections_tail,
2770  connection);
2771 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2773 #endif
2774  MHD_pool_destroy (connection->pool);
2775  free (connection->addr);
2776  free (connection);
2777  if (0 != eno)
2778  errno = eno;
2779  else
2780  errno = EINVAL;
2781  return MHD_NO;
2782 }
2783 
2784 
2794 void
2796 {
2797  struct MHD_Daemon *daemon = connection->daemon;
2798 
2799 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2801 #endif
2802  if (connection->resuming)
2803  {
2804  /* suspending again while we didn't even complete resuming yet */
2805  connection->resuming = false;
2806 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2808 #endif
2809  return;
2810  }
2811  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2812  {
2813  if (connection->connection_timeout == daemon->connection_timeout)
2815  daemon->normal_timeout_tail,
2816  connection);
2817  else
2819  daemon->manual_timeout_tail,
2820  connection);
2821  }
2822  DLL_remove (daemon->connections_head,
2823  daemon->connections_tail,
2824  connection);
2825  mhd_assert (! connection->suspended);
2828  connection);
2829  connection->suspended = true;
2830 #ifdef EPOLL_SUPPORT
2831  if (0 != (daemon->options & MHD_USE_EPOLL))
2832  {
2833  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2834  {
2835  EDLL_remove (daemon->eready_head,
2836  daemon->eready_tail,
2837  connection);
2838  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2839  }
2840  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
2841  {
2842  if (0 != epoll_ctl (daemon->epoll_fd,
2843  EPOLL_CTL_DEL,
2844  connection->socket_fd,
2845  NULL))
2846  MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
2847  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
2848  }
2849  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
2850  }
2851 #endif
2852 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2854 #endif
2855 }
2856 
2857 
2889 void
2891 {
2892  struct MHD_Daemon *const daemon = connection->daemon;
2893 
2894  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2895  MHD_PANIC (_ (
2896  "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2897 #ifdef UPGRADE_SUPPORT
2898  if (NULL != connection->urh)
2899  {
2900 #ifdef HAVE_MESSAGES
2901  MHD_DLOG (daemon,
2902  _ (
2903  "Error: connection scheduled for \"upgrade\" cannot be suspended"));
2904 #endif /* HAVE_MESSAGES */
2905  return;
2906  }
2907 #endif /* UPGRADE_SUPPORT */
2908  internal_suspend_connection_ (connection);
2909 }
2910 
2911 
2920 void
2922 {
2923  struct MHD_Daemon *daemon = connection->daemon;
2924 
2925  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2926  MHD_PANIC (_ (
2927  "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2928 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2930 #endif
2931  connection->resuming = true;
2932  daemon->resuming = true;
2933 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2935 #endif
2936  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
2937  (! MHD_itc_activate_ (daemon->itc, "r")) )
2938  {
2939 #ifdef HAVE_MESSAGES
2940  MHD_DLOG (daemon,
2941  _ (
2942  "Failed to signal resume via inter-thread communication channel."));
2943 #endif
2944  }
2945 }
2946 
2947 
2957 static int
2959 {
2960  struct MHD_Connection *pos;
2961  struct MHD_Connection *prev = NULL;
2962  int ret;
2963  const bool used_thr_p_c = (0 != (daemon->options
2965 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2967 #endif
2968  ret = MHD_NO;
2969 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2971 #endif
2972  if (daemon->resuming)
2973  {
2975  /* During shutdown check for resuming is forced. */
2976  mhd_assert ((NULL != prev) || (daemon->shutdown));
2977  }
2978 
2979  daemon->resuming = false;
2980 
2981  while (NULL != (pos = prev))
2982  {
2983 #ifdef UPGRADE_SUPPORT
2984  struct MHD_UpgradeResponseHandle *const urh = pos->urh;
2985 #else /* ! UPGRADE_SUPPORT */
2986  static const void *const urh = NULL;
2987 #endif /* ! UPGRADE_SUPPORT */
2988  prev = pos->prev;
2989  if ( (! pos->resuming)
2990 #ifdef UPGRADE_SUPPORT
2991  || ( (NULL != urh) &&
2992  ( (! urh->was_closed) ||
2993  (! urh->clean_ready) ) )
2994 #endif /* UPGRADE_SUPPORT */
2995  )
2996  continue;
2997  ret = MHD_YES;
2998  mhd_assert (pos->suspended);
3001  pos);
3002  pos->suspended = false;
3003  if (NULL == urh)
3004  {
3005  DLL_insert (daemon->connections_head,
3006  daemon->connections_tail,
3007  pos);
3008  if (! used_thr_p_c)
3009  {
3010  /* Reset timeout timer on resume. */
3011  if (0 != pos->connection_timeout)
3013 
3014  if (pos->connection_timeout == daemon->connection_timeout)
3016  daemon->normal_timeout_tail,
3017  pos);
3018  else
3020  daemon->manual_timeout_tail,
3021  pos);
3022  }
3023 #ifdef EPOLL_SUPPORT
3024  if (0 != (daemon->options & MHD_USE_EPOLL))
3025  {
3026  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3027  MHD_PANIC ("Resumed connection was already in EREADY set\n");
3028  /* we always mark resumed connections as ready, as we
3029  might have missed the edge poll event during suspension */
3030  EDLL_insert (daemon->eready_head,
3031  daemon->eready_tail,
3032  pos);
3033  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \
3036  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
3037  }
3038 #endif
3039  }
3040 #ifdef UPGRADE_SUPPORT
3041  else
3042  {
3043  /* Data forwarding was finished (for TLS connections) AND
3044  * application was closed upgraded connection.
3045  * Insert connection into cleanup list. */
3046 
3047  if ( (NULL != daemon->notify_completed) &&
3048  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3049  (pos->client_aware) )
3050  {
3051  daemon->notify_completed (daemon->notify_completed_cls,
3052  pos,
3053  &pos->client_context,
3055  pos->client_aware = false;
3056  }
3057  DLL_insert (daemon->cleanup_head,
3058  daemon->cleanup_tail,
3059  pos);
3060 
3061  }
3062 #endif /* UPGRADE_SUPPORT */
3063  pos->resuming = false;
3064  }
3065 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3067 #endif
3068  if ( (used_thr_p_c) &&
3069  (MHD_NO != ret) )
3070  { /* Wake up suspended connections. */
3071  if (! MHD_itc_activate_ (daemon->itc,
3072  "w"))
3073  {
3074 #ifdef HAVE_MESSAGES
3075  MHD_DLOG (daemon,
3076  _ (
3077  "Failed to signal resume of connection via inter-thread communication channel."));
3078 #endif
3079  }
3080  }
3081  return ret;
3082 }
3083 
3084 
3112 int
3114  MHD_socket client_socket,
3115  const struct sockaddr *addr,
3116  socklen_t addrlen)
3117 {
3118  bool sk_nonbl;
3119 
3120  if (! MHD_socket_nonblocking_ (client_socket))
3121  {
3122 #ifdef HAVE_MESSAGES
3123  MHD_DLOG (daemon,
3124  _ ("Failed to set nonblocking mode on new client socket: %s\n"),
3126 #endif
3127  sk_nonbl = false;
3128  }
3129  else
3130  sk_nonbl = true;
3131 
3132  if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
3133  (! MHD_socket_noninheritable_ (client_socket)) )
3134  {
3135 #ifdef HAVE_MESSAGES
3136  MHD_DLOG (daemon,
3137  _ ("Failed to set noninheritable mode on new client socket.\n"));
3138 #endif
3139  }
3140 
3141  if ( (0 == (daemon->options & MHD_USE_TURBO)) &&
3142  (! MHD_socket_buffering_reset_ (client_socket)) )
3143  {
3144 #ifdef HAVE_MESSAGES
3145  MHD_DLOG (daemon,
3146  _ ("Failed to reset buffering mode on new client socket.\n"));
3147 #endif
3148  }
3149  return internal_add_connection (daemon,
3150  client_socket,
3151  addr,
3152  addrlen,
3153  true,
3154  sk_nonbl);
3155 }
3156 
3157 
3172 static int
3174 {
3175 #if HAVE_INET6
3176  struct sockaddr_in6 addrstorage;
3177 #else
3178  struct sockaddr_in addrstorage;
3179 #endif
3180  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
3181  socklen_t addrlen;
3182  MHD_socket s;
3183  MHD_socket fd;
3184  bool sk_nonbl;
3185 
3186  addrlen = sizeof (addrstorage);
3187  memset (addr,
3188  0,
3189  sizeof (addrstorage));
3190  if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) ||
3191  (daemon->was_quiesced) )
3192  return MHD_NO;
3193 #ifdef USE_ACCEPT4
3194  s = accept4 (fd,
3195  addr,
3196  &addrlen,
3198  sk_nonbl = (MAYBE_SOCK_NONBLOCK != 0);
3199 #else /* ! USE_ACCEPT4 */
3200  s = accept (fd,
3201  addr,
3202  &addrlen);
3203  sk_nonbl = false;
3204 #endif /* ! USE_ACCEPT4 */
3205  if ( (MHD_INVALID_SOCKET == s) ||
3206  (addrlen <= 0) )
3207  {
3208  const int err = MHD_socket_get_error_ ();
3209 
3210  /* This could be a common occurance with multiple worker threads */
3211  if (MHD_SCKT_ERR_IS_ (err,
3213  return MHD_NO; /* can happen during shutdown */
3215  return MHD_NO; /* do not print error if client just disconnected early */
3216 #ifdef HAVE_MESSAGES
3217  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
3218  MHD_DLOG (daemon,
3219  _ ("Error accepting connection: %s\n"),
3220  MHD_socket_strerr_ (err));
3221 #endif
3222  if (MHD_INVALID_SOCKET != s)
3223  {
3225  }
3226  if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
3227  {
3228  /* system/process out of resources */
3229  if (0 == daemon->connections)
3230  {
3231 #ifdef HAVE_MESSAGES
3232  /* Not setting 'at_limit' flag, as there is no way it
3233  would ever be cleared. Instead trying to produce
3234  bit fat ugly warning. */
3235  MHD_DLOG (daemon,
3236  _ (
3237  "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"));
3238 #endif
3239  }
3240  else
3241  {
3242 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3244 #endif
3245  daemon->at_limit = true;
3246 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3248 #endif
3249 #ifdef HAVE_MESSAGES
3250  MHD_DLOG (daemon,
3251  _ (
3252  "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3253  (unsigned int) daemon->connections);
3254 #endif
3255  }
3256  }
3257  return MHD_NO;
3258  }
3259 #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE)
3260  /* We will use TCP_CORK or TCP_NOPUSH or MSG_MORE to control
3261  transmission, disable Nagle's algorithm (always) */
3262  if ( (0 != MHD_socket_set_nodelay_ (s,
3263  true)) &&
3264  (EOPNOTSUPP != errno) )
3265  {
3266 #ifdef HAVE_MESSAGES
3267  MHD_DLOG (daemon,
3268  _ ("Failed to disable TCP Nagle on socket: %s\n"),
3270  }
3271 #endif
3272 #endif
3273 #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK)
3274  if (! MHD_socket_nonblocking_ (s))
3275  {
3276 #ifdef HAVE_MESSAGES
3277  MHD_DLOG (daemon,
3278  _ (
3279  "Failed to set nonblocking mode on incoming connection socket: %s\n"),
3281 #endif
3282  }
3283  else
3284  sk_nonbl = true;
3285 #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
3286 #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC)
3287  if (! MHD_socket_noninheritable_ (s))
3288  {
3289 #ifdef HAVE_MESSAGES
3290  MHD_DLOG (daemon,
3291  _ (
3292  "Failed to set noninheritable mode on incoming connection socket.\n"));
3293 #endif
3294  }
3295 #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
3296 #ifdef HAVE_MESSAGES
3297 #if DEBUG_CONNECT
3298  MHD_DLOG (daemon,
3299  _ ("Accepted connection on socket %d\n"),
3300  s);
3301 #endif
3302 #endif
3303  (void) internal_add_connection (daemon,
3304  s,
3305  addr,
3306  addrlen,
3307  false,
3308  sk_nonbl);
3309  return MHD_YES;
3310 }
3311 
3312 
3322 static void
3324 {
3325  struct MHD_Connection *pos;
3326 
3327 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3329 #endif
3330  while (NULL != (pos = daemon->cleanup_tail))
3331  {
3334  pos);
3335 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3337  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3338  (! pos->thread_joined) &&
3339  (! MHD_join_thread_ (pos->pid.handle)) )
3340  MHD_PANIC (_ ("Failed to join a thread\n"));
3341 #endif
3342 #ifdef UPGRADE_SUPPORT
3343  cleanup_upgraded_connection (pos);
3344 #endif /* UPGRADE_SUPPORT */
3345  MHD_pool_destroy (pos->pool);
3346 #ifdef HTTPS_SUPPORT
3347  if (NULL != pos->tls_session)
3348  gnutls_deinit (pos->tls_session);
3349 #endif /* HTTPS_SUPPORT */
3350 
3351  /* clean up the connection */
3352  if (NULL != daemon->notify_connection)
3354  pos,
3355  &pos->socket_context,
3358  pos->addr,
3359  pos->addr_len);
3360 #ifdef EPOLL_SUPPORT
3361  if (0 != (daemon->options & MHD_USE_EPOLL))
3362  {
3363  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3364  {
3365  EDLL_remove (daemon->eready_head,
3366  daemon->eready_tail,
3367  pos);
3368  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3369  }
3370  if ( (-1 != daemon->epoll_fd) &&
3371  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
3372  {
3373  /* epoll documentation suggests that closing a FD
3374  automatically removes it from the epoll set; however,
3375  this is not true as if we fail to do manually remove it,
3376  we are still seeing an event for this fd in epoll,
3377  causing grief (use-after-free...) --- at least on my
3378  system. */
3379  if (0 != epoll_ctl (daemon->epoll_fd,
3380  EPOLL_CTL_DEL,
3381  pos->socket_fd,
3382  NULL))
3383  MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
3384  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
3385  }
3386  }
3387 #endif
3388  if (NULL != pos->response)
3389  {
3391  pos->response = NULL;
3392  }
3393  if (MHD_INVALID_SOCKET != pos->socket_fd)
3395  if (NULL != pos->addr)
3396  free (pos->addr);
3397  free (pos);
3398 
3399 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3401 #endif
3402  daemon->connections--;
3403  daemon->at_limit = false;
3404  }
3405 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3407 #endif
3408 }
3409 
3410 
3431 int
3433  MHD_UNSIGNED_LONG_LONG *timeout)
3434 {
3435  time_t earliest_deadline;
3436  time_t now;
3437  struct MHD_Connection *pos;
3438  bool have_timeout;
3439 
3441  {
3442 #ifdef HAVE_MESSAGES
3443  MHD_DLOG (daemon,
3444  _ ("Illegal call to MHD_get_timeout\n"));
3445 #endif
3446  return MHD_NO;
3447  }
3448 
3450  {
3451  /* Some data already waiting to be processed. */
3452  *timeout = 0;
3453  return MHD_YES;
3454  }
3455 
3456 #ifdef EPOLL_SUPPORT
3457  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
3458  ((NULL != daemon->eready_head)
3459 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3460  || (NULL != daemon->eready_urh_head)
3461 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
3462  ) )
3463  {
3464  /* Some connection(s) already have some data pending. */
3465  *timeout = 0;
3466  return MHD_YES;
3467  }
3468 #endif /* EPOLL_SUPPORT */
3469 
3470  have_timeout = false;
3471  earliest_deadline = 0; /* avoid compiler warnings */
3472  for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
3473  {
3474  if (0 != pos->connection_timeout)
3475  {
3476  if ( (! have_timeout) ||
3477  (earliest_deadline - pos->last_activity > pos->connection_timeout) )
3478  earliest_deadline = pos->last_activity + pos->connection_timeout;
3479  have_timeout = true;
3480  }
3481  }
3482  /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
3483  pos = daemon->normal_timeout_tail;
3484  if ( (NULL != pos) &&
3485  (0 != pos->connection_timeout) )
3486  {
3487  if ( (! have_timeout) ||
3488  (earliest_deadline - pos->connection_timeout > pos->last_activity) )
3489  earliest_deadline = pos->last_activity + pos->connection_timeout;
3490  have_timeout = true;
3491  }
3492 
3493  if (! have_timeout)
3494  return MHD_NO;
3495  now = MHD_monotonic_sec_counter ();
3496  if (earliest_deadline < now)
3497  *timeout = 0;
3498  else
3499  {
3500  const time_t second_left = earliest_deadline - now;
3501 
3502  if (((unsigned long long) second_left) > ULLONG_MAX / 1000)
3503  *timeout = ULLONG_MAX;
3504  else
3505  *timeout = 1000LLU * (unsigned long long) second_left;
3506  }
3507  return MHD_YES;
3508 }
3509 
3510 
3521 static int
3523  const fd_set *read_fd_set,
3524  const fd_set *write_fd_set,
3525  const fd_set *except_fd_set)
3526 {
3527  MHD_socket ds;
3528  struct MHD_Connection *pos;
3529  struct MHD_Connection *prev;
3530 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3531  struct MHD_UpgradeResponseHandle *urh;
3532  struct MHD_UpgradeResponseHandle *urhn;
3533 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3534  /* Reset. New value will be set when connections are processed. */
3535  /* Note: no-op for thread-per-connection as it is always false in that mode. */
3536  daemon->data_already_pending = false;
3537 
3538  /* Clear ITC to avoid spinning select */
3539  /* Do it before any other processing so new signals
3540  will trigger select again and will be processed */
3541  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
3542  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
3543  read_fd_set)) )
3544  MHD_itc_clear_ (daemon->itc);
3545 
3546  /* select connection thread handling type */
3547  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
3548  (! daemon->was_quiesced) &&
3549  (FD_ISSET (ds,
3550  read_fd_set)) )
3551  (void) MHD_accept_connection (daemon);
3552 
3553  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3554  {
3555  /* do not have a thread per connection, process all connections now */
3556  prev = daemon->connections_tail;
3557  while (NULL != (pos = prev))
3558  {
3559  prev = pos->prev;
3560  ds = pos->socket_fd;
3561  if (MHD_INVALID_SOCKET == ds)
3562  continue;
3563  call_handlers (pos,
3564  FD_ISSET (ds,
3565  read_fd_set),
3566  FD_ISSET (ds,
3567  write_fd_set),
3568  FD_ISSET (ds,
3569  except_fd_set));
3570  }
3571  }
3572 
3573 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3574  /* handle upgraded HTTPS connections */
3575  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3576  {
3577  urhn = urh->prev;
3578  /* update urh state based on select() output */
3579  urh_from_fdset (urh,
3580  read_fd_set,
3581  write_fd_set,
3582  except_fd_set);
3583  /* call generic forwarding function for passing data */
3584  process_urh (urh);
3585  /* Finished forwarding? */
3586  if ( (0 == urh->in_buffer_size) &&
3587  (0 == urh->out_buffer_size) &&
3588  (0 == urh->in_buffer_used) &&
3589  (0 == urh->out_buffer_used) )
3590  {
3591  MHD_connection_finish_forward_ (urh->connection);
3592  urh->clean_ready = true;
3593  /* Resuming will move connection to cleanup list. */
3594  MHD_resume_connection (urh->connection);
3595  }
3596  }
3597 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3598  MHD_cleanup_connections (daemon);
3599  return MHD_YES;
3600 }
3601 
3602 
3625 int
3627  const fd_set *read_fd_set,
3628  const fd_set *write_fd_set,
3629  const fd_set *except_fd_set)
3630 {
3631  fd_set es;
3632  if (0 != (daemon->options
3634  return MHD_NO;
3635  if ((NULL == read_fd_set)||(NULL == write_fd_set))
3636  return MHD_NO;
3637  if (NULL == except_fd_set)
3638  { /* Workaround to maintain backward compatibility. */
3639 #ifdef HAVE_MESSAGES
3640  MHD_DLOG (daemon,
3641  _ ("MHD_run_from_select() called with except_fd_set "
3642  "set to NULL. Such behavior is deprecated.\n"));
3643 #endif
3644  FD_ZERO (&es);
3645  except_fd_set = &es;
3646  }
3647  if (0 != (daemon->options & MHD_USE_EPOLL))
3648  {
3649 #ifdef EPOLL_SUPPORT
3650  int ret = MHD_epoll (daemon,
3651  MHD_NO);
3652 
3653  MHD_cleanup_connections (daemon);
3654  return ret;
3655 #else /* ! EPOLL_SUPPORT */
3656  return MHD_NO;
3657 #endif /* ! EPOLL_SUPPORT */
3658  }
3659 
3660  /* Resuming external connections when using an extern mainloop */
3661  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3663 
3664  return internal_run_from_select (daemon,
3665  read_fd_set,
3666  write_fd_set,
3667  except_fd_set);
3668 }
3669 
3670 
3679 static int
3680 MHD_select (struct MHD_Daemon *daemon,
3681  int may_block)
3682 {
3683  int num_ready;
3684  fd_set rs;
3685  fd_set ws;
3686  fd_set es;
3687  MHD_socket maxsock;
3688  struct timeval timeout;
3689  struct timeval *tv;
3690  MHD_UNSIGNED_LONG_LONG ltimeout;
3691  int err_state;
3692  MHD_socket ls;
3693 
3694  timeout.tv_sec = 0;
3695  timeout.tv_usec = 0;
3696  if (daemon->shutdown)
3697  return MHD_NO;
3698  FD_ZERO (&rs);
3699  FD_ZERO (&ws);
3700  FD_ZERO (&es);
3701  maxsock = MHD_INVALID_SOCKET;
3702  err_state = MHD_NO;
3703  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3704  (MHD_YES == resume_suspended_connections (daemon)) &&
3705  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
3706  may_block = MHD_NO;
3707 
3708  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3709  {
3710  /* single-threaded, go over everything */
3711  if (MHD_NO ==
3712  internal_get_fdset2 (daemon,
3713  &rs,
3714  &ws,
3715  &es,
3716  &maxsock,
3717  FD_SETSIZE))
3718  {
3719 #ifdef HAVE_MESSAGES
3720  MHD_DLOG (daemon,
3721  _ ("Could not obtain daemon fdsets"));
3722 #endif
3723  err_state = MHD_YES;
3724  }
3725  }
3726  else
3727  {
3728  /* accept only, have one thread per connection */
3729  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3730  (! daemon->was_quiesced) &&
3731  (! MHD_add_to_fd_set_ (ls,
3732  &rs,
3733  &maxsock,
3734  FD_SETSIZE)) )
3735  {
3736 #ifdef HAVE_MESSAGES
3737  MHD_DLOG (daemon,
3738  _ ("Could not add listen socket to fdset"));
3739 #endif
3740  return MHD_NO;
3741  }
3742  }
3743  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
3744  (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
3745  &rs,
3746  &maxsock,
3747  FD_SETSIZE)) )
3748  {
3749 #if defined(MHD_WINSOCK_SOCKETS)
3750  /* fdset limit reached, new connections
3751  cannot be handled. Remove listen socket FD
3752  from fdset and retry to add ITC FD. */
3753  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3754  (! daemon->was_quiesced) )
3755  {
3756  FD_CLR (ls,
3757  &rs);
3758  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
3759  &rs,
3760  &maxsock,
3761  FD_SETSIZE))
3762  {
3763 #endif /* MHD_WINSOCK_SOCKETS */
3764 #ifdef HAVE_MESSAGES
3765  MHD_DLOG (daemon,
3766  _ (
3767  "Could not add control inter-thread communication channel FD to fdset"));
3768 #endif
3769  err_state = MHD_YES;
3770 #if defined(MHD_WINSOCK_SOCKETS)
3771  }
3772 }
3773 #endif /* MHD_WINSOCK_SOCKETS */
3774  }
3775  /* Stop listening if we are at the configured connection limit */
3776  /* If we're at the connection limit, no point in really
3777  accepting new connections; however, make sure we do not miss
3778  the shutdown OR the termination of an existing connection; so
3779  only do this optimization if we have a signaling ITC in
3780  place. */
3781  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3782  (MHD_ITC_IS_VALID_ (daemon->itc)) &&
3783  ( (daemon->connections == daemon->connection_limit) ||
3784  (daemon->at_limit) ) )
3785  {
3786  FD_CLR (ls,
3787  &rs);
3788  }
3789  tv = NULL;
3790  if (MHD_YES == err_state)
3791  may_block = MHD_NO;
3792  if (MHD_NO == may_block)
3793  {
3794  timeout.tv_usec = 0;
3795  timeout.tv_sec = 0;
3796  tv = &timeout;
3797  }
3798  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3799  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
3800  {
3801  /* ltimeout is in ms */
3802  timeout.tv_usec = (ltimeout % 1000) * 1000;
3803  if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
3804  timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
3805  else
3806  timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
3807  tv = &timeout;
3808  }
3809  num_ready = MHD_SYS_select_ (maxsock + 1,
3810  &rs,
3811  &ws,
3812  &es,
3813  tv);
3814  if (daemon->shutdown)
3815  return MHD_NO;
3816  if (num_ready < 0)
3817  {
3818  const int err = MHD_socket_get_error_ ();
3819  if (MHD_SCKT_ERR_IS_EINTR_ (err))
3820  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3821 #ifdef HAVE_MESSAGES
3822  MHD_DLOG (daemon,
3823  _ ("select failed: %s\n"),
3824  MHD_socket_strerr_ (err));
3825 #endif
3826  return MHD_NO;
3827  }
3828  if (MHD_YES == internal_run_from_select (daemon,
3829  &rs,
3830  &ws,
3831  &es))
3832  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3833  return MHD_NO;
3834 }
3835 
3836 
3837 #ifdef HAVE_POLL
3838 
3846 static int
3847 MHD_poll_all (struct MHD_Daemon *daemon,
3848  int may_block)
3849 {
3850  unsigned int num_connections;
3851  struct MHD_Connection *pos;
3852  struct MHD_Connection *prev;
3853 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3854  struct MHD_UpgradeResponseHandle *urh;
3855  struct MHD_UpgradeResponseHandle *urhn;
3856 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3857 
3858  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3859  (MHD_YES == resume_suspended_connections (daemon)) )
3860  may_block = MHD_NO;
3861 
3862  /* count number of connections and thus determine poll set size */
3863  num_connections = 0;
3864  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
3865  num_connections++;
3866 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3867  for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
3868  num_connections += 2;
3869 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3870  {
3871  MHD_UNSIGNED_LONG_LONG ltimeout;
3872  unsigned int i;
3873  int timeout;
3874  unsigned int poll_server;
3875  int poll_listen;
3876  int poll_itc_idx;
3877  struct pollfd *p;
3878  MHD_socket ls;
3879 
3880  p = MHD_calloc_ ((2 + (size_t) num_connections),
3881  sizeof (struct pollfd));
3882  if (NULL == p)
3883  {
3884 #ifdef HAVE_MESSAGES
3885  MHD_DLOG (daemon,
3886  _ ("Error allocating memory: %s\n"),
3887  MHD_strerror_ (errno));
3888 #endif
3889  return MHD_NO;
3890  }
3891  poll_server = 0;
3892  poll_listen = -1;
3893  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3894  (! daemon->was_quiesced) &&
3895  (daemon->connections < daemon->connection_limit) &&
3896  (! daemon->at_limit) )
3897  {
3898  /* only listen if we are not at the connection limit */
3899  p[poll_server].fd = ls;
3900  p[poll_server].events = POLLIN;
3901  p[poll_server].revents = 0;
3902  poll_listen = (int) poll_server;
3903  poll_server++;
3904  }
3905  poll_itc_idx = -1;
3906  if (MHD_ITC_IS_VALID_ (daemon->itc))
3907  {
3908  p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
3909  p[poll_server].events = POLLIN;
3910  p[poll_server].revents = 0;
3911  poll_itc_idx = (int) poll_server;
3912  poll_server++;
3913  }
3914  if (may_block == MHD_NO)
3915  timeout = 0;
3916  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
3917  (MHD_YES != MHD_get_timeout (daemon,
3918  &ltimeout)) )
3919  timeout = -1;
3920  else
3921  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
3922 
3923  i = 0;
3924  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
3925  {
3926  p[poll_server + i].fd = pos->socket_fd;
3927  switch (pos->event_loop_info)
3928  {
3930  p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3931  break;
3933  p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3934  break;
3936  p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC;
3937  break;
3939  timeout = 0; /* clean up "pos" immediately */
3940  break;
3941  }
3942  i++;
3943  }
3944 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3945  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
3946  {
3947  urh_to_pollfd (urh, &(p[poll_server + i]));
3948  i += 2;
3949  }
3950 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3951  if (0 == poll_server + num_connections)
3952  {
3953  free (p);
3954  return MHD_YES;
3955  }
3956  if (MHD_sys_poll_ (p,
3957  poll_server + num_connections,
3958  timeout) < 0)
3959  {
3960  const int err = MHD_socket_get_error_ ();
3961  if (MHD_SCKT_ERR_IS_EINTR_ (err))
3962  {
3963  free (p);
3964  return MHD_YES;
3965  }
3966 #ifdef HAVE_MESSAGES
3967  MHD_DLOG (daemon,
3968  _ ("poll failed: %s\n"),
3969  MHD_socket_strerr_ (err));
3970 #endif
3971  free (p);
3972  return MHD_NO;
3973  }
3974 
3975  /* Reset. New value will be set when connections are processed. */
3976  daemon->data_already_pending = false;
3977 
3978  /* handle ITC FD */
3979  /* do it before any other processing so
3980  new signals will be processed in next loop */
3981  if ( (-1 != poll_itc_idx) &&
3982  (0 != (p[poll_itc_idx].revents & POLLIN)) )
3983  MHD_itc_clear_ (daemon->itc);
3984 
3985  /* handle shutdown */
3986  if (daemon->shutdown)
3987  {
3988  free (p);
3989  return MHD_NO;
3990  }
3991  i = 0;
3992  prev = daemon->connections_tail;
3993  while (NULL != (pos = prev))
3994  {
3995  prev = pos->prev;
3996  /* first, sanity checks */
3997  if (i >= num_connections)
3998  break; /* connection list changed somehow, retry later ... */
3999  if (p[poll_server + i].fd != pos->socket_fd)
4000  continue; /* fd mismatch, something else happened, retry later ... */
4001  call_handlers (pos,
4002  0 != (p[poll_server + i].revents & POLLIN),
4003  0 != (p[poll_server + i].revents & POLLOUT),
4004  0 != (p[poll_server + i].revents
4005  & MHD_POLL_REVENTS_ERR_DISC));
4006  i++;
4007  }
4008 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4009  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
4010  {
4011  if (i >= num_connections)
4012  break; /* connection list changed somehow, retry later ... */
4013 
4014  /* Get next connection here as connection can be removed
4015  * from 'daemon->urh_head' list. */
4016  urhn = urh->prev;
4017  /* Check for fd mismatch. FIXME: required for safety? */
4018  if ((p[poll_server + i].fd != urh->connection->socket_fd) ||
4019  (p[poll_server + i + 1].fd != urh->mhd.socket))
4020  break;
4021  urh_from_pollfd (urh,
4022  &p[poll_server + i]);
4023  i += 2;
4024  process_urh (urh);
4025  /* Finished forwarding? */
4026  if ( (0 == urh->in_buffer_size) &&
4027  (0 == urh->out_buffer_size) &&
4028  (0 == urh->in_buffer_used) &&
4029  (0 == urh->out_buffer_used) )
4030  {
4031  /* MHD_connection_finish_forward_() will remove connection from
4032  * 'daemon->urh_head' list. */
4033  MHD_connection_finish_forward_ (urh->connection);
4034  urh->clean_ready = true;
4035  /* If 'urh->was_closed' already was set to true, connection will be
4036  * moved immediately to cleanup list. Otherwise connection
4037  * will stay in suspended list until 'urh' will be marked
4038  * with 'was_closed' by application. */
4039  MHD_resume_connection (urh->connection);
4040  }
4041  }
4042 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4043  /* handle 'listen' FD */
4044  if ( (-1 != poll_listen) &&
4045  (0 != (p[poll_listen].revents & POLLIN)) )
4046  (void) MHD_accept_connection (daemon);
4047 
4048  free (p);
4049  }
4050  return MHD_YES;
4051 }
4052 
4053 
4061 static int
4062 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
4063  int may_block)
4064 {
4065  struct pollfd p[2];
4066  int timeout;
4067  unsigned int poll_count;
4068  int poll_listen;
4069  int poll_itc_idx;
4070  MHD_socket ls;
4071 
4072  memset (&p,
4073  0,
4074  sizeof (p));
4075  poll_count = 0;
4076  poll_listen = -1;
4077  poll_itc_idx = -1;
4078  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4079  (! daemon->was_quiesced) )
4080 
4081  {
4082  p[poll_count].fd = ls;
4083  p[poll_count].events = POLLIN;
4084  p[poll_count].revents = 0;
4085  poll_listen = poll_count;
4086  poll_count++;
4087  }
4088  if (MHD_ITC_IS_VALID_ (daemon->itc))
4089  {
4090  p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
4091  p[poll_count].events = POLLIN;
4092  p[poll_count].revents = 0;
4093  poll_itc_idx = poll_count;
4094  poll_count++;
4095  }
4096 
4097  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
4098  (void) resume_suspended_connections (daemon);
4099 
4100  if (MHD_NO == may_block)
4101  timeout = 0;
4102  else
4103  timeout = -1;
4104  if (0 == poll_count)
4105  return MHD_YES;
4106  if (MHD_sys_poll_ (p,
4107  poll_count,
4108  timeout) < 0)
4109  {
4110  const int err = MHD_socket_get_error_ ();
4111 
4112  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4113  return MHD_YES;
4114 #ifdef HAVE_MESSAGES
4115  MHD_DLOG (daemon,
4116  _ ("poll failed: %s\n"),
4117  MHD_socket_strerr_ (err));
4118 #endif
4119  return MHD_NO;
4120  }
4121  if ( (-1 != poll_itc_idx) &&
4122  (0 != (p[poll_itc_idx].revents & POLLIN)) )
4123  MHD_itc_clear_ (daemon->itc);
4124 
4125  /* handle shutdown */
4126  if (daemon->shutdown)
4127  return MHD_NO;
4128  if ( (-1 != poll_listen) &&
4129  (0 != (p[poll_listen].revents & POLLIN)) )
4130  (void) MHD_accept_connection (daemon);
4131  return MHD_YES;
4132 }
4133 #endif
4134 
4135 
4143 static int
4144 MHD_poll (struct MHD_Daemon *daemon,
4145  int may_block)
4146 {
4147 #ifdef HAVE_POLL
4148  if (daemon->shutdown)
4149  return MHD_NO;
4150  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4151  return MHD_poll_all (daemon,
4152  may_block);
4153  return MHD_poll_listen_socket (daemon,
4154  may_block);
4155 #else
4156  (void) daemon;
4157  (void) may_block;
4158  return MHD_NO;
4159 #endif
4160 }
4161 
4162 
4163 #ifdef EPOLL_SUPPORT
4164 
4173 #define MAX_EVENTS 128
4174 
4175 
4176 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4177 
4185 static bool
4186 is_urh_ready (struct MHD_UpgradeResponseHandle *const urh)
4187 {
4188  const struct MHD_Connection *const connection = urh->connection;
4189 
4190  if ( (0 == urh->in_buffer_size) &&
4191  (0 == urh->out_buffer_size) &&
4192  (0 == urh->in_buffer_used) &&
4193  (0 == urh->out_buffer_used) )
4194  return false;
4195  if (connection->daemon->shutdown)
4196  return true;
4197  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
4198  (connection->tls_read_ready) ) &&
4199  (urh->in_buffer_used < urh->in_buffer_size) )
4200  return true;
4201  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
4202  (urh->out_buffer_used < urh->out_buffer_size) )
4203  return true;
4204  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
4205  (urh->out_buffer_used > 0) )
4206  return true;
4207  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
4208  (urh->in_buffer_used > 0) )
4209  return true;
4210  return false;
4211 }
4212 
4213 
4222 static int
4223 run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4224 {
4225  struct epoll_event events[MAX_EVENTS];
4226  int num_events;
4227  struct MHD_UpgradeResponseHandle *pos;
4228  struct MHD_UpgradeResponseHandle *prev;
4229 
4230  num_events = MAX_EVENTS;
4231  while (0 != num_events)
4232  {
4233  unsigned int i;
4234  /* update event masks */
4235  num_events = epoll_wait (daemon->epoll_upgrade_fd,
4236  events,
4237  MAX_EVENTS,
4238  0);
4239  if (-1 == num_events)
4240  {
4241  const int err = MHD_socket_get_error_ ();
4242 
4243  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4244  return MHD_YES;
4245 #ifdef HAVE_MESSAGES
4246  MHD_DLOG (daemon,
4247  _ ("Call to epoll_wait failed: %s\n"),
4248  MHD_socket_strerr_ (err));
4249 #endif
4250  return MHD_NO;
4251  }
4252  for (i = 0; i < (unsigned int) num_events; i++)
4253  {
4254  struct UpgradeEpollHandle *const ueh = events[i].data.ptr;
4255  struct MHD_UpgradeResponseHandle *const urh = ueh->urh;
4256  bool new_err_state = false;
4257 
4258  if (urh->clean_ready)
4259  continue;
4260 
4261  /* Update ueh state based on what is ready according to epoll() */
4262  if (0 != (events[i].events & EPOLLIN))
4263  ueh->celi |= MHD_EPOLL_STATE_READ_READY;
4264  if (0 != (events[i].events & EPOLLOUT))
4265  ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
4266  if (0 != (events[i].events & EPOLLHUP))
4268 
4269  if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
4270  (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4271  {
4272  /* Process new error state only one time
4273  * and avoid continuously marking this connection
4274  * as 'ready'. */
4275  ueh->celi |= MHD_EPOLL_STATE_ERROR;
4276  new_err_state = true;
4277  }
4278 
4279  if (! urh->in_eready_list)
4280  {
4281  if (new_err_state ||
4282  is_urh_ready (urh))
4283  {
4284  EDLL_insert (daemon->eready_urh_head,
4285  daemon->eready_urh_tail,
4286  urh);
4287  urh->in_eready_list = true;
4288  }
4289  }
4290  }
4291  }
4292  prev = daemon->eready_urh_tail;
4293  while (NULL != (pos = prev))
4294  {
4295  prev = pos->prevE;
4296  process_urh (pos);
4297  if (! is_urh_ready (pos))
4298  {
4299  EDLL_remove (daemon->eready_urh_head,
4300  daemon->eready_urh_tail,
4301  pos);
4302  pos->in_eready_list = false;
4303  }
4304  /* Finished forwarding? */
4305  if ( (0 == pos->in_buffer_size) &&
4306  (0 == pos->out_buffer_size) &&
4307  (0 == pos->in_buffer_used) &&
4308  (0 == pos->out_buffer_used) )
4309  {
4310  MHD_connection_finish_forward_ (pos->connection);
4311  pos->clean_ready = true;
4312  /* If 'pos->was_closed' already was set to true, connection
4313  * will be moved immediately to cleanup list. Otherwise
4314  * connection will stay in suspended list until 'pos' will
4315  * be marked with 'was_closed' by application. */
4316  MHD_resume_connection (pos->connection);
4317  }
4318  }
4319 
4320  return MHD_YES;
4321 }
4322 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4323 
4324 
4328 static const char *const epoll_itc_marker = "itc_marker";
4329 
4330 
4339 static int
4340 MHD_epoll (struct MHD_Daemon *daemon,
4341  int may_block)
4342 {
4343 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4344  static const char *const upgrade_marker = "upgrade_ptr";
4345 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4346  struct MHD_Connection *pos;
4347  struct MHD_Connection *prev;
4348  struct epoll_event events[MAX_EVENTS];
4349  struct epoll_event event;
4350  int timeout_ms;
4351  MHD_UNSIGNED_LONG_LONG timeout_ll;
4352  int num_events;
4353  unsigned int i;
4354  MHD_socket ls;
4355 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4356  bool run_upgraded = false;
4357 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4358 
4359  if (-1 == daemon->epoll_fd)
4360  return MHD_NO; /* we're down! */
4361  if (daemon->shutdown)
4362  return MHD_NO;
4363  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4364  (! daemon->was_quiesced) &&
4365  (daemon->connections < daemon->connection_limit) &&
4366  (! daemon->listen_socket_in_epoll) &&
4367  (! daemon->at_limit) )
4368  {
4369  event.events = EPOLLIN;
4370  event.data.ptr = daemon;
4371  if (0 != epoll_ctl (daemon->epoll_fd,
4372  EPOLL_CTL_ADD,
4373  ls,
4374  &event))
4375  {
4376 #ifdef HAVE_MESSAGES
4377  MHD_DLOG (daemon,
4378  _ ("Call to epoll_ctl failed: %s\n"),
4380 #endif
4381  return MHD_NO;
4382  }
4383  daemon->listen_socket_in_epoll = true;
4384  }
4385  if ( (daemon->was_quiesced) &&
4386  (daemon->listen_socket_in_epoll) )
4387  {
4388  if ( (0 != epoll_ctl (daemon->epoll_fd,
4389  EPOLL_CTL_DEL,
4390  ls,
4391  NULL)) &&
4392  (ENOENT != errno) ) /* ENOENT can happen due to race with
4393  #MHD_quiesce_daemon() */
4394  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4395  daemon->listen_socket_in_epoll = false;
4396  }
4397 
4398 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4399  if ( ( (! daemon->upgrade_fd_in_epoll) &&
4400  (-1 != daemon->epoll_upgrade_fd) ) )
4401  {
4402  event.events = EPOLLIN | EPOLLOUT;
4403  event.data.ptr = (void *) upgrade_marker;
4404  if (0 != epoll_ctl (daemon->epoll_fd,
4405  EPOLL_CTL_ADD,
4406  daemon->epoll_upgrade_fd,
4407  &event))
4408  {
4409 #ifdef HAVE_MESSAGES
4410  MHD_DLOG (daemon,
4411  _ ("Call to epoll_ctl failed: %s\n"),
4413 #endif
4414  return MHD_NO;
4415  }
4416  daemon->upgrade_fd_in_epoll = true;
4417  }
4418 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4419  if ( (daemon->listen_socket_in_epoll) &&
4420  ( (daemon->connections == daemon->connection_limit) ||
4421  (daemon->at_limit) ||
4422  (daemon->was_quiesced) ) )
4423  {
4424  /* we're at the connection limit, disable listen socket
4425  for event loop for now */
4426  if (0 != epoll_ctl (daemon->epoll_fd,
4427  EPOLL_CTL_DEL,
4428  ls,
4429  NULL))
4430  MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n"));
4431  daemon->listen_socket_in_epoll = false;
4432  }
4433 
4434  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
4435  (MHD_YES == resume_suspended_connections (daemon)) )
4436  may_block = MHD_NO;
4437 
4438  if (MHD_YES == may_block)
4439  {
4440  if (MHD_YES == MHD_get_timeout (daemon,
4441  &timeout_ll))
4442  {
4443  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
4444  timeout_ms = INT_MAX;
4445  else
4446  timeout_ms = (int) timeout_ll;
4447  }
4448  else
4449  timeout_ms = -1;
4450  }
4451  else
4452  timeout_ms = 0;
4453 
4454  /* Reset. New value will be set when connections are processed. */
4455  /* Note: Used mostly for uniformity here as same situation is
4456  * signaled in epoll mode by non-empty eready DLL. */
4457  daemon->data_already_pending = false;
4458 
4459  /* drain 'epoll' event queue; need to iterate as we get at most
4460  MAX_EVENTS in one system call here; in practice this should
4461  pretty much mean only one round, but better an extra loop here
4462  than unfair behavior... */
4463  num_events = MAX_EVENTS;
4464  while (MAX_EVENTS == num_events)
4465  {
4466  /* update event masks */
4467  num_events = epoll_wait (daemon->epoll_fd,
4468  events,
4469  MAX_EVENTS,
4470  timeout_ms);
4471  if (-1 == num_events)
4472  {
4473  const int err = MHD_socket_get_error_ ();
4474  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4475  return MHD_YES;
4476 #ifdef HAVE_MESSAGES
4477  MHD_DLOG (daemon,
4478  _ ("Call to epoll_wait failed: %s\n"),
4479  MHD_socket_strerr_ (err));
4480 #endif
4481  return MHD_NO;
4482  }
4483  for (i = 0; i<(unsigned int) num_events; i++)
4484  {
4485  /* First, check for the values of `ptr` that would indicate
4486  that this event is not about a normal connection. */
4487  if (NULL == events[i].data.ptr)
4488  continue; /* shutdown signal! */
4489 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4490  if (upgrade_marker == events[i].data.ptr)
4491  {
4492  /* activity on an upgraded connection, we process
4493  those in a separate epoll() */
4494  run_upgraded = true;
4495  continue;
4496  }
4497 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4498  if (epoll_itc_marker == events[i].data.ptr)
4499  {
4500  /* It's OK to clear ITC here as all external
4501  conditions will be processed later. */
4502  MHD_itc_clear_ (daemon->itc);
4503  continue;
4504  }
4505  if (daemon == events[i].data.ptr)
4506  {
4507  /* Check for error conditions on listen socket. */
4508  /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
4509  if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4510  {
4511  unsigned int series_length = 0;
4512  /* Run 'accept' until it fails or daemon at limit of connections.
4513  * Do not accept more then 10 connections at once. The rest will
4514  * be accepted on next turn (level trigger is used for listen
4515  * socket). */
4516  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
4517  (series_length < 10) &&
4518  (daemon->connections < daemon->connection_limit) &&
4519  (! daemon->at_limit) )
4520  series_length++;
4521  }
4522  continue;
4523  }
4524  /* this is an event relating to a 'normal' connection,
4525  remember the event and if appropriate mark the
4526  connection as 'eready'. */
4527  pos = events[i].data.ptr;
4528  /* normal processing: update read/write data */
4529  if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4530  {
4531  pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
4532  if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
4533  {
4534  EDLL_insert (daemon->eready_head,
4535  daemon->eready_tail,
4536  pos);
4537  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4538  }
4539  }
4540  else
4541  {
4542  if (0 != (events[i].events & EPOLLIN))
4543  {
4544  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
4545  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
4546  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
4547  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4548  {
4549  EDLL_insert (daemon->eready_head,
4550  daemon->eready_tail,
4551  pos);
4552  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4553  }
4554  }
4555  if (0 != (events[i].events & EPOLLOUT))
4556  {
4557  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
4558  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
4559  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4560  {
4561  EDLL_insert (daemon->eready_head,
4562  daemon->eready_tail,
4563  pos);
4564  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4565  }
4566  }
4567  }
4568  }
4569  }
4570 
4571 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4572  if (run_upgraded || (NULL != daemon->eready_urh_head))
4573  run_epoll_for_upgrade (daemon);
4574 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4575 
4576  /* process events for connections */
4577  prev = daemon->eready_tail;
4578  while (NULL != (pos = prev))
4579  {
4580  prev = pos->prevE;
4581  call_handlers (pos,
4582  0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
4583  0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
4584  0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
4586  (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED
4588  {
4589  if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) &&
4590  (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) ||
4592  (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) ||
4594  {
4595  EDLL_remove (daemon->eready_head,
4596  daemon->eready_tail,
4597  pos);
4598  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
4599  }
4600  }
4601  }
4602 
4603  /* Finally, handle timed-out connections; we need to do this here
4604  as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
4605  as the other event loops do. As timeouts do not get an explicit
4606  event, we need to find those connections that might have timed out
4607  here.
4608 
4609  Connections with custom timeouts must all be looked at, as we
4610  do not bother to sort that (presumably very short) list. */
4611  prev = daemon->manual_timeout_tail;
4612  while (NULL != (pos = prev))
4613  {
4614  prev = pos->prevX;
4616  }
4617  /* Connections with the default timeout are sorted by prepending
4618  them to the head of the list whenever we touch the connection;
4619  thus it suffices to iterate from the tail until the first
4620  connection is NOT timed out */
4621  prev = daemon->normal_timeout_tail;
4622  while (NULL != (pos = prev))
4623  {
4624  prev = pos->prevX;
4626  if (MHD_CONNECTION_CLOSED != pos->state)
4627  break; /* sorted by timeout, no need to visit the rest! */
4628  }
4629  return MHD_YES;
4630 }
4631 #endif
4632 
4633 
4654 int
4655 MHD_run (struct MHD_Daemon *daemon)
4656 {
4657  if ( (daemon->shutdown) ||
4658  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
4659  return MHD_NO;
4660  if (0 != (daemon->options & MHD_USE_POLL))
4661  {
4662  MHD_poll (daemon, MHD_NO);
4663  MHD_cleanup_connections (daemon);
4664  }
4665 #ifdef EPOLL_SUPPORT
4666  else if (0 != (daemon->options & MHD_USE_EPOLL))
4667  {
4668  MHD_epoll (daemon, MHD_NO);
4669  MHD_cleanup_connections (daemon);
4670  }
4671 #endif
4672  else
4673  {
4674  MHD_select (daemon, MHD_NO);
4675  /* MHD_select does MHD_cleanup_connections already */
4676  }
4677  return MHD_YES;
4678 }
4679 
4680 
4689 static void
4691 {
4692  struct MHD_Daemon *daemon = pos->daemon;
4693 
4694  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4695  {
4697  return; /* must let thread to do the rest */
4698  }
4699  MHD_connection_close_ (pos,
4701 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4703 #endif
4704  mhd_assert (! pos->suspended);
4705  mhd_assert (! pos->resuming);
4706  if (pos->connection_timeout == daemon->connection_timeout)
4708  daemon->normal_timeout_tail,
4709  pos);
4710  else
4712  daemon->manual_timeout_tail,
4713  pos);
4714  DLL_remove (daemon->connections_head,
4715  daemon->connections_tail,
4716  pos);
4717  DLL_insert (daemon->cleanup_head,
4718  daemon->cleanup_tail,
4719  pos);
4720 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4722 #endif
4723 }
4724 
4725 
4726 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4727 
4734 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4735 MHD_polling_thread (void *cls)
4736 {
4737  struct MHD_Daemon *daemon = cls;
4738 
4739  MHD_thread_init_ (&(daemon->pid));
4740  while (! daemon->shutdown)
4741  {
4742  if (0 != (daemon->options & MHD_USE_POLL))
4743  MHD_poll (daemon, MHD_YES);
4744 #ifdef EPOLL_SUPPORT
4745  else if (0 != (daemon->options & MHD_USE_EPOLL))
4746  MHD_epoll (daemon, MHD_YES);
4747 #endif
4748  else
4749  MHD_select (daemon, MHD_YES);
4750  MHD_cleanup_connections (daemon);
4751  }
4752 
4753  /* Resume any pending for resume connections, join
4754  * all connection's threads (if any) and finally cleanup
4755  * everything. */
4756  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
4758  close_all_connections (daemon);
4759 
4760  return (MHD_THRD_RTRN_TYPE_) 0;
4761 }
4762 #endif
4763 
4764 
4776 static size_t
4777 unescape_wrapper (void *cls,
4778  struct MHD_Connection *connection,
4779  char *val)
4780 {
4781  (void) cls; /* Mute compiler warning. */
4782 
4783  (void) connection; /* Mute compiler warning. */
4784  return MHD_http_unescape (val);
4785 }
4786 
4787 
4808 struct MHD_Daemon *
4809 MHD_start_daemon (unsigned int flags,
4810  uint16_t port,
4812  void *apc_cls,
4814  void *dh_cls,
4815  ...)
4816 {
4817  struct MHD_Daemon *daemon;
4818  va_list ap;
4819 
4820  va_start (ap,
4821  dh_cls);
4822  daemon = MHD_start_daemon_va (flags,
4823  port,
4824  apc,
4825  apc_cls,
4826  dh,
4827  dh_cls,
4828  ap);
4829  va_end (ap);
4830  return daemon;
4831 }
4832 
4833 
4853 MHD_socket
4855 {
4856 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4857  unsigned int i;
4858 #endif
4859  MHD_socket ret;
4860 
4861  ret = daemon->listen_fd;
4862  if (MHD_INVALID_SOCKET == ret)
4863  return MHD_INVALID_SOCKET;
4864  if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
4865  (0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) )
4866  {
4867 #ifdef HAVE_MESSAGES
4868  MHD_DLOG (daemon,
4869  "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4870 #endif
4871  return MHD_INVALID_SOCKET;
4872  }
4873 
4874 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4875  if (NULL != daemon->worker_pool)
4876  for (i = 0; i < daemon->worker_pool_size; i++)
4877  {
4878  daemon->worker_pool[i].was_quiesced = true;
4879 #ifdef EPOLL_SUPPORT
4880  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4881  (-1 != daemon->worker_pool[i].epoll_fd) &&
4882  (daemon->worker_pool[i].listen_socket_in_epoll) )
4883  {
4884  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
4885  EPOLL_CTL_DEL,
4886  ret,
4887  NULL))
4888  MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n"));
4889  daemon->worker_pool[i].listen_socket_in_epoll = false;
4890  }
4891  else
4892 #endif
4893  if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
4894  {
4895  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
4896  MHD_PANIC (_ (
4897  "Failed to signal quiesce via inter-thread communication channel"));
4898  }
4899  }
4900 #endif
4901  daemon->was_quiesced = true;
4902 #ifdef EPOLL_SUPPORT
4903  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4904  (-1 != daemon->epoll_fd) &&
4905  (daemon->listen_socket_in_epoll) )
4906  {
4907  if ( (0 != epoll_ctl (daemon->epoll_fd,
4908  EPOLL_CTL_DEL,
4909  ret,
4910  NULL)) &&
4911  (ENOENT != errno) ) /* ENOENT can happen due to race with
4912  #MHD_epoll() */
4913  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4914  daemon->listen_socket_in_epoll = false;
4915  }
4916 #endif
4917  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
4918  (! MHD_itc_activate_ (daemon->itc, "q")) )
4919  MHD_PANIC (_ (
4920  "failed to signal quiesce via inter-thread communication channel"));
4921  return ret;
4922 }
4923 
4924 
4932 typedef void
4934  const char *format,
4935  va_list va);
4936 
4937 
4946 static int
4947 parse_options_va (struct MHD_Daemon *daemon,
4948  const struct sockaddr **servaddr,
4949  va_list ap);
4950 
4951 
4960 static int
4961 parse_options (struct MHD_Daemon *daemon,
4962  const struct sockaddr **servaddr,
4963  ...)
4964 {
4965  va_list ap;
4966  int ret;
4967 
4968  va_start (ap, servaddr);
4969  ret = parse_options_va (daemon,
4970  servaddr,
4971  ap);
4972  va_end (ap);
4973  return ret;
4974 }
4975 
4976 
4985 static int
4987  const struct sockaddr **servaddr,
4988  va_list ap)
4989 {
4990  enum MHD_OPTION opt;
4991  struct MHD_OptionItem *oa;
4992  unsigned int i;
4993  unsigned int uv;
4994 #ifdef HTTPS_SUPPORT
4995  int ret;
4996  const char *pstr;
4997 #if GNUTLS_VERSION_MAJOR >= 3
4998  gnutls_certificate_retrieve_function2 *pgcrf;
4999 #endif
5000 #if GNUTLS_VERSION_NUMBER >= 0x030603
5001  gnutls_certificate_retrieve_function3 *pgcrf2;
5002 #endif
5003 #endif /* HTTPS_SUPPORT */
5004 
5005  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
5006  {
5007  switch (opt)
5008  {
5010  daemon->pool_size = va_arg (ap,
5011  size_t);
5012  break;
5014  daemon->pool_increment = va_arg (ap,
5015  size_t);
5016  break;
5018  daemon->connection_limit = va_arg (ap,
5019  unsigned int);
5020  break;
5022  uv = va_arg (ap,
5023  unsigned int);
5024  daemon->connection_timeout = (time_t) uv;
5025  /* Next comparison could be always false on some platforms and whole branch will
5026  * be optimized out on those platforms. On others it will be compiled into real
5027  * check. */
5028  if ( ( (MHD_TYPE_IS_SIGNED_ (time_t)) &&
5029  (daemon->connection_timeout < 0) ) || /* Compiler may warn on some platforms, ignore warning. */
5030  (uv != (unsigned int) daemon->connection_timeout) )
5031  {
5032 #ifdef HAVE_MESSAGES
5033  MHD_DLOG (daemon,
5034  _ ("Warning: Too large timeout value, ignored.\n"));
5035 #endif
5036  daemon->connection_timeout = 0;
5037  }
5038  break;
5040  daemon->notify_completed = va_arg (ap,
5042  daemon->notify_completed_cls = va_arg (ap,
5043  void *);
5044  break;
5046  daemon->notify_connection = va_arg (ap,
5048  daemon->notify_connection_cls = va_arg (ap,
5049  void *);
5050  break;
5052  daemon->per_ip_connection_limit = va_arg (ap,
5053  unsigned int);
5054  break;
5055  case MHD_OPTION_SOCK_ADDR:
5056  *servaddr = va_arg (ap,
5057  const struct sockaddr *);
5058  break;
5060  daemon->uri_log_callback = va_arg (ap,
5061  LogCallback);
5062  daemon->uri_log_callback_cls = va_arg (ap,
5063  void *);
5064  break;
5066  daemon->insanity_level = (enum MHD_DisableSanityCheck)
5067  va_arg (ap,
5068  unsigned int);
5069  break;
5070 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5072  daemon->worker_pool_size = va_arg (ap,
5073  unsigned int);
5074  if (0 == daemon->worker_pool_size)
5075  {
5076 #ifdef HAVE_MESSAGES
5077  MHD_DLOG (daemon,
5078  _ (
5079  "Warning: Zero size, specified for thread pool size, is ignored. "
5080  "Thread pool is not used.\n"));
5081 #endif
5082  }
5083  else if (1 == daemon->worker_pool_size)
5084  {
5085 #ifdef HAVE_MESSAGES
5086  MHD_DLOG (daemon,
5087  _ (
5088  "Warning: \"1\", specified for thread pool size, is ignored. "
5089  "Thread pool is not used.\n"));
5090 #endif
5091  daemon->worker_pool_size = 0;
5092  }
5093  /* Next comparison could be always false on some platforms and whole branch will
5094  * be optimized out on those platforms. On others it will be compiled into real
5095  * check. */
5096  else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct
5097  MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */
5098  {
5099 #ifdef HAVE_MESSAGES
5100  MHD_DLOG (daemon,
5101  _ ("Specified thread pool size (%u) too big\n"),
5102  daemon->worker_pool_size);
5103 #endif
5104  return MHD_NO;
5105  }
5106  else
5107  {
5108  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
5109  {
5110 #ifdef HAVE_MESSAGES
5111  MHD_DLOG (daemon,
5112  _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
5113  "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5114 #endif
5115  return MHD_NO;
5116  }
5117  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
5118  {
5119 #ifdef HAVE_MESSAGES
5120  MHD_DLOG (daemon,
5121  _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and "
5122  "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5123 #endif
5124  return MHD_NO;
5125  }
5126  }
5127  break;
5128 #endif
5129 #ifdef HTTPS_SUPPORT
5131  pstr = va_arg (ap,
5132  const char *);
5133  if (0 != (daemon->options & MHD_USE_TLS))
5134  daemon->https_mem_key = pstr;
5135 #ifdef HAVE_MESSAGES
5136  else
5137  MHD_DLOG (daemon,
5138  _ (
5139  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5140  opt);
5141 #endif
5142  break;
5144  pstr = va_arg (ap,
5145  const char *);
5146  if (0 != (daemon->options & MHD_USE_TLS))
5147  daemon->https_key_password = pstr;
5148 #ifdef HAVE_MESSAGES
5149  else
5150  MHD_DLOG (daemon,
5151  _ (
5152  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5153  opt);
5154 #endif
5155  break;
5157  pstr = va_arg (ap,
5158  const char *);
5159  if (0 != (daemon->options & MHD_USE_TLS))
5160  daemon->https_mem_cert = pstr;
5161 #ifdef HAVE_MESSAGES
5162  else
5163  MHD_DLOG (daemon,
5164  _ (
5165  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5166  opt);
5167 #endif
5168  break;
5170  pstr = va_arg (ap,
5171  const char *);
5172  if (0 != (daemon->options & MHD_USE_TLS))
5173  daemon->https_mem_trust = pstr;
5174 #ifdef HAVE_MESSAGES
5175  else
5176  MHD_DLOG (daemon,
5177  _ (
5178  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5179  opt);
5180 #endif
5181  break;
5183  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5184  int);
5185  break;
5187  pstr = va_arg (ap,
5188  const char *);
5189  if (0 != (daemon->options & MHD_USE_TLS))
5190  {
5191  gnutls_datum_t dhpar;
5192  size_t pstr_len;
5193 
5194  if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5195  {
5196 #ifdef HAVE_MESSAGES
5197  MHD_DLOG (daemon,
5198  _ ("Error initializing DH parameters\n"));
5199 #endif
5200  return MHD_NO;
5201  }
5202  dhpar.data = (unsigned char *) pstr;
5203  pstr_len = strlen (pstr);
5204  if (UINT_MAX < pstr_len)
5205  {
5206 #ifdef HAVE_MESSAGES
5207  MHD_DLOG (daemon,
5208  _ ("Diffie-Hellman parameters string too long\n"));
5209 #endif
5210  return MHD_NO;
5211  }
5212  dhpar.size = (unsigned int) pstr_len;
5213  if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5214  &dhpar,
5215  GNUTLS_X509_FMT_PEM) < 0)
5216  {
5217 #ifdef HAVE_MESSAGES
5218  MHD_DLOG (daemon,
5219  _ ("Bad Diffie-Hellman parameters format\n"));
5220 #endif
5221  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5222  return MHD_NO;
5223  }
5224  daemon->have_dhparams = true;
5225  }
5226 #ifdef HAVE_MESSAGES
5227  else
5228  MHD_DLOG (daemon,
5229  _ (
5230  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5231  opt);
5232 #endif
5233  break;
5235  pstr = va_arg (ap,
5236  const char *);
5237  if (0 != (daemon->options & MHD_USE_TLS))
5238  {
5239  gnutls_priority_deinit (daemon->priority_cache);
5240  ret = gnutls_priority_init (&daemon->priority_cache,
5241  pstr,
5242  NULL);
5243  if (GNUTLS_E_SUCCESS != ret)
5244  {
5245 #ifdef HAVE_MESSAGES
5246  MHD_DLOG (daemon,
5247  _ ("Setting priorities to `%s' failed: %s\n"),
5248  pstr,
5249  gnutls_strerror (ret));
5250 #endif
5251  daemon->priority_cache = NULL;
5252  return MHD_NO;
5253  }
5254  }
5255 #ifdef HAVE_MESSAGES
5256  else
5257  MHD_DLOG (daemon,
5258  _ (
5259  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5260  opt);
5261 #endif
5262  break;
5264 #if GNUTLS_VERSION_MAJOR < 3
5265 #ifdef HAVE_MESSAGES
5266  MHD_DLOG (daemon,
5267  _ (
5268  "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5269 #endif
5270  return MHD_NO;
5271 #else
5272  pgcrf = va_arg (ap,
5273  gnutls_certificate_retrieve_function2 *);
5274  if (0 != (daemon->options & MHD_USE_TLS))
5275  daemon->cert_callback = pgcrf;
5276  else
5277 #ifdef HAVE_MESSAGES
5278  MHD_DLOG (daemon,
5279  _ (
5280  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5281  opt);
5282 #endif
5283  break;
5284 #endif
5286 #if GNUTLS_VERSION_NUMBER < 0x030603
5287 #ifdef HAVE_MESSAGES
5288  MHD_DLOG (daemon,
5289  _ (
5290  "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n"));
5291 #endif
5292  return MHD_NO;
5293 #else
5294  pgcrf2 = va_arg (ap,
5295  gnutls_certificate_retrieve_function3 *);
5296  if (0 != (daemon->options & MHD_USE_TLS))
5297  daemon->cert_callback2 = pgcrf2;
5298  else
5299 #ifdef HAVE_MESSAGES
5300  MHD_DLOG (daemon,
5301  _ (
5302  "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5303  opt);
5304 #endif
5305  break;
5306 #endif
5307 #endif /* HTTPS_SUPPORT */
5308 #ifdef DAUTH_SUPPORT
5310  daemon->digest_auth_rand_size = va_arg (ap,
5311  size_t);
5312  daemon->digest_auth_random = va_arg (ap,
5313  const char *);
5314  break;
5316  daemon->nonce_nc_size = va_arg (ap,
5317  unsigned int);
5318  break;
5319 #endif
5321  if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET))
5322  {
5323 #ifdef HAVE_MESSAGES
5324  MHD_DLOG (daemon,
5325  _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon "
5326  "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5327 #endif
5328  return MHD_NO;
5329  }
5330  else
5331  daemon->listen_fd = va_arg (ap,
5332  MHD_socket);
5333  break;
5335 #ifdef HAVE_MESSAGES
5336  daemon->custom_error_log = va_arg (ap,
5338  daemon->custom_error_log_cls = va_arg (ap,
5339  void *);
5340 #else
5341  va_arg (ap,
5343  va_arg (ap,
5344  void *);
5345 #endif
5346  break;
5347 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5349  daemon->thread_stack_size = va_arg (ap,
5350  size_t);
5351  break;
5352 #endif
5354 #ifdef TCP_FASTOPEN
5355  daemon->fastopen_queue_size = va_arg (ap,
5356  unsigned int);
5357  break;
5358 #else /* ! TCP_FASTOPEN */
5359 #ifdef HAVE_MESSAGES
5360  MHD_DLOG (daemon,
5361  _ ("TCP fastopen is not supported on this platform\n"));
5362  return MHD_NO;
5363 #endif /* HAVE_MESSAGES */
5364 #endif /* ! TCP_FASTOPEN */
5366  daemon->listening_address_reuse = va_arg (ap,
5367  unsigned int) ? 1 : -1;
5368  break;
5370  daemon->listen_backlog_size = va_arg (ap,
5371  unsigned int);
5372  break;
5374  daemon->strict_for_client = va_arg (ap, int);
5375 #ifdef HAVE_MESSAGES
5376  if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
5377  (1 != daemon->strict_for_client) )
5378  {
5379  MHD_DLOG (daemon,
5380  _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5381  "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5382  }
5383 #endif /* HAVE_MESSAGES */
5384  break;
5385  case MHD_OPTION_ARRAY:
5386  oa = va_arg (ap, struct MHD_OptionItem*);
5387  i = 0;
5388  while (MHD_OPTION_END != (opt = oa[i].option))
5389  {
5390  switch (opt)
5391  {
5392  /* all options taking 'size_t' */
5396  if (MHD_YES != parse_options (daemon,
5397  servaddr,
5398  opt,
5399  (size_t) oa[i].value,
5400  MHD_OPTION_END))
5401  return MHD_NO;
5402  break;
5403  /* all options taking 'unsigned int' */
5413  if (MHD_YES != parse_options (daemon,
5414  servaddr,
5415  opt,
5416  (unsigned int) oa[i].value,
5417  MHD_OPTION_END))
5418  return MHD_NO;
5419  break;
5420  /* all options taking 'enum' */
5421 #ifdef HTTPS_SUPPORT
5423  if (MHD_YES != parse_options (daemon,
5424  servaddr,
5425  opt,
5426  (gnutls_credentials_type_t) oa[i].value,
5427  MHD_OPTION_END))
5428  return MHD_NO;
5429  break;
5430 #endif /* HTTPS_SUPPORT */
5431  /* all options taking 'MHD_socket' */
5433  if (MHD_YES != parse_options (daemon,
5434  servaddr,
5435  opt,
5436  (MHD_socket) oa[i].value,
5437  MHD_OPTION_END))
5438  return MHD_NO;
5439  break;
5440  /* all options taking 'int' */
5442  if (MHD_YES != parse_options (daemon,
5443  servaddr,
5444  opt,
5445  (int) oa[i].value,
5446  MHD_OPTION_END))
5447  return MHD_NO;
5448  break;
5449  /* all options taking one pointer */
5450  case MHD_OPTION_SOCK_ADDR:
5457  case MHD_OPTION_ARRAY:
5460  if (MHD_YES != parse_options (daemon,
5461  servaddr,
5462  opt,
5463  oa[i].ptr_value,
5464  MHD_OPTION_END))
5465  return MHD_NO;
5466  break;
5467  /* all options taking two pointers */
5474  if (MHD_YES != parse_options (daemon,
5475  servaddr,
5476  opt,
5477  (void *) oa[i].value,
5478  oa[i].ptr_value,
5479  MHD_OPTION_END))
5480  return MHD_NO;
5481  break;
5482  /* options taking size_t-number followed by pointer */
5484  if (MHD_YES != parse_options (daemon,
5485  servaddr,
5486  opt,
5487  (size_t) oa[i].value,
5488  oa[i].ptr_value,
5489  MHD_OPTION_END))
5490  return MHD_NO;
5491  break;
5492  default:
5493  return MHD_NO;
5494  }
5495  i++;
5496  }
5497  break;
5499  daemon->unescape_callback = va_arg (ap,
5501  daemon->unescape_callback_cls = va_arg (ap,
5502  void *);
5503  break;
5504 #ifdef HTTPS_SUPPORT
5506 #if GNUTLS_VERSION_MAJOR >= 3
5507  daemon->cred_callback = va_arg (ap,
5509  daemon->cred_callback_cls = va_arg (ap,
5510  void *);
5511  break;
5512 #else
5513  MHD_DLOG (daemon,
5514  _ (
5515  "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5516  opt);
5517  return MHD_NO;
5518 #endif
5519 #endif /* HTTPS_SUPPORT */
5520  default:
5521 #ifdef HAVE_MESSAGES
5522  if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
5523  (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) ||
5524  (opt == MHD_OPTION_HTTPS_MEM_TRUST) ||
5526  {
5527  MHD_DLOG (daemon,
5528  _ (
5529  "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5530  opt);
5531  }
5532  else
5533  {
5534  MHD_DLOG (daemon,
5535  _ (
5536  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5537  opt);
5538  }
5539 #endif
5540  return MHD_NO;
5541  }
5542  }
5543  return MHD_YES;
5544 }
5545 
5546 
5547 #ifdef EPOLL_SUPPORT
5548 static int
5549 setup_epoll_fd (struct MHD_Daemon *daemon)
5550 {
5551  int fd;
5552 
5553 #ifndef HAVE_MESSAGES
5554  (void) daemon; /* Mute compiler warning. */
5555 #endif /* ! HAVE_MESSAGES */
5556 
5557 #ifdef USE_EPOLL_CREATE1
5558  fd = epoll_create1 (EPOLL_CLOEXEC);
5559 #else /* ! USE_EPOLL_CREATE1 */
5560  fd = epoll_create (MAX_EVENTS);
5561 #endif /* ! USE_EPOLL_CREATE1 */
5562  if (MHD_INVALID_SOCKET == fd)
5563  {
5564 #ifdef HAVE_MESSAGES
5565  MHD_DLOG (daemon,
5566  _ ("Call to epoll_create1 failed: %s\n"),
5568 #endif
5569  return MHD_INVALID_SOCKET;
5570  }
5571 #if ! defined(USE_EPOLL_CREATE1)
5573  {
5574 #ifdef HAVE_MESSAGES
5575  MHD_DLOG (daemon,
5576  _ ("Failed to set noninheritable mode on epoll FD.\n"));
5577 #endif
5578  }
5579 #endif /* ! USE_EPOLL_CREATE1 */
5580  return fd;
5581 }
5582 
5583 
5593 static int
5594 setup_epoll_to_listen (struct MHD_Daemon *daemon)
5595 {
5596  struct epoll_event event;
5597  MHD_socket ls;
5598 
5599  daemon->epoll_fd = setup_epoll_fd (daemon);
5600  if (-1 == daemon->epoll_fd)
5601  return MHD_NO;
5602 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5603  if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
5604  {
5605  daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5606  if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
5607  return MHD_NO;
5608  }
5609 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5610  if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) ||
5611  (daemon->was_quiesced) )
5612  return MHD_YES; /* non-listening daemon */
5613  event.events = EPOLLIN;
5614  event.data.ptr = daemon;
5615  if (0 != epoll_ctl (daemon->epoll_fd,
5616  EPOLL_CTL_ADD,
5617  ls,
5618  &event))
5619  {
5620 #ifdef HAVE_MESSAGES
5621  MHD_DLOG (daemon,
5622  _ ("Call to epoll_ctl failed: %s\n"),
5624 #endif
5625  return MHD_NO;
5626  }
5627  daemon->listen_socket_in_epoll = true;
5628  if (MHD_ITC_IS_VALID_ (daemon->itc))
5629  {
5630  event.events = EPOLLIN;
5631  event.data.ptr = (void *) epoll_itc_marker;
5632  if (0 != epoll_ctl (daemon->epoll_fd,
5633  EPOLL_CTL_ADD,
5634  MHD_itc_r_fd_ (daemon->itc),
5635  &event))
5636  {
5637 #ifdef HAVE_MESSAGES
5638  MHD_DLOG (daemon,
5639  _ ("Call to epoll_ctl failed: %s\n"),
5641 #endif
5642  return MHD_NO;
5643  }
5644  }
5645  return MHD_YES;
5646 }
5647 #endif
5648 
5649 
5671 struct MHD_Daemon *
5672 MHD_start_daemon_va (unsigned int flags,
5673  uint16_t port,
5675  void *apc_cls,
5677  void *dh_cls,
5678  va_list ap)
5679 {
5680  const MHD_SCKT_OPT_BOOL_ on = 1;
5681  struct MHD_Daemon *daemon;
5683  struct sockaddr_in servaddr4;
5684 #if HAVE_INET6
5685  struct sockaddr_in6 servaddr6;
5686 #endif
5687  const struct sockaddr *servaddr = NULL;
5688  socklen_t addrlen;
5689 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5690  unsigned int i;
5691 #endif
5692  enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
5693  enum MHD_FLAG *pflags;
5694 
5696  eflags = (enum MHD_FLAG) flags;
5697  pflags = &eflags;
5698 #ifndef HAVE_INET6
5699  if (0 != (*pflags & MHD_USE_IPv6))
5700  return NULL;
5701 #endif
5702 #ifndef HAVE_POLL
5703  if (0 != (*pflags & MHD_USE_POLL))
5704  return NULL;
5705 #endif
5706 #ifndef EPOLL_SUPPORT
5707  if (0 != (*pflags & MHD_USE_EPOLL))
5708  return NULL;
5709 #endif /* ! EPOLL_SUPPORT */
5710 #ifndef HTTPS_SUPPORT
5711  if (0 != (*pflags & MHD_USE_TLS))
5712  return NULL;
5713 #endif /* ! HTTPS_SUPPORT */
5714 #ifndef TCP_FASTOPEN
5715  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
5716  return NULL;
5717 #endif
5718  if (0 != (*pflags & MHD_ALLOW_UPGRADE))
5719  {
5720 #ifdef UPGRADE_SUPPORT
5721  *pflags |= MHD_ALLOW_SUSPEND_RESUME;
5722 #else /* ! UPGRADE_SUPPORT */
5723  return NULL;
5724 #endif /* ! UPGRADE_SUPPORT */
5725  }
5726  if (NULL == dh)
5727  return NULL;
5728 
5729  /* Check for invalid combinations of flags. */
5730  if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) ||
5731  ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags
5732  &
5734  ||
5735  ((0 != (*pflags & MHD_USE_POLL)) &&
5736  (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD
5738  ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL
5739  | MHD_USE_EPOLL)))) )
5740  return NULL;
5741 
5742  if (0 != (*pflags & MHD_USE_AUTO))
5743  {
5744  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
5745  {
5746  /* Thread per connection with internal polling thread. */
5747 #ifdef HAVE_POLL
5748  *pflags |= MHD_USE_POLL;
5749 #else /* ! HAVE_POLL */
5750  /* use select() - do not modify flags */
5751 #endif /* ! HAVE_POLL */
5752  }
5753  else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5754  {
5755  /* Internal polling thread. */
5756 #if defined(EPOLL_SUPPORT)
5757  *pflags |= MHD_USE_EPOLL;
5758 #elif defined(HAVE_POLL)
5759  *pflags |= MHD_USE_POLL;
5760 #else /* !HAVE_POLL && !EPOLL_SUPPORT */
5761  /* use select() - do not modify flags */
5762 #endif /* !HAVE_POLL && !EPOLL_SUPPORT */
5763  }
5764  else
5765  {
5766  /* Internal threads are not used - "external" polling mode. */
5767 #if defined(EPOLL_SUPPORT)
5768  *pflags |= MHD_USE_EPOLL;
5769 #else /* ! EPOLL_SUPPORT */
5770  /* use select() - do not modify flags */
5771 #endif /* ! EPOLL_SUPPORT */
5772  }
5773  }
5774 
5775  if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
5776  return NULL;
5777 #ifdef EPOLL_SUPPORT
5778  daemon->epoll_fd = -1;
5779 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5780  daemon->epoll_upgrade_fd = -1;
5781 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5782 #endif
5783  /* try to open listen socket */
5784 #ifdef HTTPS_SUPPORT
5785  daemon->priority_cache = NULL;
5786  if (0 != (*pflags & MHD_USE_TLS))
5787  {
5788  gnutls_priority_init (&daemon->priority_cache,
5789  "@SYSTEM",
5790  NULL);
5791  }
5792 #endif /* HTTPS_SUPPORT */
5793  daemon->listen_fd = MHD_INVALID_SOCKET;
5794  daemon->listening_address_reuse = 0;
5795  daemon->options = *pflags;
5796  pflags = &daemon->options;
5797  daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 :
5798  0;
5799  daemon->port = port;
5800  daemon->apc = apc;
5801  daemon->apc_cls = apc_cls;
5802  daemon->default_handler = dh;
5803  daemon->default_handler_cls = dh_cls;
5804  daemon->connections = 0;
5806  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
5807  daemon->pool_increment = MHD_BUF_INC_SIZE;
5809  daemon->connection_timeout = 0; /* no timeout */
5810  MHD_itc_set_invalid_ (daemon->itc);
5811 #ifdef SOMAXCONN
5812  daemon->listen_backlog_size = SOMAXCONN;
5813 #else /* !SOMAXCONN */
5814  daemon->listen_backlog_size = 511; /* should be safe value */
5815 #endif /* !SOMAXCONN */
5816 #ifdef HAVE_MESSAGES
5817  daemon->custom_error_log = &MHD_default_logger_;
5818  daemon->custom_error_log_cls = stderr;
5819 #endif
5820  if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
5821  (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
5822  {
5823 #ifdef HAVE_MESSAGES
5824  MHD_DLOG (daemon,
5825  _ (
5826  "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
5827  "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
5828  "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5829 #endif
5831  }
5832  if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5833  *pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */
5834  else
5835  {
5836 #ifdef HAVE_LISTEN_SHUTDOWN
5837  if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
5838 #endif
5839  *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */
5840  }
5841 #ifdef DAUTH_SUPPORT
5842  daemon->digest_auth_rand_size = 0;
5843  daemon->digest_auth_random = NULL;
5844  daemon->nonce_nc_size = 4; /* tiny */
5845 #endif
5846 #ifdef HTTPS_SUPPORT
5847  if (0 != (*pflags & MHD_USE_TLS))
5848  {
5849  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5850  }
5851 #endif /* HTTPS_SUPPORT */
5852 
5853 
5854  if (MHD_YES != parse_options_va (daemon,
5855  &servaddr,
5856  ap))
5857  {
5858 #ifdef HTTPS_SUPPORT
5859  if ( (0 != (*pflags & MHD_USE_TLS)) &&
5860  (NULL != daemon->priority_cache) )
5861  gnutls_priority_deinit (daemon->priority_cache);
5862 #endif /* HTTPS_SUPPORT */
5863  free (daemon);
5864  return NULL;
5865  }
5866 
5867  if ( (NULL != daemon->notify_completed) &&
5868  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
5869  *pflags |= MHD_USE_ITC; /* requires ITC */
5870 
5871 #ifndef NDEBUG
5872 #ifdef HAVE_MESSAGES
5873  MHD_DLOG (daemon,
5874  _ ("Using debug build of libmicrohttpd.\n") );
5875 #endif /* HAVE_MESSAGES */
5876 #endif /* ! NDEBUG */
5877 
5878  if ( (0 != (*pflags & MHD_USE_ITC))
5879 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5880  && (0 == daemon->worker_pool_size)
5881 #endif
5882  )
5883  {
5884  if (! MHD_itc_init_ (daemon->itc))
5885  {
5886 #ifdef HAVE_MESSAGES
5887  MHD_DLOG (daemon,
5888  _ ("Failed to create inter-thread communication channel: %s\n"),
5889  MHD_itc_last_strerror_ ());
5890 #endif
5891 #ifdef HTTPS_SUPPORT
5892  if (NULL != daemon->priority_cache)
5893  gnutls_priority_deinit (daemon->priority_cache);
5894 #endif /* HTTPS_SUPPORT */
5895  free (daemon);
5896  return NULL;
5897  }
5898  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
5899  (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (daemon->itc),
5900  NULL)) )
5901  {
5902 #ifdef HAVE_MESSAGES
5903  MHD_DLOG (daemon,
5904  _ (
5905  "file descriptor for inter-thread communication channel exceeds maximum value\n"));
5906 #endif
5907  MHD_itc_destroy_chk_ (daemon->itc);
5908 #ifdef HTTPS_SUPPORT
5909  if (NULL != daemon->priority_cache)
5910  gnutls_priority_deinit (daemon->priority_cache);
5911 #endif /* HTTPS_SUPPORT */
5912  free (daemon);
5913  return NULL;
5914  }
5915  }
5916 
5917 #ifdef DAUTH_SUPPORT
5918  if (daemon->nonce_nc_size > 0)
5919  {
5920  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)))
5921  / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
5922  {
5923 #ifdef HAVE_MESSAGES
5924  MHD_DLOG (daemon,
5925  _ ("Specified value for NC_SIZE too large\n"));
5926 #endif
5927 #ifdef HTTPS_SUPPORT
5928  if (0 != (*pflags & MHD_USE_TLS))
5929  gnutls_priority_deinit (daemon->priority_cache);
5930 #endif /* HTTPS_SUPPORT */
5931  free (daemon);
5932  return NULL;
5933  }
5934  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
5935  if (NULL == daemon->nnc)
5936  {
5937 #ifdef HAVE_MESSAGES
5938  MHD_DLOG (daemon,
5939  _ ("Failed to allocate memory for nonce-nc map: %s\n"),
5940  MHD_strerror_ (errno));
5941 #endif
5942 #ifdef HTTPS_SUPPORT
5943  if (0 != (*pflags & MHD_USE_TLS))
5944  gnutls_priority_deinit (daemon->priority_cache);
5945 #endif /* HTTPS_SUPPORT */
5946  free (daemon);
5947  return NULL;
5948  }
5949  }
5950 
5951 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5952  if (! MHD_mutex_init_ (&daemon->nnc_lock))
5953  {
5954 #ifdef HAVE_MESSAGES
5955  MHD_DLOG (daemon,
5956  _ ("MHD failed to initialize nonce-nc mutex\n"));
5957 #endif
5958 #ifdef HTTPS_SUPPORT
5959  if (0 != (*pflags & MHD_USE_TLS))
5960  gnutls_priority_deinit (daemon->priority_cache);
5961 #endif /* HTTPS_SUPPORT */
5962  free (daemon->nnc);
5963  free (daemon);
5964  return NULL;
5965  }
5966 #endif
5967 #endif
5968 
5969  /* Thread pooling currently works only with internal select thread mode */
5970 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5971  if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
5972  (daemon->worker_pool_size > 0) )
5973  {
5974 #ifdef HAVE_MESSAGES
5975  MHD_DLOG (daemon,
5976  _ (
5977  "MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5978 #endif
5979  goto free_and_fail;
5980  }
5981 #endif
5982  if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
5983  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
5984  {
5985  /* try to open listen socket */
5986  int domain;
5987 
5988 #ifdef HAVE_INET6
5989  domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5990 #else /* ! HAVE_INET6 */
5991  if (*pflags & MHD_USE_IPv6)
5992  goto free_and_fail;
5993  domain = PF_INET;
5994 #endif /* ! HAVE_INET6 */
5995 
5996  listen_fd = MHD_socket_create_listen_ (domain);
5997  if (MHD_INVALID_SOCKET == listen_fd)
5998  {
5999 #ifdef HAVE_MESSAGES
6000  MHD_DLOG (daemon,
6001  _ ("Failed to create socket for listening: %s\n"),
6003 #endif
6004  goto free_and_fail;
6005  }
6006 
6007  /* Apply the socket options according to listening_address_reuse. */
6008  if (0 == daemon->listening_address_reuse)
6009  {
6010 #ifndef MHD_WINSOCK_SOCKETS
6011  /* No user requirement, use "traditional" default SO_REUSEADDR
6012  * on non-W32 platforms, and do not fail if it doesn't work.
6013  * Don't use it on W32, because on W32 it will allow multiple
6014  * bind to the same address:port, like SO_REUSEPORT on others. */
6015  if (0 > setsockopt (listen_fd,
6016  SOL_SOCKET,
6017  SO_REUSEADDR,
6018  (void*) &on, sizeof (on)))
6019  {
6020 #ifdef HAVE_MESSAGES
6021  MHD_DLOG (daemon,
6022  _ ("setsockopt failed: %s\n"),
6024 #endif
6025  }
6026 #endif /* ! MHD_WINSOCK_SOCKETS */
6027  }
6028  else if (daemon->listening_address_reuse > 0)
6029  {
6030  /* User requested to allow reusing listening address:port. */
6031 #ifndef MHD_WINSOCK_SOCKETS
6032  /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
6033  * it doesn't work. */
6034  if (0 > setsockopt (listen_fd,
6035  SOL_SOCKET,
6036  SO_REUSEADDR,
6037  (void*) &on, sizeof (on)))
6038  {
6039 #ifdef HAVE_MESSAGES
6040  MHD_DLOG (daemon,
6041  _ ("setsockopt failed: %s\n"),
6043 #endif
6044  }
6045 #endif /* ! MHD_WINSOCK_SOCKETS */
6046  /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
6047  * Fail if SO_REUSEPORT is not defined or setsockopt fails.
6048  */
6049  /* SO_REUSEADDR on W32 has the same semantics
6050  as SO_REUSEPORT on BSD/Linux */
6051 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
6052  if (0 > setsockopt (listen_fd,
6053  SOL_SOCKET,
6054 #ifndef MHD_WINSOCK_SOCKETS
6055  SO_REUSEPORT,
6056 #else /* MHD_WINSOCK_SOCKETS */
6057  SO_REUSEADDR,
6058 #endif /* MHD_WINSOCK_SOCKETS */
6059  (void *) &on,
6060  sizeof (on)))
6061  {
6062 #ifdef HAVE_MESSAGES
6063  MHD_DLOG (daemon,
6064  _ ("setsockopt failed: %s\n"),
6066 #endif
6067  goto free_and_fail;
6068  }
6069 #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
6070  /* we're supposed to allow address:port re-use, but
6071  on this platform we cannot; fail hard */
6072 #ifdef HAVE_MESSAGES
6073  MHD_DLOG (daemon,
6074  _ (
6075  "Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
6076 #endif
6077  goto free_and_fail;
6078 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
6079  }
6080  else /* if (daemon->listening_address_reuse < 0) */
6081  {
6082  /* User requested to disallow reusing listening address:port.
6083  * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
6084  * is used and Solaris with SO_EXCLBIND.
6085  * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
6086  * or setsockopt fails.
6087  */
6088 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
6089  (defined(__sun) && defined(SO_EXCLBIND))
6090  if (0 > setsockopt (listen_fd,
6091  SOL_SOCKET,
6092 #ifdef SO_EXCLUSIVEADDRUSE
6093  SO_EXCLUSIVEADDRUSE,
6094 #else /* SO_EXCLBIND */
6095  SO_EXCLBIND,
6096 #endif /* SO_EXCLBIND */
6097  (void *) &on,
6098  sizeof (on)))
6099  {
6100 #ifdef HAVE_MESSAGES
6101  MHD_DLOG (daemon,
6102  _ ("setsockopt failed: %s\n"),
6104 #endif
6105  goto free_and_fail;
6106  }
6107 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
6108 #ifdef HAVE_MESSAGES
6109  MHD_DLOG (daemon,
6110  _ (
6111  "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
6112 #endif
6113  goto free_and_fail;
6114 #endif /* MHD_WINSOCK_SOCKETS */
6115  }
6116 
6117  /* check for user supplied sockaddr */
6118 #if HAVE_INET6
6119  if (0 != (*pflags & MHD_USE_IPv6))
6120  addrlen = sizeof (struct sockaddr_in6);
6121  else
6122 #endif
6123  addrlen = sizeof (struct sockaddr_in);
6124  if (NULL == servaddr)
6125  {
6126 #if HAVE_INET6
6127  if (0 != (*pflags & MHD_USE_IPv6))
6128  {
6129 #ifdef IN6ADDR_ANY_INIT
6130  static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6131 #endif
6132  memset (&servaddr6,
6133  0,
6134  sizeof (struct sockaddr_in6));
6135  servaddr6.sin6_family = AF_INET6;
6136  servaddr6.sin6_port = htons (port);
6137 #ifdef IN6ADDR_ANY_INIT
6138  servaddr6.sin6_addr = static_in6any;
6139 #endif
6140 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
6141  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
6142 #endif
6143  servaddr = (struct sockaddr *) &servaddr6;
6144  }
6145  else
6146 #endif
6147  {
6148  memset (&servaddr4,
6149  0,
6150  sizeof (struct sockaddr_in));
6151  servaddr4.sin_family = AF_INET;
6152  servaddr4.sin_port = htons (port);
6153  if (0 != INADDR_ANY)
6154  servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6155 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
6156  servaddr4.sin_len = sizeof (struct sockaddr_in);
6157 #endif
6158  servaddr = (struct sockaddr *) &servaddr4;
6159  }
6160  }
6161  daemon->listen_fd = listen_fd;
6162 
6163  if (0 != (*pflags & MHD_USE_IPv6))
6164  {
6165 #ifdef IPPROTO_IPV6
6166 #ifdef IPV6_V6ONLY
6167  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
6168  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
6169  and may also be missing on older POSIX systems; good luck if you have any of those,
6170  your IPv6 socket may then also bind against IPv4 anyway... */
6171  const MHD_SCKT_OPT_BOOL_ v6_only =
6172  (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
6173  if (0 > setsockopt (listen_fd,
6174  IPPROTO_IPV6, IPV6_V6ONLY,
6175  (const void *) &v6_only,
6176  sizeof (v6_only)))
6177  {
6178 #ifdef HAVE_MESSAGES
6179  MHD_DLOG (daemon,
6180  _ ("setsockopt failed: %s\n"),
6182 #endif
6183  }
6184 #endif
6185 #endif
6186  }
6187  if (-1 == bind (listen_fd, servaddr, addrlen))
6188  {
6189 #ifdef HAVE_MESSAGES
6190  MHD_DLOG (daemon,
6191  _ ("Failed to bind to port %u: %s\n"),
6192  (unsigned int) port,
6194 #endif
6195  MHD_socket_close_chk_ (listen_fd);
6196  goto free_and_fail;
6197  }
6198 #ifdef TCP_FASTOPEN
6199  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
6200  {
6201  if (0 == daemon->fastopen_queue_size)
6202  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6203  if (0 != setsockopt (listen_fd,
6204  IPPROTO_TCP,
6205  TCP_FASTOPEN,
6206  (const void*) &daemon->fastopen_queue_size,
6207  sizeof (daemon->fastopen_queue_size)))
6208  {
6209 #ifdef HAVE_MESSAGES
6210  MHD_DLOG (daemon,
6211  _ ("setsockopt failed: %s\n"),
6213 #endif
6214  }
6215  }
6216 #endif
6217  if (listen (listen_fd,
6218  daemon->listen_backlog_size) < 0)
6219  {
6220 #ifdef HAVE_MESSAGES
6221  MHD_DLOG (daemon,
6222  _ ("Failed to listen for connections: %s\n"),
6224 #endif
6225  MHD_socket_close_chk_ (listen_fd);
6226  goto free_and_fail;
6227  }
6228  }
6229  else
6230  {
6231  listen_fd = daemon->listen_fd;
6232  }
6233 
6234 #ifdef HAVE_GETSOCKNAME
6235  if ( (0 == daemon->port) &&
6236  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6237  { /* Get port number. */
6238  struct sockaddr_storage bindaddr;
6239 
6240  memset (&bindaddr,
6241  0,
6242  sizeof (struct sockaddr_storage));
6243  addrlen = sizeof (struct sockaddr_storage);
6244 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
6245  bindaddr.ss_len = addrlen;
6246 #endif
6247  if (0 != getsockname (listen_fd,
6248  (struct sockaddr *) &bindaddr,
6249  &addrlen))
6250  {
6251 #ifdef HAVE_MESSAGES
6252  MHD_DLOG (daemon,
6253  _ ("Failed to get listen port number: %s\n"),
6255 #endif /* HAVE_MESSAGES */
6256  }
6257 #ifdef MHD_POSIX_SOCKETS
6258  else if (sizeof (bindaddr) < addrlen)
6259  {
6260  /* should be impossible with `struct sockaddr_storage` */
6261 #ifdef HAVE_MESSAGES
6262  MHD_DLOG (daemon,
6263  _ (
6264  "Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6265 #endif /* HAVE_MESSAGES */
6266  }
6267 #ifndef __linux__
6268  else if (0 == addrlen)
6269  {
6270  /* Many non-Linux-based platforms return zero addrlen
6271  * for AF_UNIX sockets */
6272  daemon->port = 0; /* special value for UNIX domain sockets */
6273  }
6274 #endif /* __linux__ */
6275 #endif /* MHD_POSIX_SOCKETS */
6276  else
6277  {
6278  switch (bindaddr.ss_family)
6279  {
6280  case AF_INET:
6281  {
6282  struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr;
6283 
6284  daemon->port = ntohs (s4->sin_port);
6285  break;
6286  }
6287 #ifdef HAVE_INET6
6288  case AF_INET6:
6289  {
6290  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr;
6291 
6292  daemon->port = ntohs (s6->sin6_port);
6293  mhd_assert (0 != (*pflags & MHD_USE_IPv6));
6294  break;
6295  }
6296 #endif /* HAVE_INET6 */
6297 #ifdef AF_UNIX
6298  case AF_UNIX:
6299  daemon->port = 0; /* special value for UNIX domain sockets */
6300  break;
6301 #endif
6302  default:
6303 #ifdef HAVE_MESSAGES
6304  MHD_DLOG (daemon,
6305  _ ("Unknown address family!\n"));
6306 #endif
6307  daemon->port = 0; /* ugh */
6308  break;
6309  }
6310  }
6311  }
6312 #endif /* HAVE_GETSOCKNAME */
6313  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6314  (! MHD_socket_nonblocking_ (listen_fd)) )
6315  {
6316 #ifdef HAVE_MESSAGES
6317  MHD_DLOG (daemon,
6318  _ ("Failed to set nonblocking mode on listening socket: %s\n"),
6320 #endif
6321  if (0 != (*pflags & MHD_USE_EPOLL)
6322 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6323  || (daemon->worker_pool_size > 0)
6324 #endif
6325  )
6326  {
6327  /* Accept must be non-blocking. Multiple children may wake up
6328  * to handle a new connection, but only one will win the race.
6329  * The others must immediately return. */
6330  MHD_socket_close_chk_ (listen_fd);
6331  goto free_and_fail;
6332  }
6333  }
6334  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6335  (! MHD_SCKT_FD_FITS_FDSET_ (listen_fd,
6336  NULL)) &&
6337  (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
6338  {
6339 #ifdef HAVE_MESSAGES
6340  MHD_DLOG (daemon,
6341  _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6342  listen_fd,
6343  FD_SETSIZE);
6344 #endif
6345  MHD_socket_close_chk_ (listen_fd);
6346  goto free_and_fail;
6347  }
6348 
6349 #ifdef EPOLL_SUPPORT
6350  if ( (0 != (*pflags & MHD_USE_EPOLL))
6351 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6352  && (0 == daemon->worker_pool_size)
6353 #endif
6354  )
6355  {
6356  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6357  {
6358 #ifdef HAVE_MESSAGES
6359  MHD_DLOG (daemon,
6360  _ (
6361  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6362 #endif
6363  goto free_and_fail;
6364  }
6365  if (MHD_YES != setup_epoll_to_listen (daemon))
6366  goto free_and_fail;
6367  }
6368 #endif /* EPOLL_SUPPORT */
6369 
6370 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6371  if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
6372  {
6373 #ifdef HAVE_MESSAGES
6374  MHD_DLOG (daemon,
6375  _ ("MHD failed to initialize IP connection limit mutex\n"));
6376 #endif
6377  if (MHD_INVALID_SOCKET != listen_fd)
6378  MHD_socket_close_chk_ (listen_fd);
6379  goto free_and_fail;
6380  }
6381  if (0 == daemon->worker_pool_size)
6382  { /* Initialise connection mutex only if this daemon will handle
6383  * any connections by itself. */
6384  if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
6385  {
6386 #ifdef HAVE_MESSAGES
6387  MHD_DLOG (daemon,
6388  _ ("MHD failed to initialize IP connection limit mutex\n"));
6389 #endif
6390 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6392 #endif
6393  if (MHD_INVALID_SOCKET != listen_fd)
6394  MHD_socket_close_chk_ (listen_fd);
6395  goto free_and_fail;
6396  }
6397  }
6398 #endif
6399 
6400 #ifdef HTTPS_SUPPORT
6401  /* initialize HTTPS daemon certificate aspects & send / recv functions */
6402  if ( (0 != (*pflags & MHD_USE_TLS)) &&
6403  (0 != MHD_TLS_init (daemon)) )
6404  {
6405 #ifdef HAVE_MESSAGES
6406  MHD_DLOG (daemon,
6407  _ ("Failed to initialize TLS support\n"));
6408 #endif
6409  if (MHD_INVALID_SOCKET != listen_fd)
6410  MHD_socket_close_chk_ (listen_fd);
6411 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6412  if (0 == daemon->worker_pool_size)
6415 #endif
6416  goto free_and_fail;
6417  }
6418 #endif /* HTTPS_SUPPORT */
6419 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6420  if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
6421  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6422  {
6423  if (0 == daemon->worker_pool_size)
6424  {
6425  if (! MHD_create_named_thread_ (&daemon->pid,
6426  (*pflags
6428  "MHD-listen" : "MHD-single",
6429  daemon->thread_stack_size,
6431  daemon) )
6432  {
6433 #ifdef HAVE_MESSAGES
6434  MHD_DLOG (daemon,
6435  _ ("Failed to create listen thread: %s\n"),
6436  MHD_strerror_ (errno));
6437 #endif
6440  if (MHD_INVALID_SOCKET != listen_fd)
6441  MHD_socket_close_chk_ (listen_fd);
6442  goto free_and_fail;
6443  }
6444  }
6445  else /* 0 < daemon->worker_pool_size */
6446  {
6447  /* Coarse-grained count of connections per thread (note error
6448  * due to integer division). Also keep track of how many
6449  * connections are leftover after an equal split. */
6450  unsigned int conns_per_thread = daemon->connection_limit
6451  / daemon->worker_pool_size;
6452  unsigned int leftover_conns = daemon->connection_limit
6453  % daemon->worker_pool_size;
6454 
6455  i = 0; /* we need this in case fcntl or malloc fails */
6456 
6457  /* Allocate memory for pooled objects */
6458  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
6459  * daemon->worker_pool_size);
6460  if (NULL == daemon->worker_pool)
6461  goto thread_failed;
6462 
6463  /* Start the workers in the pool */
6464  for (i = 0; i < daemon->worker_pool_size; ++i)
6465  {
6466  /* Create copy of the Daemon object for each worker */
6467  struct MHD_Daemon *d = &daemon->worker_pool[i];
6468 
6469  memcpy (d, daemon, sizeof (struct MHD_Daemon));
6470  /* Adjust pooling params for worker daemons; note that memcpy()
6471  has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
6472  the worker threads. */
6473  d->master = daemon;
6474  d->worker_pool_size = 0;
6475  d->worker_pool = NULL;
6476 
6477  if (0 != (*pflags & MHD_USE_ITC))
6478  {
6479  if (! MHD_itc_init_ (d->itc))
6480  {
6481 #ifdef HAVE_MESSAGES
6482  MHD_DLOG (daemon,
6483  _ (
6484  "Failed to create worker inter-thread communication channel: %s\n"),
6485  MHD_itc_last_strerror_ () );
6486 #endif
6487  goto thread_failed;
6488  }
6489  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
6490  (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (d->itc),
6491  NULL)) )
6492  {
6493 #ifdef HAVE_MESSAGES
6494  MHD_DLOG (daemon,
6495  _ (
6496  "File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6497 #endif
6499  goto thread_failed;
6500  }
6501  }
6502  else
6503  MHD_itc_set_invalid_ (d->itc);
6504 
6505  /* Divide available connections evenly amongst the threads.
6506  * Thread indexes in [0, leftover_conns) each get one of the
6507  * leftover connections. */
6508  d->connection_limit = conns_per_thread;
6509  if (i < leftover_conns)
6510  ++d->connection_limit;
6511 #ifdef EPOLL_SUPPORT
6512  if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
6513  (MHD_YES != setup_epoll_to_listen (d)) )
6514  goto thread_failed;
6515 #endif
6516  /* Must init cleanup connection mutex for each worker */
6517  if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
6518  {
6519 #ifdef HAVE_MESSAGES
6520  MHD_DLOG (daemon,
6521  _ ("MHD failed to initialize cleanup connection mutex\n"));
6522 #endif
6523  goto thread_failed;
6524  }
6525 
6526  /* Spawn the worker thread */
6527  if (! MHD_create_named_thread_ (&d->pid,
6528  "MHD-worker",
6529  daemon->thread_stack_size,
6531  d))
6532  {
6533 #ifdef HAVE_MESSAGES
6534  MHD_DLOG (daemon,
6535  _ ("Failed to create pool thread: %s\n"),
6536  MHD_strerror_ (errno));
6537 #endif
6538  /* Free memory for this worker; cleanup below handles
6539  * all previously-created workers. */
6541  goto thread_failed;
6542  }
6543  }
6544  }
6545  }
6546 #endif
6547 #ifdef HTTPS_SUPPORT
6548  /* API promises to never use the password after initialization,
6549  so we additionally NULL it here to not deref a dangling pointer. */
6550  daemon->https_key_password = NULL;
6551 #endif /* HTTPS_SUPPORT */
6552 
6553  return daemon;
6554 
6555 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6556  thread_failed:
6557  /* If no worker threads created, then shut down normally. Calling
6558  MHD_stop_daemon (as we do below) doesn't work here since it
6559  assumes a 0-sized thread pool means we had been in the default
6560  MHD_USE_INTERNAL_POLLING_THREAD mode. */
6561  if (0 == i)
6562  {
6566  if (NULL != daemon->worker_pool)
6567  free (daemon->worker_pool);
6568  goto free_and_fail;
6569  }
6570 
6571  /* Shutdown worker threads we've already created. Pretend
6572  as though we had fully initialized our daemon, but
6573  with a smaller number of threads than had been
6574  requested. */
6575  daemon->worker_pool_size = i;
6576  MHD_stop_daemon (daemon);
6577  return NULL;
6578 #endif
6579 
6580  free_and_fail:
6581  /* clean up basic memory state in 'daemon' and return NULL to
6582  indicate failure */
6583 #ifdef EPOLL_SUPPORT
6584 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6585  if (daemon->upgrade_fd_in_epoll)
6586  {
6587  if (0 != epoll_ctl (daemon->epoll_fd,
6588  EPOLL_CTL_DEL,
6589  daemon->epoll_upgrade_fd,
6590  NULL))
6591  MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
6592  daemon->upgrade_fd_in_epoll = false;
6593  }
6594 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6595  if (-1 != daemon->epoll_fd)
6596  close (daemon->epoll_fd);
6597 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6598  if (-1 != daemon->epoll_upgrade_fd)
6599  close (daemon->epoll_upgrade_fd);
6600 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6601 #endif /* EPOLL_SUPPORT */
6602 #ifdef DAUTH_SUPPORT
6603  free (daemon->nnc);
6604 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6605  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6606 #endif
6607 #endif
6608 #ifdef HTTPS_SUPPORT
6609  if (0 != (*pflags & MHD_USE_TLS))
6610  {
6611  gnutls_priority_deinit (daemon->priority_cache);
6612  if (daemon->x509_cred)
6613  gnutls_certificate_free_credentials (daemon->x509_cred);
6614  if (daemon->psk_cred)
6615  gnutls_psk_free_server_credentials (daemon->psk_cred);
6616  }
6617 #endif /* HTTPS_SUPPORT */
6618  if (MHD_ITC_IS_VALID_ (daemon->itc))
6619  MHD_itc_destroy_chk_ (daemon->itc);
6620  free (daemon);
6621  return NULL;
6622 }
6623 
6624 
6633 static void
6635 {
6636  struct MHD_Connection *pos;
6637  const bool used_thr_p_c = (0 != (daemon->options
6639 #ifdef UPGRADE_SUPPORT
6640  const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
6641 #endif /* UPGRADE_SUPPORT */
6642 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6643  struct MHD_UpgradeResponseHandle *urh;
6644  struct MHD_UpgradeResponseHandle *urhn;
6645  const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
6646 
6647 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6648  mhd_assert (NULL == daemon->worker_pool);
6649 #endif
6650  mhd_assert (daemon->shutdown);
6651  /* give upgraded HTTPS connections a chance to finish */
6652  /* 'daemon->urh_head' is not used in thread-per-connection mode. */
6653  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
6654  {
6655  urhn = urh->prev;
6656  /* call generic forwarding function for passing data
6657  with chance to detect that application is done. */
6658  process_urh (urh);
6659  MHD_connection_finish_forward_ (urh->connection);
6660  urh->clean_ready = true;
6661  /* Resuming will move connection to cleanup list. */
6662  MHD_resume_connection (urh->connection);
6663  }
6664 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6665 
6666  /* Give suspended connections a chance to resume to avoid
6667  running into the check for there not being any suspended
6668  connections left in case of a tight race with a recently
6669  resumed connection. */
6670  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
6671  {
6672  daemon->resuming = true; /* Force check for pending resume. */
6674  }
6675  /* first, make sure all threads are aware of shutdown; need to
6676  traverse DLLs in peace... */
6677 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6679 #endif
6680 #ifdef UPGRADE_SUPPORT
6681  if (upg_allowed)
6682  {
6683  struct MHD_Connection *susp;
6684 
6686  while (NULL != susp)
6687  {
6688  if (NULL == susp->urh) /* "Upgraded" connection? */
6689  MHD_PANIC (_ (
6690  "MHD_stop_daemon() called while we have suspended connections.\n"));
6691 #ifdef HTTPS_SUPPORT
6692  else if (used_tls &&
6693  used_thr_p_c &&
6694  (! susp->urh->clean_ready) )
6695  shutdown (susp->urh->app.socket,
6696  SHUT_RDWR); /* Wake thread by shutdown of app socket. */
6697 #endif /* HTTPS_SUPPORT */
6698  else
6699  {
6700 #ifdef HAVE_MESSAGES
6701  if (! susp->urh->was_closed)
6702  MHD_DLOG (daemon,
6703  _ (
6704  "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6705 #endif
6706  susp->urh->was_closed = true;
6707  /* If thread-per-connection is used, connection's thread
6708  * may still processing "upgrade" (exiting). */
6709  if (! used_thr_p_c)
6711  /* Do not use MHD_resume_connection() as mutex is
6712  * already locked. */
6713  susp->resuming = true;
6714  daemon->resuming = true;
6715  }
6716  susp = susp->prev;
6717  }
6718  }
6719  else /* This 'else' is combined with next 'if' */
6720 #endif /* UPGRADE_SUPPORT */
6722  MHD_PANIC (_ (
6723  "MHD_stop_daemon() called while we have suspended connections.\n"));
6724  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
6725  {
6726  shutdown (pos->socket_fd,
6727  SHUT_RDWR);
6728 #if MHD_WINSOCK_SOCKETS
6729  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6730  (MHD_ITC_IS_VALID_ (daemon->itc)) &&
6731  (! MHD_itc_activate_ (daemon->itc, "e")) )
6732  MHD_PANIC (_ (
6733  "Failed to signal shutdown via inter-thread communication channel"));
6734 #endif
6735  }
6736 
6737 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6738  /* now, collect per-connection threads */
6739  if (used_thr_p_c)
6740  {
6741  pos = daemon->connections_tail;
6742  while (NULL != pos)
6743  {
6744  if (! pos->thread_joined)
6745  {
6747  if (! MHD_join_thread_ (pos->pid.handle))
6748  MHD_PANIC (_ ("Failed to join a thread\n"));
6750  pos->thread_joined = true;
6751  /* The thread may have concurrently modified the DLL,
6752  need to restart from the beginning */
6753  pos = daemon->connections_tail;
6754  continue;
6755  }
6756  pos = pos->prev;
6757  }
6758  }
6760 #endif
6761 
6762 #ifdef UPGRADE_SUPPORT
6763  /* Finished threads with "upgraded" connections need to be moved
6764  * to cleanup list by resume_suspended_connections(). */
6765  /* "Upgraded" connections that were not closed explicitly by
6766  * application should be moved to cleanup list too. */
6767  if (upg_allowed)
6768  {
6769  daemon->resuming = true; /* Force check for pending resume. */
6771  }
6772 #endif /* UPGRADE_SUPPORT */
6773 
6774  /* now that we're alone, move everyone to cleanup */
6775  while (NULL != (pos = daemon->connections_tail))
6776  {
6777 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6778  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6779  (! pos->thread_joined) )
6780  MHD_PANIC (_ ("Failed to join a thread\n"));
6781 #endif
6782  close_connection (pos);
6783  }
6785 }
6786 
6787 
6794 void
6796 {
6797  MHD_socket fd;
6798 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6799  unsigned int i;
6800 #endif
6801 
6802  if (NULL == daemon)
6803  return;
6804 
6805  daemon->shutdown = true;
6806  if (daemon->was_quiesced)
6807  fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
6808  else
6809  fd = daemon->listen_fd;
6810 
6811 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6812  if (NULL != daemon->worker_pool)
6813  { /* Master daemon with worker pool. */
6816 
6817  /* Let workers shutdown in parallel. */
6818  for (i = 0; i < daemon->worker_pool_size; ++i)
6819  {
6820  daemon->worker_pool[i].shutdown = true;
6821  if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc))
6822  {
6823  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
6824  "e"))
6825  MHD_PANIC (_ (
6826  "Failed to signal shutdown via inter-thread communication channel."));
6827  }
6828  else
6830  }
6831 #ifdef HAVE_LISTEN_SHUTDOWN
6832  if (MHD_INVALID_SOCKET != fd)
6833  {
6834  (void) shutdown (fd,
6835  SHUT_RDWR);
6836  }
6837 #endif /* HAVE_LISTEN_SHUTDOWN */
6838  for (i = 0; i < daemon->worker_pool_size; ++i)
6839  {
6841  }
6842  free (daemon->worker_pool);
6844 #ifdef EPOLL_SUPPORT
6845  mhd_assert (-1 == daemon->epoll_fd);
6846 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6847  mhd_assert (-1 == daemon->epoll_upgrade_fd);
6848 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6849 #endif /* EPOLL_SUPPORT */
6850  }
6851  else
6852 #endif
6853  { /* Worker daemon or single daemon. */
6854 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6856  { /* Worker daemon or single daemon with internal thread(s). */
6858  /* Separate thread(s) is used for polling sockets. */
6859  if (MHD_ITC_IS_VALID_ (daemon->itc))
6860  {
6861  if (! MHD_itc_activate_ (daemon->itc,
6862  "e"))
6863  MHD_PANIC (_ (
6864  "Failed to signal shutdown via inter-thread communication channel"));
6865  }
6866  else
6867  {
6868 #ifdef HAVE_LISTEN_SHUTDOWN
6869  if (MHD_INVALID_SOCKET != fd)
6870  {
6871  if (NULL == daemon->master)
6872  (void) shutdown (fd,
6873  SHUT_RDWR);
6874  }
6875  else
6876 #endif /* HAVE_LISTEN_SHUTDOWN */
6877  mhd_assert (false); /* Should never happen */
6878  }
6879 
6880  if (! MHD_join_thread_ (daemon->pid.handle))
6881  {
6882  MHD_PANIC (_ ("Failed to join a thread\n"));
6883  }
6884  /* close_all_connections() was called in daemon thread. */
6885  }
6886  else
6887 #endif
6888  {
6889  /* No internal threads are used for polling sockets. */
6891  }
6892  if (MHD_ITC_IS_VALID_ (daemon->itc))
6894 
6895 #ifdef EPOLL_SUPPORT
6896  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6897  (-1 != daemon->epoll_fd) )
6898  MHD_socket_close_chk_ (daemon->epoll_fd);
6899 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6900  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6901  (-1 != daemon->epoll_upgrade_fd) )
6902  MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
6903 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6904 #endif /* EPOLL_SUPPORT */
6905 
6906 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6908 #endif
6909  }
6910 
6911  if (NULL == daemon->master)
6912  { /* Cleanup that should be done only one time in master/single daemon.
6913  * Do not perform this cleanup in worker daemons. */
6914 
6915  if (MHD_INVALID_SOCKET != fd)
6917 
6918  /* TLS clean up */
6919 #ifdef HTTPS_SUPPORT
6920  if (daemon->have_dhparams)
6921  {
6922  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
6923  daemon->have_dhparams = false;
6924  }
6925  if (0 != (daemon->options & MHD_USE_TLS))
6926  {
6927  gnutls_priority_deinit (daemon->priority_cache);
6928  if (daemon->x509_cred)
6929  gnutls_certificate_free_credentials (daemon->x509_cred);
6930  if (daemon->psk_cred)
6931  gnutls_psk_free_server_credentials (daemon->psk_cred);
6932  }
6933 #endif /* HTTPS_SUPPORT */
6934 
6935 #ifdef DAUTH_SUPPORT
6936  free (daemon->nnc);
6937 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6938  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6939 #endif
6940 #endif
6941 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6943 #endif
6944  free (daemon);
6945  }
6946 }
6947 
6948 
6960 const union MHD_DaemonInfo *
6962  enum MHD_DaemonInfoType info_type,
6963  ...)
6964 {
6965  if (NULL == daemon)
6966  return NULL;
6967  switch (info_type)
6968  {
6970  return NULL; /* no longer supported */
6972  return NULL; /* no longer supported */
6974  return (const union MHD_DaemonInfo *) &daemon->listen_fd;
6975 #ifdef EPOLL_SUPPORT
6977  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
6978 #endif
6980  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
6981  {
6982  /* Assume that MHD_run() in not called in other thread
6983  * at the same time. */
6984  MHD_cleanup_connections (daemon);
6985  }
6986 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6987  else if (daemon->worker_pool)
6988  {
6989  unsigned int i;
6990  /* Collect the connection information stored in the workers. */
6991  daemon->connections = 0;
6992  for (i = 0; i < daemon->worker_pool_size; i++)
6993  {
6994  /* FIXME: next line is thread-safe only if read is atomic. */
6995  daemon->connections += daemon->worker_pool[i].connections;
6996  }
6997  }
6998 #endif
6999  return (const union MHD_DaemonInfo *) &daemon->connections;
7000  case MHD_DAEMON_INFO_FLAGS:
7001  return (const union MHD_DaemonInfo *) &daemon->options;
7003  return (const union MHD_DaemonInfo *) &daemon->port;
7004  default:
7005  return NULL;
7006  }
7007 }
7008 
7009 
7026 void
7028  void *cls)
7029 {
7030  mhd_panic = cb;
7031  mhd_panic_cls = cls;
7032 }
7033 
7034 
7041 const char *
7042 MHD_get_version (void)
7043 {
7044 #ifdef PACKAGE_VERSION
7045  return PACKAGE_VERSION;
7046 #else /* !PACKAGE_VERSION */
7047  static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
7048  if (0 == ver[0])
7049  {
7050  int res = MHD_snprintf_ (ver,
7051  sizeof(ver),
7052  "%x.%x.%x",
7053  (((int) MHD_VERSION >> 24) & 0xFF),
7054  (((int) MHD_VERSION >> 16) & 0xFF),
7055  (((int) MHD_VERSION >> 8) & 0xFF));
7056  if ((0 >= res)||(sizeof(ver) <= res))
7057  return "0.0.0"; /* Can't return real version*/
7058  }
7059  return ver;
7060 #endif /* !PACKAGE_VERSION */
7061 }
7062 
7063 
7075 _MHD_EXTERN int
7077 {
7078  switch (feature)
7079  {
7080  case MHD_FEATURE_MESSAGES:
7081 #ifdef HAVE_MESSAGES
7082  return MHD_YES;
7083 #else
7084  return MHD_NO;
7085 #endif
7086  case MHD_FEATURE_TLS:
7087 #ifdef HTTPS_SUPPORT
7088  return MHD_YES;
7089 #else /* ! HTTPS_SUPPORT */
7090  return MHD_NO;
7091 #endif /* ! HTTPS_SUPPORT */
7093 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
7094  return MHD_YES;
7095 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
7096  return MHD_NO;
7097 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
7099 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
7100  return MHD_YES;
7101 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
7102  return MHD_NO;
7103 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
7104  case MHD_FEATURE_IPv6:
7105 #ifdef HAVE_INET6
7106  return MHD_YES;
7107 #else
7108  return MHD_NO;
7109 #endif
7110  case MHD_FEATURE_IPv6_ONLY:
7111 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
7112  return MHD_YES;
7113 #else
7114  return MHD_NO;
7115 #endif
7116  case MHD_FEATURE_POLL:
7117 #ifdef HAVE_POLL
7118  return MHD_YES;
7119 #else
7120  return MHD_NO;
7121 #endif
7122  case MHD_FEATURE_EPOLL:
7123 #ifdef EPOLL_SUPPORT
7124  return MHD_YES;
7125 #else
7126  return MHD_NO;
7127 #endif
7129 #ifdef HAVE_LISTEN_SHUTDOWN
7130  return MHD_YES;
7131 #else
7132  return MHD_NO;
7133 #endif
7135 #ifdef _MHD_ITC_SOCKETPAIR
7136  return MHD_YES;
7137 #else
7138  return MHD_NO;
7139 #endif
7141 #ifdef TCP_FASTOPEN
7142  return MHD_YES;
7143 #else
7144  return MHD_NO;
7145 #endif
7147 #ifdef BAUTH_SUPPORT
7148  return MHD_YES;
7149 #else
7150  return MHD_NO;
7151 #endif
7153 #ifdef DAUTH_SUPPORT
7154  return MHD_YES;
7155 #else
7156  return MHD_NO;
7157 #endif
7159 #ifdef HAVE_POSTPROCESSOR
7160  return MHD_YES;
7161 #else
7162  return MHD_NO;
7163 #endif
7165 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
7166  return MHD_YES;
7167 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
7168  return MHD_NO;
7169 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
7171 #if defined(HAVE_PREAD64) || defined(_WIN32)
7172  return MHD_YES;
7173 #elif defined(HAVE_PREAD)
7174  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
7175 #elif defined(HAVE_LSEEK64)
7176  return MHD_YES;
7177 #else
7178  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
7179 #endif
7181 #if defined(MHD_USE_THREAD_NAME_)
7182  return MHD_YES;
7183 #else
7184  return MHD_NO;
7185 #endif
7186  case MHD_FEATURE_UPGRADE:
7187 #if defined(UPGRADE_SUPPORT)
7188  return MHD_YES;
7189 #else
7190  return MHD_NO;
7191 #endif
7193 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
7194  return MHD_YES;
7195 #else
7196  return MHD_NO;
7197 #endif
7199 #ifdef MHD_USE_GETSOCKNAME
7200  return MHD_YES;
7201 #else
7202  return MHD_NO;
7203 #endif
7205 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \
7206  defined (MSG_NOSIGNAL)
7207  return MHD_YES;
7208 #else
7209  return MHD_NO;
7210 #endif
7211  case MHD_FEATURE_SENDFILE:
7212 #ifdef _MHD_HAVE_SENDFILE
7213  return MHD_YES;
7214 #else
7215  return MHD_NO;
7216 #endif
7217  case MHD_FEATURE_THREADS:
7218 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7219  return MHD_YES;
7220 #else
7221  return MHD_NO;
7222 #endif
7223 
7224  }
7225  return MHD_NO;
7226 }
7227 
7228 
7229 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7230 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
7231 #if defined(MHD_USE_POSIX_THREADS)
7232 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7233 #elif defined(MHD_W32_MUTEX_)
7234 
7235 static int
7236 gcry_w32_mutex_init (void **ppmtx)
7237 {
7238  *ppmtx = malloc (sizeof (MHD_mutex_));
7239 
7240  if (NULL == *ppmtx)
7241  return ENOMEM;
7242  if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx))
7243  {
7244  free (*ppmtx);
7245  *ppmtx = NULL;
7246  return EPERM;
7247  }
7248 
7249  return 0;
7250 }
7251 
7252 
7253 static int
7254 gcry_w32_mutex_destroy (void **ppmtx)
7255 {
7256  int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL;
7257  free (*ppmtx);
7258  return res;
7259 }
7260 
7261 
7262 static int
7263 gcry_w32_mutex_lock (void **ppmtx)
7264 {
7265  return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7266 }
7267 
7268 
7269 static int
7270 gcry_w32_mutex_unlock (void **ppmtx)
7271 {
7272  return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL;
7273 }
7274 
7275 
7276 static struct gcry_thread_cbs gcry_threads_w32 = {
7277  (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7278  NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7279  gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7280  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
7281 };
7282 
7283 #endif /* defined(MHD_W32_MUTEX_) */
7284 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
7285 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
7286 
7290 void
7291 MHD_init (void)
7292 {
7293 #if defined(MHD_WINSOCK_SOCKETS)
7294  WSADATA wsd;
7295 #endif /* MHD_WINSOCK_SOCKETS */
7296 
7297  if (NULL == mhd_panic)
7299 
7300 #if defined(MHD_WINSOCK_SOCKETS)
7301  if (0 != WSAStartup (MAKEWORD (2, 2), &wsd))
7302  MHD_PANIC (_ ("Failed to initialize winsock\n"));
7303  mhd_winsock_inited_ = 1;
7304  if ((2 != LOBYTE (wsd.wVersion))&&(2 != HIBYTE (wsd.wVersion)))
7305  MHD_PANIC (_ ("Winsock version 2.2 is not available\n"));
7306 #endif /* MHD_WINSOCK_SOCKETS */
7307 #ifdef HTTPS_SUPPORT
7308 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7309 #if GCRYPT_VERSION_NUMBER < 0x010600
7310 #if defined(MHD_USE_POSIX_THREADS)
7311  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7312  &gcry_threads_pthread))
7313  MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt\n"));
7314 #elif defined(MHD_W32_MUTEX_)
7315  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7316  &gcry_threads_w32))
7317  MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt\n"));
7318 #endif /* defined(MHD_W32_MUTEX_) */
7319  gcry_check_version (NULL);
7320 #else
7321  if (NULL == gcry_check_version ("1.6.0"))
7322  MHD_PANIC (_ (
7323  "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7324 #endif
7325 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
7326  gnutls_global_init ();
7327 #endif /* HTTPS_SUPPORT */
7329 #ifdef HAVE_FREEBSD_SENDFILE
7330  MHD_conn_init_static_ ();
7331 #endif /* HAVE_FREEBSD_SENDFILE */
7333 }
7334 
7335 
7336 void
7337 MHD_fini (void)
7338 {
7339 #ifdef HTTPS_SUPPORT
7340  gnutls_global_deinit ();
7341 #endif /* HTTPS_SUPPORT */
7342 #if defined(MHD_WINSOCK_SOCKETS)
7343  if (mhd_winsock_inited_)
7344  WSACleanup ();
7345 #endif /* MHD_WINSOCK_SOCKETS */
7347 }
7348 
7349 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
7351 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
7352 
7353 /* end of daemon.c */
bool thread_joined
Definition: internal.h:779
#define SSIZE_MAX
Definition: mhd_limits.h:111
#define MHD_send_(s, b, l)
Definition: mhd_sockets.h:261
unsigned int per_ip_connection_limit
Definition: internal.h:1598
void * unescape_callback_cls
Definition: internal.h:1415
volatile int global_init_count
Definition: daemon.c:187
#define MHD_PANIC(msg)
Definition: internal.h:69
void MHD_connection_handle_write(struct MHD_Connection *connection)
Definition: connection.c:2927
_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:5672
Header for platform missing functions.
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:4961
_MHD_EXTERN const char * MHD_get_version(void)
Definition: version.c:35
bool data_already_pending
Definition: internal.h:1500
void MHD_update_last_activity_(struct MHD_Connection *connection)
socklen_t addr_len
Definition: internal.h:733
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
Definition: microhttpd.h:1347
#define UINT_MAX
Definition: mhd_limits.h:45
#define MHD_SYS_select_(n, r, w, e, t)
Definition: mhd_sockets.h:336
struct sockaddr_storage addr
Definition: internal.h:728
struct MHD_Connection * cleanup_head
Definition: internal.h:1177
enum MHD_CONNECTION_STATE state
Definition: internal.h:922
void * data
Definition: microhttpd.h:3031
static int call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
Definition: daemon.c:1187
void MHD_init_mem_pools_(void)
Definition: memorypool.c:85
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:927
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:4933
static void MHD_default_logger_(void *cls, const char *fm, va_list ap)
Definition: daemon.c:226
#define MHD_ITC_IS_INVALID_(itc)
Definition: mhd_itc.h:366
struct MHD_Connection * prevX
Definition: internal.h:670
MHD_thread_handle_ID_ pid
Definition: internal.h:1249
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:180
time_t connection_timeout
Definition: internal.h:1592
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:3432
#define MHD_socket_get_error_()
Definition: mhd_sockets.h:523
internal monotonic clock functions implementations
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:121
void * MHD_calloc_(size_t nelem, size_t elsize)
Definition: mhd_compat.c:96
#define MHD_socket_strerr_(err)
Definition: mhd_sockets.h:541
MHD_socket MHD_socket_create_listen_(int pf)
Definition: mhd_sockets.c:472
#define EDLL_insert(head, tail, element)
Definition: internal.h:1832
#define MHD_YES
Definition: microhttpd.h:140
_MHD_EXTERN int MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:3113
#define SIZE_MAX
Definition: mhd_limits.h:99
struct MHD_Response * response
Definition: internal.h:678
struct MHD_Connection * manual_timeout_head
Definition: internal.h:1143
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:1229
#define EXTRA_SLOTS
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:70
MHD_thread_handle_ID_ pid
Definition: internal.h:723
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:95
time_t MHD_monotonic_sec_counter(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: mhd_sockets.c:375
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:132
MHD_AccessHandlerCallback default_handler
Definition: internal.h:1261
int MHD_socket
Definition: microhttpd.h:187
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:308
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:2890
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
Definition: daemon.c:4777
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
Definition: mhd_sockets.h:642
_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:4809
intptr_t value
Definition: microhttpd.h:1742
#define MHD_SCKT_LAST_ERR_IS_(code)
Definition: mhd_sockets.h:622
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:4986
platform-specific includes for libmicrohttpd
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
Definition: panic.c:56
void MHD_fini(void)
Definition: daemon.c:7337
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:290
void * uri_log_callback_cls
Definition: internal.h:1405
struct MHD_Daemon * daemon
Definition: internal.h:675
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:260
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
Definition: microhttpd.h:2107
#define MHD_TEST_ALLOW_SUSPEND_RESUME
Definition: internal.h:212
int listening_address_reuse
Definition: internal.h:1505
MHD_mutex_ per_ip_connection_mutex
Definition: internal.h:1259
#define MHD_TYPE_IS_SIGNED_(type)
Definition: mhd_limits.h:39
MHD_NotifyConnectionCallback notify_connection
Definition: internal.h:1386
Header for platform-independent inter-thread communication.
void MHD_init(void)
Definition: daemon.c:7291
struct MHD_Connection * next
Definition: internal.h:651
bool client_aware
Definition: internal.h:865
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:27
#define DLL_insert(head, tail, element)
Definition: internal.h:1745
int strict_for_client
Definition: internal.h:1613
void * socket_context
Definition: internal.h:694
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:344
#define MHD_VERSION
Definition: microhttpd.h:135
#define MHD_socket_last_strerr_()
Definition: mhd_sockets.h:548
bool was_quiesced
Definition: internal.h:1505
struct MHD_Connection * connections_tail
Definition: internal.h:1160
struct MHD_Daemon * worker_pool
Definition: internal.h:1073
MHD_DisableSanityCheck
Definition: microhttpd.h:1716
void * mhd_panic_cls
Definition: daemon.c:161
size_t read_buffer_size
Definition: internal.h:781
int fd
Definition: microhttpd.h:3161
void * client_context
Definition: internal.h:696
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:6795
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:363
struct MemoryPool * MHD_pool_create(size_t max)
Definition: memorypool.c:102
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:188
MHD_socket socket_fd
Definition: internal.h:752
internal shared structures
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:3680
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:78
void MHD_set_https_callbacks(struct MHD_Connection *connection)
#define MHD_SCKT_SEND_MAX_SIZE_
Definition: mhd_sockets.h:222
unsigned int connection_limit
Definition: internal.h:1586
unsigned int worker_pool_size
Definition: internal.h:1366
enum MHD_FLAG options
Definition: internal.h:1603
struct MHD_Connection * connections_head
Definition: internal.h:1155
_MHD_EXTERN int MHD_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
Definition: daemon.c:3626
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:248
LogCallback uri_log_callback
Definition: internal.h:1400
void MHD_connection_handle_read(struct MHD_Connection *connection)
Definition: connection.c:2814
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1211
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
Definition: internal.h:745
#define _MHD_EXTERN
Definition: mhd_options.h:51
#define MHD_SCKT_ERR_IS_(err, code)
Definition: mhd_sockets.h:610
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:414
Methods for managing connections.
time_t _MHD_TIMEVAL_TV_SEC_TYPE
Definition: platform.h:122
struct MHD_Daemon * master
Definition: internal.h:1068
#define EDLL_remove(head, tail, element)
Definition: internal.h:1850
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:1150
uint16_t port
Definition: internal.h:1608
#define NULL
Definition: reason_phrase.c:30
unsigned int connections
Definition: internal.h:1361
#define ULLONG_MAX
Definition: mhd_limits.h:58
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:480
struct MHD_Connection * prev
Definition: internal.h:656
#define TIMEVAL_TV_SEC_MAX
Definition: mhd_limits.h:140
#define DLL_remove(head, tail, element)
Definition: internal.h:1765
#define MHD_SCKT_EINVAL_
Definition: mhd_sockets.h:464
#define MHD_strerror_(errnum)
Definition: mhd_compat.h:44
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:63
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
MHD_FEATURE
Definition: microhttpd.h:3867
static int internal_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: daemon.c:972
struct MHD_Connection * normal_timeout_head
Definition: internal.h:1128
#define _MHD_SYS_DEFAULT_FD_SETSIZE
Definition: mhd_sockets.h:126
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:157
UnescapeCallback unescape_callback
Definition: internal.h:1410
_MHD_EXTERN void MHD_free(void *ptr)
Definition: daemon.c:246
#define MAYBE_SOCK_NOSIGPIPE
Definition: mhd_sockets.h:170
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:2795
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
Definition: internal.h:1757
#define XDLL_remove(head, tail, element)
Definition: internal.h:1809
void MHD_monotonic_sec_counter_finish(void)
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
static int internal_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
Definition: daemon.c:3522
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:1172
#define MHD_create_named_thread_(t, n, s, r, a)
Definition: mhd_threads.h:216
int MHD_SCKT_OPT_BOOL_
Definition: mhd_sockets.h:203
size_t pool_size
Definition: internal.h:1450
bool tls_read_ready
Definition: internal.h:769
struct MHD_itc_ itc
Definition: internal.h:1410
MHD_AcceptPolicyCallback apc
Definition: internal.h:1364
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
time_t last_activity
Definition: internal.h:739
struct MHD_Connection * cleanup_tail
Definition: internal.h:1182
int MHD_connection_handle_idle(struct MHD_Connection *connection)
Definition: connection.c:3280
static int resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:2958
#define MHD_itc_destroy_chk_(itc)
Definition: mhd_itc.h:352
static int internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, bool external_add, bool non_blck)
Definition: daemon.c:2359
int(* MHD_AccessHandlerCallback)(void *cls, struct MHD_Connection *connection, const char *url, const char *method, const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls)
Definition: microhttpd.h:2166
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:4144
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3323
int MHD_socket_set_nodelay_(MHD_socket sock, bool on)
Definition: mhd_sockets.c:475
bool sk_nonblck
Definition: internal.h:784
void MHD_monotonic_sec_counter_init(void)
#define MHD_recv_(s, b, l)
Definition: mhd_sockets.h:273
static int MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:3173
_MHD_EXTERN int MHD_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd)
Definition: daemon.c:722
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:324
void * ptr_value
Definition: microhttpd.h:1748
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:2189
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:1135
void MHD_check_global_init_(void)
Definition: daemon.c:204
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:1375
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
Definition: mhd_sockets.h:674
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:154
#define MHD_BUF_INC_SIZE
Definition: internal.h:119
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
Definition: mhd_sockets.h:309
bool resuming
Definition: internal.h:1510
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:4690
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:3816
void * notify_completed_cls
Definition: internal.h:1380
MHD_socket listen_fd
Definition: internal.h:1494
struct MemoryPool * pool
Definition: internal.h:685
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:4655
MHD_OPTION
MHD options.
Definition: microhttpd.h:1358
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:405
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:1243
void * notify_connection_cls
Definition: internal.h:1391
void * apc_cls
Definition: internal.h:1369
bool at_limit
Definition: internal.h:1483
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
Definition: daemon_start.c:617
MHD_PanicCallback mhd_panic
Definition: daemon.c:156
#define XDLL_insert(head, tail, element)
Definition: internal.h:1789
MHD_DaemonInfoType
Definition: microhttpd.h:2042
#define _(String)
Definition: mhd_options.h:42
#define MHD_UNSIGNED_LONG_LONG_PRINTF
Definition: microhttpd.h:304
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:2921
bool suspended
Definition: internal.h:764
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
Definition: daemon.c:7076
struct MHD_Connection * suspended_connections_head
Definition: internal.h:1166
void * per_ip_connection_count
Definition: internal.h:1187
size_t read_buffer_offset
Definition: internal.h:787
_MHD_EXTERN int MHD_get_fdset2(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: daemon.c:1121
void * default_handler_cls
Definition: internal.h:1266
#define MHD_NO
Definition: microhttpd.h:145
volatile bool shutdown
Definition: internal.h:1526
#define MHD_SCKT_ERR_IS_EINTR_(err)
Definition: mhd_sockets.h:633
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1265
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:4854
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Definition: microhttpd.h:2121
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
Definition: microhttpd.h:2215
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:6961
_MHD_EXTERN size_t MHD_http_unescape(char *val)
Definition: internal.c:138
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
Definition: mhd_sockets.h:655
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:6634
limits values definitions
enum MHD_OPTION option
Definition: microhttpd.h:1735
int MHD_socket_noninheritable_(MHD_socket sock)
Definition: mhd_sockets.c:440
#define MAYBE_SOCK_NONBLOCK
Definition: mhd_sockets.h:163
MHD_FLAG
Flags for the struct MHD_Daemon.
Definition: microhttpd.h:1029
size_t pool_increment
Definition: internal.h:1455
int MHD_socket_buffering_reset_(MHD_socket sock)
Definition: mhd_sockets.c:550
#define MAYBE_SOCK_CLOEXEC
Definition: mhd_sockets.h:157
#define MHD_SCKT_EINTR_
Definition: mhd_sockets.h:414