GNU libmicrohttpd  0.9.66
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 #if GNUTLS_VERSION_NUMBER >= 0x030111
613  ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
614  &cert,
615  &key,
616  GNUTLS_X509_FMT_PEM,
617  daemon->https_key_password,
618  0);
619 #else
620 #ifdef HAVE_MESSAGES
621  MHD_DLOG (daemon,
622  _("Failed to setup x509 certificate/key: pre 3.X.X version " \
623  "of GnuTLS does not support setting key password"));
624 #endif
625  return -1;
626 #endif
627  }
628  else
629  ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
630  &cert,
631  &key,
632  GNUTLS_X509_FMT_PEM);
633 #ifdef HAVE_MESSAGES
634  if (0 != ret)
635  MHD_DLOG (daemon,
636  "GnuTLS failed to setup x509 certificate/key: %s\n",
637  gnutls_strerror (ret));
638 #endif
639  return ret;
640  }
641 #if GNUTLS_VERSION_MAJOR >= 3
642  if (NULL != daemon->cert_callback)
643  return 0;
644 #endif
645 #if GNUTLS_VERSION_NUMBER >= 0x030603
646  else if (NULL != daemon->cert_callback2)
647  return 0;
648 #endif
649 #ifdef HAVE_MESSAGES
650  MHD_DLOG (daemon,
651  "You need to specify a certificate and key location\n");
652 #endif
653  return -1;
654 }
655 
662 static int
663 MHD_TLS_init (struct MHD_Daemon *daemon)
664 {
665  switch (daemon->cred_type)
666  {
667  case GNUTLS_CRD_CERTIFICATE:
668  if (0 !=
669  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
670  return GNUTLS_E_MEMORY_ERROR;
671  return MHD_init_daemon_certificate (daemon);
672  case GNUTLS_CRD_PSK:
673  if (0 !=
674  gnutls_psk_allocate_server_credentials (&daemon->psk_cred))
675  return GNUTLS_E_MEMORY_ERROR;
676  return 0;
677  default:
678 #ifdef HAVE_MESSAGES
679  MHD_DLOG (daemon,
680  _("Error: invalid credentials type %d specified.\n"),
681  daemon->cred_type);
682 #endif
683  return -1;
684  }
685 }
686 #endif /* HTTPS_SUPPORT */
687 
688 
689 #undef MHD_get_fdset
690 
720 int
721 MHD_get_fdset (struct MHD_Daemon *daemon,
722  fd_set *read_fd_set,
723  fd_set *write_fd_set,
724  fd_set *except_fd_set,
725  MHD_socket *max_fd)
726 {
727  return MHD_get_fdset2 (daemon,
728  read_fd_set,
729  write_fd_set,
730  except_fd_set,
731  max_fd,
733 }
734 
735 
736 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
737 
749 static bool
750 urh_to_fdset (struct MHD_UpgradeResponseHandle *urh,
751  fd_set *rs,
752  fd_set *ws,
753  fd_set *es,
754  MHD_socket *max_fd,
755  unsigned int fd_setsize)
756 {
757  const MHD_socket conn_sckt = urh->connection->socket_fd;
758  const MHD_socket mhd_sckt = urh->mhd.socket;
759  bool res = true;
760 
761  /* Do not add to 'es' only if socket is closed
762  * or not used anymore. */
763  if (MHD_INVALID_SOCKET != conn_sckt)
764  {
765  if ( (urh->in_buffer_used < urh->in_buffer_size) &&
766  (! MHD_add_to_fd_set_ (conn_sckt,
767  rs,
768  max_fd,
769  fd_setsize)) )
770  res = false;
771  if ( (0 != urh->out_buffer_used) &&
772  (! MHD_add_to_fd_set_ (conn_sckt,
773  ws,
774  max_fd,
775  fd_setsize)) )
776  res = false;
777  /* Do not monitor again for errors if error was detected before as
778  * error state is remembered. */
779  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
780  ((0 != urh->in_buffer_size) ||
781  (0 != urh->out_buffer_size) ||
782  (0 != urh->out_buffer_used)))
783  MHD_add_to_fd_set_ (conn_sckt,
784  es,
785  max_fd,
786  fd_setsize);
787  }
788  if (MHD_INVALID_SOCKET != mhd_sckt)
789  {
790  if ( (urh->out_buffer_used < urh->out_buffer_size) &&
791  (! MHD_add_to_fd_set_ (mhd_sckt,
792  rs,
793  max_fd,
794  fd_setsize)) )
795  res = false;
796  if ( (0 != urh->in_buffer_used) &&
797  (! MHD_add_to_fd_set_ (mhd_sckt,
798  ws,
799  max_fd,
800  fd_setsize)) )
801  res = false;
802  /* Do not monitor again for errors if error was detected before as
803  * error state is remembered. */
804  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
805  ((0 != urh->out_buffer_size) ||
806  (0 != urh->in_buffer_size) ||
807  (0 != urh->in_buffer_used)))
808  MHD_add_to_fd_set_ (mhd_sckt,
809  es,
810  max_fd,
811  fd_setsize);
812  }
813 
814  return res;
815 }
816 
817 
827 static void
828 urh_from_fdset (struct MHD_UpgradeResponseHandle *urh,
829  const fd_set *rs,
830  const fd_set *ws,
831  const fd_set *es)
832 {
833  const MHD_socket conn_sckt = urh->connection->socket_fd;
834  const MHD_socket mhd_sckt = urh->mhd.socket;
835 
836  /* Reset read/write ready, preserve error state. */
839 
840  if (MHD_INVALID_SOCKET != conn_sckt)
841  {
842  if (FD_ISSET (conn_sckt, rs))
843  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
844  if (FD_ISSET (conn_sckt, ws))
845  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
846  if (FD_ISSET (conn_sckt, es))
847  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
848  }
849  if ((MHD_INVALID_SOCKET != mhd_sckt))
850  {
851  if (FD_ISSET (mhd_sckt, rs))
852  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
853  if (FD_ISSET (mhd_sckt, ws))
854  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
855  if (FD_ISSET (mhd_sckt, es))
856  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
857  }
858 }
859 
860 #ifdef HAVE_POLL
861 
870 static void
871 urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh,
872  struct pollfd p[2])
873 {
874  p[0].events = 0;
875  p[1].events = 0;
876 
877  if (urh->in_buffer_used < urh->in_buffer_size)
878  p[0].events |= POLLIN;
879  if (0 != urh->out_buffer_used)
880  p[0].events |= POLLOUT;
881 
882  /* Do not monitor again for errors if error was detected before as
883  * error state is remembered. */
884  if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) &&
885  ((0 != urh->in_buffer_size) ||
886  (0 != urh->out_buffer_size) ||
887  (0 != urh->out_buffer_used)))
888  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
889 
890  if (urh->out_buffer_used < urh->out_buffer_size)
891  p[1].events |= POLLIN;
892  if (0 != urh->in_buffer_used)
893  p[1].events |= POLLOUT;
894 
895  /* Do not monitor again for errors if error was detected before as
896  * error state is remembered. */
897  if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) &&
898  ((0 != urh->out_buffer_size) ||
899  (0 != urh->in_buffer_size) ||
900  (0 != urh->in_buffer_used)))
901  p[1].events |= MHD_POLL_EVENTS_ERR_DISC;
902 }
903 
904 
911 static void
912 urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh,
913  struct pollfd p[2])
914 {
915  p[0].fd = urh->connection->socket_fd;
916  p[1].fd = urh->mhd.socket;
917  urh_update_pollfd (urh,
918  p);
919 }
920 
921 
927 static void
928 urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh,
929  struct pollfd p[2])
930 {
931  /* Reset read/write ready, preserve error state. */
934 
935  if (0 != (p[0].revents & POLLIN))
936  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
937  if (0 != (p[0].revents & POLLOUT))
938  urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY;
939  if (0 != (p[0].revents & POLLHUP))
941  if (0 != (p[0].revents & MHD_POLL_REVENTS_ERRROR))
942  urh->app.celi |= MHD_EPOLL_STATE_ERROR;
943  if (0 != (p[1].revents & POLLIN))
944  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
945  if (0 != (p[1].revents & POLLOUT))
946  urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY;
947  if (0 != (p[1].revents & POLLHUP))
948  urh->mhd.celi |= MHD_EPOLL_STATE_ERROR;
949  if (0 != (p[1].revents & MHD_POLL_REVENTS_ERRROR))
951 }
952 #endif /* HAVE_POLL */
953 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
954 
955 
970 static int
972  fd_set *read_fd_set,
973  fd_set *write_fd_set,
974  fd_set *except_fd_set,
975  MHD_socket *max_fd,
976  unsigned int fd_setsize)
977 
978 {
979  struct MHD_Connection *pos;
980  struct MHD_Connection *posn;
981  int result = MHD_YES;
982  MHD_socket ls;
983 
984  if (daemon->shutdown)
985  return MHD_NO;
986 
987  ls = daemon->listen_fd;
988  if ( (MHD_INVALID_SOCKET != ls) &&
989  (! daemon->was_quiesced) &&
990  (! MHD_add_to_fd_set_ (ls,
991  read_fd_set,
992  max_fd,
993  fd_setsize)) )
994  result = MHD_NO;
995 
996  /* Add all sockets to 'except_fd_set' as well to watch for
997  * out-of-band data. However, ignore errors if INFO_READ
998  * or INFO_WRITE sockets will not fit 'except_fd_set'. */
999  /* Start from oldest connections. Make sense for W32 FDSETs. */
1000  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
1001  {
1002  posn = pos->prev;
1003 
1004  switch (pos->event_loop_info)
1005  {
1007  if (! MHD_add_to_fd_set_ (pos->socket_fd,
1008  read_fd_set,
1009  max_fd,
1010  fd_setsize))
1011  result = MHD_NO;
1012 #ifdef MHD_POSIX_SOCKETS
1014  except_fd_set,
1015  max_fd,
1016  fd_setsize);
1017 #endif /* MHD_POSIX_SOCKETS */
1018  break;
1020  if (! MHD_add_to_fd_set_ (pos->socket_fd,
1021  write_fd_set,
1022  max_fd,
1023  fd_setsize))
1024  result = MHD_NO;
1025 #ifdef MHD_POSIX_SOCKETS
1027  except_fd_set,
1028  max_fd,
1029  fd_setsize);
1030 #endif /* MHD_POSIX_SOCKETS */
1031  break;
1033  if ( (NULL == except_fd_set) ||
1034  ! MHD_add_to_fd_set_ (pos->socket_fd,
1035  except_fd_set,
1036  max_fd,
1037  fd_setsize))
1038  result = MHD_NO;
1039  break;
1041  /* this should never happen */
1042  break;
1043  }
1044  }
1045 #ifdef MHD_WINSOCK_SOCKETS
1046  /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets
1047  * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will
1048  * not be pushed out. */
1049  for (pos = daemon->connections_tail; NULL != pos; pos = posn)
1050  {
1051  posn = pos->prev;
1053  except_fd_set,
1054  max_fd,
1055  fd_setsize);
1056  }
1057 #endif /* MHD_WINSOCK_SOCKETS */
1058 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1059  {
1060  struct MHD_UpgradeResponseHandle *urh;
1061 
1062  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
1063  {
1064  if (MHD_NO ==
1065  urh_to_fdset (urh,
1066  read_fd_set,
1067  write_fd_set,
1068  except_fd_set,
1069  max_fd,
1070  fd_setsize))
1071  result = MHD_NO;
1072  }
1073  }
1074 #endif
1075 #if DEBUG_CONNECT
1076 #ifdef HAVE_MESSAGES
1077  if (NULL != max_fd)
1078  MHD_DLOG (daemon,
1079  _("Maximum socket in select set: %d\n"),
1080  *max_fd);
1081 #endif
1082 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1083  return result;
1084 }
1085 
1086 
1119 int
1120 MHD_get_fdset2 (struct MHD_Daemon *daemon,
1121  fd_set *read_fd_set,
1122  fd_set *write_fd_set,
1123  fd_set *except_fd_set,
1124  MHD_socket *max_fd,
1125  unsigned int fd_setsize)
1126 {
1127  fd_set es;
1128 
1129  if ( (NULL == daemon) ||
1130  (NULL == read_fd_set) ||
1131  (NULL == write_fd_set) ||
1132  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ||
1133  (0 != (daemon->options & MHD_USE_POLL)))
1134  return MHD_NO;
1135 
1136  if (NULL == except_fd_set)
1137  { /* Workaround to maintain backward compatibility. */
1138 #ifdef HAVE_MESSAGES
1139  MHD_DLOG (daemon,
1140  _("MHD_get_fdset2() called with except_fd_set "
1141  "set to NULL. Such behavior is unsupported.\n"));
1142 #endif
1143  FD_ZERO (&es);
1144  except_fd_set = &es;
1145  }
1146 
1147 #ifdef EPOLL_SUPPORT
1148  if (0 != (daemon->options & MHD_USE_EPOLL))
1149  {
1150  if (daemon->shutdown)
1151  return MHD_NO;
1152 
1153  /* we're in epoll mode, use the epoll FD as a stand-in for
1154  the entire event set */
1155 
1156  return MHD_add_to_fd_set_ (daemon->epoll_fd,
1157  read_fd_set,
1158  max_fd,
1159  fd_setsize) ? MHD_YES : MHD_NO;
1160  }
1161 #endif
1162 
1163  return internal_get_fdset2 (daemon,
1164  read_fd_set,
1165  write_fd_set,
1166  except_fd_set,
1167  max_fd,
1168  fd_setsize);
1169 }
1170 
1171 
1185 static int
1187  bool read_ready,
1188  bool write_ready,
1189  bool force_close)
1190 {
1191  int ret;
1192  bool states_info_processed = false;
1193  /* Fast track flag */
1194  bool on_fasttrack = (con->state == MHD_CONNECTION_INIT);
1195 
1196 #ifdef HTTPS_SUPPORT
1197  if (con->tls_read_ready)
1198  read_ready = true;
1199 #endif /* HTTPS_SUPPORT */
1200  if (!force_close)
1201  {
1202  if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) &&
1203  read_ready)
1204  {
1206  ret = MHD_connection_handle_idle (con);
1207  states_info_processed = true;
1208  }
1209  /* No need to check value of 'ret' here as closed connection
1210  * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */
1211  if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) &&
1212  write_ready)
1213  {
1215  ret = MHD_connection_handle_idle (con);
1216  states_info_processed = true;
1217  }
1218  }
1219  else
1220  {
1221  MHD_connection_close_ (con,
1223  return MHD_connection_handle_idle (con);
1224  }
1225 
1226  if (!states_info_processed)
1227  { /* Connection is not read or write ready, but external conditions
1228  * may be changed and need to be processed. */
1229  ret = MHD_connection_handle_idle (con);
1230  }
1231  /* Fast track for fast connections. */
1232  /* If full request was read by single read_handler() invocation
1233  and headers were completely prepared by single MHD_connection_handle_idle()
1234  then try not to wait for next sockets polling and send response
1235  immediately.
1236  As writeability of socket was not checked and it may have
1237  some data pending in system buffers, use this optimization
1238  only for non-blocking sockets. */
1239  /* No need to check 'ret' as connection is always in
1240  * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */
1241  else if (on_fasttrack && con->sk_nonblck)
1242  {
1244  {
1246  /* Always call 'MHD_connection_handle_idle()' after each read/write. */
1247  ret = MHD_connection_handle_idle (con);
1248  }
1249  /* If all headers were sent by single write_handler() and
1250  * response body is prepared by single MHD_connection_handle_idle()
1251  * call - continue. */
1252  if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) ||
1254  {
1256  ret = MHD_connection_handle_idle (con);
1257  }
1258  }
1259 
1260  /* All connection's data and states are processed for this turn.
1261  * If connection already has more data to be processed - use
1262  * zero timeout for next select()/poll(). */
1263  /* Thread-per-connection do not need global zero timeout as
1264  * connections are processed individually. */
1265  /* Note: no need to check for read buffer availability for
1266  * TLS read-ready connection in 'read info' state as connection
1267  * without space in read buffer will be marked as 'info block'. */
1268  if ( (! con->daemon->data_already_pending) &&
1269  (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1270  {
1272  con->daemon->data_already_pending = true;
1273 #ifdef HTTPS_SUPPORT
1274  else if ( (con->tls_read_ready) &&
1276  con->daemon->data_already_pending = true;
1277 #endif /* HTTPS_SUPPORT */
1278  }
1279  return ret;
1280 }
1281 
1282 
1283 #ifdef UPGRADE_SUPPORT
1284 
1291 static void
1292 cleanup_upgraded_connection (struct MHD_Connection *connection)
1293 {
1294  struct MHD_UpgradeResponseHandle *urh = connection->urh;
1295 
1296  if (NULL == urh)
1297  return;
1298 #ifdef HTTPS_SUPPORT
1299  /* Signal remote client the end of TLS connection by
1300  * gracefully closing TLS session. */
1301  if (0 != (connection->daemon->options & MHD_USE_TLS))
1302  gnutls_bye (connection->tls_session,
1303  GNUTLS_SHUT_WR);
1304 
1305  if (MHD_INVALID_SOCKET != urh->mhd.socket)
1306  MHD_socket_close_chk_ (urh->mhd.socket);
1307 
1308  if (MHD_INVALID_SOCKET != urh->app.socket)
1309  MHD_socket_close_chk_ (urh->app.socket);
1310 #endif /* HTTPS_SUPPORT */
1311  connection->urh = NULL;
1312  free (urh);
1313 }
1314 #endif /* UPGRADE_SUPPORT */
1315 
1316 
1317 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
1318 
1326 static void
1327 process_urh (struct MHD_UpgradeResponseHandle *urh)
1328 {
1329  /* Help compiler to optimize:
1330  * pointers to 'connection' and 'daemon' are not changed
1331  * during this processing, so no need to chain dereference
1332  * each time. */
1333  struct MHD_Connection * const connection = urh->connection;
1334  struct MHD_Daemon * const daemon = connection->daemon;
1335  /* Prevent data races: use same value of 'was_closed' throughout
1336  * this function. If 'was_closed' changed externally in the middle
1337  * of processing - it will be processed on next iteration. */
1338  bool was_closed;
1339  if (daemon->shutdown)
1340  {
1341  /* Daemon shutting down, application will not receive any more data. */
1342 #ifdef HAVE_MESSAGES
1343  if (! urh->was_closed)
1344  {
1345  MHD_DLOG (daemon,
1346  _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
1347  }
1348 #endif
1349  urh->was_closed = true;
1350  }
1351  was_closed = urh->was_closed;
1352  if (was_closed)
1353  {
1354  /* Application was closed connections: no more data
1355  * can be forwarded to application socket. */
1356  if (0 < urh->in_buffer_used)
1357  {
1358 #ifdef HAVE_MESSAGES
1359  MHD_DLOG (daemon,
1360  _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
1361  " bytes of data received from remote side: application shut down socket\n"),
1362  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used);
1363 #endif
1364 
1365  }
1366  /* If application signaled MHD about socket closure then
1367  * check for any pending data even if socket is not marked
1368  * as 'ready' (signal may arrive after poll()/select()).
1369  * Socketpair for forwarding is always in non-blocking mode
1370  * so no risk that recv() will block the thread. */
1371  if (0 != urh->out_buffer_size)
1372  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1373  /* Discard any data received form remote. */
1374  urh->in_buffer_used = 0;
1375  /* Do not try to push data to application. */
1376  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1377  /* Reading from remote client is not required anymore. */
1378  urh->in_buffer_size = 0;
1379  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1380  connection->tls_read_ready = false;
1381  }
1382 
1383  /* On some platforms (W32, possibly Darwin) failed send() (send() will always
1384  * fail after remote disconnect was detected) may discard data in system
1385  * buffers received by system but not yet read by recv().
1386  * So, before trying send() on any socket, recv() must be performed at first
1387  * otherwise last part of incoming data may be lost. */
1388 
1389  /* If disconnect or error was detected - try to read from socket
1390  * to dry data possibly pending is system buffers. */
1391  if (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi))
1392  urh->app.celi |= MHD_EPOLL_STATE_READ_READY;
1393  if (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi))
1394  urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY;
1395 
1396  /*
1397  * handle reading from remote TLS client
1398  */
1399  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
1400  (connection->tls_read_ready) ) &&
1401  (urh->in_buffer_used < urh->in_buffer_size) )
1402  {
1403  ssize_t res;
1404  size_t buf_size;
1405 
1406  buf_size = urh->in_buffer_size - urh->in_buffer_used;
1407  if (buf_size > SSIZE_MAX)
1408  buf_size = SSIZE_MAX;
1409 
1410  connection->tls_read_ready = false;
1411  res = gnutls_record_recv (connection->tls_session,
1412  &urh->in_buffer[urh->in_buffer_used],
1413  buf_size);
1414  if (0 >= res)
1415  {
1416  if (GNUTLS_E_INTERRUPTED != res)
1417  {
1418  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1419  if (GNUTLS_E_AGAIN != res)
1420  {
1421  /* Unrecoverable error on socket was detected or
1422  * socket was disconnected/shut down. */
1423  /* Stop trying to read from this TLS socket. */
1424  urh->in_buffer_size = 0;
1425  }
1426  }
1427  }
1428  else /* 0 < res */
1429  {
1430  urh->in_buffer_used += res;
1431  if (buf_size > (size_t)res)
1432  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1433  else if (0 < gnutls_record_check_pending (connection->tls_session))
1434  connection->tls_read_ready = true;
1435  }
1436  if (MHD_EPOLL_STATE_ERROR ==
1437  ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi))
1438  {
1439  /* Unrecoverable error on socket was detected and all
1440  * pending data was read from system buffers. */
1441  /* Stop trying to read from this TLS socket. */
1442  urh->in_buffer_size = 0;
1443  }
1444  }
1445 
1446  /*
1447  * handle reading from application
1448  */
1449  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1450  (urh->out_buffer_used < urh->out_buffer_size) )
1451  {
1452  ssize_t res;
1453  size_t buf_size;
1454 
1455  buf_size = urh->out_buffer_size - urh->out_buffer_used;
1456  if (buf_size > MHD_SCKT_SEND_MAX_SIZE_)
1457  buf_size = MHD_SCKT_SEND_MAX_SIZE_;
1458 
1459  res = MHD_recv_ (urh->mhd.socket,
1460  &urh->out_buffer[urh->out_buffer_used],
1461  buf_size);
1462  if (0 >= res)
1463  {
1464  const int err = MHD_socket_get_error_ ();
1465  if ((0 == res) ||
1466  ((! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1468  {
1469  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1470  if ((0 == res) ||
1471  (was_closed) ||
1472  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1473  (! MHD_SCKT_ERR_IS_EAGAIN_ (err)))
1474  {
1475  /* Socket disconnect/shutdown was detected;
1476  * Application signaled about closure of 'upgraded' socket;
1477  * or persistent / unrecoverable error. */
1478  /* Do not try to pull more data from application. */
1479  urh->out_buffer_size = 0;
1480  }
1481  }
1482  }
1483  else /* 0 < res */
1484  {
1485  urh->out_buffer_used += res;
1486  if (buf_size > (size_t)res)
1487  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1488  }
1489  if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
1490  ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ||
1491  (was_closed) ) )
1492  {
1493  /* Unrecoverable error on socket was detected and all
1494  * pending data was read from system buffers. */
1495  /* Do not try to pull more data from application. */
1496  urh->out_buffer_size = 0;
1497  }
1498  }
1499 
1500  /*
1501  * handle writing to remote HTTPS client
1502  */
1503  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
1504  (urh->out_buffer_used > 0) )
1505  {
1506  ssize_t res;
1507  size_t data_size;
1508 
1509  data_size = urh->out_buffer_used;
1510  if (data_size > SSIZE_MAX)
1511  data_size = SSIZE_MAX;
1512 
1513  res = gnutls_record_send (connection->tls_session,
1514  urh->out_buffer,
1515  data_size);
1516  if (0 >= res)
1517  {
1518  if (GNUTLS_E_INTERRUPTED != res)
1519  {
1520  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1521  if (GNUTLS_E_AGAIN != res)
1522  {
1523  /* TLS connection shut down or
1524  * persistent / unrecoverable error. */
1525 #ifdef HAVE_MESSAGES
1526  MHD_DLOG (daemon,
1527  _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
1528  " bytes of data received from application: %s\n"),
1529  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used,
1530  gnutls_strerror(res));
1531 #endif
1532  /* Discard any data unsent to remote. */
1533  urh->out_buffer_used = 0;
1534  /* Do not try to pull more data from application. */
1535  urh->out_buffer_size = 0;
1536  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1537  }
1538  }
1539  }
1540  else /* 0 < res */
1541  {
1542  const size_t next_out_buffer_used = urh->out_buffer_used - res;
1543  if (0 != next_out_buffer_used)
1544  {
1545  memmove (urh->out_buffer,
1546  &urh->out_buffer[res],
1547  next_out_buffer_used);
1548  if (data_size > (size_t)res)
1549  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1550  }
1551  urh->out_buffer_used = next_out_buffer_used;
1552  }
1553  if ( (0 == urh->out_buffer_used) &&
1554  (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) )
1555  {
1556  /* Unrecoverable error on socket was detected and all
1557  * pending data was sent to remote. */
1558  /* Do not try to send to remote anymore. */
1559  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1560  /* Do not try to pull more data from application. */
1561  urh->out_buffer_size = 0;
1562  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1563  }
1564  }
1565 
1566  /*
1567  * handle writing to application
1568  */
1569  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
1570  (urh->in_buffer_used > 0) )
1571  {
1572  ssize_t res;
1573  size_t data_size;
1574 
1575  data_size = urh->in_buffer_used;
1576  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
1577  data_size = MHD_SCKT_SEND_MAX_SIZE_;
1578 
1579  res = MHD_send_ (urh->mhd.socket,
1580  urh->in_buffer,
1581  data_size);
1582  if (0 >= res)
1583  {
1584  const int err = MHD_socket_get_error_ ();
1585  if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) &&
1587  {
1588  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1589  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err))
1590  {
1591  /* Socketpair connection shut down or
1592  * persistent / unrecoverable error. */
1593 #ifdef HAVE_MESSAGES
1594  MHD_DLOG (daemon,
1595  _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \
1596  " bytes of data received from remote side: %s\n"),
1597  (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used,
1598  MHD_socket_strerr_ (err));
1599 #endif
1600  /* Discard any data received form remote. */
1601  urh->in_buffer_used = 0;
1602  /* Reading from remote client is not required anymore. */
1603  urh->in_buffer_size = 0;
1604  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1605  connection->tls_read_ready = false;
1606  }
1607  }
1608  }
1609  else /* 0 < res */
1610  {
1611  const size_t next_in_buffer_used = urh->in_buffer_used - res;
1612  if (0 != next_in_buffer_used)
1613  {
1614  memmove (urh->in_buffer,
1615  &urh->in_buffer[res],
1616  next_in_buffer_used);
1617  if (data_size > (size_t)res)
1618  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1619  }
1620  urh->in_buffer_used = next_in_buffer_used;
1621  }
1622  if ( (0 == urh->in_buffer_used) &&
1623  (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) )
1624  {
1625  /* Do not try to push data to application. */
1626  urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1627  /* Reading from remote client is not required anymore. */
1628  urh->in_buffer_size = 0;
1629  urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY;
1630  connection->tls_read_ready = false;
1631  }
1632  }
1633 
1634  /* Check whether data is present in TLS buffers
1635  * and incoming forward buffer have some space. */
1636  if ( (connection->tls_read_ready) &&
1637  (urh->in_buffer_used < urh->in_buffer_size) &&
1638  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
1639  daemon->data_already_pending = true;
1640 
1641  if ( (daemon->shutdown) &&
1642  ( (0 != urh->out_buffer_size) ||
1643  (0 != urh->out_buffer_used) ) )
1644  {
1645  /* Daemon shutting down, discard any remaining forward data. */
1646 #ifdef HAVE_MESSAGES
1647  if (0 < urh->out_buffer_used)
1648  MHD_DLOG (daemon,
1649  _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \
1650  " bytes of data received from application: daemon shut down\n"),
1651  (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used);
1652 #endif
1653  /* Discard any data unsent to remote. */
1654  urh->out_buffer_used = 0;
1655  /* Do not try to sent to remote anymore. */
1656  urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY;
1657  /* Do not try to pull more data from application. */
1658  urh->out_buffer_size = 0;
1659  urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY;
1660  }
1661 }
1662 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
1663 
1664 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
1665 #ifdef UPGRADE_SUPPORT
1666 
1674 static void
1675 thread_main_connection_upgrade (struct MHD_Connection *con)
1676 {
1677 #ifdef HTTPS_SUPPORT
1678  struct MHD_UpgradeResponseHandle *urh = con->urh;
1679  struct MHD_Daemon *daemon = con->daemon;
1680 
1681  /* Here, we need to bi-directionally forward
1682  until the application tells us that it is done
1683  with the socket; */
1684  if ( (0 != (daemon->options & MHD_USE_TLS)) &&
1685  (0 == (daemon->options & MHD_USE_POLL)))
1686  {
1687  while ( (0 != urh->in_buffer_size) ||
1688  (0 != urh->out_buffer_size) ||
1689  (0 != urh->in_buffer_used) ||
1690  (0 != urh->out_buffer_used) )
1691  {
1692  /* use select */
1693  fd_set rs;
1694  fd_set ws;
1695  fd_set es;
1696  MHD_socket max_fd;
1697  int num_ready;
1698  bool result;
1699 
1700  FD_ZERO (&rs);
1701  FD_ZERO (&ws);
1702  FD_ZERO (&es);
1703  max_fd = MHD_INVALID_SOCKET;
1704  result = urh_to_fdset (urh,
1705  &rs,
1706  &ws,
1707  &es,
1708  &max_fd,
1709  FD_SETSIZE);
1710  if (! result)
1711  {
1712 #ifdef HAVE_MESSAGES
1713  MHD_DLOG (con->daemon,
1714  _("Error preparing select\n"));
1715 #endif
1716  break;
1717  }
1718  /* FIXME: does this check really needed? */
1719  if (MHD_INVALID_SOCKET != max_fd)
1720  {
1721  struct timeval* tvp;
1722  struct timeval tv;
1723  if ( (con->tls_read_ready) &&
1724  (urh->in_buffer_used < urh->in_buffer_size))
1725  { /* No need to wait if incoming data is already pending in TLS buffers. */
1726  tv.tv_sec = 0;
1727  tv.tv_usec = 0;
1728  tvp = &tv;
1729  }
1730  else
1731  tvp = NULL;
1732  num_ready = MHD_SYS_select_ (max_fd + 1,
1733  &rs,
1734  &ws,
1735  &es,
1736  tvp);
1737  }
1738  else
1739  num_ready = 0;
1740  if (num_ready < 0)
1741  {
1742  const int err = MHD_socket_get_error_();
1743 
1744  if (MHD_SCKT_ERR_IS_EINTR_(err))
1745  continue;
1746 #ifdef HAVE_MESSAGES
1747  MHD_DLOG (con->daemon,
1748  _("Error during select (%d): `%s'\n"),
1749  err,
1750  MHD_socket_strerr_ (err));
1751 #endif
1752  break;
1753  }
1754  urh_from_fdset (urh,
1755  &rs,
1756  &ws,
1757  &es);
1758  process_urh (urh);
1759  }
1760  }
1761 #ifdef HAVE_POLL
1762  else if (0 != (daemon->options & MHD_USE_TLS))
1763  {
1764  /* use poll() */
1765  struct pollfd p[2];
1766  memset (p,
1767  0,
1768  sizeof (p));
1769  p[0].fd = urh->connection->socket_fd;
1770  p[1].fd = urh->mhd.socket;
1771 
1772  while ( (0 != urh->in_buffer_size) ||
1773  (0 != urh->out_buffer_size) ||
1774  (0 != urh->in_buffer_used) ||
1775  (0 != urh->out_buffer_used) )
1776  {
1777  int timeout;
1778 
1779  urh_update_pollfd(urh, p);
1780 
1781  if ( (con->tls_read_ready) &&
1782  (urh->in_buffer_used < urh->in_buffer_size))
1783  timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */
1784  else
1785  timeout = -1;
1786 
1787  if (MHD_sys_poll_ (p,
1788  2,
1789  timeout) < 0)
1790  {
1791  const int err = MHD_socket_get_error_ ();
1792 
1793  if (MHD_SCKT_ERR_IS_EINTR_ (err))
1794  continue;
1795 #ifdef HAVE_MESSAGES
1796  MHD_DLOG (con->daemon,
1797  _("Error during poll: `%s'\n"),
1798  MHD_socket_strerr_ (err));
1799 #endif
1800  break;
1801  }
1802  urh_from_pollfd (urh,
1803  p);
1804  process_urh (urh);
1805  }
1806  }
1807  /* end POLL */
1808 #endif
1809  /* end HTTPS */
1810 #endif /* HTTPS_SUPPORT */
1811  /* TLS forwarding was finished. Cleanup socketpair. */
1813  /* Do not set 'urh->clean_ready' yet as 'urh' will be used
1814  * in connection thread for a little while. */
1815 }
1816 #endif /* UPGRADE_SUPPORT */
1817 
1818 
1826 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
1828 {
1829  struct MHD_Connection *con = data;
1830  struct MHD_Daemon *daemon = con->daemon;
1831  int num_ready;
1832  fd_set rs;
1833  fd_set ws;
1834  fd_set es;
1835  MHD_socket maxsock;
1836  struct timeval tv;
1837  struct timeval *tvp;
1838  time_t now;
1839 #if WINDOWS
1840 #ifdef HAVE_POLL
1841  int extra_slot;
1842 #endif /* HAVE_POLL */
1843 #define EXTRA_SLOTS 1
1844 #else /* !WINDOWS */
1845 #define EXTRA_SLOTS 0
1846 #endif /* !WINDOWS */
1847 #ifdef HAVE_POLL
1848  struct pollfd p[1 + EXTRA_SLOTS];
1849 #endif
1850 #undef EXTRA_SLOTS
1851 #ifdef HAVE_POLL
1852  const bool use_poll = (0 != (daemon->options & MHD_USE_POLL));
1853 #else /* ! HAVE_POLL */
1854  const bool use_poll = 0;
1855 #endif /* ! HAVE_POLL */
1856  bool was_suspended = false;
1857  MHD_thread_init_(&(con->pid));
1858 
1859  while ( (! daemon->shutdown) &&
1860  (MHD_CONNECTION_CLOSED != con->state) )
1861  {
1862  const time_t timeout = daemon->connection_timeout;
1863 #ifdef UPGRADE_SUPPORT
1864  struct MHD_UpgradeResponseHandle * const urh = con->urh;
1865 #else /* ! UPGRADE_SUPPORT */
1866  static const void * const urh = NULL;
1867 #endif /* ! UPGRADE_SUPPORT */
1868 
1869  if ( (con->suspended) &&
1870  (NULL == urh) )
1871  {
1872  /* Connection was suspended, wait for resume. */
1873  was_suspended = true;
1874  if (! use_poll)
1875  {
1876  FD_ZERO (&rs);
1877  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
1878  &rs,
1879  NULL,
1880  FD_SETSIZE))
1881  {
1882  #ifdef HAVE_MESSAGES
1883  MHD_DLOG (con->daemon,
1884  _("Failed to add FD to fd_set\n"));
1885  #endif
1886  goto exit;
1887  }
1888  if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1,
1889  &rs,
1890  NULL,
1891  NULL,
1892  NULL))
1893  {
1894  const int err = MHD_socket_get_error_();
1895 
1896  if (MHD_SCKT_ERR_IS_EINTR_(err))
1897  continue;
1898 #ifdef HAVE_MESSAGES
1899  MHD_DLOG (con->daemon,
1900  _("Error during select (%d): `%s'\n"),
1901  err,
1902  MHD_socket_strerr_ (err));
1903 #endif
1904  break;
1905  }
1906  }
1907 #ifdef HAVE_POLL
1908  else /* use_poll */
1909  {
1910  p[0].events = POLLIN;
1911  p[0].fd = MHD_itc_r_fd_ (daemon->itc);
1912  p[0].revents = 0;
1913  if (0 > MHD_sys_poll_ (p,
1914  1,
1915  -1))
1916  {
1918  continue;
1919 #ifdef HAVE_MESSAGES
1920  MHD_DLOG (con->daemon,
1921  _("Error during poll: `%s'\n"),
1923 #endif
1924  break;
1925  }
1926  }
1927 #endif /* HAVE_POLL */
1928  MHD_itc_clear_ (daemon->itc);
1929  continue; /* Check again for resume. */
1930  } /* End of "suspended" branch. */
1931 
1932  if (was_suspended)
1933  {
1934  MHD_update_last_activity_ (con); /* Reset timeout timer. */
1935  /* Process response queued during suspend and update states. */
1937  was_suspended = false;
1938  }
1939 
1940  tvp = NULL;
1941 
1943 #ifdef HTTPS_SUPPORT
1944  || ( (con->tls_read_ready) &&
1946 #endif /* HTTPS_SUPPORT */
1947  )
1948  {
1949  /* do not block: more data may be inside of TLS buffers waiting or
1950  * application must provide response data */
1951  tv.tv_sec = 0;
1952  tv.tv_usec = 0;
1953  tvp = &tv;
1954  }
1955  if ( (NULL == tvp) &&
1956  (timeout > 0) )
1957  {
1958  now = MHD_monotonic_sec_counter();
1959  if (now - con->last_activity > timeout)
1960  tv.tv_sec = 0;
1961  else
1962  {
1963  const time_t seconds_left = timeout - (now - con->last_activity);
1964 #if !defined(_WIN32) || defined(__CYGWIN__)
1965  tv.tv_sec = seconds_left;
1966 #else /* _WIN32 && !__CYGWIN__ */
1967  if (seconds_left > TIMEVAL_TV_SEC_MAX)
1968  tv.tv_sec = TIMEVAL_TV_SEC_MAX;
1969  else
1970  tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left;
1971 #endif /* _WIN32 && ! __CYGWIN__ */
1972  }
1973  tv.tv_usec = 0;
1974  tvp = &tv;
1975  }
1976  if (! use_poll)
1977  {
1978  /* use select */
1979  bool err_state = false;
1980 
1981  FD_ZERO (&rs);
1982  FD_ZERO (&ws);
1983  FD_ZERO (&es);
1984  maxsock = MHD_INVALID_SOCKET;
1985  switch (con->event_loop_info)
1986  {
1988  if (! MHD_add_to_fd_set_ (con->socket_fd,
1989  &rs,
1990  &maxsock,
1991  FD_SETSIZE))
1992  err_state = true;
1993  break;
1995  if (! MHD_add_to_fd_set_ (con->socket_fd,
1996  &ws,
1997  &maxsock,
1998  FD_SETSIZE))
1999  err_state = true;
2000  break;
2002  if (! MHD_add_to_fd_set_ (con->socket_fd,
2003  &es,
2004  &maxsock,
2005  FD_SETSIZE))
2006  err_state = true;
2007  break;
2009  /* how did we get here!? */
2010  goto exit;
2011  }
2012 #if WINDOWS
2013  if (MHD_ITC_IS_VALID_(daemon->itc) )
2014  {
2015  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
2016  &rs,
2017  &maxsock,
2018  FD_SETSIZE))
2019  err_state = 1;
2020  }
2021 #endif
2022  if (err_state)
2023  {
2024 #ifdef HAVE_MESSAGES
2025  MHD_DLOG (con->daemon,
2026  _("Failed to add FD to fd_set\n"));
2027 #endif
2028  goto exit;
2029  }
2030 
2031  num_ready = MHD_SYS_select_ (maxsock + 1,
2032  &rs,
2033  &ws,
2034  &es,
2035  tvp);
2036  if (num_ready < 0)
2037  {
2038  const int err = MHD_socket_get_error_();
2039 
2040  if (MHD_SCKT_ERR_IS_EINTR_(err))
2041  continue;
2042 #ifdef HAVE_MESSAGES
2043  MHD_DLOG (con->daemon,
2044  _("Error during select (%d): `%s'\n"),
2045  err,
2046  MHD_socket_strerr_ (err));
2047 #endif
2048  break;
2049  }
2050 #if WINDOWS
2051  /* Clear ITC before other processing so additional
2052  * signals will trigger select() again */
2053  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2054  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
2055  &rs)) )
2056  MHD_itc_clear_ (daemon->itc);
2057 #endif
2058  if (MHD_NO ==
2059  call_handlers (con,
2060  FD_ISSET (con->socket_fd,
2061  &rs),
2062  FD_ISSET (con->socket_fd,
2063  &ws),
2064  FD_ISSET (con->socket_fd,
2065  &es)) )
2066  goto exit;
2067  }
2068 #ifdef HAVE_POLL
2069  else
2070  {
2071  /* use poll */
2072  memset (&p,
2073  0,
2074  sizeof (p));
2075  p[0].fd = con->socket_fd;
2076  switch (con->event_loop_info)
2077  {
2079  p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
2080  break;
2082  p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
2083  break;
2085  p[0].events |= MHD_POLL_EVENTS_ERR_DISC;
2086  break;
2088  /* how did we get here!? */
2089  goto exit;
2090  }
2091 #if WINDOWS
2092  extra_slot = 0;
2093  if (MHD_ITC_IS_VALID_(daemon->itc))
2094  {
2095  p[1].events |= POLLIN;
2096  p[1].fd = MHD_itc_r_fd_ (daemon->itc);
2097  p[1].revents = 0;
2098  extra_slot = 1;
2099  }
2100 #endif
2101  if (MHD_sys_poll_ (p,
2102 #if WINDOWS
2103  1 + extra_slot,
2104 #else
2105  1,
2106 #endif
2107  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
2108  {
2110  continue;
2111 #ifdef HAVE_MESSAGES
2112  MHD_DLOG (con->daemon,
2113  _("Error during poll: `%s'\n"),
2115 #endif
2116  break;
2117  }
2118 #if WINDOWS
2119  /* Clear ITC before other processing so additional
2120  * signals will trigger poll() again */
2121  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2122  (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) )
2123  MHD_itc_clear_ (daemon->itc);
2124 #endif
2125  if (MHD_NO ==
2126  call_handlers (con,
2127  0 != (p[0].revents & POLLIN),
2128  0 != (p[0].revents & POLLOUT),
2129  0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC))))
2130  goto exit;
2131  }
2132 #endif
2133 #ifdef UPGRADE_SUPPORT
2134  if (MHD_CONNECTION_UPGRADE == con->state)
2135  {
2136  /* Normal HTTP processing is finished,
2137  * notify application. */
2138  if ( (NULL != daemon->notify_completed) &&
2139  (con->client_aware) )
2140  daemon->notify_completed (daemon->notify_completed_cls,
2141  con,
2142  &con->client_context,
2144  con->client_aware = false;
2145 
2146  thread_main_connection_upgrade (con);
2147  /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */
2148 
2149  /* "Upgraded" data will not be used in this thread from this point. */
2150  con->urh->clean_ready = true;
2151  /* If 'urh->was_closed' set to true, connection will be
2152  * moved immediately to cleanup list. Otherwise connection
2153  * will stay in suspended list until 'urh' will be marked
2154  * with 'was_closed' by application. */
2155  MHD_resume_connection(con);
2156 
2157  /* skip usual clean up */
2158  return (MHD_THRD_RTRN_TYPE_) 0;
2159  }
2160 #endif /* UPGRADE_SUPPORT */
2161  }
2162 #if DEBUG_CLOSE
2163 #ifdef HAVE_MESSAGES
2164  MHD_DLOG (con->daemon,
2165  _("Processing thread terminating. Closing connection\n"));
2166 #endif
2167 #endif
2168  if (MHD_CONNECTION_CLOSED != con->state)
2169  MHD_connection_close_ (con,
2170  (daemon->shutdown) ?
2174 exit:
2175  if (NULL != con->response)
2176  {
2178  con->response = NULL;
2179  }
2180 
2181  if (MHD_INVALID_SOCKET != con->socket_fd)
2182  {
2183  shutdown (con->socket_fd,
2184  SHUT_WR);
2185  /* 'socket_fd' can be used in other thread to signal shutdown.
2186  * To avoid data races, do not close socket here. Daemon will
2187  * use more connections only after cleanup anyway. */
2188  }
2189  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2190  (! MHD_itc_activate_ (daemon->itc, "t")) )
2191  {
2192 #ifdef HAVE_MESSAGES
2193  MHD_DLOG (daemon,
2194  _("Failed to signal thread termination via inter-thread communication channel."));
2195 #endif
2196  }
2197  return (MHD_THRD_RTRN_TYPE_) 0;
2198 }
2199 #endif
2200 
2201 
2209 static void
2210 MHD_cleanup_connections (struct MHD_Daemon *daemon);
2211 
2212 #if defined(HTTPS_SUPPORT)
2213 #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \
2214  (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL)
2215 
2220 #define MHD_TLSLIB_NEED_PUSH_FUNC 1
2221 #endif /* !MHD_WINSOCK_SOCKETS && !MHD_socket_nosignal_ && (GNUTLS_VERSION_NUMBER+0 < 0x030402) */
2222 
2223 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2224 
2228 static ssize_t
2229 MHD_tls_push_func_(gnutls_transport_ptr_t trnsp,
2230  const void *data,
2231  size_t data_size)
2232 {
2233 #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX)
2234  if (data_size > MHD_SCKT_SEND_MAX_SIZE_)
2235  data_size = MHD_SCKT_SEND_MAX_SIZE_;
2236 #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */
2237  return MHD_send_ ((MHD_socket)(intptr_t)(trnsp), data, data_size);
2238 }
2239 #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */
2240 
2241 
2250 static int
2251 psk_gnutls_adapter (gnutls_session_t session,
2252  const char *username,
2253  gnutls_datum_t *key)
2254 {
2255  struct MHD_Connection *connection;
2256  struct MHD_Daemon *daemon;
2257  void *app_psk;
2258  size_t app_psk_size;
2259 
2260  connection = gnutls_session_get_ptr (session);
2261  if (NULL == connection)
2262  {
2263 #ifdef HAVE_MESSAGES
2264  /* Cannot use our logger, we don't even have "daemon" */
2265  MHD_PANIC (_("Internal server error. This should be impossible.\n"));
2266 #endif
2267  return -1;
2268  }
2269  daemon = connection->daemon;
2270 #if GNUTLS_VERSION_MAJOR >= 3
2271  if (NULL == daemon->cred_callback)
2272  {
2273 #ifdef HAVE_MESSAGES
2274  MHD_DLOG (daemon,
2275  _("PSK not supported by this server.\n"));
2276 #endif
2277  return -1;
2278  }
2279  if (0 != daemon->cred_callback (daemon->cred_callback_cls,
2280  connection,
2281  username,
2282  &app_psk,
2283  &app_psk_size))
2284  return -1;
2285  if (NULL == (key->data = gnutls_malloc (app_psk_size)))
2286  {
2287 #ifdef HAVE_MESSAGES
2288  MHD_DLOG (daemon,
2289  _("PSK authentication failed: gnutls_malloc failed to allocate memory\n"));
2290 #endif
2291  free (app_psk);
2292  return -1;
2293  }
2294  if (UINT_MAX < app_psk_size)
2295  {
2296 #ifdef HAVE_MESSAGES
2297  MHD_DLOG (daemon,
2298  _("PSK authentication failed: PSK too long\n"));
2299 #endif
2300  free (app_psk);
2301  return -1;
2302  }
2303  key->size = (unsigned int)app_psk_size;
2304  memcpy (key->data,
2305  app_psk,
2306  app_psk_size);
2307  free (app_psk);
2308  return 0;
2309 #else
2310 #ifdef HAVE_MESSAGES
2311  MHD_DLOG (daemon,
2312  _("PSK not supported by this server.\n"));
2313 #endif
2314  return -1;
2315 #endif
2316 }
2317 #endif /* HTTPS_SUPPORT */
2318 
2319 
2345 static int
2347  MHD_socket client_socket,
2348  const struct sockaddr *addr,
2349  socklen_t addrlen,
2350  bool external_add,
2351  bool non_blck)
2352 {
2353  struct MHD_Connection *connection;
2354 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2355  unsigned int i;
2356 #endif
2357  int eno = 0;
2358 
2359  /* Direct add to master daemon could happen only with "external" add mode. */
2360 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2361  mhd_assert ((NULL == daemon->worker_pool) || (external_add));
2362  if ((external_add) && (NULL != daemon->worker_pool))
2363  {
2364  /* have a pool, try to find a pool with capacity; we use the
2365  socket as the initial offset into the pool for load
2366  balancing */
2367  for (i = 0; i < daemon->worker_pool_size; ++i)
2368  {
2369  struct MHD_Daemon * const worker =
2370  &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
2371  if (worker->connections < worker->connection_limit)
2372  return internal_add_connection (worker,
2373  client_socket,
2374  addr,
2375  addrlen,
2376  true,
2377  non_blck);
2378  }
2379  /* all pools are at their connection limit, must refuse */
2380  MHD_socket_close_chk_ (client_socket);
2381 #if ENFILE
2382  errno = ENFILE;
2383 #endif
2384  return MHD_NO;
2385  }
2386 #endif
2387 
2388  if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket,
2389  NULL)) &&
2390  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) )
2391  {
2392 #ifdef HAVE_MESSAGES
2393  MHD_DLOG (daemon,
2394  _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
2395  (int) client_socket,
2396  (int) FD_SETSIZE);
2397 #endif
2398  MHD_socket_close_chk_ (client_socket);
2399 #if EINVAL
2400  errno = EINVAL;
2401 #endif
2402  return MHD_NO;
2403  }
2404 
2405 #ifdef MHD_socket_nosignal_
2406  if (! MHD_socket_nosignal_ (client_socket))
2407  {
2408 #ifdef HAVE_MESSAGES
2409  MHD_DLOG (daemon,
2410  _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"),
2412 #endif
2413 #ifndef MSG_NOSIGNAL
2414  /* Cannot use socket as it can produce SIGPIPE. */
2415 #ifdef ENOTSOCK
2416  errno = ENOTSOCK;
2417 #endif /* ENOTSOCK */
2418  return MHD_NO;
2419 #endif /* ! MSG_NOSIGNAL */
2420  }
2421 #endif /* MHD_socket_nosignal_ */
2422 
2423 
2424 #ifdef HAVE_MESSAGES
2425 #if DEBUG_CONNECT
2426  MHD_DLOG (daemon,
2427  _("Accepted connection on socket %d\n"),
2428  client_socket);
2429 #endif
2430 #endif
2431  if ( (daemon->connections == daemon->connection_limit) ||
2432  (MHD_NO == MHD_ip_limit_add (daemon,
2433  addr,
2434  addrlen)) )
2435  {
2436  /* above connection limit - reject */
2437 #ifdef HAVE_MESSAGES
2438  MHD_DLOG (daemon,
2439  _("Server reached connection limit. Closing inbound connection.\n"));
2440 #endif
2441  MHD_socket_close_chk_ (client_socket);
2442 #if ENFILE
2443  errno = ENFILE;
2444 #endif
2445  return MHD_NO;
2446  }
2447 
2448  /* apply connection acceptance policy if present */
2449  if ( (NULL != daemon->apc) &&
2450  (MHD_NO == daemon->apc (daemon->apc_cls,
2451  addr,
2452  addrlen)) )
2453  {
2454 #if DEBUG_CLOSE
2455 #ifdef HAVE_MESSAGES
2456  MHD_DLOG (daemon,
2457  _("Connection rejected by application. Closing connection.\n"));
2458 #endif
2459 #endif
2460  MHD_socket_close_chk_ (client_socket);
2461  MHD_ip_limit_del (daemon,
2462  addr,
2463  addrlen);
2464 #if EACCESS
2465  errno = EACCESS;
2466 #endif
2467  return MHD_NO;
2468  }
2469 
2470  if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection))))
2471  {
2472  eno = errno;
2473 #ifdef HAVE_MESSAGES
2474  MHD_DLOG (daemon,
2475  "Error allocating memory: %s\n",
2476  MHD_strerror_ (errno));
2477 #endif
2478  MHD_socket_close_chk_ (client_socket);
2479  MHD_ip_limit_del (daemon,
2480  addr,
2481  addrlen);
2482  errno = eno;
2483  return MHD_NO;
2484  }
2485  connection->pool = MHD_pool_create (daemon->pool_size);
2486  if (NULL == connection->pool)
2487  {
2488 #ifdef HAVE_MESSAGES
2489  MHD_DLOG (daemon,
2490  _("Error allocating memory: %s\n"),
2491  MHD_strerror_ (errno));
2492 #endif
2493  MHD_socket_close_chk_ (client_socket);
2494  MHD_ip_limit_del (daemon,
2495  addr,
2496  addrlen);
2497  free (connection);
2498 #if ENOMEM
2499  errno = ENOMEM;
2500 #endif
2501  return MHD_NO;
2502  }
2503 
2504  connection->connection_timeout = daemon->connection_timeout;
2505  if (NULL == (connection->addr = malloc (addrlen)))
2506  {
2507  eno = errno;
2508 #ifdef HAVE_MESSAGES
2509  MHD_DLOG (daemon,
2510  _("Error allocating memory: %s\n"),
2511  MHD_strerror_ (errno));
2512 #endif
2513  MHD_socket_close_chk_ (client_socket);
2514  MHD_ip_limit_del (daemon,
2515  addr,
2516  addrlen);
2517  MHD_pool_destroy (connection->pool);
2518  free (connection);
2519  errno = eno;
2520  return MHD_NO;
2521  }
2522  memcpy (connection->addr,
2523  addr,
2524  addrlen);
2525  connection->addr_len = addrlen;
2526  connection->socket_fd = client_socket;
2527  connection->sk_nonblck = non_blck;
2528  connection->daemon = daemon;
2529  connection->last_activity = MHD_monotonic_sec_counter();
2530 
2531  if (0 == (daemon->options & MHD_USE_TLS))
2532  {
2533  /* set default connection handlers */
2534  MHD_set_http_callbacks_ (connection);
2535  }
2536  else
2537  {
2538 #ifdef HTTPS_SUPPORT
2539  gnutls_init_flags_t flags;
2540 
2541  flags = GNUTLS_SERVER;
2542 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402)
2543  flags |= GNUTLS_NO_SIGNAL;
2544 #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */
2545 #if GNUTLS_VERSION_MAJOR >= 3
2546  flags |= GNUTLS_NONBLOCK;
2547 #endif /* GNUTLS_VERSION_MAJOR >= 3*/
2548 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030603)
2549  if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT))
2550  flags |= GNUTLS_POST_HANDSHAKE_AUTH;
2551 #endif
2552 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030605)
2553  if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA))
2554  flags |= GNUTLS_ENABLE_EARLY_DATA;
2555 #endif
2556  connection->tls_state = MHD_TLS_CONN_INIT;
2557  MHD_set_https_callbacks (connection);
2558  gnutls_init (&connection->tls_session,
2559  flags);
2560  gnutls_priority_set (connection->tls_session,
2561  daemon->priority_cache);
2562  gnutls_session_set_ptr (connection->tls_session,
2563  connection);
2564  switch (daemon->cred_type)
2565  {
2566  /* set needed credentials for certificate authentication. */
2567  case GNUTLS_CRD_CERTIFICATE:
2568  gnutls_credentials_set (connection->tls_session,
2569  GNUTLS_CRD_CERTIFICATE,
2570  daemon->x509_cred);
2571  break;
2572  case GNUTLS_CRD_PSK:
2573  gnutls_credentials_set (connection->tls_session,
2574  GNUTLS_CRD_PSK,
2575  daemon->psk_cred);
2576  gnutls_psk_set_server_credentials_function (daemon->psk_cred,
2577  &psk_gnutls_adapter);
2578  break;
2579  default:
2580 #ifdef HAVE_MESSAGES
2581  MHD_DLOG (connection->daemon,
2582  _("Failed to setup TLS credentials: unknown credential type %d\n"),
2583  daemon->cred_type);
2584 #endif
2585  MHD_socket_close_chk_ (client_socket);
2586  MHD_ip_limit_del (daemon,
2587  addr,
2588  addrlen);
2589  free (connection->addr);
2590  free (connection);
2591  MHD_PANIC (_("Unknown credential type"));
2592 #if EINVAL
2593  errno = EINVAL;
2594 #endif
2595  return MHD_NO;
2596  }
2597 #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64)
2598  gnutls_transport_set_int (connection->tls_session,
2599  (int)(client_socket));
2600 #else /* GnuTLS before 3.1.9 or Win x64 */
2601  gnutls_transport_set_ptr (connection->tls_session,
2602  (gnutls_transport_ptr_t)(intptr_t)(client_socket));
2603 #endif /* GnuTLS before 3.1.9 */
2604 #ifdef MHD_TLSLIB_NEED_PUSH_FUNC
2605  gnutls_transport_set_push_function (connection->tls_session,
2606  MHD_tls_push_func_);
2607 #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */
2608  if (daemon->https_mem_trust)
2609  gnutls_certificate_server_set_request (connection->tls_session,
2610  GNUTLS_CERT_REQUEST);
2611 #else /* ! HTTPS_SUPPORT */
2612  eno = EINVAL;
2613  goto cleanup;
2614 #endif /* ! HTTPS_SUPPORT */
2615  }
2616 
2617 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2619 #endif
2620  /* Firm check under lock. */
2621  if (daemon->connections >= daemon->connection_limit)
2622  {
2623 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2625 #endif
2626  /* above connection limit - reject */
2627 #ifdef HAVE_MESSAGES
2628  MHD_DLOG (daemon,
2629  _("Server reached connection limit. Closing inbound connection.\n"));
2630 #endif
2631 #if ENFILE
2632  eno = ENFILE;
2633 #endif
2634  goto cleanup;
2635  }
2636  daemon->connections++;
2637  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2638  {
2640  daemon->normal_timeout_tail,
2641  connection);
2642  }
2643  DLL_insert (daemon->connections_head,
2644  daemon->connections_tail,
2645  connection);
2646 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2648 #endif
2649  if (NULL != daemon->notify_connection)
2650  daemon->notify_connection (daemon->notify_connection_cls,
2651  connection,
2652  &connection->socket_context,
2654 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2655  /* attempt to create handler thread */
2656  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2657  {
2658  if (! MHD_create_named_thread_ (&connection->pid,
2659  "MHD-connection",
2660  daemon->thread_stack_size,
2662  connection))
2663  {
2664  eno = errno;
2665 #ifdef HAVE_MESSAGES
2666  MHD_DLOG (daemon,
2667  "Failed to create a thread: %s\n",
2668  MHD_strerror_ (eno));
2669 #endif
2670  goto cleanup;
2671  }
2672  }
2673  else
2674  connection->pid = daemon->pid;
2675 #endif
2676 #ifdef EPOLL_SUPPORT
2677  if (0 != (daemon->options & MHD_USE_EPOLL))
2678  {
2679  if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add))
2680  { /* Do not manipulate EReady DL-list in 'external_add' mode. */
2681  struct epoll_event event;
2682 
2683  event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET;
2684  event.data.ptr = connection;
2685  if (0 != epoll_ctl (daemon->epoll_fd,
2686  EPOLL_CTL_ADD,
2687  client_socket,
2688  &event))
2689  {
2690  eno = errno;
2691 #ifdef HAVE_MESSAGES
2692  MHD_DLOG (daemon,
2693  _("Call to epoll_ctl failed: %s\n"),
2695 #endif
2696  goto cleanup;
2697  }
2698  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
2699  }
2700  else
2701  {
2702  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
2704  EDLL_insert (daemon->eready_head,
2705  daemon->eready_tail,
2706  connection);
2707  }
2708  }
2709  else /* This 'else' is combined with next 'if'. */
2710 #endif
2711  if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2712  (external_add) &&
2713  (MHD_ITC_IS_VALID_(daemon->itc)) &&
2714  (! MHD_itc_activate_ (daemon->itc, "n")) )
2715  {
2716 #ifdef HAVE_MESSAGES
2717  MHD_DLOG (daemon,
2718  _("Failed to signal new connection via inter-thread communication channel."));
2719 #endif
2720  }
2721  return MHD_YES;
2722  cleanup:
2723  if (NULL != daemon->notify_connection)
2724  daemon->notify_connection (daemon->notify_connection_cls,
2725  connection,
2726  &connection->socket_context,
2728 #ifdef HTTPS_SUPPORT
2729  if (NULL != connection->tls_session)
2730  gnutls_deinit (connection->tls_session);
2731 #endif /* HTTPS_SUPPORT */
2732  MHD_socket_close_chk_ (client_socket);
2733  MHD_ip_limit_del (daemon,
2734  addr,
2735  addrlen);
2736 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2738 #endif
2739  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2740  {
2742  daemon->normal_timeout_tail,
2743  connection);
2744  }
2745  DLL_remove (daemon->connections_head,
2746  daemon->connections_tail,
2747  connection);
2748 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2750 #endif
2751  MHD_pool_destroy (connection->pool);
2752  free (connection->addr);
2753  free (connection);
2754  if (0 != eno)
2755  errno = eno;
2756  else
2757  errno = EINVAL;
2758  return MHD_NO;
2759 }
2760 
2761 
2771 void
2773 {
2774  struct MHD_Daemon *daemon = connection->daemon;
2775 
2776 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2778 #endif
2779  if (connection->resuming)
2780  {
2781  /* suspending again while we didn't even complete resuming yet */
2782  connection->resuming = false;
2783 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2785 #endif
2786  return;
2787  }
2788  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2789  {
2790  if (connection->connection_timeout == daemon->connection_timeout)
2792  daemon->normal_timeout_tail,
2793  connection);
2794  else
2796  daemon->manual_timeout_tail,
2797  connection);
2798  }
2799  DLL_remove (daemon->connections_head,
2800  daemon->connections_tail,
2801  connection);
2802  mhd_assert (! connection->suspended);
2805  connection);
2806  connection->suspended = true;
2807 #ifdef EPOLL_SUPPORT
2808  if (0 != (daemon->options & MHD_USE_EPOLL))
2809  {
2810  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2811  {
2812  EDLL_remove (daemon->eready_head,
2813  daemon->eready_tail,
2814  connection);
2815  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2816  }
2817  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
2818  {
2819  if (0 != epoll_ctl (daemon->epoll_fd,
2820  EPOLL_CTL_DEL,
2821  connection->socket_fd,
2822  NULL))
2823  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
2824  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
2825  }
2826  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
2827  }
2828 #endif
2829 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2831 #endif
2832 }
2833 
2834 
2866 void
2868 {
2869  struct MHD_Daemon * const daemon = connection->daemon;
2870 
2871  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2872  MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2873 #ifdef UPGRADE_SUPPORT
2874  if (NULL != connection->urh)
2875  {
2876 #ifdef HAVE_MESSAGES
2877  MHD_DLOG (daemon,
2878  _("Error: connection scheduled for \"upgrade\" cannot be suspended"));
2879 #endif /* HAVE_MESSAGES */
2880  return;
2881  }
2882 #endif /* UPGRADE_SUPPORT */
2883  internal_suspend_connection_ (connection);
2884 }
2885 
2886 
2895 void
2897 {
2898  struct MHD_Daemon *daemon = connection->daemon;
2899 
2900  if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
2901  MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n"));
2902 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2904 #endif
2905  connection->resuming = true;
2906  daemon->resuming = true;
2907 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2909 #endif
2910  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
2911  (! MHD_itc_activate_ (daemon->itc, "r")) )
2912  {
2913 #ifdef HAVE_MESSAGES
2914  MHD_DLOG (daemon,
2915  _("Failed to signal resume via inter-thread communication channel."));
2916 #endif
2917  }
2918 }
2919 
2920 
2930 static int
2932 {
2933  struct MHD_Connection *pos;
2934  struct MHD_Connection *prev = NULL;
2935  int ret;
2936  const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
2937 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2939 #endif
2940  ret = MHD_NO;
2941 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
2943 #endif
2944  if (daemon->resuming)
2945  {
2947  /* During shutdown check for resuming is forced. */
2948  mhd_assert((NULL != prev) || (daemon->shutdown));
2949  }
2950 
2951  daemon->resuming = false;
2952 
2953  while (NULL != (pos = prev))
2954  {
2955 #ifdef UPGRADE_SUPPORT
2956  struct MHD_UpgradeResponseHandle * const urh = pos->urh;
2957 #else /* ! UPGRADE_SUPPORT */
2958  static const void * const urh = NULL;
2959 #endif /* ! UPGRADE_SUPPORT */
2960  prev = pos->prev;
2961  if ( (! pos->resuming)
2962 #ifdef UPGRADE_SUPPORT
2963  || ( (NULL != urh) &&
2964  ( (! urh->was_closed) ||
2965  (! urh->clean_ready) ) )
2966 #endif /* UPGRADE_SUPPORT */
2967  )
2968  continue;
2969  ret = MHD_YES;
2970  mhd_assert (pos->suspended);
2973  pos);
2974  pos->suspended = false;
2975  if (NULL == urh)
2976  {
2977  DLL_insert (daemon->connections_head,
2978  daemon->connections_tail,
2979  pos);
2980  if (! used_thr_p_c)
2981  {
2982  /* Reset timeout timer on resume. */
2983  if (0 != pos->connection_timeout)
2985 
2986  if (pos->connection_timeout == daemon->connection_timeout)
2988  daemon->normal_timeout_tail,
2989  pos);
2990  else
2992  daemon->manual_timeout_tail,
2993  pos);
2994  }
2995 #ifdef EPOLL_SUPPORT
2996  if (0 != (daemon->options & MHD_USE_EPOLL))
2997  {
2998  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2999  MHD_PANIC ("Resumed connection was already in EREADY set\n");
3000  /* we always mark resumed connections as ready, as we
3001  might have missed the edge poll event during suspension */
3002  EDLL_insert (daemon->eready_head,
3003  daemon->eready_tail,
3004  pos);
3005  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \
3006  MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
3007  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
3008  }
3009 #endif
3010  }
3011 #ifdef UPGRADE_SUPPORT
3012  else
3013  {
3014  /* Data forwarding was finished (for TLS connections) AND
3015  * application was closed upgraded connection.
3016  * Insert connection into cleanup list. */
3017 
3018  if ( (NULL != daemon->notify_completed) &&
3019  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3020  (pos->client_aware) )
3021  {
3022  daemon->notify_completed (daemon->notify_completed_cls,
3023  pos,
3024  &pos->client_context,
3026  pos->client_aware = false;
3027  }
3028  DLL_insert (daemon->cleanup_head,
3029  daemon->cleanup_tail,
3030  pos);
3031 
3032  }
3033 #endif /* UPGRADE_SUPPORT */
3034  pos->resuming = false;
3035  }
3036 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3038 #endif
3039  if ( (used_thr_p_c) &&
3040  (MHD_NO != ret) )
3041  { /* Wake up suspended connections. */
3042  if (! MHD_itc_activate_(daemon->itc,
3043  "w"))
3044  {
3045 #ifdef HAVE_MESSAGES
3046  MHD_DLOG (daemon,
3047  _("Failed to signal resume of connection via inter-thread communication channel."));
3048 #endif
3049  }
3050  }
3051  return ret;
3052 }
3053 
3054 
3082 int
3084  MHD_socket client_socket,
3085  const struct sockaddr *addr,
3086  socklen_t addrlen)
3087 {
3088  bool sk_nonbl;
3089 
3090  if (! MHD_socket_nonblocking_ (client_socket))
3091  {
3092 #ifdef HAVE_MESSAGES
3093  MHD_DLOG (daemon,
3094  _("Failed to set nonblocking mode on new client socket: %s\n"),
3096 #endif
3097  sk_nonbl = 0;
3098  }
3099  else
3100  sk_nonbl = !0;
3101 
3102  if ( (0 != (daemon->options & MHD_USE_TURBO)) &&
3103  (! MHD_socket_noninheritable_ (client_socket)) )
3104  {
3105 #ifdef HAVE_MESSAGES
3106  MHD_DLOG (daemon,
3107  _("Failed to set noninheritable mode on new client socket.\n"));
3108 #endif
3109  }
3110 
3111  if ( (0 == (daemon->options & MHD_USE_TURBO)) &&
3112  (! MHD_socket_buffering_reset_ (client_socket)) )
3113  {
3114 #ifdef HAVE_MESSAGES
3115  MHD_DLOG (daemon,
3116  _("Failed to reset buffering mode on new client socket.\n"));
3117 #endif
3118  }
3119  return internal_add_connection (daemon,
3120  client_socket,
3121  addr,
3122  addrlen,
3123  true,
3124  sk_nonbl);
3125 }
3126 
3127 
3142 static int
3144 {
3145 #if HAVE_INET6
3146  struct sockaddr_in6 addrstorage;
3147 #else
3148  struct sockaddr_in addrstorage;
3149 #endif
3150  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
3151  socklen_t addrlen;
3152  MHD_socket s;
3153  MHD_socket fd;
3154  bool sk_nonbl;
3155 
3156  addrlen = sizeof (addrstorage);
3157  memset (addr,
3158  0,
3159  sizeof (addrstorage));
3160  if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) ||
3161  (daemon->was_quiesced) )
3162  return MHD_NO;
3163 #ifdef USE_ACCEPT4
3164  s = accept4 (fd,
3165  addr,
3166  &addrlen,
3168  sk_nonbl = (MAYBE_SOCK_NONBLOCK != 0);
3169 #else /* ! USE_ACCEPT4 */
3170  s = accept (fd,
3171  addr,
3172  &addrlen);
3173  sk_nonbl = 0;
3174 #endif /* ! USE_ACCEPT4 */
3175  if ( (MHD_INVALID_SOCKET == s) ||
3176  (addrlen <= 0) )
3177  {
3178  const int err = MHD_socket_get_error_ ();
3179 
3180  /* This could be a common occurance with multiple worker threads */
3181  if (MHD_SCKT_ERR_IS_ (err,
3183  return MHD_NO; /* can happen during shutdown */
3185  return MHD_NO; /* do not print error if client just disconnected early */
3186 #ifdef HAVE_MESSAGES
3187  if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) )
3188  MHD_DLOG (daemon,
3189  _("Error accepting connection: %s\n"),
3190  MHD_socket_strerr_(err));
3191 #endif
3192  if (MHD_INVALID_SOCKET != s)
3193  {
3195  }
3196  if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) )
3197  {
3198  /* system/process out of resources */
3199  if (0 == daemon->connections)
3200  {
3201 #ifdef HAVE_MESSAGES
3202  /* Not setting 'at_limit' flag, as there is no way it
3203  would ever be cleared. Instead trying to produce
3204  bit fat ugly warning. */
3205  MHD_DLOG (daemon,
3206  _("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"));
3207 #endif
3208  }
3209  else
3210  {
3211 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3213 #endif
3214  daemon->at_limit = true;
3215 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3217 #endif
3218 #ifdef HAVE_MESSAGES
3219  MHD_DLOG (daemon,
3220  _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"),
3221  (unsigned int) daemon->connections);
3222 #endif
3223  }
3224  }
3225  return MHD_NO;
3226  }
3227 #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK)
3228  if (! MHD_socket_nonblocking_ (s))
3229  {
3230 #ifdef HAVE_MESSAGES
3231  MHD_DLOG (daemon,
3232  _("Failed to set nonblocking mode on incoming connection socket: %s\n"),
3234 #endif
3235  }
3236  else
3237  sk_nonbl = !0;
3238 #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */
3239 #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC)
3240  if (! MHD_socket_noninheritable_ (s))
3241  {
3242 #ifdef HAVE_MESSAGES
3243  MHD_DLOG (daemon,
3244  _("Failed to set noninheritable mode on incoming connection socket.\n"));
3245 #endif
3246  }
3247 #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */
3248 #ifdef HAVE_MESSAGES
3249 #if DEBUG_CONNECT
3250  MHD_DLOG (daemon,
3251  _("Accepted connection on socket %d\n"),
3252  s);
3253 #endif
3254 #endif
3255  (void) internal_add_connection (daemon,
3256  s,
3257  addr,
3258  addrlen,
3259  false,
3260  sk_nonbl);
3261  return MHD_YES;
3262 }
3263 
3264 
3274 static void
3276 {
3277  struct MHD_Connection *pos;
3278 
3279 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3281 #endif
3282  while (NULL != (pos = daemon->cleanup_tail))
3283  {
3286  pos);
3287 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3289  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3290  (! pos->thread_joined) &&
3291  (! MHD_join_thread_ (pos->pid.handle)) )
3292  MHD_PANIC (_("Failed to join a thread\n"));
3293 #endif
3294 #ifdef UPGRADE_SUPPORT
3295  cleanup_upgraded_connection (pos);
3296 #endif /* UPGRADE_SUPPORT */
3297  MHD_pool_destroy (pos->pool);
3298 #ifdef HTTPS_SUPPORT
3299  if (NULL != pos->tls_session)
3300  gnutls_deinit (pos->tls_session);
3301 #endif /* HTTPS_SUPPORT */
3302 
3303  /* clean up the connection */
3304  if (NULL != daemon->notify_connection)
3306  pos,
3307  &pos->socket_context,
3310  pos->addr,
3311  pos->addr_len);
3312 #ifdef EPOLL_SUPPORT
3313  if (0 != (daemon->options & MHD_USE_EPOLL))
3314  {
3315  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
3316  {
3317  EDLL_remove (daemon->eready_head,
3318  daemon->eready_tail,
3319  pos);
3320  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
3321  }
3322  if ( (-1 != daemon->epoll_fd) &&
3323  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
3324  {
3325  /* epoll documentation suggests that closing a FD
3326  automatically removes it from the epoll set; however,
3327  this is not true as if we fail to do manually remove it,
3328  we are still seeing an event for this fd in epoll,
3329  causing grief (use-after-free...) --- at least on my
3330  system. */
3331  if (0 != epoll_ctl (daemon->epoll_fd,
3332  EPOLL_CTL_DEL,
3333  pos->socket_fd,
3334  NULL))
3335  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
3336  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
3337  }
3338  }
3339 #endif
3340  if (NULL != pos->response)
3341  {
3343  pos->response = NULL;
3344  }
3345  if (MHD_INVALID_SOCKET != pos->socket_fd)
3347  if (NULL != pos->addr)
3348  free (pos->addr);
3349  free (pos);
3350 
3351 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3353 #endif
3354  daemon->connections--;
3355  daemon->at_limit = false;
3356  }
3357 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
3359 #endif
3360 }
3361 
3362 
3383 int
3385  MHD_UNSIGNED_LONG_LONG *timeout)
3386 {
3387  time_t earliest_deadline;
3388  time_t now;
3389  struct MHD_Connection *pos;
3390  bool have_timeout;
3391 
3393  {
3394 #ifdef HAVE_MESSAGES
3395  MHD_DLOG (daemon,
3396  _("Illegal call to MHD_get_timeout\n"));
3397 #endif
3398  return MHD_NO;
3399  }
3400 
3402  {
3403  /* Some data already waiting to be processed. */
3404  *timeout = 0;
3405  return MHD_YES;
3406  }
3407 
3408 #ifdef EPOLL_SUPPORT
3409  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
3410  ((NULL != daemon->eready_head)
3411 #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT)
3412  || (NULL != daemon->eready_urh_head)
3413 #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */
3414  ) )
3415  {
3416  /* Some connection(s) already have some data pending. */
3417  *timeout = 0;
3418  return MHD_YES;
3419  }
3420 #endif /* EPOLL_SUPPORT */
3421 
3422  have_timeout = false;
3423  earliest_deadline = 0; /* avoid compiler warnings */
3424  for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX)
3425  {
3426  if (0 != pos->connection_timeout)
3427  {
3428  if ( (! have_timeout) ||
3429  (earliest_deadline - pos->last_activity > pos->connection_timeout) )
3430  earliest_deadline = pos->last_activity + pos->connection_timeout;
3431  have_timeout = true;
3432  }
3433  }
3434  /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */
3435  pos = daemon->normal_timeout_tail;
3436  if ( (NULL != pos) &&
3437  (0 != pos->connection_timeout) )
3438  {
3439  if ( (! have_timeout) ||
3440  (earliest_deadline - pos->connection_timeout > pos->last_activity) )
3441  earliest_deadline = pos->last_activity + pos->connection_timeout;
3442  have_timeout = true;
3443  }
3444 
3445  if (! have_timeout)
3446  return MHD_NO;
3447  now = MHD_monotonic_sec_counter();
3448  if (earliest_deadline < now)
3449  *timeout = 0;
3450  else
3451  {
3452  const time_t second_left = earliest_deadline - now;
3453 
3454  if (((unsigned long long)second_left) > ULLONG_MAX / 1000)
3455  *timeout = ULLONG_MAX;
3456  else
3457  *timeout = 1000LLU * (unsigned long long) second_left;
3458  }
3459  return MHD_YES;
3460 }
3461 
3462 
3473 static int
3475  const fd_set *read_fd_set,
3476  const fd_set *write_fd_set,
3477  const fd_set *except_fd_set)
3478 {
3479  MHD_socket ds;
3480  struct MHD_Connection *pos;
3481  struct MHD_Connection *prev;
3482 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3483  struct MHD_UpgradeResponseHandle *urh;
3484  struct MHD_UpgradeResponseHandle *urhn;
3485 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3486  /* Reset. New value will be set when connections are processed. */
3487  /* Note: no-op for thread-per-connection as it is always false in that mode. */
3488  daemon->data_already_pending = false;
3489 
3490  /* Clear ITC to avoid spinning select */
3491  /* Do it before any other processing so new signals
3492  will trigger select again and will be processed */
3493  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
3494  (FD_ISSET (MHD_itc_r_fd_ (daemon->itc),
3495  read_fd_set)) )
3496  MHD_itc_clear_ (daemon->itc);
3497 
3498  /* select connection thread handling type */
3499  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
3500  (! daemon->was_quiesced) &&
3501  (FD_ISSET (ds,
3502  read_fd_set)) )
3503  (void) MHD_accept_connection (daemon);
3504 
3505  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3506  {
3507  /* do not have a thread per connection, process all connections now */
3508  prev = daemon->connections_tail;
3509  while (NULL != (pos = prev))
3510  {
3511  prev = pos->prev;
3512  ds = pos->socket_fd;
3513  if (MHD_INVALID_SOCKET == ds)
3514  continue;
3515  call_handlers (pos,
3516  FD_ISSET (ds,
3517  read_fd_set),
3518  FD_ISSET (ds,
3519  write_fd_set),
3520  FD_ISSET (ds,
3521  except_fd_set));
3522  }
3523  }
3524 
3525 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3526  /* handle upgraded HTTPS connections */
3527  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3528  {
3529  urhn = urh->prev;
3530  /* update urh state based on select() output */
3531  urh_from_fdset (urh,
3532  read_fd_set,
3533  write_fd_set,
3534  except_fd_set);
3535  /* call generic forwarding function for passing data */
3536  process_urh (urh);
3537  /* Finished forwarding? */
3538  if ( (0 == urh->in_buffer_size) &&
3539  (0 == urh->out_buffer_size) &&
3540  (0 == urh->in_buffer_used) &&
3541  (0 == urh->out_buffer_used) )
3542  {
3543  MHD_connection_finish_forward_ (urh->connection);
3544  urh->clean_ready = true;
3545  /* Resuming will move connection to cleanup list. */
3546  MHD_resume_connection(urh->connection);
3547  }
3548  }
3549 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3550  MHD_cleanup_connections (daemon);
3551  return MHD_YES;
3552 }
3553 
3554 
3577 int
3579  const fd_set *read_fd_set,
3580  const fd_set *write_fd_set,
3581  const fd_set *except_fd_set)
3582 {
3583  fd_set es;
3584  if (0 != (daemon->options &
3586  return MHD_NO;
3587  if (NULL == read_fd_set || NULL == write_fd_set)
3588  return MHD_NO;
3589  if (NULL == except_fd_set)
3590  { /* Workaround to maintain backward compatibility. */
3591 #ifdef HAVE_MESSAGES
3592  MHD_DLOG (daemon,
3593  _("MHD_run_from_select() called with except_fd_set "
3594  "set to NULL. Such behavior is deprecated.\n"));
3595 #endif
3596  FD_ZERO (&es);
3597  except_fd_set = &es;
3598  }
3599  if (0 != (daemon->options & MHD_USE_EPOLL))
3600  {
3601 #ifdef EPOLL_SUPPORT
3602  int ret = MHD_epoll (daemon,
3603  MHD_NO);
3604 
3605  MHD_cleanup_connections (daemon);
3606  return ret;
3607 #else /* ! EPOLL_SUPPORT */
3608  return MHD_NO;
3609 #endif /* ! EPOLL_SUPPORT */
3610  }
3611 
3612  /* Resuming external connections when using an extern mainloop */
3613  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
3615 
3616  return internal_run_from_select (daemon,
3617  read_fd_set,
3618  write_fd_set,
3619  except_fd_set);
3620 }
3621 
3622 
3631 static int
3632 MHD_select (struct MHD_Daemon *daemon,
3633  int may_block)
3634 {
3635  int num_ready;
3636  fd_set rs;
3637  fd_set ws;
3638  fd_set es;
3639  MHD_socket maxsock;
3640  struct timeval timeout;
3641  struct timeval *tv;
3642  MHD_UNSIGNED_LONG_LONG ltimeout;
3643  int err_state;
3644  MHD_socket ls;
3645 
3646  timeout.tv_sec = 0;
3647  timeout.tv_usec = 0;
3648  if (daemon->shutdown)
3649  return MHD_NO;
3650  FD_ZERO (&rs);
3651  FD_ZERO (&ws);
3652  FD_ZERO (&es);
3653  maxsock = MHD_INVALID_SOCKET;
3654  err_state = MHD_NO;
3655  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3656  (MHD_YES == resume_suspended_connections (daemon)) &&
3657  (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
3658  may_block = MHD_NO;
3659 
3660  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3661  {
3662  /* single-threaded, go over everything */
3663  if (MHD_NO ==
3664  internal_get_fdset2 (daemon,
3665  &rs,
3666  &ws,
3667  &es,
3668  &maxsock,
3669  FD_SETSIZE))
3670  {
3671 #ifdef HAVE_MESSAGES
3672  MHD_DLOG (daemon,
3673  _("Could not obtain daemon fdsets"));
3674 #endif
3675  err_state = MHD_YES;
3676  }
3677  }
3678  else
3679  {
3680  /* accept only, have one thread per connection */
3681  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3682  (! daemon->was_quiesced) &&
3683  (! MHD_add_to_fd_set_ (ls,
3684  &rs,
3685  &maxsock,
3686  FD_SETSIZE)) )
3687  {
3688 #ifdef HAVE_MESSAGES
3689  MHD_DLOG (daemon,
3690  _("Could not add listen socket to fdset"));
3691 #endif
3692  return MHD_NO;
3693  }
3694  }
3695  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
3696  (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc),
3697  &rs,
3698  &maxsock,
3699  FD_SETSIZE)) )
3700  {
3701 #if defined(MHD_WINSOCK_SOCKETS)
3702  /* fdset limit reached, new connections
3703  cannot be handled. Remove listen socket FD
3704  from fdset and retry to add ITC FD. */
3705  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3706  (! daemon->was_quiesced) )
3707  {
3708  FD_CLR (ls,
3709  &rs);
3710  if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc),
3711  &rs,
3712  &maxsock,
3713  FD_SETSIZE))
3714  {
3715 #endif /* MHD_WINSOCK_SOCKETS */
3716 #ifdef HAVE_MESSAGES
3717  MHD_DLOG (daemon,
3718  _("Could not add control inter-thread communication channel FD to fdset"));
3719 #endif
3720  err_state = MHD_YES;
3721 #if defined(MHD_WINSOCK_SOCKETS)
3722  }
3723  }
3724 #endif /* MHD_WINSOCK_SOCKETS */
3725  }
3726  /* Stop listening if we are at the configured connection limit */
3727  /* If we're at the connection limit, no point in really
3728  accepting new connections; however, make sure we do not miss
3729  the shutdown OR the termination of an existing connection; so
3730  only do this optimization if we have a signaling ITC in
3731  place. */
3732  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3733  (MHD_ITC_IS_VALID_(daemon->itc)) &&
3734  ( (daemon->connections == daemon->connection_limit) ||
3735  (daemon->at_limit) ) )
3736  {
3737  FD_CLR (ls,
3738  &rs);
3739  }
3740  tv = NULL;
3741  if (MHD_YES == err_state)
3742  may_block = MHD_NO;
3743  if (MHD_NO == may_block)
3744  {
3745  timeout.tv_usec = 0;
3746  timeout.tv_sec = 0;
3747  tv = &timeout;
3748  }
3749  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3750  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
3751  {
3752  /* ltimeout is in ms */
3753  timeout.tv_usec = (ltimeout % 1000) * 1000;
3754  if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
3755  timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
3756  else
3757  timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000);
3758  tv = &timeout;
3759  }
3760  num_ready = MHD_SYS_select_ (maxsock + 1,
3761  &rs,
3762  &ws,
3763  &es,
3764  tv);
3765  if (daemon->shutdown)
3766  return MHD_NO;
3767  if (num_ready < 0)
3768  {
3769  const int err = MHD_socket_get_error_ ();
3770  if (MHD_SCKT_ERR_IS_EINTR_(err))
3771  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3772 #ifdef HAVE_MESSAGES
3773  MHD_DLOG (daemon,
3774  _("select failed: %s\n"),
3775  MHD_socket_strerr_ (err));
3776 #endif
3777  return MHD_NO;
3778  }
3779  if (MHD_YES == internal_run_from_select (daemon,
3780  &rs,
3781  &ws,
3782  &es))
3783  return (MHD_NO == err_state) ? MHD_YES : MHD_NO;
3784  return MHD_NO;
3785 }
3786 
3787 
3788 #ifdef HAVE_POLL
3789 
3797 static int
3798 MHD_poll_all (struct MHD_Daemon *daemon,
3799  int may_block)
3800 {
3801  unsigned int num_connections;
3802  struct MHD_Connection *pos;
3803  struct MHD_Connection *prev;
3804 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3805  struct MHD_UpgradeResponseHandle *urh;
3806  struct MHD_UpgradeResponseHandle *urhn;
3807 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3808 
3809  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
3810  (MHD_YES == resume_suspended_connections (daemon)) )
3811  may_block = MHD_NO;
3812 
3813  /* count number of connections and thus determine poll set size */
3814  num_connections = 0;
3815  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
3816  num_connections++;
3817 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3818  for (urh = daemon->urh_head; NULL != urh; urh = urh->next)
3819  num_connections += 2;
3820 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3821  {
3822  MHD_UNSIGNED_LONG_LONG ltimeout;
3823  unsigned int i;
3824  int timeout;
3825  unsigned int poll_server;
3826  int poll_listen;
3827  int poll_itc_idx;
3828  struct pollfd *p;
3829  MHD_socket ls;
3830 
3831  p = MHD_calloc_ ((2 + (size_t)num_connections),
3832  sizeof (struct pollfd));
3833  if (NULL == p)
3834  {
3835 #ifdef HAVE_MESSAGES
3836  MHD_DLOG (daemon,
3837  _("Error allocating memory: %s\n"),
3838  MHD_strerror_(errno));
3839 #endif
3840  return MHD_NO;
3841  }
3842  poll_server = 0;
3843  poll_listen = -1;
3844  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
3845  (! daemon->was_quiesced) &&
3846  (daemon->connections < daemon->connection_limit) &&
3847  (! daemon->at_limit) )
3848  {
3849  /* only listen if we are not at the connection limit */
3850  p[poll_server].fd = ls;
3851  p[poll_server].events = POLLIN;
3852  p[poll_server].revents = 0;
3853  poll_listen = (int) poll_server;
3854  poll_server++;
3855  }
3856  poll_itc_idx = -1;
3857  if (MHD_ITC_IS_VALID_(daemon->itc))
3858  {
3859  p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc);
3860  p[poll_server].events = POLLIN;
3861  p[poll_server].revents = 0;
3862  poll_itc_idx = (int) poll_server;
3863  poll_server++;
3864  }
3865  if (may_block == MHD_NO)
3866  timeout = 0;
3867  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
3868  (MHD_YES != MHD_get_timeout (daemon,
3869  &ltimeout)) )
3870  timeout = -1;
3871  else
3872  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
3873 
3874  i = 0;
3875  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
3876  {
3877  p[poll_server+i].fd = pos->socket_fd;
3878  switch (pos->event_loop_info)
3879  {
3881  p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC;
3882  break;
3884  p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC;
3885  break;
3887  p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC;
3888  break;
3890  timeout = 0; /* clean up "pos" immediately */
3891  break;
3892  }
3893  i++;
3894  }
3895 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3896  for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev)
3897  {
3898  urh_to_pollfd(urh, &(p[poll_server+i]));
3899  i += 2;
3900  }
3901 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3902  if (0 == poll_server + num_connections)
3903  {
3904  free(p);
3905  return MHD_YES;
3906  }
3907  if (MHD_sys_poll_(p,
3908  poll_server + num_connections,
3909  timeout) < 0)
3910  {
3911  const int err = MHD_socket_get_error_ ();
3912  if (MHD_SCKT_ERR_IS_EINTR_ (err))
3913  {
3914  free(p);
3915  return MHD_YES;
3916  }
3917 #ifdef HAVE_MESSAGES
3918  MHD_DLOG (daemon,
3919  _("poll failed: %s\n"),
3920  MHD_socket_strerr_ (err));
3921 #endif
3922  free(p);
3923  return MHD_NO;
3924  }
3925 
3926  /* Reset. New value will be set when connections are processed. */
3927  daemon->data_already_pending = false;
3928 
3929  /* handle ITC FD */
3930  /* do it before any other processing so
3931  new signals will be processed in next loop */
3932  if ( (-1 != poll_itc_idx) &&
3933  (0 != (p[poll_itc_idx].revents & POLLIN)) )
3934  MHD_itc_clear_ (daemon->itc);
3935 
3936  /* handle shutdown */
3937  if (daemon->shutdown)
3938  {
3939  free(p);
3940  return MHD_NO;
3941  }
3942  i = 0;
3943  prev = daemon->connections_tail;
3944  while (NULL != (pos = prev))
3945  {
3946  prev = pos->prev;
3947  /* first, sanity checks */
3948  if (i >= num_connections)
3949  break; /* connection list changed somehow, retry later ... */
3950  if (p[poll_server+i].fd != pos->socket_fd)
3951  continue; /* fd mismatch, something else happened, retry later ... */
3952  call_handlers (pos,
3953  0 != (p[poll_server+i].revents & POLLIN),
3954  0 != (p[poll_server+i].revents & POLLOUT),
3955  0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC));
3956  i++;
3957  }
3958 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
3959  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
3960  {
3961  if (i >= num_connections)
3962  break; /* connection list changed somehow, retry later ... */
3963 
3964  /* Get next connection here as connection can be removed
3965  * from 'daemon->urh_head' list. */
3966  urhn = urh->prev;
3967  /* Check for fd mismatch. FIXME: required for safety? */
3968  if ((p[poll_server+i].fd != urh->connection->socket_fd) ||
3969  (p[poll_server+i+1].fd != urh->mhd.socket))
3970  break;
3971  urh_from_pollfd (urh,
3972  &p[poll_server+i]);
3973  i += 2;
3974  process_urh (urh);
3975  /* Finished forwarding? */
3976  if ( (0 == urh->in_buffer_size) &&
3977  (0 == urh->out_buffer_size) &&
3978  (0 == urh->in_buffer_used) &&
3979  (0 == urh->out_buffer_used) )
3980  {
3981  /* MHD_connection_finish_forward_() will remove connection from
3982  * 'daemon->urh_head' list. */
3983  MHD_connection_finish_forward_ (urh->connection);
3984  urh->clean_ready = true;
3985  /* If 'urh->was_closed' already was set to true, connection will be
3986  * moved immediately to cleanup list. Otherwise connection
3987  * will stay in suspended list until 'urh' will be marked
3988  * with 'was_closed' by application. */
3989  MHD_resume_connection(urh->connection);
3990  }
3991  }
3992 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
3993  /* handle 'listen' FD */
3994  if ( (-1 != poll_listen) &&
3995  (0 != (p[poll_listen].revents & POLLIN)) )
3996  (void) MHD_accept_connection (daemon);
3997 
3998  free(p);
3999  }
4000  return MHD_YES;
4001 }
4002 
4003 
4011 static int
4012 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
4013  int may_block)
4014 {
4015  struct pollfd p[2];
4016  int timeout;
4017  unsigned int poll_count;
4018  int poll_listen;
4019  int poll_itc_idx;
4020  MHD_socket ls;
4021 
4022  memset (&p,
4023  0,
4024  sizeof (p));
4025  poll_count = 0;
4026  poll_listen = -1;
4027  poll_itc_idx = -1;
4028  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4029  (! daemon->was_quiesced) )
4030 
4031  {
4032  p[poll_count].fd = ls;
4033  p[poll_count].events = POLLIN;
4034  p[poll_count].revents = 0;
4035  poll_listen = poll_count;
4036  poll_count++;
4037  }
4038  if (MHD_ITC_IS_VALID_(daemon->itc))
4039  {
4040  p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc);
4041  p[poll_count].events = POLLIN;
4042  p[poll_count].revents = 0;
4043  poll_itc_idx = poll_count;
4044  poll_count++;
4045  }
4046 
4047  if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME))
4048  (void) resume_suspended_connections (daemon);
4049 
4050  if (MHD_NO == may_block)
4051  timeout = 0;
4052  else
4053  timeout = -1;
4054  if (0 == poll_count)
4055  return MHD_YES;
4056  if (MHD_sys_poll_(p,
4057  poll_count,
4058  timeout) < 0)
4059  {
4060  const int err = MHD_socket_get_error_ ();
4061 
4062  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4063  return MHD_YES;
4064 #ifdef HAVE_MESSAGES
4065  MHD_DLOG (daemon,
4066  _("poll failed: %s\n"),
4067  MHD_socket_strerr_ (err));
4068 #endif
4069  return MHD_NO;
4070  }
4071  if ( (-1 != poll_itc_idx) &&
4072  (0 != (p[poll_itc_idx].revents & POLLIN)) )
4073  MHD_itc_clear_ (daemon->itc);
4074 
4075  /* handle shutdown */
4076  if (daemon->shutdown)
4077  return MHD_NO;
4078  if ( (-1 != poll_listen) &&
4079  (0 != (p[poll_listen].revents & POLLIN)) )
4080  (void) MHD_accept_connection (daemon);
4081  return MHD_YES;
4082 }
4083 #endif
4084 
4085 
4093 static int
4094 MHD_poll (struct MHD_Daemon *daemon,
4095  int may_block)
4096 {
4097 #ifdef HAVE_POLL
4098  if (daemon->shutdown)
4099  return MHD_NO;
4100  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4101  return MHD_poll_all (daemon,
4102  may_block);
4103  return MHD_poll_listen_socket (daemon,
4104  may_block);
4105 #else
4106  (void) daemon;
4107  (void) may_block;
4108  return MHD_NO;
4109 #endif
4110 }
4111 
4112 
4113 #ifdef EPOLL_SUPPORT
4114 
4123 #define MAX_EVENTS 128
4124 
4125 
4126 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4127 
4135 static bool
4136 is_urh_ready(struct MHD_UpgradeResponseHandle * const urh)
4137 {
4138  const struct MHD_Connection * const connection = urh->connection;
4139 
4140  if ( (0 == urh->in_buffer_size) &&
4141  (0 == urh->out_buffer_size) &&
4142  (0 == urh->in_buffer_used) &&
4143  (0 == urh->out_buffer_used) )
4144  return false;
4145  if (connection->daemon->shutdown)
4146  return true;
4147  if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) ||
4148  (connection->tls_read_ready) ) &&
4149  (urh->in_buffer_used < urh->in_buffer_size) )
4150  return true;
4151  if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) &&
4152  (urh->out_buffer_used < urh->out_buffer_size) )
4153  return true;
4154  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) &&
4155  (urh->out_buffer_used > 0) )
4156  return true;
4157  if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) &&
4158  (urh->in_buffer_used > 0) )
4159  return true;
4160  return false;
4161 }
4162 
4163 
4172 static int
4173 run_epoll_for_upgrade (struct MHD_Daemon *daemon)
4174 {
4175  struct epoll_event events[MAX_EVENTS];
4176  int num_events;
4177  struct MHD_UpgradeResponseHandle * pos;
4178  struct MHD_UpgradeResponseHandle * prev;
4179 
4180  num_events = MAX_EVENTS;
4181  while (0 != num_events)
4182  {
4183  unsigned int i;
4184  /* update event masks */
4185  num_events = epoll_wait (daemon->epoll_upgrade_fd,
4186  events,
4187  MAX_EVENTS,
4188  0);
4189  if (-1 == num_events)
4190  {
4191  const int err = MHD_socket_get_error_ ();
4192 
4193  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4194  return MHD_YES;
4195 #ifdef HAVE_MESSAGES
4196  MHD_DLOG (daemon,
4197  _("Call to epoll_wait failed: %s\n"),
4198  MHD_socket_strerr_ (err));
4199 #endif
4200  return MHD_NO;
4201  }
4202  for (i = 0; i < (unsigned int) num_events; i++)
4203  {
4204  struct UpgradeEpollHandle * const ueh = events[i].data.ptr;
4205  struct MHD_UpgradeResponseHandle * const urh = ueh->urh;
4206  bool new_err_state = false;
4207 
4208  if (urh->clean_ready)
4209  continue;
4210 
4211  /* Update ueh state based on what is ready according to epoll() */
4212  if (0 != (events[i].events & EPOLLIN))
4213  ueh->celi |= MHD_EPOLL_STATE_READ_READY;
4214  if (0 != (events[i].events & EPOLLOUT))
4215  ueh->celi |= MHD_EPOLL_STATE_WRITE_READY;
4216  if (0 != (events[i].events & EPOLLHUP))
4218 
4219  if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) &&
4220  (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) )
4221  {
4222  /* Process new error state only one time
4223  * and avoid continuously marking this connection
4224  * as 'ready'. */
4225  ueh->celi |= MHD_EPOLL_STATE_ERROR;
4226  new_err_state = true;
4227  }
4228 
4229  if (! urh->in_eready_list)
4230  {
4231  if (new_err_state ||
4232  is_urh_ready(urh))
4233  {
4234  EDLL_insert (daemon->eready_urh_head,
4235  daemon->eready_urh_tail,
4236  urh);
4237  urh->in_eready_list = true;
4238  }
4239  }
4240  }
4241  }
4242  prev = daemon->eready_urh_tail;
4243  while (NULL != (pos = prev))
4244  {
4245  prev = pos->prevE;
4246  process_urh (pos);
4247  if (! is_urh_ready(pos))
4248  {
4249  EDLL_remove (daemon->eready_urh_head,
4250  daemon->eready_urh_tail,
4251  pos);
4252  pos->in_eready_list = false;
4253  }
4254  /* Finished forwarding? */
4255  if ( (0 == pos->in_buffer_size) &&
4256  (0 == pos->out_buffer_size) &&
4257  (0 == pos->in_buffer_used) &&
4258  (0 == pos->out_buffer_used) )
4259  {
4260  MHD_connection_finish_forward_ (pos->connection);
4261  pos->clean_ready = true;
4262  /* If 'pos->was_closed' already was set to true, connection
4263  * will be moved immediately to cleanup list. Otherwise
4264  * connection will stay in suspended list until 'pos' will
4265  * be marked with 'was_closed' by application. */
4266  MHD_resume_connection (pos->connection);
4267  }
4268  }
4269 
4270  return MHD_YES;
4271 }
4272 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4273 
4274 
4278 static const char * const epoll_itc_marker = "itc_marker";
4279 
4280 
4289 static int
4290 MHD_epoll (struct MHD_Daemon *daemon,
4291  int may_block)
4292 {
4293 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4294  static const char * const upgrade_marker = "upgrade_ptr";
4295 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4296  struct MHD_Connection *pos;
4297  struct MHD_Connection *prev;
4298  struct epoll_event events[MAX_EVENTS];
4299  struct epoll_event event;
4300  int timeout_ms;
4301  MHD_UNSIGNED_LONG_LONG timeout_ll;
4302  int num_events;
4303  unsigned int i;
4304  MHD_socket ls;
4305 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4306  bool run_upgraded = false;
4307 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4308 
4309  if (-1 == daemon->epoll_fd)
4310  return MHD_NO; /* we're down! */
4311  if (daemon->shutdown)
4312  return MHD_NO;
4313  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
4314  (! daemon->was_quiesced) &&
4315  (daemon->connections < daemon->connection_limit) &&
4316  (! daemon->listen_socket_in_epoll) &&
4317  (! daemon->at_limit) )
4318  {
4319  event.events = EPOLLIN;
4320  event.data.ptr = daemon;
4321  if (0 != epoll_ctl (daemon->epoll_fd,
4322  EPOLL_CTL_ADD,
4323  ls,
4324  &event))
4325  {
4326 #ifdef HAVE_MESSAGES
4327  MHD_DLOG (daemon,
4328  _("Call to epoll_ctl failed: %s\n"),
4330 #endif
4331  return MHD_NO;
4332  }
4333  daemon->listen_socket_in_epoll = true;
4334  }
4335  if ( (daemon->was_quiesced) &&
4336  (daemon->listen_socket_in_epoll) )
4337  {
4338  if ( (0 != epoll_ctl (daemon->epoll_fd,
4339  EPOLL_CTL_DEL,
4340  ls,
4341  NULL)) &&
4342  (ENOENT != errno) ) /* ENOENT can happen due to race with
4343  #MHD_quiesce_daemon() */
4344  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4345  daemon->listen_socket_in_epoll = false;
4346  }
4347 
4348 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4349  if ( ( (! daemon->upgrade_fd_in_epoll) &&
4350  (-1 != daemon->epoll_upgrade_fd) ) )
4351  {
4352  event.events = EPOLLIN | EPOLLOUT;
4353  event.data.ptr = (void *) upgrade_marker;
4354  if (0 != epoll_ctl (daemon->epoll_fd,
4355  EPOLL_CTL_ADD,
4356  daemon->epoll_upgrade_fd,
4357  &event))
4358  {
4359 #ifdef HAVE_MESSAGES
4360  MHD_DLOG (daemon,
4361  _("Call to epoll_ctl failed: %s\n"),
4363 #endif
4364  return MHD_NO;
4365  }
4366  daemon->upgrade_fd_in_epoll = true;
4367  }
4368 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4369  if ( (daemon->listen_socket_in_epoll) &&
4370  ( (daemon->connections == daemon->connection_limit) ||
4371  (daemon->at_limit) ||
4372  (daemon->was_quiesced) ) )
4373  {
4374  /* we're at the connection limit, disable listen socket
4375  for event loop for now */
4376  if (0 != epoll_ctl (daemon->epoll_fd,
4377  EPOLL_CTL_DEL,
4378  ls,
4379  NULL))
4380  MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4381  daemon->listen_socket_in_epoll = false;
4382  }
4383 
4384  if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
4385  (MHD_YES == resume_suspended_connections (daemon)) )
4386  may_block = MHD_NO;
4387 
4388  if (MHD_YES == may_block)
4389  {
4390  if (MHD_YES == MHD_get_timeout (daemon,
4391  &timeout_ll))
4392  {
4393  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
4394  timeout_ms = INT_MAX;
4395  else
4396  timeout_ms = (int) timeout_ll;
4397  }
4398  else
4399  timeout_ms = -1;
4400  }
4401  else
4402  timeout_ms = 0;
4403 
4404  /* Reset. New value will be set when connections are processed. */
4405  /* Note: Used mostly for uniformity here as same situation is
4406  * signaled in epoll mode by non-empty eready DLL. */
4407  daemon->data_already_pending = false;
4408 
4409  /* drain 'epoll' event queue; need to iterate as we get at most
4410  MAX_EVENTS in one system call here; in practice this should
4411  pretty much mean only one round, but better an extra loop here
4412  than unfair behavior... */
4413  num_events = MAX_EVENTS;
4414  while (MAX_EVENTS == num_events)
4415  {
4416  /* update event masks */
4417  num_events = epoll_wait (daemon->epoll_fd,
4418  events,
4419  MAX_EVENTS,
4420  timeout_ms);
4421  if (-1 == num_events)
4422  {
4423  const int err = MHD_socket_get_error_ ();
4424  if (MHD_SCKT_ERR_IS_EINTR_ (err))
4425  return MHD_YES;
4426 #ifdef HAVE_MESSAGES
4427  MHD_DLOG (daemon,
4428  _("Call to epoll_wait failed: %s\n"),
4429  MHD_socket_strerr_ (err));
4430 #endif
4431  return MHD_NO;
4432  }
4433  for (i=0;i<(unsigned int) num_events;i++)
4434  {
4435  /* First, check for the values of `ptr` that would indicate
4436  that this event is not about a normal connection. */
4437  if (NULL == events[i].data.ptr)
4438  continue; /* shutdown signal! */
4439 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4440  if (upgrade_marker == events[i].data.ptr)
4441  {
4442  /* activity on an upgraded connection, we process
4443  those in a separate epoll() */
4444  run_upgraded = true;
4445  continue;
4446  }
4447 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4448  if (epoll_itc_marker == events[i].data.ptr)
4449  {
4450  /* It's OK to clear ITC here as all external
4451  conditions will be processed later. */
4452  MHD_itc_clear_ (daemon->itc);
4453  continue;
4454  }
4455  if (daemon == events[i].data.ptr)
4456  {
4457  /* Check for error conditions on listen socket. */
4458  /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */
4459  if (0 == (events[i].events & (EPOLLERR | EPOLLHUP)))
4460  {
4461  unsigned int series_length = 0;
4462  /* Run 'accept' until it fails or daemon at limit of connections.
4463  * Do not accept more then 10 connections at once. The rest will
4464  * be accepted on next turn (level trigger is used for listen
4465  * socket). */
4466  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
4467  (series_length < 10) &&
4468  (daemon->connections < daemon->connection_limit) &&
4469  (! daemon->at_limit) )
4470  series_length++;
4471  }
4472  continue;
4473  }
4474  /* this is an event relating to a 'normal' connection,
4475  remember the event and if appropriate mark the
4476  connection as 'eready'. */
4477  pos = events[i].data.ptr;
4478  /* normal processing: update read/write data */
4479  if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP)))
4480  {
4481  pos->epoll_state |= MHD_EPOLL_STATE_ERROR;
4482  if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
4483  {
4484  EDLL_insert (daemon->eready_head,
4485  daemon->eready_tail,
4486  pos);
4487  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4488  }
4489  }
4490  else
4491  {
4492  if (0 != (events[i].events & EPOLLIN))
4493  {
4494  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
4495  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
4496  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
4497  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4498  {
4499  EDLL_insert (daemon->eready_head,
4500  daemon->eready_tail,
4501  pos);
4502  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4503  }
4504  }
4505  if (0 != (events[i].events & EPOLLOUT))
4506  {
4507  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
4508  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
4509  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
4510  {
4511  EDLL_insert (daemon->eready_head,
4512  daemon->eready_tail,
4513  pos);
4514  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
4515  }
4516  }
4517  }
4518  }
4519  }
4520 
4521 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
4522  if (run_upgraded || (NULL != daemon->eready_urh_head))
4523  run_epoll_for_upgrade (daemon);
4524 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
4525 
4526  /* process events for connections */
4527  prev = daemon->eready_tail;
4528  while (NULL != (pos = prev))
4529  {
4530  prev = pos->prevE;
4531  call_handlers (pos,
4532  0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY),
4533  0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY),
4534  0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR));
4537  {
4538  if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info &&
4539  0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) ||
4541  0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) ||
4543  {
4544  EDLL_remove (daemon->eready_head,
4545  daemon->eready_tail,
4546  pos);
4547  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
4548  }
4549  }
4550  }
4551 
4552  /* Finally, handle timed-out connections; we need to do this here
4553  as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything,
4554  as the other event loops do. As timeouts do not get an explicit
4555  event, we need to find those connections that might have timed out
4556  here.
4557 
4558  Connections with custom timeouts must all be looked at, as we
4559  do not bother to sort that (presumably very short) list. */
4560  prev = daemon->manual_timeout_tail;
4561  while (NULL != (pos = prev))
4562  {
4563  prev = pos->prevX;
4565  }
4566  /* Connections with the default timeout are sorted by prepending
4567  them to the head of the list whenever we touch the connection;
4568  thus it suffices to iterate from the tail until the first
4569  connection is NOT timed out */
4570  prev = daemon->normal_timeout_tail;
4571  while (NULL != (pos = prev))
4572  {
4573  prev = pos->prevX;
4575  if (MHD_CONNECTION_CLOSED != pos->state)
4576  break; /* sorted by timeout, no need to visit the rest! */
4577  }
4578  return MHD_YES;
4579 }
4580 #endif
4581 
4582 
4603 int
4604 MHD_run (struct MHD_Daemon *daemon)
4605 {
4606  if ( (daemon->shutdown) ||
4607  (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
4608  return MHD_NO;
4609  if (0 != (daemon->options & MHD_USE_POLL))
4610  {
4611  MHD_poll (daemon, MHD_NO);
4612  MHD_cleanup_connections (daemon);
4613  }
4614 #ifdef EPOLL_SUPPORT
4615  else if (0 != (daemon->options & MHD_USE_EPOLL))
4616  {
4617  MHD_epoll (daemon, MHD_NO);
4618  MHD_cleanup_connections (daemon);
4619  }
4620 #endif
4621  else
4622  {
4623  MHD_select (daemon, MHD_NO);
4624  /* MHD_select does MHD_cleanup_connections already */
4625  }
4626  return MHD_YES;
4627 }
4628 
4629 
4638 static void
4640 {
4641  struct MHD_Daemon *daemon = pos->daemon;
4642 
4643  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4644  {
4646  return; /* must let thread to do the rest */
4647  }
4648  MHD_connection_close_ (pos,
4650 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4652 #endif
4653  mhd_assert (! pos->suspended);
4654  mhd_assert (! pos->resuming);
4655  if (pos->connection_timeout == daemon->connection_timeout)
4657  daemon->normal_timeout_tail,
4658  pos);
4659  else
4661  daemon->manual_timeout_tail,
4662  pos);
4663  DLL_remove (daemon->connections_head,
4664  daemon->connections_tail,
4665  pos);
4666  DLL_insert (daemon->cleanup_head,
4667  daemon->cleanup_tail,
4668  pos);
4669 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4671 #endif
4672 }
4673 
4674 
4675 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4676 
4683 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
4684 MHD_polling_thread (void *cls)
4685 {
4686  struct MHD_Daemon *daemon = cls;
4687 
4688  MHD_thread_init_(&(daemon->pid));
4689  while (! daemon->shutdown)
4690  {
4691  if (0 != (daemon->options & MHD_USE_POLL))
4692  MHD_poll (daemon, MHD_YES);
4693 #ifdef EPOLL_SUPPORT
4694  else if (0 != (daemon->options & MHD_USE_EPOLL))
4695  MHD_epoll (daemon, MHD_YES);
4696 #endif
4697  else
4698  MHD_select (daemon, MHD_YES);
4699  MHD_cleanup_connections (daemon);
4700  }
4701 
4702  /* Resume any pending for resume connections, join
4703  * all connection's threads (if any) and finally cleanup
4704  * everything. */
4705  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
4707  close_all_connections (daemon);
4708 
4709  return (MHD_THRD_RTRN_TYPE_)0;
4710 }
4711 #endif
4712 
4713 
4725 static size_t
4726 unescape_wrapper (void *cls,
4727  struct MHD_Connection *connection,
4728  char *val)
4729 {
4730  (void) cls; /* Mute compiler warning. */
4731 
4732  (void) connection; /* Mute compiler warning. */
4733  return MHD_http_unescape (val);
4734 }
4735 
4736 
4757 struct MHD_Daemon *
4758 MHD_start_daemon (unsigned int flags,
4759  uint16_t port,
4761  void *apc_cls,
4763  void *dh_cls,
4764  ...)
4765 {
4766  struct MHD_Daemon *daemon;
4767  va_list ap;
4768 
4769  va_start (ap,
4770  dh_cls);
4771  daemon = MHD_start_daemon_va (flags,
4772  port,
4773  apc,
4774  apc_cls,
4775  dh,
4776  dh_cls,
4777  ap);
4778  va_end (ap);
4779  return daemon;
4780 }
4781 
4782 
4802 MHD_socket
4804 {
4805 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4806  unsigned int i;
4807 #endif
4808  MHD_socket ret;
4809 
4810  ret = daemon->listen_fd;
4811  if (MHD_INVALID_SOCKET == ret)
4812  return MHD_INVALID_SOCKET;
4813  if ( (0 == (daemon->options & (MHD_USE_ITC))) &&
4814  (0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) )
4815  {
4816 #ifdef HAVE_MESSAGES
4817  MHD_DLOG (daemon,
4818  "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n");
4819 #endif
4820  return MHD_INVALID_SOCKET;
4821  }
4822 
4823 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
4824  if (NULL != daemon->worker_pool)
4825  for (i = 0; i < daemon->worker_pool_size; i++)
4826  {
4827  daemon->worker_pool[i].was_quiesced = true;
4828 #ifdef EPOLL_SUPPORT
4829  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4830  (-1 != daemon->worker_pool[i].epoll_fd) &&
4831  (daemon->worker_pool[i].listen_socket_in_epoll) )
4832  {
4833  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
4834  EPOLL_CTL_DEL,
4835  ret,
4836  NULL))
4837  MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
4838  daemon->worker_pool[i].listen_socket_in_epoll = false;
4839  }
4840  else
4841 #endif
4842  if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
4843  {
4844  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q"))
4845  MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
4846  }
4847  }
4848 #endif
4849  daemon->was_quiesced = true;
4850 #ifdef EPOLL_SUPPORT
4851  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
4852  (-1 != daemon->epoll_fd) &&
4853  (daemon->listen_socket_in_epoll) )
4854  {
4855  if ( (0 != epoll_ctl (daemon->epoll_fd,
4856  EPOLL_CTL_DEL,
4857  ret,
4858  NULL)) &&
4859  (ENOENT != errno) ) /* ENOENT can happen due to race with
4860  #MHD_epoll() */
4861  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
4862  daemon->listen_socket_in_epoll = false;
4863  }
4864 #endif
4865  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
4866  (! MHD_itc_activate_ (daemon->itc, "q")) )
4867  MHD_PANIC (_("failed to signal quiesce via inter-thread communication channel"));
4868  return ret;
4869 }
4870 
4871 
4879 typedef void
4881  const char *format,
4882  va_list va);
4883 
4884 
4893 static int
4894 parse_options_va (struct MHD_Daemon *daemon,
4895  const struct sockaddr **servaddr,
4896  va_list ap);
4897 
4898 
4907 static int
4908 parse_options (struct MHD_Daemon *daemon,
4909  const struct sockaddr **servaddr,
4910  ...)
4911 {
4912  va_list ap;
4913  int ret;
4914 
4915  va_start (ap, servaddr);
4916  ret = parse_options_va (daemon,
4917  servaddr,
4918  ap);
4919  va_end (ap);
4920  return ret;
4921 }
4922 
4923 
4932 static int
4934  const struct sockaddr **servaddr,
4935  va_list ap)
4936 {
4937  enum MHD_OPTION opt;
4938  struct MHD_OptionItem *oa;
4939  unsigned int i;
4940  unsigned int uv;
4941 #ifdef HTTPS_SUPPORT
4942  int ret;
4943  const char *pstr;
4944 #if GNUTLS_VERSION_MAJOR >= 3
4945  gnutls_certificate_retrieve_function2 *pgcrf;
4946 #endif
4947 #if GNUTLS_VERSION_NUMBER >= 0x030603
4948  gnutls_certificate_retrieve_function3 *pgcrf2;
4949 #endif
4950 #endif /* HTTPS_SUPPORT */
4951 
4952  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
4953  {
4954  switch (opt)
4955  {
4957  daemon->pool_size = va_arg (ap,
4958  size_t);
4959  break;
4961  daemon->pool_increment= va_arg (ap,
4962  size_t);
4963  break;
4965  daemon->connection_limit = va_arg (ap,
4966  unsigned int);
4967  break;
4969  uv = va_arg (ap,
4970  unsigned int);
4971  daemon->connection_timeout = (time_t)uv;
4972  /* Next comparison could be always false on some platforms and whole branch will
4973  * be optimized out on those platforms. On others it will be compiled into real
4974  * check. */
4975  if ( ( (MHD_TYPE_IS_SIGNED_(time_t)) &&
4976  (daemon->connection_timeout < 0) ) || /* Compiler may warn on some platforms, ignore warning. */
4977  (uv != (unsigned int)daemon->connection_timeout) )
4978  {
4979 #ifdef HAVE_MESSAGES
4980  MHD_DLOG (daemon,
4981  _("Warning: Too large timeout value, ignored.\n"));
4982 #endif
4983  daemon->connection_timeout = 0;
4984  }
4985  break;
4987  daemon->notify_completed = va_arg (ap,
4989  daemon->notify_completed_cls = va_arg (ap,
4990  void *);
4991  break;
4993  daemon->notify_connection = va_arg (ap,
4995  daemon->notify_connection_cls = va_arg (ap,
4996  void *);
4997  break;
4999  daemon->per_ip_connection_limit = va_arg (ap,
5000  unsigned int);
5001  break;
5002  case MHD_OPTION_SOCK_ADDR:
5003  *servaddr = va_arg (ap,
5004  const struct sockaddr *);
5005  break;
5007  daemon->uri_log_callback = va_arg (ap,
5008  LogCallback);
5009  daemon->uri_log_callback_cls = va_arg (ap,
5010  void *);
5011  break;
5012 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5014  daemon->worker_pool_size = va_arg (ap,
5015  unsigned int);
5016  if (0 == daemon->worker_pool_size)
5017  {
5018 #ifdef HAVE_MESSAGES
5019  MHD_DLOG (daemon,
5020  _("Warning: Zero size, specified for thread pool size, is ignored. "
5021  "Thread pool is not used.\n"));
5022 #endif
5023  }
5024  else if (1 == daemon->worker_pool_size)
5025  {
5026 #ifdef HAVE_MESSAGES
5027  MHD_DLOG (daemon,
5028  _("Warning: \"1\", specified for thread pool size, is ignored. "
5029  "Thread pool is not used.\n"));
5030 #endif
5031  daemon->worker_pool_size = 0;
5032  }
5033  /* Next comparison could be always false on some platforms and whole branch will
5034  * be optimized out on those platforms. On others it will be compiled into real
5035  * check. */
5036  else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */
5037  {
5038 #ifdef HAVE_MESSAGES
5039  MHD_DLOG (daemon,
5040  _("Specified thread pool size (%u) too big\n"),
5041  daemon->worker_pool_size);
5042 #endif
5043  return MHD_NO;
5044  }
5045  else
5046  {
5047  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
5048  {
5049 #ifdef HAVE_MESSAGES
5050  MHD_DLOG (daemon,
5051  _("MHD_OPTION_THREAD_POOL_SIZE option is specified but "
5052  "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n"));
5053 #endif
5054  return MHD_NO;
5055  }
5056  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
5057  {
5058 #ifdef HAVE_MESSAGES
5059  MHD_DLOG (daemon,
5060  _("Both MHD_OPTION_THREAD_POOL_SIZE option and "
5061  "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n"));
5062 #endif
5063  return MHD_NO;
5064  }
5065  }
5066  break;
5067 #endif
5068 #ifdef HTTPS_SUPPORT
5070  pstr = va_arg (ap,
5071  const char *);
5072  if (0 != (daemon->options & MHD_USE_TLS))
5073  daemon->https_mem_key = pstr;
5074 #ifdef HAVE_MESSAGES
5075  else
5076  MHD_DLOG (daemon,
5077  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5078  opt);
5079 #endif
5080  break;
5082  pstr = va_arg (ap,
5083  const char *);
5084  if (0 != (daemon->options & MHD_USE_TLS))
5085  daemon->https_key_password = pstr;
5086 #ifdef HAVE_MESSAGES
5087  else
5088  MHD_DLOG (daemon,
5089  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5090  opt);
5091 #endif
5092  break;
5094  pstr = va_arg (ap,
5095  const char *);
5096  if (0 != (daemon->options & MHD_USE_TLS))
5097  daemon->https_mem_cert = pstr;
5098 #ifdef HAVE_MESSAGES
5099  else
5100  MHD_DLOG (daemon,
5101  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5102  opt);
5103 #endif
5104  break;
5106  pstr = va_arg (ap,
5107  const char *);
5108  if (0 != (daemon->options & MHD_USE_TLS))
5109  daemon->https_mem_trust = pstr;
5110 #ifdef HAVE_MESSAGES
5111  else
5112  MHD_DLOG (daemon,
5113  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5114  opt);
5115 #endif
5116  break;
5118  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap,
5119  int);
5120  break;
5122  pstr = va_arg (ap,
5123  const char *);
5124  if (0 != (daemon->options & MHD_USE_TLS))
5125  {
5126  gnutls_datum_t dhpar;
5127  size_t pstr_len;
5128 
5129  if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
5130  {
5131 #ifdef HAVE_MESSAGES
5132  MHD_DLOG (daemon,
5133  _("Error initializing DH parameters\n"));
5134 #endif
5135  return MHD_NO;
5136  }
5137  dhpar.data = (unsigned char *) pstr;
5138  pstr_len = strlen (pstr);
5139  if (UINT_MAX < pstr_len)
5140  {
5141 #ifdef HAVE_MESSAGES
5142  MHD_DLOG (daemon,
5143  _("Diffie-Hellman parameters string too long\n"));
5144 #endif
5145  return MHD_NO;
5146  }
5147  dhpar.size = (unsigned int) pstr_len;
5148  if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams,
5149  &dhpar,
5150  GNUTLS_X509_FMT_PEM) < 0)
5151  {
5152 #ifdef HAVE_MESSAGES
5153  MHD_DLOG (daemon,
5154  _("Bad Diffie-Hellman parameters format\n"));
5155 #endif
5156  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
5157  return MHD_NO;
5158  }
5159  daemon->have_dhparams = true;
5160  }
5161 #ifdef HAVE_MESSAGES
5162  else
5163  MHD_DLOG (daemon,
5164  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5165  opt);
5166 #endif
5167  break;
5169  pstr = va_arg (ap,
5170  const char *);
5171  if (0 != (daemon->options & MHD_USE_TLS))
5172  {
5173  gnutls_priority_deinit (daemon->priority_cache);
5174  ret = gnutls_priority_init (&daemon->priority_cache,
5175  pstr,
5176  NULL);
5177  if (GNUTLS_E_SUCCESS != ret)
5178  {
5179 #ifdef HAVE_MESSAGES
5180  MHD_DLOG (daemon,
5181  _("Setting priorities to `%s' failed: %s\n"),
5182  pstr,
5183  gnutls_strerror (ret));
5184 #endif
5185  daemon->priority_cache = NULL;
5186  return MHD_NO;
5187  }
5188  }
5189 #ifdef HAVE_MESSAGES
5190  else
5191  MHD_DLOG (daemon,
5192  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5193  opt);
5194 #endif
5195  break;
5197 #if GNUTLS_VERSION_MAJOR < 3
5198 #ifdef HAVE_MESSAGES
5199  MHD_DLOG (daemon,
5200  _("MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n"));
5201 #endif
5202  return MHD_NO;
5203 #else
5204  pgcrf = va_arg (ap,
5205  gnutls_certificate_retrieve_function2 *);
5206  if (0 != (daemon->options & MHD_USE_TLS))
5207  daemon->cert_callback = pgcrf;
5208  else
5209 #ifdef HAVE_MESSAGES
5210  MHD_DLOG (daemon,
5211  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5212  opt);
5213 #endif
5214  break;
5215 #endif
5217 #if GNUTLS_VERSION_NUMBER < 0x030603
5218 #ifdef HAVE_MESSAGES
5219  MHD_DLOG (daemon,
5220  _("MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n"));
5221 #endif
5222  return MHD_NO;
5223 #else
5224  pgcrf2 = va_arg (ap,
5225  gnutls_certificate_retrieve_function3 *);
5226  if (0 != (daemon->options & MHD_USE_TLS))
5227  daemon->cert_callback2 = pgcrf2;
5228  else
5229 #ifdef HAVE_MESSAGES
5230  MHD_DLOG (daemon,
5231  _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"),
5232  opt);
5233 #endif
5234  break;
5235 #endif
5236 #endif /* HTTPS_SUPPORT */
5237 #ifdef DAUTH_SUPPORT
5239  daemon->digest_auth_rand_size = va_arg (ap,
5240  size_t);
5241  daemon->digest_auth_random = va_arg (ap,
5242  const char *);
5243  break;
5245  daemon->nonce_nc_size = va_arg (ap,
5246  unsigned int);
5247  break;
5248 #endif
5250  if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET))
5251  {
5252 #ifdef HAVE_MESSAGES
5253  MHD_DLOG (daemon,
5254  _("MHD_OPTION_LISTEN_SOCKET specified for daemon "
5255  "with MHD_USE_NO_LISTEN_SOCKET flag set.\n"));
5256 #endif
5257  return MHD_NO;
5258  }
5259  else
5260  daemon->listen_fd = va_arg (ap,
5261  MHD_socket);
5262  break;
5264 #ifdef HAVE_MESSAGES
5265  daemon->custom_error_log = va_arg (ap,
5267  daemon->custom_error_log_cls = va_arg (ap,
5268  void *);
5269 #else
5270  va_arg (ap,
5272  va_arg (ap,
5273  void *);
5274 #endif
5275  break;
5276 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5278  daemon->thread_stack_size = va_arg (ap,
5279  size_t);
5280  break;
5281 #endif
5283 #ifdef TCP_FASTOPEN
5284  daemon->fastopen_queue_size = va_arg (ap,
5285  unsigned int);
5286  break;
5287 #else /* ! TCP_FASTOPEN */
5288 #ifdef HAVE_MESSAGES
5289  MHD_DLOG (daemon,
5290  _("TCP fastopen is not supported on this platform\n"));
5291  return MHD_NO;
5292 #endif /* HAVE_MESSAGES */
5293 #endif /* ! TCP_FASTOPEN */
5295  daemon->listening_address_reuse = va_arg (ap,
5296  unsigned int) ? 1 : -1;
5297  break;
5299  daemon->listen_backlog_size = va_arg (ap,
5300  unsigned int);
5301  break;
5303  daemon->strict_for_client = va_arg (ap, int);
5304 #ifdef HAVE_MESSAGES
5305  if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) &&
5306  (1 != daemon->strict_for_client) )
5307  {
5308  MHD_DLOG (daemon,
5309  _("Flag MHD_USE_PEDANTIC_CHECKS is ignored because "
5310  "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n"));
5311  }
5312 #endif /* HAVE_MESSAGES */
5313  break;
5314  case MHD_OPTION_ARRAY:
5315  oa = va_arg (ap, struct MHD_OptionItem*);
5316  i = 0;
5317  while (MHD_OPTION_END != (opt = oa[i].option))
5318  {
5319  switch (opt)
5320  {
5321  /* all options taking 'size_t' */
5325  if (MHD_YES != parse_options (daemon,
5326  servaddr,
5327  opt,
5328  (size_t) oa[i].value,
5329  MHD_OPTION_END))
5330  return MHD_NO;
5331  break;
5332  /* all options taking 'unsigned int' */
5341  if (MHD_YES != parse_options (daemon,
5342  servaddr,
5343  opt,
5344  (unsigned int) oa[i].value,
5345  MHD_OPTION_END))
5346  return MHD_NO;
5347  break;
5348  /* all options taking 'enum' */
5349 #ifdef HTTPS_SUPPORT
5351  if (MHD_YES != parse_options (daemon,
5352  servaddr,
5353  opt,
5354  (gnutls_credentials_type_t) oa[i].value,
5355  MHD_OPTION_END))
5356  return MHD_NO;
5357  break;
5358 #endif /* HTTPS_SUPPORT */
5359  /* all options taking 'MHD_socket' */
5361  if (MHD_YES != parse_options (daemon,
5362  servaddr,
5363  opt,
5364  (MHD_socket) oa[i].value,
5365  MHD_OPTION_END))
5366  return MHD_NO;
5367  break;
5368  /* all options taking 'int' */
5370  if (MHD_YES != parse_options (daemon,
5371  servaddr,
5372  opt,
5373  (int) oa[i].value,
5374  MHD_OPTION_END))
5375  return MHD_NO;
5376  break;
5377  /* all options taking one pointer */
5378  case MHD_OPTION_SOCK_ADDR:
5385  case MHD_OPTION_ARRAY:
5388  if (MHD_YES != parse_options (daemon,
5389  servaddr,
5390  opt,
5391  oa[i].ptr_value,
5392  MHD_OPTION_END))
5393  return MHD_NO;
5394  break;
5395  /* all options taking two pointers */
5402  if (MHD_YES != parse_options (daemon,
5403  servaddr,
5404  opt,
5405  (void *) oa[i].value,
5406  oa[i].ptr_value,
5407  MHD_OPTION_END))
5408  return MHD_NO;
5409  break;
5410  /* options taking size_t-number followed by pointer */
5412  if (MHD_YES != parse_options (daemon,
5413  servaddr,
5414  opt,
5415  (size_t) oa[i].value,
5416  oa[i].ptr_value,
5417  MHD_OPTION_END))
5418  return MHD_NO;
5419  break;
5420  default:
5421  return MHD_NO;
5422  }
5423  i++;
5424  }
5425  break;
5427  daemon->unescape_callback = va_arg (ap,
5429  daemon->unescape_callback_cls = va_arg (ap,
5430  void *);
5431  break;
5432 #ifdef HTTPS_SUPPORT
5434 #if GNUTLS_VERSION_MAJOR >= 3
5435  daemon->cred_callback = va_arg (ap,
5437  daemon->cred_callback_cls = va_arg (ap,
5438  void *);
5439  break;
5440 #else
5441  MHD_DLOG (daemon,
5442  _("MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"),
5443  opt);
5444  return MHD_NO;
5445 #endif
5446 #endif /* HTTPS_SUPPORT */
5447  default:
5448 #ifdef HAVE_MESSAGES
5449  if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
5450  (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) ||
5451  (opt == MHD_OPTION_HTTPS_MEM_TRUST) ||
5453  {
5454  MHD_DLOG (daemon,
5455  _("MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"),
5456  opt);
5457  }
5458  else
5459  {
5460  MHD_DLOG (daemon,
5461  _("Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"),
5462  opt);
5463  }
5464 #endif
5465  return MHD_NO;
5466  }
5467  }
5468  return MHD_YES;
5469 }
5470 
5471 
5472 #ifdef EPOLL_SUPPORT
5473 static int
5474 setup_epoll_fd (struct MHD_Daemon *daemon)
5475 {
5476  int fd;
5477 
5478 #ifndef HAVE_MESSAGES
5479  (void)daemon; /* Mute compiler warning. */
5480 #endif /* ! HAVE_MESSAGES */
5481 
5482 #ifdef USE_EPOLL_CREATE1
5483  fd = epoll_create1 (EPOLL_CLOEXEC);
5484 #else /* ! USE_EPOLL_CREATE1 */
5485  fd = epoll_create (MAX_EVENTS);
5486 #endif /* ! USE_EPOLL_CREATE1 */
5487  if (MHD_INVALID_SOCKET == fd)
5488  {
5489 #ifdef HAVE_MESSAGES
5490  MHD_DLOG (daemon,
5491  _("Call to epoll_create1 failed: %s\n"),
5493 #endif
5494  return MHD_INVALID_SOCKET;
5495  }
5496 #if !defined(USE_EPOLL_CREATE1)
5498  {
5499 #ifdef HAVE_MESSAGES
5500  MHD_DLOG (daemon,
5501  _("Failed to set noninheritable mode on epoll FD.\n"));
5502 #endif
5503  }
5504 #endif /* ! USE_EPOLL_CREATE1 */
5505  return fd;
5506 }
5507 
5508 
5518 static int
5519 setup_epoll_to_listen (struct MHD_Daemon *daemon)
5520 {
5521  struct epoll_event event;
5522  MHD_socket ls;
5523 
5524  daemon->epoll_fd = setup_epoll_fd (daemon);
5525  if (-1 == daemon->epoll_fd)
5526  return MHD_NO;
5527 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5528  if (0 != (MHD_ALLOW_UPGRADE & daemon->options))
5529  {
5530  daemon->epoll_upgrade_fd = setup_epoll_fd (daemon);
5531  if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd)
5532  return MHD_NO;
5533  }
5534 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5535  if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) ||
5536  (daemon->was_quiesced) )
5537  return MHD_YES; /* non-listening daemon */
5538  event.events = EPOLLIN;
5539  event.data.ptr = daemon;
5540  if (0 != epoll_ctl (daemon->epoll_fd,
5541  EPOLL_CTL_ADD,
5542  ls,
5543  &event))
5544  {
5545 #ifdef HAVE_MESSAGES
5546  MHD_DLOG (daemon,
5547  _("Call to epoll_ctl failed: %s\n"),
5549 #endif
5550  return MHD_NO;
5551  }
5552  daemon->listen_socket_in_epoll = true;
5553  if (MHD_ITC_IS_VALID_(daemon->itc))
5554  {
5555  event.events = EPOLLIN;
5556  event.data.ptr = (void *) epoll_itc_marker;
5557  if (0 != epoll_ctl (daemon->epoll_fd,
5558  EPOLL_CTL_ADD,
5559  MHD_itc_r_fd_ (daemon->itc),
5560  &event))
5561  {
5562 #ifdef HAVE_MESSAGES
5563  MHD_DLOG (daemon,
5564  _("Call to epoll_ctl failed: %s\n"),
5566 #endif
5567  return MHD_NO;
5568  }
5569  }
5570  return MHD_YES;
5571 }
5572 #endif
5573 
5574 
5596 struct MHD_Daemon *
5597 MHD_start_daemon_va (unsigned int flags,
5598  uint16_t port,
5600  void *apc_cls,
5602  void *dh_cls,
5603  va_list ap)
5604 {
5605  const MHD_SCKT_OPT_BOOL_ on = 1;
5606  struct MHD_Daemon *daemon;
5608  struct sockaddr_in servaddr4;
5609 #if HAVE_INET6
5610  struct sockaddr_in6 servaddr6;
5611 #endif
5612  const struct sockaddr *servaddr = NULL;
5613  socklen_t addrlen;
5614 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5615  unsigned int i;
5616 #endif
5617  enum MHD_FLAG eflags; /* same type as in MHD_Daemon */
5618  enum MHD_FLAG *pflags;
5619 
5621  eflags = (enum MHD_FLAG) flags;
5622  pflags = &eflags;
5623 #ifndef HAVE_INET6
5624  if (0 != (*pflags & MHD_USE_IPv6))
5625  return NULL;
5626 #endif
5627 #ifndef HAVE_POLL
5628  if (0 != (*pflags & MHD_USE_POLL))
5629  return NULL;
5630 #endif
5631 #ifndef EPOLL_SUPPORT
5632  if (0 != (*pflags & MHD_USE_EPOLL))
5633  return NULL;
5634 #endif /* ! EPOLL_SUPPORT */
5635 #ifndef HTTPS_SUPPORT
5636  if (0 != (*pflags & MHD_USE_TLS))
5637  return NULL;
5638 #endif /* ! HTTPS_SUPPORT */
5639 #ifndef TCP_FASTOPEN
5640  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
5641  return NULL;
5642 #endif
5643  if (0 != (*pflags & MHD_ALLOW_UPGRADE))
5644  {
5645 #ifdef UPGRADE_SUPPORT
5646  *pflags |= MHD_ALLOW_SUSPEND_RESUME;
5647 #else /* ! UPGRADE_SUPPORT */
5648  return NULL;
5649 #endif /* ! UPGRADE_SUPPORT */
5650  }
5651  if (NULL == dh)
5652  return NULL;
5653 
5654  /* Check for invalid combinations of flags. */
5655  if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) ||
5656  ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))) ||
5657  ((0 != (*pflags & MHD_USE_POLL)) &&
5659  ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) )
5660  return NULL;
5661 
5662  if (0 != (*pflags & MHD_USE_AUTO))
5663  {
5664  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
5665  {
5666  /* Thread per connection with internal polling thread. */
5667 #ifdef HAVE_POLL
5668  *pflags |= MHD_USE_POLL;
5669 #else /* ! HAVE_POLL */
5670  /* use select() - do not modify flags */
5671 #endif /* ! HAVE_POLL */
5672  }
5673  else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5674  {
5675  /* Internal polling thread. */
5676 #if defined(EPOLL_SUPPORT)
5677  *pflags |= MHD_USE_EPOLL;
5678 #elif defined(HAVE_POLL)
5679  *pflags |= MHD_USE_POLL;
5680 #else /* !HAVE_POLL && !EPOLL_SUPPORT */
5681  /* use select() - do not modify flags */
5682 #endif /* !HAVE_POLL && !EPOLL_SUPPORT */
5683  }
5684  else
5685  {
5686  /* Internal threads are not used - "external" polling mode. */
5687 #if defined(EPOLL_SUPPORT)
5688  *pflags |= MHD_USE_EPOLL;
5689 #else /* ! EPOLL_SUPPORT */
5690  /* use select() - do not modify flags */
5691 #endif /* ! EPOLL_SUPPORT */
5692  }
5693  }
5694 
5695  if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon))))
5696  return NULL;
5697 #ifdef EPOLL_SUPPORT
5698  daemon->epoll_fd = -1;
5699 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
5700  daemon->epoll_upgrade_fd = -1;
5701 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
5702 #endif
5703  /* try to open listen socket */
5704 #ifdef HTTPS_SUPPORT
5705  daemon->priority_cache = NULL;
5706  if (0 != (*pflags & MHD_USE_TLS))
5707  {
5708  gnutls_priority_init (&daemon->priority_cache,
5709  "@SYSTEM",
5710  NULL);
5711  }
5712 #endif /* HTTPS_SUPPORT */
5713  daemon->listen_fd = MHD_INVALID_SOCKET;
5714  daemon->listening_address_reuse = 0;
5715  daemon->options = *pflags;
5716  pflags = &daemon->options;
5717  daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 : 0;
5718  daemon->port = port;
5719  daemon->apc = apc;
5720  daemon->apc_cls = apc_cls;
5721  daemon->default_handler = dh;
5722  daemon->default_handler_cls = dh_cls;
5723  daemon->connections = 0;
5725  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
5726  daemon->pool_increment = MHD_BUF_INC_SIZE;
5728  daemon->connection_timeout = 0; /* no timeout */
5729  MHD_itc_set_invalid_ (daemon->itc);
5730 #ifdef SOMAXCONN
5731  daemon->listen_backlog_size = SOMAXCONN;
5732 #else /* !SOMAXCONN */
5733  daemon->listen_backlog_size = 511; /* should be safe value */
5734 #endif /* !SOMAXCONN */
5735 #ifdef HAVE_MESSAGES
5736  daemon->custom_error_log = &MHD_default_logger_;
5737  daemon->custom_error_log_cls = stderr;
5738 #endif
5739  if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) &&
5740  (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) )
5741  {
5742 #ifdef HAVE_MESSAGES
5743  MHD_DLOG (daemon,
5744  _("Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with "
5745  "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD "
5746  "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n"));
5747 #endif
5749  }
5750  if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD))
5751  *pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */
5752  else
5753  {
5754 #ifdef HAVE_LISTEN_SHUTDOWN
5755  if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET))
5756 #endif
5757  *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */
5758  }
5759 #ifdef DAUTH_SUPPORT
5760  daemon->digest_auth_rand_size = 0;
5761  daemon->digest_auth_random = NULL;
5762  daemon->nonce_nc_size = 4; /* tiny */
5763 #endif
5764 #ifdef HTTPS_SUPPORT
5765  if (0 != (*pflags & MHD_USE_TLS))
5766  {
5767  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
5768  }
5769 #endif /* HTTPS_SUPPORT */
5770 
5771 
5772  if (MHD_YES != parse_options_va (daemon,
5773  &servaddr,
5774  ap))
5775  {
5776 #ifdef HTTPS_SUPPORT
5777  if ( (0 != (*pflags & MHD_USE_TLS)) &&
5778  (NULL != daemon->priority_cache) )
5779  gnutls_priority_deinit (daemon->priority_cache);
5780 #endif /* HTTPS_SUPPORT */
5781  free (daemon);
5782  return NULL;
5783  }
5784 
5785  if ( (NULL != daemon->notify_completed) &&
5786  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
5787  *pflags |= MHD_USE_ITC; /* requires ITC */
5788 
5789 #ifndef NDEBUG
5790 #ifdef HAVE_MESSAGES
5791  MHD_DLOG (daemon,
5792  _("Using debug build of libmicrohttpd.\n") );
5793 #endif /* HAVE_MESSAGES */
5794 #endif /* ! NDEBUG */
5795 
5796  if ( (0 != (*pflags & MHD_USE_ITC))
5797 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5798  && (0 == daemon->worker_pool_size)
5799 #endif
5800  )
5801  {
5802  if (! MHD_itc_init_ (daemon->itc))
5803  {
5804 #ifdef HAVE_MESSAGES
5805  MHD_DLOG (daemon,
5806  _("Failed to create inter-thread communication channel: %s\n"),
5807  MHD_itc_last_strerror_ ());
5808 #endif
5809 #ifdef HTTPS_SUPPORT
5810  if (NULL != daemon->priority_cache)
5811  gnutls_priority_deinit (daemon->priority_cache);
5812 #endif /* HTTPS_SUPPORT */
5813  free (daemon);
5814  return NULL;
5815  }
5816  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
5817  (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc),
5818  NULL)) )
5819  {
5820 #ifdef HAVE_MESSAGES
5821  MHD_DLOG (daemon,
5822  _("file descriptor for inter-thread communication channel exceeds maximum value\n"));
5823 #endif
5824  MHD_itc_destroy_chk_ (daemon->itc);
5825 #ifdef HTTPS_SUPPORT
5826  if (NULL != daemon->priority_cache)
5827  gnutls_priority_deinit (daemon->priority_cache);
5828 #endif /* HTTPS_SUPPORT */
5829  free (daemon);
5830  return NULL;
5831  }
5832  }
5833 
5834 #ifdef DAUTH_SUPPORT
5835  if (daemon->nonce_nc_size > 0)
5836  {
5837  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
5838  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
5839  {
5840 #ifdef HAVE_MESSAGES
5841  MHD_DLOG (daemon,
5842  _("Specified value for NC_SIZE too large\n"));
5843 #endif
5844 #ifdef HTTPS_SUPPORT
5845  if (0 != (*pflags & MHD_USE_TLS))
5846  gnutls_priority_deinit (daemon->priority_cache);
5847 #endif /* HTTPS_SUPPORT */
5848  free (daemon);
5849  return NULL;
5850  }
5851  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
5852  if (NULL == daemon->nnc)
5853  {
5854 #ifdef HAVE_MESSAGES
5855  MHD_DLOG (daemon,
5856  _("Failed to allocate memory for nonce-nc map: %s\n"),
5857  MHD_strerror_ (errno));
5858 #endif
5859 #ifdef HTTPS_SUPPORT
5860  if (0 != (*pflags & MHD_USE_TLS))
5861  gnutls_priority_deinit (daemon->priority_cache);
5862 #endif /* HTTPS_SUPPORT */
5863  free (daemon);
5864  return NULL;
5865  }
5866  }
5867 
5868 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5869  if (! MHD_mutex_init_ (&daemon->nnc_lock))
5870  {
5871 #ifdef HAVE_MESSAGES
5872  MHD_DLOG (daemon,
5873  _("MHD failed to initialize nonce-nc mutex\n"));
5874 #endif
5875 #ifdef HTTPS_SUPPORT
5876  if (0 != (*pflags & MHD_USE_TLS))
5877  gnutls_priority_deinit (daemon->priority_cache);
5878 #endif /* HTTPS_SUPPORT */
5879  free (daemon->nnc);
5880  free (daemon);
5881  return NULL;
5882  }
5883 #endif
5884 #endif
5885 
5886  /* Thread pooling currently works only with internal select thread mode */
5887 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
5888  if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
5889  (daemon->worker_pool_size > 0) )
5890  {
5891 #ifdef HAVE_MESSAGES
5892  MHD_DLOG (daemon,
5893  _("MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n"));
5894 #endif
5895  goto free_and_fail;
5896  }
5897 #endif
5898  if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
5899  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
5900  {
5901  /* try to open listen socket */
5902  int domain;
5903 
5904 #ifdef HAVE_INET6
5905  domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET;
5906 #else /* ! HAVE_INET6 */
5907  if (*pflags & MHD_USE_IPv6)
5908  goto free_and_fail;
5909  domain = PF_INET;
5910 #endif /* ! HAVE_INET6 */
5911 
5912  listen_fd = MHD_socket_create_listen_(domain);
5913  if (MHD_INVALID_SOCKET == listen_fd)
5914  {
5915 #ifdef HAVE_MESSAGES
5916  MHD_DLOG (daemon,
5917  _("Failed to create socket for listening: %s\n"),
5919 #endif
5920  goto free_and_fail;
5921  }
5922 
5923  /* Apply the socket options according to listening_address_reuse. */
5924  if (0 == daemon->listening_address_reuse)
5925  {
5926 #ifndef MHD_WINSOCK_SOCKETS
5927  /* No user requirement, use "traditional" default SO_REUSEADDR
5928  * on non-W32 platforms, and do not fail if it doesn't work.
5929  * Don't use it on W32, because on W32 it will allow multiple
5930  * bind to the same address:port, like SO_REUSEPORT on others. */
5931  if (0 > setsockopt (listen_fd,
5932  SOL_SOCKET,
5933  SO_REUSEADDR,
5934  (void*)&on, sizeof (on)))
5935  {
5936 #ifdef HAVE_MESSAGES
5937  MHD_DLOG (daemon,
5938  _("setsockopt failed: %s\n"),
5940 #endif
5941  }
5942 #endif /* ! MHD_WINSOCK_SOCKETS */
5943  }
5944  else if (daemon->listening_address_reuse > 0)
5945  {
5946  /* User requested to allow reusing listening address:port. */
5947 #ifndef MHD_WINSOCK_SOCKETS
5948  /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
5949  * it doesn't work. */
5950  if (0 > setsockopt (listen_fd,
5951  SOL_SOCKET,
5952  SO_REUSEADDR,
5953  (void*)&on, sizeof (on)))
5954  {
5955 #ifdef HAVE_MESSAGES
5956  MHD_DLOG (daemon,
5957  _("setsockopt failed: %s\n"),
5959 #endif
5960  }
5961 #endif /* ! MHD_WINSOCK_SOCKETS */
5962  /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
5963  * Fail if SO_REUSEPORT is not defined or setsockopt fails.
5964  */
5965  /* SO_REUSEADDR on W32 has the same semantics
5966  as SO_REUSEPORT on BSD/Linux */
5967 #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT)
5968  if (0 > setsockopt (listen_fd,
5969  SOL_SOCKET,
5970 #ifndef MHD_WINSOCK_SOCKETS
5971  SO_REUSEPORT,
5972 #else /* MHD_WINSOCK_SOCKETS */
5973  SO_REUSEADDR,
5974 #endif /* MHD_WINSOCK_SOCKETS */
5975  (void *) &on,
5976  sizeof (on)))
5977  {
5978 #ifdef HAVE_MESSAGES
5979  MHD_DLOG (daemon,
5980  _("setsockopt failed: %s\n"),
5982 #endif
5983  goto free_and_fail;
5984  }
5985 #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
5986  /* we're supposed to allow address:port re-use, but
5987  on this platform we cannot; fail hard */
5988 #ifdef HAVE_MESSAGES
5989  MHD_DLOG (daemon,
5990  _("Cannot allow listening address reuse: SO_REUSEPORT not defined\n"));
5991 #endif
5992  goto free_and_fail;
5993 #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */
5994  }
5995  else /* if (daemon->listening_address_reuse < 0) */
5996  {
5997  /* User requested to disallow reusing listening address:port.
5998  * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
5999  * is used and Solaris with SO_EXCLBIND.
6000  * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE
6001  * or setsockopt fails.
6002  */
6003 #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \
6004  (defined(__sun) && defined(SO_EXCLBIND))
6005  if (0 > setsockopt (listen_fd,
6006  SOL_SOCKET,
6007 #ifdef SO_EXCLUSIVEADDRUSE
6008  SO_EXCLUSIVEADDRUSE,
6009 #else /* SO_EXCLBIND */
6010  SO_EXCLBIND,
6011 #endif /* SO_EXCLBIND */
6012  (void *) &on,
6013  sizeof (on)))
6014  {
6015 #ifdef HAVE_MESSAGES
6016  MHD_DLOG (daemon,
6017  _("setsockopt failed: %s\n"),
6019 #endif
6020  goto free_and_fail;
6021  }
6022 #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */
6023 #ifdef HAVE_MESSAGES
6024  MHD_DLOG (daemon,
6025  _("Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n"));
6026 #endif
6027  goto free_and_fail;
6028 #endif /* MHD_WINSOCK_SOCKETS */
6029  }
6030 
6031  /* check for user supplied sockaddr */
6032 #if HAVE_INET6
6033  if (0 != (*pflags & MHD_USE_IPv6))
6034  addrlen = sizeof (struct sockaddr_in6);
6035  else
6036 #endif
6037  addrlen = sizeof (struct sockaddr_in);
6038  if (NULL == servaddr)
6039  {
6040 #if HAVE_INET6
6041  if (0 != (*pflags & MHD_USE_IPv6))
6042  {
6043 #ifdef IN6ADDR_ANY_INIT
6044  static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT;
6045 #endif
6046  memset (&servaddr6,
6047  0,
6048  sizeof (struct sockaddr_in6));
6049  servaddr6.sin6_family = AF_INET6;
6050  servaddr6.sin6_port = htons (port);
6051 #ifdef IN6ADDR_ANY_INIT
6052  servaddr6.sin6_addr = static_in6any;
6053 #endif
6054 #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
6055  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
6056 #endif
6057  servaddr = (struct sockaddr *) &servaddr6;
6058  }
6059  else
6060 #endif
6061  {
6062  memset (&servaddr4,
6063  0,
6064  sizeof (struct sockaddr_in));
6065  servaddr4.sin_family = AF_INET;
6066  servaddr4.sin_port = htons (port);
6067  if (0 != INADDR_ANY)
6068  servaddr4.sin_addr.s_addr = htonl (INADDR_ANY);
6069 #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
6070  servaddr4.sin_len = sizeof (struct sockaddr_in);
6071 #endif
6072  servaddr = (struct sockaddr *) &servaddr4;
6073  }
6074  }
6075  daemon->listen_fd = listen_fd;
6076 
6077  if (0 != (*pflags & MHD_USE_IPv6))
6078  {
6079 #ifdef IPPROTO_IPV6
6080 #ifdef IPV6_V6ONLY
6081  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
6082  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
6083  and may also be missing on older POSIX systems; good luck if you have any of those,
6084  your IPv6 socket may then also bind against IPv4 anyway... */
6085  const MHD_SCKT_OPT_BOOL_ v6_only =
6086  (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK));
6087  if (0 > setsockopt (listen_fd,
6088  IPPROTO_IPV6, IPV6_V6ONLY,
6089  (const void *) &v6_only,
6090  sizeof (v6_only)))
6091  {
6092 #ifdef HAVE_MESSAGES
6093  MHD_DLOG (daemon,
6094  _("setsockopt failed: %s\n"),
6096 #endif
6097  }
6098 #endif
6099 #endif
6100  }
6101  if (-1 == bind (listen_fd, servaddr, addrlen))
6102  {
6103 #ifdef HAVE_MESSAGES
6104  MHD_DLOG (daemon,
6105  _("Failed to bind to port %u: %s\n"),
6106  (unsigned int) port,
6108 #endif
6109  MHD_socket_close_chk_ (listen_fd);
6110  goto free_and_fail;
6111  }
6112 #ifdef TCP_FASTOPEN
6113  if (0 != (*pflags & MHD_USE_TCP_FASTOPEN))
6114  {
6115  if (0 == daemon->fastopen_queue_size)
6116  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
6117  if (0 != setsockopt (listen_fd,
6118  IPPROTO_TCP,
6119  TCP_FASTOPEN,
6120  (const void*)&daemon->fastopen_queue_size,
6121  sizeof (daemon->fastopen_queue_size)))
6122  {
6123 #ifdef HAVE_MESSAGES
6124  MHD_DLOG (daemon,
6125  _("setsockopt failed: %s\n"),
6127 #endif
6128  }
6129  }
6130 #endif
6131  if (listen (listen_fd,
6132  daemon->listen_backlog_size) < 0)
6133  {
6134 #ifdef HAVE_MESSAGES
6135  MHD_DLOG (daemon,
6136  _("Failed to listen for connections: %s\n"),
6138 #endif
6139  MHD_socket_close_chk_ (listen_fd);
6140  goto free_and_fail;
6141  }
6142  }
6143  else
6144  {
6145  listen_fd = daemon->listen_fd;
6146  }
6147 
6148 #ifdef HAVE_GETSOCKNAME
6149  if ( (0 == daemon->port) &&
6150  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6151  { /* Get port number. */
6152  struct sockaddr_storage bindaddr;
6153 
6154  memset (&bindaddr,
6155  0,
6156  sizeof (struct sockaddr_storage));
6157  addrlen = sizeof (struct sockaddr_storage);
6158 #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
6159  bindaddr.ss_len = addrlen;
6160 #endif
6161  if (0 != getsockname (listen_fd,
6162  (struct sockaddr *) &bindaddr,
6163  &addrlen))
6164  {
6165 #ifdef HAVE_MESSAGES
6166  MHD_DLOG (daemon,
6167  _("Failed to get listen port number: %s\n"),
6169 #endif /* HAVE_MESSAGES */
6170  }
6171 #ifdef MHD_POSIX_SOCKETS
6172  else if (sizeof (bindaddr) < addrlen)
6173  {
6174  /* should be impossible with `struct sockaddr_storage` */
6175 #ifdef HAVE_MESSAGES
6176  MHD_DLOG (daemon,
6177  _("Failed to get listen port number (`struct sockaddr_storage` too small!?)\n"));
6178 #endif /* HAVE_MESSAGES */
6179  }
6180 #ifndef __linux__
6181  else if (0 == addrlen)
6182  {
6183  /* Many non-Linux-based platforms return zero addrlen
6184  * for AF_UNIX sockets */
6185  daemon->port = 0; /* special value for UNIX domain sockets */
6186  }
6187 #endif /* __linux__ */
6188 #endif /* MHD_POSIX_SOCKETS */
6189  else
6190  {
6191  switch (bindaddr.ss_family)
6192  {
6193  case AF_INET:
6194  {
6195  struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr;
6196 
6197  daemon->port = ntohs (s4->sin_port);
6198  break;
6199  }
6200 #ifdef HAVE_INET6
6201  case AF_INET6:
6202  {
6203  struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr;
6204 
6205  daemon->port = ntohs(s6->sin6_port);
6206  mhd_assert (0 != (*pflags & MHD_USE_IPv6));
6207  break;
6208  }
6209 #endif /* HAVE_INET6 */
6210 #ifdef AF_UNIX
6211  case AF_UNIX:
6212  daemon->port = 0; /* special value for UNIX domain sockets */
6213  break;
6214 #endif
6215  default:
6216 #ifdef HAVE_MESSAGES
6217  MHD_DLOG (daemon,
6218  _("Unknown address family!\n"));
6219 #endif
6220  daemon->port = 0; /* ugh */
6221  break;
6222  }
6223  }
6224  }
6225 #endif /* HAVE_GETSOCKNAME */
6226 
6227  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6228  (! MHD_socket_nonblocking_ (listen_fd)) )
6229  {
6230 #ifdef HAVE_MESSAGES
6231  MHD_DLOG (daemon,
6232  _("Failed to set nonblocking mode on listening socket: %s\n"),
6234 #endif
6235  if (0 != (*pflags & MHD_USE_EPOLL)
6236 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6237  || (daemon->worker_pool_size > 0)
6238 #endif
6239  )
6240  {
6241  /* Accept must be non-blocking. Multiple children may wake up
6242  * to handle a new connection, but only one will win the race.
6243  * The others must immediately return. */
6244  MHD_socket_close_chk_ (listen_fd);
6245  goto free_and_fail;
6246  }
6247  }
6248  if ( (MHD_INVALID_SOCKET != listen_fd) &&
6249  (! MHD_SCKT_FD_FITS_FDSET_(listen_fd,
6250  NULL)) &&
6251  (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
6252  {
6253 #ifdef HAVE_MESSAGES
6254  MHD_DLOG (daemon,
6255  _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
6256  listen_fd,
6257  FD_SETSIZE);
6258 #endif
6259  MHD_socket_close_chk_ (listen_fd);
6260  goto free_and_fail;
6261  }
6262 
6263 #ifdef EPOLL_SUPPORT
6264  if ( (0 != (*pflags & MHD_USE_EPOLL))
6265 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6266  && (0 == daemon->worker_pool_size)
6267 #endif
6268  )
6269  {
6270  if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))
6271  {
6272 #ifdef HAVE_MESSAGES
6273  MHD_DLOG (daemon,
6274  _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n"));
6275 #endif
6276  goto free_and_fail;
6277  }
6278  if (MHD_YES != setup_epoll_to_listen (daemon))
6279  goto free_and_fail;
6280  }
6281 #endif /* EPOLL_SUPPORT */
6282 
6283 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6284  if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex))
6285  {
6286 #ifdef HAVE_MESSAGES
6287  MHD_DLOG (daemon,
6288  _("MHD failed to initialize IP connection limit mutex\n"));
6289 #endif
6290  if (MHD_INVALID_SOCKET != listen_fd)
6291  MHD_socket_close_chk_ (listen_fd);
6292  goto free_and_fail;
6293  }
6294  if (0 == daemon->worker_pool_size)
6295  { /* Initialise connection mutex only if this daemon will handle
6296  * any connections by itself. */
6297  if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
6298  {
6299 #ifdef HAVE_MESSAGES
6300  MHD_DLOG (daemon,
6301  _("MHD failed to initialize IP connection limit mutex\n"));
6302 #endif
6303 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6305 #endif
6306  if (MHD_INVALID_SOCKET != listen_fd)
6307  MHD_socket_close_chk_ (listen_fd);
6308  goto free_and_fail;
6309  }
6310  }
6311 #endif
6312 
6313 #ifdef HTTPS_SUPPORT
6314  /* initialize HTTPS daemon certificate aspects & send / recv functions */
6315  if ( (0 != (*pflags & MHD_USE_TLS)) &&
6316  (0 != MHD_TLS_init (daemon)) )
6317  {
6318 #ifdef HAVE_MESSAGES
6319  MHD_DLOG (daemon,
6320  _("Failed to initialize TLS support\n"));
6321 #endif
6322  if (MHD_INVALID_SOCKET != listen_fd)
6323  MHD_socket_close_chk_ (listen_fd);
6324 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6325  if (0 == daemon->worker_pool_size)
6328 #endif
6329  goto free_and_fail;
6330  }
6331 #endif /* HTTPS_SUPPORT */
6332 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6333  if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) &&
6334  (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) )
6335  {
6336  if (0 == daemon->worker_pool_size)
6337  {
6338  if (! MHD_create_named_thread_ (&daemon->pid,
6339  (*pflags & MHD_USE_THREAD_PER_CONNECTION) ?
6340  "MHD-listen" : "MHD-single",
6341  daemon->thread_stack_size,
6343  daemon) )
6344  {
6345 #ifdef HAVE_MESSAGES
6346  MHD_DLOG (daemon,
6347  _("Failed to create listen thread: %s\n"),
6348  MHD_strerror_ (errno));
6349 #endif
6352  if (MHD_INVALID_SOCKET != listen_fd)
6353  MHD_socket_close_chk_ (listen_fd);
6354  goto free_and_fail;
6355  }
6356  }
6357  else /* 0 < daemon->worker_pool_size */
6358  {
6359  /* Coarse-grained count of connections per thread (note error
6360  * due to integer division). Also keep track of how many
6361  * connections are leftover after an equal split. */
6362  unsigned int conns_per_thread = daemon->connection_limit
6363  / daemon->worker_pool_size;
6364  unsigned int leftover_conns = daemon->connection_limit
6365  % daemon->worker_pool_size;
6366 
6367  i = 0; /* we need this in case fcntl or malloc fails */
6368 
6369  /* Allocate memory for pooled objects */
6370  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
6371  * daemon->worker_pool_size);
6372  if (NULL == daemon->worker_pool)
6373  goto thread_failed;
6374 
6375  /* Start the workers in the pool */
6376  for (i = 0; i < daemon->worker_pool_size; ++i)
6377  {
6378  /* Create copy of the Daemon object for each worker */
6379  struct MHD_Daemon *d = &daemon->worker_pool[i];
6380 
6381  memcpy (d, daemon, sizeof (struct MHD_Daemon));
6382  /* Adjust pooling params for worker daemons; note that memcpy()
6383  has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into
6384  the worker threads. */
6385  d->master = daemon;
6386  d->worker_pool_size = 0;
6387  d->worker_pool = NULL;
6388 
6389  if (0 != (*pflags & MHD_USE_ITC))
6390  {
6391  if (! MHD_itc_init_ (d->itc))
6392  {
6393 #ifdef HAVE_MESSAGES
6394  MHD_DLOG (daemon,
6395  _("Failed to create worker inter-thread communication channel: %s\n"),
6396  MHD_itc_last_strerror_() );
6397 #endif
6398  goto thread_failed;
6399  }
6400  if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) &&
6401  (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (d->itc),
6402  NULL)) )
6403  {
6404 #ifdef HAVE_MESSAGES
6405  MHD_DLOG (daemon,
6406  _("File descriptor for worker inter-thread communication channel exceeds maximum value\n"));
6407 #endif
6409  goto thread_failed;
6410  }
6411  }
6412  else
6413  MHD_itc_set_invalid_ (d->itc);
6414 
6415  /* Divide available connections evenly amongst the threads.
6416  * Thread indexes in [0, leftover_conns) each get one of the
6417  * leftover connections. */
6418  d->connection_limit = conns_per_thread;
6419  if (i < leftover_conns)
6420  ++d->connection_limit;
6421 #ifdef EPOLL_SUPPORT
6422  if ( (0 != (*pflags & MHD_USE_EPOLL)) &&
6423  (MHD_YES != setup_epoll_to_listen (d)) )
6424  goto thread_failed;
6425 #endif
6426  /* Must init cleanup connection mutex for each worker */
6427  if (! MHD_mutex_init_ (&d->cleanup_connection_mutex))
6428  {
6429 #ifdef HAVE_MESSAGES
6430  MHD_DLOG (daemon,
6431  _("MHD failed to initialize cleanup connection mutex\n"));
6432 #endif
6433  goto thread_failed;
6434  }
6435 
6436  /* Spawn the worker thread */
6437  if (! MHD_create_named_thread_ (&d->pid,
6438  "MHD-worker",
6439  daemon->thread_stack_size,
6441  d))
6442  {
6443 #ifdef HAVE_MESSAGES
6444  MHD_DLOG (daemon,
6445  _("Failed to create pool thread: %s\n"),
6446  MHD_strerror_ (errno));
6447 #endif
6448  /* Free memory for this worker; cleanup below handles
6449  * all previously-created workers. */
6451  goto thread_failed;
6452  }
6453  }
6454  }
6455  }
6456 #endif
6457 #ifdef HTTPS_SUPPORT
6458  /* API promises to never use the password after initialization,
6459  so we additionally NULL it here to not deref a dangling pointer. */
6460  daemon->https_key_password = NULL;
6461 #endif /* HTTPS_SUPPORT */
6462 
6463  return daemon;
6464 
6465 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6466 thread_failed:
6467  /* If no worker threads created, then shut down normally. Calling
6468  MHD_stop_daemon (as we do below) doesn't work here since it
6469  assumes a 0-sized thread pool means we had been in the default
6470  MHD_USE_INTERNAL_POLLING_THREAD mode. */
6471  if (0 == i)
6472  {
6476  if (NULL != daemon->worker_pool)
6477  free (daemon->worker_pool);
6478  goto free_and_fail;
6479  }
6480 
6481  /* Shutdown worker threads we've already created. Pretend
6482  as though we had fully initialized our daemon, but
6483  with a smaller number of threads than had been
6484  requested. */
6485  daemon->worker_pool_size = i;
6486  MHD_stop_daemon (daemon);
6487  return NULL;
6488 #endif
6489 
6490  free_and_fail:
6491  /* clean up basic memory state in 'daemon' and return NULL to
6492  indicate failure */
6493 #ifdef EPOLL_SUPPORT
6494 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6495  if (daemon->upgrade_fd_in_epoll)
6496  {
6497  if (0 != epoll_ctl (daemon->epoll_fd,
6498  EPOLL_CTL_DEL,
6499  daemon->epoll_upgrade_fd,
6500  NULL))
6501  MHD_PANIC (_("Failed to remove FD from epoll set\n"));
6502  daemon->upgrade_fd_in_epoll = false;
6503  }
6504 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6505  if (-1 != daemon->epoll_fd)
6506  close (daemon->epoll_fd);
6507 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6508  if (-1 != daemon->epoll_upgrade_fd)
6509  close (daemon->epoll_upgrade_fd);
6510 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6511 #endif /* EPOLL_SUPPORT */
6512 #ifdef DAUTH_SUPPORT
6513  free (daemon->nnc);
6514 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6515  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6516 #endif
6517 #endif
6518 #ifdef HTTPS_SUPPORT
6519  if (0 != (*pflags & MHD_USE_TLS))
6520  {
6521  gnutls_priority_deinit (daemon->priority_cache);
6522  if (daemon->x509_cred)
6523  gnutls_certificate_free_credentials (daemon->x509_cred);
6524  if (daemon->psk_cred)
6525  gnutls_psk_free_server_credentials (daemon->psk_cred);
6526  }
6527 #endif /* HTTPS_SUPPORT */
6528  if (MHD_ITC_IS_VALID_(daemon->itc))
6529  MHD_itc_destroy_chk_ (daemon->itc);
6530  free (daemon);
6531  return NULL;
6532 }
6533 
6534 
6543 static void
6545 {
6546  struct MHD_Connection *pos;
6547  const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION));
6548 #ifdef UPGRADE_SUPPORT
6549  const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE));
6550 #endif /* UPGRADE_SUPPORT */
6551 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6552  struct MHD_UpgradeResponseHandle *urh;
6553  struct MHD_UpgradeResponseHandle *urhn;
6554  const bool used_tls = (0 != (daemon->options & MHD_USE_TLS));
6555 
6556 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6557  mhd_assert (NULL == daemon->worker_pool);
6558 #endif
6559  mhd_assert (daemon->shutdown);
6560  /* give upgraded HTTPS connections a chance to finish */
6561  /* 'daemon->urh_head' is not used in thread-per-connection mode. */
6562  for (urh = daemon->urh_tail; NULL != urh; urh = urhn)
6563  {
6564  urhn = urh->prev;
6565  /* call generic forwarding function for passing data
6566  with chance to detect that application is done. */
6567  process_urh (urh);
6568  MHD_connection_finish_forward_ (urh->connection);
6569  urh->clean_ready = true;
6570  /* Resuming will move connection to cleanup list. */
6571  MHD_resume_connection(urh->connection);
6572  }
6573 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6574 
6575  /* Give suspended connections a chance to resume to avoid
6576  running into the check for there not being any suspended
6577  connections left in case of a tight race with a recently
6578  resumed connection. */
6579  if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options))
6580  {
6581  daemon->resuming = true; /* Force check for pending resume. */
6583  }
6584  /* first, make sure all threads are aware of shutdown; need to
6585  traverse DLLs in peace... */
6586 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6588 #endif
6589 #ifdef UPGRADE_SUPPORT
6590  if (upg_allowed)
6591  {
6592  struct MHD_Connection * susp;
6593 
6595  while (NULL != susp)
6596  {
6597  if (NULL == susp->urh) /* "Upgraded" connection? */
6598  MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
6599 #ifdef HTTPS_SUPPORT
6600  else if (used_tls &&
6601  used_thr_p_c &&
6602  (! susp->urh->clean_ready) )
6603  shutdown (susp->urh->app.socket,
6604  SHUT_RDWR); /* Wake thread by shutdown of app socket. */
6605 #endif /* HTTPS_SUPPORT */
6606  else
6607  {
6608 #ifdef HAVE_MESSAGES
6609  if (! susp->urh->was_closed)
6610  MHD_DLOG (daemon,
6611  _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n"));
6612 #endif
6613  susp->urh->was_closed = true;
6614  /* If thread-per-connection is used, connection's thread
6615  * may still processing "upgrade" (exiting). */
6616  if (! used_thr_p_c)
6618  /* Do not use MHD_resume_connection() as mutex is
6619  * already locked. */
6620  susp->resuming = true;
6621  daemon->resuming = true;
6622  }
6623  susp = susp->prev;
6624  }
6625  }
6626  else /* This 'else' is combined with next 'if' */
6627 #endif /* UPGRADE_SUPPORT */
6629  MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n"));
6630  for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
6631  {
6632  shutdown (pos->socket_fd,
6633  SHUT_RDWR);
6634 #if MHD_WINSOCK_SOCKETS
6635  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6636  (MHD_ITC_IS_VALID_(daemon->itc)) &&
6637  (! MHD_itc_activate_ (daemon->itc, "e")) )
6638  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
6639 #endif
6640  }
6641 
6642 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6643  /* now, collect per-connection threads */
6644  if (used_thr_p_c)
6645  {
6646  pos = daemon->connections_tail;
6647  while (NULL != pos)
6648  {
6649  if (! pos->thread_joined)
6650  {
6652  if (! MHD_join_thread_ (pos->pid.handle))
6653  MHD_PANIC (_("Failed to join a thread\n"));
6655  pos->thread_joined = true;
6656  /* The thread may have concurrently modified the DLL,
6657  need to restart from the beginning */
6658  pos = daemon->connections_tail;
6659  continue;
6660  }
6661  pos = pos->prev;
6662  }
6663  }
6665 #endif
6666 
6667 #ifdef UPGRADE_SUPPORT
6668  /* Finished threads with "upgraded" connections need to be moved
6669  * to cleanup list by resume_suspended_connections(). */
6670  /* "Upgraded" connections that were not closed explicitly by
6671  * application should be moved to cleanup list too. */
6672  if (upg_allowed)
6673  {
6674  daemon->resuming = true; /* Force check for pending resume. */
6676  }
6677 #endif /* UPGRADE_SUPPORT */
6678 
6679  /* now that we're alone, move everyone to cleanup */
6680  while (NULL != (pos = daemon->connections_tail))
6681  {
6682 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6683  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
6684  (! pos->thread_joined) )
6685  MHD_PANIC (_("Failed to join a thread\n"));
6686 #endif
6687  close_connection (pos);
6688  }
6690 }
6691 
6692 
6699 void
6701 {
6702  MHD_socket fd;
6703 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6704  unsigned int i;
6705 #endif
6706 
6707  if (NULL == daemon)
6708  return;
6709 
6710  daemon->shutdown = true;
6711  if (daemon->was_quiesced)
6712  fd = MHD_INVALID_SOCKET; /* Do not use FD if daemon was quiesced */
6713  else
6714  fd = daemon->listen_fd;
6715 
6716 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6717  if (NULL != daemon->worker_pool)
6718  { /* Master daemon with worker pool. */
6721 
6722  /* Let workers shutdown in parallel. */
6723  for (i = 0; i < daemon->worker_pool_size; ++i)
6724  {
6725  daemon->worker_pool[i].shutdown = true;
6726  if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc))
6727  {
6728  if (! MHD_itc_activate_ (daemon->worker_pool[i].itc,
6729  "e"))
6730  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel."));
6731  }
6732  else
6734  }
6735 #ifdef HAVE_LISTEN_SHUTDOWN
6736  if (MHD_INVALID_SOCKET != fd)
6737  {
6738  (void) shutdown (fd,
6739  SHUT_RDWR);
6740  }
6741 #endif /* HAVE_LISTEN_SHUTDOWN */
6742  for (i = 0; i < daemon->worker_pool_size; ++i)
6743  {
6745  }
6746  free (daemon->worker_pool);
6748 #ifdef EPOLL_SUPPORT
6749  mhd_assert (-1 == daemon->epoll_fd);
6750 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6751  mhd_assert (-1 == daemon->epoll_upgrade_fd);
6752 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6753 #endif /* EPOLL_SUPPORT */
6754  }
6755  else
6756 #endif
6757  { /* Worker daemon or single daemon. */
6758 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6760  { /* Worker daemon or single daemon with internal thread(s). */
6762  /* Separate thread(s) is used for polling sockets. */
6763  if (MHD_ITC_IS_VALID_ (daemon->itc))
6764  {
6765  if (! MHD_itc_activate_ (daemon->itc,
6766  "e"))
6767  MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel"));
6768  }
6769  else
6770  {
6771 #ifdef HAVE_LISTEN_SHUTDOWN
6772  if (MHD_INVALID_SOCKET != fd)
6773  {
6774  if (NULL == daemon->master)
6775  (void) shutdown (fd,
6776  SHUT_RDWR);
6777  }
6778  else
6779 #endif /* HAVE_LISTEN_SHUTDOWN */
6780  mhd_assert (false); /* Should never happen */
6781  }
6782 
6783  if (! MHD_join_thread_ (daemon->pid.handle))
6784  {
6785  MHD_PANIC (_("Failed to join a thread\n"));
6786  }
6787  /* close_all_connections() was called in daemon thread. */
6788  }
6789  else
6790 #endif
6791  {
6792  /* No internal threads are used for polling sockets. */
6794  }
6795  if (MHD_ITC_IS_VALID_ (daemon->itc))
6797 
6798 #ifdef EPOLL_SUPPORT
6799  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6800  (-1 != daemon->epoll_fd) )
6801  MHD_socket_close_chk_ (daemon->epoll_fd);
6802 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
6803  if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
6804  (-1 != daemon->epoll_upgrade_fd) )
6805  MHD_socket_close_chk_ (daemon->epoll_upgrade_fd);
6806 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
6807 #endif /* EPOLL_SUPPORT */
6808 
6809 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6811 #endif
6812  }
6813 
6814  if (NULL == daemon->master)
6815  { /* Cleanup that should be done only one time in master/single daemon.
6816  * Do not perform this cleanup in worker daemons. */
6817 
6818  if (MHD_INVALID_SOCKET != fd)
6820 
6821  /* TLS clean up */
6822 #ifdef HTTPS_SUPPORT
6823  if (daemon->have_dhparams)
6824  {
6825  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
6826  daemon->have_dhparams = false;
6827  }
6828  if (0 != (daemon->options & MHD_USE_TLS))
6829  {
6830  gnutls_priority_deinit (daemon->priority_cache);
6831  if (daemon->x509_cred)
6832  gnutls_certificate_free_credentials (daemon->x509_cred);
6833  if (daemon->psk_cred)
6834  gnutls_psk_free_server_credentials (daemon->psk_cred);
6835  }
6836 #endif /* HTTPS_SUPPORT */
6837 
6838 #ifdef DAUTH_SUPPORT
6839  free (daemon->nnc);
6840 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6841  MHD_mutex_destroy_chk_ (&daemon->nnc_lock);
6842 #endif
6843 #endif
6844 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6846 #endif
6847  free (daemon);
6848  }
6849 }
6850 
6851 
6863 const union MHD_DaemonInfo *
6865  enum MHD_DaemonInfoType info_type,
6866  ...)
6867 {
6868  if (NULL == daemon)
6869  return NULL;
6870  switch (info_type)
6871  {
6873  return NULL; /* no longer supported */
6875  return NULL; /* no longer supported */
6877  return (const union MHD_DaemonInfo *) &daemon->listen_fd;
6878 #ifdef EPOLL_SUPPORT
6880  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
6881 #endif
6883  if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
6884  {
6885  /* Assume that MHD_run() in not called in other thread
6886  * at the same time. */
6887  MHD_cleanup_connections (daemon);
6888  }
6889 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
6890  else if (daemon->worker_pool)
6891  {
6892  unsigned int i;
6893  /* Collect the connection information stored in the workers. */
6894  daemon->connections = 0;
6895  for (i = 0; i < daemon->worker_pool_size; i++)
6896  {
6897  /* FIXME: next line is thread-safe only if read is atomic. */
6898  daemon->connections += daemon->worker_pool[i].connections;
6899  }
6900  }
6901 #endif
6902  return (const union MHD_DaemonInfo *) &daemon->connections;
6903  case MHD_DAEMON_INFO_FLAGS:
6904  return (const union MHD_DaemonInfo *) &daemon->options;
6906  return (const union MHD_DaemonInfo *) &daemon->port;
6907  default:
6908  return NULL;
6909  }
6910 }
6911 
6912 
6929 void
6931  void *cls)
6932 {
6933  mhd_panic = cb;
6934  mhd_panic_cls = cls;
6935 }
6936 
6937 
6944 const char *
6945 MHD_get_version (void)
6946 {
6947 #ifdef PACKAGE_VERSION
6948  return PACKAGE_VERSION;
6949 #else /* !PACKAGE_VERSION */
6950  static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
6951  if (0 == ver[0])
6952  {
6953  int res = MHD_snprintf_(ver,
6954  sizeof(ver),
6955  "%x.%x.%x",
6956  (((int)MHD_VERSION >> 24) & 0xFF),
6957  (((int)MHD_VERSION >> 16) & 0xFF),
6958  (((int)MHD_VERSION >> 8) & 0xFF));
6959  if (0 >= res || sizeof(ver) <= res)
6960  return "0.0.0"; /* Can't return real version*/
6961  }
6962  return ver;
6963 #endif /* !PACKAGE_VERSION */
6964 }
6965 
6966 
6978 _MHD_EXTERN int
6980 {
6981  switch(feature)
6982  {
6983  case MHD_FEATURE_MESSAGES:
6984 #ifdef HAVE_MESSAGES
6985  return MHD_YES;
6986 #else
6987  return MHD_NO;
6988 #endif
6989  case MHD_FEATURE_TLS:
6990 #ifdef HTTPS_SUPPORT
6991  return MHD_YES;
6992 #else /* ! HTTPS_SUPPORT */
6993  return MHD_NO;
6994 #endif /* ! HTTPS_SUPPORT */
6996 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3
6997  return MHD_YES;
6998 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
6999  return MHD_NO;
7000 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */
7002 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603
7003  return MHD_YES;
7004 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
7005  return MHD_NO;
7006 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */
7007  case MHD_FEATURE_IPv6:
7008 #ifdef HAVE_INET6
7009  return MHD_YES;
7010 #else
7011  return MHD_NO;
7012 #endif
7013  case MHD_FEATURE_IPv6_ONLY:
7014 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
7015  return MHD_YES;
7016 #else
7017  return MHD_NO;
7018 #endif
7019  case MHD_FEATURE_POLL:
7020 #ifdef HAVE_POLL
7021  return MHD_YES;
7022 #else
7023  return MHD_NO;
7024 #endif
7025  case MHD_FEATURE_EPOLL:
7026 #ifdef EPOLL_SUPPORT
7027  return MHD_YES;
7028 #else
7029  return MHD_NO;
7030 #endif
7032 #ifdef HAVE_LISTEN_SHUTDOWN
7033  return MHD_YES;
7034 #else
7035  return MHD_NO;
7036 #endif
7038 #ifdef _MHD_ITC_SOCKETPAIR
7039  return MHD_YES;
7040 #else
7041  return MHD_NO;
7042 #endif
7044 #ifdef TCP_FASTOPEN
7045  return MHD_YES;
7046 #else
7047  return MHD_NO;
7048 #endif
7050 #ifdef BAUTH_SUPPORT
7051  return MHD_YES;
7052 #else
7053  return MHD_NO;
7054 #endif
7056 #ifdef DAUTH_SUPPORT
7057  return MHD_YES;
7058 #else
7059  return MHD_NO;
7060 #endif
7062 #ifdef HAVE_POSTPROCESSOR
7063  return MHD_YES;
7064 #else
7065  return MHD_NO;
7066 #endif
7068 #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111
7069  return MHD_YES;
7070 #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
7071  return MHD_NO;
7072 #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */
7074 #if defined(HAVE_PREAD64) || defined(_WIN32)
7075  return MHD_YES;
7076 #elif defined(HAVE_PREAD)
7077  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
7078 #elif defined(HAVE_LSEEK64)
7079  return MHD_YES;
7080 #else
7081  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
7082 #endif
7084 #if defined(MHD_USE_THREAD_NAME_)
7085  return MHD_YES;
7086 #else
7087  return MHD_NO;
7088 #endif
7089  case MHD_FEATURE_UPGRADE:
7090 #if defined(UPGRADE_SUPPORT)
7091  return MHD_YES;
7092 #else
7093  return MHD_NO;
7094 #endif
7096 #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32)
7097  return MHD_YES;
7098 #else
7099  return MHD_NO;
7100 #endif
7102 #ifdef MHD_USE_GETSOCKNAME
7103  return MHD_YES;
7104 #else
7105  return MHD_NO;
7106 #endif
7108 #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL)
7109  return MHD_YES;
7110 #else
7111  return MHD_NO;
7112 #endif
7113  case MHD_FEATURE_SENDFILE:
7114 #ifdef _MHD_HAVE_SENDFILE
7115  return MHD_YES;
7116 #else
7117  return MHD_NO;
7118 #endif
7119  case MHD_FEATURE_THREADS:
7120 #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS)
7121  return MHD_YES;
7122 #else
7123  return MHD_NO;
7124 #endif
7125 
7126  }
7127  return MHD_NO;
7128 }
7129 
7130 
7131 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7132 #if defined(HTTPS_SUPPORT) && GCRYPT_VERSION_NUMBER < 0x010600
7133 #if defined(MHD_USE_POSIX_THREADS)
7134 GCRY_THREAD_OPTION_PTHREAD_IMPL;
7135 #elif defined(MHD_W32_MUTEX_)
7136 
7137 static int
7138 gcry_w32_mutex_init (void **ppmtx)
7139 {
7140  *ppmtx = malloc (sizeof (MHD_mutex_));
7141 
7142  if (NULL == *ppmtx)
7143  return ENOMEM;
7144  if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx))
7145  {
7146  free (*ppmtx);
7147  *ppmtx = NULL;
7148  return EPERM;
7149  }
7150 
7151  return 0;
7152 }
7153 
7154 
7155 static int
7156 gcry_w32_mutex_destroy (void **ppmtx)
7157 {
7158  int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL;
7159  free (*ppmtx);
7160  return res;
7161 }
7162 
7163 
7164 static int
7165 gcry_w32_mutex_lock (void **ppmtx)
7166 {
7167  return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7168 }
7169 
7170 
7171 static int
7172 gcry_w32_mutex_unlock (void **ppmtx)
7173 {
7174  return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL;
7175 }
7176 
7177 
7178 static struct gcry_thread_cbs gcry_threads_w32 = {
7179  (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
7180  NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
7181  gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
7182  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
7183 
7184 #endif /* defined(MHD_W32_MUTEX_) */
7185 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
7186 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
7187 
7191 void
7193 {
7194 #if defined(MHD_WINSOCK_SOCKETS)
7195  WSADATA wsd;
7196 #endif /* MHD_WINSOCK_SOCKETS */
7197 
7198  if (NULL == mhd_panic)
7200 
7201 #if defined(MHD_WINSOCK_SOCKETS)
7202  if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
7203  MHD_PANIC (_("Failed to initialize winsock\n"));
7204  mhd_winsock_inited_ = 1;
7205  if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
7206  MHD_PANIC (_("Winsock version 2.2 is not available\n"));
7207 #endif /* MHD_WINSOCK_SOCKETS */
7208 #ifdef HTTPS_SUPPORT
7209 #ifdef MHD_HTTPS_REQUIRE_GRYPT
7210 #if GCRYPT_VERSION_NUMBER < 0x010600
7211 #if defined(MHD_USE_POSIX_THREADS)
7212  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7213  &gcry_threads_pthread))
7214  MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
7215 #elif defined(MHD_W32_MUTEX_)
7216  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS,
7217  &gcry_threads_w32))
7218  MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n"));
7219 #endif /* defined(MHD_W32_MUTEX_) */
7220  gcry_check_version (NULL);
7221 #else
7222  if (NULL == gcry_check_version ("1.6.0"))
7223  MHD_PANIC (_("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n"));
7224 #endif
7225 #endif /* MHD_HTTPS_REQUIRE_GRYPT */
7226  gnutls_global_init ();
7227 #endif /* HTTPS_SUPPORT */
7229 #ifdef HAVE_FREEBSD_SENDFILE
7230  MHD_conn_init_static_ ();
7231 #endif /* HAVE_FREEBSD_SENDFILE */
7233 }
7234 
7235 
7236 void
7238 {
7239 #ifdef HTTPS_SUPPORT
7240  gnutls_global_deinit ();
7241 #endif /* HTTPS_SUPPORT */
7242 #if defined(MHD_WINSOCK_SOCKETS)
7243  if (mhd_winsock_inited_)
7244  WSACleanup();
7245 #endif /* MHD_WINSOCK_SOCKETS */
7247 }
7248 
7249 #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED
7251 #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */
7252 
7253 /* end of daemon.c */
bool thread_joined
Definition: internal.h:776
#define SSIZE_MAX
Definition: mhd_limits.h:111
#define MHD_send_(s, b, l)
Definition: mhd_sockets.h:259
unsigned int per_ip_connection_limit
Definition: internal.h:1595
void * unescape_callback_cls
Definition: internal.h:1418
volatile int global_init_count
Definition: daemon.c:187
#define MHD_PANIC(msg)
Definition: internal.h:68
void MHD_connection_handle_write(struct MHD_Connection *connection)
Definition: connection.c:3283
_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:5597
Header for platform missing functions.
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:4908
_MHD_EXTERN const char * MHD_get_version(void)
Definition: version.c:35
bool data_already_pending
Definition: internal.h:1497
void MHD_update_last_activity_(struct MHD_Connection *connection)
socklen_t addr_len
Definition: internal.h:730
int(* MHD_PskServerCredentialsCallback)(void *cls, const struct MHD_Connection *connection, const char *username, void **psk, size_t *psk_size)
Definition: microhttpd.h:1310
#define UINT_MAX
Definition: mhd_limits.h:45
#define MHD_SYS_select_(n, r, w, e, t)
Definition: mhd_sockets.h:323
struct sockaddr_storage addr
Definition: internal.h:725
struct MHD_Connection * cleanup_head
Definition: internal.h:1174
enum MHD_CONNECTION_STATE state
Definition: internal.h:925
void * data
Definition: microhttpd.h:2959
static int call_handlers(struct MHD_Connection *con, bool read_ready, bool write_ready, bool force_close)
Definition: daemon.c:1186
void MHD_init_mem_pools_(void)
Definition: memorypool.c:84
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:930
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:4880
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:361
struct MHD_Connection * prevX
Definition: internal.h:667
MHD_thread_handle_ID_ pid
Definition: internal.h:1246
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:177
time_t connection_timeout
Definition: internal.h:1589
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:3384
#define MHD_socket_get_error_()
Definition: mhd_sockets.h:507
internal monotonic clock functions implementations
#define MHD_mutex_destroy_chk_(pmutex)
Definition: mhd_locks.h:118
void * MHD_calloc_(size_t nelem, size_t elsize)
Definition: mhd_compat.c:96
#define MHD_socket_strerr_(err)
Definition: mhd_sockets.h:525
MHD_socket MHD_socket_create_listen_(int pf)
Definition: mhd_sockets.c:471
#define EDLL_insert(head, tail, element)
Definition: internal.h:1829
#define MHD_YES
Definition: microhttpd.h: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:3083
#define SIZE_MAX
Definition: mhd_limits.h:99
struct MHD_Response * response
Definition: internal.h:675
struct MHD_Connection * manual_timeout_head
Definition: internal.h:1140
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:1232
#define EXTRA_SLOTS
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:70
MHD_thread_handle_ID_ pid
Definition: internal.h:720
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:95
time_t MHD_monotonic_sec_counter(void)
int MHD_add_to_fd_set_(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: mhd_sockets.c:374
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:132
MHD_AccessHandlerCallback default_handler
Definition: internal.h:1264
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:2867
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
Definition: daemon.c:4726
#define MHD_SCKT_ERR_IS_EAGAIN_(err)
Definition: mhd_sockets.h:622
_MHD_EXTERN struct MHD_Daemon * MHD_start_daemon(unsigned int flags, uint16_t port, MHD_AcceptPolicyCallback apc, void *apc_cls, MHD_AccessHandlerCallback dh, void *dh_cls,...)
Definition: daemon.c:4758
intptr_t value
Definition: microhttpd.h:1680
#define MHD_SCKT_LAST_ERR_IS_(code)
Definition: mhd_sockets.h:603
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:4933
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:7237
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:283
void * uri_log_callback_cls
Definition: internal.h:1408
struct MHD_Daemon * daemon
Definition: internal.h:672
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:2044
#define MHD_TEST_ALLOW_SUSPEND_RESUME
Definition: internal.h:209
int listening_address_reuse
Definition: internal.h:1502
MHD_mutex_ per_ip_connection_mutex
Definition: internal.h:1256
#define MHD_TYPE_IS_SIGNED_(type)
Definition: mhd_limits.h:39
MHD_NotifyConnectionCallback notify_connection
Definition: internal.h:1389
Header for platform-independent inter-thread communication.
void MHD_init(void)
Definition: daemon.c:7192
struct MHD_Connection * next
Definition: internal.h:648
bool client_aware
Definition: internal.h:862
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:27
#define DLL_insert(head, tail, element)
Definition: internal.h:1742
int strict_for_client
Definition: internal.h:1610
void * socket_context
Definition: internal.h:691
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:532
bool was_quiesced
Definition: internal.h:1502
struct MHD_Connection * connections_tail
Definition: internal.h:1157
struct MHD_Daemon * worker_pool
Definition: internal.h:1070
void * mhd_panic_cls
Definition: daemon.c:161
size_t read_buffer_size
Definition: internal.h:778
int fd
Definition: microhttpd.h:3087
void * client_context
Definition: internal.h:693
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:6700
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:749
internal shared structures
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:3632
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:78
void MHD_set_https_callbacks(struct MHD_Connection *connection)
#define MHD_SCKT_SEND_MAX_SIZE_
Definition: mhd_sockets.h:220
unsigned int connection_limit
Definition: internal.h:1583
unsigned int worker_pool_size
Definition: internal.h:1363
enum MHD_FLAG options
Definition: internal.h:1600
struct MHD_Connection * connections_head
Definition: internal.h:1152
_MHD_EXTERN int MHD_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
Definition: daemon.c:3578
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:246
LogCallback uri_log_callback
Definition: internal.h:1403
void MHD_connection_handle_read(struct MHD_Connection *connection)
Definition: connection.c:3173
void MHD_connection_mark_closed_(struct MHD_Connection *connection)
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:1162
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode rtc)
time_t connection_timeout
Definition: internal.h:742
#define _MHD_EXTERN
Definition: mhd_options.h:51
#define MHD_SCKT_ERR_IS_(err, code)
Definition: mhd_sockets.h:591
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:414
Methods for managing connections.
time_t _MHD_TIMEVAL_TV_SEC_TYPE
Definition: platform.h:122
struct MHD_Daemon * master
Definition: internal.h:1065
#define EDLL_remove(head, tail, element)
Definition: internal.h:1847
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:1147
uint16_t port
Definition: internal.h:1605
#define NULL
Definition: reason_phrase.c:30
unsigned int connections
Definition: internal.h:1358
#define ULLONG_MAX
Definition: mhd_limits.h:58
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:480
struct MHD_Connection * prev
Definition: internal.h:653
#define TIMEVAL_TV_SEC_MAX
Definition: mhd_limits.h:140
#define DLL_remove(head, tail, element)
Definition: internal.h:1762
#define MHD_SCKT_EINVAL_
Definition: mhd_sockets.h:448
#define MHD_strerror_(errnum)
Definition: mhd_compat.h:44
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:63
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ thread_main_handle_connection(void *data)
MHD_FEATURE
Definition: microhttpd.h:3781
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:971
struct MHD_Connection * normal_timeout_head
Definition: internal.h:1125
#define _MHD_SYS_DEFAULT_FD_SETSIZE
Definition: mhd_sockets.h:126
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:157
UnescapeCallback unescape_callback
Definition: internal.h:1413
_MHD_EXTERN void MHD_free(void *ptr)
Definition: daemon.c:246
#define MAYBE_SOCK_NOSIGPIPE
Definition: mhd_sockets.h:168
void internal_suspend_connection_(struct MHD_Connection *connection)
Definition: daemon.c:2772
void MHD_connection_finish_forward_(struct MHD_Connection *connection) MHD_NONNULL(1)
unsigned int listen_backlog_size
Definition: internal.h:1754
#define XDLL_remove(head, tail, element)
Definition: internal.h:1806
void MHD_monotonic_sec_counter_finish(void)
#define _SET_INIT_AND_DEINIT_FUNCS(FI, FD)
static int internal_run_from_select(struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set)
Definition: daemon.c:3474
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:1169
#define MHD_create_named_thread_(t, n, s, r, a)
Definition: mhd_threads.h:208
int MHD_SCKT_OPT_BOOL_
Definition: mhd_sockets.h:201
size_t pool_size
Definition: internal.h:1453
bool tls_read_ready
Definition: internal.h:766
struct MHD_itc_ itc
Definition: internal.h:1407
MHD_AcceptPolicyCallback apc
Definition: internal.h:1367
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
time_t last_activity
Definition: internal.h:736
struct MHD_Connection * cleanup_tail
Definition: internal.h:1179
int MHD_connection_handle_idle(struct MHD_Connection *connection)
Definition: connection.c:3599
static int resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:2931
#define MHD_itc_destroy_chk_(itc)
Definition: mhd_itc.h:347
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:2346
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:2103
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:4094
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3275
bool sk_nonblck
Definition: internal.h:781
void MHD_monotonic_sec_counter_init(void)
#define MHD_recv_(s, b, l)
Definition: mhd_sockets.h:270
static int MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:3143
_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:721
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:324
void * ptr_value
Definition: microhttpd.h:1686
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:2126
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:1132
void MHD_check_global_init_(void)
Definition: daemon.c:204
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:1378
#define MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)
Definition: mhd_sockets.h:645
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:151
#define MHD_BUF_INC_SIZE
Definition: internal.h:117
#define MHD_SCKT_FD_FITS_FDSET_(fd, pset)
Definition: mhd_sockets.h:299
bool resuming
Definition: internal.h:1507
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:4639
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:4162
void * notify_completed_cls
Definition: internal.h:1383
MHD_socket listen_fd
Definition: internal.h:1491
struct MemoryPool * pool
Definition: internal.h:682
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:4604
MHD_OPTION
MHD options.
Definition: microhttpd.h:1321
int MHD_socket_nonblocking_(MHD_socket sock)
Definition: mhd_sockets.c:404
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:1246
void * notify_connection_cls
Definition: internal.h:1394
void * apc_cls
Definition: internal.h:1372
bool at_limit
Definition: internal.h:1480
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_polling_thread(void *cls)
Definition: daemon_start.c:613
MHD_PanicCallback mhd_panic
Definition: daemon.c:156
#define XDLL_insert(head, tail, element)
Definition: internal.h:1786
MHD_DaemonInfoType
Definition: microhttpd.h:1979
#define _(String)
Definition: mhd_options.h:42
#define MHD_UNSIGNED_LONG_LONG_PRINTF
Definition: microhttpd.h:296
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:2896
bool suspended
Definition: internal.h:761
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
Definition: daemon.c:6979
struct MHD_Connection * suspended_connections_head
Definition: internal.h:1163
void * per_ip_connection_count
Definition: internal.h:1184
size_t read_buffer_offset
Definition: internal.h:784
_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:1120
void * default_handler_cls
Definition: internal.h:1269
#define MHD_NO
Definition: microhttpd.h:145
volatile bool shutdown
Definition: internal.h:1523
#define MHD_SCKT_ERR_IS_EINTR_(err)
Definition: mhd_sockets.h:613
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1262
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:4803
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Definition: microhttpd.h:2058
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
Definition: microhttpd.h:2152
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:6864
_MHD_EXTERN size_t MHD_http_unescape(char *val)
Definition: internal.c:138
#define MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)
Definition: mhd_sockets.h:633
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:6544
limits values definitions
enum MHD_OPTION option
Definition: microhttpd.h:1673
int MHD_socket_noninheritable_(MHD_socket sock)
Definition: mhd_sockets.c:439
#define MAYBE_SOCK_NONBLOCK
Definition: mhd_sockets.h:162
MHD_FLAG
Flags for the struct MHD_Daemon.
Definition: microhttpd.h:1004
size_t pool_increment
Definition: internal.h:1458
int MHD_socket_buffering_reset_(MHD_socket sock)
Definition: mhd_sockets.c:471
#define MAYBE_SOCK_CLOEXEC
Definition: mhd_sockets.h:156
#define MHD_SCKT_EINTR_
Definition: mhd_sockets.h:398