GNU libmicrohttpd  0.9.29
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
daemon.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  (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(_WIN32) && !defined(__CYGWIN__)
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 <limits.h>
40 #include "autoinit_funcs.h"
41 
42 #if HAVE_SEARCH_H
43 #include <search.h>
44 #else
45 #include "tsearch.h"
46 #endif
47 
48 #if HTTPS_SUPPORT
49 #include "connection_https.h"
50 #include <gcrypt.h>
51 #endif
52 
53 #ifdef HAVE_POLL_H
54 #include <poll.h>
55 #endif
56 
57 #ifdef LINUX
58 #include <sys/sendfile.h>
59 #endif
60 
61 #ifdef _WIN32
62 #ifndef WIN32_LEAN_AND_MEAN
63 #define WIN32_LEAN_AND_MEAN 1
64 #endif /* !WIN32_LEAN_AND_MEAN */
65 #include <windows.h>
66 #endif
67 
68 #ifndef HAVE_ACCEPT4
69 #define HAVE_ACCEPT4 0
70 #endif
71 
75 #ifndef WINDOWS
76 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4
77 #else
78 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
79 #endif
80 
84 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
85 
86 #ifdef TCP_FASTOPEN
87 
90 #define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10
91 #endif
92 
97 #define DEBUG_CLOSE MHD_NO
98 
103 #define DEBUG_CONNECT MHD_NO
104 
105 #ifndef LINUX
106 #ifndef MSG_NOSIGNAL
107 #define MSG_NOSIGNAL 0
108 #endif
109 #endif
110 
111 #ifndef SOCK_CLOEXEC
112 #define SOCK_CLOEXEC 0
113 #endif
114 
115 #ifndef EPOLL_CLOEXEC
116 #define EPOLL_CLOEXEC 0
117 #endif
118 
119 
129 static void
130 mhd_panic_std (void *cls,
131  const char *file,
132  unsigned int line,
133  const char *reason)
134 {
135 #if HAVE_MESSAGES
136  fprintf (stderr, "Fatal error in GNU libmicrohttpd %s:%u: %s\n",
137  file, line, reason);
138 #endif
139  abort ();
140 }
141 
142 
147 
152 
153 #ifdef _WIN32
154 
157 static int mhd_winsock_inited_ = 0;
158 #endif
159 
167 static struct MHD_Daemon*
168 MHD_get_master (struct MHD_Daemon *daemon)
169 {
170  while (NULL != daemon->master)
171  daemon = daemon->master;
172  return daemon;
173 }
174 
175 
179 struct MHD_IPCount
180 {
184  int family;
185 
189  union
190  {
194  struct in_addr ipv4;
195 #if HAVE_INET6
196 
199  struct in6_addr ipv6;
200 #endif
201  } addr;
202 
206  unsigned int count;
207 };
208 
209 
215 static void
217 {
218  if (MHD_YES != MHD_mutex_lock_(&daemon->per_ip_connection_mutex))
219  {
220  MHD_PANIC ("Failed to acquire IP connection limit mutex\n");
221  }
222 }
223 
224 
230 static void
232 {
233  if (MHD_YES != MHD_mutex_unlock_(&daemon->per_ip_connection_mutex))
234  {
235  MHD_PANIC ("Failed to release IP connection limit mutex\n");
236  }
237 }
238 
239 
249 static int
250 MHD_ip_addr_compare (const void *a1, const void *a2)
251 {
252  return memcmp (a1, a2, offsetof (struct MHD_IPCount, count));
253 }
254 
255 
264 static int
265 MHD_ip_addr_to_key (const struct sockaddr *addr,
266  socklen_t addrlen,
267  struct MHD_IPCount *key)
268 {
269  memset(key, 0, sizeof(*key));
270 
271  /* IPv4 addresses */
272  if (sizeof (struct sockaddr_in) == addrlen)
273  {
274  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
275  key->family = AF_INET;
276  memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr));
277  return MHD_YES;
278  }
279 
280 #if HAVE_INET6
281  /* IPv6 addresses */
282  if (sizeof (struct sockaddr_in6) == addrlen)
283  {
284  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
285  key->family = AF_INET6;
286  memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr));
287  return MHD_YES;
288  }
289 #endif
290 
291  /* Some other address */
292  return MHD_NO;
293 }
294 
295 
305 static int
306 MHD_ip_limit_add (struct MHD_Daemon *daemon,
307  const struct sockaddr *addr,
308  socklen_t addrlen)
309 {
310  struct MHD_IPCount *key;
311  void **nodep;
312  void *node;
313  int result;
314 
315  daemon = MHD_get_master (daemon);
316  /* Ignore if no connection limit assigned */
317  if (0 == daemon->per_ip_connection_limit)
318  return MHD_YES;
319 
320  if (NULL == (key = malloc (sizeof(*key))))
321  return MHD_NO;
322 
323  /* Initialize key */
324  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key))
325  {
326  /* Allow unhandled address types through */
327  free (key);
328  return MHD_YES;
329  }
330  MHD_ip_count_lock (daemon);
331 
332  /* Search for the IP address */
333  if (NULL == (nodep = tsearch (key,
334  &daemon->per_ip_connection_count,
336  {
337 #if HAVE_MESSAGES
338  MHD_DLOG (daemon,
339  "Failed to add IP connection count node\n");
340 #endif
341  MHD_ip_count_unlock (daemon);
342  free (key);
343  return MHD_NO;
344  }
345  node = *nodep;
346  /* If we got an existing node back, free the one we created */
347  if (node != key)
348  free(key);
349  key = (struct MHD_IPCount *) node;
350  /* Test if there is room for another connection; if so,
351  * increment count */
352  result = (key->count < daemon->per_ip_connection_limit);
353  if (MHD_YES == result)
354  ++key->count;
355 
356  MHD_ip_count_unlock (daemon);
357  return result;
358 }
359 
360 
369 static void
370 MHD_ip_limit_del (struct MHD_Daemon *daemon,
371  const struct sockaddr *addr,
372  socklen_t addrlen)
373 {
374  struct MHD_IPCount search_key;
375  struct MHD_IPCount *found_key;
376  void **nodep;
377 
378  daemon = MHD_get_master (daemon);
379  /* Ignore if no connection limit assigned */
380  if (0 == daemon->per_ip_connection_limit)
381  return;
382  /* Initialize search key */
383  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key))
384  return;
385 
386  MHD_ip_count_lock (daemon);
387 
388  /* Search for the IP address */
389  if (NULL == (nodep = tfind (&search_key,
390  &daemon->per_ip_connection_count,
392  {
393  /* Something's wrong if we couldn't find an IP address
394  * that was previously added */
395  MHD_PANIC ("Failed to find previously-added IP address\n");
396  }
397  found_key = (struct MHD_IPCount *) *nodep;
398  /* Validate existing count for IP address */
399  if (0 == found_key->count)
400  {
401  MHD_PANIC ("Previously-added IP address had 0 count\n");
402  }
403  /* Remove the node entirely if count reduces to 0 */
404  if (0 == --found_key->count)
405  {
406  tdelete (found_key,
407  &daemon->per_ip_connection_count,
409  free (found_key);
410  }
411 
412  MHD_ip_count_unlock (daemon);
413 }
414 
415 
416 #if HTTPS_SUPPORT
417 
425 static ssize_t
426 recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
427 {
428  int res;
429 
430  if (MHD_YES == connection->tls_read_ready)
431  {
432  connection->daemon->num_tls_read_ready--;
433  connection->tls_read_ready = MHD_NO;
434  }
435  res = gnutls_record_recv (connection->tls_session, other, i);
436  if ( (GNUTLS_E_AGAIN == res) ||
437  (GNUTLS_E_INTERRUPTED == res) )
438  {
439  MHD_set_socket_errno_ (EINTR);
440 #if EPOLL_SUPPORT
441  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
442 #endif
443  return -1;
444  }
445  if (res < 0)
446  {
447  /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
448  disrupted); set errno to something caller will interpret
449  correctly as a hard error */
451  return res;
452  }
453  if (res == i)
454  {
455  connection->tls_read_ready = MHD_YES;
456  connection->daemon->num_tls_read_ready++;
457  }
458  return res;
459 }
460 
461 
470 static ssize_t
471 send_tls_adapter (struct MHD_Connection *connection,
472  const void *other, size_t i)
473 {
474  int res;
475 
476  res = gnutls_record_send (connection->tls_session, other, i);
477  if ( (GNUTLS_E_AGAIN == res) ||
478  (GNUTLS_E_INTERRUPTED == res) )
479  {
480  MHD_set_socket_errno_ (EINTR);
481 #if EPOLL_SUPPORT
482  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
483 #endif
484  return -1;
485  }
486  if (res < 0)
487  {
488  /* some other GNUTLS error, should set 'errno'; as we do not
489  really understand the error (not listed in GnuTLS
490  documentation explicitly), we set 'errno' to something that
491  will cause the connection to fail. */
493  return -1;
494  }
495  return res;
496 }
497 
498 
505 static int
506 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
507 {
508  gnutls_datum_t key;
509  gnutls_datum_t cert;
510 
511 #if GNUTLS_VERSION_MAJOR >= 3
512  if (NULL != daemon->cert_callback)
513  {
514  gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
515  daemon->cert_callback);
516  }
517 #endif
518  if (NULL != daemon->https_mem_trust)
519  {
520  cert.data = (unsigned char *) daemon->https_mem_trust;
521  cert.size = strlen (daemon->https_mem_trust);
522  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, &cert,
523  GNUTLS_X509_FMT_PEM) < 0)
524  {
525 #if HAVE_MESSAGES
526  MHD_DLOG(daemon,
527  "Bad trust certificate format\n");
528 #endif
529  return -1;
530  }
531  }
532 
533  if (MHD_YES == daemon->have_dhparams)
534  {
535  gnutls_certificate_set_dh_params (daemon->x509_cred,
536  daemon->https_mem_dhparams);
537  }
538  /* certificate & key loaded from memory */
539  if ( (NULL != daemon->https_mem_cert) &&
540  (NULL != daemon->https_mem_key) )
541  {
542  key.data = (unsigned char *) daemon->https_mem_key;
543  key.size = strlen (daemon->https_mem_key);
544  cert.data = (unsigned char *) daemon->https_mem_cert;
545  cert.size = strlen (daemon->https_mem_cert);
546 
547  return gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
548  &cert, &key,
549  GNUTLS_X509_FMT_PEM);
550  }
551 #if GNUTLS_VERSION_MAJOR >= 3
552  if (NULL != daemon->cert_callback)
553  return 0;
554 #endif
555 #if HAVE_MESSAGES
556  MHD_DLOG (daemon,
557  "You need to specify a certificate and key location\n");
558 #endif
559  return -1;
560 }
561 
562 
569 static int
570 MHD_TLS_init (struct MHD_Daemon *daemon)
571 {
572  switch (daemon->cred_type)
573  {
574  case GNUTLS_CRD_CERTIFICATE:
575  if (0 !=
576  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
577  return GNUTLS_E_MEMORY_ERROR;
578  return MHD_init_daemon_certificate (daemon);
579  default:
580 #if HAVE_MESSAGES
581  MHD_DLOG (daemon,
582  "Error: invalid credentials type %d specified.\n",
583  daemon->cred_type);
584 #endif
585  return -1;
586  }
587 }
588 #endif
589 
590 
601 static int
603  fd_set *set,
604  MHD_socket *max_fd,
605  unsigned int fd_setsize)
606 {
607  if (NULL == set)
608  return MHD_NO;
609 #ifdef MHD_WINSOCK_SOCKETS
610  if (set->fd_count >= fd_setsize)
611  {
612  if (FD_ISSET(fd, set))
613  return MHD_YES;
614  else
615  return MHD_NO;
616  }
617 #else // ! MHD_WINSOCK_SOCKETS
618  if (fd >= fd_setsize)
619  return MHD_NO;
620 #endif // ! MHD_WINSOCK_SOCKETS
621  FD_SET (fd, set);
622  if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) &&
623  ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) )
624  *max_fd = fd;
625 
626  return MHD_YES;
627 }
628 
629 #undef MHD_get_fdset
630 
650 int
651 MHD_get_fdset (struct MHD_Daemon *daemon,
652  fd_set *read_fd_set,
653  fd_set *write_fd_set,
654  fd_set *except_fd_set,
655  MHD_socket *max_fd)
656 {
657  return MHD_get_fdset2(daemon, read_fd_set,
658  write_fd_set, except_fd_set,
659  max_fd, MHD_DEFAULT_FD_SETSIZE);
660 }
661 
683 int
684 MHD_get_fdset2 (struct MHD_Daemon *daemon,
685  fd_set *read_fd_set,
686  fd_set *write_fd_set,
687  fd_set *except_fd_set,
688  MHD_socket *max_fd,
689  unsigned int fd_setsize)
690 {
691  struct MHD_Connection *pos;
692 
693  if ( (NULL == daemon)
694  || (NULL == read_fd_set)
695  || (NULL == write_fd_set)
696  || (MHD_YES == daemon->shutdown)
697  || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
698  || (0 != (daemon->options & MHD_USE_POLL)))
699  return MHD_NO;
700 #if EPOLL_SUPPORT
701  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
702  {
703  /* we're in epoll mode, use the epoll FD as a stand-in for
704  the entire event set */
705 
706  return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd, fd_setsize);
707  }
708 #endif
709  if (MHD_INVALID_SOCKET != daemon->socket_fd &&
710  MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd, fd_setsize))
711  return MHD_NO;
712 
713  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
714  {
715  switch (pos->event_loop_info)
716  {
718  if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
719  return MHD_NO;
720  break;
722  if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd, fd_setsize))
723  return MHD_NO;
724  if (pos->read_buffer_size > pos->read_buffer_offset &&
725  MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
726  return MHD_NO;
727  break;
729  if (pos->read_buffer_size > pos->read_buffer_offset &&
730  MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd, fd_setsize))
731  return MHD_NO;
732  break;
734  /* this should never happen */
735  break;
736  }
737  }
738 #if DEBUG_CONNECT
739 #if HAVE_MESSAGES
740  if (NULL != max_fd)
741  MHD_DLOG (daemon,
742  "Maximum socket in select set: %d\n",
743  *max_fd);
744 #endif
745 #endif
746  return MHD_YES;
747 }
748 
749 
757 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
759 {
760  struct MHD_Connection *con = data;
761  int num_ready;
762  fd_set rs;
763  fd_set ws;
764  MHD_socket max;
765  struct timeval tv;
766  struct timeval *tvp;
767  unsigned int timeout;
768  time_t now;
769 #ifdef HAVE_POLL_H
770  struct pollfd p[1];
771 #endif
772 
773  timeout = con->daemon->connection_timeout;
774  while ( (MHD_YES != con->daemon->shutdown) &&
775  (MHD_CONNECTION_CLOSED != con->state) )
776  {
777  tvp = NULL;
778  if (timeout > 0)
779  {
780  now = MHD_monotonic_time();
781  if (now - con->last_activity > timeout)
782  tv.tv_sec = 0;
783  else
784  tv.tv_sec = timeout - (now - con->last_activity);
785  tv.tv_usec = 0;
786  tvp = &tv;
787  }
788 #if HTTPS_SUPPORT
789  if (MHD_YES == con->tls_read_ready)
790  {
791  /* do not block (more data may be inside of TLS buffers waiting for us) */
792  tv.tv_sec = 0;
793  tv.tv_usec = 0;
794  tvp = &tv;
795  }
796 #endif
797  if (0 == (con->daemon->options & MHD_USE_POLL))
798  {
799  /* use select */
800  int err_state = 0;
801  FD_ZERO (&rs);
802  FD_ZERO (&ws);
803  max = 0;
804  switch (con->event_loop_info)
805  {
807  if (MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
808  err_state = 1;
809  break;
811  if (MHD_YES != add_to_fd_set (con->socket_fd, &ws, &max, FD_SETSIZE))
812  err_state = 1;
813  if (con->read_buffer_size > con->read_buffer_offset &&
814  MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
815  err_state = 1;
816  break;
818  if (con->read_buffer_size > con->read_buffer_offset &&
819  MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max, FD_SETSIZE))
820  err_state = 1;
821  tv.tv_sec = 0;
822  tv.tv_usec = 0;
823  tvp = &tv;
824  break;
826  /* how did we get here!? */
827  goto exit;
828  }
829  if (0 != err_state)
830  {
831 #if HAVE_MESSAGES
832  MHD_DLOG (con->daemon,
833  "Can't add FD to fd_set\n");
834 #endif
835  goto exit;
836  }
837 
838  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp);
839  if (num_ready < 0)
840  {
841  if (EINTR == MHD_socket_errno_)
842  continue;
843 #if HAVE_MESSAGES
844  MHD_DLOG (con->daemon,
845  "Error during select (%d): `%s'\n",
848 #endif
849  break;
850  }
851  /* call appropriate connection handler if necessary */
852  if ( (FD_ISSET (con->socket_fd, &rs))
853 #if HTTPS_SUPPORT
854  || (MHD_YES == con->tls_read_ready)
855 #endif
856  )
857  con->read_handler (con);
858  if (FD_ISSET (con->socket_fd, &ws))
859  con->write_handler (con);
860  if (MHD_NO == con->idle_handler (con))
861  goto exit;
862  }
863 #ifdef HAVE_POLL_H
864  else
865  {
866  /* use poll */
867  memset (&p, 0, sizeof (p));
868  p[0].fd = con->socket_fd;
869  switch (con->event_loop_info)
870  {
872  p[0].events |= POLLIN;
873  break;
875  p[0].events |= POLLOUT;
876  if (con->read_buffer_size > con->read_buffer_offset)
877  p[0].events |= POLLIN;
878  break;
880  if (con->read_buffer_size > con->read_buffer_offset)
881  p[0].events |= POLLIN;
882  tv.tv_sec = 0;
883  tv.tv_usec = 0;
884  tvp = &tv;
885  break;
887  /* how did we get here!? */
888  goto exit;
889  }
890  if (poll (p, 1,
891  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
892  {
893  if (EINTR == MHD_socket_errno_)
894  continue;
895 #if HAVE_MESSAGES
896  MHD_DLOG (con->daemon, "Error during poll: `%s'\n",
898 #endif
899  break;
900  }
901  if ( (0 != (p[0].revents & POLLIN))
902 #if HTTPS_SUPPORT
903  || (MHD_YES == con->tls_read_ready)
904 #endif
905  )
906  con->read_handler (con);
907  if (0 != (p[0].revents & POLLOUT))
908  con->write_handler (con);
909  if (0 != (p[0].revents & (POLLERR | POLLHUP)))
911  if (MHD_NO == con->idle_handler (con))
912  goto exit;
913  }
914 #endif
915  }
916  if (MHD_CONNECTION_IN_CLEANUP != con->state)
917  {
918 #if DEBUG_CLOSE
919 #if HAVE_MESSAGES
920  MHD_DLOG (con->daemon,
921  "Processing thread terminating, closing connection\n");
922 #endif
923 #endif
924  if (MHD_CONNECTION_CLOSED != con->state)
927  con->idle_handler (con);
928  }
929 exit:
930  if (NULL != con->response)
931  {
933  con->response = NULL;
934  }
935  return (MHD_THRD_RTRN_TYPE_)0;
936 }
937 
938 
947 static ssize_t
948 recv_param_adapter (struct MHD_Connection *connection,
949  void *other,
950  size_t i)
951 {
952  ssize_t ret;
953 
954  if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
955  (MHD_CONNECTION_CLOSED == connection->state) )
956  {
958  return -1;
959  }
960  ret = recv (connection->socket_fd, other, i, MSG_NOSIGNAL);
961 #if EPOLL_SUPPORT
962  if (ret < (ssize_t) i)
963  {
964  /* partial read --- no longer read-ready */
965  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
966  }
967 #endif
968  return ret;
969 }
970 
971 
980 static ssize_t
981 send_param_adapter (struct MHD_Connection *connection,
982  const void *other,
983  size_t i)
984 {
985  ssize_t ret;
986 #if LINUX
987  MHD_socket fd;
988  off_t offset;
989  off_t left;
990 #endif
991 
992  if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
993  (MHD_CONNECTION_CLOSED == connection->state) )
994  {
996  return -1;
997  }
998  if (0 != (connection->daemon->options & MHD_USE_SSL))
999  return send (connection->socket_fd, other, i, MSG_NOSIGNAL);
1000 #if LINUX
1001  if ( (connection->write_buffer_append_offset ==
1002  connection->write_buffer_send_offset) &&
1003  (NULL != connection->response) &&
1004  (MHD_INVALID_SOCKET != (fd = connection->response->fd)) )
1005  {
1006  /* can use sendfile */
1007  offset = (off_t) connection->response_write_position + connection->response->fd_off;
1008  left = connection->response->total_size - connection->response_write_position;
1009  if (left > SSIZE_MAX)
1010  left = SSIZE_MAX; /* cap at return value limit */
1011  if (-1 != (ret = sendfile (connection->socket_fd,
1012  fd,
1013  &offset,
1014  (size_t) left)))
1015  {
1016 #if EPOLL_SUPPORT
1017  if (ret < left)
1018  {
1019  /* partial write --- no longer write-ready */
1020  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
1021  }
1022 #endif
1023  return ret;
1024  }
1025  const int err = MHD_socket_errno_;
1026  if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) )
1027  return 0;
1028  if ( (EINVAL == err) || (EBADF == err) )
1029  return -1;
1030  /* None of the 'usual' sendfile errors occurred, so we should try
1031  to fall back to 'SEND'; see also this thread for info on
1032  odd libc/Linux behavior with sendfile:
1033  http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
1034  }
1035 #endif
1036  ret = send (connection->socket_fd, other, i, MSG_NOSIGNAL);
1037 #if EPOLL_SUPPORT
1038  if (ret < (ssize_t) i)
1039  {
1040  /* partial write --- no longer write-ready */
1041  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
1042  }
1043 #endif
1044  /* Handle broken kernel / libc, returning -1 but not setting errno;
1045  kill connection as that should be safe; reported on mailinglist here:
1046  http://lists.gnu.org/archive/html/libmicrohttpd/2014-10/msg00023.html */
1047  if ( (-1 == ret) && (0 == errno) )
1048  errno = ECONNRESET;
1049  return ret;
1050 }
1051 
1052 
1059 typedef MHD_THRD_RTRN_TYPE_ (MHD_THRD_CALL_SPEC_ *ThreadStartRoutine)(void *cls);
1060 
1061 
1071 static int
1072 create_thread (MHD_thread_handle_ *thread,
1073  const struct MHD_Daemon *daemon,
1074  ThreadStartRoutine start_routine,
1075  void *arg)
1076 {
1077 #if defined(MHD_USE_POSIX_THREADS)
1078  pthread_attr_t attr;
1079  pthread_attr_t *pattr;
1080  int ret;
1081 
1082  if (0 != daemon->thread_stack_size)
1083  {
1084  if (0 != (ret = pthread_attr_init (&attr)))
1085  goto ERR;
1086  if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size)))
1087  {
1088  pthread_attr_destroy (&attr);
1089  goto ERR;
1090  }
1091  pattr = &attr;
1092  }
1093  else
1094  {
1095  pattr = NULL;
1096  }
1097  ret = pthread_create (thread, pattr,
1098  start_routine, arg);
1099 #ifdef HAVE_PTHREAD_SETNAME_NP
1100  (void) pthread_setname_np (*thread, "libmicrohttpd");
1101 #endif /* HAVE_PTHREAD_SETNAME_NP */
1102  if (0 != daemon->thread_stack_size)
1103  pthread_attr_destroy (&attr);
1104  return ret;
1105  ERR:
1106 #if HAVE_MESSAGES
1107  MHD_DLOG (daemon,
1108  "Failed to set thread stack size\n");
1109 #endif
1110  errno = EINVAL;
1111  return ret;
1112 #elif defined(MHD_USE_W32_THREADS)
1113  *thread = CreateThread(NULL, daemon->thread_stack_size, start_routine,
1114  arg, 0, NULL);
1115  return (NULL != (*thread)) ? 0 : 1;
1116 #endif
1117 }
1118 
1119 
1146 static int
1148  MHD_socket client_socket,
1149  const struct sockaddr *addr,
1150  socklen_t addrlen,
1151  int external_add)
1152 {
1153  struct MHD_Connection *connection;
1154  int res_thread_create;
1155  unsigned int i;
1156  int eno;
1157  struct MHD_Daemon *worker;
1158 #if OSX
1159  static int on = 1;
1160 #endif
1161 
1162  if (NULL != daemon->worker_pool)
1163  {
1164  /* have a pool, try to find a pool with capacity; we use the
1165  socket as the initial offset into the pool for load
1166  balancing */
1167  for (i=0;i<daemon->worker_pool_size;i++)
1168  {
1169  worker = &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size];
1170  if (worker->connections < worker->connection_limit)
1171  return internal_add_connection (worker,
1172  client_socket,
1173  addr, addrlen,
1174  external_add);
1175  }
1176  /* all pools are at their connection limit, must refuse */
1177  if (0 != MHD_socket_close_ (client_socket))
1178  MHD_PANIC ("close failed\n");
1179 #if ENFILE
1180  errno = ENFILE;
1181 #endif
1182  return MHD_NO;
1183  }
1184 
1185 #ifndef WINDOWS
1186  if ( (client_socket >= FD_SETSIZE) &&
1187  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) )
1188  {
1189 #if HAVE_MESSAGES
1190  MHD_DLOG (daemon,
1191  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
1192  client_socket,
1193  FD_SETSIZE);
1194 #endif
1195  if (0 != MHD_socket_close_ (client_socket))
1196  MHD_PANIC ("close failed\n");
1197 #if EINVAL
1198  errno = EINVAL;
1199 #endif
1200  return MHD_NO;
1201  }
1202 #endif
1203 
1204 
1205 #if HAVE_MESSAGES
1206 #if DEBUG_CONNECT
1207  MHD_DLOG (daemon,
1208  "Accepted connection on socket %d\n",
1209  client_socket);
1210 #endif
1211 #endif
1212  if ( (daemon->connections == daemon->connection_limit) ||
1213  (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) )
1214  {
1215  /* above connection limit - reject */
1216 #if HAVE_MESSAGES
1217  MHD_DLOG (daemon,
1218  "Server reached connection limit (closing inbound connection)\n");
1219 #endif
1220  if (0 != MHD_socket_close_ (client_socket))
1221  MHD_PANIC ("close failed\n");
1222 #if ENFILE
1223  errno = ENFILE;
1224 #endif
1225  return MHD_NO;
1226  }
1227 
1228  /* apply connection acceptance policy if present */
1229  if ( (NULL != daemon->apc) &&
1230  (MHD_NO == daemon->apc (daemon->apc_cls,
1231  addr, addrlen)) )
1232  {
1233 #if DEBUG_CLOSE
1234 #if HAVE_MESSAGES
1235  MHD_DLOG (daemon,
1236  "Connection rejected, closing connection\n");
1237 #endif
1238 #endif
1239  if (0 != MHD_socket_close_ (client_socket))
1240  MHD_PANIC ("close failed\n");
1241  MHD_ip_limit_del (daemon, addr, addrlen);
1242 #if EACCESS
1243  errno = EACCESS;
1244 #endif
1245  return MHD_NO;
1246  }
1247 
1248 #if OSX
1249 #ifdef SOL_SOCKET
1250 #ifdef SO_NOSIGPIPE
1251  setsockopt (client_socket,
1252  SOL_SOCKET, SO_NOSIGPIPE,
1253  &on, sizeof (on));
1254 #endif
1255 #endif
1256 #endif
1257 
1258  if (NULL == (connection = malloc (sizeof (struct MHD_Connection))))
1259  {
1260  eno = errno;
1261 #if HAVE_MESSAGES
1262  MHD_DLOG (daemon,
1263  "Error allocating memory: %s\n",
1264  MHD_strerror_ (errno));
1265 #endif
1266  if (0 != MHD_socket_close_ (client_socket))
1267  MHD_PANIC ("close failed\n");
1268  MHD_ip_limit_del (daemon, addr, addrlen);
1269  errno = eno;
1270  return MHD_NO;
1271  }
1272  memset (connection, 0, sizeof (struct MHD_Connection));
1273  connection->pool = MHD_pool_create (daemon->pool_size);
1274  if (NULL == connection->pool)
1275  {
1276 #if HAVE_MESSAGES
1277  MHD_DLOG (daemon,
1278  "Error allocating memory: %s\n",
1279  MHD_strerror_ (errno));
1280 #endif
1281  if (0 != MHD_socket_close_ (client_socket))
1282  MHD_PANIC ("close failed\n");
1283  MHD_ip_limit_del (daemon, addr, addrlen);
1284  free (connection);
1285 #if ENOMEM
1286  errno = ENOMEM;
1287 #endif
1288  return MHD_NO;
1289  }
1290 
1291  connection->connection_timeout = daemon->connection_timeout;
1292  if (NULL == (connection->addr = malloc (addrlen)))
1293  {
1294  eno = errno;
1295 #if HAVE_MESSAGES
1296  MHD_DLOG (daemon,
1297  "Error allocating memory: %s\n",
1298  MHD_strerror_ (errno));
1299 #endif
1300  if (0 != MHD_socket_close_ (client_socket))
1301  MHD_PANIC ("close failed\n");
1302  MHD_ip_limit_del (daemon, addr, addrlen);
1303  MHD_pool_destroy (connection->pool);
1304  free (connection);
1305  errno = eno;
1306  return MHD_NO;
1307  }
1308  memcpy (connection->addr, addr, addrlen);
1309  connection->addr_len = addrlen;
1310  connection->socket_fd = client_socket;
1311  connection->daemon = daemon;
1312  connection->last_activity = MHD_monotonic_time();
1313 
1314  /* set default connection handlers */
1315  MHD_set_http_callbacks_ (connection);
1316  connection->recv_cls = &recv_param_adapter;
1317  connection->send_cls = &send_param_adapter;
1318 
1319  if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
1320  {
1321  /* non-blocking sockets are required on most systems and for GNUtls;
1322  however, they somehow cause serious problems on CYGWIN (#1824);
1323  in turbo mode, we assume that non-blocking was already set
1324  by 'accept4' or whoever calls 'MHD_add_connection' */
1325 #ifdef CYGWIN
1326  if (0 != (daemon->options & MHD_USE_SSL))
1327 #endif
1328  {
1329  /* make socket non-blocking */
1330 #if !defined(WINDOWS) || defined(CYGWIN)
1331  int flags = fcntl (connection->socket_fd, F_GETFL);
1332  if ( (-1 == flags) ||
1333  (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
1334  {
1335 #if HAVE_MESSAGES
1336  MHD_DLOG (daemon,
1337  "Failed to make socket non-blocking: %s\n",
1339 #endif
1340  }
1341 #else
1342  unsigned long flags = 1;
1343  if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
1344  {
1345 #if HAVE_MESSAGES
1346  MHD_DLOG (daemon,
1347  "Failed to make socket non-blocking: %s\n",
1349 #endif
1350  }
1351 #endif
1352  }
1353  }
1354 
1355 #if HTTPS_SUPPORT
1356  if (0 != (daemon->options & MHD_USE_SSL))
1357  {
1358  connection->recv_cls = &recv_tls_adapter;
1359  connection->send_cls = &send_tls_adapter;
1360  connection->state = MHD_TLS_CONNECTION_INIT;
1361  MHD_set_https_callbacks (connection);
1362  gnutls_init (&connection->tls_session, GNUTLS_SERVER);
1363  gnutls_priority_set (connection->tls_session,
1364  daemon->priority_cache);
1365  switch (daemon->cred_type)
1366  {
1367  /* set needed credentials for certificate authentication. */
1368  case GNUTLS_CRD_CERTIFICATE:
1369  gnutls_credentials_set (connection->tls_session,
1370  GNUTLS_CRD_CERTIFICATE,
1371  daemon->x509_cred);
1372  break;
1373  default:
1374 #if HAVE_MESSAGES
1375  MHD_DLOG (connection->daemon,
1376  "Failed to setup TLS credentials: unknown credential type %d\n",
1377  daemon->cred_type);
1378 #endif
1379  if (0 != MHD_socket_close_ (client_socket))
1380  MHD_PANIC ("close failed\n");
1381  MHD_ip_limit_del (daemon, addr, addrlen);
1382  free (connection->addr);
1383  free (connection);
1384  MHD_PANIC ("Unknown credential type");
1385 #if EINVAL
1386  errno = EINVAL;
1387 #endif
1388  return MHD_NO;
1389  }
1390  gnutls_transport_set_ptr (connection->tls_session,
1391  (gnutls_transport_ptr_t) connection);
1392  gnutls_transport_set_pull_function (connection->tls_session,
1393  (gnutls_pull_func) &recv_param_adapter);
1394  gnutls_transport_set_push_function (connection->tls_session,
1395  (gnutls_push_func) &send_param_adapter);
1396 
1397  if (daemon->https_mem_trust)
1398  gnutls_certificate_server_set_request (connection->tls_session,
1399  GNUTLS_CERT_REQUEST);
1400  }
1401 #endif
1402 
1403  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1404  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1405  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1407  daemon->normal_timeout_tail,
1408  connection);
1409  DLL_insert (daemon->connections_head,
1410  daemon->connections_tail,
1411  connection);
1412  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1413  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1414  MHD_PANIC ("Failed to release cleanup mutex\n");
1415 
1416  /* attempt to create handler thread */
1417  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1418  {
1419  res_thread_create = create_thread (&connection->pid, daemon,
1420  &MHD_handle_connection, connection);
1421  if (0 != res_thread_create)
1422  {
1423  eno = errno;
1424 #if HAVE_MESSAGES
1425  MHD_DLOG (daemon,
1426  "Failed to create a thread: %s\n",
1427  MHD_strerror_ (res_thread_create));
1428 #endif
1429  goto cleanup;
1430  }
1431  }
1432  else
1433  if ( (MHD_YES == external_add) &&
1434  (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1435  (1 != MHD_pipe_write_ (daemon->wpipe[1], "n", 1)) )
1436  {
1437 #if HAVE_MESSAGES
1438  MHD_DLOG (daemon,
1439  "failed to signal new connection via pipe");
1440 #endif
1441  }
1442 #if EPOLL_SUPPORT
1443  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1444  {
1445  if (0 == (daemon->options & MHD_USE_EPOLL_TURBO))
1446  {
1447  struct epoll_event event;
1448 
1449  event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1450  event.data.ptr = connection;
1451  if (0 != epoll_ctl (daemon->epoll_fd,
1452  EPOLL_CTL_ADD,
1453  client_socket,
1454  &event))
1455  {
1456  eno = errno;
1457 #if HAVE_MESSAGES
1458  MHD_DLOG (daemon,
1459  "Call to epoll_ctl failed: %s\n",
1461 #endif
1462  goto cleanup;
1463  }
1464  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1465  }
1466  else
1467  {
1468  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
1470  EDLL_insert (daemon->eready_head,
1471  daemon->eready_tail,
1472  connection);
1473  }
1474  }
1475 #endif
1476  daemon->connections++;
1477  return MHD_YES;
1478  cleanup:
1479  if (0 != MHD_socket_close_ (client_socket))
1480  MHD_PANIC ("close failed\n");
1481  MHD_ip_limit_del (daemon, addr, addrlen);
1482  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1483  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1484  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1485  DLL_remove (daemon->connections_head,
1486  daemon->connections_tail,
1487  connection);
1489  daemon->normal_timeout_tail,
1490  connection);
1491  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1492  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1493  MHD_PANIC ("Failed to release cleanup mutex\n");
1494  MHD_pool_destroy (connection->pool);
1495  free (connection->addr);
1496  free (connection);
1497 #if EINVAL
1498  errno = eno;
1499 #endif
1500  return MHD_NO;
1501 }
1502 
1503 
1531 void
1533 {
1534  struct MHD_Daemon *daemon;
1535 
1536  daemon = connection->daemon;
1538  MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1539  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1540  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1541  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1542  DLL_remove (daemon->connections_head,
1543  daemon->connections_tail,
1544  connection);
1547  connection);
1548  if (connection->connection_timeout == daemon->connection_timeout)
1550  daemon->normal_timeout_tail,
1551  connection);
1552  else
1554  daemon->manual_timeout_tail,
1555  connection);
1556 #if EPOLL_SUPPORT
1557  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1558  {
1559  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1560  {
1561  EDLL_remove (daemon->eready_head,
1562  daemon->eready_tail,
1563  connection);
1564  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
1565  }
1566  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
1567  {
1568  if (0 != epoll_ctl (daemon->epoll_fd,
1569  EPOLL_CTL_DEL,
1570  connection->socket_fd,
1571  NULL))
1572  MHD_PANIC ("Failed to remove FD from epoll set\n");
1573  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1574  }
1575  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
1576  }
1577 #endif
1578  connection->suspended = MHD_YES;
1579  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1580  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1581  MHD_PANIC ("Failed to release cleanup mutex\n");
1582 }
1583 
1584 
1593 void
1595 {
1596  struct MHD_Daemon *daemon;
1597 
1598  daemon = connection->daemon;
1600  MHD_PANIC ("Cannot resume connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1601  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1602  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1603  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1604  connection->resuming = MHD_YES;
1605  daemon->resuming = MHD_YES;
1606  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1607  (1 != MHD_pipe_write_ (daemon->wpipe[1], "r", 1)) )
1608  {
1609 #if HAVE_MESSAGES
1610  MHD_DLOG (daemon,
1611  "failed to signal resume via pipe");
1612 #endif
1613  }
1614  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1615  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1616  MHD_PANIC ("Failed to release cleanup mutex\n");
1617 }
1618 
1619 
1626 static void
1628 {
1629  struct MHD_Connection *pos;
1630  struct MHD_Connection *next = NULL;
1631 
1632  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1633  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1634  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1635 
1636  if (MHD_YES == daemon->resuming)
1637  next = daemon->suspended_connections_head;
1638 
1639  while (NULL != (pos = next))
1640  {
1641  next = pos->next;
1642  if (MHD_NO == pos->resuming)
1643  continue;
1644 
1647  pos);
1648  DLL_insert (daemon->connections_head,
1649  daemon->connections_tail,
1650  pos);
1651  if (pos->connection_timeout == daemon->connection_timeout)
1653  daemon->normal_timeout_tail,
1654  pos);
1655  else
1657  daemon->manual_timeout_tail,
1658  pos);
1659 #if EPOLL_SUPPORT
1660  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1661  {
1662  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1663  MHD_PANIC ("Resumed connection was already in EREADY set\n");
1664  /* we always mark resumed connections as ready, as we
1665  might have missed the edge poll event during suspension */
1666  EDLL_insert (daemon->eready_head,
1667  daemon->eready_tail,
1668  pos);
1669  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
1670  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
1671  }
1672 #endif
1673  pos->suspended = MHD_NO;
1674  pos->resuming = MHD_NO;
1675  }
1676  daemon->resuming = MHD_NO;
1677  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1678  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1679  MHD_PANIC ("Failed to release cleanup mutex\n");
1680 }
1681 
1682 
1689 static void
1691  MHD_socket sock)
1692 {
1693 #ifdef WINDOWS
1694  DWORD dwFlags;
1695  unsigned long flags = 1;
1696 
1697  if (0 != ioctlsocket (sock, FIONBIO, &flags))
1698  {
1699 #if HAVE_MESSAGES
1700  MHD_DLOG (daemon,
1701  "Failed to make socket non-blocking: %s\n",
1703 #endif
1704  }
1705  if (!GetHandleInformation ((HANDLE) sock, &dwFlags) ||
1706  ((dwFlags != (dwFlags & ~HANDLE_FLAG_INHERIT)) &&
1707  !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)))
1708  {
1709 #if HAVE_MESSAGES
1710  MHD_DLOG (daemon,
1711  "Failed to make socket non-inheritable: %u\n",
1712  (unsigned int) GetLastError ());
1713 #endif
1714  }
1715 #else
1716  int flags;
1717  int nonblock;
1718 
1719  nonblock = O_NONBLOCK;
1720 #ifdef CYGWIN
1721  if (0 == (daemon->options & MHD_USE_SSL))
1722  nonblock = 0;
1723 #endif
1724  flags = fcntl (sock, F_GETFD);
1725  if ( ( (-1 == flags) ||
1726  ( (flags != (flags | FD_CLOEXEC)) &&
1727  (0 != fcntl (sock, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) )
1728  {
1729 #if HAVE_MESSAGES
1730  MHD_DLOG (daemon,
1731  "Failed to make socket non-inheritable: %s\n",
1733 #endif
1734  }
1735 #endif
1736 }
1737 
1738 
1768 int
1770  MHD_socket client_socket,
1771  const struct sockaddr *addr,
1772  socklen_t addrlen)
1773 {
1775  client_socket);
1776  return internal_add_connection (daemon,
1777  client_socket,
1778  addr, addrlen,
1779  MHD_YES);
1780 }
1781 
1782 
1795 static int
1797 {
1798 #if HAVE_INET6
1799  struct sockaddr_in6 addrstorage;
1800 #else
1801  struct sockaddr_in addrstorage;
1802 #endif
1803  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
1804  socklen_t addrlen;
1805  MHD_socket s;
1806  MHD_socket fd;
1807  int nonblock;
1808 
1809  addrlen = sizeof (addrstorage);
1810  memset (addr, 0, sizeof (addrstorage));
1811  if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd))
1812  return MHD_NO;
1813 #ifdef HAVE_SOCK_NONBLOCK
1814  nonblock = SOCK_NONBLOCK;
1815 #else
1816  nonblock = 0;
1817 #endif
1818 #ifdef CYGWIN
1819  if (0 == (daemon->options & MHD_USE_SSL))
1820  nonblock = 0;
1821 #endif
1822 #if HAVE_ACCEPT4
1823  s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock);
1824 #else
1825  s = accept (fd, addr, &addrlen);
1826 #endif
1827  if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0))
1828  {
1829 #if HAVE_MESSAGES
1830  const int err = MHD_socket_errno_;
1831  /* This could be a common occurance with multiple worker threads */
1832  if ((EAGAIN != err) && (EWOULDBLOCK != err))
1833  MHD_DLOG (daemon,
1834  "Error accepting connection: %s\n",
1836 #endif
1837  if (MHD_INVALID_SOCKET != s)
1838  {
1839  if (0 != MHD_socket_close_ (s))
1840  MHD_PANIC ("close failed\n");
1841  /* just in case */
1842  }
1843  return MHD_NO;
1844  }
1845 #if !defined(HAVE_ACCEPT4) || HAVE_ACCEPT4+0 == 0 || !defined(HAVE_SOCK_NONBLOCK) || SOCK_CLOEXEC+0 == 0
1846  make_nonblocking_noninheritable (daemon, s);
1847 #endif
1848 #if HAVE_MESSAGES
1849 #if DEBUG_CONNECT
1850  MHD_DLOG (daemon,
1851  "Accepted connection on socket %d\n",
1852  s);
1853 #endif
1854 #endif
1855  (void) internal_add_connection (daemon, s,
1856  addr, addrlen,
1857  MHD_NO);
1858  return MHD_YES;
1859 }
1860 
1861 
1869 static void
1871 {
1872  struct MHD_Connection *pos;
1873 
1874  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1875  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
1876  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1877  while (NULL != (pos = daemon->cleanup_head))
1878  {
1879  DLL_remove (daemon->cleanup_head,
1880  daemon->cleanup_tail,
1881  pos);
1882  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1883  (MHD_NO == pos->thread_joined) )
1884  {
1885  if (0 != MHD_join_thread_ (pos->pid))
1886  {
1887  MHD_PANIC ("Failed to join a thread\n");
1888  }
1889  }
1890  MHD_pool_destroy (pos->pool);
1891 #if HTTPS_SUPPORT
1892  if (pos->tls_session != NULL)
1893  gnutls_deinit (pos->tls_session);
1894 #endif
1895  MHD_ip_limit_del (daemon,
1896  (struct sockaddr *) pos->addr,
1897  pos->addr_len);
1898 #if EPOLL_SUPPORT
1899  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1900  {
1901  EDLL_remove (daemon->eready_head,
1902  daemon->eready_tail,
1903  pos);
1904  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
1905  }
1906  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
1907  (MHD_INVALID_SOCKET != daemon->epoll_fd) &&
1908  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
1909  {
1910  /* epoll documentation suggests that closing a FD
1911  automatically removes it from the epoll set; however,
1912  this is not true as if we fail to do manually remove it,
1913  we are still seeing an event for this fd in epoll,
1914  causing grief (use-after-free...) --- at least on my
1915  system. */
1916  if (0 != epoll_ctl (daemon->epoll_fd,
1917  EPOLL_CTL_DEL,
1918  pos->socket_fd,
1919  NULL))
1920  MHD_PANIC ("Failed to remove FD from epoll set\n");
1921  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1922  }
1923 #endif
1924  if (NULL != pos->response)
1925  {
1927  pos->response = NULL;
1928  }
1929  if (MHD_INVALID_SOCKET != pos->socket_fd)
1930  {
1931 #ifdef WINDOWS
1932  shutdown (pos->socket_fd, SHUT_WR);
1933 #endif
1934  if (0 != MHD_socket_close_ (pos->socket_fd))
1935  MHD_PANIC ("close failed\n");
1936  }
1937  if (NULL != pos->addr)
1938  free (pos->addr);
1939  free (pos);
1940  daemon->connections--;
1941  }
1942  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1943  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1944  MHD_PANIC ("Failed to release cleanup mutex\n");
1945 }
1946 
1947 
1962 int
1963 MHD_get_timeout (struct MHD_Daemon *daemon,
1964  MHD_UNSIGNED_LONG_LONG *timeout)
1965 {
1966  time_t earliest_deadline;
1967  time_t now;
1968  struct MHD_Connection *pos;
1969  int have_timeout;
1970 
1971  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1972  {
1973 #if HAVE_MESSAGES
1974  MHD_DLOG (daemon,
1975  "Illegal call to MHD_get_timeout\n");
1976 #endif
1977  return MHD_NO;
1978  }
1979 
1980 #if HTTPS_SUPPORT
1981  if (0 != daemon->num_tls_read_ready)
1982  {
1983  /* if there is any TLS connection with data ready for
1984  reading, we must not block in the event loop */
1985  *timeout = 0;
1986  return MHD_YES;
1987  }
1988 #endif
1989 
1990  have_timeout = MHD_NO;
1991  earliest_deadline = 0; /* avoid compiler warnings */
1992  for (pos = daemon->manual_timeout_head; NULL != pos; pos = pos->nextX)
1993  {
1994  if (0 != pos->connection_timeout)
1995  {
1996  if ( (! have_timeout) ||
1997  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
1998  earliest_deadline = pos->last_activity + pos->connection_timeout;
1999 #if HTTPS_SUPPORT
2000  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
2001  (0 != gnutls_record_check_pending (pos->tls_session)) )
2002  earliest_deadline = 0;
2003 #endif
2004  have_timeout = MHD_YES;
2005  }
2006  }
2007  /* normal timeouts are sorted, so we only need to look at the 'head' */
2008  pos = daemon->normal_timeout_head;
2009  if ( (NULL != pos) &&
2010  (0 != pos->connection_timeout) )
2011  {
2012  if ( (! have_timeout) ||
2013  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
2014  earliest_deadline = pos->last_activity + pos->connection_timeout;
2015 #if HTTPS_SUPPORT
2016  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
2017  (0 != gnutls_record_check_pending (pos->tls_session)) )
2018  earliest_deadline = 0;
2019 #endif
2020  have_timeout = MHD_YES;
2021  }
2022 
2023  if (MHD_NO == have_timeout)
2024  return MHD_NO;
2025  now = MHD_monotonic_time();
2026  if (earliest_deadline < now)
2027  *timeout = 0;
2028  else
2029  *timeout = 1000 * (1 + earliest_deadline - now);
2030  return MHD_YES;
2031 }
2032 
2033 
2053 int
2055  const fd_set *read_fd_set,
2056  const fd_set *write_fd_set,
2057  const fd_set *except_fd_set)
2058 {
2059  MHD_socket ds;
2060  char tmp;
2061  struct MHD_Connection *pos;
2062  struct MHD_Connection *next;
2063 
2064 #if EPOLL_SUPPORT
2065  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2066  {
2067  /* we're in epoll mode, the epoll FD stands for
2068  the entire event set! */
2069  if (daemon->epoll_fd >= FD_SETSIZE)
2070  return MHD_NO; /* poll fd too big, fail hard */
2071  if (FD_ISSET (daemon->epoll_fd, read_fd_set))
2072  return MHD_run (daemon);
2073  return MHD_YES;
2074  }
2075 #endif
2076 
2077  /* select connection thread handling type */
2078  if ( (MHD_INVALID_SOCKET != (ds = daemon->socket_fd)) &&
2079  (FD_ISSET (ds, read_fd_set)) )
2080  (void) MHD_accept_connection (daemon);
2081  /* drain signaling pipe to avoid spinning select */
2082  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2083  (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
2084  (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2085 
2086  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2087  {
2088  /* do not have a thread per connection, process all connections now */
2089  next = daemon->connections_head;
2090  while (NULL != (pos = next))
2091  {
2092  next = pos->next;
2093  ds = pos->socket_fd;
2094  if (MHD_INVALID_SOCKET == ds)
2095  continue;
2096  switch (pos->event_loop_info)
2097  {
2099  if ( (FD_ISSET (ds, read_fd_set))
2100 #if HTTPS_SUPPORT
2101  || (MHD_YES == pos->tls_read_ready)
2102 #endif
2103  )
2104  pos->read_handler (pos);
2105  break;
2107  if ( (FD_ISSET (ds, read_fd_set)) &&
2108  (pos->read_buffer_size > pos->read_buffer_offset) )
2109  pos->read_handler (pos);
2110  if (FD_ISSET (ds, write_fd_set))
2111  pos->write_handler (pos);
2112  break;
2114  if ( (FD_ISSET (ds, read_fd_set)) &&
2115  (pos->read_buffer_size > pos->read_buffer_offset) )
2116  pos->read_handler (pos);
2117  break;
2119  /* should never happen */
2120  break;
2121  }
2122  pos->idle_handler (pos);
2123  }
2124  }
2125  MHD_cleanup_connections (daemon);
2126  return MHD_YES;
2127 }
2128 
2129 
2138 static int
2139 MHD_select (struct MHD_Daemon *daemon,
2140  int may_block)
2141 {
2142  int num_ready;
2143  fd_set rs;
2144  fd_set ws;
2145  fd_set es;
2146  MHD_socket max;
2147  struct timeval timeout;
2148  struct timeval *tv;
2149  MHD_UNSIGNED_LONG_LONG ltimeout;
2150 
2151  timeout.tv_sec = 0;
2152  timeout.tv_usec = 0;
2153  if (MHD_YES == daemon->shutdown)
2154  return MHD_NO;
2155  FD_ZERO (&rs);
2156  FD_ZERO (&ws);
2157  FD_ZERO (&es);
2158  max = MHD_INVALID_SOCKET;
2159  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2160  {
2163 
2164  /* single-threaded, go over everything */
2165  if (MHD_NO == MHD_get_fdset2 (daemon, &rs, &ws, &es, &max, FD_SETSIZE))
2166  return MHD_NO;
2167 
2168  /* If we're at the connection limit, no need to
2169  accept new connections. */
2170  if ( (daemon->connections == daemon->connection_limit) &&
2171  (MHD_INVALID_SOCKET != daemon->socket_fd) )
2172  FD_CLR (daemon->socket_fd, &rs);
2173  }
2174  else
2175  {
2176  /* accept only, have one thread per connection */
2177  if (MHD_INVALID_SOCKET != daemon->socket_fd &&
2178  MHD_YES != add_to_fd_set(daemon->socket_fd, &rs, &max, FD_SETSIZE))
2179  return MHD_NO;
2180  }
2181  if (MHD_INVALID_PIPE_ != daemon->wpipe[0] &&
2182  MHD_YES != add_to_fd_set(daemon->wpipe[0], &rs, &max, FD_SETSIZE))
2183  return MHD_NO;
2184 
2185  tv = NULL;
2186  if (MHD_NO == may_block)
2187  {
2188  timeout.tv_usec = 0;
2189  timeout.tv_sec = 0;
2190  tv = &timeout;
2191  }
2192  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2193  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
2194  {
2195  /* ltimeout is in ms */
2196  timeout.tv_usec = (ltimeout % 1000) * 1000;
2197  timeout.tv_sec = ltimeout / 1000;
2198  tv = &timeout;
2199  }
2200  if (MHD_INVALID_SOCKET == max)
2201  return MHD_YES;
2202  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, &es, tv);
2203  if (MHD_YES == daemon->shutdown)
2204  return MHD_NO;
2205  if (num_ready < 0)
2206  {
2207  if (EINTR == MHD_socket_errno_)
2208  return MHD_YES;
2209 #if HAVE_MESSAGES
2210  MHD_DLOG (daemon,
2211  "select failed: %s\n",
2213 #endif
2214  return MHD_NO;
2215  }
2216  return MHD_run_from_select (daemon, &rs, &ws, &es);
2217 }
2218 
2219 
2220 #ifdef HAVE_POLL_H
2221 
2229 static int
2230 MHD_poll_all (struct MHD_Daemon *daemon,
2231  int may_block)
2232 {
2233  unsigned int num_connections;
2234  struct MHD_Connection *pos;
2235  struct MHD_Connection *next;
2236 
2239 
2240  /* count number of connections and thus determine poll set size */
2241  num_connections = 0;
2242  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2243  num_connections++;
2244  {
2245  struct pollfd p[2 + num_connections];
2246  MHD_UNSIGNED_LONG_LONG ltimeout;
2247  unsigned int i;
2248  int timeout;
2249  unsigned int poll_server;
2250  int poll_listen;
2251 
2252  memset (p, 0, sizeof (p));
2253  poll_server = 0;
2254  poll_listen = -1;
2255  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2256  (daemon->connections < daemon->connection_limit) )
2257  {
2258  /* only listen if we are not at the connection limit */
2259  p[poll_server].fd = daemon->socket_fd;
2260  p[poll_server].events = POLLIN;
2261  p[poll_server].revents = 0;
2262  poll_listen = (int) poll_server;
2263  poll_server++;
2264  }
2265  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2266  {
2267  p[poll_server].fd = daemon->wpipe[0];
2268  p[poll_server].events = POLLIN;
2269  p[poll_server].revents = 0;
2270  poll_server++;
2271  }
2272  if (may_block == MHD_NO)
2273  timeout = 0;
2274  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2275  (MHD_YES != MHD_get_timeout (daemon, &ltimeout)) )
2276  timeout = -1;
2277  else
2278  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
2279 
2280  i = 0;
2281  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2282  {
2283  p[poll_server+i].fd = pos->socket_fd;
2284  switch (pos->event_loop_info)
2285  {
2287  p[poll_server+i].events |= POLLIN;
2288  break;
2290  p[poll_server+i].events |= POLLOUT;
2291  if (pos->read_buffer_size > pos->read_buffer_offset)
2292  p[poll_server+i].events |= POLLIN;
2293  break;
2295  if (pos->read_buffer_size > pos->read_buffer_offset)
2296  p[poll_server+i].events |= POLLIN;
2297  break;
2299  /* should never happen */
2300  break;
2301  }
2302  i++;
2303  }
2304  if (0 == poll_server + num_connections)
2305  return MHD_YES;
2306  if (poll (p, poll_server + num_connections, timeout) < 0)
2307  {
2308  if (EINTR == MHD_socket_errno_)
2309  return MHD_YES;
2310 #if HAVE_MESSAGES
2311  MHD_DLOG (daemon,
2312  "poll failed: %s\n",
2314 #endif
2315  return MHD_NO;
2316  }
2317  /* handle shutdown */
2318  if (MHD_YES == daemon->shutdown)
2319  return MHD_NO;
2320  i = 0;
2321  next = daemon->connections_head;
2322  while (NULL != (pos = next))
2323  {
2324  next = pos->next;
2325  switch (pos->event_loop_info)
2326  {
2328  /* first, sanity checks */
2329  if (i >= num_connections)
2330  break; /* connection list changed somehow, retry later ... */
2331  if (p[poll_server+i].fd != pos->socket_fd)
2332  break; /* fd mismatch, something else happened, retry later ... */
2333  /* normal handling */
2334  if (0 != (p[poll_server+i].revents & POLLIN))
2335  pos->read_handler (pos);
2336  pos->idle_handler (pos);
2337  i++;
2338  break;
2340  /* first, sanity checks */
2341  if (i >= num_connections)
2342  break; /* connection list changed somehow, retry later ... */
2343  if (p[poll_server+i].fd != pos->socket_fd)
2344  break; /* fd mismatch, something else happened, retry later ... */
2345  /* normal handling */
2346  if (0 != (p[poll_server+i].revents & POLLIN))
2347  pos->read_handler (pos);
2348  if (0 != (p[poll_server+i].revents & POLLOUT))
2349  pos->write_handler (pos);
2350  pos->idle_handler (pos);
2351  i++;
2352  break;
2354  if (0 != (p[poll_server+i].revents & POLLIN))
2355  pos->read_handler (pos);
2356  pos->idle_handler (pos);
2357  break;
2359  /* should never happen */
2360  break;
2361  }
2362  }
2363  /* handle 'listen' FD */
2364  if ( (-1 != poll_listen) &&
2365  (0 != (p[poll_listen].revents & POLLIN)) )
2366  (void) MHD_accept_connection (daemon);
2367  }
2368  return MHD_YES;
2369 }
2370 
2371 
2379 static int
2380 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2381  int may_block)
2382 {
2383  struct pollfd p[2];
2384  int timeout;
2385  unsigned int poll_count;
2386  int poll_listen;
2387 
2388  memset (&p, 0, sizeof (p));
2389  poll_count = 0;
2390  poll_listen = -1;
2391  if (MHD_INVALID_SOCKET != daemon->socket_fd)
2392  {
2393  p[poll_count].fd = daemon->socket_fd;
2394  p[poll_count].events = POLLIN;
2395  p[poll_count].revents = 0;
2396  poll_listen = poll_count;
2397  poll_count++;
2398  }
2399  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2400  {
2401  p[poll_count].fd = daemon->wpipe[0];
2402  p[poll_count].events = POLLIN;
2403  p[poll_count].revents = 0;
2404  poll_count++;
2405  }
2406  if (MHD_NO == may_block)
2407  timeout = 0;
2408  else
2409  timeout = -1;
2410  if (0 == poll_count)
2411  return MHD_YES;
2412  if (poll (p, poll_count, timeout) < 0)
2413  {
2414  if (EINTR == MHD_socket_errno_)
2415  return MHD_YES;
2416 #if HAVE_MESSAGES
2417  MHD_DLOG (daemon,
2418  "poll failed: %s\n",
2420 #endif
2421  return MHD_NO;
2422  }
2423  /* handle shutdown */
2424  if (MHD_YES == daemon->shutdown)
2425  return MHD_NO;
2426  if ( (-1 != poll_listen) &&
2427  (0 != (p[poll_listen].revents & POLLIN)) )
2428  (void) MHD_accept_connection (daemon);
2429  return MHD_YES;
2430 }
2431 #endif
2432 
2433 
2441 static int
2442 MHD_poll (struct MHD_Daemon *daemon,
2443  int may_block)
2444 {
2445 #ifdef HAVE_POLL_H
2446  if (MHD_YES == daemon->shutdown)
2447  return MHD_NO;
2448  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2449  return MHD_poll_all (daemon, may_block);
2450  else
2451  return MHD_poll_listen_socket (daemon, may_block);
2452 #else
2453  return MHD_NO;
2454 #endif
2455 }
2456 
2457 
2458 #if EPOLL_SUPPORT
2459 
2468 #define MAX_EVENTS 128
2469 
2470 
2479 static int
2480 MHD_epoll (struct MHD_Daemon *daemon,
2481  int may_block)
2482 {
2483  struct MHD_Connection *pos;
2484  struct MHD_Connection *next;
2485  struct epoll_event events[MAX_EVENTS];
2486  struct epoll_event event;
2487  int timeout_ms;
2488  MHD_UNSIGNED_LONG_LONG timeout_ll;
2489  int num_events;
2490  unsigned int i;
2491  unsigned int series_length;
2492  char tmp;
2493 
2494  if (-1 == daemon->epoll_fd)
2495  return MHD_NO; /* we're down! */
2496  if (MHD_YES == daemon->shutdown)
2497  return MHD_NO;
2498  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2499  (daemon->connections < daemon->connection_limit) &&
2500  (MHD_NO == daemon->listen_socket_in_epoll) )
2501  {
2502  event.events = EPOLLIN;
2503  event.data.ptr = daemon;
2504  if (0 != epoll_ctl (daemon->epoll_fd,
2505  EPOLL_CTL_ADD,
2506  daemon->socket_fd,
2507  &event))
2508  {
2509 #if HAVE_MESSAGES
2510  MHD_DLOG (daemon,
2511  "Call to epoll_ctl failed: %s\n",
2513 #endif
2514  return MHD_NO;
2515  }
2516  daemon->listen_socket_in_epoll = MHD_YES;
2517  }
2518  if ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2519  (daemon->connections == daemon->connection_limit) )
2520  {
2521  /* we're at the connection limit, disable listen socket
2522  for event loop for now */
2523  if (0 != epoll_ctl (daemon->epoll_fd,
2524  EPOLL_CTL_DEL,
2525  daemon->socket_fd,
2526  NULL))
2527  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2528  daemon->listen_socket_in_epoll = MHD_NO;
2529  }
2530  if (MHD_YES == may_block)
2531  {
2532  if (MHD_YES == MHD_get_timeout (daemon,
2533  &timeout_ll))
2534  {
2535  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
2536  timeout_ms = INT_MAX;
2537  else
2538  timeout_ms = (int) timeout_ll;
2539  }
2540  else
2541  timeout_ms = -1;
2542  }
2543  else
2544  timeout_ms = 0;
2545 
2546  /* drain 'epoll' event queue; need to iterate as we get at most
2547  MAX_EVENTS in one system call here; in practice this should
2548  pretty much mean only one round, but better an extra loop here
2549  than unfair behavior... */
2550  num_events = MAX_EVENTS;
2551  while (MAX_EVENTS == num_events)
2552  {
2553  /* update event masks */
2554  num_events = epoll_wait (daemon->epoll_fd,
2555  events, MAX_EVENTS, timeout_ms);
2556  if (-1 == num_events)
2557  {
2558  if (EINTR == MHD_socket_errno_)
2559  return MHD_YES;
2560 #if HAVE_MESSAGES
2561  MHD_DLOG (daemon,
2562  "Call to epoll_wait failed: %s\n",
2564 #endif
2565  return MHD_NO;
2566  }
2567  for (i=0;i<(unsigned int) num_events;i++)
2568  {
2569  if (NULL == events[i].data.ptr)
2570  continue; /* shutdown signal! */
2571  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2572  (daemon->wpipe[0] == events[i].data.fd) )
2573  {
2574  (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2575  continue;
2576  }
2577  if (daemon != events[i].data.ptr)
2578  {
2579  /* this is an event relating to a 'normal' connection,
2580  remember the event and if appropriate mark the
2581  connection as 'eready'. */
2582  pos = events[i].data.ptr;
2583  if (0 != (events[i].events & EPOLLIN))
2584  {
2585  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
2586  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
2587  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
2588  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2589  {
2590  EDLL_insert (daemon->eready_head,
2591  daemon->eready_tail,
2592  pos);
2593  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2594  }
2595  }
2596  if (0 != (events[i].events & EPOLLOUT))
2597  {
2598  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
2599  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
2600  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2601  {
2602  EDLL_insert (daemon->eready_head,
2603  daemon->eready_tail,
2604  pos);
2605  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2606  }
2607  }
2608  }
2609  else /* must be listen socket */
2610  {
2611  /* run 'accept' until it fails or we are not allowed to take
2612  on more connections */
2613  series_length = 0;
2614  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2615  (daemon->connections < daemon->connection_limit) &&
2616  (series_length < 128) )
2617  series_length++;
2618  }
2619  }
2620  }
2621 
2622  /* we handle resumes here because we may have ready connections
2623  that will not be placed into the epoll list immediately. */
2626 
2627  /* process events for connections */
2628  while (NULL != (pos = daemon->eready_tail))
2629  {
2630  EDLL_remove (daemon->eready_head,
2631  daemon->eready_tail,
2632  pos);
2633  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2635  pos->read_handler (pos);
2637  pos->write_handler (pos);
2638  pos->idle_handler (pos);
2639  }
2640  /* Finally, handle timed-out connections; we need to do this here
2641  as the epoll mechanism won't call the 'idle_handler' on everything,
2642  as the other event loops do. As timeouts do not get an explicit
2643  event, we need to find those connections that might have timed out
2644  here.
2645 
2646  Connections with custom timeouts must all be looked at, as we
2647  do not bother to sort that (presumably very short) list. */
2648  next = daemon->manual_timeout_head;
2649  while (NULL != (pos = next))
2650  {
2651  next = pos->nextX;
2652  pos->idle_handler (pos);
2653  }
2654  /* Connections with the default timeout are sorted by prepending
2655  them to the head of the list whenever we touch the connection;
2656  thus it sufficies to iterate from the tail until the first
2657  connection is NOT timed out */
2658  next = daemon->normal_timeout_tail;
2659  while (NULL != (pos = next))
2660  {
2661  next = pos->prevX;
2662  pos->idle_handler (pos);
2663  if (MHD_CONNECTION_CLOSED != pos->state)
2664  break; /* sorted by timeout, no need to visit the rest! */
2665  }
2666  return MHD_YES;
2667 }
2668 #endif
2669 
2670 
2690 int
2691 MHD_run (struct MHD_Daemon *daemon)
2692 {
2693  if ( (MHD_YES == daemon->shutdown) ||
2694  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2695  (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2696  return MHD_NO;
2697  if (0 != (daemon->options & MHD_USE_POLL))
2698  {
2699  MHD_poll (daemon, MHD_NO);
2700  MHD_cleanup_connections (daemon);
2701  }
2702 #if EPOLL_SUPPORT
2703  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2704  {
2705  MHD_epoll (daemon, MHD_NO);
2706  MHD_cleanup_connections (daemon);
2707  }
2708 #endif
2709  else
2710  {
2711  MHD_select (daemon, MHD_NO);
2712  /* MHD_select does MHD_cleanup_connections already */
2713  }
2714  return MHD_YES;
2715 }
2716 
2717 
2725 static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_
2727 {
2728  struct MHD_Daemon *daemon = cls;
2729 
2730  while (MHD_YES != daemon->shutdown)
2731  {
2732  if (0 != (daemon->options & MHD_USE_POLL))
2733  MHD_poll (daemon, MHD_YES);
2734 #if EPOLL_SUPPORT
2735  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2736  MHD_epoll (daemon, MHD_YES);
2737 #endif
2738  else
2739  MHD_select (daemon, MHD_YES);
2740  MHD_cleanup_connections (daemon);
2741  }
2742  return (MHD_THRD_RTRN_TYPE_)0;
2743 }
2744 
2745 
2757 static size_t
2758 unescape_wrapper (void *cls,
2759  struct MHD_Connection *connection,
2760  char *val)
2761 {
2762  return MHD_http_unescape (val);
2763 }
2764 
2765 
2782 struct MHD_Daemon *
2783 MHD_start_daemon (unsigned int flags,
2784  uint16_t port,
2786  void *apc_cls,
2787  MHD_AccessHandlerCallback dh, void *dh_cls, ...)
2788 {
2789  struct MHD_Daemon *daemon;
2790  va_list ap;
2791 
2792  va_start (ap, dh_cls);
2793  daemon = MHD_start_daemon_va (flags, port, apc, apc_cls, dh, dh_cls, ap);
2794  va_end (ap);
2795  return daemon;
2796 }
2797 
2798 
2818 MHD_socket
2820 {
2821  unsigned int i;
2822  MHD_socket ret;
2823 
2824  ret = daemon->socket_fd;
2825  if (MHD_INVALID_SOCKET == ret)
2826  return MHD_INVALID_SOCKET;
2827  if ( (MHD_INVALID_PIPE_ == daemon->wpipe[1]) &&
2829  {
2830 #if HAVE_MESSAGES
2831  MHD_DLOG (daemon,
2832  "Using MHD_quiesce_daemon in this mode requires MHD_USE_PIPE_FOR_SHUTDOWN\n");
2833 #endif
2834  return MHD_INVALID_SOCKET;
2835  }
2836 
2837  if (NULL != daemon->worker_pool)
2838  for (i = 0; i < daemon->worker_pool_size; i++)
2839  {
2841 #if EPOLL_SUPPORT
2842  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2843  (-1 != daemon->worker_pool[i].epoll_fd) &&
2844  (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) )
2845  {
2846  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
2847  EPOLL_CTL_DEL,
2848  ret,
2849  NULL))
2850  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2851  daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO;
2852  }
2853 #endif
2854  }
2855  daemon->socket_fd = MHD_INVALID_SOCKET;
2856 #if EPOLL_SUPPORT
2857  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2858  (-1 != daemon->epoll_fd) &&
2859  (MHD_YES == daemon->listen_socket_in_epoll) )
2860  {
2861  if (0 != epoll_ctl (daemon->epoll_fd,
2862  EPOLL_CTL_DEL,
2863  ret,
2864  NULL))
2865  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2866  daemon->listen_socket_in_epoll = MHD_NO;
2867  }
2868 #endif
2869  return ret;
2870 }
2871 
2872 
2880 typedef void (*VfprintfFunctionPointerType)(void *cls,
2881  const char *format,
2882  va_list va);
2883 
2884 
2893 static int
2894 parse_options_va (struct MHD_Daemon *daemon,
2895  const struct sockaddr **servaddr,
2896  va_list ap);
2897 
2898 
2907 static int
2908 parse_options (struct MHD_Daemon *daemon,
2909  const struct sockaddr **servaddr,
2910  ...)
2911 {
2912  va_list ap;
2913  int ret;
2914 
2915  va_start (ap, servaddr);
2916  ret = parse_options_va (daemon, servaddr, ap);
2917  va_end (ap);
2918  return ret;
2919 }
2920 
2921 
2930 static int
2932  const struct sockaddr **servaddr,
2933  va_list ap)
2934 {
2935  enum MHD_OPTION opt;
2936  struct MHD_OptionItem *oa;
2937  unsigned int i;
2938 #if HTTPS_SUPPORT
2939  int ret;
2940  const char *pstr;
2941 #endif
2942 
2943  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
2944  {
2945  switch (opt)
2946  {
2948  daemon->pool_size = va_arg (ap, size_t);
2949  break;
2951  daemon->pool_increment= va_arg (ap, size_t);
2952  break;
2954  daemon->connection_limit = va_arg (ap, unsigned int);
2955  break;
2957  daemon->connection_timeout = va_arg (ap, unsigned int);
2958  break;
2960  daemon->notify_completed =
2961  va_arg (ap, MHD_RequestCompletedCallback);
2962  daemon->notify_completed_cls = va_arg (ap, void *);
2963  break;
2965  daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
2966  break;
2967  case MHD_OPTION_SOCK_ADDR:
2968  *servaddr = va_arg (ap, const struct sockaddr *);
2969  break;
2971  daemon->uri_log_callback =
2972  va_arg (ap, LogCallback);
2973  daemon->uri_log_callback_cls = va_arg (ap, void *);
2974  break;
2976  daemon->worker_pool_size = va_arg (ap, unsigned int);
2977  if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon)))
2978  {
2979 #if HAVE_MESSAGES
2980  MHD_DLOG (daemon,
2981  "Specified thread pool size (%u) too big\n",
2982  daemon->worker_pool_size);
2983 #endif
2984  return MHD_NO;
2985  }
2986  break;
2987 #if HTTPS_SUPPORT
2989  if (0 != (daemon->options & MHD_USE_SSL))
2990  daemon->https_mem_key = va_arg (ap, const char *);
2991 #if HAVE_MESSAGES
2992  else
2993  MHD_DLOG (daemon,
2994  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
2995  opt);
2996 #endif
2997  break;
2999  if (0 != (daemon->options & MHD_USE_SSL))
3000  daemon->https_mem_cert = va_arg (ap, const char *);
3001 #if HAVE_MESSAGES
3002  else
3003  MHD_DLOG (daemon,
3004  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3005  opt);
3006 #endif
3007  break;
3009  if (0 != (daemon->options & MHD_USE_SSL))
3010  daemon->https_mem_trust = va_arg (ap, const char *);
3011 #if HAVE_MESSAGES
3012  else
3013  MHD_DLOG (daemon,
3014  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3015  opt);
3016 #endif
3017  break;
3019  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, int);
3020  break;
3022  if (0 != (daemon->options & MHD_USE_SSL))
3023  {
3024  const char *arg = va_arg (ap, const char *);
3025  gnutls_datum_t dhpar;
3026 
3027  if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0)
3028  {
3029 #if HAVE_MESSAGES
3030  MHD_DLOG(daemon,
3031  "Error initializing DH parameters\n");
3032 #endif
3033  return MHD_NO;
3034  }
3035  dhpar.data = (unsigned char *) arg;
3036  dhpar.size = strlen (arg);
3037  if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, &dhpar,
3038  GNUTLS_X509_FMT_PEM) < 0)
3039  {
3040 #if HAVE_MESSAGES
3041  MHD_DLOG(daemon,
3042  "Bad Diffie-Hellman parameters format\n");
3043 #endif
3044  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
3045  return MHD_NO;
3046  }
3047  daemon->have_dhparams = MHD_YES;
3048  }
3049  else
3050  {
3051 #if HAVE_MESSAGES
3052  MHD_DLOG (daemon,
3053  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
3054  opt);
3055 #endif
3056  return MHD_NO;
3057  }
3058  break;
3060  if (0 != (daemon->options & MHD_USE_SSL))
3061  {
3062  gnutls_priority_deinit (daemon->priority_cache);
3063  ret = gnutls_priority_init (&daemon->priority_cache,
3064  pstr = va_arg (ap, const char*),
3065  NULL);
3066  if (GNUTLS_E_SUCCESS != ret)
3067  {
3068 #if HAVE_MESSAGES
3069  MHD_DLOG (daemon,
3070  "Setting priorities to `%s' failed: %s\n",
3071  pstr,
3072  gnutls_strerror (ret));
3073 #endif
3074  daemon->priority_cache = NULL;
3075  return MHD_NO;
3076  }
3077  }
3078  break;
3080 #if GNUTLS_VERSION_MAJOR < 3
3081 #if HAVE_MESSAGES
3082  MHD_DLOG (daemon,
3083  "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n");
3084 #endif
3085  return MHD_NO;
3086 #else
3087  if (0 != (daemon->options & MHD_USE_SSL))
3088  daemon->cert_callback = va_arg (ap, gnutls_certificate_retrieve_function2 *);
3089  break;
3090 #endif
3091 #endif
3092 #ifdef DAUTH_SUPPORT
3094  daemon->digest_auth_rand_size = va_arg (ap, size_t);
3095  daemon->digest_auth_random = va_arg (ap, const char *);
3096  break;
3098  daemon->nonce_nc_size = va_arg (ap, unsigned int);
3099  break;
3100 #endif
3102  daemon->socket_fd = va_arg (ap, MHD_socket);
3103  break;
3105 #if HAVE_MESSAGES
3106  daemon->custom_error_log =
3107  va_arg (ap, VfprintfFunctionPointerType);
3108  daemon->custom_error_log_cls = va_arg (ap, void *);
3109 #else
3110  va_arg (ap, VfprintfFunctionPointerType);
3111  va_arg (ap, void *);
3112 #endif
3113  break;
3115  daemon->thread_stack_size = va_arg (ap, size_t);
3116  break;
3117 #ifdef TCP_FASTOPEN
3119  daemon->fastopen_queue_size = va_arg (ap, unsigned int);
3120  break;
3121 #endif
3123  daemon->listening_address_reuse = va_arg (ap, unsigned int) ? 1 : -1;
3124  break;
3125  case MHD_OPTION_ARRAY:
3126  oa = va_arg (ap, struct MHD_OptionItem*);
3127  i = 0;
3128  while (MHD_OPTION_END != (opt = oa[i].option))
3129  {
3130  switch (opt)
3131  {
3132  /* all options taking 'size_t' */
3136  if (MHD_YES != parse_options (daemon,
3137  servaddr,
3138  opt,
3139  (size_t) oa[i].value,
3140  MHD_OPTION_END))
3141  return MHD_NO;
3142  break;
3143  /* all options taking 'unsigned int' */
3151  if (MHD_YES != parse_options (daemon,
3152  servaddr,
3153  opt,
3154  (unsigned int) oa[i].value,
3155  MHD_OPTION_END))
3156  return MHD_NO;
3157  break;
3158  /* all options taking 'enum' */
3160  if (MHD_YES != parse_options (daemon,
3161  servaddr,
3162  opt,
3163  (int) oa[i].value,
3164  MHD_OPTION_END))
3165  return MHD_NO;
3166  break;
3167  /* all options taking 'MHD_socket' */
3169  if (MHD_YES != parse_options (daemon,
3170  servaddr,
3171  opt,
3172  (MHD_socket) oa[i].value,
3173  MHD_OPTION_END))
3174  return MHD_NO;
3175  break;
3176  /* all options taking one pointer */
3177  case MHD_OPTION_SOCK_ADDR:
3182  case MHD_OPTION_ARRAY:
3184  if (MHD_YES != parse_options (daemon,
3185  servaddr,
3186  opt,
3187  oa[i].ptr_value,
3188  MHD_OPTION_END))
3189  return MHD_NO;
3190  break;
3191  /* all options taking two pointers */
3196  if (MHD_YES != parse_options (daemon,
3197  servaddr,
3198  opt,
3199  (void *) oa[i].value,
3200  oa[i].ptr_value,
3201  MHD_OPTION_END))
3202  return MHD_NO;
3203  break;
3204  /* options taking size_t-number followed by pointer */
3206  if (MHD_YES != parse_options (daemon,
3207  servaddr,
3208  opt,
3209  (size_t) oa[i].value,
3210  oa[i].ptr_value,
3211  MHD_OPTION_END))
3212  return MHD_NO;
3213  break;
3214  default:
3215  return MHD_NO;
3216  }
3217  i++;
3218  }
3219  break;
3221  daemon->unescape_callback =
3222  va_arg (ap, UnescapeCallback);
3223  daemon->unescape_callback_cls = va_arg (ap, void *);
3224  break;
3225  default:
3226 #if HAVE_MESSAGES
3227  if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
3229  {
3230  MHD_DLOG (daemon,
3231  "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
3232  opt);
3233  }
3234  else
3235  {
3236  MHD_DLOG (daemon,
3237  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
3238  opt);
3239  }
3240 #endif
3241  return MHD_NO;
3242  }
3243  }
3244  return MHD_YES;
3245 }
3246 
3247 
3256 static MHD_socket
3257 create_socket (struct MHD_Daemon *daemon,
3258  int domain, int type, int protocol)
3259 {
3260  int ctype = type | SOCK_CLOEXEC;
3261  MHD_socket fd;
3262 
3263  /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
3264  * implementations do not set ai_socktype, e.g. RHL6.2. */
3265  fd = socket (domain, ctype, protocol);
3266  if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 != SOCK_CLOEXEC) )
3267  {
3268  ctype = type;
3269  fd = socket(domain, type, protocol);
3270  }
3271  if (MHD_INVALID_SOCKET == fd)
3272  return MHD_INVALID_SOCKET;
3273  if (type == ctype)
3274  make_nonblocking_noninheritable (daemon, fd);
3275  return fd;
3276 }
3277 
3278 
3279 #if EPOLL_SUPPORT
3280 
3287 static int
3288 setup_epoll_to_listen (struct MHD_Daemon *daemon)
3289 {
3290  struct epoll_event event;
3291 
3292  daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
3293  if (-1 == daemon->epoll_fd)
3294  {
3295 #if HAVE_MESSAGES
3296  MHD_DLOG (daemon,
3297  "Call to epoll_create1 failed: %s\n",
3299 #endif
3300  return MHD_NO;
3301  }
3302  if (0 == EPOLL_CLOEXEC)
3304  daemon->epoll_fd);
3305  if (MHD_INVALID_SOCKET == daemon->socket_fd)
3306  return MHD_YES; /* non-listening daemon */
3307  event.events = EPOLLIN;
3308  event.data.ptr = daemon;
3309  if (0 != epoll_ctl (daemon->epoll_fd,
3310  EPOLL_CTL_ADD,
3311  daemon->socket_fd,
3312  &event))
3313  {
3314 #if HAVE_MESSAGES
3315  MHD_DLOG (daemon,
3316  "Call to epoll_ctl failed: %s\n",
3318 #endif
3319  return MHD_NO;
3320  }
3321  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
3323  {
3324  event.events = EPOLLIN | EPOLLET;
3325  event.data.ptr = NULL;
3326  event.data.fd = daemon->wpipe[0];
3327  if (0 != epoll_ctl (daemon->epoll_fd,
3328  EPOLL_CTL_ADD,
3329  daemon->wpipe[0],
3330  &event))
3331  {
3332 #if HAVE_MESSAGES
3333  MHD_DLOG (daemon,
3334  "Call to epoll_ctl failed: %s\n",
3336 #endif
3337  return MHD_NO;
3338  }
3339  }
3340  daemon->listen_socket_in_epoll = MHD_YES;
3341  return MHD_YES;
3342 }
3343 #endif
3344 
3345 
3363 struct MHD_Daemon *
3364 MHD_start_daemon_va (unsigned int flags,
3365  uint16_t port,
3367  void *apc_cls,
3368  MHD_AccessHandlerCallback dh, void *dh_cls,
3369  va_list ap)
3370 {
3371  const int on = 1;
3372  struct MHD_Daemon *daemon;
3374  struct sockaddr_in servaddr4;
3375 #if HAVE_INET6
3376  struct sockaddr_in6 servaddr6;
3377 #endif
3378  const struct sockaddr *servaddr = NULL;
3379  socklen_t addrlen;
3380  unsigned int i;
3381  int res_thread_create;
3382  int use_pipe;
3383 
3384 #ifndef HAVE_INET6
3385  if (0 != (flags & MHD_USE_IPv6))
3386  return NULL;
3387 #endif
3388 #ifndef HAVE_POLL_H
3389  if (0 != (flags & MHD_USE_POLL))
3390  return NULL;
3391 #endif
3392 #if ! HTTPS_SUPPORT
3393  if (0 != (flags & MHD_USE_SSL))
3394  return NULL;
3395 #endif
3396 #ifndef TCP_FASTOPEN
3397  if (0 != (flags & MHD_USE_TCP_FASTOPEN))
3398  return NULL;
3399 #endif
3400  if (NULL == dh)
3401  return NULL;
3402  if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
3403  return NULL;
3404  memset (daemon, 0, sizeof (struct MHD_Daemon));
3405 #if EPOLL_SUPPORT
3406  daemon->epoll_fd = -1;
3407 #endif
3408  /* try to open listen socket */
3409 #if HTTPS_SUPPORT
3410  if (0 != (flags & MHD_USE_SSL))
3411  {
3412  gnutls_priority_init (&daemon->priority_cache,
3413  "@SYSTEM",
3414  NULL);
3415  }
3416 #endif
3417  daemon->socket_fd = MHD_INVALID_SOCKET;
3418  daemon->listening_address_reuse = 0;
3419  daemon->options = (enum MHD_OPTION) flags;
3420 #if WINDOWS
3421  /* Winsock is broken with respect to 'shutdown';
3422  this disables us calling 'shutdown' on W32. */
3423  daemon->options |= MHD_USE_EPOLL_TURBO;
3424 #endif
3425  daemon->port = port;
3426  daemon->apc = apc;
3427  daemon->apc_cls = apc_cls;
3428  daemon->default_handler = dh;
3429  daemon->default_handler_cls = dh_cls;
3430  daemon->connections = 0;
3432  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
3433  daemon->pool_increment = MHD_BUF_INC_SIZE;
3435  daemon->connection_timeout = 0; /* no timeout */
3436  daemon->wpipe[0] = MHD_INVALID_PIPE_;
3437  daemon->wpipe[1] = MHD_INVALID_PIPE_;
3438 #if HAVE_MESSAGES
3439  daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
3440  daemon->custom_error_log_cls = stderr;
3441 #endif
3442 #ifdef HAVE_LISTEN_SHUTDOWN
3443  use_pipe = (0 != (daemon->options & (MHD_USE_NO_LISTEN_SOCKET | MHD_USE_PIPE_FOR_SHUTDOWN)));
3444 #else
3445  use_pipe = 1; /* yes, must use pipe to signal shutdown */
3446 #endif
3448  use_pipe = 0; /* useless if we are using 'external' select */
3449  if ( (use_pipe) && (0 != MHD_pipe_ (daemon->wpipe)) )
3450  {
3451 #if HAVE_MESSAGES
3452  MHD_DLOG (daemon,
3453  "Failed to create control pipe: %s\n",
3454  MHD_strerror_ (errno));
3455 #endif
3456  free (daemon);
3457  return NULL;
3458  }
3459 #ifndef WINDOWS
3460  if ( (0 == (flags & MHD_USE_POLL)) &&
3461  (1 == use_pipe) &&
3462  (daemon->wpipe[0] >= FD_SETSIZE) )
3463  {
3464 #if HAVE_MESSAGES
3465  MHD_DLOG (daemon,
3466  "file descriptor for control pipe exceeds maximum value\n");
3467 #endif
3468  if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
3469  MHD_PANIC ("close failed\n");
3470  if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
3471  MHD_PANIC ("close failed\n");
3472  free (daemon);
3473  return NULL;
3474  }
3475 #endif
3476 #ifdef DAUTH_SUPPORT
3477  daemon->digest_auth_rand_size = 0;
3478  daemon->digest_auth_random = NULL;
3479  daemon->nonce_nc_size = 4; /* tiny */
3480 #endif
3481 #if HTTPS_SUPPORT
3482  if (0 != (flags & MHD_USE_SSL))
3483  {
3484  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
3485  }
3486 #endif
3487 
3488 
3489  if (MHD_YES != parse_options_va (daemon, &servaddr, ap))
3490  {
3491 #if HTTPS_SUPPORT
3492  if ( (0 != (flags & MHD_USE_SSL)) &&
3493  (NULL != daemon->priority_cache) )
3494  gnutls_priority_deinit (daemon->priority_cache);
3495 #endif
3496  free (daemon);
3497  return NULL;
3498  }
3499 #ifdef DAUTH_SUPPORT
3500  if (daemon->nonce_nc_size > 0)
3501  {
3502  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
3503  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
3504  {
3505 #if HAVE_MESSAGES
3506  MHD_DLOG (daemon,
3507  "Specified value for NC_SIZE too large\n");
3508 #endif
3509 #if HTTPS_SUPPORT
3510  if (0 != (flags & MHD_USE_SSL))
3511  gnutls_priority_deinit (daemon->priority_cache);
3512 #endif
3513  free (daemon);
3514  return NULL;
3515  }
3516  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
3517  if (NULL == daemon->nnc)
3518  {
3519 #if HAVE_MESSAGES
3520  MHD_DLOG (daemon,
3521  "Failed to allocate memory for nonce-nc map: %s\n",
3522  MHD_strerror_ (errno));
3523 #endif
3524 #if HTTPS_SUPPORT
3525  if (0 != (flags & MHD_USE_SSL))
3526  gnutls_priority_deinit (daemon->priority_cache);
3527 #endif
3528  free (daemon);
3529  return NULL;
3530  }
3531  }
3532 
3533  if (MHD_YES != MHD_mutex_create_ (&daemon->nnc_lock))
3534  {
3535 #if HAVE_MESSAGES
3536  MHD_DLOG (daemon,
3537  "MHD failed to initialize nonce-nc mutex\n");
3538 #endif
3539 #if HTTPS_SUPPORT
3540  if (0 != (flags & MHD_USE_SSL))
3541  gnutls_priority_deinit (daemon->priority_cache);
3542 #endif
3543  free (daemon->nnc);
3544  free (daemon);
3545  return NULL;
3546  }
3547 #endif
3548 
3549  /* Thread pooling currently works only with internal select thread model */
3550  if ( (0 == (flags & MHD_USE_SELECT_INTERNALLY)) &&
3551  (daemon->worker_pool_size > 0) )
3552  {
3553 #if HAVE_MESSAGES
3554  MHD_DLOG (daemon,
3555  "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
3556 #endif
3557  goto free_and_fail;
3558  }
3559 
3560  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3561  (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) )
3562  {
3563 #if HAVE_MESSAGES
3564  MHD_DLOG (daemon,
3565  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_SUSPEND_RESUME is not supported.\n");
3566 #endif
3567  goto free_and_fail;
3568  }
3569 
3570 #ifdef __SYMBIAN32__
3571  if (0 != (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
3572  {
3573 #if HAVE_MESSAGES
3574  MHD_DLOG (daemon,
3575  "Threaded operations are not supported on Symbian.\n");
3576 #endif
3577  goto free_and_fail;
3578  }
3579 #endif
3580  if ( (MHD_INVALID_SOCKET == daemon->socket_fd) &&
3581  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3582  {
3583  /* try to open listen socket */
3584  if (0 != (flags & MHD_USE_IPv6))
3585  socket_fd = create_socket (daemon,
3586  PF_INET6, SOCK_STREAM, 0);
3587  else
3588  socket_fd = create_socket (daemon,
3589  PF_INET, SOCK_STREAM, 0);
3590  if (MHD_INVALID_SOCKET == socket_fd)
3591  {
3592 #if HAVE_MESSAGES
3593  MHD_DLOG (daemon,
3594  "Call to socket failed: %s\n",
3596 #endif
3597  goto free_and_fail;
3598  }
3599 
3600  /* Apply the socket options according to listening_address_reuse. */
3601  if (0 == daemon->listening_address_reuse)
3602  {
3603  /* No user requirement, use "traditional" default SO_REUSEADDR,
3604  and do not fail if it doesn't work */
3605  if (0 > setsockopt (socket_fd,
3606  SOL_SOCKET,
3607  SO_REUSEADDR,
3608  (void*)&on, sizeof (on)))
3609  {
3610 #if HAVE_MESSAGES
3611  MHD_DLOG (daemon,
3612  "setsockopt failed: %s\n",
3614 #endif
3615  }
3616  }
3617  else if (daemon->listening_address_reuse > 0)
3618  {
3619  /* User requested to allow reusing listening address:port.
3620  * Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms.
3621  * Fail if SO_REUSEPORT does not exist or setsockopt fails.
3622  */
3623 #ifdef _WIN32
3624  /* SO_REUSEADDR on W32 has the same semantics
3625  as SO_REUSEPORT on BSD/Linux */
3626  if (0 > setsockopt (socket_fd,
3627  SOL_SOCKET,
3628  SO_REUSEADDR,
3629  (void*)&on, sizeof (on)))
3630  {
3631 #if HAVE_MESSAGES
3632  MHD_DLOG (daemon,
3633  "setsockopt failed: %s\n",
3635 #endif
3636  goto free_and_fail;
3637  }
3638 #else
3639 #ifndef SO_REUSEPORT
3640 #ifdef LINUX
3641 /* Supported since Linux 3.9, but often not present (or commented out)
3642  in the headers at this time; but 15 is reserved for this and
3643  thus should be safe to use. */
3644 #define SO_REUSEPORT 15
3645 #endif
3646 #endif
3647 #ifdef SO_REUSEPORT
3648  if (0 > setsockopt (socket_fd,
3649  SOL_SOCKET,
3650  SO_REUSEPORT,
3651  (void*)&on, sizeof (on)))
3652  {
3653 #if HAVE_MESSAGES
3654  MHD_DLOG (daemon,
3655  "setsockopt failed: %s\n",
3657 #endif
3658  goto free_and_fail;
3659  }
3660 #else
3661  /* we're supposed to allow address:port re-use, but
3662  on this platform we cannot; fail hard */
3663 #if HAVE_MESSAGES
3664  MHD_DLOG (daemon,
3665  "Cannot allow listening address reuse: SO_REUSEPORT not defined\n");
3666 #endif
3667  goto free_and_fail;
3668 #endif
3669 #endif
3670  }
3671  else /* if (daemon->listening_address_reuse < 0) */
3672  {
3673  /* User requested to disallow reusing listening address:port.
3674  * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE
3675  * is used. Fail if it does not exist or setsockopt fails.
3676  */
3677 #ifdef _WIN32
3678 #ifdef SO_EXCLUSIVEADDRUSE
3679  if (0 > setsockopt (socket_fd,
3680  SOL_SOCKET,
3681  SO_EXCLUSIVEADDRUSE,
3682  (void*)&on, sizeof (on)))
3683  {
3684 #if HAVE_MESSAGES
3685  MHD_DLOG (daemon,
3686  "setsockopt failed: %s\n",
3688 #endif
3689  goto free_and_fail;
3690  }
3691 #else /* SO_EXCLUSIVEADDRUSE not defined on W32? */
3692 #if HAVE_MESSAGES
3693  MHD_DLOG (daemon,
3694  "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n");
3695 #endif
3696  goto free_and_fail;
3697 #endif
3698 #endif /* _WIN32 */
3699  }
3700 
3701  /* check for user supplied sockaddr */
3702 #if HAVE_INET6
3703  if (0 != (flags & MHD_USE_IPv6))
3704  addrlen = sizeof (struct sockaddr_in6);
3705  else
3706 #endif
3707  addrlen = sizeof (struct sockaddr_in);
3708  if (NULL == servaddr)
3709  {
3710 #if HAVE_INET6
3711  if (0 != (flags & MHD_USE_IPv6))
3712  {
3713  memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
3714  servaddr6.sin6_family = AF_INET6;
3715  servaddr6.sin6_port = htons (port);
3716 #if HAVE_SOCKADDR_IN_SIN_LEN
3717  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
3718 #endif
3719  servaddr = (struct sockaddr *) &servaddr6;
3720  }
3721  else
3722 #endif
3723  {
3724  memset (&servaddr4, 0, sizeof (struct sockaddr_in));
3725  servaddr4.sin_family = AF_INET;
3726  servaddr4.sin_port = htons (port);
3727 #if HAVE_SOCKADDR_IN_SIN_LEN
3728  servaddr4.sin_len = sizeof (struct sockaddr_in);
3729 #endif
3730  servaddr = (struct sockaddr *) &servaddr4;
3731  }
3732  }
3733  daemon->socket_fd = socket_fd;
3734 
3735  if (0 != (flags & MHD_USE_IPv6))
3736  {
3737 #ifdef IPPROTO_IPV6
3738 #ifdef IPV6_V6ONLY
3739  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
3740  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
3741  and may also be missing on older POSIX systems; good luck if you have any of those,
3742  your IPv6 socket may then also bind against IPv4 anyway... */
3743 #ifndef WINDOWS
3744  const int
3745 #else
3746  const char
3747 #endif
3748  on = (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK));
3749  if (0 > setsockopt (socket_fd,
3750  IPPROTO_IPV6, IPV6_V6ONLY,
3751  &on, sizeof (on)))
3752  {
3753 #if HAVE_MESSAGES
3754  MHD_DLOG (daemon,
3755  "setsockopt failed: %s\n",
3757 #endif
3758  }
3759 #endif
3760 #endif
3761  }
3762  if (-1 == bind (socket_fd, servaddr, addrlen))
3763  {
3764 #if HAVE_MESSAGES
3765  MHD_DLOG (daemon,
3766  "Failed to bind to port %u: %s\n",
3767  (unsigned int) port,
3769 #endif
3770  if (0 != MHD_socket_close_ (socket_fd))
3771  MHD_PANIC ("close failed\n");
3772  goto free_and_fail;
3773  }
3774 #ifdef TCP_FASTOPEN
3775  if (0 != (flags & MHD_USE_TCP_FASTOPEN))
3776  {
3777  if (0 == daemon->fastopen_queue_size)
3778  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
3779  if (0 != setsockopt (socket_fd,
3780  IPPROTO_TCP, TCP_FASTOPEN,
3781  &daemon->fastopen_queue_size,
3782  sizeof (daemon->fastopen_queue_size)))
3783  {
3784 #if HAVE_MESSAGES
3785  MHD_DLOG (daemon,
3786  "setsockopt failed: %s\n",
3788 #endif
3789  }
3790  }
3791 #endif
3792 #if EPOLL_SUPPORT
3793  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3794  {
3795  int sk_flags = fcntl (socket_fd, F_GETFL);
3796  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3797  {
3798 #if HAVE_MESSAGES
3799  MHD_DLOG (daemon,
3800  "Failed to make listen socket non-blocking: %s\n",
3802 #endif
3803  if (0 != MHD_socket_close_ (socket_fd))
3804  MHD_PANIC ("close failed\n");
3805  goto free_and_fail;
3806  }
3807  }
3808 #endif
3809  if (listen (socket_fd, 32) < 0)
3810  {
3811 #if HAVE_MESSAGES
3812  MHD_DLOG (daemon,
3813  "Failed to listen for connections: %s\n",
3815 #endif
3816  if (0 != MHD_socket_close_ (socket_fd))
3817  MHD_PANIC ("close failed\n");
3818  goto free_and_fail;
3819  }
3820  }
3821  else
3822  {
3823  socket_fd = daemon->socket_fd;
3824  }
3825 #ifndef WINDOWS
3826  if ( (socket_fd >= FD_SETSIZE) &&
3827  (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
3828  {
3829 #if HAVE_MESSAGES
3830  MHD_DLOG (daemon,
3831  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
3832  socket_fd,
3833  FD_SETSIZE);
3834 #endif
3835  if (0 != MHD_socket_close_ (socket_fd))
3836  MHD_PANIC ("close failed\n");
3837  goto free_and_fail;
3838  }
3839 #endif
3840 
3841 #if EPOLL_SUPPORT
3842  if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) &&
3843  (0 == daemon->worker_pool_size) &&
3844  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3845  {
3846  if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))
3847  {
3848 #if HAVE_MESSAGES
3849  MHD_DLOG (daemon,
3850  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL_LINUX_ONLY is not supported.\n");
3851 #endif
3852  goto free_and_fail;
3853  }
3854  if (MHD_YES != setup_epoll_to_listen (daemon))
3855  goto free_and_fail;
3856  }
3857 #else
3858  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3859  {
3860 #if HAVE_MESSAGES
3861  MHD_DLOG (daemon,
3862  "epoll is not supported on this platform by this build.\n");
3863 #endif
3864  goto free_and_fail;
3865  }
3866 #endif
3867 
3868  if (MHD_YES != MHD_mutex_create_ (&daemon->per_ip_connection_mutex))
3869  {
3870 #if HAVE_MESSAGES
3871  MHD_DLOG (daemon,
3872  "MHD failed to initialize IP connection limit mutex\n");
3873 #endif
3874  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3875  (0 != MHD_socket_close_ (socket_fd)) )
3876  MHD_PANIC ("close failed\n");
3877  goto free_and_fail;
3878  }
3879  if (MHD_YES != MHD_mutex_create_ (&daemon->cleanup_connection_mutex))
3880  {
3881 #if HAVE_MESSAGES
3882  MHD_DLOG (daemon,
3883  "MHD failed to initialize IP connection limit mutex\n");
3884 #endif
3885  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
3886  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3887  (0 != MHD_socket_close_ (socket_fd)) )
3888  MHD_PANIC ("close failed\n");
3889  goto free_and_fail;
3890  }
3891 
3892 #if HTTPS_SUPPORT
3893  /* initialize HTTPS daemon certificate aspects & send / recv functions */
3894  if ((0 != (flags & MHD_USE_SSL)) && (0 != MHD_TLS_init (daemon)))
3895  {
3896 #if HAVE_MESSAGES
3897  MHD_DLOG (daemon,
3898  "Failed to initialize TLS support\n");
3899 #endif
3900  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3901  (0 != MHD_socket_close_ (socket_fd)) )
3902  MHD_PANIC ("close failed\n");
3903  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
3904  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
3905  goto free_and_fail;
3906  }
3907 #endif
3908  if ( ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) ||
3909  ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) &&
3910  (0 == daemon->worker_pool_size)) ) &&
3911  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) &&
3912  (0 != (res_thread_create =
3913  create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon))))
3914  {
3915 #if HAVE_MESSAGES
3916  MHD_DLOG (daemon,
3917  "Failed to create listen thread: %s\n",
3918  MHD_strerror_ (res_thread_create));
3919 #endif
3920  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
3921  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
3922  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3923  (0 != MHD_socket_close_ (socket_fd)) )
3924  MHD_PANIC ("close failed\n");
3925  goto free_and_fail;
3926  }
3927  if ( (daemon->worker_pool_size > 0) &&
3928  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3929  {
3930 #if !defined(WINDOWS) || defined(CYGWIN)
3931  int sk_flags;
3932 #else
3933  unsigned long sk_flags;
3934 #endif
3935 
3936  /* Coarse-grained count of connections per thread (note error
3937  * due to integer division). Also keep track of how many
3938  * connections are leftover after an equal split. */
3939  unsigned int conns_per_thread = daemon->connection_limit
3940  / daemon->worker_pool_size;
3941  unsigned int leftover_conns = daemon->connection_limit
3942  % daemon->worker_pool_size;
3943 
3944  i = 0; /* we need this in case fcntl or malloc fails */
3945 
3946  /* Accept must be non-blocking. Multiple children may wake up
3947  * to handle a new connection, but only one will win the race.
3948  * The others must immediately return. */
3949 #if !defined(WINDOWS) || defined(CYGWIN)
3950  sk_flags = fcntl (socket_fd, F_GETFL);
3951  if (sk_flags < 0)
3952  goto thread_failed;
3953  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3954  goto thread_failed;
3955 #else
3956  sk_flags = 1;
3957  if (SOCKET_ERROR == ioctlsocket (socket_fd, FIONBIO, &sk_flags))
3958  goto thread_failed;
3959 #endif /* WINDOWS && !CYGWIN */
3960 
3961  /* Allocate memory for pooled objects */
3962  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
3963  * daemon->worker_pool_size);
3964  if (NULL == daemon->worker_pool)
3965  goto thread_failed;
3966 
3967  /* Start the workers in the pool */
3968  for (i = 0; i < daemon->worker_pool_size; ++i)
3969  {
3970  /* Create copy of the Daemon object for each worker */
3971  struct MHD_Daemon *d = &daemon->worker_pool[i];
3972 
3973  memcpy (d, daemon, sizeof (struct MHD_Daemon));
3974  /* Adjust pooling params for worker daemons; note that memcpy()
3975  has already copied MHD_USE_SELECT_INTERNALLY thread model into
3976  the worker threads. */
3977  d->master = daemon;
3978  d->worker_pool_size = 0;
3979  d->worker_pool = NULL;
3980 
3981  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3982  (0 != MHD_pipe_ (d->wpipe)) )
3983  {
3984 #if HAVE_MESSAGES
3985  MHD_DLOG (daemon,
3986  "Failed to create worker control pipe: %s\n",
3988 #endif
3989  goto thread_failed;
3990  }
3991 #ifndef WINDOWS
3992  if ( (0 == (flags & MHD_USE_POLL)) &&
3993  (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3994  (d->wpipe[0] >= FD_SETSIZE) )
3995  {
3996 #if HAVE_MESSAGES
3997  MHD_DLOG (daemon,
3998  "file descriptor for worker control pipe exceeds maximum value\n");
3999 #endif
4000  if (0 != MHD_pipe_close_ (d->wpipe[0]))
4001  MHD_PANIC ("close failed\n");
4002  if (0 != MHD_pipe_close_ (d->wpipe[1]))
4003  MHD_PANIC ("close failed\n");
4004  goto thread_failed;
4005  }
4006 #endif
4007 
4008  /* Divide available connections evenly amongst the threads.
4009  * Thread indexes in [0, leftover_conns) each get one of the
4010  * leftover connections. */
4011  d->connection_limit = conns_per_thread;
4012  if (i < leftover_conns)
4013  ++d->connection_limit;
4014 #if EPOLL_SUPPORT
4015  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4016  (MHD_YES != setup_epoll_to_listen (d)) )
4017  goto thread_failed;
4018 #endif
4019  /* Must init cleanup connection mutex for each worker */
4020  if (MHD_YES != MHD_mutex_create_ (&d->cleanup_connection_mutex))
4021  {
4022 #if HAVE_MESSAGES
4023  MHD_DLOG (daemon,
4024  "MHD failed to initialize cleanup connection mutex for thread worker %d\n", i);
4025 #endif
4026  goto thread_failed;
4027  }
4028 
4029  /* Spawn the worker thread */
4030  if (0 != (res_thread_create =
4031  create_thread (&d->pid, daemon, &MHD_select_thread, d)))
4032  {
4033 #if HAVE_MESSAGES
4034  MHD_DLOG (daemon,
4035  "Failed to create pool thread: %s\n",
4036  MHD_strerror_ (res_thread_create));
4037 #endif
4038  /* Free memory for this worker; cleanup below handles
4039  * all previously-created workers. */
4040  (void) MHD_mutex_destroy_ (&d->cleanup_connection_mutex);
4041  goto thread_failed;
4042  }
4043  }
4044  }
4045  return daemon;
4046 
4047 thread_failed:
4048  /* If no worker threads created, then shut down normally. Calling
4049  MHD_stop_daemon (as we do below) doesn't work here since it
4050  assumes a 0-sized thread pool means we had been in the default
4051  MHD_USE_SELECT_INTERNALLY mode. */
4052  if (0 == i)
4053  {
4054  if ( (MHD_INVALID_SOCKET != socket_fd) &&
4055  (0 != MHD_socket_close_ (socket_fd)) )
4056  MHD_PANIC ("close failed\n");
4057  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4058  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4059  if (NULL != daemon->worker_pool)
4060  free (daemon->worker_pool);
4061  goto free_and_fail;
4062  }
4063 
4064  /* Shutdown worker threads we've already created. Pretend
4065  as though we had fully initialized our daemon, but
4066  with a smaller number of threads than had been
4067  requested. */
4068  daemon->worker_pool_size = i - 1;
4069  MHD_stop_daemon (daemon);
4070  return NULL;
4071 
4072  free_and_fail:
4073  /* clean up basic memory state in 'daemon' and return NULL to
4074  indicate failure */
4075 #if EPOLL_SUPPORT
4076  if (-1 != daemon->epoll_fd)
4077  close (daemon->epoll_fd);
4078 #endif
4079 #ifdef DAUTH_SUPPORT
4080  free (daemon->nnc);
4081  (void) MHD_mutex_destroy_ (&daemon->nnc_lock);
4082 #endif
4083 #if HTTPS_SUPPORT
4084  if (0 != (flags & MHD_USE_SSL))
4085  gnutls_priority_deinit (daemon->priority_cache);
4086 #endif
4087  free (daemon);
4088  return NULL;
4089 }
4090 
4091 
4098 static void
4100 {
4101  struct MHD_Daemon *daemon = pos->daemon;
4102 
4103  MHD_connection_close (pos,
4105  if (pos->connection_timeout == pos->daemon->connection_timeout)
4107  daemon->normal_timeout_tail,
4108  pos);
4109  else
4111  daemon->manual_timeout_tail,
4112  pos);
4113  DLL_remove (daemon->connections_head,
4114  daemon->connections_tail,
4115  pos);
4117  DLL_insert (daemon->cleanup_head,
4118  daemon->cleanup_tail,
4119  pos);
4120 }
4121 
4122 
4130 static void
4132 {
4133  struct MHD_Connection *pos;
4134 
4135  /* first, make sure all threads are aware of shutdown; need to
4136  traverse DLLs in peace... */
4137  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4138  (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
4139  MHD_PANIC ("Failed to acquire cleanup mutex\n");
4140  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
4141  shutdown (pos->socket_fd,
4142  (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
4143  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
4144  (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
4145  MHD_PANIC ("Failed to release cleanup mutex\n");
4146 
4147  /* now, collect threads from thread pool */
4148  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
4149  {
4150  while (NULL != (pos = daemon->connections_head))
4151  {
4152  if (0 != MHD_join_thread_ (pos->pid))
4153  MHD_PANIC ("Failed to join a thread\n");
4154  pos->thread_joined = MHD_YES;
4155  }
4156  }
4157 
4158  /* now that we're alone, move everyone to cleanup */
4159  while (NULL != (pos = daemon->connections_head))
4160  close_connection (pos);
4161  MHD_cleanup_connections (daemon);
4162 }
4163 
4164 
4165 #if EPOLL_SUPPORT
4166 
4171 static void
4172 epoll_shutdown (struct MHD_Daemon *daemon)
4173 {
4174  struct epoll_event event;
4175 
4176  if (MHD_INVALID_PIPE_ == daemon->wpipe[1])
4177  {
4178  /* wpipe was required in this mode, how could this happen? */
4179  MHD_PANIC ("Internal error\n");
4180  }
4181  event.events = EPOLLOUT;
4182  event.data.ptr = NULL;
4183  if (0 != epoll_ctl (daemon->epoll_fd,
4184  EPOLL_CTL_ADD,
4185  daemon->wpipe[1],
4186  &event))
4187  MHD_PANIC ("Failed to add wpipe to epoll set to signal termination\n");
4188 }
4189 #endif
4190 
4191 
4198 void
4199 MHD_stop_daemon (struct MHD_Daemon *daemon)
4200 {
4201  MHD_socket fd;
4202  unsigned int i;
4203 
4204  if (NULL == daemon)
4205  return;
4206  daemon->shutdown = MHD_YES;
4207  fd = daemon->socket_fd;
4208  daemon->socket_fd = MHD_INVALID_SOCKET;
4209  /* Prepare workers for shutdown */
4210  if (NULL != daemon->worker_pool)
4211  {
4212  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
4213  for (i = 0; i < daemon->worker_pool_size; ++i)
4214  {
4215  daemon->worker_pool[i].shutdown = MHD_YES;
4217 #if EPOLL_SUPPORT
4218  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4219  (-1 != daemon->worker_pool[i].epoll_fd) &&
4220  (MHD_INVALID_SOCKET == fd) )
4221  epoll_shutdown (&daemon->worker_pool[i]);
4222 #endif
4223  }
4224  }
4225  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
4226  {
4227  if (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1))
4228  MHD_PANIC ("failed to signal shutdown via pipe");
4229  }
4230 #ifdef HAVE_LISTEN_SHUTDOWN
4231  else
4232  {
4233  /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
4234  if (MHD_INVALID_SOCKET != fd)
4235  (void) shutdown (fd, SHUT_RDWR);
4236  }
4237 #endif
4238 #if EPOLL_SUPPORT
4239  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4240  (-1 != daemon->epoll_fd) &&
4241  (MHD_INVALID_SOCKET == fd) )
4242  epoll_shutdown (daemon);
4243 #endif
4244 
4245 #if DEBUG_CLOSE
4246 #if HAVE_MESSAGES
4247  MHD_DLOG (daemon,
4248  "MHD listen socket shutdown\n");
4249 #endif
4250 #endif
4251 
4252 
4253  /* Signal workers to stop and clean them up */
4254  if (NULL != daemon->worker_pool)
4255  {
4256  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
4257  for (i = 0; i < daemon->worker_pool_size; ++i)
4258  {
4259  if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4260  {
4261  if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 1))
4262  MHD_PANIC ("failed to signal shutdown via pipe");
4263  }
4264  if (0 != MHD_join_thread_ (daemon->worker_pool[i].pid))
4265  MHD_PANIC ("Failed to join a thread\n");
4266  close_all_connections (&daemon->worker_pool[i]);
4267  (void) MHD_mutex_destroy_ (&daemon->worker_pool[i].cleanup_connection_mutex);
4268 #if EPOLL_SUPPORT
4269  if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
4270  (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) )
4271  MHD_PANIC ("close failed\n");
4272 #endif
4273  if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) )
4274  {
4275  if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4276  {
4277  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[0]))
4278  MHD_PANIC ("close failed\n");
4279  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[1]))
4280  MHD_PANIC ("close failed\n");
4281  }
4282  }
4283  }
4284  free (daemon->worker_pool);
4285  }
4286  else
4287  {
4288  /* clean up master threads */
4289  if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
4290  ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
4291  && (0 == daemon->worker_pool_size)))
4292  {
4293  if (0 != MHD_join_thread_ (daemon->pid))
4294  {
4295  MHD_PANIC ("Failed to join a thread\n");
4296  }
4297  }
4298  }
4299  close_all_connections (daemon);
4300  if ( (MHD_INVALID_SOCKET != fd) &&
4301  (0 != MHD_socket_close_ (fd)) )
4302  MHD_PANIC ("close failed\n");
4303 
4304  /* TLS clean up */
4305 #if HTTPS_SUPPORT
4306  if (MHD_YES == daemon->have_dhparams)
4307  {
4308  gnutls_dh_params_deinit (daemon->https_mem_dhparams);
4309  daemon->have_dhparams = MHD_NO;
4310  }
4311  if (0 != (daemon->options & MHD_USE_SSL))
4312  {
4313  gnutls_priority_deinit (daemon->priority_cache);
4314  if (daemon->x509_cred)
4315  gnutls_certificate_free_credentials (daemon->x509_cred);
4316  }
4317 #endif
4318 #if EPOLL_SUPPORT
4319  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4320  (-1 != daemon->epoll_fd) &&
4321  (0 != MHD_socket_close_ (daemon->epoll_fd)) )
4322  MHD_PANIC ("close failed\n");
4323 #endif
4324 
4325 #ifdef DAUTH_SUPPORT
4326  free (daemon->nnc);
4327  (void) MHD_mutex_destroy_ (&daemon->nnc_lock);
4328 #endif
4329  (void) MHD_mutex_destroy_ (&daemon->per_ip_connection_mutex);
4330  (void) MHD_mutex_destroy_ (&daemon->cleanup_connection_mutex);
4331 
4332  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
4333  {
4334  if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
4335  MHD_PANIC ("close failed\n");
4336  if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
4337  MHD_PANIC ("close failed\n");
4338  }
4339  free (daemon);
4340 }
4341 
4342 
4354 const union MHD_DaemonInfo *
4356  enum MHD_DaemonInfoType info_type,
4357  ...)
4358 {
4359  switch (info_type)
4360  {
4362  return NULL; /* no longer supported */
4364  return NULL; /* no longer supported */
4366  return (const union MHD_DaemonInfo *) &daemon->socket_fd;
4367 #if EPOLL_SUPPORT
4369  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
4370 #endif
4372  MHD_cleanup_connections (daemon);
4373  if (daemon->worker_pool)
4374  {
4375  /* Collect the connection information stored in the workers. */
4376  unsigned int i;
4377 
4378  daemon->connections = 0;
4379  for (i=0;i<daemon->worker_pool_size;i++)
4380  {
4381  MHD_cleanup_connections (&daemon->worker_pool[i]);
4382  daemon->connections += daemon->worker_pool[i].connections;
4383  }
4384  }
4385  return (const union MHD_DaemonInfo *) &daemon->connections;
4386  default:
4387  return NULL;
4388  };
4389 }
4390 
4391 
4408 void
4410 {
4411  mhd_panic = cb;
4412  mhd_panic_cls = cls;
4413 }
4414 
4415 
4422 const char *
4424 {
4425 #ifdef PACKAGE_VERSION
4426  return PACKAGE_VERSION;
4427 #else /* !PACKAGE_VERSION */
4428  static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0";
4429  if (0 == ver[0])
4430  {
4431  int res = MHD_snprintf_(ver, sizeof(ver), "%x.%x.%x",
4432  (((int)MHD_VERSION >> 24) & 0xFF),
4433  (((int)MHD_VERSION >> 16) & 0xFF),
4434  (((int)MHD_VERSION >> 8) & 0xFF));
4435  if (0 >= res || sizeof(ver) <= res)
4436  return "0.0.0"; /* Can't return real version*/
4437  }
4438  return ver;
4439 #endif /* !PACKAGE_VERSION */
4440 }
4441 
4442 
4454 _MHD_EXTERN int
4456 {
4457  switch(feature)
4458  {
4459  case MHD_FEATURE_MESSGES:
4460 #if HAVE_MESSAGES
4461  return MHD_YES;
4462 #else
4463  return MHD_NO;
4464 #endif
4465  case MHD_FEATURE_SSL:
4466 #if HTTPS_SUPPORT
4467  return MHD_YES;
4468 #else
4469  return MHD_NO;
4470 #endif
4472 #if HTTPS_SUPPORT && GNUTLS_VERSION_MAJOR >= 3
4473  return MHD_YES;
4474 #else
4475  return MHD_NO;
4476 #endif
4477  case MHD_FEATURE_IPv6:
4478 #ifdef HAVE_INET6
4479  return MHD_YES;
4480 #else
4481  return MHD_NO;
4482 #endif
4483  case MHD_FEATURE_IPv6_ONLY:
4484 #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
4485  return MHD_YES;
4486 #else
4487  return MHD_NO;
4488 #endif
4489  case MHD_FEATURE_POLL:
4490 #ifdef HAVE_POLL_H
4491  return MHD_YES;
4492 #else
4493  return MHD_NO;
4494 #endif
4495  case MHD_FEATURE_EPOLL:
4496 #if EPOLL_SUPPORT
4497  return MHD_YES;
4498 #else
4499  return MHD_NO;
4500 #endif
4502 #ifdef HAVE_LISTEN_SHUTDOWN
4503  return MHD_YES;
4504 #else
4505  return MHD_NO;
4506 #endif
4508 #ifdef MHD_DONT_USE_PIPES
4509  return MHD_YES;
4510 #else
4511  return MHD_NO;
4512 #endif
4514 #ifdef TCP_FASTOPEN
4515  return MHD_YES;
4516 #else
4517  return MHD_NO;
4518 #endif
4520 #if BAUTH_SUPPORT
4521  return MHD_YES;
4522 #else
4523  return MHD_NO;
4524 #endif
4526 #if DAUTH_SUPPORT
4527  return MHD_YES;
4528 #else
4529  return MHD_NO;
4530 #endif
4532 #if HAVE_POSTPROCESSOR
4533  return MHD_YES;
4534 #else
4535  return MHD_NO;
4536 #endif
4537  }
4538  return MHD_NO;
4539 }
4540 
4541 
4542 #if HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600
4543 #if defined(MHD_USE_POSIX_THREADS)
4544 GCRY_THREAD_OPTION_PTHREAD_IMPL;
4545 #elif defined(MHD_W32_MUTEX_)
4546 static int gcry_w32_mutex_init (void **ppmtx)
4547 {
4548  *ppmtx = malloc (sizeof (MHD_mutex_));
4549 
4550  if (NULL == *ppmtx)
4551  return ENOMEM;
4552 
4553  if (MHD_YES != MHD_mutex_create_ ((MHD_mutex_*)*ppmtx))
4554  {
4555  free (*ppmtx);
4556  *ppmtx = NULL;
4557  return EPERM;
4558  }
4559 
4560  return 0;
4561 }
4562 static int gcry_w32_mutex_destroy (void **ppmtx)
4563  { int res = (MHD_YES == MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1;
4564  free (*ppmtx); return res; }
4565 static int gcry_w32_mutex_lock (void **ppmtx)
4566  { return (MHD_YES == MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1; }
4567 static int gcry_w32_mutex_unlock (void **ppmtx)
4568  { return (MHD_YES == MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx)) ? 0 : 1; }
4569 
4570 static struct gcry_thread_cbs gcry_threads_w32 = {
4571  (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)),
4572  NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy,
4573  gcry_w32_mutex_lock, gcry_w32_mutex_unlock,
4574  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
4575 
4576 #endif // defined(MHD_W32_MUTEX_)
4577 #endif // HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600
4578 
4579 
4583 void MHD_init(void)
4584 {
4586  mhd_panic_cls = NULL;
4587 
4588 #ifdef _WIN32
4589  WSADATA wsd;
4590  if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
4591  MHD_PANIC ("Failed to initialize winsock\n");
4592  mhd_winsock_inited_ = 1;
4593  if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
4594  MHD_PANIC ("Winsock version 2.2 is not available\n");
4595 #endif
4596 #if HTTPS_SUPPORT
4597 #if GCRYPT_VERSION_NUMBER < 0x010600
4598 #if defined(MHD_USE_POSIX_THREADS)
4599  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
4600  MHD_PANIC ("Failed to initialise multithreading in libgcrypt\n");
4601 #elif defined(MHD_W32_MUTEX_)
4602  if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_w32))
4603  MHD_PANIC ("Failed to initialise multithreading in libgcrypt\n");
4604 #endif // defined(MHD_W32_MUTEX_)
4605  gcry_check_version (NULL);
4606 #else
4607  if (NULL == gcry_check_version ("1.6.0"))
4608  MHD_PANIC ("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n");
4609 #endif
4610  gnutls_global_init ();
4611 #endif
4612 }
4613 
4614 
4615 void MHD_fini(void)
4616 {
4617 #if HTTPS_SUPPORT
4618  gnutls_global_deinit ();
4619 #endif
4620 #ifdef _WIN32
4621  if (mhd_winsock_inited_)
4622  WSACleanup();
4623 #endif
4624 }
4625 
4627 
4628 /* end of daemon.c */
4629 
unsigned int per_ip_connection_limit
Definition: internal.h:1155
void * unescape_callback_cls
Definition: internal.h:1024
#define XDLL_insert(head, tail, element)
Definition: internal.h:1330
void MHD_fini(void)
Definition: daemon.c:4615
uint64_t total_size
Definition: internal.h:287
_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:3364
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:2908
_MHD_EXTERN const char * MHD_get_version(void)
Definition: daemon.c:4423
void * mhd_panic_cls
Definition: daemon.c:151
#define MHD_socket_errno_
off_t fd_off
Definition: internal.h:298
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:306
int(* write_handler)(struct MHD_Connection *connection)
Definition: internal.h:808
socklen_t addr_len
Definition: internal.h:699
int thread_joined
Definition: internal.h:738
enum MHD_CONNECTION_STATE state
Definition: internal.h:755
int(* idle_handler)(struct MHD_Connection *connection)
Definition: internal.h:813
uint64_t response_write_position
Definition: internal.h:688
#define NULL
Definition: reason_phrase.c:31
#define EDLL_remove(head, tail, element)
Definition: internal.h:1393
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:135
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:760
#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:1306
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:1963
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:265
void MHD_init(void)
Definition: daemon.c:4583
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:1870
#define SOCK_CLOEXEC
Definition: daemon.c:112
MHD_socket socket_fd
Definition: internal.h:1092
#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:1769
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
Definition: daemon.c:981
#define MSG_NOSIGNAL
Definition: daemon.c:107
struct MHD_Response * response
Definition: internal.h:566
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:1232
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:965
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_handle_connection(void *data)
Definition: daemon.c:758
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:867
#define MHD_strerror_(errnum)
#define MHD_socket_close_(fd)
MHD_AccessHandlerCallback default_handler
Definition: internal.h:898
int MHD_socket
Definition: microhttpd.h:185
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:2880
_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:2783
intptr_t value
Definition: microhttpd.h:885
platform-specific includes for libmicrohttpd
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:76
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
Definition: daemon.c:948
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
Definition: daemon.c:4409
#define MHD_socket_last_strerr_()
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:206
void * uri_log_callback_cls
Definition: internal.h:1014
int(* read_handler)(struct MHD_Connection *connection)
Definition: internal.h:803
struct MHD_Daemon * daemon
Definition: internal.h:551
int listening_address_reuse
Definition: internal.h:1101
MHD_mutex_ per_ip_connection_mutex
Definition: internal.h:1082
struct MHD_Connection * manual_timeout_head
Definition: internal.h:972
struct MHD_Connection * cleanup_head
Definition: internal.h:928
struct MHD_Connection * cleanup_tail
Definition: internal.h:933
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:4099
#define EWOULDBLOCK
Definition: w32functions.h:45
#define MHD_VERSION
Definition: microhttpd.h:133
size_t write_buffer_send_offset
Definition: internal.h:669
#define ECONNRESET
Definition: w32functions.h:96
struct MHD_Daemon * worker_pool
Definition: internal.h:1047
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:130
size_t read_buffer_size
Definition: internal.h:653
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:370
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:4199
struct MHD_Connection * nextX
Definition: internal.h:541
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:231
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:978
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:1532
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:1594
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:186
MHD_socket socket_fd
Definition: internal.h:725
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:645
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:2139
unsigned int connection_limit
Definition: internal.h:1143
unsigned int worker_pool_size
Definition: internal.h:1072
time_t MHD_monotonic_time(void)
Definition: internal.c:182
static void resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:1627
_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:2054
LogCallback uri_log_callback
Definition: internal.h:1009
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:488
static void cleanup(struct Proxy *proxy)
Definition: proxy.c:483
int(* MHD_AcceptPolicyCallback)(void *cls, const struct sockaddr *addr, socklen_t addrlen)
Definition: microhttpd.h:1164
int shutdown
Definition: internal.h:1128
Methods for managing connections.
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:880
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:216
static MHD_THRD_RTRN_TYPE_ MHD_THRD_CALL_SPEC_ MHD_select_thread(void *cls)
Definition: daemon.c:2726
uint16_t port
Definition: internal.h:1165
unsigned int connections
Definition: internal.h:1138
struct MHD_Connection * normal_timeout_head
Definition: internal.h:959
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:87
#define MHD_snprintf_
#define ENOTCONN
Definition: w32functions.h:105
_SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini)
ReceiveCallback recv_cls
Definition: internal.h:818
size_t thread_stack_size
Definition: internal.h:1067
static void make_nonblocking_noninheritable(struct MHD_Daemon *daemon, MHD_socket sock)
Definition: daemon.c:1690
MHD_FEATURE
Definition: microhttpd.h:2465
#define MHD_pipe_read_(fd, ptr, sz)
#define MHD_pipe_write_(fd, ptr, sz)
UnescapeCallback unescape_callback
Definition: internal.h:1019
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:250
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:168
static int add_to_fd_set(MHD_socket fd, fd_set *set, MHD_socket *max_fd, unsigned int fd_setsize)
Definition: daemon.c:602
static MHD_socket create_socket(struct MHD_Daemon *daemon, int domain, int type, int protocol)
Definition: daemon.c:3257
struct MHD_Connection * connections_head
Definition: internal.h:908
struct MHD_Daemon * master
Definition: internal.h:1042
size_t pool_size
Definition: internal.h:1057
struct MHD_Connection * next
Definition: internal.h:527
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:2442
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:2931
MHD_AcceptPolicyCallback apc
Definition: internal.h:984
time_t last_activity
Definition: internal.h:705
#define MHD_pipe_(fdarr)
unsigned int connection_timeout
Definition: internal.h:711
#define MHD_pipe_close_(fd)
#define MHD_PANIC(msg)
Definition: internal.h:99
struct MemoryPool * pool
Definition: internal.h:578
_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:651
static int create_thread(MHD_thread_handle_ *thread, const struct MHD_Daemon *daemon, ThreadStartRoutine start_routine, void *arg)
Definition: daemon.c:1072
void * ptr_value
Definition: microhttpd.h:891
MHD_pipe wpipe[2]
Definition: internal.h:1123
size_t write_buffer_append_offset
Definition: internal.h:675
int resuming
Definition: internal.h:1133
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:995
struct MHD_Connection * prevX
Definition: internal.h:546
#define MHD_set_socket_errno_(errnum)
enum MHD_OPTION options
Definition: internal.h:1160
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:2786
#define MHD_INVALID_PIPE_
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:84
MHD_thread_handle_ pid
Definition: internal.h:1077
MHD_THRD_RTRN_TYPE_(MHD_THRD_CALL_SPEC_ * ThreadStartRoutine)(void *cls)
Definition: daemon.c:1059
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:4131
void * notify_completed_cls
Definition: internal.h:1000
struct MemoryPool * MHD_pool_create(size_t max)
Definition: memorypool.c:87
TransmitCallback send_cls
Definition: internal.h:823
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:2691
#define XDLL_remove(head, tail, element)
Definition: internal.h:1351
#define DLL_insert(head, tail, element)
Definition: internal.h:1285
MHD_OPTION
MHD options.
Definition: microhttpd.h:595
#define EPOLL_CLOEXEC
Definition: daemon.c:116
void * tfind(void *vkey, void *const *vrootp, int *compar) const
Definition: tsearch.c:57
void * apc_cls
Definition: internal.h:989
struct sockaddr * addr
Definition: internal.h:639
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:1147
static size_t unescape_wrapper(void *cls, struct MHD_Connection *connection, char *val)
Definition: daemon.c:2758
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:923
MHD_DaemonInfoType
Definition: microhttpd.h:1107
#define MHD_SYS_select_(n, r, w, e, t)
MHD_PanicCallback mhd_panic
Definition: daemon.c:146
#define MHD_pipe_last_strerror_()
void * per_ip_connection_count
Definition: internal.h:1052
_MHD_EXTERN int MHD_is_feature_supported(enum MHD_FEATURE feature)
Definition: daemon.c:4455
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:1209
size_t read_buffer_offset
Definition: internal.h:659
_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:684
void * default_handler_cls
Definition: internal.h:903
#define MHD_NO
Definition: microhttpd.h:143
unsigned int connection_timeout
Definition: internal.h:1149
static int MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:1796
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1087
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:2819
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:4355
_MHD_EXTERN size_t MHD_http_unescape(char *val)
Definition: internal.c:132
struct MHD_Connection * connections_tail
Definition: internal.h:913
enum MHD_OPTION option
Definition: microhttpd.h:878
#define EDLL_insert(head, tail, element)
Definition: internal.h:1374
void MHD_connection_close(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
Definition: connection.c:268
size_t pool_increment
Definition: internal.h:1062
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
Definition: microhttpd.h:587
void * tsearch(void *vkey, void **vrootp, int *compar) const
Definition: tsearch.c:23
struct MHD_Connection * suspended_connections_head
Definition: internal.h:918
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
Definition: microhttpd.h:1150
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...