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 #include "platform.h"
28 #include "internal.h"
29 #include "response.h"
30 #include "connection.h"
31 #include "memorypool.h"
32 #include <limits.h>
33 
34 #if HAVE_SEARCH_H
35 #include <search.h>
36 #else
37 #include "tsearch.h"
38 #endif
39 
40 #if HTTPS_SUPPORT
41 #include "connection_https.h"
42 #include <gcrypt.h>
43 #endif
44 
45 #ifdef HAVE_POLL_H
46 #include <poll.h>
47 #endif
48 
49 #ifdef LINUX
50 #include <sys/sendfile.h>
51 #endif
52 
53 #ifdef _WIN32
54 #ifndef WIN32_LEAN_AND_MEAN
55 #define WIN32_LEAN_AND_MEAN 1
56 #endif /* !WIN32_LEAN_AND_MEAN */
57 #include <windows.h>
58 #endif
59 
60 #ifndef HAVE_ACCEPT4
61 #define HAVE_ACCEPT4 0
62 #endif
63 
67 #ifndef WINDOWS
68 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4
69 #else
70 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
71 #endif
72 
76 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
77 
78 #ifdef TCP_FASTOPEN
79 
82 #define MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT 10
83 #endif
84 
89 #define DEBUG_CLOSE MHD_NO
90 
95 #define DEBUG_CONNECT MHD_NO
96 
97 #ifndef LINUX
98 #ifndef MSG_NOSIGNAL
99 #define MSG_NOSIGNAL 0
100 #endif
101 #endif
102 
103 #ifndef SOCK_CLOEXEC
104 #define SOCK_CLOEXEC 0
105 #endif
106 
107 #ifndef EPOLL_CLOEXEC
108 #define EPOLL_CLOEXEC 0
109 #endif
110 
111 
121 static void
122 mhd_panic_std (void *cls,
123  const char *file,
124  unsigned int line,
125  const char *reason)
126 {
127 #if HAVE_MESSAGES
128  fprintf (stderr, "Fatal error in GNU libmicrohttpd %s:%u: %s\n",
129  file, line, reason);
130 #endif
131  abort ();
132 }
133 
134 
139 
144 
145 #ifdef _WIN32
146 
149 static int mhd_winsock_inited_ = 0;
150 #endif
151 
159 static struct MHD_Daemon*
160 MHD_get_master (struct MHD_Daemon *daemon)
161 {
162  while (NULL != daemon->master)
163  daemon = daemon->master;
164  return daemon;
165 }
166 
167 
171 struct MHD_IPCount
172 {
176  int family;
177 
181  union
182  {
186  struct in_addr ipv4;
187 #if HAVE_IPV6
188 
191  struct in6_addr ipv6;
192 #endif
193  } addr;
194 
198  unsigned int count;
199 };
200 
201 
207 static void
209 {
210  if (0 != pthread_mutex_lock(&daemon->per_ip_connection_mutex))
211  {
212  MHD_PANIC ("Failed to acquire IP connection limit mutex\n");
213  }
214 }
215 
216 
222 static void
224 {
225  if (0 != pthread_mutex_unlock(&daemon->per_ip_connection_mutex))
226  {
227  MHD_PANIC ("Failed to release IP connection limit mutex\n");
228  }
229 }
230 
231 
241 static int
242 MHD_ip_addr_compare (const void *a1, const void *a2)
243 {
244  return memcmp (a1, a2, offsetof (struct MHD_IPCount, count));
245 }
246 
247 
256 static int
257 MHD_ip_addr_to_key (const struct sockaddr *addr,
258  socklen_t addrlen,
259  struct MHD_IPCount *key)
260 {
261  memset(key, 0, sizeof(*key));
262 
263  /* IPv4 addresses */
264  if (sizeof (struct sockaddr_in) == addrlen)
265  {
266  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
267  key->family = AF_INET;
268  memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr));
269  return MHD_YES;
270  }
271 
272 #if HAVE_IPV6
273  /* IPv6 addresses */
274  if (sizeof (struct sockaddr_in6) == addrlen)
275  {
276  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
277  key->family = AF_INET6;
278  memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr));
279  return MHD_YES;
280  }
281 #endif
282 
283  /* Some other address */
284  return MHD_NO;
285 }
286 
287 
297 static int
298 MHD_ip_limit_add (struct MHD_Daemon *daemon,
299  const struct sockaddr *addr,
300  socklen_t addrlen)
301 {
302  struct MHD_IPCount *key;
303  void **nodep;
304  void *node;
305  int result;
306 
307  daemon = MHD_get_master (daemon);
308  /* Ignore if no connection limit assigned */
309  if (0 == daemon->per_ip_connection_limit)
310  return MHD_YES;
311 
312  if (NULL == (key = malloc (sizeof(*key))))
313  return MHD_NO;
314 
315  /* Initialize key */
316  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key))
317  {
318  /* Allow unhandled address types through */
319  free (key);
320  return MHD_YES;
321  }
322  MHD_ip_count_lock (daemon);
323 
324  /* Search for the IP address */
325  if (NULL == (nodep = tsearch (key,
326  &daemon->per_ip_connection_count,
328  {
329 #if HAVE_MESSAGES
330  MHD_DLOG (daemon,
331  "Failed to add IP connection count node\n");
332 #endif
333  MHD_ip_count_unlock (daemon);
334  free (key);
335  return MHD_NO;
336  }
337  node = *nodep;
338  /* If we got an existing node back, free the one we created */
339  if (node != key)
340  free(key);
341  key = (struct MHD_IPCount *) node;
342  /* Test if there is room for another connection; if so,
343  * increment count */
344  result = (key->count < daemon->per_ip_connection_limit);
345  if (MHD_YES == result)
346  ++key->count;
347 
348  MHD_ip_count_unlock (daemon);
349  return result;
350 }
351 
352 
361 static void
362 MHD_ip_limit_del (struct MHD_Daemon *daemon,
363  const struct sockaddr *addr,
364  socklen_t addrlen)
365 {
366  struct MHD_IPCount search_key;
367  struct MHD_IPCount *found_key;
368  void **nodep;
369 
370  daemon = MHD_get_master (daemon);
371  /* Ignore if no connection limit assigned */
372  if (0 == daemon->per_ip_connection_limit)
373  return;
374  /* Initialize search key */
375  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key))
376  return;
377 
378  MHD_ip_count_lock (daemon);
379 
380  /* Search for the IP address */
381  if (NULL == (nodep = tfind (&search_key,
382  &daemon->per_ip_connection_count,
384  {
385  /* Something's wrong if we couldn't find an IP address
386  * that was previously added */
387  MHD_PANIC ("Failed to find previously-added IP address\n");
388  }
389  found_key = (struct MHD_IPCount *) *nodep;
390  /* Validate existing count for IP address */
391  if (0 == found_key->count)
392  {
393  MHD_PANIC ("Previously-added IP address had 0 count\n");
394  }
395  /* Remove the node entirely if count reduces to 0 */
396  if (0 == --found_key->count)
397  {
398  tdelete (found_key,
399  &daemon->per_ip_connection_count,
401  free (found_key);
402  }
403 
404  MHD_ip_count_unlock (daemon);
405 }
406 
407 
408 #if HTTPS_SUPPORT
409 
417 static ssize_t
418 recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
419 {
420  int res;
421 
422  if (MHD_YES == connection->tls_read_ready)
423  {
424  connection->daemon->num_tls_read_ready--;
425  connection->tls_read_ready = MHD_NO;
426  }
427  res = gnutls_record_recv (connection->tls_session, other, i);
428  if ( (GNUTLS_E_AGAIN == res) ||
429  (GNUTLS_E_INTERRUPTED == res) )
430  {
431  MHD_set_socket_errno_ (EINTR);
432 #if EPOLL_SUPPORT
433  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
434 #endif
435  return -1;
436  }
437  if (res < 0)
438  {
439  /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
440  disrupted); set errno to something caller will interpret
441  correctly as a hard error */
443  return res;
444  }
445  if (res == i)
446  {
447  connection->tls_read_ready = MHD_YES;
448  connection->daemon->num_tls_read_ready++;
449  }
450  return res;
451 }
452 
453 
462 static ssize_t
463 send_tls_adapter (struct MHD_Connection *connection,
464  const void *other, size_t i)
465 {
466  int res;
467 
468  res = gnutls_record_send (connection->tls_session, other, i);
469  if ( (GNUTLS_E_AGAIN == res) ||
470  (GNUTLS_E_INTERRUPTED == res) )
471  {
472  MHD_set_socket_errno_ (EINTR);
473 #if EPOLL_SUPPORT
474  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
475 #endif
476  return -1;
477  }
478  return res;
479 }
480 
481 
488 static int
489 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
490 {
491  gnutls_datum_t key;
492  gnutls_datum_t cert;
493 
494 #if GNUTLS_VERSION_MAJOR >= 3
495  if (NULL != daemon->cert_callback)
496  {
497  gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
498  daemon->cert_callback);
499  }
500 #endif
501  if (NULL != daemon->https_mem_trust)
502  {
503  cert.data = (unsigned char *) daemon->https_mem_trust;
504  cert.size = strlen (daemon->https_mem_trust);
505  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, &cert,
506  GNUTLS_X509_FMT_PEM) < 0)
507  {
508 #if HAVE_MESSAGES
509  MHD_DLOG(daemon,
510  "Bad trust certificate format\n");
511 #endif
512  return -1;
513  }
514  }
515 
516  /* certificate & key loaded from memory */
517  if ( (NULL != daemon->https_mem_cert) &&
518  (NULL != daemon->https_mem_key) )
519  {
520  key.data = (unsigned char *) daemon->https_mem_key;
521  key.size = strlen (daemon->https_mem_key);
522  cert.data = (unsigned char *) daemon->https_mem_cert;
523  cert.size = strlen (daemon->https_mem_cert);
524 
525  return gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
526  &cert, &key,
527  GNUTLS_X509_FMT_PEM);
528  }
529 #if GNUTLS_VERSION_MAJOR >= 3
530  if (NULL != daemon->cert_callback)
531  return 0;
532 #endif
533 #if HAVE_MESSAGES
534  MHD_DLOG (daemon, "You need to specify a certificate and key location\n");
535 #endif
536  return -1;
537 }
538 
539 
546 static int
547 MHD_TLS_init (struct MHD_Daemon *daemon)
548 {
549  switch (daemon->cred_type)
550  {
551  case GNUTLS_CRD_CERTIFICATE:
552  if (0 !=
553  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
554  return GNUTLS_E_MEMORY_ERROR;
555  return MHD_init_daemon_certificate (daemon);
556  default:
557 #if HAVE_MESSAGES
558  MHD_DLOG (daemon,
559  "Error: invalid credentials type %d specified.\n",
560  daemon->cred_type);
561 #endif
562  return -1;
563  }
564 }
565 #endif
566 
567 
576 static void
578  fd_set *set,
579  MHD_socket *max_fd)
580 {
581  FD_SET (fd, set);
582  if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) &&
583  ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) )
584  *max_fd = fd;
585 }
586 
587 
605 int
606 MHD_get_fdset (struct MHD_Daemon *daemon,
607  fd_set *read_fd_set,
608  fd_set *write_fd_set,
609  fd_set *except_fd_set,
610  MHD_socket *max_fd)
611 {
612  struct MHD_Connection *pos;
613  MHD_socket fd;
614 
615  if ( (NULL == daemon)
616  || (NULL == read_fd_set)
617  || (NULL == write_fd_set)
618  || (NULL == except_fd_set)
619  || (MHD_YES == daemon->shutdown)
620  || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
621  || (0 != (daemon->options & MHD_USE_POLL)))
622  return MHD_NO;
623 #if EPOLL_SUPPORT
624  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
625  {
626  /* we're in epoll mode, use the epoll FD as a stand-in for
627  the entire event set */
628 
629  if (daemon->epoll_fd >= FD_SETSIZE)
630  return MHD_NO; /* poll fd too big, fail hard */
631  FD_SET (daemon->epoll_fd, read_fd_set);
632  if ( (NULL != max_fd) && ((*max_fd) < daemon->epoll_fd) )
633  *max_fd = daemon->epoll_fd;
634  return MHD_YES;
635  }
636 #endif
637  fd = daemon->socket_fd;
638  if (MHD_INVALID_SOCKET != fd)
639  {
640  FD_SET (fd, read_fd_set);
641  /* update max file descriptor */
642  if ( (NULL != max_fd) &&
643  ((*max_fd) < fd || MHD_INVALID_SOCKET == (*max_fd)))
644  *max_fd = fd;
645  }
646  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
647  {
648  switch (pos->event_loop_info)
649  {
651  add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
652  break;
654  add_to_fd_set (pos->socket_fd, write_fd_set, max_fd);
655  if (pos->read_buffer_size > pos->read_buffer_offset)
656  add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
657  break;
659  if (pos->read_buffer_size > pos->read_buffer_offset)
660  add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
661  break;
663  /* this should never happen */
664  break;
665  }
666  }
667 #if DEBUG_CONNECT
668 #if HAVE_MESSAGES
669  if (NULL != max_fd)
670  MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd);
671 #endif
672 #endif
673  return MHD_YES;
674 }
675 
676 
684 static void *
686 {
687  struct MHD_Connection *con = data;
688  int num_ready;
689  fd_set rs;
690  fd_set ws;
691  MHD_socket max;
692  struct timeval tv;
693  struct timeval *tvp;
694  unsigned int timeout;
695  time_t now;
696 #ifdef HAVE_POLL_H
697  struct pollfd p[1];
698 #endif
699 
700  timeout = con->daemon->connection_timeout;
701  while ( (MHD_YES != con->daemon->shutdown) &&
702  (MHD_CONNECTION_CLOSED != con->state) )
703  {
704  tvp = NULL;
705  if (timeout > 0)
706  {
707  now = MHD_monotonic_time();
708  if (now - con->last_activity > timeout)
709  tv.tv_sec = 0;
710  else
711  tv.tv_sec = timeout - (now - con->last_activity);
712  tv.tv_usec = 0;
713  tvp = &tv;
714  }
715 #if HTTPS_SUPPORT
716  if (MHD_YES == con->tls_read_ready)
717  {
718  /* do not block (more data may be inside of TLS buffers waiting for us) */
719  tv.tv_sec = 0;
720  tv.tv_usec = 0;
721  tvp = &tv;
722  }
723 #endif
724  if (0 == (con->daemon->options & MHD_USE_POLL))
725  {
726  /* use select */
727  FD_ZERO (&rs);
728  FD_ZERO (&ws);
729  max = 0;
730  switch (con->event_loop_info)
731  {
733  add_to_fd_set (con->socket_fd, &rs, &max);
734  break;
736  add_to_fd_set (con->socket_fd, &ws, &max);
737  if (con->read_buffer_size > con->read_buffer_offset)
738  add_to_fd_set (con->socket_fd, &rs, &max);
739  break;
741  if (con->read_buffer_size > con->read_buffer_offset)
742  add_to_fd_set (con->socket_fd, &rs, &max);
743  tv.tv_sec = 0;
744  tv.tv_usec = 0;
745  tvp = &tv;
746  break;
748  /* how did we get here!? */
749  goto exit;
750  }
751  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp);
752  if (num_ready < 0)
753  {
754  if (EINTR == MHD_socket_errno_)
755  continue;
756 #if HAVE_MESSAGES
757  MHD_DLOG (con->daemon,
758  "Error during select (%d): `%s'\n",
759  max,
761 #endif
762  break;
763  }
764  /* call appropriate connection handler if necessary */
765  if ( (FD_ISSET (con->socket_fd, &rs))
766 #if HTTPS_SUPPORT
767  || (MHD_YES == con->tls_read_ready)
768 #endif
769  )
770  con->read_handler (con);
771  if (FD_ISSET (con->socket_fd, &ws))
772  con->write_handler (con);
773  if (MHD_NO == con->idle_handler (con))
774  goto exit;
775  }
776 #ifdef HAVE_POLL_H
777  else
778  {
779  /* use poll */
780  memset (&p, 0, sizeof (p));
781  p[0].fd = con->socket_fd;
782  switch (con->event_loop_info)
783  {
785  p[0].events |= POLLIN;
786  break;
788  p[0].events |= POLLOUT;
789  if (con->read_buffer_size > con->read_buffer_offset)
790  p[0].events |= POLLIN;
791  break;
793  if (con->read_buffer_size > con->read_buffer_offset)
794  p[0].events |= POLLIN;
795  tv.tv_sec = 0;
796  tv.tv_usec = 0;
797  tvp = &tv;
798  break;
800  /* how did we get here!? */
801  goto exit;
802  }
803  if (poll (p, 1,
804  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
805  {
806  if (EINTR == MHD_socket_errno_)
807  continue;
808 #if HAVE_MESSAGES
809  MHD_DLOG (con->daemon, "Error during poll: `%s'\n",
811 #endif
812  break;
813  }
814  if ( (0 != (p[0].revents & POLLIN))
815 #if HTTPS_SUPPORT
816  || (MHD_YES == con->tls_read_ready)
817 #endif
818  )
819  con->read_handler (con);
820  if (0 != (p[0].revents & POLLOUT))
821  con->write_handler (con);
822  if (0 != (p[0].revents & (POLLERR | POLLHUP)))
824  if (MHD_NO == con->idle_handler (con))
825  goto exit;
826  }
827 #endif
828  }
829  if (MHD_CONNECTION_IN_CLEANUP != con->state)
830  {
831 #if DEBUG_CLOSE
832 #if HAVE_MESSAGES
833  MHD_DLOG (con->daemon,
834  "Processing thread terminating, closing connection\n");
835 #endif
836 #endif
837  if (MHD_CONNECTION_CLOSED != con->state)
840  con->idle_handler (con);
841  }
842 exit:
843  if (NULL != con->response)
844  {
846  con->response = NULL;
847  }
848  return NULL;
849 }
850 
851 
860 static ssize_t
861 recv_param_adapter (struct MHD_Connection *connection,
862  void *other,
863  size_t i)
864 {
865  ssize_t ret;
866 
867  if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
868  (MHD_CONNECTION_CLOSED == connection->state) )
869  {
871  return -1;
872  }
873  ret = recv (connection->socket_fd, other, i, MSG_NOSIGNAL);
874 #if EPOLL_SUPPORT
875  if (ret < (ssize_t) i)
876  {
877  /* partial read --- no longer read-ready */
878  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
879  }
880 #endif
881  return ret;
882 }
883 
884 
893 static ssize_t
894 send_param_adapter (struct MHD_Connection *connection,
895  const void *other,
896  size_t i)
897 {
898  ssize_t ret;
899 #if LINUX
900  MHD_socket fd;
901  off_t offset;
902  off_t left;
903 #endif
904 
905  if ( (MHD_INVALID_SOCKET == connection->socket_fd) ||
906  (MHD_CONNECTION_CLOSED == connection->state) )
907  {
909  return -1;
910  }
911  if (0 != (connection->daemon->options & MHD_USE_SSL))
912  return send (connection->socket_fd, other, i, MSG_NOSIGNAL);
913 #if LINUX
914  if ( (connection->write_buffer_append_offset ==
915  connection->write_buffer_send_offset) &&
916  (NULL != connection->response) &&
917  (MHD_INVALID_SOCKET != (fd = connection->response->fd)) )
918  {
919  /* can use sendfile */
920  offset = (off_t) connection->response_write_position + connection->response->fd_off;
921  left = connection->response->total_size - connection->response_write_position;
922  if (left > SSIZE_MAX)
923  left = SSIZE_MAX; /* cap at return value limit */
924  if (-1 != (ret = sendfile (connection->socket_fd,
925  fd,
926  &offset,
927  (size_t) left)))
928  {
929 #if EPOLL_SUPPORT
930  if (ret < left)
931  {
932  /* partial write --- no longer write-ready */
933  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
934  }
935 #endif
936  return ret;
937  }
938  const int err = MHD_socket_errno_;
939  if ( (EINTR == err) || (EAGAIN == err) || (EWOULDBLOCK == err) )
940  return 0;
941  if ( (EINVAL == err) || (EBADF == err) )
942  return -1;
943  /* None of the 'usual' sendfile errors occurred, so we should try
944  to fall back to 'SEND'; see also this thread for info on
945  odd libc/Linux behavior with sendfile:
946  http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
947  }
948 #endif
949  ret = send (connection->socket_fd, other, i, MSG_NOSIGNAL);
950 #if EPOLL_SUPPORT
951  if (ret < (ssize_t) i)
952  {
953  /* partial write --- no longer write-ready */
954  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
955  }
956 #endif
957  return ret;
958 }
959 
960 
967 typedef void *(*ThreadStartRoutine)(void *cls);
968 
969 
979 static int
980 create_thread (pthread_t *thread,
981  const struct MHD_Daemon *daemon,
982  ThreadStartRoutine start_routine,
983  void *arg)
984 {
985  pthread_attr_t attr;
986  pthread_attr_t *pattr;
987  int ret;
988 
989  if (0 != daemon->thread_stack_size)
990  {
991  if (0 != (ret = pthread_attr_init (&attr)))
992  goto ERR;
993  if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size)))
994  {
995  pthread_attr_destroy (&attr);
996  goto ERR;
997  }
998  pattr = &attr;
999  }
1000  else
1001  {
1002  pattr = NULL;
1003  }
1004  ret = pthread_create (thread, pattr,
1005  start_routine, arg);
1006 #if (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12)
1007 #if LINUX
1008  (void) pthread_setname_np (*thread, "libmicrohttpd");
1009 #endif
1010 #endif
1011  if (0 != daemon->thread_stack_size)
1012  pthread_attr_destroy (&attr);
1013  return ret;
1014  ERR:
1015 #if HAVE_MESSAGES
1016  MHD_DLOG (daemon,
1017  "Failed to set thread stack size\n");
1018 #endif
1019  errno = EINVAL;
1020  return ret;
1021 }
1022 
1023 
1050 static int
1052  MHD_socket client_socket,
1053  const struct sockaddr *addr,
1054  socklen_t addrlen,
1055  int external_add)
1056 {
1057  struct MHD_Connection *connection;
1058  int res_thread_create;
1059  unsigned int i;
1060  int eno;
1061 #if OSX
1062  static int on = 1;
1063 #endif
1064  if (NULL != daemon->worker_pool)
1065  {
1066  /* have a pool, try to find a pool with capacity; we use the
1067  socket as the initial offset into the pool for load
1068  balancing */
1069  for (i=0;i<daemon->worker_pool_size;i++)
1070  if (0 < daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size].max_connections)
1071  return internal_add_connection (&daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size],
1072  client_socket,
1073  addr, addrlen,
1074  external_add);
1075  /* all pools are at their connection limit, must refuse */
1076  if (0 != MHD_socket_close_ (client_socket))
1077  MHD_PANIC ("close failed\n");
1078 #if ENFILE
1079  errno = ENFILE;
1080 #endif
1081  return MHD_NO;
1082  }
1083 
1084 #ifndef WINDOWS
1085  if ( (client_socket >= FD_SETSIZE) &&
1086  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) )
1087  {
1088 #if HAVE_MESSAGES
1089  MHD_DLOG (daemon,
1090  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
1091  client_socket,
1092  FD_SETSIZE);
1093 #endif
1094  if (0 != MHD_socket_close_ (client_socket))
1095  MHD_PANIC ("close failed\n");
1096 #if EINVAL
1097  errno = EINVAL;
1098 #endif
1099  return MHD_NO;
1100  }
1101 #endif
1102 
1103 
1104 #if HAVE_MESSAGES
1105 #if DEBUG_CONNECT
1106  MHD_DLOG (daemon, "Accepted connection on socket %d\n", client_socket);
1107 #endif
1108 #endif
1109  if ( (0 == daemon->max_connections) ||
1110  (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) )
1111  {
1112  /* above connection limit - reject */
1113 #if HAVE_MESSAGES
1114  MHD_DLOG (daemon,
1115  "Server reached connection limit (closing inbound connection)\n");
1116 #endif
1117  if (0 != MHD_socket_close_ (client_socket))
1118  MHD_PANIC ("close failed\n");
1119 #if ENFILE
1120  errno = ENFILE;
1121 #endif
1122  return MHD_NO;
1123  }
1124 
1125  /* apply connection acceptance policy if present */
1126  if ( (NULL != daemon->apc) &&
1127  (MHD_NO == daemon->apc (daemon->apc_cls,
1128  addr, addrlen)) )
1129  {
1130 #if DEBUG_CLOSE
1131 #if HAVE_MESSAGES
1132  MHD_DLOG (daemon, "Connection rejected, closing connection\n");
1133 #endif
1134 #endif
1135  if (0 != MHD_socket_close_ (client_socket))
1136  MHD_PANIC ("close failed\n");
1137  MHD_ip_limit_del (daemon, addr, addrlen);
1138 #if EACCESS
1139  errno = EACCESS;
1140 #endif
1141  return MHD_NO;
1142  }
1143 
1144 #if OSX
1145 #ifdef SOL_SOCKET
1146 #ifdef SO_NOSIGPIPE
1147  setsockopt (client_socket,
1148  SOL_SOCKET, SO_NOSIGPIPE,
1149  &on, sizeof (on));
1150 #endif
1151 #endif
1152 #endif
1153 
1154  if (NULL == (connection = malloc (sizeof (struct MHD_Connection))))
1155  {
1156  eno = errno;
1157 #if HAVE_MESSAGES
1158  MHD_DLOG (daemon,
1159  "Error allocating memory: %s\n",
1160  MHD_strerror_ (errno));
1161 #endif
1162  if (0 != MHD_socket_close_ (client_socket))
1163  MHD_PANIC ("close failed\n");
1164  MHD_ip_limit_del (daemon, addr, addrlen);
1165  errno = eno;
1166  return MHD_NO;
1167  }
1168  memset (connection, 0, sizeof (struct MHD_Connection));
1169  connection->pool = MHD_pool_create (daemon->pool_size);
1170  if (NULL == connection->pool)
1171  {
1172 #if HAVE_MESSAGES
1173  MHD_DLOG (daemon,
1174  "Error allocating memory: %s\n",
1175  MHD_strerror_ (errno));
1176 #endif
1177  if (0 != MHD_socket_close_ (client_socket))
1178  MHD_PANIC ("close failed\n");
1179  MHD_ip_limit_del (daemon, addr, addrlen);
1180  free (connection);
1181 #if ENOMEM
1182  errno = ENOMEM;
1183 #endif
1184  return MHD_NO;
1185  }
1186 
1187  connection->connection_timeout = daemon->connection_timeout;
1188  if (NULL == (connection->addr = malloc (addrlen)))
1189  {
1190  eno = errno;
1191 #if HAVE_MESSAGES
1192  MHD_DLOG (daemon,
1193  "Error allocating memory: %s\n",
1194  MHD_strerror_ (errno));
1195 #endif
1196  if (0 != MHD_socket_close_ (client_socket))
1197  MHD_PANIC ("close failed\n");
1198  MHD_ip_limit_del (daemon, addr, addrlen);
1199  MHD_pool_destroy (connection->pool);
1200  free (connection);
1201  errno = eno;
1202  return MHD_NO;
1203  }
1204  memcpy (connection->addr, addr, addrlen);
1205  connection->addr_len = addrlen;
1206  connection->socket_fd = client_socket;
1207  connection->daemon = daemon;
1208  connection->last_activity = MHD_monotonic_time();
1209 
1210  /* set default connection handlers */
1211  MHD_set_http_callbacks_ (connection);
1212  connection->recv_cls = &recv_param_adapter;
1213  connection->send_cls = &send_param_adapter;
1214 
1215  if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
1216  {
1217  /* non-blocking sockets are required on most systems and for GNUtls;
1218  however, they somehow cause serious problems on CYGWIN (#1824);
1219  in turbo mode, we assume that non-blocking was already set
1220  by 'accept4' or whoever calls 'MHD_add_connection' */
1221 #ifdef CYGWIN
1222  if (0 != (daemon->options & MHD_USE_SSL))
1223 #endif
1224  {
1225  /* make socket non-blocking */
1226 #ifndef MINGW
1227  int flags = fcntl (connection->socket_fd, F_GETFL);
1228  if ( (-1 == flags) ||
1229  (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
1230  {
1231 #if HAVE_MESSAGES
1232  MHD_DLOG (daemon,
1233  "Failed to make socket non-blocking: %s\n",
1235 #endif
1236  }
1237 #else
1238  unsigned long flags = 1;
1239  if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
1240  {
1241 #if HAVE_MESSAGES
1242  MHD_DLOG (daemon,
1243  "Failed to make socket non-blocking: %s\n",
1245 #endif
1246  }
1247 #endif
1248  }
1249  }
1250 
1251 #if HTTPS_SUPPORT
1252  if (0 != (daemon->options & MHD_USE_SSL))
1253  {
1254  connection->recv_cls = &recv_tls_adapter;
1255  connection->send_cls = &send_tls_adapter;
1256  connection->state = MHD_TLS_CONNECTION_INIT;
1257  MHD_set_https_callbacks (connection);
1258  gnutls_init (&connection->tls_session, GNUTLS_SERVER);
1259  gnutls_priority_set (connection->tls_session,
1260  daemon->priority_cache);
1261  switch (daemon->cred_type)
1262  {
1263  /* set needed credentials for certificate authentication. */
1264  case GNUTLS_CRD_CERTIFICATE:
1265  gnutls_credentials_set (connection->tls_session,
1266  GNUTLS_CRD_CERTIFICATE,
1267  daemon->x509_cred);
1268  break;
1269  default:
1270 #if HAVE_MESSAGES
1271  MHD_DLOG (connection->daemon,
1272  "Failed to setup TLS credentials: unknown credential type %d\n",
1273  daemon->cred_type);
1274 #endif
1275  if (0 != MHD_socket_close_ (client_socket))
1276  MHD_PANIC ("close failed\n");
1277  MHD_ip_limit_del (daemon, addr, addrlen);
1278  free (connection->addr);
1279  free (connection);
1280  MHD_PANIC ("Unknown credential type");
1281 #if EINVAL
1282  errno = EINVAL;
1283 #endif
1284  return MHD_NO;
1285  }
1286  gnutls_transport_set_ptr (connection->tls_session,
1287  (gnutls_transport_ptr_t) connection);
1288  gnutls_transport_set_pull_function (connection->tls_session,
1289  (gnutls_pull_func) &recv_param_adapter);
1290  gnutls_transport_set_push_function (connection->tls_session,
1291  (gnutls_push_func) &send_param_adapter);
1292 
1293  if (daemon->https_mem_trust)
1294  gnutls_certificate_server_set_request (connection->tls_session,
1295  GNUTLS_CERT_REQUEST);
1296  }
1297 #endif
1298 
1299  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1300  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1301  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1303  daemon->normal_timeout_tail,
1304  connection);
1305  DLL_insert (daemon->connections_head,
1306  daemon->connections_tail,
1307  connection);
1308  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1309  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1310  MHD_PANIC ("Failed to release cleanup mutex\n");
1311 
1312  /* attempt to create handler thread */
1313  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1314  {
1315  res_thread_create = create_thread (&connection->pid, daemon,
1316  &MHD_handle_connection, connection);
1317  if (0 != res_thread_create)
1318  {
1319  eno = errno;
1320 #if HAVE_MESSAGES
1321  MHD_DLOG (daemon, "Failed to create a thread: %s\n",
1322  MHD_strerror_ (res_thread_create));
1323 #endif
1324  goto cleanup;
1325  }
1326  }
1327  else
1328  if ( (MHD_YES == external_add) &&
1329  (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1330  (1 != MHD_pipe_write_ (daemon->wpipe[1], "n", 1)) )
1331  {
1332 #if HAVE_MESSAGES
1333  MHD_DLOG (daemon,
1334  "failed to signal new connection via pipe");
1335 #endif
1336  }
1337 #if EPOLL_SUPPORT
1338  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1339  {
1340  if (0 == (daemon->options & MHD_USE_EPOLL_TURBO))
1341  {
1342  struct epoll_event event;
1343 
1344  event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1345  event.data.ptr = connection;
1346  if (0 != epoll_ctl (daemon->epoll_fd,
1347  EPOLL_CTL_ADD,
1348  client_socket,
1349  &event))
1350  {
1351  eno = errno;
1352 #if HAVE_MESSAGES
1353  MHD_DLOG (daemon,
1354  "Call to epoll_ctl failed: %s\n",
1356 #endif
1357  goto cleanup;
1358  }
1359  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1360  }
1361  else
1362  {
1363  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
1365  EDLL_insert (daemon->eready_head,
1366  daemon->eready_tail,
1367  connection);
1368  }
1369  }
1370 #endif
1371  daemon->max_connections--;
1372  return MHD_YES;
1373  cleanup:
1374  if (0 != MHD_socket_close_ (client_socket))
1375  MHD_PANIC ("close failed\n");
1376  MHD_ip_limit_del (daemon, addr, addrlen);
1377  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1378  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1379  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1380  DLL_remove (daemon->connections_head,
1381  daemon->connections_tail,
1382  connection);
1384  daemon->normal_timeout_tail,
1385  connection);
1386  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1387  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1388  MHD_PANIC ("Failed to release cleanup mutex\n");
1389  MHD_pool_destroy (connection->pool);
1390  free (connection->addr);
1391  free (connection);
1392 #if EINVAL
1393  errno = eno;
1394 #endif
1395  return MHD_NO;
1396 }
1397 
1398 
1426 void
1428 {
1429  struct MHD_Daemon *daemon;
1430 
1431  daemon = connection->daemon;
1433  MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1434  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1435  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1436  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1437  DLL_remove (daemon->connections_head,
1438  daemon->connections_tail,
1439  connection);
1442  connection);
1443  if (connection->connection_timeout == daemon->connection_timeout)
1445  daemon->normal_timeout_tail,
1446  connection);
1447  else
1449  daemon->manual_timeout_tail,
1450  connection);
1451 #if EPOLL_SUPPORT
1452  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1453  {
1454  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1455  {
1456  EDLL_remove (daemon->eready_head,
1457  daemon->eready_tail,
1458  connection);
1459  }
1460  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
1461  {
1462  if (0 != epoll_ctl (daemon->epoll_fd,
1463  EPOLL_CTL_DEL,
1464  connection->socket_fd,
1465  NULL))
1466  MHD_PANIC ("Failed to remove FD from epoll set\n");
1467  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1468  }
1469  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
1470  }
1471 #endif
1472  connection->suspended = MHD_YES;
1473  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1474  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1475  MHD_PANIC ("Failed to release cleanup mutex\n");
1476 }
1477 
1478 
1487 void
1489 {
1490  struct MHD_Daemon *daemon;
1491 
1492  daemon = connection->daemon;
1494  MHD_PANIC ("Cannot resume connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1495  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1496  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1497  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1498  connection->resuming = MHD_YES;
1499  daemon->resuming = MHD_YES;
1500  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
1501  (1 != MHD_pipe_write_ (daemon->wpipe[1], "r", 1)) )
1502  {
1503 #if HAVE_MESSAGES
1504  MHD_DLOG (daemon,
1505  "failed to signal resume via pipe");
1506 #endif
1507  }
1508  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1509  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1510  MHD_PANIC ("Failed to release cleanup mutex\n");
1511 }
1512 
1519 static void
1521 {
1522  struct MHD_Connection *pos;
1523  struct MHD_Connection *next = NULL;
1524 
1525  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1526  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1527  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1528 
1529  if (MHD_YES == daemon->resuming)
1530  next = daemon->suspended_connections_head;
1531 
1532  while (NULL != (pos = next))
1533  {
1534  next = pos->next;
1535  if (MHD_NO == pos->resuming)
1536  continue;
1537 
1540  pos);
1541  DLL_insert (daemon->connections_head,
1542  daemon->connections_tail,
1543  pos);
1544  if (pos->connection_timeout == daemon->connection_timeout)
1546  daemon->normal_timeout_tail,
1547  pos);
1548  else
1550  daemon->manual_timeout_tail,
1551  pos);
1552 #if EPOLL_SUPPORT
1553  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1554  {
1555  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1556  {
1557  EDLL_insert (daemon->eready_head,
1558  daemon->eready_tail,
1559  pos);
1560  }
1561  else
1562  {
1563  struct epoll_event event;
1564 
1565  event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1566  event.data.ptr = pos;
1567  if (0 != epoll_ctl (daemon->epoll_fd,
1568  EPOLL_CTL_ADD,
1569  pos->socket_fd,
1570  &event))
1571  MHD_PANIC ("Failed to add FD to epoll set\n");
1572  else
1573  pos->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1574  }
1575  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
1576  }
1577 #endif
1578  pos->suspended = MHD_NO;
1579  pos->resuming = MHD_NO;
1580  }
1581  daemon->resuming = MHD_NO;
1582  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1583  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1584  MHD_PANIC ("Failed to release cleanup mutex\n");
1585 }
1586 
1587 
1594 static void
1596  MHD_socket sock)
1597 {
1598 #ifdef WINDOWS
1599  DWORD dwFlags;
1600  unsigned long flags = 1;
1601 
1602  if (0 != ioctlsocket (sock, FIONBIO, &flags))
1603  {
1604 #if HAVE_MESSAGES
1605  MHD_DLOG (daemon,
1606  "Failed to make socket non-blocking: %s\n",
1608 #endif
1609  }
1610  if (!GetHandleInformation ((HANDLE) sock, &dwFlags) ||
1611  ((dwFlags != (dwFlags & ~HANDLE_FLAG_INHERIT)) &&
1612  !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)))
1613  {
1614 #if HAVE_MESSAGES
1615  MHD_DLOG (daemon,
1616  "Failed to make socket non-inheritable: %u\n",
1617  (unsigned int) GetLastError ());
1618 #endif
1619  }
1620 #else
1621  int flags;
1622  int nonblock;
1623 
1624  nonblock = O_NONBLOCK;
1625 #ifdef CYGWIN
1626  if (0 == (daemon->options & MHD_USE_SSL))
1627  nonblock = 0;
1628 #endif
1629  flags = fcntl (sock, F_GETFD);
1630  if ( ( (-1 == flags) ||
1631  ( (flags != (flags | FD_CLOEXEC)) &&
1632  (0 != fcntl (sock, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) )
1633  {
1634 #if HAVE_MESSAGES
1635  MHD_DLOG (daemon,
1636  "Failed to make socket non-inheritable: %s\n",
1638 #endif
1639  }
1640 #endif
1641 }
1642 
1643 
1673 int
1675  MHD_socket client_socket,
1676  const struct sockaddr *addr,
1677  socklen_t addrlen)
1678 {
1680  client_socket);
1681  return internal_add_connection (daemon,
1682  client_socket,
1683  addr, addrlen,
1684  MHD_YES);
1685 }
1686 
1687 
1700 static int
1702 {
1703 #if HAVE_INET6
1704  struct sockaddr_in6 addrstorage;
1705 #else
1706  struct sockaddr_in addrstorage;
1707 #endif
1708  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
1709  socklen_t addrlen;
1710  MHD_socket s;
1711  MHD_socket fd;
1712  int nonblock;
1713 
1714  addrlen = sizeof (addrstorage);
1715  memset (addr, 0, sizeof (addrstorage));
1716  if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd))
1717  return MHD_NO;
1718 #ifdef HAVE_SOCK_NONBLOCK
1719  nonblock = SOCK_NONBLOCK;
1720 #else
1721  nonblock = 0;
1722 #endif
1723 #ifdef CYGWIN
1724  if (0 == (daemon->options & MHD_USE_SSL))
1725  nonblock = 0;
1726 #endif
1727 #if HAVE_ACCEPT4
1728  s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock);
1729 #else
1730  s = accept (fd, addr, &addrlen);
1731 #endif
1732  if ((MHD_INVALID_SOCKET == s) || (addrlen <= 0))
1733  {
1734 #if HAVE_MESSAGES
1735  const int err = MHD_socket_errno_;
1736  /* This could be a common occurance with multiple worker threads */
1737  if ((EAGAIN != err) && (EWOULDBLOCK != err))
1738  MHD_DLOG (daemon,
1739  "Error accepting connection: %s\n",
1741 #endif
1742  if (MHD_INVALID_SOCKET != s)
1743  {
1744  if (0 != MHD_socket_close_ (s))
1745  MHD_PANIC ("close failed\n");
1746  /* just in case */
1747  }
1748  return MHD_NO;
1749  }
1750 #if !defined(HAVE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) || SOCK_CLOEXEC+0 == 0
1751  make_nonblocking_noninheritable (daemon, s);
1752 #endif
1753 #if HAVE_MESSAGES
1754 #if DEBUG_CONNECT
1755  MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
1756 #endif
1757 #endif
1758  (void) internal_add_connection (daemon, s,
1759  addr, addrlen,
1760  MHD_NO);
1761  return MHD_YES;
1762 }
1763 
1764 
1772 static void
1774 {
1775  struct MHD_Connection *pos;
1776  void *unused;
1777  int rc;
1778 
1779  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1780  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1781  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1782  while (NULL != (pos = daemon->cleanup_head))
1783  {
1784  DLL_remove (daemon->cleanup_head,
1785  daemon->cleanup_tail,
1786  pos);
1787  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1788  (MHD_NO == pos->thread_joined) )
1789  {
1790  if (0 != (rc = pthread_join (pos->pid, &unused)))
1791  {
1792  MHD_PANIC ("Failed to join a thread\n");
1793  }
1794  }
1795  MHD_pool_destroy (pos->pool);
1796 #if HTTPS_SUPPORT
1797  if (pos->tls_session != NULL)
1798  gnutls_deinit (pos->tls_session);
1799 #endif
1800  MHD_ip_limit_del (daemon,
1801  (struct sockaddr *) pos->addr,
1802  pos->addr_len);
1803 #if EPOLL_SUPPORT
1804  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1805  {
1806  EDLL_remove (daemon->eready_head,
1807  daemon->eready_tail,
1808  pos);
1809  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
1810  }
1811  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
1812  (MHD_INVALID_SOCKET != daemon->epoll_fd) &&
1813  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
1814  {
1815  /* epoll documentation suggests that closing a FD
1816  automatically removes it from the epoll set; however,
1817  this is not true as if we fail to do manually remove it,
1818  we are still seeing an event for this fd in epoll,
1819  causing grief (use-after-free...) --- at least on my
1820  system. */
1821  if (0 != epoll_ctl (daemon->epoll_fd,
1822  EPOLL_CTL_DEL,
1823  pos->socket_fd,
1824  NULL))
1825  MHD_PANIC ("Failed to remove FD from epoll set\n");
1826  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1827  }
1828 #endif
1829  if (NULL != pos->response)
1830  {
1832  pos->response = NULL;
1833  }
1834  if (MHD_INVALID_SOCKET != pos->socket_fd)
1835  {
1836 #ifdef WINDOWS
1837  shutdown (pos->socket_fd, SHUT_WR);
1838 #endif
1839  if (0 != MHD_socket_close_ (pos->socket_fd))
1840  MHD_PANIC ("close failed\n");
1841  }
1842  if (NULL != pos->addr)
1843  free (pos->addr);
1844  free (pos);
1845  daemon->max_connections++;
1846  }
1847  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1848  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1849  MHD_PANIC ("Failed to release cleanup mutex\n");
1850 }
1851 
1852 
1867 int
1868 MHD_get_timeout (struct MHD_Daemon *daemon,
1869  MHD_UNSIGNED_LONG_LONG *timeout)
1870 {
1871  time_t earliest_deadline;
1872  time_t now;
1873  struct MHD_Connection *pos;
1874  int have_timeout;
1875 
1876  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1877  {
1878 #if HAVE_MESSAGES
1879  MHD_DLOG (daemon, "Illegal call to MHD_get_timeout\n");
1880 #endif
1881  return MHD_NO;
1882  }
1883 
1884 #if HTTPS_SUPPORT
1885  if (0 != daemon->num_tls_read_ready)
1886  {
1887  /* if there is any TLS connection with data ready for
1888  reading, we must not block in the event loop */
1889  *timeout = 0;
1890  return MHD_YES;
1891  }
1892 #endif
1893 
1894  have_timeout = MHD_NO;
1895  earliest_deadline = 0; /* avoid compiler warnings */
1896  for (pos = daemon->manual_timeout_head; NULL != pos; pos = pos->nextX)
1897  {
1898  if (0 != pos->connection_timeout)
1899  {
1900  if ( (! have_timeout) ||
1901  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
1902  earliest_deadline = pos->last_activity + pos->connection_timeout;
1903 #if HTTPS_SUPPORT
1904  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
1905  (0 != gnutls_record_check_pending (pos->tls_session)) )
1906  earliest_deadline = 0;
1907 #endif
1908  have_timeout = MHD_YES;
1909  }
1910  }
1911  /* normal timeouts are sorted, so we only need to look at the 'head' */
1912  pos = daemon->normal_timeout_head;
1913  if ( (NULL != pos) &&
1914  (0 != pos->connection_timeout) )
1915  {
1916  if ( (! have_timeout) ||
1917  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
1918  earliest_deadline = pos->last_activity + pos->connection_timeout;
1919 #if HTTPS_SUPPORT
1920  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
1921  (0 != gnutls_record_check_pending (pos->tls_session)) )
1922  earliest_deadline = 0;
1923 #endif
1924  have_timeout = MHD_YES;
1925  }
1926 
1927  if (MHD_NO == have_timeout)
1928  return MHD_NO;
1929  now = MHD_monotonic_time();
1930  if (earliest_deadline < now)
1931  *timeout = 0;
1932  else
1933  *timeout = 1000 * (1 + earliest_deadline - now);
1934  return MHD_YES;
1935 }
1936 
1937 
1957 int
1959  const fd_set *read_fd_set,
1960  const fd_set *write_fd_set,
1961  const fd_set *except_fd_set)
1962 {
1963  MHD_socket ds;
1964  char tmp;
1965  struct MHD_Connection *pos;
1966  struct MHD_Connection *next;
1967 
1968 #if EPOLL_SUPPORT
1969  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1970  {
1971  /* we're in epoll mode, the epoll FD stands for
1972  the entire event set! */
1973  if (daemon->epoll_fd >= FD_SETSIZE)
1974  return MHD_NO; /* poll fd too big, fail hard */
1975  if (FD_ISSET (daemon->epoll_fd, read_fd_set))
1976  return MHD_run (daemon);
1977  return MHD_YES;
1978  }
1979 #endif
1980 
1981  /* select connection thread handling type */
1982  if ( (MHD_INVALID_SOCKET != (ds = daemon->socket_fd)) &&
1983  (FD_ISSET (ds, read_fd_set)) )
1984  (void) MHD_accept_connection (daemon);
1985  /* drain signaling pipe to avoid spinning select */
1986  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
1987  (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
1988  (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
1989 
1990  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1991  {
1992  /* do not have a thread per connection, process all connections now */
1993  next = daemon->connections_head;
1994  while (NULL != (pos = next))
1995  {
1996  next = pos->next;
1997  ds = pos->socket_fd;
1998  if (MHD_INVALID_SOCKET == ds)
1999  continue;
2000  switch (pos->event_loop_info)
2001  {
2003  if ( (FD_ISSET (ds, read_fd_set))
2004 #if HTTPS_SUPPORT
2005  || (MHD_YES == pos->tls_read_ready)
2006 #endif
2007  )
2008  pos->read_handler (pos);
2009  break;
2011  if ( (FD_ISSET (ds, read_fd_set)) &&
2012  (pos->read_buffer_size > pos->read_buffer_offset) )
2013  pos->read_handler (pos);
2014  if (FD_ISSET (ds, write_fd_set))
2015  pos->write_handler (pos);
2016  break;
2018  if ( (FD_ISSET (ds, read_fd_set)) &&
2019  (pos->read_buffer_size > pos->read_buffer_offset) )
2020  pos->read_handler (pos);
2021  break;
2023  /* should never happen */
2024  break;
2025  }
2026  pos->idle_handler (pos);
2027  }
2028  }
2029  MHD_cleanup_connections (daemon);
2030  return MHD_YES;
2031 }
2032 
2033 
2042 static int
2043 MHD_select (struct MHD_Daemon *daemon,
2044  int may_block)
2045 {
2046  int num_ready;
2047  fd_set rs;
2048  fd_set ws;
2049  fd_set es;
2050  MHD_socket max;
2051  struct timeval timeout;
2052  struct timeval *tv;
2053  MHD_UNSIGNED_LONG_LONG ltimeout;
2054 
2055  timeout.tv_sec = 0;
2056  timeout.tv_usec = 0;
2057  if (MHD_YES == daemon->shutdown)
2058  return MHD_NO;
2059  FD_ZERO (&rs);
2060  FD_ZERO (&ws);
2061  FD_ZERO (&es);
2062  max = MHD_INVALID_SOCKET;
2063  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2064  {
2067 
2068  /* single-threaded, go over everything */
2069  if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
2070  return MHD_NO;
2071 
2072  /* If we're at the connection limit, no need to
2073  accept new connections. */
2074  if ( (0 == daemon->max_connections) &&
2075  (MHD_INVALID_SOCKET != daemon->socket_fd) )
2076  FD_CLR (daemon->socket_fd, &rs);
2077  }
2078  else
2079  {
2080  /* accept only, have one thread per connection */
2081  if (MHD_INVALID_SOCKET != daemon->socket_fd)
2082  {
2083  max = daemon->socket_fd;
2084  FD_SET (daemon->socket_fd, &rs);
2085  }
2086  }
2087  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2088  {
2089  FD_SET (daemon->wpipe[0], &rs);
2090  /* update max file descriptor */
2091  if (max < daemon->wpipe[0] || max == MHD_INVALID_SOCKET)
2092  max = daemon->wpipe[0];
2093  }
2094 
2095  tv = NULL;
2096  if (MHD_NO == may_block)
2097  {
2098  timeout.tv_usec = 0;
2099  timeout.tv_sec = 0;
2100  tv = &timeout;
2101  }
2102  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2103  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
2104  {
2105  /* ltimeout is in ms */
2106  timeout.tv_usec = (ltimeout % 1000) * 1000;
2107  timeout.tv_sec = ltimeout / 1000;
2108  tv = &timeout;
2109  }
2110  if (MHD_INVALID_SOCKET == max)
2111  return MHD_YES;
2112  num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, &es, tv);
2113  if (MHD_YES == daemon->shutdown)
2114  return MHD_NO;
2115  if (num_ready < 0)
2116  {
2117  if (EINTR == MHD_socket_errno_)
2118  return MHD_YES;
2119 #if HAVE_MESSAGES
2120  MHD_DLOG (daemon, "select failed: %s\n", MHD_socket_last_strerr_ ());
2121 #endif
2122  return MHD_NO;
2123  }
2124  return MHD_run_from_select (daemon, &rs, &ws, &es);
2125 }
2126 
2127 
2128 #ifdef HAVE_POLL_H
2129 
2137 static int
2138 MHD_poll_all (struct MHD_Daemon *daemon,
2139  int may_block)
2140 {
2141  unsigned int num_connections;
2142  struct MHD_Connection *pos;
2143  struct MHD_Connection *next;
2144 
2147 
2148  /* count number of connections and thus determine poll set size */
2149  num_connections = 0;
2150  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2151  num_connections++;
2152  {
2153  struct pollfd p[2 + num_connections];
2154  MHD_UNSIGNED_LONG_LONG ltimeout;
2155  unsigned int i;
2156  int timeout;
2157  unsigned int poll_server;
2158  int poll_listen;
2159 
2160  memset (p, 0, sizeof (p));
2161  poll_server = 0;
2162  poll_listen = -1;
2163  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2164  (0 != daemon->max_connections) )
2165  {
2166  /* only listen if we are not at the connection limit */
2167  p[poll_server].fd = daemon->socket_fd;
2168  p[poll_server].events = POLLIN;
2169  p[poll_server].revents = 0;
2170  poll_listen = (int) poll_server;
2171  poll_server++;
2172  }
2173  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2174  {
2175  p[poll_server].fd = daemon->wpipe[0];
2176  p[poll_server].events = POLLIN;
2177  p[poll_server].revents = 0;
2178  poll_server++;
2179  }
2180  if (may_block == MHD_NO)
2181  timeout = 0;
2182  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2183  (MHD_YES != MHD_get_timeout (daemon, &ltimeout)) )
2184  timeout = -1;
2185  else
2186  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
2187 
2188  i = 0;
2189  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2190  {
2191  p[poll_server+i].fd = pos->socket_fd;
2192  switch (pos->event_loop_info)
2193  {
2195  p[poll_server+i].events |= POLLIN;
2196  break;
2198  p[poll_server+i].events |= POLLOUT;
2199  if (pos->read_buffer_size > pos->read_buffer_offset)
2200  p[poll_server+i].events |= POLLIN;
2201  break;
2203  if (pos->read_buffer_size > pos->read_buffer_offset)
2204  p[poll_server+i].events |= POLLIN;
2205  break;
2207  /* should never happen */
2208  break;
2209  }
2210  i++;
2211  }
2212  if (0 == poll_server + num_connections)
2213  return MHD_YES;
2214  if (poll (p, poll_server + num_connections, timeout) < 0)
2215  {
2216  if (EINTR == MHD_socket_errno_)
2217  return MHD_YES;
2218 #if HAVE_MESSAGES
2219  MHD_DLOG (daemon,
2220  "poll failed: %s\n",
2222 #endif
2223  return MHD_NO;
2224  }
2225  /* handle shutdown */
2226  if (MHD_YES == daemon->shutdown)
2227  return MHD_NO;
2228  i = 0;
2229  next = daemon->connections_head;
2230  while (NULL != (pos = next))
2231  {
2232  next = pos->next;
2233  switch (pos->event_loop_info)
2234  {
2236  /* first, sanity checks */
2237  if (i >= num_connections)
2238  break; /* connection list changed somehow, retry later ... */
2239  if (p[poll_server+i].fd != pos->socket_fd)
2240  break; /* fd mismatch, something else happened, retry later ... */
2241  /* normal handling */
2242  if (0 != (p[poll_server+i].revents & POLLIN))
2243  pos->read_handler (pos);
2244  pos->idle_handler (pos);
2245  i++;
2246  break;
2248  /* first, sanity checks */
2249  if (i >= num_connections)
2250  break; /* connection list changed somehow, retry later ... */
2251  if (p[poll_server+i].fd != pos->socket_fd)
2252  break; /* fd mismatch, something else happened, retry later ... */
2253  /* normal handling */
2254  if (0 != (p[poll_server+i].revents & POLLIN))
2255  pos->read_handler (pos);
2256  if (0 != (p[poll_server+i].revents & POLLOUT))
2257  pos->write_handler (pos);
2258  pos->idle_handler (pos);
2259  i++;
2260  break;
2262  if (0 != (p[poll_server+i].revents & POLLIN))
2263  pos->read_handler (pos);
2264  pos->idle_handler (pos);
2265  break;
2267  /* should never happen */
2268  break;
2269  }
2270  }
2271  /* handle 'listen' FD */
2272  if ( (-1 != poll_listen) &&
2273  (0 != (p[poll_listen].revents & POLLIN)) )
2274  (void) MHD_accept_connection (daemon);
2275  }
2276  return MHD_YES;
2277 }
2278 
2279 
2287 static int
2288 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2289  int may_block)
2290 {
2291  struct pollfd p[2];
2292  int timeout;
2293  unsigned int poll_count;
2294  int poll_listen;
2295 
2296  memset (&p, 0, sizeof (p));
2297  poll_count = 0;
2298  poll_listen = -1;
2299  if (MHD_INVALID_SOCKET != daemon->socket_fd)
2300  {
2301  p[poll_count].fd = daemon->socket_fd;
2302  p[poll_count].events = POLLIN;
2303  p[poll_count].revents = 0;
2304  poll_listen = poll_count;
2305  poll_count++;
2306  }
2307  if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2308  {
2309  p[poll_count].fd = daemon->wpipe[0];
2310  p[poll_count].events = POLLIN;
2311  p[poll_count].revents = 0;
2312  poll_count++;
2313  }
2314  if (MHD_NO == may_block)
2315  timeout = 0;
2316  else
2317  timeout = -1;
2318  if (0 == poll_count)
2319  return MHD_YES;
2320  if (poll (p, poll_count, timeout) < 0)
2321  {
2322  if (EINTR == MHD_socket_errno_)
2323  return MHD_YES;
2324 #if HAVE_MESSAGES
2325  MHD_DLOG (daemon, "poll failed: %s\n", MHD_socket_last_strerr_ ());
2326 #endif
2327  return MHD_NO;
2328  }
2329  /* handle shutdown */
2330  if (MHD_YES == daemon->shutdown)
2331  return MHD_NO;
2332  if ( (-1 != poll_listen) &&
2333  (0 != (p[poll_listen].revents & POLLIN)) )
2334  (void) MHD_accept_connection (daemon);
2335  return MHD_YES;
2336 }
2337 #endif
2338 
2339 
2347 static int
2348 MHD_poll (struct MHD_Daemon *daemon,
2349  int may_block)
2350 {
2351 #ifdef HAVE_POLL_H
2352  if (MHD_YES == daemon->shutdown)
2353  return MHD_NO;
2354  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2355  return MHD_poll_all (daemon, may_block);
2356  else
2357  return MHD_poll_listen_socket (daemon, may_block);
2358 #else
2359  return MHD_NO;
2360 #endif
2361 }
2362 
2363 
2364 #if EPOLL_SUPPORT
2365 
2374 #define MAX_EVENTS 128
2375 
2376 
2385 static int
2386 MHD_epoll (struct MHD_Daemon *daemon,
2387  int may_block)
2388 {
2389  struct MHD_Connection *pos;
2390  struct MHD_Connection *next;
2391  struct epoll_event events[MAX_EVENTS];
2392  struct epoll_event event;
2393  int timeout_ms;
2394  MHD_UNSIGNED_LONG_LONG timeout_ll;
2395  int num_events;
2396  unsigned int i;
2397  unsigned int series_length;
2398  char tmp;
2399 
2400  if (-1 == daemon->epoll_fd)
2401  return MHD_NO; /* we're down! */
2402  if (MHD_YES == daemon->shutdown)
2403  return MHD_NO;
2404  if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
2405  (0 != daemon->max_connections) &&
2406  (MHD_NO == daemon->listen_socket_in_epoll) )
2407  {
2408  event.events = EPOLLIN;
2409  event.data.ptr = daemon;
2410  if (0 != epoll_ctl (daemon->epoll_fd,
2411  EPOLL_CTL_ADD,
2412  daemon->socket_fd,
2413  &event))
2414  {
2415 #if HAVE_MESSAGES
2416  if (0 != (daemon->options & MHD_USE_DEBUG))
2417  MHD_DLOG (daemon,
2418  "Call to epoll_ctl failed: %s\n",
2420 #endif
2421  return MHD_NO;
2422  }
2423  daemon->listen_socket_in_epoll = MHD_YES;
2424  }
2425  if ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2426  (0 == daemon->max_connections) )
2427  {
2428  /* we're at the connection limit, disable listen socket
2429  for event loop for now */
2430  if (0 != epoll_ctl (daemon->epoll_fd,
2431  EPOLL_CTL_DEL,
2432  daemon->socket_fd,
2433  NULL))
2434  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2435  daemon->listen_socket_in_epoll = MHD_NO;
2436  }
2437  if (MHD_YES == may_block)
2438  {
2439  if (MHD_YES == MHD_get_timeout (daemon,
2440  &timeout_ll))
2441  {
2442  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
2443  timeout_ms = INT_MAX;
2444  else
2445  timeout_ms = (int) timeout_ll;
2446  }
2447  else
2448  timeout_ms = -1;
2449  }
2450  else
2451  timeout_ms = 0;
2452 
2453  /* drain 'epoll' event queue; need to iterate as we get at most
2454  MAX_EVENTS in one system call here; in practice this should
2455  pretty much mean only one round, but better an extra loop here
2456  than unfair behavior... */
2457  num_events = MAX_EVENTS;
2458  while (MAX_EVENTS == num_events)
2459  {
2460  /* update event masks */
2461  num_events = epoll_wait (daemon->epoll_fd,
2462  events, MAX_EVENTS, timeout_ms);
2463  if (-1 == num_events)
2464  {
2465  if (EINTR == MHD_socket_errno_)
2466  return MHD_YES;
2467 #if HAVE_MESSAGES
2468  if (0 != (daemon->options & MHD_USE_DEBUG))
2469  MHD_DLOG (daemon,
2470  "Call to epoll_wait failed: %s\n",
2472 #endif
2473  return MHD_NO;
2474  }
2475  for (i=0;i<(unsigned int) num_events;i++)
2476  {
2477  if (NULL == events[i].data.ptr)
2478  continue; /* shutdown signal! */
2479  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
2480  (daemon->wpipe[0] == events[i].data.fd) )
2481  {
2482  (void) MHD_pipe_read_ (daemon->wpipe[0], &tmp, sizeof (tmp));
2483  continue;
2484  }
2485  if (daemon != events[i].data.ptr)
2486  {
2487  /* this is an event relating to a 'normal' connection,
2488  remember the event and if appropriate mark the
2489  connection as 'eready'. */
2490  pos = events[i].data.ptr;
2491  if (0 != (events[i].events & EPOLLIN))
2492  {
2493  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
2494  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
2495  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
2496  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2497  {
2498  EDLL_insert (daemon->eready_head,
2499  daemon->eready_tail,
2500  pos);
2501  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2502  }
2503  }
2504  if (0 != (events[i].events & EPOLLOUT))
2505  {
2506  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
2507  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
2508  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2509  {
2510  EDLL_insert (daemon->eready_head,
2511  daemon->eready_tail,
2512  pos);
2513  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2514  }
2515  }
2516  }
2517  else /* must be listen socket */
2518  {
2519  /* run 'accept' until it fails or we are not allowed to take
2520  on more connections */
2521  series_length = 0;
2522  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2523  (0 != daemon->max_connections) &&
2524  (series_length < 128) )
2525  series_length++;
2526  }
2527  }
2528  }
2529 
2530  /* we handle resumes here because we may have ready connections
2531  that will not be placed into the epoll list immediately. */
2534 
2535  /* process events for connections */
2536  while (NULL != (pos = daemon->eready_tail))
2537  {
2538  EDLL_remove (daemon->eready_head,
2539  daemon->eready_tail,
2540  pos);
2541  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2543  pos->read_handler (pos);
2545  pos->write_handler (pos);
2546  pos->idle_handler (pos);
2547  }
2548  /* Finally, handle timed-out connections; we need to do this here
2549  as the epoll mechanism won't call the 'idle_handler' on everything,
2550  as the other event loops do. As timeouts do not get an explicit
2551  event, we need to find those connections that might have timed out
2552  here.
2553 
2554  Connections with custom timeouts must all be looked at, as we
2555  do not bother to sort that (presumably very short) list. */
2556  next = daemon->manual_timeout_head;
2557  while (NULL != (pos = next))
2558  {
2559  next = pos->nextX;
2560  pos->idle_handler (pos);
2561  }
2562  /* Connections with the default timeout are sorted by prepending
2563  them to the head of the list whenever we touch the connection;
2564  thus it sufficies to iterate from the tail until the first
2565  connection is NOT timed out */
2566  next = daemon->normal_timeout_tail;
2567  while (NULL != (pos = next))
2568  {
2569  next = pos->prevX;
2570  pos->idle_handler (pos);
2571  if (MHD_CONNECTION_CLOSED != pos->state)
2572  break; /* sorted by timeout, no need to visit the rest! */
2573  }
2574  return MHD_YES;
2575 }
2576 #endif
2577 
2578 
2598 int
2599 MHD_run (struct MHD_Daemon *daemon)
2600 {
2601  if ( (MHD_YES == daemon->shutdown) ||
2602  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2603  (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2604  return MHD_NO;
2605  if (0 != (daemon->options & MHD_USE_POLL))
2606  {
2607  MHD_poll (daemon, MHD_NO);
2608  MHD_cleanup_connections (daemon);
2609  }
2610 #if EPOLL_SUPPORT
2611  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2612  {
2613  MHD_epoll (daemon, MHD_NO);
2614  MHD_cleanup_connections (daemon);
2615  }
2616 #endif
2617  else
2618  {
2619  MHD_select (daemon, MHD_NO);
2620  /* MHD_select does MHD_cleanup_connections already */
2621  }
2622  return MHD_YES;
2623 }
2624 
2625 
2633 static void *
2635 {
2636  struct MHD_Daemon *daemon = cls;
2637 
2638  while (MHD_YES != daemon->shutdown)
2639  {
2640  if (0 != (daemon->options & MHD_USE_POLL))
2641  MHD_poll (daemon, MHD_YES);
2642 #if EPOLL_SUPPORT
2643  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2644  MHD_epoll (daemon, MHD_YES);
2645 #endif
2646  else
2647  MHD_select (daemon, MHD_YES);
2648  MHD_cleanup_connections (daemon);
2649  }
2650  return NULL;
2651 }
2652 
2653 
2670 struct MHD_Daemon *
2671 MHD_start_daemon (unsigned int flags,
2672  uint16_t port,
2674  void *apc_cls,
2675  MHD_AccessHandlerCallback dh, void *dh_cls, ...)
2676 {
2677  struct MHD_Daemon *daemon;
2678  va_list ap;
2679 
2680  va_start (ap, dh_cls);
2681  daemon = MHD_start_daemon_va (flags, port, apc, apc_cls, dh, dh_cls, ap);
2682  va_end (ap);
2683  return daemon;
2684 }
2685 
2686 
2706 MHD_socket
2708 {
2709  unsigned int i;
2710  MHD_socket ret;
2711 
2712  ret = daemon->socket_fd;
2713  if (MHD_INVALID_SOCKET == ret)
2714  return MHD_INVALID_SOCKET;
2715  if ( (MHD_INVALID_PIPE_ == daemon->wpipe[1]) &&
2716  (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2717  {
2718 #if HAVE_MESSAGES
2719  MHD_DLOG (daemon,
2720  "Using MHD_quiesce_daemon in this mode requires MHD_USE_PIPE_FOR_SHUTDOWN\n");
2721 #endif
2722  return MHD_INVALID_SOCKET;
2723  }
2724 
2725  if (NULL != daemon->worker_pool)
2726  for (i = 0; i < daemon->worker_pool_size; i++)
2727  {
2729 #if EPOLL_SUPPORT
2730  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2731  (-1 != daemon->worker_pool[i].epoll_fd) &&
2732  (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) )
2733  {
2734  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
2735  EPOLL_CTL_DEL,
2736  ret,
2737  NULL))
2738  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2739  daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO;
2740  }
2741 #endif
2742  }
2743  daemon->socket_fd = MHD_INVALID_SOCKET;
2744 #if EPOLL_SUPPORT
2745  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2746  (-1 != daemon->epoll_fd) &&
2747  (MHD_YES == daemon->listen_socket_in_epoll) )
2748  {
2749  if (0 != epoll_ctl (daemon->epoll_fd,
2750  EPOLL_CTL_DEL,
2751  ret,
2752  NULL))
2753  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2754  daemon->listen_socket_in_epoll = MHD_NO;
2755  }
2756 #endif
2757  return ret;
2758 }
2759 
2760 
2768 typedef void (*VfprintfFunctionPointerType)(void *cls,
2769  const char *format,
2770  va_list va);
2771 
2772 
2781 static int
2782 parse_options_va (struct MHD_Daemon *daemon,
2783  const struct sockaddr **servaddr,
2784  va_list ap);
2785 
2786 
2795 static int
2796 parse_options (struct MHD_Daemon *daemon,
2797  const struct sockaddr **servaddr,
2798  ...)
2799 {
2800  va_list ap;
2801  int ret;
2802 
2803  va_start (ap, servaddr);
2804  ret = parse_options_va (daemon, servaddr, ap);
2805  va_end (ap);
2806  return ret;
2807 }
2808 
2809 
2818 static int
2820  const struct sockaddr **servaddr,
2821  va_list ap)
2822 {
2823  enum MHD_OPTION opt;
2824  struct MHD_OptionItem *oa;
2825  unsigned int i;
2826 #if HTTPS_SUPPORT
2827  int ret;
2828  const char *pstr;
2829 #endif
2830 
2831  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
2832  {
2833  switch (opt)
2834  {
2836  daemon->pool_size = va_arg (ap, size_t);
2837  break;
2839  daemon->pool_increment= va_arg (ap, size_t);
2840  break;
2842  daemon->max_connections = va_arg (ap, unsigned int);
2843  break;
2845  daemon->connection_timeout = va_arg (ap, unsigned int);
2846  break;
2848  daemon->notify_completed =
2849  va_arg (ap, MHD_RequestCompletedCallback);
2850  daemon->notify_completed_cls = va_arg (ap, void *);
2851  break;
2853  daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
2854  break;
2855  case MHD_OPTION_SOCK_ADDR:
2856  *servaddr = va_arg (ap, const struct sockaddr *);
2857  break;
2859  daemon->uri_log_callback =
2860  va_arg (ap, LogCallback);
2861  daemon->uri_log_callback_cls = va_arg (ap, void *);
2862  break;
2864  daemon->worker_pool_size = va_arg (ap, unsigned int);
2865  if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon)))
2866  {
2867 #if HAVE_MESSAGES
2868  MHD_DLOG (daemon,
2869  "Specified thread pool size (%u) too big\n",
2870  daemon->worker_pool_size);
2871 #endif
2872  return MHD_NO;
2873  }
2874  break;
2875 #if HTTPS_SUPPORT
2877  if (0 != (daemon->options & MHD_USE_SSL))
2878  daemon->https_mem_key = va_arg (ap, const char *);
2879 #if HAVE_MESSAGES
2880  else
2881  MHD_DLOG (daemon,
2882  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
2883  opt);
2884 #endif
2885  break;
2887  if (0 != (daemon->options & MHD_USE_SSL))
2888  daemon->https_mem_cert = va_arg (ap, const char *);
2889 #if HAVE_MESSAGES
2890  else
2891  MHD_DLOG (daemon,
2892  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
2893  opt);
2894 #endif
2895  break;
2897  if (0 != (daemon->options & MHD_USE_SSL))
2898  daemon->https_mem_trust = va_arg (ap, const char *);
2899 #if HAVE_MESSAGES
2900  else
2901  MHD_DLOG (daemon,
2902  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
2903  opt);
2904 #endif
2905  break;
2907  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, int);
2908  break;
2910  if (0 != (daemon->options & MHD_USE_SSL))
2911  {
2912  gnutls_priority_deinit (daemon->priority_cache);
2913  ret = gnutls_priority_init (&daemon->priority_cache,
2914  pstr = va_arg (ap, const char*),
2915  NULL);
2916  if (ret != GNUTLS_E_SUCCESS)
2917  {
2918 #if HAVE_MESSAGES
2919  MHD_DLOG (daemon,
2920  "Setting priorities to `%s' failed: %s\n",
2921  pstr,
2922  gnutls_strerror (ret));
2923 #endif
2924  daemon->priority_cache = NULL;
2925  return MHD_NO;
2926  }
2927  }
2928  break;
2930 #if GNUTLS_VERSION_MAJOR < 3
2931 #if HAVE_MESSAGES
2932  MHD_DLOG (daemon,
2933  "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n");
2934 #endif
2935  return MHD_NO;
2936 #else
2937  if (0 != (daemon->options & MHD_USE_SSL))
2938  daemon->cert_callback = va_arg (ap, gnutls_certificate_retrieve_function2 *);
2939  break;
2940 #endif
2941 #endif
2942 #ifdef DAUTH_SUPPORT
2944  daemon->digest_auth_rand_size = va_arg (ap, size_t);
2945  daemon->digest_auth_random = va_arg (ap, const char *);
2946  break;
2948  daemon->nonce_nc_size = va_arg (ap, unsigned int);
2949  break;
2950 #endif
2952  daemon->socket_fd = va_arg (ap, MHD_socket);
2953  break;
2955 #if HAVE_MESSAGES
2956  daemon->custom_error_log =
2957  va_arg (ap, VfprintfFunctionPointerType);
2958  daemon->custom_error_log_cls = va_arg (ap, void *);
2959 #else
2960  va_arg (ap, VfprintfFunctionPointerType);
2961  va_arg (ap, void *);
2962 #endif
2963  break;
2965  daemon->thread_stack_size = va_arg (ap, size_t);
2966  break;
2967 #ifdef TCP_FASTOPEN
2969  daemon->fastopen_queue_size = va_arg (ap, unsigned int);
2970  break;
2971 #endif
2972  case MHD_OPTION_ARRAY:
2973  oa = va_arg (ap, struct MHD_OptionItem*);
2974  i = 0;
2975  while (MHD_OPTION_END != (opt = oa[i].option))
2976  {
2977  switch (opt)
2978  {
2979  /* all options taking 'size_t' */
2983  if (MHD_YES != parse_options (daemon,
2984  servaddr,
2985  opt,
2986  (size_t) oa[i].value,
2987  MHD_OPTION_END))
2988  return MHD_NO;
2989  break;
2990  /* all options taking 'unsigned int' */
2997  if (MHD_YES != parse_options (daemon,
2998  servaddr,
2999  opt,
3000  (unsigned int) oa[i].value,
3001  MHD_OPTION_END))
3002  return MHD_NO;
3003  break;
3004  /* all options taking 'enum' */
3006  if (MHD_YES != parse_options (daemon,
3007  servaddr,
3008  opt,
3009  (int) oa[i].value,
3010  MHD_OPTION_END))
3011  return MHD_NO;
3012  break;
3013  /* all options taking 'MHD_socket' */
3015  if (MHD_YES != parse_options (daemon,
3016  servaddr,
3017  opt,
3018  (MHD_socket) oa[i].value,
3019  MHD_OPTION_END))
3020  return MHD_NO;
3021  break;
3022  /* all options taking one pointer */
3023  case MHD_OPTION_SOCK_ADDR:
3028  case MHD_OPTION_ARRAY:
3030  if (MHD_YES != parse_options (daemon,
3031  servaddr,
3032  opt,
3033  oa[i].ptr_value,
3034  MHD_OPTION_END))
3035  return MHD_NO;
3036  break;
3037  /* all options taking two pointers */
3042  if (MHD_YES != parse_options (daemon,
3043  servaddr,
3044  opt,
3045  (void *) oa[i].value,
3046  oa[i].ptr_value,
3047  MHD_OPTION_END))
3048  return MHD_NO;
3049  break;
3050  /* options taking size_t-number followed by pointer */
3052  if (MHD_YES != parse_options (daemon,
3053  servaddr,
3054  opt,
3055  (size_t) oa[i].value,
3056  oa[i].ptr_value,
3057  MHD_OPTION_END))
3058  return MHD_NO;
3059  break;
3060  default:
3061  return MHD_NO;
3062  }
3063  i++;
3064  }
3065  break;
3067  daemon->unescape_callback =
3068  va_arg (ap, UnescapeCallback);
3069  daemon->unescape_callback_cls = va_arg (ap, void *);
3070  break;
3071  default:
3072 #if HAVE_MESSAGES
3073  if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
3075  {
3076  MHD_DLOG (daemon,
3077  "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
3078  opt);
3079  }
3080  else
3081  {
3082  MHD_DLOG (daemon,
3083  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
3084  opt);
3085  }
3086 #endif
3087  return MHD_NO;
3088  }
3089  }
3090  return MHD_YES;
3091 }
3092 
3093 
3102 static MHD_socket
3103 create_socket (struct MHD_Daemon *daemon,
3104  int domain, int type, int protocol)
3105 {
3106  int ctype = type | SOCK_CLOEXEC;
3107  MHD_socket fd;
3108 
3109  /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
3110  * implementations do not set ai_socktype, e.g. RHL6.2. */
3111  fd = socket (domain, ctype, protocol);
3112  if ( (MHD_INVALID_SOCKET == fd) && (EINVAL == MHD_socket_errno_) && (0 != SOCK_CLOEXEC) )
3113  {
3114  ctype = type;
3115  fd = socket(domain, type, protocol);
3116  }
3117  if (MHD_INVALID_SOCKET == fd)
3118  return MHD_INVALID_SOCKET;
3119  if (type == ctype)
3120  make_nonblocking_noninheritable (daemon, fd);
3121  return fd;
3122 }
3123 
3124 
3125 #if EPOLL_SUPPORT
3126 
3133 static int
3134 setup_epoll_to_listen (struct MHD_Daemon *daemon)
3135 {
3136  struct epoll_event event;
3137 
3138  daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
3139  if (-1 == daemon->epoll_fd)
3140  {
3141 #if HAVE_MESSAGES
3142  if (0 != (daemon->options & MHD_USE_DEBUG))
3143  MHD_DLOG (daemon,
3144  "Call to epoll_create1 failed: %s\n",
3146 #endif
3147  return MHD_NO;
3148  }
3149  if (0 == EPOLL_CLOEXEC)
3151  daemon->epoll_fd);
3152  if (MHD_INVALID_SOCKET == daemon->socket_fd)
3153  return MHD_YES; /* non-listening daemon */
3154  event.events = EPOLLIN;
3155  event.data.ptr = daemon;
3156  if (0 != epoll_ctl (daemon->epoll_fd,
3157  EPOLL_CTL_ADD,
3158  daemon->socket_fd,
3159  &event))
3160  {
3161 #if HAVE_MESSAGES
3162  if (0 != (daemon->options & MHD_USE_DEBUG))
3163  MHD_DLOG (daemon,
3164  "Call to epoll_ctl failed: %s\n",
3166 #endif
3167  return MHD_NO;
3168  }
3169  if ( (MHD_INVALID_PIPE_ != daemon->wpipe[0]) &&
3171  {
3172  event.events = EPOLLIN | EPOLLET;
3173  event.data.ptr = NULL;
3174  event.data.fd = daemon->wpipe[0];
3175  if (0 != epoll_ctl (daemon->epoll_fd,
3176  EPOLL_CTL_ADD,
3177  daemon->wpipe[0],
3178  &event))
3179  {
3180 #if HAVE_MESSAGES
3181  if (0 != (daemon->options & MHD_USE_DEBUG))
3182  MHD_DLOG (daemon,
3183  "Call to epoll_ctl failed: %s\n",
3185 #endif
3186  return MHD_NO;
3187  }
3188  }
3189  daemon->listen_socket_in_epoll = MHD_YES;
3190  return MHD_YES;
3191 }
3192 #endif
3193 
3194 
3212 struct MHD_Daemon *
3213 MHD_start_daemon_va (unsigned int flags,
3214  uint16_t port,
3216  void *apc_cls,
3217  MHD_AccessHandlerCallback dh, void *dh_cls,
3218  va_list ap)
3219 {
3220  const int on = 1;
3221  struct MHD_Daemon *daemon;
3223  struct sockaddr_in servaddr4;
3224 #if HAVE_INET6
3225  struct sockaddr_in6 servaddr6;
3226 #endif
3227  const struct sockaddr *servaddr = NULL;
3228  socklen_t addrlen;
3229  unsigned int i;
3230  int res_thread_create;
3231  int use_pipe;
3232 
3233 #ifndef HAVE_INET6
3234  if (0 != (flags & MHD_USE_IPv6))
3235  return NULL;
3236 #endif
3237 #ifndef HAVE_POLL_H
3238  if (0 != (flags & MHD_USE_POLL))
3239  return NULL;
3240 #endif
3241 #if ! HTTPS_SUPPORT
3242  if (0 != (flags & MHD_USE_SSL))
3243  return NULL;
3244 #endif
3245 #ifndef TCP_FASTOPEN
3246  if (0 != (flags & MHD_USE_TCP_FASTOPEN))
3247  return NULL;
3248 #endif
3249  if (NULL == dh)
3250  return NULL;
3251  if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
3252  return NULL;
3253  memset (daemon, 0, sizeof (struct MHD_Daemon));
3254 #if EPOLL_SUPPORT
3255  daemon->epoll_fd = -1;
3256 #endif
3257  /* try to open listen socket */
3258 #if HTTPS_SUPPORT
3259  if (0 != (flags & MHD_USE_SSL))
3260  {
3261  gnutls_priority_init (&daemon->priority_cache,
3262  "NORMAL",
3263  NULL);
3264  }
3265 #endif
3266  daemon->socket_fd = MHD_INVALID_SOCKET;
3267  daemon->options = (enum MHD_OPTION) flags;
3268 #if WINDOWS
3269  /* Winsock is broken with respect to 'shutdown';
3270  this disables us calling 'shutdown' on W32. */
3271  daemon->options |= MHD_USE_EPOLL_TURBO;
3272 #endif
3273  daemon->port = port;
3274  daemon->apc = apc;
3275  daemon->apc_cls = apc_cls;
3276  daemon->default_handler = dh;
3277  daemon->default_handler_cls = dh_cls;
3279  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
3280  daemon->pool_increment = MHD_BUF_INC_SIZE;
3282  daemon->connection_timeout = 0; /* no timeout */
3283  daemon->wpipe[0] = MHD_INVALID_PIPE_;
3284  daemon->wpipe[1] = MHD_INVALID_PIPE_;
3285 #if HAVE_MESSAGES
3286  daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
3287  daemon->custom_error_log_cls = stderr;
3288 #endif
3289 #ifdef HAVE_LISTEN_SHUTDOWN
3290  use_pipe = (0 != (daemon->options & (MHD_USE_NO_LISTEN_SOCKET | MHD_USE_PIPE_FOR_SHUTDOWN)));
3291 #else
3292  use_pipe = 1; /* yes, must use pipe to signal shutdown */
3293 #endif
3295  use_pipe = 0; /* useless if we are using 'external' select */
3296  if ( (use_pipe) && (0 != MHD_pipe_ (daemon->wpipe)) )
3297  {
3298 #if HAVE_MESSAGES
3299  MHD_DLOG (daemon,
3300  "Failed to create control pipe: %s\n",
3301  MHD_strerror_ (errno));
3302 #endif
3303  free (daemon);
3304  return NULL;
3305  }
3306 #ifndef WINDOWS
3307  if ( (0 == (flags & MHD_USE_POLL)) &&
3308  (1 == use_pipe) &&
3309  (daemon->wpipe[0] >= FD_SETSIZE) )
3310  {
3311 #if HAVE_MESSAGES
3312  MHD_DLOG (daemon,
3313  "file descriptor for control pipe exceeds maximum value\n");
3314 #endif
3315  if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
3316  MHD_PANIC ("close failed\n");
3317  if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
3318  MHD_PANIC ("close failed\n");
3319  free (daemon);
3320  return NULL;
3321  }
3322 #endif
3323 #ifdef DAUTH_SUPPORT
3324  daemon->digest_auth_rand_size = 0;
3325  daemon->digest_auth_random = NULL;
3326  daemon->nonce_nc_size = 4; /* tiny */
3327 #endif
3328 #if HTTPS_SUPPORT
3329  if (0 != (flags & MHD_USE_SSL))
3330  {
3331  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
3332  }
3333 #endif
3334 
3335 
3336  if (MHD_YES != parse_options_va (daemon, &servaddr, ap))
3337  {
3338 #if HTTPS_SUPPORT
3339  if ( (0 != (flags & MHD_USE_SSL)) &&
3340  (NULL != daemon->priority_cache) )
3341  gnutls_priority_deinit (daemon->priority_cache);
3342 #endif
3343  free (daemon);
3344  return NULL;
3345  }
3346 #ifdef DAUTH_SUPPORT
3347  if (daemon->nonce_nc_size > 0)
3348  {
3349  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
3350  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
3351  {
3352 #if HAVE_MESSAGES
3353  MHD_DLOG (daemon,
3354  "Specified value for NC_SIZE too large\n");
3355 #endif
3356 #if HTTPS_SUPPORT
3357  if (0 != (flags & MHD_USE_SSL))
3358  gnutls_priority_deinit (daemon->priority_cache);
3359 #endif
3360  free (daemon);
3361  return NULL;
3362  }
3363  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
3364  if (NULL == daemon->nnc)
3365  {
3366 #if HAVE_MESSAGES
3367  MHD_DLOG (daemon,
3368  "Failed to allocate memory for nonce-nc map: %s\n",
3369  MHD_strerror_ (errno));
3370 #endif
3371 #if HTTPS_SUPPORT
3372  if (0 != (flags & MHD_USE_SSL))
3373  gnutls_priority_deinit (daemon->priority_cache);
3374 #endif
3375  free (daemon);
3376  return NULL;
3377  }
3378  }
3379 
3380  if (0 != pthread_mutex_init (&daemon->nnc_lock, NULL))
3381  {
3382 #if HAVE_MESSAGES
3383  MHD_DLOG (daemon,
3384  "MHD failed to initialize nonce-nc mutex\n");
3385 #endif
3386 #if HTTPS_SUPPORT
3387  if (0 != (flags & MHD_USE_SSL))
3388  gnutls_priority_deinit (daemon->priority_cache);
3389 #endif
3390  free (daemon->nnc);
3391  free (daemon);
3392  return NULL;
3393  }
3394 #endif
3395 
3396  /* Thread pooling currently works only with internal select thread model */
3397  if ( (0 == (flags & MHD_USE_SELECT_INTERNALLY)) &&
3398  (daemon->worker_pool_size > 0) )
3399  {
3400 #if HAVE_MESSAGES
3401  MHD_DLOG (daemon,
3402  "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
3403 #endif
3404  goto free_and_fail;
3405  }
3406 
3407  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3408  (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) )
3409  {
3410 #if HAVE_MESSAGES
3411  MHD_DLOG (daemon,
3412  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_SUSPEND_RESUME is not supported.\n");
3413 #endif
3414  goto free_and_fail;
3415  }
3416 
3417 #ifdef __SYMBIAN32__
3418  if (0 != (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
3419  {
3420 #if HAVE_MESSAGES
3421  MHD_DLOG (daemon,
3422  "Threaded operations are not supported on Symbian.\n");
3423 #endif
3424  goto free_and_fail;
3425  }
3426 #endif
3427 #if EPOLL_SUPPORT
3428  if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) &&
3429  (0 == daemon->worker_pool_size) &&
3430  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3431  {
3432  if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))
3433  {
3434 #if HAVE_MESSAGES
3435  MHD_DLOG (daemon,
3436  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL_LINUX_ONLY is not supported.\n");
3437 #endif
3438  goto free_and_fail;
3439  }
3440  if (MHD_YES != setup_epoll_to_listen (daemon))
3441  goto free_and_fail;
3442  }
3443 #else
3444  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3445  {
3446 #if HAVE_MESSAGES
3447  MHD_DLOG (daemon,
3448  "epoll is not supported on this platform by this build.\n");
3449 #endif
3450  goto free_and_fail;
3451  }
3452 #endif
3453  if ( (MHD_INVALID_SOCKET == daemon->socket_fd) &&
3454  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3455  {
3456  /* try to open listen socket */
3457  if ((flags & MHD_USE_IPv6) != 0)
3458  socket_fd = create_socket (daemon,
3459  PF_INET6, SOCK_STREAM, 0);
3460  else
3461  socket_fd = create_socket (daemon,
3462  PF_INET, SOCK_STREAM, 0);
3463  if (MHD_INVALID_SOCKET == socket_fd)
3464  {
3465 #if HAVE_MESSAGES
3466  if (0 != (flags & MHD_USE_DEBUG))
3467  MHD_DLOG (daemon,
3468  "Call to socket failed: %s\n",
3470 #endif
3471  goto free_and_fail;
3472  }
3473  if ( (0 > setsockopt (socket_fd,
3474  SOL_SOCKET,
3475  SO_REUSEADDR,
3476  (void*)&on, sizeof (on))) &&
3477  (0 != (flags & MHD_USE_DEBUG)) )
3478  {
3479 #if HAVE_MESSAGES
3480  MHD_DLOG (daemon,
3481  "setsockopt failed: %s\n",
3483 #endif
3484  }
3485 
3486  /* check for user supplied sockaddr */
3487 #if HAVE_INET6
3488  if (0 != (flags & MHD_USE_IPv6))
3489  addrlen = sizeof (struct sockaddr_in6);
3490  else
3491 #endif
3492  addrlen = sizeof (struct sockaddr_in);
3493  if (NULL == servaddr)
3494  {
3495 #if HAVE_INET6
3496  if (0 != (flags & MHD_USE_IPv6))
3497  {
3498  memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
3499  servaddr6.sin6_family = AF_INET6;
3500  servaddr6.sin6_port = htons (port);
3501 #if HAVE_SOCKADDR_IN_SIN_LEN
3502  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
3503 #endif
3504  servaddr = (struct sockaddr *) &servaddr6;
3505  }
3506  else
3507 #endif
3508  {
3509  memset (&servaddr4, 0, sizeof (struct sockaddr_in));
3510  servaddr4.sin_family = AF_INET;
3511  servaddr4.sin_port = htons (port);
3512 #if HAVE_SOCKADDR_IN_SIN_LEN
3513  servaddr4.sin_len = sizeof (struct sockaddr_in);
3514 #endif
3515  servaddr = (struct sockaddr *) &servaddr4;
3516  }
3517  }
3518  daemon->socket_fd = socket_fd;
3519 
3520  if (0 != (flags & MHD_USE_IPv6))
3521  {
3522 #ifdef IPPROTO_IPV6
3523 #ifdef IPV6_V6ONLY
3524  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
3525  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
3526  and may also be missing on older POSIX systems; good luck if you have any of those,
3527  your IPv6 socket may then also bind against IPv4 anyway... */
3528 #ifndef WINDOWS
3529  const int
3530 #else
3531  const char
3532 #endif
3533  on = (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK));
3534  if ( (0 > setsockopt (socket_fd,
3535  IPPROTO_IPV6, IPV6_V6ONLY,
3536  &on, sizeof (on))) &&
3537  (0 != (flags & MHD_USE_DEBUG)) )
3538  {
3539 #if HAVE_MESSAGES
3540  MHD_DLOG (daemon,
3541  "setsockopt failed: %s\n",
3543 #endif
3544  }
3545 #endif
3546 #endif
3547  }
3548  if (-1 == bind (socket_fd, servaddr, addrlen))
3549  {
3550 #if HAVE_MESSAGES
3551  if (0 != (flags & MHD_USE_DEBUG))
3552  MHD_DLOG (daemon,
3553  "Failed to bind to port %u: %s\n",
3554  (unsigned int) port,
3556 #endif
3557  if (0 != MHD_socket_close_ (socket_fd))
3558  MHD_PANIC ("close failed\n");
3559  goto free_and_fail;
3560  }
3561 #ifdef TCP_FASTOPEN
3562  if (0 != (flags & MHD_USE_TCP_FASTOPEN))
3563  {
3564  if (0 == daemon->fastopen_queue_size)
3565  daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
3566  if (0 != setsockopt (socket_fd,
3567  IPPROTO_TCP, TCP_FASTOPEN,
3568  &daemon->fastopen_queue_size,
3569  sizeof (daemon->fastopen_queue_size)))
3570  {
3571 #if HAVE_MESSAGES
3572  MHD_DLOG (daemon,
3573  "setsockopt failed: %s\n",
3575 #endif
3576  }
3577  }
3578 #endif
3579 #if EPOLL_SUPPORT
3580  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3581  {
3582  int sk_flags = fcntl (socket_fd, F_GETFL);
3583  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3584  {
3585 #if HAVE_MESSAGES
3586  MHD_DLOG (daemon,
3587  "Failed to make listen socket non-blocking: %s\n",
3589 #endif
3590  if (0 != MHD_socket_close_ (socket_fd))
3591  MHD_PANIC ("close failed\n");
3592  goto free_and_fail;
3593  }
3594  }
3595 #endif
3596  if (listen (socket_fd, 32) < 0)
3597  {
3598 #if HAVE_MESSAGES
3599  if (0 != (flags & MHD_USE_DEBUG))
3600  MHD_DLOG (daemon,
3601  "Failed to listen for connections: %s\n",
3603 #endif
3604  if (0 != MHD_socket_close_ (socket_fd))
3605  MHD_PANIC ("close failed\n");
3606  goto free_and_fail;
3607  }
3608  }
3609  else
3610  {
3611  socket_fd = daemon->socket_fd;
3612  }
3613 #ifndef WINDOWS
3614  if ( (socket_fd >= FD_SETSIZE) &&
3615  (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
3616  {
3617 #if HAVE_MESSAGES
3618  if ((flags & MHD_USE_DEBUG) != 0)
3619  MHD_DLOG (daemon,
3620  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
3621  socket_fd,
3622  FD_SETSIZE);
3623 #endif
3624  if (0 != MHD_socket_close_ (socket_fd))
3625  MHD_PANIC ("close failed\n");
3626  goto free_and_fail;
3627  }
3628 #endif
3629 
3630  if (0 != pthread_mutex_init (&daemon->per_ip_connection_mutex, NULL))
3631  {
3632 #if HAVE_MESSAGES
3633  MHD_DLOG (daemon,
3634  "MHD failed to initialize IP connection limit mutex\n");
3635 #endif
3636  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3637  (0 != MHD_socket_close_ (socket_fd)) )
3638  MHD_PANIC ("close failed\n");
3639  goto free_and_fail;
3640  }
3641  if (0 != pthread_mutex_init (&daemon->cleanup_connection_mutex, NULL))
3642  {
3643 #if HAVE_MESSAGES
3644  MHD_DLOG (daemon,
3645  "MHD failed to initialize IP connection limit mutex\n");
3646 #endif
3647  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3648  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3649  (0 != MHD_socket_close_ (socket_fd)) )
3650  MHD_PANIC ("close failed\n");
3651  goto free_and_fail;
3652  }
3653 
3654 #if HTTPS_SUPPORT
3655  /* initialize HTTPS daemon certificate aspects & send / recv functions */
3656  if ((0 != (flags & MHD_USE_SSL)) && (0 != MHD_TLS_init (daemon)))
3657  {
3658 #if HAVE_MESSAGES
3659  MHD_DLOG (daemon,
3660  "Failed to initialize TLS support\n");
3661 #endif
3662  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3663  (0 != MHD_socket_close_ (socket_fd)) )
3664  MHD_PANIC ("close failed\n");
3665  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3666  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
3667  goto free_and_fail;
3668  }
3669 #endif
3670  if ( ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) ||
3671  ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) &&
3672  (0 == daemon->worker_pool_size)) ) &&
3673  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) &&
3674  (0 != (res_thread_create =
3675  create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon))))
3676  {
3677 #if HAVE_MESSAGES
3678  MHD_DLOG (daemon,
3679  "Failed to create listen thread: %s\n",
3680  MHD_strerror_ (res_thread_create));
3681 #endif
3682  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3683  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
3684  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3685  (0 != MHD_socket_close_ (socket_fd)) )
3686  MHD_PANIC ("close failed\n");
3687  goto free_and_fail;
3688  }
3689  if ( (daemon->worker_pool_size > 0) &&
3690  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3691  {
3692 #ifndef MINGW
3693  int sk_flags;
3694 #else
3695  unsigned long sk_flags;
3696 #endif
3697 
3698  /* Coarse-grained count of connections per thread (note error
3699  * due to integer division). Also keep track of how many
3700  * connections are leftover after an equal split. */
3701  unsigned int conns_per_thread = daemon->max_connections
3702  / daemon->worker_pool_size;
3703  unsigned int leftover_conns = daemon->max_connections
3704  % daemon->worker_pool_size;
3705 
3706  i = 0; /* we need this in case fcntl or malloc fails */
3707 
3708  /* Accept must be non-blocking. Multiple children may wake up
3709  * to handle a new connection, but only one will win the race.
3710  * The others must immediately return. */
3711 #ifndef MINGW
3712  sk_flags = fcntl (socket_fd, F_GETFL);
3713  if (sk_flags < 0)
3714  goto thread_failed;
3715  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3716  goto thread_failed;
3717 #else
3718  sk_flags = 1;
3719  if (SOCKET_ERROR == ioctlsocket (socket_fd, FIONBIO, &sk_flags))
3720  goto thread_failed;
3721 #endif // MINGW
3722 
3723  /* Allocate memory for pooled objects */
3724  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
3725  * daemon->worker_pool_size);
3726  if (NULL == daemon->worker_pool)
3727  goto thread_failed;
3728 
3729  /* Start the workers in the pool */
3730  for (i = 0; i < daemon->worker_pool_size; ++i)
3731  {
3732  /* Create copy of the Daemon object for each worker */
3733  struct MHD_Daemon *d = &daemon->worker_pool[i];
3734 
3735  memcpy (d, daemon, sizeof (struct MHD_Daemon));
3736  /* Adjust pooling params for worker daemons; note that memcpy()
3737  has already copied MHD_USE_SELECT_INTERNALLY thread model into
3738  the worker threads. */
3739  d->master = daemon;
3740  d->worker_pool_size = 0;
3741  d->worker_pool = NULL;
3742 
3743  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3744  (0 != MHD_pipe_ (d->wpipe)) )
3745  {
3746 #if HAVE_MESSAGES
3747  MHD_DLOG (daemon,
3748  "Failed to create worker control pipe: %s\n",
3750 #endif
3751  goto thread_failed;
3752  }
3753 #ifndef WINDOWS
3754  if ( (0 == (flags & MHD_USE_POLL)) &&
3755  (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3756  (d->wpipe[0] >= FD_SETSIZE) )
3757  {
3758 #if HAVE_MESSAGES
3759  MHD_DLOG (daemon,
3760  "file descriptor for worker control pipe exceeds maximum value\n");
3761 #endif
3762  if (0 != MHD_pipe_close_ (d->wpipe[0]))
3763  MHD_PANIC ("close failed\n");
3764  if (0 != MHD_pipe_close_ (d->wpipe[1]))
3765  MHD_PANIC ("close failed\n");
3766  goto thread_failed;
3767  }
3768 #endif
3769 
3770  /* Divide available connections evenly amongst the threads.
3771  * Thread indexes in [0, leftover_conns) each get one of the
3772  * leftover connections. */
3773  d->max_connections = conns_per_thread;
3774  if (i < leftover_conns)
3775  ++d->max_connections;
3776 #if EPOLL_SUPPORT
3777  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3778  (MHD_YES != setup_epoll_to_listen (d)) )
3779  goto thread_failed;
3780 #endif
3781  /* Must init cleanup connection mutex for each worker */
3782  if (0 != pthread_mutex_init (&d->cleanup_connection_mutex, NULL))
3783  {
3784 #if HAVE_MESSAGES
3785  MHD_DLOG (daemon,
3786  "MHD failed to initialize cleanup connection mutex for thread worker %d\n", i);
3787 #endif
3788  goto thread_failed;
3789  }
3790 
3791  /* Spawn the worker thread */
3792  if (0 != (res_thread_create =
3793  create_thread (&d->pid, daemon, &MHD_select_thread, d)))
3794  {
3795 #if HAVE_MESSAGES
3796  MHD_DLOG (daemon,
3797  "Failed to create pool thread: %s\n",
3798  MHD_strerror_ (res_thread_create));
3799 #endif
3800  /* Free memory for this worker; cleanup below handles
3801  * all previously-created workers. */
3802  pthread_mutex_destroy (&d->cleanup_connection_mutex);
3803  goto thread_failed;
3804  }
3805  }
3806  }
3807  return daemon;
3808 
3809 thread_failed:
3810  /* If no worker threads created, then shut down normally. Calling
3811  MHD_stop_daemon (as we do below) doesn't work here since it
3812  assumes a 0-sized thread pool means we had been in the default
3813  MHD_USE_SELECT_INTERNALLY mode. */
3814  if (0 == i)
3815  {
3816  if ( (MHD_INVALID_SOCKET != socket_fd) &&
3817  (0 != MHD_socket_close_ (socket_fd)) )
3818  MHD_PANIC ("close failed\n");
3819  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3820  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
3821  if (NULL != daemon->worker_pool)
3822  free (daemon->worker_pool);
3823  goto free_and_fail;
3824  }
3825 
3826  /* Shutdown worker threads we've already created. Pretend
3827  as though we had fully initialized our daemon, but
3828  with a smaller number of threads than had been
3829  requested. */
3830  daemon->worker_pool_size = i - 1;
3831  MHD_stop_daemon (daemon);
3832  return NULL;
3833 
3834  free_and_fail:
3835  /* clean up basic memory state in 'daemon' and return NULL to
3836  indicate failure */
3837 #if EPOLL_SUPPORT
3838  if (-1 != daemon->epoll_fd)
3839  close (daemon->epoll_fd);
3840 #endif
3841 #ifdef DAUTH_SUPPORT
3842  free (daemon->nnc);
3843  pthread_mutex_destroy (&daemon->nnc_lock);
3844 #endif
3845 #if HTTPS_SUPPORT
3846  if (0 != (flags & MHD_USE_SSL))
3847  gnutls_priority_deinit (daemon->priority_cache);
3848 #endif
3849  free (daemon);
3850  return NULL;
3851 }
3852 
3853 
3860 static void
3862 {
3863  struct MHD_Daemon *daemon = pos->daemon;
3864 
3865  MHD_connection_close (pos,
3867  if (pos->connection_timeout == pos->daemon->connection_timeout)
3869  daemon->normal_timeout_tail,
3870  pos);
3871  else
3873  daemon->manual_timeout_tail,
3874  pos);
3875  DLL_remove (daemon->connections_head,
3876  daemon->connections_tail,
3877  pos);
3879  DLL_insert (daemon->cleanup_head,
3880  daemon->cleanup_tail,
3881  pos);
3882 }
3883 
3884 
3892 static void
3894 {
3895  struct MHD_Connection *pos;
3896  void *unused;
3897  int rc;
3898 
3899  /* first, make sure all threads are aware of shutdown; need to
3900  traverse DLLs in peace... */
3901  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3902  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
3903  MHD_PANIC ("Failed to acquire cleanup mutex\n");
3904  for (pos = daemon->connections_head; NULL != pos; pos = pos->nextX)
3905  shutdown (pos->socket_fd,
3906  (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
3907  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3908  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
3909  MHD_PANIC ("Failed to release cleanup mutex\n");
3910 
3911  /* now, collect threads from thread pool */
3912  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3913  {
3914  while (NULL != (pos = daemon->connections_head))
3915  {
3916  if (0 != (rc = pthread_join (pos->pid, &unused)))
3917  MHD_PANIC ("Failed to join a thread\n");
3918  pos->thread_joined = MHD_YES;
3919  }
3920  }
3921 
3922  /* now that we're alone, move everyone to cleanup */
3923  while (NULL != (pos = daemon->connections_head))
3924  close_connection (pos);
3925  MHD_cleanup_connections (daemon);
3926 }
3927 
3928 
3929 #if EPOLL_SUPPORT
3930 
3935 static void
3936 epoll_shutdown (struct MHD_Daemon *daemon)
3937 {
3938  struct epoll_event event;
3939 
3940  if (MHD_INVALID_PIPE_ == daemon->wpipe[1])
3941  {
3942  /* wpipe was required in this mode, how could this happen? */
3943  MHD_PANIC ("Internal error\n");
3944  }
3945  event.events = EPOLLOUT;
3946  event.data.ptr = NULL;
3947  if (0 != epoll_ctl (daemon->epoll_fd,
3948  EPOLL_CTL_ADD,
3949  daemon->wpipe[1],
3950  &event))
3951  MHD_PANIC ("Failed to add wpipe to epoll set to signal termination\n");
3952 }
3953 #endif
3954 
3955 
3962 void
3963 MHD_stop_daemon (struct MHD_Daemon *daemon)
3964 {
3965  void *unused;
3966  MHD_socket fd;
3967  unsigned int i;
3968  int rc;
3969 
3970  if (NULL == daemon)
3971  return;
3972  daemon->shutdown = MHD_YES;
3973  fd = daemon->socket_fd;
3974  daemon->socket_fd = MHD_INVALID_SOCKET;
3975  /* Prepare workers for shutdown */
3976  if (NULL != daemon->worker_pool)
3977  {
3978  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
3979  for (i = 0; i < daemon->worker_pool_size; ++i)
3980  {
3981  daemon->worker_pool[i].shutdown = MHD_YES;
3983 #if EPOLL_SUPPORT
3984  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3985  (-1 != daemon->worker_pool[i].epoll_fd) &&
3986  (MHD_INVALID_SOCKET == fd) )
3987  epoll_shutdown (&daemon->worker_pool[i]);
3988 #endif
3989  }
3990  }
3991  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
3992  {
3993  if (1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1))
3994  MHD_PANIC ("failed to signal shutdown via pipe");
3995  }
3996 #ifdef HAVE_LISTEN_SHUTDOWN
3997  else
3998  {
3999  /* fd might be MHD_INVALID_SOCKET here due to 'MHD_quiesce_daemon' */
4000  if (MHD_INVALID_SOCKET != fd)
4001  (void) shutdown (fd, SHUT_RDWR);
4002  }
4003 #endif
4004 #if EPOLL_SUPPORT
4005  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4006  (-1 != daemon->epoll_fd) &&
4007  (MHD_INVALID_SOCKET == fd) )
4008  epoll_shutdown (daemon);
4009 #endif
4010 
4011 #if DEBUG_CLOSE
4012 #if HAVE_MESSAGES
4013  MHD_DLOG (daemon, "MHD listen socket shutdown\n");
4014 #endif
4015 #endif
4016 
4017 
4018  /* Signal workers to stop and clean them up */
4019  if (NULL != daemon->worker_pool)
4020  {
4021  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
4022  for (i = 0; i < daemon->worker_pool_size; ++i)
4023  {
4024  if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4025  {
4026  if (1 != MHD_pipe_write_ (daemon->worker_pool[i].wpipe[1], "e", 1))
4027  MHD_PANIC ("failed to signal shutdown via pipe");
4028  }
4029  if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
4030  MHD_PANIC ("Failed to join a thread\n");
4031  close_all_connections (&daemon->worker_pool[i]);
4032  pthread_mutex_destroy (&daemon->worker_pool[i].cleanup_connection_mutex);
4033 #if EPOLL_SUPPORT
4034  if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
4035  (0 != MHD_socket_close_ (daemon->worker_pool[i].epoll_fd)) )
4036  MHD_PANIC ("close failed\n");
4037 #endif
4038  if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) )
4039  {
4040  if (MHD_INVALID_PIPE_ != daemon->worker_pool[i].wpipe[1])
4041  {
4042  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[0]))
4043  MHD_PANIC ("close failed\n");
4044  if (0 != MHD_pipe_close_ (daemon->worker_pool[i].wpipe[1]))
4045  MHD_PANIC ("close failed\n");
4046  }
4047  }
4048  }
4049  free (daemon->worker_pool);
4050  }
4051  else
4052  {
4053  /* clean up master threads */
4054  if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
4055  ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
4056  && (0 == daemon->worker_pool_size)))
4057  {
4058  if (0 != (rc = pthread_join (daemon->pid, &unused)))
4059  {
4060  MHD_PANIC ("Failed to join a thread\n");
4061  }
4062  }
4063  }
4064  close_all_connections (daemon);
4065  if ( (MHD_INVALID_SOCKET != fd) &&
4066  (0 != MHD_socket_close_ (fd)) )
4067  MHD_PANIC ("close failed\n");
4068 
4069  /* TLS clean up */
4070 #if HTTPS_SUPPORT
4071  if (0 != (daemon->options & MHD_USE_SSL))
4072  {
4073  gnutls_priority_deinit (daemon->priority_cache);
4074  if (daemon->x509_cred)
4075  gnutls_certificate_free_credentials (daemon->x509_cred);
4076  }
4077 #endif
4078 #if EPOLL_SUPPORT
4079  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4080  (-1 != daemon->epoll_fd) &&
4081  (0 != MHD_socket_close_ (daemon->epoll_fd)) )
4082  MHD_PANIC ("close failed\n");
4083 #endif
4084 
4085 #ifdef DAUTH_SUPPORT
4086  free (daemon->nnc);
4087  pthread_mutex_destroy (&daemon->nnc_lock);
4088 #endif
4089  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
4090  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
4091 
4092  if (MHD_INVALID_PIPE_ != daemon->wpipe[1])
4093  {
4094  if (0 != MHD_pipe_close_ (daemon->wpipe[0]))
4095  MHD_PANIC ("close failed\n");
4096  if (0 != MHD_pipe_close_ (daemon->wpipe[1]))
4097  MHD_PANIC ("close failed\n");
4098  }
4099  free (daemon);
4100 }
4101 
4102 
4114 const union MHD_DaemonInfo *
4116  enum MHD_DaemonInfoType info_type,
4117  ...)
4118 {
4119  switch (info_type)
4120  {
4122  return NULL; /* no longer supported */
4124  return NULL; /* no longer supported */
4126  return (const union MHD_DaemonInfo *) &daemon->socket_fd;
4127 #if EPOLL_SUPPORT
4129  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
4130 #endif
4131  default:
4132  return NULL;
4133  };
4134 }
4135 
4136 
4153 void
4155 {
4156  mhd_panic = cb;
4157  mhd_panic_cls = cls;
4158 }
4159 
4160 
4167 const char *
4169 {
4170  return PACKAGE_VERSION;
4171 }
4172 
4173 
4174 #ifdef __GNUC__
4175 #define FUNC_CONSTRUCTOR(f) static void __attribute__ ((constructor)) f
4176 #define FUNC_DESTRUCTOR(f) static void __attribute__ ((destructor)) f
4177 #else // !__GNUC__
4178 #define FUNC_CONSTRUCTOR(f) _MHD_EXTERN void f
4179 #define FUNC_DESTRUCTOR(f) _MHD_EXTERN void f
4180 #endif // __GNUC__
4181 
4182 #if HTTPS_SUPPORT
4183 #if GCRYPT_VERSION_NUMBER < 0x010600
4184 GCRY_THREAD_OPTION_PTHREAD_IMPL;
4185 #endif
4186 #endif
4187 
4188 
4193 {
4195  mhd_panic_cls = NULL;
4196 
4197 #ifdef _WIN32
4198  WSADATA wsd;
4199  if (0 != WSAStartup(MAKEWORD(2, 2), &wsd))
4200  MHD_PANIC ("Failed to initialize winsock\n");
4201  mhd_winsock_inited_ = 1;
4202  if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion))
4203  MHD_PANIC ("Winsock version 2.2 is not available\n");
4204 #endif
4205 #if HTTPS_SUPPORT
4206 #if GCRYPT_VERSION_NUMBER < 0x010600
4207  gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
4208 #endif
4209  gcry_check_version (NULL);
4210  gnutls_global_init ();
4211 #endif
4212 }
4213 
4214 
4216 {
4217 #if HTTPS_SUPPORT
4218  gnutls_global_deinit ();
4219 #endif
4220 #ifdef _WIN32
4221  if (mhd_winsock_inited_)
4222  WSACleanup();
4223 #endif
4224 }
4225 
4226 /* end of daemon.c */
4227 
unsigned int per_ip_connection_limit
Definition: internal.h:1139
void * unescape_callback_cls
Definition: internal.h:1022
#define XDLL_insert(head, tail, element)
Definition: internal.h:1300
uint64_t total_size
Definition: internal.h:295
_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:3213
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:2796
pthread_mutex_t per_ip_connection_mutex
Definition: internal.h:1080
_MHD_EXTERN const char * MHD_get_version(void)
Definition: daemon.c:4168
pthread_mutex_t cleanup_connection_mutex
Definition: internal.h:1085
void * mhd_panic_cls
Definition: daemon.c:143
#define MHD_socket_errno_
off_t fd_off
Definition: internal.h:306
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:298
int(* write_handler)(struct MHD_Connection *connection)
Definition: internal.h:806
socklen_t addr_len
Definition: internal.h:697
int thread_joined
Definition: internal.h:736
pthread_t pid
Definition: internal.h:643
enum MHD_CONNECTION_STATE state
Definition: internal.h:753
int(* idle_handler)(struct MHD_Connection *connection)
Definition: internal.h:811
uint64_t response_write_position
Definition: internal.h:686
#define NULL
Definition: reason_phrase.c:31
#define EDLL_remove(head, tail, element)
Definition: internal.h:1359
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:135
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:758
#define MHD_BUF_INC_SIZE
Definition: internal.h:65
#define DLL_remove(head, tail, element)
Definition: internal.h:1278
Methods for managing connections.
_MHD_EXTERN int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:1868
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:257
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:1773
#define SOCK_CLOEXEC
Definition: daemon.c:104
MHD_socket socket_fd
Definition: internal.h:1090
#define MHD_YES
Definition: microhttpd.h:134
_MHD_EXTERN int MHD_add_connection(struct MHD_Daemon *daemon, MHD_socket client_socket, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:1674
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
Definition: daemon.c:894
#define MSG_NOSIGNAL
Definition: daemon.c:99
struct MHD_Response * response
Definition: internal.h:564
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:1197
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:963
#define FUNC_CONSTRUCTOR(f)
Definition: daemon.c:4178
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:865
#define MHD_strerror_(errnum)
#define MHD_socket_close_(fd)
MHD_AccessHandlerCallback default_handler
Definition: internal.h:896
int MHD_socket
Definition: microhttpd.h:174
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:2768
#define FUNC_DESTRUCTOR(f)
Definition: daemon.c:4179
_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:2671
intptr_t value
Definition: microhttpd.h:857
platform-specific includes for libmicrohttpd
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:68
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
Definition: daemon.c:861
Methods for managing response objects.
_MHD_EXTERN void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
Definition: daemon.c:4154
#define MHD_socket_last_strerr_()
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:195
void * uri_log_callback_cls
Definition: internal.h:1012
int(* read_handler)(struct MHD_Connection *connection)
Definition: internal.h:801
struct MHD_Daemon * daemon
Definition: internal.h:549
struct MHD_Connection * manual_timeout_head
Definition: internal.h:970
struct MHD_Connection * cleanup_head
Definition: internal.h:926
struct MHD_Connection * cleanup_tail
Definition: internal.h:931
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:3861
#define EWOULDBLOCK
Definition: w32functions.h:45
size_t write_buffer_send_offset
Definition: internal.h:667
#define ECONNRESET
Definition: w32functions.h:96
struct MHD_Daemon * worker_pool
Definition: internal.h:1045
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:122
size_t read_buffer_size
Definition: internal.h:651
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:362
_MHD_EXTERN void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:3963
struct MHD_Connection * nextX
Definition: internal.h:539
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:223
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:976
static int create_thread(pthread_t *thread, const struct MHD_Daemon *daemon, ThreadStartRoutine start_routine, void *arg)
Definition: daemon.c:980
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:1427
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:1488
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:175
MHD_socket socket_fd
Definition: internal.h:723
internal shared structures
void MHD_set_https_callbacks(struct MHD_Connection *connection)
static int MHD_select(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:2043
unsigned int worker_pool_size
Definition: internal.h:1070
time_t MHD_monotonic_time(void)
Definition: internal.c:169
static void resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:1520
_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:1958
LogCallback uri_log_callback
Definition: internal.h:1007
_MHD_EXTERN void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:444
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:1129
int shutdown
Definition: internal.h:1117
Methods for managing connections.
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:878
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:208
uint16_t port
Definition: internal.h:1149
struct MHD_Connection * normal_timeout_head
Definition: internal.h:957
void * tdelete(const void *__restrict vkey, void **__restrict vrootp, int(*compar)(const void *, const void *))
Definition: tsearch.c:85
FUNC_DESTRUCTOR() MHD_fini()
Definition: daemon.c:4215
#define ENOTCONN
Definition: w32functions.h:105
ReceiveCallback recv_cls
Definition: internal.h:816
size_t thread_stack_size
Definition: internal.h:1065
static void make_nonblocking_noninheritable(struct MHD_Daemon *daemon, MHD_socket sock)
Definition: daemon.c:1595
#define MHD_pipe_read_(fd, ptr, sz)
#define MHD_pipe_write_(fd, ptr, sz)
UnescapeCallback unescape_callback
Definition: internal.h:1017
pthread_t pid
Definition: internal.h:1075
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:242
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:160
static MHD_socket create_socket(struct MHD_Daemon *daemon, int domain, int type, int protocol)
Definition: daemon.c:3103
struct MHD_Connection * connections_head
Definition: internal.h:906
struct MHD_Daemon * master
Definition: internal.h:1040
size_t pool_size
Definition: internal.h:1055
struct MHD_Connection * next
Definition: internal.h:529
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:2348
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:2819
MHD_AcceptPolicyCallback apc
Definition: internal.h:982
time_t last_activity
Definition: internal.h:703
#define MHD_pipe_(fdarr)
unsigned int connection_timeout
Definition: internal.h:709
#define MHD_pipe_close_(fd)
#define MHD_PANIC(msg)
Definition: internal.h:91
size_t MHD_http_unescape(void *cls, struct MHD_Connection *connection, char *val)
Definition: internal.c:119
struct MemoryPool * pool
Definition: internal.h:576
_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:606
static void * MHD_handle_connection(void *data)
Definition: daemon.c:685
void * ptr_value
Definition: microhttpd.h:863
MHD_pipe wpipe[2]
Definition: internal.h:1112
size_t write_buffer_append_offset
Definition: internal.h:673
int resuming
Definition: internal.h:1122
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:993
struct MHD_Connection * prevX
Definition: internal.h:544
#define MHD_set_socket_errno_(errnum)
enum MHD_OPTION options
Definition: internal.h:1144
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:2705
#define MHD_INVALID_PIPE_
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:76
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3893
void * notify_completed_cls
Definition: internal.h:998
struct MemoryPool * MHD_pool_create(size_t max)
Definition: memorypool.c:87
TransmitCallback send_cls
Definition: internal.h:821
_MHD_EXTERN int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:2599
#define XDLL_remove(head, tail, element)
Definition: internal.h:1319
#define DLL_insert(head, tail, element)
Definition: internal.h:1259
MHD_OPTION
MHD options.
Definition: microhttpd.h:582
#define EPOLL_CLOEXEC
Definition: daemon.c:108
FUNC_CONSTRUCTOR() MHD_init()
Definition: daemon.c:4192
void * tfind(void *vkey, void *const *vrootp, int *compar) const
Definition: tsearch.c:55
void * apc_cls
Definition: internal.h:987
struct sockaddr * addr
Definition: internal.h:637
void *(* ThreadStartRoutine)(void *cls)
Definition: daemon.c:967
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:1051
static void add_to_fd_set(MHD_socket fd, fd_set *set, MHD_socket *max_fd)
Definition: daemon.c:577
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:921
MHD_DaemonInfoType
Definition: microhttpd.h:1079
#define MHD_SYS_select_(n, r, w, e, t)
MHD_PanicCallback mhd_panic
Definition: daemon.c:138
#define MHD_pipe_last_strerror_()
void * per_ip_connection_count
Definition: internal.h:1050
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:1174
size_t read_buffer_offset
Definition: internal.h:657
void * default_handler_cls
Definition: internal.h:901
#define MHD_NO
Definition: microhttpd.h:139
unsigned int connection_timeout
Definition: internal.h:1133
static int MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:1701
_MHD_EXTERN MHD_socket MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:2707
_MHD_EXTERN const union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:4115
struct MHD_Connection * connections_tail
Definition: internal.h:911
enum MHD_OPTION option
Definition: microhttpd.h:850
#define EDLL_insert(head, tail, element)
Definition: internal.h:1340
void MHD_connection_close(struct MHD_Connection *connection, enum MHD_RequestTerminationCode termination_code)
Definition: connection.c:261
static void * MHD_select_thread(void *cls)
Definition: daemon.c:2634
size_t pool_increment
Definition: internal.h:1060
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
Definition: microhttpd.h:574
void * tsearch(void *vkey, void **vrootp, int *compar) const
Definition: tsearch.c:21
unsigned int max_connections
Definition: internal.h:1127
struct MHD_Connection * suspended_connections_head
Definition: internal.h:916
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
Definition: microhttpd.h:1116
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...