GNU libmicrohttpd  0.9.29
daemon.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007-2014 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 
27 #if defined(MHD_WINSOCK_SOCKETS)
28 /* override small default value */
29 #define FD_SETSIZE 1024
30 #define MHD_DEFAULT_FD_SETSIZE 64
31 #else
32 #define MHD_DEFAULT_FD_SETSIZE FD_SETSIZE
33 #endif
34 #include "platform.h"
35 #include "internal.h"
36 #include "response.h"
37 #include "connection.h"
38 #include "memorypool.h"
39 #include "mhd_limits.h"
40 #include "autoinit_funcs.h"
41 #include "mhd_mono_clock.h"
42 
43 #if HAVE_SEARCH_H
44 #include <search.h>
45 #else
46 #include "tsearch.h"
47 #endif
48 
49 #if HTTPS_SUPPORT
50 #include "connection_https.h"
51 #include <gcrypt.h>
52 #endif
53 
54 #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
55 #include <poll.h>
56 #endif
57 
58 #ifdef LINUX
59 #include <sys/sendfile.h>
60 #endif
61 
62 #ifdef _WIN32
63 #ifndef WIN32_LEAN_AND_MEAN
64 #define WIN32_LEAN_AND_MEAN 1
65 #endif /* !WIN32_LEAN_AND_MEAN */
66 #include <windows.h>
67 #include <process.h>
68 #endif
69 
70 #ifndef HAVE_ACCEPT4
71 #define HAVE_ACCEPT4 0
72 #endif
73 
77 #ifndef MHD_WINSOCK_SOCKETS
78 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4
79 #else
80 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
81 #endif
82 
86 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
87 
88 #ifdef TCP_FASTOPEN
89 
92 #define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10
93 #endif
94 
99 #define DEBUG_CLOSE MHD_NO
100 
105 #define DEBUG_CONNECT MHD_NO
106 
107 #ifndef LINUX
108 #ifndef MSG_NOSIGNAL
109 #define MSG_NOSIGNAL 0
110 #endif
111 #endif
112 
113 #ifndef SOCK_CLOEXEC
114 #define SOCK_CLOEXEC 0
115 #endif
116 
117 #ifndef EPOLL_CLOEXEC
118 #define EPOLL_CLOEXEC 0
119 #endif
120 
121 
131 static void
132 mhd_panic_std (void *cls,
133  const char *file,
134  unsigned int line,
135  const char *reason)
136 {
137 #if HAVE_MESSAGES
138  fprintf (stderr,
139  "Fatal error in GNU libmicrohttpd %s:%u: %s\n",
140  file, line, reason);
141 #endif
142  abort ();
143 }
144 
145 
150 
155 
156 #ifdef _WIN32
157 
160 static int mhd_winsock_inited_ = 0;
161 #endif
162 
170 static struct MHD_Daemon*
171 MHD_get_master (struct MHD_Daemon *daemon)
172 {
173  while (NULL != daemon->master)
174  daemon = daemon->master;
175  return daemon;
176 }
177 
178 
182 struct MHD_IPCount
183 {
187  int family;
188 
192  union
193  {
197  struct in_addr ipv4;
198 #if HAVE_INET6
199 
202  struct in6_addr ipv6;
203 #endif
204  } addr;
205 
209  unsigned int count;
210 };
211 
212 
218 static void
220 {
221  if (MHD_YES != MHD_mutex_lock_(&daemon->per_ip_connection_mutex))
222  {
223  MHD_PANIC ("Failed to acquire IP connection limit mutex\n");
224  }
225 }
226 
227 
233 static void
235 {
236  if (MHD_YES != MHD_mutex_unlock_(&daemon->per_ip_connection_mutex))
237  {
238  MHD_PANIC ("Failed to release IP connection limit mutex\n");
239  }
240 }
241 
242 
252 static int
253 MHD_ip_addr_compare (const void *a1, const void *a2)
254 {
255  return memcmp (a1, a2, offsetof (struct MHD_IPCount, count));
256 }
257 
258 
267 static int
268 MHD_ip_addr_to_key (const struct sockaddr *addr,
269  socklen_t addrlen,
270  struct MHD_IPCount *key)
271 {
272  memset(key, 0, sizeof(*key));
273 
274  /* IPv4 addresses */
275  if (sizeof (struct sockaddr_in) == addrlen)
276  {
277  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
278  key->family = AF_INET;
279  memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr));
280  return MHD_YES;
281  }
282 
283 #if HAVE_INET6
284  /* IPv6 addresses */
285  if (sizeof (struct sockaddr_in6) == addrlen)
286  {
287  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
288  key->family = AF_INET6;
289  memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr));
290  return MHD_YES;
291  }
292 #endif
293 
294  /* Some other address */
295  return MHD_NO;
296 }
297 
298 
308 static int
309 MHD_ip_limit_add (struct MHD_Daemon *daemon,
310  const struct sockaddr *addr,
311  socklen_t addrlen)
312 {
313  struct MHD_IPCount *key;
314  void **nodep;
315  void *node;
316  int result;
317 
318  daemon = MHD_get_master (daemon);
319  /* Ignore if no connection limit assigned */
320  if (0 == daemon->per_ip_connection_limit)
321  return MHD_YES;
322 
323  if (NULL == (key = malloc (sizeof(*key))))
324  return MHD_NO;
325 
326  /* Initialize key */
327  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key))
328  {
329  /* Allow unhandled address types through */
330  free (key);
331  return MHD_YES;
332  }
333  MHD_ip_count_lock (daemon);
334 
335  /* Search for the IP address */
336  if (NULL == (nodep = tsearch (key,
337  &daemon->per_ip_connection_count,
339  {
340 #if HAVE_MESSAGES
341  MHD_DLOG (daemon,
342  "Failed to add IP connection count node\n");
343 #endif
344  MHD_ip_count_unlock (daemon);
345  free (key);
346  return MHD_NO;
347  }
348  node = *nodep;
349  /* If we got an existing node back, free the one we created */
350  if (node != key)
351  free(key);
352  key = (struct MHD_IPCount *) node;
353  /* Test if there is room for another connection; if so,
354  * increment count */
355  result = (key->count < daemon->per_ip_connection_limit) ? MHD_YES : MHD_NO;
356  if (MHD_YES == result)
357  ++key->count;
358 
359  MHD_ip_count_unlock (daemon);
360  return result;
361 }
362 
363 
372 static void
373 MHD_ip_limit_del (struct MHD_Daemon *daemon,
374  const struct sockaddr *addr,
375  socklen_t addrlen)
376 {
377  struct MHD_IPCount search_key;
378  struct MHD_IPCount *found_key;
379  void **nodep;
380 
381  daemon = MHD_get_master (daemon);
382  /* Ignore if no connection limit assigned */
383  if (0 == daemon->per_ip_connection_limit)
384  return;
385  /* Initialize search key */
386  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key))
387  return;
388 
389  MHD_ip_count_lock (daemon);
390 
391  /* Search for the IP address */
392  if (NULL == (nodep = tfind (&search_key,
393  &daemon->per_ip_connection_count,
395  {
396  /* Something's wrong if we couldn't find an IP address
397  * that was previously added */
398  MHD_PANIC ("Failed to find previously-added IP address\n");
399  }
400  found_key = (struct MHD_IPCount *) *nodep;
401  /* Validate existing count for IP address */
402  if (0 == found_key->count)
403  {
404  MHD_PANIC ("Previously-added IP address had 0 count\n");
405  }
406  /* Remove the node entirely if count reduces to 0 */
407  if (0 == --found_key->count)
408  {
409  tdelete (found_key,
410  &daemon->per_ip_connection_count,
412  free (found_key);
413  }
414 
415  MHD_ip_count_unlock (daemon);
416 }
417 
418 
419 #if HTTPS_SUPPORT
420 
428 static ssize_t
429 recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
430 {
431  ssize_t res;
432 
433  if (MHD_YES == connection->tls_read_ready)
434  {
435  connection->daemon->num_tls_read_ready--;
436  connection->tls_read_ready = MHD_NO;
437  }
438  res = gnutls_record_recv (connection->tls_session, other, i);
439  if ( (GNUTLS_E_AGAIN == res) ||
440  (GNUTLS_E_INTERRUPTED == res) )
441  {
442  MHD_set_socket_errno_ (EINTR);
443 #if EPOLL_SUPPORT
444  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
445 #endif
446  return -1;
447  }
448  if (res < 0)
449  {
450  /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
451  disrupted); set errno to something caller will interpret
452  correctly as a hard error */
454  return res;
455  }
456  if ((size_t)res == i)
457  {
458  connection->tls_read_ready = MHD_YES;
459  connection->daemon->num_tls_read_ready++;
460  }
461  return res;
462 }
463 
464 
473 static ssize_t
474 send_tls_adapter (struct MHD_Connection *connection,
475  const void *other, size_t i)
476 {
477  int res;
478 
479  res = gnutls_record_send (connection->tls_session, other, i);
480  if ( (GNUTLS_E_AGAIN == res) ||
481  (GNUTLS_E_INTERRUPTED == res) )
482  {
483  MHD_set_socket_errno_ (EINTR);
484 #if EPOLL_SUPPORT
485  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
486 #endif
487  return -1;
488  }
489  if (res < 0)
490  {
491  /* some other GNUTLS error, should set 'errno'; as we do not
492  really understand the error (not listed in GnuTLS
493  documentation explicitly), we set 'errno' to something that
494  will cause the connection to fail. */
496  return -1;
497  }
498  return res;
499 }
500 
501 
508 static int
509 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
510 {
511  gnutls_datum_t key;
512  gnutls_datum_t cert;
513  int ret;
514 
515 #if GNUTLS_VERSION_MAJOR >= 3
516  if (NULL != daemon->cert_callback)
517  {
518  gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
519  daemon->cert_callback);
520  }
521 #endif
522  if (NULL != daemon->https_mem_trust)
523  {
524  cert.data = (unsigned char *) daemon->https_mem_trust;
525  cert.size = strlen (daemon->https_mem_trust);
526  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, &cert,
527  GNUTLS_X509_FMT_PEM) < 0)
528  {
529 #if HAVE_MESSAGES
530  MHD_DLOG(daemon,
531  "Bad trust certificate format\n");
532 #endif
533  return -1;
534  }
535  }
536 
537  if (MHD_YES == daemon->have_dhparams)
538  {
539  gnutls_certificate_set_dh_params (daemon->x509_cred,
540  daemon->https_mem_dhparams);
541  }
542  /* certificate & key loaded from memory */
543  if ( (NULL != daemon->https_mem_cert) &&
544  (NULL != daemon->https_mem_key) )
545  {
546  key.data = (unsigned char *) daemon->https_mem_key;
547  key.size = strlen (daemon->https_mem_key);
548  cert.data = (unsigned char *) daemon->https_mem_cert;
549  cert.size = strlen (daemon->https_mem_cert);
550 
551  if (NULL != daemon->https_key_password) {
552 #if GNUTLS_VERSION_NUMBER >= 0x030111
553  ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred,
554  &cert, &key,
555  GNUTLS_X509_FMT_PEM,
556  daemon->https_key_password,
557  0);
558 #else
559 #if HAVE_MESSAGES
560  MHD_DLOG (daemon,
561  "Failed to setup x509 certificate/key: pre 3.X.X version " \
562  "of GnuTLS does not support setting key password");
563 #endif
564  return -1;
565 #endif
566  }
567  else
568  ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
569  &cert, &key,
570  GNUTLS_X509_FMT_PEM);
571 #if HAVE_MESSAGES
572  if (0 != ret)
573  MHD_DLOG (daemon,
574  "GnuTLS failed to setup x509 certificate/key: %s\n",
575  gnutls_strerror (ret));
576 #endif
577  return ret;
578  }
579 #if GNUTLS_VERSION_MAJOR >= 3
580  if (NULL != daemon->cert_callback)
581  return 0;
582 #endif
583 #if HAVE_MESSAGES
584  MHD_DLOG (daemon,
585  "You need to specify a certificate and key location\n");
586 #endif
587  return -1;
588 }
589 
590 
597 static int
598 MHD_TLS_init (struct MHD_Daemon *daemon)
599 {
600  switch (daemon->cred_type)
601  {
602  case GNUTLS_CRD_CERTIFICATE:
603  if (0 !=
604  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
605  return GNUTLS_E_MEMORY_ERROR;
606  return MHD_init_daemon_certificate (daemon);
607  default:
608 #if HAVE_MESSAGES
609  MHD_DLOG (daemon,
610  "Error: invalid credentials type %d specified.\n",
611  daemon->cred_type);
612 #endif
613  return -1;
614  }
615 }
616 #endif
617 
618 
629 static int
631  fd_set *set,
632  MHD_socket *max_fd,
633  unsigned int fd_setsize)
634 {
635  if (NULL == set)
636  return MHD_NO;
637 #ifdef MHD_WINSOCK_SOCKETS
638  if (set->fd_count >= fd_setsize)
639  {
640  if (FD_ISSET(fd, set))
641  return MHD_YES;
642  else
643  return MHD_NO;
644  }
645 #else /* ! MHD_WINSOCK_SOCKETS */
646  if (fd >= (MHD_socket)fd_setsize)
647  return MHD_NO;
648 #endif /* ! MHD_WINSOCK_SOCKETS */
649  FD_SET (fd, set);
650  if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) &&
651  ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) )
652  *max_fd = fd;
653 
654  return MHD_YES;
655 }
656 
657 #undef MHD_get_fdset
658 
678 int
679 MHD_get_fdset (struct MHD_Daemon *daemon,
680  fd_set *read_fd_set,
681  fd_set *write_fd_set,
682  fd_set *except_fd_set,
683  MHD_socket *max_fd)
684 {
685  return MHD_get_fdset2(daemon, read_fd_set,
686  write_fd_set, except_fd_set,
687  max_fd, MHD_DEFAULT_FD_SETSIZE);
688 }
689 
711 int
712 MHD_get_fdset2 (struct MHD_Daemon *daemon,
713  fd_set *read_fd_set,
714  fd_set *write_fd_set,
715  fd_set *except_fd_set,
716  MHD_socket *max_fd,
717  unsigned int fd_setsize)
718 {
719  struct MHD_Connection *pos;
720 
721  if ( (NULL == daemon)
722  || (NULL == read_fd_set)
723  || (NULL == write_fd_set)
724  || (MHD_YES == daemon->shutdown)
725  || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
726  || (0 != (daemon->options & MHD_USE_POLL)))
727  return MHD_NO;
728 #if EPOLL_SUPPORT
729  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
730  {
731  /* we're in epoll mode, use the epoll FD as a stand-in for
732  the entire event set */
733 
734  return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd, fd_setsize);
735  }
736 #endif
737  if (MHD_INVALID_SOCKET != daemon->socket_fd &&
738  MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd, fd_setsize))
739  return MHD_NO;
740 
741  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
742  {
743  switch (pos->event_loop_info)
744  {
746  if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
747  return MHD_NO;
748  break;
750  if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd, fd_setsize))
751  return MHD_NO;
752  if (pos->read_buffer_size > pos->read_buffer_offset &&
753  MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
754  return MHD_NO;
755  break;
757  if (pos->read_buffer_size > pos->read_buffer_offset &&
758  MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
759  return MHD_NO;
760  break;
762  /* this should never happen */
763  break;
764  }
765  }
766 #if DEBUG_CONNECT
767 #if HAVE_MESSAGES
768  if (NULL != max_fd)
769  MHD_DLOG (daemon,
770  "Maximum socket in select set: %d\n",
771  *max_fd);
772 #endif
773 #endif
774  return MHD_YES;
775 }
776 
777 
785 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
787 {
788  struct MHD_Connection *con = data;
789  int num_ready;
790  fd_set rs;
791  fd_set ws;
792  MHD_socket max;
793  struct timeval tv;
794  struct timeval *tvp;
795  unsigned int timeout;
796  time_t now;
797 #if WINDOWS
798  MHD_pipe spipe = con->daemon->wpipe[0];
799  char tmp;
800 #ifdef HAVE_POLL
801  int extra_slot;
802 #endif /* HAVE_POLL */
803 #define EXTRA_SLOTS 1
804 #else /* !WINDOWS */
805 #define EXTRA_SLOTS 0
806 #endif /* !WINDOWS */
807 #ifdef HAVE_POLL
808  struct pollfd p[1 + EXTRA_SLOTS];
809 #endif
810 
811  timeout = con->daemon->connection_timeout;
812  while ( (MHD_YES != con->daemon->shutdown) &&
813  (MHD_CONNECTION_CLOSED != con->state) )
814  {
815  tvp = NULL;
816 #if HTTPS_SUPPORT
817  if (MHD_YES == con->tls_read_ready)
818  {
819  /* do not block (more data may be inside of TLS buffers waiting for us) */
820  tv.tv_sec = 0;
821  tv.tv_usec = 0;
822  tvp = &tv;
823  }
824 #endif
825  if (NULL == tvp && timeout > 0)
826  {
828  if (now - con->last_activity > timeout)
829  tv.tv_sec = 0;
830  else
831  {
832  const time_t seconds_left = timeout - (now - con->last_activity);
833 #ifndef _WIN32
834  tv.tv_sec = seconds_left;
835 #else /* _WIN32 */
836  if (seconds_left > TIMEVAL_TV_SEC_MAX)
837  tv.tv_sec = TIMEVAL_TV_SEC_MAX;
838  else
839  tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)seconds_left;
840 #endif /* _WIN32 */
841  }
842  tv.tv_usec = 0;
843  tvp = &tv;
844  }
845  if (0 == (con->daemon->options & MHD_USE_POLL))
846  {
847  /* use select */
848  int err_state = 0;
849  FD_ZERO (&rs);
850  FD_ZERO (&ws);
851  max = 0;
852  switch (con->event_loop_info)
853  {
855  if (MHD_YES !=
856  add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
857  err_state = 1;
858  break;
860  if (MHD_YES !=
861  add_to_fd_set (con->socket_fd, &ws, &max, FD_SETSIZE))
862  err_state = 1;
863  if ( (con->read_buffer_size > con->read_buffer_offset) &&
864  (MHD_YES !=
865  add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE)) )
866  err_state = 1;
867  break;
869  if ( (con->read_buffer_size > con->read_buffer_offset) &&
870  (MHD_YES !=
871  add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE)) )
872  err_state = 1;
873  tv.tv_sec = 0;
874  tv.tv_usec = 0;
875  tvp = &tv;
876  break;
878  /* how did we get here!? */
879  goto exit;
880  }
881 #if WINDOWS
882  if (MHD_INVALID_PIPE_ != spipe)
883  {
884  if (MHD_YES !=
885  add_to_fd_set (spipe, &rs, &max, FD_SETSIZE))
886  err_state = 1;
887  }
888 #endif
889  if (0 != err_state)
890  {
891 #if HAVE_MESSAGES
892  MHD_DLOG (con->daemon,
893  "Can't add FD to fd_set\n");
894 #endif
895  goto exit;
896  }
897 
898  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp);
899  if (num_ready < 0)
900  {
901  if (EINTR == MHD_socket_errno_)
902  continue;
903 #if HAVE_MESSAGES
904  MHD_DLOG (con->daemon,
905  "Error during select (%d): `%s'\n",
908 #endif
909  break;
910  }
911 #if WINDOWS
912  /* drain signaling pipe */
913  if ( (MHD_INVALID_PIPE_ != spipe) &&
914  (FD_ISSET (spipe, &rs)) )
915  (void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp));
916 #endif
917  /* call appropriate connection handler if necessary */
918  if ( (FD_ISSET (con->socket_fd, &rs))
919 #if HTTPS_SUPPORT
920  || (MHD_YES == con->tls_read_ready)
921 #endif
922  )
923  con->read_handler (con);
924  if (FD_ISSET (con->socket_fd, &ws))
925  con->write_handler (con);
926  if (MHD_NO == con->idle_handler (con))
927  goto exit;
928  }
929 #ifdef HAVE_POLL
930  else
931  {
932  /* use poll */
933  memset (&p, 0, sizeof (p));
934  p[0].fd = con->socket_fd;
935  switch (con->event_loop_info)
936  {
938  p[0].events |= POLLIN;
939  break;
941  p[0].events |= POLLOUT;
942  if (con->read_buffer_size > con->read_buffer_offset)
943  p[0].events |= POLLIN;
944  break;
946  if (con->read_buffer_size > con->read_buffer_offset)
947  p[0].events |= POLLIN;
948  tv.tv_sec = 0;
949  tv.tv_usec = 0;
950  tvp = &tv;
951  break;
953  /* how did we get here!? */
954  goto exit;
955  }
956 #if WINDOWS
957  extra_slot = 0;
958  if (MHD_INVALID_PIPE_ != spipe)
959  {
960  p[1].events |= POLLIN;
961  p[1].fd = spipe;
962  p[1].revents = 0;
963  extra_slot = 1;
964  }
965 #endif
966  if (MHD_sys_poll_ (p,
967 #if WINDOWS
968  1 + extra_slot,
969 #else
970  1,
971 #endif
972  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
973  {
974  if (EINTR == MHD_socket_errno_)
975  continue;
976 #if HAVE_MESSAGES
977  MHD_DLOG (con->daemon,
978  "Error during poll: `%s'\n",
980 #endif
981  break;
982  }
983 #if WINDOWS
984  /* drain signaling pipe */
985  if ( (MHD_INVALID_PIPE_ != spipe) &&
986  (0 != (p[1].revents & (POLLERR | POLLHUP))) )
987  (void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp));
988 #endif
989  if ( (0 != (p[0].revents & POLLIN))
990 #if HTTPS_SUPPORT
991  || (MHD_YES == con->tls_read_ready)
992 #endif
993  )
994  con->read_handler (con);
995  if (0 != (p[0].revents & POLLOUT))
996  con->write_handler (con);
997  if (0 != (p[0].revents & (POLLERR | POLLHUP)))
1000  if (MHD_NO == con->idle_handler (con))
1001  goto exit;
1002  }
1003 #endif
1004  }
1005  if (MHD_CONNECTION_IN_CLEANUP != con->state)
1006  {
1007 #if DEBUG_CLOSE
1008 #if HAVE_MESSAGES
1009  MHD_DLOG (con->daemon,
1010  "Processing thread terminating, closing connection\n");
1011 #endif
1012 #endif
1013  if (MHD_CONNECTION_CLOSED != con->state)
1014  MHD_connection_close_ (con,
1016  con->idle_handler (con);
1017  }
1018 exit:
1019  if (NULL != con->response)
1020  {
1022  con->response = NULL;
1023  }
1024 
1025  if (NULL != con->daemon->notify_connection)
1027  con,
1028  &con->socket_context,
1030 
1031  return (MHD_THRD_RTRN_TYPE_) 0;
1032 }
1033 
1034 
1043 static ssize_t
1045  void *other,
1046  size_t i)
1047 {
1048  ssize_t ret;
1049 #if EPOLL_SUPPORT
1050  const size_t requested_size = i;
1051 #endif
1052 
1053  if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
1054  (MHD_CONNECTION_CLOSED == connection->state) )
1055  {
1057  return -1;
1058  }
1059 #ifdef MHD_POSIX_SOCKETS
1060  if (i > SSIZE_MAX)
1061  i = SSIZE_MAX; /* return value limit */
1062 #else /* MHD_WINSOCK_SOCKETS */
1063  if (i > INT_MAX)
1064  i = INT_MAX; /* return value limit */
1065 #endif /* MHD_WINSOCK_SOCKETS */
1066 
1067  ret = (ssize_t)recv (connection->socket_fd, other, (_MHD_socket_funcs_size)i, MSG_NOSIGNAL);
1068 #if EPOLL_SUPPORT
1069  if ( (0 > ret) || (requested_size > (size_t) ret))
1070  {
1071  /* partial read --- no longer read-ready */
1072  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
1073  }
1074 #endif
1075  return ret;
1076 }
1077 
1078 
1087 static ssize_t
1089  const void *other,
1090  size_t i)
1091 {
1092  ssize_t ret;
1093 #if EPOLL_SUPPORT
1094  const size_t requested_size = i;
1095 #endif
1096 #if LINUX
1097  MHD_socket fd;
1098 #endif
1099 
1100  if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
1101  (MHD_CONNECTION_CLOSED == connection->state) )
1102  {
1104  return -1;
1105  }
1106 #ifdef MHD_POSIX_SOCKETS
1107  if (i > SSIZE_MAX)
1108  i = SSIZE_MAX; /* return value limit */
1109 #else /* MHD_WINSOCK_SOCKETS */
1110  if (i > INT_MAX)
1111  i = INT_MAX; /* return value limit */
1112 #endif /* MHD_WINSOCK_SOCKETS */
1113 
1114  if (0 != (connection->daemon->options & MHD_USE_SSL))
1115  return (ssize_t)send (connection->socket_fd, other, (_MHD_socket_funcs_size)i, MSG_NOSIGNAL);
1116 #if LINUX
1117  if ( (connection->write_buffer_append_offset ==
1118  connection->write_buffer_send_offset) &&
1119  (NULL != connection->response) &&
1120  (-1 != (fd = connection->response->fd)) )
1121  {
1122  /* can use sendfile */
1123  uint64_t left;
1124  uint64_t offsetu64;
1125  int err;
1126 #ifndef HAVE_SENDFILE64
1127  off_t offset;
1128 #else /* HAVE_SENDFILE64 */
1129  off64_t offset;
1130 #endif /* HAVE_SENDFILE64 */
1131  offsetu64 = connection->response_write_position + connection->response->fd_off;
1132  left = connection->response->total_size - connection->response_write_position;
1133 #ifndef HAVE_SENDFILE64
1134  offset = (off_t) offsetu64;
1135  if ( (offsetu64 <= (uint64_t) OFF_T_MAX) &&
1136  (0 < (ret = sendfile (connection->socket_fd, fd, &offset, left))) )
1137 #else /* HAVE_SENDFILE64 */
1138  offset = (off64_t) offsetu64;
1139  if ( (offsetu64 <= (uint64_t) OFF64_T_MAX) &&
1140  (0 < (ret = sendfile64 (connection->socket_fd, fd, &offset, left))) )
1141 #endif /* HAVE_SENDFILE64 */
1142  {
1143 #if EPOLL_SUPPORT
1144  if (requested_size > (size_t) ret)
1145  {
1146  /* partial write --- no longer write-ready */
1147  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
1148  }
1149 #endif
1150  return ret;
1151  }
1152  err = MHD_socket_errno_;
1153  if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) )
1154  return 0;
1155  if ( (EINVAL == err) || (EBADF == err) )
1156  return -1;
1157  /* None of the 'usual' sendfile errors occurred, so we should try
1158  to fall back to 'SEND'; see also this thread for info on
1159  odd libc/Linux behavior with sendfile:
1160  http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
1161  }
1162 #endif
1163  ret = (ssize_t)send (connection->socket_fd, other, (_MHD_socket_funcs_size)i, MSG_NOSIGNAL);
1164 #if EPOLL_SUPPORT
1165  if ( (0 > ret) || (requested_size > (size_t) ret) )
1166  {
1167  /* partial write --- no longer write-ready */
1168  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
1169  }
1170 #endif
1171  /* Handle broken kernel / libc, returning -1 but not setting errno;
1172  kill connection as that should be safe; reported on mailinglist here:
1173  http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */
1174  if ( (0 > ret) && (0 == MHD_socket_errno_) )
1176  return ret;
1177 }
1178 
1179 
1186 typedef MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *ThreadStartRoutine)(void *cls);
1187 
1188 
1198 static int
1199 create_thread (MHD_thread_handle_ *thread,
1200  const struct MHD_Daemon *daemon,
1201  ThreadStartRoutine start_routine,
1202  void *arg)
1203 {
1204 #if defined(MHD_USE_POSIX_THREADS)
1205  pthread_attr_t attr;
1206  pthread_attr_t *pattr;
1207  int ret;
1208 
1209  if (0 != daemon->thread_stack_size)
1210  {
1211  if (0 != (ret = pthread_attr_init (&attr)))
1212  goto ERR;
1213  if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size)))
1214  {
1215  pthread_attr_destroy (&attr);
1216  goto ERR;
1217  }
1218  pattr = &attr;
1219  }
1220  else
1221  {
1222  pattr = NULL;
1223  }
1224  ret = pthread_create (thread, pattr,
1225  start_routine, arg);
1226 #ifdef HAVE_PTHREAD_SETNAME_NP
1227  (void) pthread_setname_np (*thread, "libmicrohttpd");
1228 #endif /* HAVE_PTHREAD_SETNAME_NP */
1229  if (0 != daemon->thread_stack_size)
1230  pthread_attr_destroy (&attr);
1231  return ret;
1232  ERR:
1233 #if HAVE_MESSAGES
1234  MHD_DLOG (daemon,
1235  "Failed to set thread stack size\n");
1236 #endif
1237  errno = EINVAL;
1238  return ret;
1239 #elif defined(MHD_USE_W32_THREADS)
1240  unsigned threadID;
1241  *thread = (HANDLE)_beginthreadex(NULL, (unsigned)daemon->thread_stack_size, start_routine,
1242  arg, 0, &threadID);
1243  if (NULL == (*thread))
1244  return errno;
1245 
1246  W32_SetThreadName(threadID, "libmicrohttpd");
1247 
1248  return 0;
1249 #endif
1250 }
1251 
1252 
1279 static int
1281  MHD_socket client_socket,
1282  const struct sockaddr *addr,
1283  socklen_t addrlen,
1284  int external_add)
1285 {
1286  struct MHD_Connection *connection;
1287  int res_thread_create;
1288  unsigned int i;
1289  int eno;
1290  struct MHD_Daemon *worker;
1291 #if OSX
1292  static int on = 1;
1293 #endif
1294 
1295  if (NULL != daemon->worker_pool)
1296  {
1297  /* have a pool, try to find a pool with capacity; we use the
1298  socket as the initial offset into the pool for load
1299  balancing */
1300  for (i=0;i<daemon->worker_pool_size;i++)
1301  {
1302  worker = &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
1303  if (worker->connections < worker->connection_limit)
1304  return internal_add_connection (worker,
1305  client_socket,
1306  addr, addrlen,
1307  external_add);
1308  }
1309  /* all pools are at their connection limit, must refuse */
1310  if (0 != MHD_socket_close_ (client_socket))
1311  MHD_PANIC ("close failed\n");
1312 #if ENFILE
1313  errno = ENFILE;
1314 #endif
1315  return MHD_NO;
1316  }
1317 
1318 #ifndef MHD_WINSOCK_SOCKETS
1319  if ( (client_socket >= FD_SETSIZE) &&
1320  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) )
1321  {
1322 #if HAVE_MESSAGES
1323  MHD_DLOG (daemon,
1324  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
1325  client_socket,
1326  FD_SETSIZE);
1327 #endif
1328  if (0 != MHD_socket_close_ (client_socket))
1329  MHD_PANIC ("close failed\n");
1330 #if EINVAL
1331  errno = EINVAL;
1332 #endif
1333  return MHD_NO;
1334  }
1335 #endif
1336 
1337 
1338 #if HAVE_MESSAGES
1339 #if DEBUG_CONNECT
1340  MHD_DLOG (daemon,
1341  "Accepted connection on socket %d\n",
1342  client_socket);
1343 #endif
1344 #endif
1345  if ( (daemon->connections == daemon->connection_limit) ||
1346  (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) )
1347  {
1348  /* above connection limit - reject */
1349 #if HAVE_MESSAGES
1350  MHD_DLOG (daemon,
1351  "Server reached connection limit (closing inbound connection)\n");
1352 #endif
1353  if (0 != MHD_socket_close_ (client_socket))
1354  MHD_PANIC ("close failed\n");
1355 #if ENFILE
1356  errno = ENFILE;
1357 #endif
1358  return MHD_NO;
1359  }
1360 
1361  /* apply connection acceptance policy if present */
1362  if ( (NULL != daemon->apc) &&
1363  (MHD_NO == daemon->apc (daemon->apc_cls,
1364  addr, addrlen)) )
1365  {
1366 #if DEBUG_CLOSE
1367 #if HAVE_MESSAGES
1368  MHD_DLOG (daemon,
1369  "Connection rejected, closing connection\n");
1370 #endif
1371 #endif
1372  if (0 != MHD_socket_close_ (client_socket))
1373  MHD_PANIC ("close failed\n");
1374  MHD_ip_limit_del (daemon, addr, addrlen);
1375 #if EACCESS
1376  errno = EACCESS;
1377 #endif
1378  return MHD_NO;
1379  }
1380 
1381 #if OSX
1382 #ifdef SOL_SOCKET
1383 #ifdef SO_NOSIGPIPE
1384  setsockopt (client_socket,
1385  SOL_SOCKET, SO_NOSIGPIPE,
1386  &on, sizeof (on));
1387 #endif
1388 #endif
1389 #endif
1390 
1391  if (NULL == (connection = malloc (sizeof (struct MHD_Connection))))
1392  {
1393  eno = errno;
1394 #if HAVE_MESSAGES
1395  MHD_DLOG (daemon,
1396  "Error allocating memory: %s\n",
1397  MHD_strerror_ (errno));
1398 #endif
1399  if (0 != MHD_socket_close_ (client_socket))
1400  MHD_PANIC ("close failed\n");
1401  MHD_ip_limit_del (daemon, addr, addrlen);
1402  errno = eno;
1403  return MHD_NO;
1404  }
1405  memset (connection,
1406  0,
1407  sizeof (struct MHD_Connection));
1408  connection->pool = MHD_pool_create (daemon->pool_size);
1409  if (NULL == connection->pool)
1410  {
1411 #if HAVE_MESSAGES
1412  MHD_DLOG (daemon,
1413  "Error allocating memory: %s\n",
1414  MHD_strerror_ (errno));
1415 #endif
1416  if (0 != MHD_socket_close_ (client_socket))
1417  MHD_PANIC ("close failed\n");
1418  MHD_ip_limit_del (daemon, addr, addrlen);
1419  free (connection);
1420 #if ENOMEM
1421  errno = ENOMEM;
1422 #endif
1423  return MHD_NO;
1424  }
1425 
1426  connection->connection_timeout = daemon->connection_timeout;
1427  if (NULL == (connection->addr = malloc (addrlen)))
1428  {
1429  eno = errno;
1430 #if HAVE_MESSAGES
1431  MHD_DLOG (daemon,
1432  "Error allocating memory: %s\n",
1433  MHD_strerror_ (errno));
1434 #endif
1435  if (0 != MHD_socket_close_ (client_socket))
1436  MHD_PANIC ("close failed\n");
1437  MHD_ip_limit_del (daemon, addr, addrlen);
1438  MHD_pool_destroy (connection->pool);
1439  free (connection);
1440  errno = eno;
1441  return MHD_NO;
1442  }
1443  memcpy (connection->addr, addr, addrlen);
1444  connection->addr_len = addrlen;
1445  connection->socket_fd = client_socket;
1446  connection->daemon = daemon;
1447  connection->last_activity = MHD_monotonic_sec_counter();
1448 
1449  /* set default connection handlers */
1450  MHD_set_http_callbacks_ (connection);
1451  connection->recv_cls = &recv_param_adapter;
1452  connection->send_cls = &send_param_adapter;
1453 
1454  if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
1455  {
1456  /* non-blocking sockets are required on most systems and for GNUtls;
1457  however, they somehow cause serious problems on CYGWIN (#1824);
1458  in turbo mode, we assume that non-blocking was already set
1459  by 'accept4' or whoever calls 'MHD_add_connection' */
1460 #ifdef CYGWIN
1461  if (0 != (daemon->options & MHD_USE_SSL))
1462 #endif
1463  {
1464  /* make socket non-blocking */
1465 #if !defined(MHD_WINSOCK_SOCKETS)
1466  int flags = fcntl (connection->socket_fd, F_GETFL);
1467  if ( (-1 == flags) ||
1468  (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
1469  {
1470 #if HAVE_MESSAGES
1471  MHD_DLOG (daemon,
1472  "Failed to make socket non-blocking: %s\n",
1474 #endif
1475  }
1476 #else
1477  unsigned long flags = 1;
1478  if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
1479  {
1480 #if HAVE_MESSAGES
1481  MHD_DLOG (daemon,
1482  "Failed to make socket non-blocking: %s\n",
1484 #endif
1485  }
1486 #endif
1487  }
1488  }
1489 
1490 #if HTTPS_SUPPORT
1491  if (0 != (daemon->options & MHD_USE_SSL))
1492  {
1493  connection->recv_cls = &recv_tls_adapter;
1494  connection->send_cls = &send_tls_adapter;
1495  connection->state = MHD_TLS_CONNECTION_INIT;
1496  MHD_set_https_callbacks (connection);
1497  gnutls_init (&connection->tls_session, GNUTLS_SERVER);
1498  gnutls_priority_set (connection->tls_session,
1499  daemon->priority_cache);
1500  switch (daemon->cred_type)
1501  {
1502  /* set needed credentials for certificate authentication. */
1503  case GNUTLS_CRD_CERTIFICATE:
1504  gnutls_credentials_set (connection->tls_session,
1505  GNUTLS_CRD_CERTIFICATE,
1506  daemon->x509_cred);
1507  break;
1508  default:
1509 #if HAVE_MESSAGES
1510  MHD_DLOG (connection->daemon,
1511  "Failed to setup TLS credentials: unknown credential type %d\n",
1512  daemon->cred_type);
1513 #endif
1514  if (0 != MHD_socket_close_ (client_socket))
1515  MHD_PANIC ("close failed\n");
1516  MHD_ip_limit_del (daemon, addr, addrlen);
1517  free (connection->addr);
1518  free (connection);
1519  MHD_PANIC ("Unknown credential type");
1520 #if EINVAL
1521  errno = EINVAL;
1522 #endif
1523  return MHD_NO;
1524  }
1525  gnutls_transport_set_ptr (connection->tls_session,
1526  (gnutls_transport_ptr_t) connection);
1527  gnutls_transport_set_pull_function (connection->tls_session,
1528  (gnutls_pull_func) &recv_param_adapter);
1529  gnutls_transport_set_push_function (connection->tls_session,
1530  (gnutls_push_func) &send_param_adapter);
1531 
1532  if (daemon->https_mem_trust)
1533  gnutls_certificate_server_set_request (connection->tls_session,
1534  GNUTLS_CERT_REQUEST);
1535  }
1536 #endif
1537 
1538  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1539  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1540  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1542  daemon->normal_timeout_tail,
1543  connection);
1544  DLL_insert (daemon->connections_head,
1545  daemon->connections_tail,
1546  connection);
1547  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1548  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1549  MHD_PANIC ("Failed to release cleanup mutex\n");
1550 
1551  if (NULL != daemon->notify_connection)
1552  daemon->notify_connection (daemon->notify_connection_cls,
1553  connection,
1554  &connection->socket_context,
1556 
1557  /* attempt to create handler thread */
1558  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1559  {
1560  res_thread_create = create_thread (&connection->pid,
1561  daemon,
1563  connection);
1564  if (0 != res_thread_create)
1565  {
1566  eno = errno;
1567 #if HAVE_MESSAGES
1568  MHD_DLOG (daemon,
1569  "Failed to create a thread: %s\n",
1570  MHD_strerror_ (res_thread_create));
1571 #endif
1572  goto cleanup;
1573  }
1574  }
1575  else
1576  if ( (MHD_YES == external_add) &&
1577  (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1578  (1 != MHD_pipe_write_ (daemon->wpipe[1], "n", 1)) )
1579  {
1580 #if HAVE_MESSAGES
1581  MHD_DLOG (daemon,
1582  "failed to signal new connection via pipe");
1583 #endif
1584  }
1585 #if EPOLL_SUPPORT
1586  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1587  {
1588  if (0 == (daemon->options & MHD_USE_EPOLL_TURBO))
1589  {
1590  struct epoll_event event;
1591 
1592  event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1593  event.data.ptr = connection;
1594  if (0 != epoll_ctl (daemon->epoll_fd,
1595  EPOLL_CTL_ADD,
1596  client_socket,
1597  &event))
1598  {
1599  eno = errno;
1600 #if HAVE_MESSAGES
1601  MHD_DLOG (daemon,
1602  "Call to epoll_ctl failed: %s\n",
1604 #endif
1605  goto cleanup;
1606  }
1607  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1608  }
1609  else
1610  {
1611  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
1613  EDLL_insert (daemon->eready_head,
1614  daemon->eready_tail,
1615  connection);
1616  }
1617  }
1618 #endif
1619  daemon->connections++;
1620  return MHD_YES;
1621  cleanup:
1622  if (NULL != daemon->notify_connection)
1623  daemon->notify_connection (daemon->notify_connection_cls,
1624  connection,
1625  &connection->socket_context,
1627  if (0 != MHD_socket_close_ (client_socket))
1628  MHD_PANIC ("close failed\n");
1629  MHD_ip_limit_del (daemon, addr, addrlen);
1630  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1631  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1632  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1633  DLL_remove (daemon->connections_head,
1634  daemon->connections_tail,
1635  connection);
1637  daemon->normal_timeout_tail,
1638  connection);
1639  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1640  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1641  MHD_PANIC ("Failed to release cleanup mutex\n");
1642  MHD_pool_destroy (connection->pool);
1643  free (connection->addr);
1644  free (connection);
1645 #if EINVAL
1646  errno = eno;
1647 #endif
1648  return MHD_NO;
1649 }
1650 
1651 
1679 void
1681 {
1682  struct MHD_Daemon *daemon;
1683 
1684  daemon = connection->daemon;
1686  MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1687  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1688  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1689  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1690  DLL_remove (daemon->connections_head,
1691  daemon->connections_tail,
1692  connection);
1695  connection);
1696  if (connection->connection_timeout == daemon->connection_timeout)
1698  daemon->normal_timeout_tail,
1699  connection);
1700  else
1702  daemon->manual_timeout_tail,
1703  connection);
1704 #if EPOLL_SUPPORT
1705  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1706  {
1707  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1708  {
1709  EDLL_remove (daemon->eready_head,
1710  daemon->eready_tail,
1711  connection);
1712  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
1713  }
1714  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
1715  {
1716  if (0 != epoll_ctl (daemon->epoll_fd,
1717  EPOLL_CTL_DEL,
1718  connection->socket_fd,
1719  NULL))
1720  MHD_PANIC ("Failed to remove FD from epoll set\n");
1721  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1722  }
1723  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
1724  }
1725 #endif
1726  connection->suspended = MHD_YES;
1727  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1728  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1729  MHD_PANIC ("Failed to release cleanup mutex\n");
1730 }
1731 
1732 
1741 void
1743 {
1744  struct MHD_Daemon *daemon;
1745 
1746  daemon = connection->daemon;
1748  MHD_PANIC ("Cannot resume connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1749  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1750  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1751  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1752  connection->resuming = MHD_YES;
1753  daemon->resuming = MHD_YES;
1754  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1755  (1 != MHD_pipe_write_ (daemon->wpipe[1], "r", 1)) )
1756  {
1757 #if HAVE_MESSAGES
1758  MHD_DLOG (daemon,
1759  "failed to signal resume via pipe");
1760 #endif
1761  }
1762  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1763  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1764  MHD_PANIC ("Failed to release cleanup mutex\n");
1765 }
1766 
1767 
1775 static int
1777 {
1778  struct MHD_Connection *pos;
1779  struct MHD_Connection *next = NULL;
1780  int ret;
1781 
1782  ret = MHD_NO;
1783  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1784  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1785  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1786  if (MHD_YES == daemon->resuming)
1787  next = daemon->suspended_connections_head;
1788 
1789  while (NULL != (pos = next))
1790  {
1791  next = pos->next;
1792  if (MHD_NO == pos->resuming)
1793  continue;
1794  ret = MHD_YES;
1797  pos);
1798  DLL_insert (daemon->connections_head,
1799  daemon->connections_tail,
1800  pos);
1801  if (pos->connection_timeout == daemon->connection_timeout)
1803  daemon->normal_timeout_tail,
1804  pos);
1805  else
1807  daemon->manual_timeout_tail,
1808  pos);
1809 #if EPOLL_SUPPORT
1810  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1811  {
1812  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1813  MHD_PANIC ("Resumed connection was already in EREADY set\n");
1814  /* we always mark resumed connections as ready, as we
1815  might have missed the edge poll event during suspension */
1816  EDLL_insert (daemon->eready_head,
1817  daemon->eready_tail,
1818  pos);
1819  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
1820  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
1821  }
1822 #endif
1823  pos->suspended = MHD_NO;
1824  pos->resuming = MHD_NO;
1825  }
1826  daemon->resuming = MHD_NO;
1827  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1828  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1829  MHD_PANIC ("Failed to release cleanup mutex\n");
1830  return ret;
1831 }
1832 
1833 
1840 static void
1842  MHD_socket sock)
1843 {
1844 #ifdef MHD_WINSOCK_SOCKETS
1845  DWORD dwFlags;
1846  unsigned long flags = 1;
1847 
1848  if (0 != ioctlsocket (sock, FIONBIO, &flags))
1849  {
1850 #if HAVE_MESSAGES
1851  MHD_DLOG (daemon,
1852  "Failed to make socket non-blocking: %s\n",
1854 #endif
1855  }
1856  if (!GetHandleInformation ((HANDLE) sock, &dwFlags) ||
1857  ((dwFlags != (dwFlags & ~HANDLE_FLAG_INHERIT)) &&
1858  !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)))
1859  {
1860 #if HAVE_MESSAGES
1861  MHD_DLOG (daemon,
1862  "Failed to make socket non-inheritable: %u\n",
1863  (unsigned int) GetLastError ());
1864 #endif
1865  }
1866 #else
1867  int flags;
1868  int nonblock;
1869 
1870  nonblock = O_NONBLOCK;
1871 #ifdef CYGWIN
1872  if (0 == (daemon->options & MHD_USE_SSL))
1873  nonblock = 0;
1874 #endif
1875  flags = fcntl (sock, F_GETFD);
1876  if ( ( (-1 == flags) ||
1877  ( (flags != (flags | FD_CLOEXEC)) &&
1878  (0 != fcntl (sock, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) )
1879  {
1880 #if HAVE_MESSAGES
1881  MHD_DLOG (daemon,
1882  "Failed to make socket non-inheritable: %s\n",
1884 #endif
1885  }
1886 #endif
1887 }
1888 
1889 
1919 int
1921  MHD_socket client_socket,
1922  const struct sockaddr *addr,
1923  socklen_t addrlen)
1924 {
1926  client_socket);
1927  return internal_add_connection (daemon,
1928  client_socket,
1929  addr, addrlen,
1930  MHD_YES);
1931 }
1932 
1933 
1946 static int
1948 {
1949 #if HAVE_INET6
1950  struct sockaddr_in6 addrstorage;
1951 #else
1952  struct sockaddr_in addrstorage;
1953 #endif
1954  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
1955  socklen_t addrlen;
1956  MHD_socket s;
1957  MHD_socket fd;
1958  int nonblock;
1959 
1960  addrlen = sizeof (addrstorage);
1961  memset (addr, 0, sizeof (addrstorage));
1962  if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd))
1963  return MHD_NO;
1964 #ifdef HAVE_SOCK_NONBLOCK
1965  nonblock = SOCK_NONBLOCK;
1966 #else
1967  nonblock = 0;
1968 #endif
1969 #ifdef CYGWIN
1970  if (0 == (daemon->options & MHD_USE_SSL))
1971  nonblock = 0;
1972 #endif
1973 #if HAVE_ACCEPT4
1974  s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock);
1975 #else
1976  s = accept (fd, addr, &addrlen);
1977 #endif
1978  if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0))
1979  {
1980 #if HAVE_MESSAGES
1981  const int err = MHD_socket_errno_;
1982  /* This could be a common occurance with multiple worker threads */
1983  if ( (EINVAL == err) &&
1984  (MHD_INVALID_SOCKET == daemon->socket_fd) )
1985  return MHD_NO; /* can happen during shutdown */
1986  if ((EAGAIN != err) && (EWOULDBLOCK != err))
1987  MHD_DLOG (daemon,
1988  "Error accepting connection: %s\n",
1990 #endif
1991  if (MHD_INVALID_SOCKET != s)
1992  {
1993  if (0 != MHD_socket_close_ (s))
1994  MHD_PANIC ("close failed\n");
1995  /* just in case */
1996  }
1997  return MHD_NO;
1998  }
1999 #if !defined(HAVE_ACCEPT4) || HAVE_ACCEPT4+0 == 0 || !defined(HAVE_SOCK_NONBLOCK) || SOCK_CLOEXEC+0 == 0
2000  make_nonblocking_noninheritable (daemon, s);
2001 #endif
2002 #if HAVE_MESSAGES
2003 #if DEBUG_CONNECT
2004  MHD_DLOG (daemon,
2005  "Accepted connection on socket %d\n",
2006  s);
2007 #endif
2008 #endif
2009  (void) internal_add_connection (daemon, s,
2010  addr, addrlen,
2011  MHD_NO);
2012  return MHD_YES;
2013 }
2014 
2015 
2023 static void
2025 {
2026  struct MHD_Connection *pos;
2027 
2028  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2029  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
2030  MHD_PANIC ("Failed to acquire cleanup mutex\n");
2031  while (NULL != (pos = daemon->cleanup_head))
2032  {
2033  DLL_remove (daemon->cleanup_head,
2034  daemon->cleanup_tail,
2035  pos);
2036  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2037  (MHD_NO == pos->thread_joined) )
2038  {
2039  if (0 != MHD_join_thread_ (pos->pid))
2040  {
2041  MHD_PANIC ("Failed to join a thread\n");
2042  }
2043  }
2044  MHD_pool_destroy (pos->pool);
2045 #if HTTPS_SUPPORT
2046  if (NULL != pos->tls_session)
2047  gnutls_deinit (pos->tls_session);
2048 #endif
2049  daemon->connections--;
2050  if (NULL != daemon->notify_connection)
2051  daemon->notify_connection (daemon->notify_connection_cls,
2052  pos,
2053  &pos->socket_context,
2055  MHD_ip_limit_del (daemon, pos->addr, pos->addr_len);
2056 #if EPOLL_SUPPORT
2057  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
2058  {
2059  EDLL_remove (daemon->eready_head,
2060  daemon->eready_tail,
2061  pos);
2062  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2063  }
2064  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2065  (MHD_INVALID_SOCKET != daemon->epoll_fd) &&
2066  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
2067  {
2068  /* epoll documentation suggests that closing a FD
2069  automatically removes it from the epoll set; however,
2070  this is not true as if we fail to do manually remove it,
2071  we are still seeing an event for this fd in epoll,
2072  causing grief (use-after-free...) --- at least on my
2073  system. */
2074  if (0 != epoll_ctl (daemon->epoll_fd,
2075  EPOLL_CTL_DEL,
2076  pos->socket_fd,
2077  NULL))
2078  MHD_PANIC ("Failed to remove FD from epoll set\n");
2079  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
2080  }
2081 #endif
2082  if (NULL != pos->response)
2083  {
2085  pos->response = NULL;
2086  }
2087  if (MHD_INVALID_SOCKET != pos->socket_fd)
2088  {
2089 #ifdef WINDOWS
2090  shutdown (pos->socket_fd, SHUT_WR);
2091 #endif
2092  if (0 != MHD_socket_close_ (pos->socket_fd))
2093  MHD_PANIC ("close failed\n");
2094  }
2095  if (NULL != pos->addr)
2096  free (pos->addr);
2097  free (pos);
2098  }
2099  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2100  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
2101  MHD_PANIC ("Failed to release cleanup mutex\n");
2102 }
2103 
2104 
2119 int
2120 MHD_get_timeout (struct MHD_Daemon *daemon,
2121  MHD_UNSIGNED_LONG_LONG *timeout)
2122 {
2123  time_t earliest_deadline;
2124  time_t now;
2125  struct MHD_Connection *pos;
2126  int have_timeout;
2127 
2128  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2129  {
2130 #if HAVE_MESSAGES
2131  MHD_DLOG (daemon,
2132  "Illegal call to MHD_get_timeout\n");
2133 #endif
2134  return MHD_NO;
2135  }
2136 
2137 #if HTTPS_SUPPORT
2138  if (0 != daemon->num_tls_read_ready)
2139  {
2140  /* if there is any TLS connection with data ready for
2141  reading, we must not block in the event loop */
2142  *timeout = 0;
2143  return MHD_YES;
2144  }
2145 #endif
2146 
2147  have_timeout = MHD_NO;
2148  earliest_deadline = 0; /* avoid compiler warnings */
2149  for (pos = daemon->manual_timeout_head; NULL != pos; pos = pos->nextX)
2150  {
2151  if (0 != pos->connection_timeout)
2152  {
2153  if ( (! have_timeout) ||
2154  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
2155  earliest_deadline = pos->last_activity + pos->connection_timeout;
2156 #if HTTPS_SUPPORT
2157  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
2158  (0 != gnutls_record_check_pending (pos->tls_session)) )
2159  earliest_deadline = 0;
2160 #endif
2161  have_timeout = MHD_YES;
2162  }
2163  }
2164  /* normal timeouts are sorted, so we only need to look at the 'head' */
2165  pos = daemon->normal_timeout_head;
2166  if ( (NULL != pos) &&
2167  (0 != pos->connection_timeout) )
2168  {
2169  if ( (! have_timeout) ||
2170  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
2171  earliest_deadline = pos->last_activity + pos->connection_timeout;
2172 #if HTTPS_SUPPORT
2173  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
2174  (0 != gnutls_record_check_pending (pos->tls_session)) )
2175  earliest_deadline = 0;
2176 #endif
2177  have_timeout = MHD_YES;
2178  }
2179 
2180  if (MHD_NO == have_timeout)
2181  return MHD_NO;
2182  now = MHD_monotonic_sec_counter();
2183  if (earliest_deadline < now)
2184  *timeout = 0;
2185  else
2186  {
2187  const time_t second_left = earliest_deadline - now;
2188  if (second_left > ULLONG_MAX / 1000)
2189  *timeout = ULLONG_MAX;
2190  else
2191  *timeout = 1000 * second_left;
2192  }
2193  return MHD_YES;
2194 }
2195 
2196 
2216 int
2218  const fd_set *read_fd_set,
2219  const fd_set *write_fd_set,
2220  const fd_set *except_fd_set)
2221 {
2222  MHD_socket ds;
2223  char tmp;
2224  struct MHD_Connection *pos;
2225  struct MHD_Connection *next;
2228 
2229  /* Resuming external connections when using an extern mainloop */
2230  if (MHD_USE_SUSPEND_RESUME == (daemon->options & mask))
2232 
2233 #if EPOLL_SUPPORT
2234  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2235  {
2236  /* we're in epoll mode, the epoll FD stands for
2237  the entire event set! */
2238  if (daemon->epoll_fd >= FD_SETSIZE)
2239  return MHD_NO; /* poll fd too big, fail hard */
2240  if (FD_ISSET (daemon->epoll_fd, read_fd_set))
2241  return MHD_run (daemon);
2242  return MHD_YES;
2243  }
2244 #endif
2245 
2246  /* select connection thread handling type */
2247  if ( (MHD_INVALID_SOCKET != (ds = daemon->socket_fd)) &&
2248  (FD_ISSET (ds, read_fd_set)) )
2249  (void) MHD_accept_connection (daemon);
2250  /* drain signaling pipe to avoid spinning select */
2251  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2252  (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
2253  (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2254 
2255  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2256  {
2257  /* do not have a thread per connection, process all connections now */
2258  next = daemon->connections_head;
2259  while (NULL != (pos = next))
2260  {
2261  next = pos->next;
2262  ds = pos->socket_fd;
2263  if (MHD_INVALID_SOCKET == ds)
2264  continue;
2265  switch (pos->event_loop_info)
2266  {
2268  if ( (FD_ISSET (ds, read_fd_set))
2269 #if HTTPS_SUPPORT
2270  || (MHD_YES == pos->tls_read_ready)
2271 #endif
2272  )
2273  pos->read_handler (pos);
2274  break;
2276  if ( (FD_ISSET (ds, read_fd_set)) &&
2277  (pos->read_buffer_size > pos->read_buffer_offset) )
2278  pos->read_handler (pos);
2279  if (FD_ISSET (ds, write_fd_set))
2280  pos->write_handler (pos);
2281  break;
2283  if ( (FD_ISSET (ds, read_fd_set)) &&
2284  (pos->read_buffer_size > pos->read_buffer_offset) )
2285  pos->read_handler (pos);
2286  break;
2288  /* should never happen */
2289  break;
2290  }
2291  pos->idle_handler (pos);
2292  }
2293  }
2294  MHD_cleanup_connections (daemon);
2295  return MHD_YES;
2296 }
2297 
2298 
2307 static int
2308 MHD_select (struct MHD_Daemon *daemon,
2309  int may_block)
2310 {
2311  int num_ready;
2312  fd_set rs;
2313  fd_set ws;
2314  fd_set es;
2315  MHD_socket max;
2316  struct timeval timeout;
2317  struct timeval *tv;
2318  MHD_UNSIGNED_LONG_LONG ltimeout;
2319 
2320  timeout.tv_sec = 0;
2321  timeout.tv_usec = 0;
2322  if (MHD_YES == daemon->shutdown)
2323  return MHD_NO;
2324  FD_ZERO (&rs);
2325  FD_ZERO (&ws);
2326  FD_ZERO (&es);
2327  max = MHD_INVALID_SOCKET;
2328  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2329  {
2330  if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) &&
2331  (MHD_YES == resume_suspended_connections (daemon)) )
2332  may_block = MHD_NO;
2333 
2334  /* single-threaded, go over everything */
2335  if (MHD_NO == MHD_get_fdset2 (daemon, &rs, &ws, &es, &max, FD_SETSIZE))
2336  return MHD_NO;
2337 
2338  /* If we're at the connection limit, no need to
2339  accept new connections; however, make sure
2340  we do not miss the shutdown, so only do this
2341  optimization if we have a shutdown signaling
2342  pipe. */
2343  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2344  (daemon->connections == daemon->connection_limit) &&
2345  (0 != (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) )
2346  FD_CLR (daemon->socket_fd, &rs);
2347  }
2348  else
2349  {
2350  /* accept only, have one thread per connection */
2351  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2352  (MHD_YES != add_to_fd_set (daemon->socket_fd,
2353  &rs,
2354  &max,
2355  FD_SETSIZE)) )
2356  return MHD_NO;
2357  }
2358  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2359  (MHD_YES != add_to_fd_set (daemon->wpipe[0],
2360  &rs,
2361  &max,
2362  FD_SETSIZE)) )
2363  return MHD_NO;
2364 
2365  tv = NULL;
2366  if (MHD_NO == may_block)
2367  {
2368  timeout.tv_usec = 0;
2369  timeout.tv_sec = 0;
2370  tv = &timeout;
2371  }
2372  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2373  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
2374  {
2375  /* ltimeout is in ms */
2376  timeout.tv_usec = (ltimeout % 1000) * 1000;
2377  if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
2378  timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
2379  else
2380  timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000);
2381  tv = &timeout;
2382  }
2383  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, &es, tv);
2384  if (MHD_YES == daemon->shutdown)
2385  return MHD_NO;
2386  if (num_ready < 0)
2387  {
2388  if (EINTR == MHD_socket_errno_)
2389  return MHD_YES;
2390 #if HAVE_MESSAGES
2391  MHD_DLOG (daemon,
2392  "select failed: %s\n",
2394 #endif
2395  return MHD_NO;
2396  }
2397  return MHD_run_from_select (daemon, &rs, &ws, &es);
2398 }
2399 
2400 
2401 #ifdef HAVE_POLL
2402 
2410 static int
2411 MHD_poll_all (struct MHD_Daemon *daemon,
2412  int may_block)
2413 {
2414  unsigned int num_connections;
2415  struct MHD_Connection *pos;
2416  struct MHD_Connection *next;
2417 
2418  if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) &&
2419  (MHD_YES == resume_suspended_connections (daemon)) )
2420  may_block = MHD_NO;
2421 
2422  /* count number of connections and thus determine poll set size */
2423  num_connections = 0;
2424  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2425  num_connections++;
2426  {
2427  MHD_UNSIGNED_LONG_LONG ltimeout;
2428  unsigned int i;
2429  int timeout;
2430  unsigned int poll_server;
2431  int poll_listen;
2432  int poll_pipe;
2433  char tmp;
2434  struct pollfd *p;
2435 
2436  p = malloc(sizeof (struct pollfd) * (2 + num_connections));
2437  if (NULL == p)
2438  {
2439 #if HAVE_MESSAGES
2440  MHD_DLOG(daemon,
2441  "Error allocating memory: %s\n",
2442  MHD_strerror_(errno));
2443 #endif
2444  return MHD_NO;
2445  }
2446  memset (p, 0, sizeof (struct pollfd) * (2 + num_connections));
2447  poll_server = 0;
2448  poll_listen = -1;
2449  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2450  (daemon->connections < daemon->connection_limit) )
2451  {
2452  /* only listen if we are not at the connection limit */
2453  p[poll_server].fd = daemon->socket_fd;
2454  p[poll_server].events = POLLIN;
2455  p[poll_server].revents = 0;
2456  poll_listen = (int) poll_server;
2457  poll_server++;
2458  }
2459  poll_pipe = -1;
2460  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2461  {
2462  p[poll_server].fd = daemon->wpipe[0];
2463  p[poll_server].events = POLLIN;
2464  p[poll_server].revents = 0;
2465  poll_pipe = (int) poll_server;
2466  poll_server++;
2467  }
2468  if (may_block == MHD_NO)
2469  timeout = 0;
2470  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2471  (MHD_YES != MHD_get_timeout (daemon, &ltimeout)) )
2472  timeout = -1;
2473  else
2474  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
2475 
2476  i = 0;
2477  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2478  {
2479  p[poll_server+i].fd = pos->socket_fd;
2480  switch (pos->event_loop_info)
2481  {
2483  p[poll_server+i].events |= POLLIN;
2484  break;
2486  p[poll_server+i].events |= POLLOUT;
2487  if (pos->read_buffer_size > pos->read_buffer_offset)
2488  p[poll_server+i].events |= POLLIN;
2489  break;
2491  if (pos->read_buffer_size > pos->read_buffer_offset)
2492  p[poll_server+i].events |= POLLIN;
2493  break;
2495  timeout = 0; /* clean up "pos" immediately */
2496  break;
2497  }
2498  i++;
2499  }
2500  if (0 == poll_server + num_connections)
2501  {
2502  free(p);
2503  return MHD_YES;
2504  }
2505  if (MHD_sys_poll_(p, poll_server + num_connections, timeout) < 0)
2506  {
2507  if (EINTR == MHD_socket_errno_)
2508  {
2509  free(p);
2510  return MHD_YES;
2511  }
2512 #if HAVE_MESSAGES
2513  MHD_DLOG (daemon,
2514  "poll failed: %s\n",
2516 #endif
2517  free(p);
2518  return MHD_NO;
2519  }
2520  /* handle shutdown */
2521  if (MHD_YES == daemon->shutdown)
2522  {
2523  free(p);
2524  return MHD_NO;
2525  }
2526  i = 0;
2527  next = daemon->connections_head;
2528  while (NULL != (pos = next))
2529  {
2530  next = pos->next;
2531  switch (pos->event_loop_info)
2532  {
2534  /* first, sanity checks */
2535  if (i >= num_connections)
2536  break; /* connection list changed somehow, retry later ... */
2537  if (p[poll_server+i].fd != pos->socket_fd)
2538  break; /* fd mismatch, something else happened, retry later ... */
2539  /* normal handling */
2540  if (0 != (p[poll_server+i].revents & POLLIN))
2541  pos->read_handler (pos);
2542  pos->idle_handler (pos);
2543  i++;
2544  break;
2546  /* first, sanity checks */
2547  if (i >= num_connections)
2548  break; /* connection list changed somehow, retry later ... */
2549  if (p[poll_server+i].fd != pos->socket_fd)
2550  break; /* fd mismatch, something else happened, retry later ... */
2551  /* normal handling */
2552  if (0 != (p[poll_server+i].revents & POLLIN))
2553  pos->read_handler (pos);
2554  if (0 != (p[poll_server+i].revents & POLLOUT))
2555  pos->write_handler (pos);
2556  pos->idle_handler (pos);
2557  i++;
2558  break;
2560  if (0 != (p[poll_server+i].revents & POLLIN))
2561  pos->read_handler (pos);
2562  pos->idle_handler (pos);
2563  break;
2565  pos->idle_handler (pos);
2566  break;
2567  }
2568  }
2569  /* handle 'listen' FD */
2570  if ( (-1 != poll_listen) &&
2571  (0 != (p[poll_listen].revents & POLLIN)) )
2572  (void) MHD_accept_connection (daemon);
2573 
2574  /* handle pipe FD */
2575  if ( (-1 != poll_pipe) &&
2576  (0 != (p[poll_pipe].revents & POLLIN)) )
2577  (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2578 
2579  free(p);
2580  }
2581  return MHD_YES;
2582 }
2583 
2584 
2592 static int
2593 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2594  int may_block)
2595 {
2596  struct pollfd p[2];
2597  int timeout;
2598  unsigned int poll_count;
2599  int poll_listen;
2600 
2601  memset (&p, 0, sizeof (p));
2602  poll_count = 0;
2603  poll_listen = -1;
2604  if (MHD_INVALID_SOCKET != daemon->socket_fd)
2605  {
2606  p[poll_count].fd = daemon->socket_fd;
2607  p[poll_count].events = POLLIN;
2608  p[poll_count].revents = 0;
2609  poll_listen = poll_count;
2610  poll_count++;
2611  }
2612  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2613  {
2614  p[poll_count].fd = daemon->wpipe[0];
2615  p[poll_count].events = POLLIN;
2616  p[poll_count].revents = 0;
2617  poll_count++;
2618  }
2619  if (MHD_NO == may_block)
2620  timeout = 0;
2621  else
2622  timeout = -1;
2623  if (0 == poll_count)
2624  return MHD_YES;
2625  if (MHD_sys_poll_(p, poll_count, timeout) < 0)
2626  {
2627  if (EINTR == MHD_socket_errno_)
2628  return MHD_YES;
2629 #if HAVE_MESSAGES
2630  MHD_DLOG (daemon,
2631  "poll failed: %s\n",
2633 #endif
2634  return MHD_NO;
2635  }
2636  /* handle shutdown */
2637  if (MHD_YES == daemon->shutdown)
2638  return MHD_NO;
2639  if ( (-1 != poll_listen) &&
2640  (0 != (p[poll_listen].revents & POLLIN)) )
2641  (void) MHD_accept_connection (daemon);
2642  return MHD_YES;
2643 }
2644 #endif
2645 
2646 
2654 static int
2655 MHD_poll (struct MHD_Daemon *daemon,
2656  int may_block)
2657 {
2658 #ifdef HAVE_POLL
2659  if (MHD_YES == daemon->shutdown)
2660  return MHD_NO;
2661  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2662  return MHD_poll_all (daemon, may_block);
2663  else
2664  return MHD_poll_listen_socket (daemon, may_block);
2665 #else
2666  return MHD_NO;
2667 #endif
2668 }
2669 
2670 
2671 #if EPOLL_SUPPORT
2672 
2681 #define MAX_EVENTS 128
2682 
2683 
2692 static int
2693 MHD_epoll (struct MHD_Daemon *daemon,
2694  int may_block)
2695 {
2696  struct MHD_Connection *pos;
2697  struct MHD_Connection *next;
2698  struct epoll_event events[MAX_EVENTS];
2699  struct epoll_event event;
2700  int timeout_ms;
2701  MHD_UNSIGNED_LONG_LONG timeout_ll;
2702  int num_events;
2703  unsigned int i;
2704  unsigned int series_length;
2705  char tmp;
2706 
2707  if (-1 == daemon->epoll_fd)
2708  return MHD_NO; /* we're down! */
2709  if (MHD_YES == daemon->shutdown)
2710  return MHD_NO;
2711  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2712  (daemon->connections < daemon->connection_limit) &&
2713  (MHD_NO == daemon->listen_socket_in_epoll) )
2714  {
2715  event.events = EPOLLIN;
2716  event.data.ptr = daemon;
2717  if (0 != epoll_ctl (daemon->epoll_fd,
2718  EPOLL_CTL_ADD,
2719  daemon->socket_fd,
2720  &event))
2721  {
2722 #if HAVE_MESSAGES
2723  MHD_DLOG (daemon,
2724  "Call to epoll_ctl failed: %s\n",
2726 #endif
2727  return MHD_NO;
2728  }
2729  daemon->listen_socket_in_epoll = MHD_YES;
2730  }
2731  if ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2732  (daemon->connections == daemon->connection_limit) )
2733  {
2734  /* we're at the connection limit, disable listen socket
2735  for event loop for now */
2736  if (0 != epoll_ctl (daemon->epoll_fd,
2737  EPOLL_CTL_DEL,
2738  daemon->socket_fd,
2739  NULL))
2740  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2741  daemon->listen_socket_in_epoll = MHD_NO;
2742  }
2743  if (MHD_YES == may_block)
2744  {
2745  if (MHD_YES == MHD_get_timeout (daemon,
2746  &timeout_ll))
2747  {
2748  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
2749  timeout_ms = INT_MAX;
2750  else
2751  timeout_ms = (int) timeout_ll;
2752  }
2753  else
2754  timeout_ms = -1;
2755  }
2756  else
2757  timeout_ms = 0;
2758 
2759  /* drain 'epoll' event queue; need to iterate as we get at most
2760  MAX_EVENTS in one system call here; in practice this should
2761  pretty much mean only one round, but better an extra loop here
2762  than unfair behavior... */
2763  num_events = MAX_EVENTS;
2764  while (MAX_EVENTS == num_events)
2765  {
2766  /* update event masks */
2767  num_events = epoll_wait (daemon->epoll_fd,
2768  events, MAX_EVENTS, timeout_ms);
2769  if (-1 == num_events)
2770  {
2771  if (EINTR == MHD_socket_errno_)
2772  return MHD_YES;
2773 #if HAVE_MESSAGES
2774  MHD_DLOG (daemon,
2775  "Call to epoll_wait failed: %s\n",
2777 #endif
2778  return MHD_NO;
2779  }
2780  for (i=0;i<(unsigned int) num_events;i++)
2781  {
2782  if (NULL == events[i].data.ptr)
2783  continue; /* shutdown signal! */
2784  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2785  (daemon->wpipe[0] == events[i].data.fd) )
2786  {
2787  (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2788  continue;
2789  }
2790  if (daemon != events[i].data.ptr)
2791  {
2792  /* this is an event relating to a 'normal' connection,
2793  remember the event and if appropriate mark the
2794  connection as 'eready'. */
2795  pos = events[i].data.ptr;
2796  if (0 != (events[i].events & EPOLLIN))
2797  {
2798  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
2799  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
2800  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
2801  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2802  {
2803  EDLL_insert (daemon->eready_head,
2804  daemon->eready_tail,
2805  pos);
2806  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2807  }
2808  }
2809  if (0 != (events[i].events & EPOLLOUT))
2810  {
2811  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
2812  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
2813  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2814  {
2815  EDLL_insert (daemon->eready_head,
2816  daemon->eready_tail,
2817  pos);
2818  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2819  }
2820  }
2821  }
2822  else /* must be listen socket */
2823  {
2824  /* run 'accept' until it fails or we are not allowed to take
2825  on more connections */
2826  series_length = 0;
2827  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2828  (daemon->connections < daemon->connection_limit) &&
2829  (series_length < 128) )
2830  series_length++;
2831  }
2832  }
2833  }
2834 
2835  /* we handle resumes here because we may have ready connections
2836  that will not be placed into the epoll list immediately. */
2837  if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) &&
2838  (MHD_YES == resume_suspended_connections (daemon)) )
2839  may_block = MHD_NO;
2840 
2841  /* process events for connections */
2842  while (NULL != (pos = daemon->eready_tail))
2843  {
2844  EDLL_remove (daemon->eready_head,
2845  daemon->eready_tail,
2846  pos);
2847  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2849  pos->read_handler (pos);
2851  pos->write_handler (pos);
2852  pos->idle_handler (pos);
2853  }
2854 
2855  /* Finally, handle timed-out connections; we need to do this here
2856  as the epoll mechanism won't call the 'idle_handler' on everything,
2857  as the other event loops do. As timeouts do not get an explicit
2858  event, we need to find those connections that might have timed out
2859  here.
2860 
2861  Connections with custom timeouts must all be looked at, as we
2862  do not bother to sort that (presumably very short) list. */
2863  next = daemon->manual_timeout_head;
2864  while (NULL != (pos = next))
2865  {
2866  next = pos->nextX;
2867  pos->idle_handler (pos);
2868  }
2869  /* Connections with the default timeout are sorted by prepending
2870  them to the head of the list whenever we touch the connection;
2871  thus it sufficies to iterate from the tail until the first
2872  connection is NOT timed out */
2873  next = daemon->normal_timeout_tail;
2874  while (NULL != (pos = next))
2875  {
2876  next = pos->prevX;
2877  pos->idle_handler (pos);
2878  if (MHD_CONNECTION_CLOSED != pos->state)
2879  break; /* sorted by timeout, no need to visit the rest! */
2880  }
2881  return MHD_YES;
2882 }
2883 #endif
2884 
2885 
2905 int
2906 MHD_run (struct MHD_Daemon *daemon)
2907 {
2908  if ( (MHD_YES == daemon->shutdown) ||
2909  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2910  (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2911  return MHD_NO;
2912  if (0 != (daemon->options & MHD_USE_POLL))
2913  {
2914  MHD_poll (daemon, MHD_NO);
2915  MHD_cleanup_connections (daemon);
2916  }
2917 #if EPOLL_SUPPORT
2918  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2919  {
2920  MHD_epoll (daemon, MHD_NO);
2921  MHD_cleanup_connections (daemon);
2922  }
2923 #endif
2924  else
2925  {
2926  MHD_select (daemon, MHD_NO);
2927  /* MHD_select does MHD_cleanup_connections already */
2928  }
2929  return MHD_YES;
2930 }
2931 
2932 
2940 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
2942 {
2943  struct MHD_Daemon *daemon = cls;
2944 
2945  while (MHD_YES != daemon->shutdown)
2946  {
2947  if (0 != (daemon->options & MHD_USE_POLL))
2948  MHD_poll (daemon, MHD_YES);
2949 #if EPOLL_SUPPORT
2950  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2951  MHD_epoll (daemon, MHD_YES);
2952 #endif
2953  else
2954  MHD_select (daemon, MHD_YES);
2955  MHD_cleanup_connections (daemon);
2956  }
2957  return (MHD_THRD_RTRN_TYPE_)0;
2958 }
2959 
2960 
2972 static size_t
2973 unescape_wrapper (void *cls,
2974  struct MHD_Connection *connection,
2975  char *val)
2976 {
2977  return MHD_http_unescape (val);
2978 }
2979 
2980 
2997 struct MHD_Daemon *
2998 MHD_start_daemon (unsigned int flags,
2999  uint16_t port,
3001  void *apc_cls,
3002  MHD_AccessHandlerCallback dh, void *dh_cls, ...)
3003 {
3004  struct MHD_Daemon *daemon;
3005  va_list ap;
3006 
3007  va_start (ap, dh_cls);
3008  daemon = MHD_start_daemon_va (flags, port, apc, apc_cls, dh, dh_cls, ap);
3009  va_end (ap);
3010  return daemon;
3011 }
3012 
3013 
3033 MHD_socket
3035 {
3036  unsigned int i;
3037  MHD_socket ret;
3038 
3039  ret = daemon->socket_fd;
3040  if (MHD_INVALID_SOCKET == ret)
3041  return MHD_INVALID_SOCKET;
3042  if ( (MHD_INVALID_PIPE_ == daemon->wpipe[1]) &&
3044  {
3045 #if HAVE_MESSAGES
3046  MHD_DLOG (daemon,
3047  "Using MHD_quiesce_daemon in this mode requires MHD_USE_PIPE_FOR_SHUTDOWN\n");
3048 #endif
3049  return MHD_INVALID_SOCKET;
3050  }
3051 
3052  if (NULL != daemon->worker_pool)
3053  for (i = 0; i < daemon->worker_pool_size; i++)
3054  {
3056 #if EPOLL_SUPPORT
3057  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3058  (-1 != daemon->worker_pool[i].epoll_fd) &&
3059  (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) )
3060  {
3061  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
3062  EPOLL_CTL_DEL,
3063  ret,
3064  NULL))
3065  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
3066  daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO;
3067  }
3068 #endif
3069  }
3070  daemon->socket_fd = MHD_INVALID_SOCKET;
3071 #if EPOLL_SUPPORT
3072  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3073  (-1 != daemon->epoll_fd) &&
3074  (MHD_YES == daemon->listen_socket_in_epoll) )
3075  {
3076  if (0 != epoll_ctl (daemon->epoll_fd,
3077  EPOLL_CTL_DEL,
3078  ret,
3079  NULL))
3080  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
3081  daemon->listen_socket_in_epoll = MHD_NO;
3082  }
3083 #endif
3084  return ret;
3085 }
3086 
3087 
3095 typedef void (*VfprintfFunctionPointerType)(void *cls,
3096  const char *format,
3097  va_list va);
3098 
3099 
3108 static int
3109 parse_options_va (struct MHD_Daemon *daemon,
3110  const struct sockaddr **servaddr,
3111  va_list ap);
3112 
3113 
3122 static int
3123 parse_options (struct MHD_Daemon *daemon,
3124  const struct sockaddr **servaddr,
3125  ...)
3126 {
3127  va_list ap;
3128  int ret;
3129 
3130  va_start (ap, servaddr);
3131  ret = parse_options_va (daemon, servaddr, ap);
3132  va_end (ap);
3133  return ret;
3134 }
3135 
3136 
3145 static int
3147  const struct sockaddr **servaddr,
3148  va_list ap)
3149 {
3150  enum MHD_OPTION opt;
3151  struct MHD_OptionItem *oa;
3152  unsigned int i;
3153 #if HTTPS_SUPPORT
3154  int ret;
3155  const char *pstr;
3156 #endif
3157 
3158  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
3159  {
3160  switch (opt)
3161  {
3163  daemon->pool_size = va_arg (ap, size_t);
3164  break;
3166  daemon->pool_increment= va_arg (ap, size_t);
3167  break;
3169  daemon->connection_limit = va_arg (ap, unsigned int);
3170  break;
3172  daemon->connection_timeout = va_arg (ap, unsigned int);
3173  break;
3175  daemon->notify_completed =
3176  va_arg (ap, MHD_RequestCompletedCallback);
3177  daemon->notify_completed_cls = va_arg (ap, void *);
3178  break;
3180  daemon->notify_connection =
3181  va_arg (ap, MHD_NotifyConnectionCallback);
3182  daemon->notify_connection_cls = va_arg (ap, void *);
3183  break;
3185  daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
3186  break;
3187  case MHD_OPTION_SOCK_ADDR:
3188  *servaddr = va_arg (ap, const struct sockaddr *);
3189  break;
3191  daemon->uri_log_callback =
3192  va_arg (ap, LogCallback);
3193  daemon->uri_log_callback_cls = va_arg (ap, void *);
3194  break;
3196  daemon->worker_pool_size = va_arg (ap, unsigned int);
3197  if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon)))
3198  {
3199 #if HAVE_MESSAGES
3200  MHD_DLOG (daemon,
3201  "Specified thread pool size (%u) too big\n",
3202  daemon->worker_pool_size);
3203 #endif
3204  return MHD_NO;
3205  }
3206  break;
3207 #if HTTPS_SUPPORT
3209  if (0 != (daemon->options & MHD_USE_SSL))
3210  daemon->https_mem_key = va_arg (ap, const char *);
3211 #if HAVE_MESSAGES
3212  else
3213  MHD_DLOG (daemon,
3214  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3215  opt);
3216 #endif
3217  break;
3219  if (0 != (daemon->options & MHD_USE_SSL))
3220  daemon->https_key_password = va_arg (ap, const char *);
3221 #if HAVE_MESSAGES
3222  else
3223  MHD_DLOG (daemon,
3224  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3225  opt);
3226 #endif
3227  break;
3229  if (0 != (daemon->options & MHD_USE_SSL))
3230  daemon->https_mem_cert = va_arg (ap, const char *);
3231 #if HAVE_MESSAGES
3232  else
3233  MHD_DLOG (daemon,
3234  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3235  opt);
3236 #endif
3237  break;
3239  if (0 != (daemon->options & MHD_USE_SSL))
3240  daemon->https_mem_trust = va_arg (ap, const char *);
3241 #if HAVE_MESSAGES
3242  else
3243  MHD_DLOG (daemon,
3244  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3245  opt);
3246 #endif
3247  break;
3249  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, int);
3250  break;
3252  if (0 != (daemon->options & MHD_USE_SSL))
3253  {
3254  const char *arg = va_arg (ap, const char *);
3255  gnutls_datum_t dhpar;
3256 
3257  if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
3258  {
3259 #if HAVE_MESSAGES
3260  MHD_DLOG(daemon,
3261  "Error initializing DH parameters\n");
3262 #endif
3263  return MHD_NO;
3264  }
3265  dhpar.data = (unsigned char *) arg;
3266  dhpar.size = strlen (arg);
3267  if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, &dhpar,
3268  GNUTLS_X509_FMT_PEM) < 0)
3269  {
3270 #if HAVE_MESSAGES
3271  MHD_DLOG(daemon,
3272  "Bad Diffie-Hellman parameters format\n");
3273 #endif
3274  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
3275  return MHD_NO;
3276  }
3277  daemon->have_dhparams = MHD_YES;
3278  }
3279  else
3280  {
3281 #if HAVE_MESSAGES
3282  MHD_DLOG (daemon,
3283  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3284  opt);
3285 #endif
3286  return MHD_NO;
3287  }
3288  break;
3290  if (0 != (daemon->options & MHD_USE_SSL))
3291  {
3292  gnutls_priority_deinit (daemon->priority_cache);
3293  ret = gnutls_priority_init (&daemon->priority_cache,
3294  pstr = va_arg (ap, const char*),
3295  NULL);
3296  if (GNUTLS_E_SUCCESS != ret)
3297  {
3298 #if HAVE_MESSAGES
3299  MHD_DLOG (daemon,
3300  "Setting priorities to `%s' failed: %s\n",
3301  pstr,
3302  gnutls_strerror (ret));
3303 #endif
3304  daemon->priority_cache = NULL;
3305  return MHD_NO;
3306  }
3307  }
3308  break;
3310 #if GNUTLS_VERSION_MAJOR < 3
3311 #if HAVE_MESSAGES
3312  MHD_DLOG (daemon,
3313  "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n");
3314 #endif
3315  return MHD_NO;
3316 #else
3317  if (0 != (daemon->options & MHD_USE_SSL))
3318  daemon->cert_callback = va_arg (ap, gnutls_certificate_retrieve_function2 *);
3319  break;
3320 #endif
3321 #endif
3322 #ifdef DAUTH_SUPPORT
3324  daemon->digest_auth_rand_size = va_arg (ap, size_t);
3325  daemon->digest_auth_random = va_arg (ap, const char *);
3326  break;
3328  daemon->nonce_nc_size = va_arg (ap, unsigned int);
3329  break;
3330 #endif
3332  daemon->socket_fd = va_arg (ap, MHD_socket);
3333  break;
3335 #if HAVE_MESSAGES
3336  daemon->custom_error_log =
3337  va_arg (ap, VfprintfFunctionPointerType);
3338  daemon->custom_error_log_cls = va_arg (ap, void *);
3339 #else
3340  va_arg (ap, VfprintfFunctionPointerType);
3341  va_arg (ap, void *);
3342 #endif
3343  break;
3345  daemon->thread_stack_size = va_arg (ap, size_t);
3346  break;
3347 #ifdef TCP_FASTOPEN
3349  daemon->fastopen_queue_size = va_arg (ap, unsigned int);
3350  break;
3351 #endif
3353  daemon->listening_address_reuse = va_arg (ap, unsigned int) ? 1 : -1;
3354  break;
3355  case MHD_OPTION_ARRAY:
3356  oa = va_arg (ap, struct MHD_OptionItem*);
3357  i = 0;
3358  while (MHD_OPTION_END != (opt = oa[i].option))
3359  {
3360  switch (opt)
3361  {
3362  /* all options taking 'size_t' */
3366  if (MHD_YES != parse_options (daemon,
3367  servaddr,
3368  opt,
3369  (size_t) oa[i].value,
3370  MHD_OPTION_END))
3371  return MHD_NO;
3372  break;
3373  /* all options taking 'unsigned int' */
3381  if (MHD_YES != parse_options (daemon,
3382  servaddr,
3383  opt,
3384  (unsigned int) oa[i].value,
3385  MHD_OPTION_END))
3386  return MHD_NO;
3387  break;
3388  /* all options taking 'enum' */
3390  if (MHD_YES != parse_options (daemon,
3391  servaddr,
3392  opt,
3393  (int) oa[i].value,
3394  MHD_OPTION_END))
3395  return MHD_NO;
3396  break;
3397  /* all options taking 'MHD_socket' */
3399  if (MHD_YES != parse_options (daemon,
3400  servaddr,
3401  opt,
3402  (MHD_socket) oa[i].value,
3403  MHD_OPTION_END))
3404  return MHD_NO;
3405  break;
3406  /* all options taking one pointer */
3407  case MHD_OPTION_SOCK_ADDR:
3414  case MHD_OPTION_ARRAY:
3416  if (MHD_YES != parse_options (daemon,
3417  servaddr,
3418  opt,
3419  oa[i].ptr_value,
3420  MHD_OPTION_END))
3421  return MHD_NO;
3422  break;
3423  /* all options taking two pointers */
3429  if (MHD_YES != parse_options (daemon,
3430  servaddr,
3431  opt,
3432  (void *) oa[i].value,
3433  oa[i].ptr_value,
3434  MHD_OPTION_END))
3435  return MHD_NO;
3436  break;
3437  /* options taking size_t-number followed by pointer */
3439  if (MHD_YES != parse_options (daemon,
3440  servaddr,
3441  opt,
3442  (size_t) oa[i].value,
3443  oa[i].ptr_value,
3444  MHD_OPTION_END))
3445  return MHD_NO;
3446  break;
3447  default:
3448  return MHD_NO;
3449  }
3450  i++;
3451  }
3452  break;
3454  daemon->unescape_callback =
3455  va_arg (ap, UnescapeCallback);
3456  daemon->unescape_callback_cls = va_arg (ap, void *);
3457  break;
3458  default:
3459 #if HAVE_MESSAGES
3460  if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
3462  {
3463  MHD_DLOG (daemon,
3464  "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
3465  opt);
3466  }
3467  else
3468  {
3469  MHD_DLOG (daemon,
3470  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
3471  opt);
3472  }
3473 #endif
3474  return MHD_NO;
3475  }
3476  }
3477  return MHD_YES;
3478 }
3479 
3480 
3489 static MHD_socket
3490 create_socket (struct MHD_Daemon *daemon,
3491  int domain, int type, int protocol)
3492 {
3493  int ctype = type | SOCK_CLOEXEC;
3494  MHD_socket fd;
3495 
3496  /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
3497  * implementations do not set ai_socktype, e.g. RHL6.2. */
3498  fd = socket (domain, ctype, protocol);
3499  if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 != SOCK_CLOEXEC) )
3500  {
3501  ctype = type;
3502  fd = socket(domain, type, protocol);
3503  }
3504  if (MHD_INVALID_SOCKET == fd)
3505  return MHD_INVALID_SOCKET;
3506  if (type == ctype)
3507  make_nonblocking_noninheritable (daemon, fd);
3508  return fd;
3509 }
3510 
3511 
3512 #if EPOLL_SUPPORT
3513 
3520 static int
3521 setup_epoll_to_listen (struct MHD_Daemon *daemon)
3522 {
3523  struct epoll_event event;
3524 
3525 #ifdef HAVE_EPOLL_CREATE1
3526  daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
3527 #else /* !HAVE_EPOLL_CREATE1 */
3528  daemon->epoll_fd = epoll_create (MAX_EVENTS);
3529 #endif /* !HAVE_EPOLL_CREATE1 */
3530  if (-1 == daemon->epoll_fd)
3531  {
3532 #if HAVE_MESSAGES
3533  MHD_DLOG (daemon,
3534  "Call to epoll_create1 failed: %s\n",
3536 #endif
3537  return MHD_NO;
3538  }
3539 #ifndef HAVE_EPOLL_CREATE1
3540  else
3541  {
3542  int fdflags = fcntl (daemon->epoll_fd, F_GETFD);
3543  if (0 > fdflags || 0 > fcntl (daemon->epoll_fd, F_SETFD, fdflags | FD_CLOEXEC))
3544  {
3545 #if HAVE_MESSAGES
3546  MHD_DLOG (daemon,
3547  "Failed to change flags on epoll fd: %s\n",
3549 #endif /* HAVE_MESSAGES */
3550  }
3551  }
3552 #endif /* !HAVE_EPOLL_CREATE1 */
3553  if (0 == EPOLL_CLOEXEC)
3555  daemon->epoll_fd);
3556  if (MHD_INVALID_SOCKET == daemon->socket_fd)
3557  return MHD_YES; /* non-listening daemon */
3558  event.events = EPOLLIN;
3559  event.data.ptr = daemon;
3560  if (0 != epoll_ctl (daemon->epoll_fd,
3561  EPOLL_CTL_ADD,
3562  daemon->socket_fd,
3563  &event))
3564  {
3565 #if HAVE_MESSAGES
3566  MHD_DLOG (daemon,
3567  "Call to epoll_ctl failed: %s\n",
3569 #endif
3570  return MHD_NO;
3571  }
3572  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
3574  {
3575  event.events = EPOLLIN | EPOLLET;
3576  event.data.ptr = NULL;
3577  event.data.fd = daemon->wpipe[0];
3578  if (0 != epoll_ctl (daemon->epoll_fd,
3579  EPOLL_CTL_ADD,
3580  daemon->wpipe[0],
3581  &event))
3582  {
3583 #if HAVE_MESSAGES
3584  MHD_DLOG (daemon,
3585  "Call to epoll_ctl failed: %s\n",
3587 #endif
3588  return MHD_NO;
3589  }
3590  }
3591  daemon->listen_socket_in_epoll = MHD_YES;
3592  return MHD_YES;
3593 }
3594 #endif
3595 
3596 
3614 struct MHD_Daemon *
3615 MHD_start_daemon_va (unsigned int flags,
3616  uint16_t port,
3618  void *apc_cls,
3619  MHD_AccessHandlerCallback dh, void *dh_cls,
3620  va_list ap)
3621 {
3622 #if defined(MHD_POSIX_SOCKETS)
3623  const int on = 1;
3624 #elif defined(MHD_WINSOCK_SOCKETS)
3625  const uint32_t on = 1;
3626 #endif /* MHD_WINSOCK_SOCKETS */
3627  struct MHD_Daemon *daemon;
3629  struct sockaddr_in servaddr4;
3630 #if HAVE_INET6
3631  struct sockaddr_in6 servaddr6;
3632 #endif
3633  const struct sockaddr *servaddr = NULL;
3634  socklen_t addrlen;
3635  unsigned int i;
3636  int res_thread_create;
3637  int use_pipe;
3638 
3639 #ifndef HAVE_INET6
3640  if (0 != (flags & MHD_USE_IPv6))
3641  return NULL;
3642 #endif
3643 #ifndef HAVE_POLL
3644  if (0 != (flags & MHD_USE_POLL))
3645  return NULL;
3646 #endif
3647 #if ! HTTPS_SUPPORT
3648  if (0 != (flags & MHD_USE_SSL))
3649  return NULL;
3650 #endif
3651 #ifndef TCP_FASTOPEN
3652  if (0 != (flags & MHD_USE_TCP_FASTOPEN))
3653  return NULL;
3654 #endif
3655  if (NULL == dh)
3656  return NULL;
3657  if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
3658  return NULL;
3659  memset (daemon, 0, sizeof (struct MHD_Daemon));
3660 #if EPOLL_SUPPORT
3661  daemon->epoll_fd = -1;
3662 #endif
3663  /* try to open listen socket */
3664 #if HTTPS_SUPPORT
3665  if (0 != (flags & MHD_USE_SSL))
3666  {
3667  gnutls_priority_init (&daemon->priority_cache,
3668  "@SYSTEM",
3669  NULL);
3670  }
3671 #endif
3672  daemon->socket_fd = MHD_INVALID_SOCKET;
3673  daemon->listening_address_reuse = 0;
3674  daemon->options = flags;
3675 #if defined(MHD_WINSOCK_SOCKETS) || defined(CYGWIN)
3676  /* Winsock is broken with respect to 'shutdown';
3677  this disables us calling 'shutdown' on W32. */
3678  daemon->options |= MHD_USE_EPOLL_TURBO;
3679 #endif
3680  daemon->port = port;
3681  daemon->apc = apc;
3682  daemon->apc_cls = apc_cls;
3683  daemon->default_handler = dh;
3684  daemon->default_handler_cls = dh_cls;
3685  daemon->connections = 0;
3687  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
3688  daemon->pool_increment = MHD_BUF_INC_SIZE;
3690  daemon->connection_timeout = 0; /* no timeout */
3691  daemon->wpipe[0] = MHD_INVALID_PIPE_;
3692  daemon->wpipe[1] = MHD_INVALID_PIPE_;
3693 #if HAVE_MESSAGES
3694  daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
3695  daemon->custom_error_log_cls = stderr;
3696 #endif
3697 #ifdef HAVE_LISTEN_SHUTDOWN
3698  use_pipe = (0 != (daemon->options & (MHD_USE_NO_LISTEN_SOCKET | MHD_USE_PIPE_FOR_SHUTDOWN)));
3699 #else
3700  use_pipe = 1; /* yes, must use pipe to signal shutdown */
3701 #endif
3703  use_pipe = 0; /* useless if we are using 'external' select */
3704  if ( (use_pipe) && (0 != MHD_pipe_ (daemon->wpipe)) )
3705  {
3706 #if HAVE_MESSAGES
3707  MHD_DLOG (daemon,
3708  "Failed to create control pipe: %s\n",
3709  MHD_strerror_ (errno));
3710 #endif
3711  free (daemon);
3712  return NULL;
3713  }
3714 #ifndef MHD_WINSOCK_SOCKETS
3715  if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) &&
3716  (1 == use_pipe) &&
3717  (daemon->wpipe[0] >= FD_SETSIZE) )
3718  {
3719 #if HAVE_MESSAGES
3720  MHD_DLOG (daemon,
3721  "file descriptor for control pipe exceeds maximum value\n");
3722 #endif
3723  if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
3724  MHD_PANIC ("close failed\n");
3725  if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
3726  MHD_PANIC ("close failed\n");
3727  free (daemon);
3728  return NULL;
3729  }
3730 #endif
3731 #ifdef DAUTH_SUPPORT
3732  daemon->digest_auth_rand_size = 0;
3733  daemon->digest_auth_random = NULL;
3734  daemon->nonce_nc_size = 4; /* tiny */
3735 #endif
3736 #if HTTPS_SUPPORT
3737  if (0 != (flags & MHD_USE_SSL))
3738  {
3739  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
3740  }
3741 #endif
3742 
3743 
3744  if (MHD_YES != parse_options_va (daemon, &servaddr, ap))
3745  {
3746 #if HTTPS_SUPPORT
3747  if ( (0 != (flags & MHD_USE_SSL)) &&
3748  (NULL != daemon->priority_cache) )
3749  gnutls_priority_deinit (daemon->priority_cache);
3750 #endif
3751  free (daemon);
3752  return NULL;
3753  }
3754 #ifdef DAUTH_SUPPORT
3755  if (daemon->nonce_nc_size > 0)
3756  {
3757  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
3758  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
3759  {
3760 #if HAVE_MESSAGES
3761  MHD_DLOG (daemon,
3762  "Specified value for NC_SIZE too large\n");
3763 #endif
3764 #if HTTPS_SUPPORT
3765  if (0 != (flags & MHD_USE_SSL))
3766  gnutls_priority_deinit (daemon->priority_cache);
3767 #endif
3768  free (daemon);
3769  return NULL;
3770  }
3771  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
3772  if (NULL == daemon->nnc)
3773  {
3774 #if HAVE_MESSAGES
3775  MHD_DLOG (daemon,
3776  "Failed to allocate memory for nonce-nc map: %s\n",
3777  MHD_strerror_ (errno));
3778 #endif
3779 #if HTTPS_SUPPORT
3780  if (0 != (flags & MHD_USE_SSL))
3781  gnutls_priority_deinit (daemon->priority_cache);
3782 #endif
3783  free (daemon);
3784  return NULL;
3785  }
3786  }
3787 
3788  if (MHD_YES != MHD_mutex_create_ (&daemon->nnc_lock))
3789  {
3790 #if HAVE_MESSAGES
3791  MHD_DLOG (daemon,
3792  "MHD failed to initialize nonce-nc mutex\n");
3793 #endif
3794 #if HTTPS_SUPPORT
3795  if (0 != (flags & MHD_USE_SSL))
3796  gnutls_priority_deinit (daemon->priority_cache);
3797 #endif
3798  free (daemon->nnc);
3799  free (daemon);
3800  return NULL;
3801  }
3802 #endif
3803 
3804  /* Thread pooling currently works only with internal select thread model */
3805  if ( (0 == (flags & MHD_USE_SELECT_INTERNALLY)) &&
3806  (daemon->worker_pool_size > 0) )
3807  {
3808 #if HAVE_MESSAGES
3809  MHD_DLOG (daemon,
3810  "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
3811 #endif
3812  goto free_and_fail;
3813  }
3814 
3815  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3816  (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) )
3817  {
3818 #if HAVE_MESSAGES
3819  MHD_DLOG (daemon,
3820  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_SUSPEND_RESUME is not supported.\n");
3821 #endif
3822  goto free_and_fail;
3823  }
3824 
3825 #ifdef __SYMBIAN32__
3826  if (0 != (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
3827  {
3828 #if HAVE_MESSAGES
3829  MHD_DLOG (daemon,
3830  "Threaded operations are not supported on Symbian.\n");
3831 #endif
3832  goto free_and_fail;
3833  }
3834 #endif
3835  if ( (MHD_INVALID_SOCKET == daemon->socket_fd) &&
3836  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3837  {
3838  /* try to open listen socket */
3839  if (0 != (flags & MHD_USE_IPv6))
3840  socket_fd = create_socket (daemon,
3841  PF_INET6, SOCK_STREAM, 0);
3842  else
3843  socket_fd = create_socket (daemon,
3844  PF_INET, SOCK_STREAM, 0);
3845  if (MHD_INVALID_SOCKET == socket_fd)
3846  {
3847 #if HAVE_MESSAGES
3848  MHD_DLOG (daemon,
3849  "Call to socket failed: %s\n",
3851 #endif
3852  goto free_and_fail;
3853  }
3854 
3855  /* Apply the socket options according to listening_address_reuse. */
3856  if (0 == daemon->listening_address_reuse)
3857  {
3858  /* No user requirement, use "traditional" default SO_REUSEADDR,
3859  and do not fail if it doesn't work */
3860  if (0 > setsockopt (socket_fd,
3861  SOL_SOCKET,
3862  SO_REUSEADDR,
3863  (void*)&on, sizeof (on)))
3864  {
3865 #if HAVE_MESSAGES
3866  MHD_DLOG (daemon,
3867  "setsockopt failed: %s\n",
3869 #endif
3870  }
3871  }
3872  else if (daemon->listening_address_reuse > 0)
3873  {
3874  /* User requested to allow reusing listening address:port.
3875  * Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
3876  * Fail if SO_REUSEPORT does not exist or setsockopt fails.
3877  */
3878 #ifdef _WIN32
3879  /* SO_REUSEADDR on W32 has the same semantics
3880  as SO_REUSEPORT on BSD/Linux */
3881  if (0 > setsockopt (socket_fd,
3882  SOL_SOCKET,
3883  SO_REUSEADDR,
3884  (void*)&on, sizeof (on)))
3885  {
3886 #if HAVE_MESSAGES
3887  MHD_DLOG (daemon,
3888  "setsockopt failed: %s\n",
3890 #endif
3891  goto free_and_fail;
3892  }
3893 #else
3894 #ifndef SO_REUSEPORT
3895 #ifdef LINUX
3896 /* Supported since Linux 3.9, but often not present (or commented out)
3897  in the headers at this time; but 15 is reserved for this and
3898  thus should be safe to use. */
3899 #define SO_REUSEPORT 15
3900 #endif
3901 #endif
3902 #ifdef SO_REUSEPORT
3903  if (0 > setsockopt (socket_fd,
3904  SOL_SOCKET,
3905  SO_REUSEPORT,
3906  (void*)&on, sizeof (on)))
3907  {
3908 #if HAVE_MESSAGES
3909  MHD_DLOG (daemon,
3910  "setsockopt failed: %s\n",
3912 #endif
3913  goto free_and_fail;
3914  }
3915 #else
3916  /* we're supposed to allow address:port re-use, but
3917  on this platform we cannot; fail hard */
3918 #if HAVE_MESSAGES
3919  MHD_DLOG (daemon,
3920  "Cannot allow listening address reuse: SO_REUSEPORT not defined\n");
3921 #endif
3922  goto free_and_fail;
3923 #endif
3924 #endif
3925  }
3926  else /* if (daemon->listening_address_reuse < 0) */
3927  {
3928  /* User requested to disallow reusing listening address:port.
3929  * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
3930  * is used. Fail if it does not exist or setsockopt fails.
3931  */
3932 #ifdef _WIN32
3933 #ifdef SO_EXCLUSIVEADDRUSE
3934  if (0 > setsockopt (socket_fd,
3935  SOL_SOCKET,
3936  SO_EXCLUSIVEADDRUSE,
3937  (void*)&on, sizeof (on)))
3938  {
3939 #if HAVE_MESSAGES
3940  MHD_DLOG (daemon,
3941  "setsockopt failed: %s\n",
3943 #endif
3944  goto free_and_fail;
3945  }
3946 #else /* SO_EXCLUSIVEADDRUSE not defined on W32? */
3947 #if HAVE_MESSAGES
3948  MHD_DLOG (daemon,
3949  "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n");
3950 #endif
3951  goto free_and_fail;
3952 #endif
3953 #endif /* _WIN32 */
3954  }
3955 
3956  /* check for user supplied sockaddr */
3957 #if HAVE_INET6
3958  if (0 != (flags & MHD_USE_IPv6))
3959  addrlen = sizeof (struct sockaddr_in6);
3960  else
3961 #endif
3962  addrlen = sizeof (struct sockaddr_in);
3963  if (NULL == servaddr)
3964  {
3965 #if HAVE_INET6
3966  if (0 != (flags & MHD_USE_IPv6))
3967  {
3968  memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
3969  servaddr6.sin6_family = AF_INET6;
3970  servaddr6.sin6_port = htons (port);
3971 #if HAVE_SOCKADDR_IN_SIN_LEN
3972  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
3973 #endif
3974  servaddr = (struct sockaddr *) &servaddr6;
3975  }
3976  else
3977 #endif
3978  {
3979  memset (&servaddr4, 0, sizeof (struct sockaddr_in));
3980  servaddr4.sin_family = AF_INET;
3981  servaddr4.sin_port = htons (port);
3982 #if HAVE_SOCKADDR_IN_SIN_LEN
3983  servaddr4.sin_len = sizeof (struct sockaddr_in);
3984 #endif
3985  servaddr = (struct sockaddr *) &servaddr4;
3986  }
3987  }
3988  daemon->socket_fd = socket_fd;
3989 
3990  if (0 != (flags & MHD_USE_IPv6))
3991  {
3992 #ifdef IPPROTO_IPV6
3993 #ifdef IPV6_V6ONLY
3994  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
3995  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
3996  and may also be missing on older POSIX systems; good luck if you have any of those,
3997  your IPv6 socket may then also bind against IPv4 anyway... */
3998 #ifndef MHD_WINSOCK_SOCKETS
3999  const int
4000 #else
4001  const uint32_t
4002 #endif
4003  v6_only = (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK));
4004  if (0 > setsockopt (socket_fd,
4005  IPPROTO_IPV6, IPV6_V6ONLY,
4006  (const void*)&v6_only, sizeof (v6_only)))
4007  {
4008 #if HAVE_MESSAGES
4009  MHD_DLOG (daemon,
4010  "setsockopt failed: %s\n",
4012 #endif
4013  }
4014 #endif
4015 #endif
4016  }
4017  if (-1 == bind (socket_fd, servaddr, addrlen))
4018  {
4019 #if HAVE_MESSAGES
4020  MHD_DLOG (daemon,
4021  "Failed to bind to port %u: %s\n",
4022  (unsigned int) port,
4024 #endif
4025  if (0 != MHD_socket_close_ (socket_fd))
4026  MHD_PANIC ("close failed\n");
4027  goto free_and_fail;
4028  }
4029 #ifdef TCP_FASTOPEN
4030  if (0 != (flags & MHD_USE_TCP_FASTOPEN))
4031  {
4032  if (0 == daemon->fastopen_queue_size)
4033  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
4034  if (0 != setsockopt (socket_fd,
4035  IPPROTO_TCP, TCP_FASTOPEN,
4036  &daemon->fastopen_queue_size,
4037  sizeof (daemon->fastopen_queue_size)))
4038  {
4039 #if HAVE_MESSAGES
4040  MHD_DLOG (daemon,
4041  "setsockopt failed: %s\n",
4043 #endif
4044  }
4045  }
4046 #endif
4047 #if EPOLL_SUPPORT
4048  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
4049  {
4050  int sk_flags = fcntl (socket_fd, F_GETFL);
4051  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
4052  {
4053 #if HAVE_MESSAGES
4054  MHD_DLOG (daemon,
4055  "Failed to make listen socket non-blocking: %s\n",
4057 #endif
4058  if (0 != MHD_socket_close_ (socket_fd))
4059  MHD_PANIC ("close failed\n");
4060  goto free_and_fail;
4061  }
4062  }
4063 #endif
4064  if (listen (socket_fd, 32) < 0)
4065  {
4066 #if HAVE_MESSAGES
4067  MHD_DLOG (daemon,
4068  "Failed to listen for connections: %s\n",
4070 #endif
4071  if (0 != MHD_socket_close_ (socket_fd))
4072  MHD_PANIC ("close failed\n");
4073  goto free_and_fail;
4074  }
4075  }
4076  else
4077  {
4078  socket_fd = daemon->socket_fd;
4079  }
4080 #ifndef MHD_WINSOCK_SOCKETS
4081  if ( (socket_fd >= FD_SETSIZE) &&
4082  (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
4083  {
4084 #if HAVE_MESSAGES
4085  MHD_DLOG (daemon,
4086  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
4087  socket_fd,
4088  FD_SETSIZE);
4089 #endif
4090  if (0 != MHD_socket_close_ (socket_fd))
4091  MHD_PANIC ("close failed\n");
4092  goto free_and_fail;
4093  }
4094 #endif
4095 
4096 #if EPOLL_SUPPORT
4097  if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) &&
4098  (0 == daemon->worker_pool_size) &&
4099  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
4100  {
4101  if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))
4102  {
4103 #if HAVE_MESSAGES
4104  MHD_DLOG (daemon,
4105  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL_LINUX_ONLY is not supported.\n");
4106 #endif
4107  goto free_and_fail;
4108  }
4109  if (MHD_YES != setup_epoll_to_listen (daemon))
4110  goto free_and_fail;
4111  }
4112 #else
4113  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
4114  {
4115 #if HAVE_MESSAGES
4116  MHD_DLOG (daemon,
4117  "epoll is not supported on this platform by this build.\n");
4118 #endif
4119  goto free_and_fail;
4120  }
4121 #endif
4122 
4123  if (MHD_YES != MHD_mutex_create_ (&daemon->per_ip_connection_mutex))
4124  {
4125 #if HAVE_MESSAGES
4126  MHD_DLOG (daemon,
4127  "MHD failed to initialize IP connection limit mutex\n");
4128 #endif
4129  if ( (MHD_INVALID_SOCKET != socket_fd) &&
4130  (0 != MHD_socket_close_ (socket_fd)) )
4131  MHD_PANIC ("close failed\n");
4132  goto free_and_fail;
4133  }
4134  if (MHD_YES != MHD_mutex_create_ (&daemon->cleanup_connection_mutex))
4135  {
4136 #if HAVE_MESSAGES
4137  MHD_DLOG (daemon,
4138  "MHD failed to initialize IP connection limit mutex\n");
4139 #endif
4140  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4141  if ( (MHD_INVALID_SOCKET != socket_fd) &&
4142  (0 != MHD_socket_close_ (socket_fd)) )
4143  MHD_PANIC ("close failed\n");
4144  goto free_and_fail;
4145  }
4146 
4147 #if HTTPS_SUPPORT
4148  /* initialize HTTPS daemon certificate aspects & send / recv functions */
4149  if ((0 != (flags & MHD_USE_SSL)) && (0 != MHD_TLS_init (daemon)))
4150  {
4151 #if HAVE_MESSAGES
4152  MHD_DLOG (daemon,
4153  "Failed to initialize TLS support\n");
4154 #endif
4155  if ( (MHD_INVALID_SOCKET != socket_fd) &&
4156  (0 != MHD_socket_close_ (socket_fd)) )
4157  MHD_PANIC ("close failed\n");
4158  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4159  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4160  goto free_and_fail;
4161  }
4162 #endif
4163  if ( ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) ||
4164  ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) &&
4165  (0 == daemon->worker_pool_size)) ) &&
4166  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) &&
4167  (0 != (res_thread_create =
4168  create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon))))
4169  {
4170 #if HAVE_MESSAGES
4171  MHD_DLOG (daemon,
4172  "Failed to create listen thread: %s\n",
4173  MHD_strerror_ (res_thread_create));
4174 #endif
4175  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4176  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4177  if ( (MHD_INVALID_SOCKET != socket_fd) &&
4178  (0 != MHD_socket_close_ (socket_fd)) )
4179  MHD_PANIC ("close failed\n");
4180  goto free_and_fail;
4181  }
4182  if ( (daemon->worker_pool_size > 0) &&
4183  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
4184  {
4185 #if !defined(MHD_WINSOCK_SOCKETS)
4186  int sk_flags;
4187 #else
4188  unsigned long sk_flags;
4189 #endif
4190 
4191  /* Coarse-grained count of connections per thread (note error
4192  * due to integer division). Also keep track of how many
4193  * connections are leftover after an equal split. */
4194  unsigned int conns_per_thread = daemon->connection_limit
4195  / daemon->worker_pool_size;
4196  unsigned int leftover_conns = daemon->connection_limit
4197  % daemon->worker_pool_size;
4198 
4199  i = 0; /* we need this in case fcntl or malloc fails */
4200 
4201  /* Accept must be non-blocking. Multiple children may wake up
4202  * to handle a new connection, but only one will win the race.
4203  * The others must immediately return. */
4204 #if !defined(MHD_WINSOCK_SOCKETS)
4205  sk_flags = fcntl (socket_fd, F_GETFL);
4206  if (sk_flags < 0)
4207  goto thread_failed;
4208  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
4209  goto thread_failed;
4210 #else
4211  sk_flags = 1;
4212  if (SOCKET_ERROR == ioctlsocket (socket_fd, FIONBIO, &sk_flags))
4213  goto thread_failed;
4214 #endif /* MHD_WINSOCK_SOCKETS */
4215 
4216  /* Allocate memory for pooled objects */
4217  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
4218  * daemon->worker_pool_size);
4219  if (NULL == daemon->worker_pool)
4220  goto thread_failed;
4221 
4222  /* Start the workers in the pool */
4223  for (i = 0; i < daemon->worker_pool_size; ++i)
4224  {
4225  /* Create copy of the Daemon object for each worker */
4226  struct MHD_Daemon *d = &daemon->worker_pool[i];
4227 
4228  memcpy (d, daemon, sizeof (struct MHD_Daemon));
4229  /* Adjust pooling params for worker daemons; note that memcpy()
4230  has already copied MHD_USE_SELECT_INTERNALLY thread model into
4231  the worker threads. */
4232  d->master = daemon;
4233  d->worker_pool_size = 0;
4234  d->worker_pool = NULL;
4235 
4236  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
4237  (0 != MHD_pipe_ (d->wpipe)) )
4238  {
4239 #if HAVE_MESSAGES
4240  MHD_DLOG (daemon,
4241  "Failed to create worker control pipe: %s\n",
4243 #endif
4244  goto thread_failed;
4245  }
4246 #ifndef MHD_WINSOCK_SOCKETS
4247  if ( (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) &&
4248  (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
4249  (d->wpipe[0] >= FD_SETSIZE) )
4250  {
4251 #if HAVE_MESSAGES
4252  MHD_DLOG (daemon,
4253  "File descriptor for worker control pipe exceeds maximum value\n");
4254 #endif
4255  if (0 != MHD_pipe_close_ (d->wpipe[0]))
4256  MHD_PANIC ("close failed\n");
4257  if (0 != MHD_pipe_close_ (d->wpipe[1]))
4258  MHD_PANIC ("close failed\n");
4259  goto thread_failed;
4260  }
4261 #endif
4262 
4263  /* Divide available connections evenly amongst the threads.
4264  * Thread indexes in [0, leftover_conns) each get one of the
4265  * leftover connections. */
4266  d->connection_limit = conns_per_thread;
4267  if (i < leftover_conns)
4268  ++d->connection_limit;
4269 #if EPOLL_SUPPORT
4270  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4271  (MHD_YES != setup_epoll_to_listen (d)) )
4272  goto thread_failed;
4273 #endif
4274  /* Must init cleanup connection mutex for each worker */
4275  if (MHD_YES != MHD_mutex_create_ (&d->cleanup_connection_mutex))
4276  {
4277 #if HAVE_MESSAGES
4278  MHD_DLOG (daemon,
4279  "MHD failed to initialize cleanup connection mutex for thread worker %d\n", i);
4280 #endif
4281  goto thread_failed;
4282  }
4283 
4284  /* Spawn the worker thread */
4285  if (0 != (res_thread_create =
4286  create_thread (&d->pid, daemon, &MHD_select_thread, d)))
4287  {
4288 #if HAVE_MESSAGES
4289  MHD_DLOG (daemon,
4290  "Failed to create pool thread: %s\n",
4291  MHD_strerror_ (res_thread_create));
4292 #endif
4293  /* Free memory for this worker; cleanup below handles
4294  * all previously-created workers. */
4295  (void) MHD_mutex_destroy_ (&d->cleanup_connection_mutex);
4296  goto thread_failed;
4297  }
4298  }
4299  }
4300 #if HTTPS_SUPPORT
4301  /* API promises to never use the password after initialization,
4302  so we additionally NULL it here to not deref a dangling pointer. */
4303  daemon->https_key_password = NULL;
4304 #endif /* HTTPS_SUPPORT */
4305 
4306  return daemon;
4307 
4308 thread_failed:
4309  /* If no worker threads created, then shut down normally. Calling
4310  MHD_stop_daemon (as we do below) doesn't work here since it
4311  assumes a 0-sized thread pool means we had been in the default
4312  MHD_USE_SELECT_INTERNALLY mode. */
4313  if (0 == i)
4314  {
4315  if ( (MHD_INVALID_SOCKET != socket_fd) &&
4316  (0 != MHD_socket_close_ (socket_fd)) )
4317  MHD_PANIC ("close failed\n");
4318  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4319  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4320  if (NULL != daemon->worker_pool)
4321  free (daemon->worker_pool);
4322  goto free_and_fail;
4323  }
4324 
4325  /* Shutdown worker threads we've already created. Pretend
4326  as though we had fully initialized our daemon, but
4327  with a smaller number of threads than had been
4328  requested. */
4329  daemon->worker_pool_size = i;
4330  MHD_stop_daemon (daemon);
4331  return NULL;
4332 
4333  free_and_fail:
4334  /* clean up basic memory state in 'daemon' and return NULL to
4335  indicate failure */
4336 #if EPOLL_SUPPORT
4337  if (-1 != daemon->epoll_fd)
4338  close (daemon->epoll_fd);
4339 #endif
4340 #ifdef DAUTH_SUPPORT
4341  free (daemon->nnc);
4342  (void) MHD_mutex_destroy_ (&daemon->nnc_lock);
4343 #endif
4344 #if HTTPS_SUPPORT
4345  if (0 != (flags & MHD_USE_SSL))
4346  gnutls_priority_deinit (daemon->priority_cache);
4347 #endif
4348  free (daemon);
4349  return NULL;
4350 }
4351 
4352 
4359 static void
4361 {
4362  struct MHD_Daemon *daemon = pos->daemon;
4363 
4364  MHD_connection_close_ (pos,
4366  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4367  return; /* must let thread to the rest */
4368  if (pos->connection_timeout == pos->daemon->connection_timeout)
4370  daemon->normal_timeout_tail,
4371  pos);
4372  else
4374  daemon->manual_timeout_tail,
4375  pos);
4376  DLL_remove (daemon->connections_head,
4377  daemon->connections_tail,
4378  pos);
4380  DLL_insert (daemon->cleanup_head,
4381  daemon->cleanup_tail,
4382  pos);
4383 }
4384 
4385 
4393 static void
4395 {
4396  struct MHD_Connection *pos;
4397 
4398  /* first, make sure all threads are aware of shutdown; need to
4399  traverse DLLs in peace... */
4400  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4401  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
4402  MHD_PANIC ("Failed to acquire cleanup mutex\n");
4403  if (NULL != daemon->suspended_connections_head)
4404  MHD_PANIC ("MHD_stop_daemon() called while we have suspended connections.\n");
4405  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
4406  {
4407  shutdown (pos->socket_fd,
4408  (MHD_YES == pos->read_closed) ? SHUT_WR : SHUT_RDWR);
4409 #if MHD_WINSOCK_SOCKETS
4410  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4411  (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
4412  (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1)) )
4413  MHD_PANIC ("Failed to signal shutdown via pipe");
4414 #endif
4415  }
4416  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4417  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
4418  MHD_PANIC ("Failed to release cleanup mutex\n");
4419 
4420  /* now, collect per-connection threads */
4421  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4422  {
4423  pos = daemon->connections_head;
4424  while (NULL != pos)
4425  {
4426  if (MHD_YES != pos->thread_joined)
4427  {
4428  if (0 != MHD_join_thread_ (pos->pid))
4429  MHD_PANIC ("Failed to join a thread\n");
4430  pos->thread_joined = MHD_YES;
4431  /* The thread may have concurrently modified the DLL,
4432  need to restart from the beginning */
4433  pos = daemon->connections_head;
4434  continue;
4435  }
4436  pos = pos->next;
4437  }
4438  }
4439  /* now that we're alone, move everyone to cleanup */
4440  while (NULL != (pos = daemon->connections_head))
4441  {
4442  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4443  (MHD_YES != pos->thread_joined) )
4444  MHD_PANIC ("Failed to join a thread\n");
4445  close_connection (pos);
4446  }
4447  MHD_cleanup_connections (daemon);
4448 }
4449 
4450 
4451 #if EPOLL_SUPPORT
4452 
4457 static void
4458 epoll_shutdown (struct MHD_Daemon *daemon)
4459 {
4460  struct epoll_event event;
4461 
4462  if (MHD_INVALID_PIPE_ == daemon->wpipe[1])
4463  {
4464  /* wpipe was required in this mode, how could this happen? */
4465  MHD_PANIC ("Internal error\n");
4466  }
4467  event.events = EPOLLOUT;
4468  event.data.ptr = NULL;
4469  if (0 != epoll_ctl (daemon->epoll_fd,
4470  EPOLL_CTL_ADD,
4471  daemon->wpipe[1],
4472  &event))
4473  MHD_PANIC ("Failed to add wpipe to epoll set to signal termination\n");
4474 }
4475 #endif
4476 
4477 
4484 void
4485 MHD_stop_daemon (struct MHD_Daemon *daemon)
4486 {
4487  MHD_socket fd;
4488  unsigned int i;
4489 
4490  if (NULL == daemon)
4491  return;
4492  daemon->shutdown = MHD_YES;
4493  fd = daemon->socket_fd;
4494  daemon->socket_fd = MHD_INVALID_SOCKET;
4495  /* Prepare workers for shutdown */
4496  if (NULL != daemon->worker_pool)
4497  {
4498  /* #MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
4499  for (i = 0; i < daemon->worker_pool_size; ++i)
4500  {
4501  daemon->worker_pool[i].shutdown = MHD_YES;
4503 #if EPOLL_SUPPORT
4504  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4505  (-1 != daemon->worker_pool[i].epoll_fd) &&
4506  (MHD_INVALID_SOCKET == fd) )
4507  epoll_shutdown (&daemon->worker_pool[i]);
4508 #endif
4509  }
4510  }
4511  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
4512  {
4513  if (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1))
4514  MHD_PANIC ("failed to signal shutdown via pipe");
4515  }
4516 #ifdef HAVE_LISTEN_SHUTDOWN
4517  else
4518  {
4519  /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
4520  if ( (MHD_INVALID_SOCKET != fd) &&
4521  (0 == (daemon->options & MHD_USE_PIPE_FOR_SHUTDOWN)) )
4522  (void) shutdown (fd, SHUT_RDWR);
4523  }
4524 #endif
4525 #if EPOLL_SUPPORT
4526  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4527  (-1 != daemon->epoll_fd) &&
4528  (MHD_INVALID_SOCKET == fd) )
4529  epoll_shutdown (daemon);
4530 #endif
4531 
4532 #if DEBUG_CLOSE
4533 #if HAVE_MESSAGES
4534  MHD_DLOG (daemon,
4535  "MHD listen socket shutdown\n");
4536 #endif
4537 #endif
4538 
4539 
4540  /* Signal workers to stop and clean them up */
4541  if (NULL != daemon->worker_pool)
4542  {
4543  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
4544  for (i = 0; i < daemon->worker_pool_size; ++i)
4545  {
4546  if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4547  {
4548  if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 1))
4549  MHD_PANIC ("failed to signal shutdown via pipe");
4550  }
4551  if (0 != MHD_join_thread_ (daemon->worker_pool[i].pid))
4552  MHD_PANIC ("Failed to join a thread\n");
4553  close_all_connections (&daemon->worker_pool[i]);
4554  (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex);
4555 #if EPOLL_SUPPORT
4556  if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
4557  (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) )
4558  MHD_PANIC ("close failed\n");
4559 #endif
4560  if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) )
4561  {
4562  if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4563  {
4564  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[0]))
4565  MHD_PANIC ("close failed\n");
4566  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[1]))
4567  MHD_PANIC ("close failed\n");
4568  }
4569  }
4570  }
4571  free (daemon->worker_pool);
4572  }
4573  else
4574  {
4575  /* clean up master threads */
4576  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
4577  ( (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) &&
4578  (0 == daemon->worker_pool_size) ) )
4579  {
4580  if (0 != MHD_join_thread_ (daemon->pid))
4581  {
4582  MHD_PANIC ("Failed to join a thread\n");
4583  }
4584  }
4585  }
4586  close_all_connections (daemon);
4587  if ( (MHD_INVALID_SOCKET != fd) &&
4588  (0 != MHD_socket_close_ (fd)) )
4589  MHD_PANIC ("close failed\n");
4590 
4591  /* TLS clean up */
4592 #if HTTPS_SUPPORT
4593  if (MHD_YES == daemon->have_dhparams)
4594  {
4595  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
4596  daemon->have_dhparams = MHD_NO;
4597  }
4598  if (0 != (daemon->options & MHD_USE_SSL))
4599  {
4600  gnutls_priority_deinit (daemon->priority_cache);
4601  if (daemon->x509_cred)
4602  gnutls_certificate_free_credentials (daemon->x509_cred);
4603  }
4604 #endif
4605 #if EPOLL_SUPPORT
4606  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4607  (-1 != daemon->epoll_fd) &&
4608  (0 != MHD_socket_close_ (daemon->epoll_fd)) )
4609  MHD_PANIC ("close failed\n");
4610 #endif
4611 
4612 #ifdef DAUTH_SUPPORT
4613  free (daemon->nnc);
4614  (void) MHD_mutex_destroy_ (&daemon->nnc_lock);
4615 #endif
4616  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4617  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4618 
4619  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
4620  {
4621  if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
4622  MHD_PANIC ("close failed\n");
4623  if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
4624  MHD_PANIC ("close failed\n");
4625  }
4626  free (daemon);
4627 }
4628 
4629 
4641 const union MHD_DaemonInfo *
4643  enum MHD_DaemonInfoType info_type,
4644  ...)
4645 {
4646  switch (info_type)
4647  {
4649  return NULL; /* no longer supported */
4651  return NULL; /* no longer supported */
4653  return (const union MHD_DaemonInfo *) &daemon->socket_fd;
4654 #if EPOLL_SUPPORT
4656  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
4657 #endif
4659  MHD_cleanup_connections (daemon);
4660  if (daemon->worker_pool)
4661  {
4662  /* Collect the connection information stored in the workers. */
4663  unsigned int i;
4664 
4665  daemon->connections = 0;
4666  for (i=0;i<daemon->worker_pool_size;i++)
4667  {
4668  MHD_cleanup_connections (&daemon->worker_pool[i]);
4669  daemon->connections += daemon->worker_pool[i].connections;
4670  }
4671  }
4672  return (const union MHD_DaemonInfo *) &daemon->connections;
4673  default:
4674  return NULL;
4675  };
4676 }
4677 
4678 
4695 void
4697  void *cls)
4698 {
4699  mhd_panic = cb;
4700  mhd_panic_cls = cls;
4701 }
4702 
4703 
4710 const char *
4712 {
4713 #ifdef PACKAGE_VERSION
4714  return PACKAGE_VERSION;
4715 #else /* !PACKAGE_VERSION */
4716  static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
4717  if (0 == ver[0])
4718  {
4719  int res = MHD_snprintf_(ver, sizeof(ver), "%x.%x.%x",
4720  (((int)MHD_VERSION >> 24) & 0xFF),
4721  (((int)MHD_VERSION >> 16) & 0xFF),
4722  (((int)MHD_VERSION >> 8) & 0xFF));
4723  if (0 >= res || sizeof(ver) <= res)
4724  return "0.0.0"; /* Can't return real version*/
4725  }
4726  return ver;
4727 #endif /* !PACKAGE_VERSION */
4728 }
4729 
4730 
4742 _MHD_EXTERN int
4744 {
4745  switch(feature)
4746  {
4747  case MHD_FEATURE_MESSGES:
4748 #if HAVE_MESSAGES
4749  return MHD_YES;
4750 #else
4751  return MHD_NO;
4752 #endif
4753  case MHD_FEATURE_SSL:
4754 #if HTTPS_SUPPORT
4755  return MHD_YES;
4756 #else
4757  return MHD_NO;
4758 #endif
4760 #if HTTPS_SUPPORT && GNUTLS_VERSION_MAJOR >= 3
4761  return MHD_YES;
4762 #else
4763  return MHD_NO;
4764 #endif
4765  case MHD_FEATURE_IPv6:
4766 #ifdef HAVE_INET6
4767  return MHD_YES;
4768 #else
4769  return MHD_NO;
4770 #endif
4771  case MHD_FEATURE_IPv6_ONLY:
4772 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
4773  return MHD_YES;
4774 #else
4775  return MHD_NO;
4776 #endif
4777  case MHD_FEATURE_POLL:
4778 #ifdef HAVE_POLL
4779  return MHD_YES;
4780 #else
4781  return MHD_NO;
4782 #endif
4783  case MHD_FEATURE_EPOLL:
4784 #if EPOLL_SUPPORT
4785  return MHD_YES;
4786 #else
4787  return MHD_NO;
4788 #endif
4790 #ifdef HAVE_LISTEN_SHUTDOWN
4791  return MHD_YES;
4792 #else
4793  return MHD_NO;
4794 #endif
4796 #ifdef MHD_DONT_USE_PIPES
4797  return MHD_YES;
4798 #else
4799  return MHD_NO;
4800 #endif
4802 #ifdef TCP_FASTOPEN
4803  return MHD_YES;
4804 #else
4805  return MHD_NO;
4806 #endif
4808 #if BAUTH_SUPPORT
4809  return MHD_YES;
4810 #else
4811  return MHD_NO;
4812 #endif
4814 #if DAUTH_SUPPORT
4815  return MHD_YES;
4816 #else
4817  return MHD_NO;
4818 #endif
4820 #if HAVE_POSTPROCESSOR
4821  return MHD_YES;
4822 #else
4823  return MHD_NO;
4824 #endif
4826 #if HTTPS_SUPPORT && GNUTLS_VERSION_NUMBER >= 0x030111
4827  return MHD_YES;
4828 #else
4829  return MHD_NO;
4830 #endif
4832 #if defined(HAVE___LSEEKI64) || defined(HAVE_LSEEK64)
4833  return MHD_YES;
4834 #else
4835  return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES;
4836 #endif
4837  }
4838  return MHD_NO;
4839 }
4840 
4841 
4842 #if HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600
4843 #if defined(MHD_USE_POSIX_THREADS)
4844 GCRY_THREAD_OPTION_PTHREAD_IMPL;
4845 #elif defined(MHD_W32_MUTEX_)
4846 
4847 static int
4848 gcry_w32_mutex_init (void **ppmtx)
4849 {
4850  *ppmtx = malloc (sizeof (MHD_mutex_));
4851 
4852  if (NULL == *ppmtx)
4853  return ENOMEM;
4854  if (MHD_YES != MHD_mutex_create_ ((MHD_mutex_*)*ppmtx))
4855  {
4856  free (*ppmtx);
4857  *ppmtx = NULL;
4858  return EPERM;
4859  }
4860 
4861  return 0;
4862 }
4863 
4864 
4865 static int
4866 gcry_w32_mutex_destroy (void **ppmtx)
4867 {
4868  int res = (MHD_YES == MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1;
4869  free (*ppmtx);
4870  return res;
4871 }
4872 
4873 
4874 static int
4875 gcry_w32_mutex_lock (void **ppmtx)
4876 {
4877  return (MHD_YES == MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1;
4878 }
4879 
4880 
4881 static int
4882 gcry_w32_mutex_unlock (void **ppmtx)
4883 {
4884  return (MHD_YES == MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1;
4885 }
4886 
4887 
4888 static struct gcry_thread_cbs gcry_threads_w32 = {
4889  (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
4890  NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
4891  gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
4892  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
4893 
4894 #endif /* defined(MHD_W32_MUTEX_) */
4895 #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */
4896 
4897 
4901 void
4903 {
4905  mhd_panic_cls = NULL;
4906 
4907 #ifdef _WIN32
4908  WSADATA wsd;
4909  if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
4910  MHD_PANIC ("Failed to initialize winsock\n");
4911  mhd_winsock_inited_ = 1;
4912  if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
4913  MHD_PANIC ("Winsock version 2.2 is not available\n");
4914 #endif
4915 #if HTTPS_SUPPORT
4916 #if GCRYPT_VERSION_NUMBER < 0x010600
4917 #if defined(MHD_USE_POSIX_THREADS)
4918  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
4919  MHD_PANIC ("Failed to initialise multithreading in libgcrypt\n");
4920 #elif defined(MHD_W32_MUTEX_)
4921  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_w32))
4922  MHD_PANIC ("Failed to initialise multithreading in libgcrypt\n");
4923 #endif /* defined(MHD_W32_MUTEX_) */
4924  gcry_check_version (NULL);
4925 #else
4926  if (NULL == gcry_check_version ("1.6.0"))
4927  MHD_PANIC ("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n");
4928 #endif
4929  gnutls_global_init ();
4930 #endif
4932 }
4933 
4934 
4935 void
4937 {
4938 #if HTTPS_SUPPORT
4939  gnutls_global_deinit ();
4940 #endif
4941 #ifdef _WIN32
4942  if (mhd_winsock_inited_)
4943  WSACleanup();
4944 #endif
4946 }
4947 
4949 
4950 /* end of daemon.c */
unsigned int per_ip_connection_limit
Definition: internal.h:1187
void * unescape_callback_cls
Definition: internal.h:1056
#define XDLL_insert(head, tail, element)
Definition: internal.h:1367
void MHD_fini(void)
Definition: daemon.c:4936
uint64_t total_size
Definition: internal.h:289
_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:3615
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:3123
uint64_t fd_off
Definition: internal.h:300
_MHD_EXTERN const char * MHD_get_version(void)
Definition: daemon.c:4711
void * mhd_panic_cls
Definition: daemon.c:154
#define MHD_socket_errno_
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:309
socklen_t addr_len
Definition: internal.h:717
int thread_joined
Definition: internal.h:756
void * socket_context
Definition: internal.h:602
enum MHD_CONNECTION_STATE state
Definition: internal.h:774
void * data
Definition: microhttpd.h:2035
uint64_t response_write_position
Definition: internal.h:706
#define NULL
Definition: reason_phrase.c:30
#define EDLL_remove(head, tail, element)
Definition: internal.h:1430
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:135
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:779
#define MHD_DEFAULT_FD_SETSIZE
Definition: daemon.c:32
#define MHD_BUF_INC_SIZE
Definition: internal.h:65
#define DLL_remove(head, tail, element)
Definition: internal.h:1343
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:2120
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:268
void MHD_init(void)
Definition: daemon.c:4902
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:2024
#define SOCK_CLOEXEC
Definition: daemon.c:114
MHD_socket socket_fd
Definition: internal.h:1124
void MHD_connection_close_(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
Definition: connection.c:270
#define MHD_YES
Definition: microhttpd.h:138
_MHD_EXTERN int MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:1920
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
Definition: daemon.c:1088
#define MSG_NOSIGNAL
Definition: daemon.c:109
struct MHD_Response * response
Definition: internal.h:573
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:986
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_handle_connection(void *data)
Definition: daemon.c:786
#define MHD_strerror_(errnum)
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:887
#define MHD_socket_close_(fd)
MHD_AccessHandlerCallback default_handler
Definition: internal.h:919
int MHD_socket
Definition: microhttpd.h:185
_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:2998
static void W32_SetThreadName(const DWORD thread_id, const char *thread_name)
Definition: w32functions.h:199
intptr_t value
Definition: microhttpd.h:982
platform-specific includes for libmicrohttpd
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:78
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
Definition: daemon.c:1044
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
Definition: daemon.c:4696
#define MHD_socket_last_strerr_()
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:264
void * uri_log_callback_cls
Definition: internal.h:1046
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
Definition: microhttpd.h:1286
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
Definition: microhttpd.h:663
#define OFF_T_MAX
Definition: mhd_limits.h:52
struct MHD_Daemon * daemon
Definition: internal.h:558
int MHD_pipe
Definition: platform.h:205
int(* idle_handler)(struct MHD_Connection *connection)
Definition: internal.h:832
int listening_address_reuse
Definition: internal.h:1133
MHD_mutex_ per_ip_connection_mutex
Definition: internal.h:1114
MHD_THRD_RTRN_TYPE_(MHD_THRD_CALL_SPEC_ * ThreadStartRoutine)(void *cls)
Definition: daemon.c:1186
struct MHD_Connection * manual_timeout_head
Definition: internal.h:993
MHD_NotifyConnectionCallback notify_connection
Definition: internal.h:1027
struct MHD_Connection * cleanup_head
Definition: internal.h:949
struct MHD_Connection * cleanup_tail
Definition: internal.h:954
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:4360
#define EWOULDBLOCK
Definition: w32functions.h:45
#define MHD_VERSION
Definition: microhttpd.h:133
size_t write_buffer_send_offset
Definition: internal.h:687
#define ECONNRESET
Definition: w32functions.h:96
struct MHD_Daemon * worker_pool
Definition: internal.h:1079
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:132
size_t read_buffer_size
Definition: internal.h:671
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:373
int fd
Definition: microhttpd.h:2145
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:4485
struct MHD_Connection * nextX
Definition: internal.h:548
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:234
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:999
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:1680
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:1742
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:186
MHD_socket socket_fd
Definition: internal.h:743
internal shared structures
void MHD_set_https_callbacks(struct MHD_Connection *connection)
#define _MHD_EXTERN
Definition: microhttpd.h:175
MHD_thread_handle_ pid
Definition: internal.h:663
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:2308
unsigned int connection_limit
Definition: internal.h:1175
unsigned int worker_pool_size
Definition: internal.h:1104
enum MHD_FLAG options
Definition: internal.h:1192
_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:2217
LogCallback uri_log_callback
Definition: internal.h:1041
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:574
static void cleanup(struct Proxy *proxy)
Definition: proxy.c:483
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:3095
int shutdown
Definition: internal.h:1160
Methods for managing connections.
time_t _MHD_TIMEVAL_TV_SEC_TYPE
Definition: platform.h:193
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:219
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_select_thread(void *cls)
Definition: daemon.c:2941
uint16_t port
Definition: internal.h:1197
int(* read_handler)(struct MHD_Connection *connection)
Definition: internal.h:822
unsigned int connections
Definition: internal.h:1170
struct MHD_Connection * normal_timeout_head
Definition: internal.h:980
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:86
#define MHD_snprintf_
void * tfind(const void *vkey, void *const *vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:56
#define ENOTCONN
Definition: w32functions.h:105
_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini)
ReceiveCallback recv_cls
Definition: internal.h:837
size_t thread_stack_size
Definition: internal.h:1099
static void make_nonblocking_noninheritable(struct MHD_Daemon *daemon, MHD_socket sock)
Definition: daemon.c:1841
limits values definitions
MHD_FEATURE
Definition: microhttpd.h:2677
#define MHD_pipe_read_(fd, ptr, sz)
void MHD_monotonic_sec_counter_init(void)
#define MHD_pipe_write_(fd, ptr, sz)
UnescapeCallback unescape_callback
Definition: internal.h:1051
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:253
size_t _MHD_socket_funcs_size
int off_t offset
Definition: microhttpd.h:2145
internal monotonic clock functions implementations
int(* write_handler)(struct MHD_Connection *connection)
Definition: internal.h:827
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:171
static int add_to_fd_set(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: daemon.c:630
static MHD_socket create_socket(struct MHD_Daemon *daemon, int domain, int type, int protocol)
Definition: daemon.c:3490
struct MHD_Connection * connections_head
Definition: internal.h:929
struct MHD_Daemon * master
Definition: internal.h:1074
size_t pool_size
Definition: internal.h:1089
struct MHD_Connection * next
Definition: internal.h:534
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:2655
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:3146
MHD_AcceptPolicyCallback apc
Definition: internal.h:1005
time_t last_activity
Definition: internal.h:723
#define MHD_pipe_(fdarr)
unsigned int connection_timeout
Definition: internal.h:729
#define MHD_pipe_close_(fd)
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:1345
#define MHD_PANIC(msg)
Definition: internal.h:101
struct MemoryPool * pool
Definition: internal.h:585
_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:679
static int create_thread(MHD_thread_handle_ *thread, const struct MHD_Daemon *daemon, ThreadStartRoutine start_routine, void *arg)
Definition: daemon.c:1199
void * ptr_value
Definition: microhttpd.h:988
time_t MHD_monotonic_sec_counter(void)
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:1368
MHD_pipe wpipe[2]
Definition: internal.h:1155
size_t write_buffer_append_offset
Definition: internal.h:693
int resuming
Definition: internal.h:1165
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:1016
struct MHD_Connection * prevX
Definition: internal.h:553
#define MHD_set_socket_errno_(errnum)
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:2711
#define MHD_INVALID_PIPE_
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:86
MHD_thread_handle_ pid
Definition: internal.h:1109
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:4394
void * notify_completed_cls
Definition: internal.h:1021
struct MemoryPool * MHD_pool_create(size_t max)
Definition: memorypool.c:87
TransmitCallback send_cls
Definition: internal.h:842
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:2906
#define XDLL_remove(head, tail, element)
Definition: internal.h:1388
#define DLL_insert(head, tail, element)
Definition: internal.h:1322
MHD_OPTION
MHD options.
Definition: microhttpd.h:671
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:901
#define TIMEVAL_TV_SEC_MAX
Definition: mhd_limits.h:67
void * notify_connection_cls
Definition: internal.h:1032
#define EPOLL_CLOEXEC
Definition: daemon.c:118
void * apc_cls
Definition: internal.h:1010
void * tsearch(const void *vkey, void **vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:23
struct sockaddr * addr
Definition: internal.h:657
static int resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:1776
static int internal_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen, int external_add)
Definition: daemon.c:1280
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
Definition: daemon.c:2973
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:944
MHD_DaemonInfoType
Definition: microhttpd.h:1243
#define MHD_SYS_select_(n, r, w, e, t)
MHD_PanicCallback mhd_panic
Definition: daemon.c:149
#define MHD_pipe_last_strerror_()
void * per_ip_connection_count
Definition: internal.h:1084
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
Definition: daemon.c:4743
size_t read_buffer_offset
Definition: internal.h:677
_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:712
void * default_handler_cls
Definition: internal.h:924
#define MHD_NO
Definition: microhttpd.h:143
unsigned int connection_timeout
Definition: internal.h:1181
static int MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:1947
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1119
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:3034
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Definition: microhttpd.h:1300
void(* MHD_NotifyConnectionCallback)(void *cls, struct MHD_Connection *connection, void **socket_context, enum MHD_ConnectionNotificationCode toe)
Definition: microhttpd.h:1393
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:4642
_MHD_EXTERN size_t MHD_http_unescape(char *val)
Definition: internal.c:132
struct MHD_Connection * connections_tail
Definition: internal.h:934
enum MHD_OPTION option
Definition: microhttpd.h:975
void MHD_monotonic_sec_counter_finish(void)
#define EDLL_insert(head, tail, element)
Definition: internal.h:1411
#define SIZE_MAX
Definition: mhd_limits.h:48
size_t pool_increment
Definition: internal.h:1094
struct MHD_Connection * suspended_connections_head
Definition: internal.h:939
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...