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-2013 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 #ifndef HAVE_ACCEPT4
54 #define HAVE_ACCEPT4 0
55 #endif
56 
60 #ifndef WINDOWS
61 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4
62 #else
63 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
64 #endif
65 
69 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
70 
75 #define DEBUG_CLOSE MHD_NO
76 
81 #define DEBUG_CONNECT MHD_NO
82 
83 #ifndef LINUX
84 #ifndef MSG_NOSIGNAL
85 #define MSG_NOSIGNAL 0
86 #endif
87 #endif
88 
89 #ifndef SOCK_CLOEXEC
90 #define SOCK_CLOEXEC 0
91 #endif
92 
93 #ifndef EPOLL_CLOEXEC
94 #define EPOLL_CLOEXEC 0
95 #endif
96 
97 
107 static void
108 mhd_panic_std (void *cls,
109  const char *file,
110  unsigned int line,
111  const char *reason)
112 {
113 #if HAVE_MESSAGES
114  fprintf (stderr, "Fatal error in GNU libmicrohttpd %s:%u: %s\n",
115  file, line, reason);
116 #endif
117  abort ();
118 }
119 
120 
125 
130 
131 
139 static struct MHD_Daemon*
140 MHD_get_master (struct MHD_Daemon *daemon)
141 {
142  while (NULL != daemon->master)
143  daemon = daemon->master;
144  return daemon;
145 }
146 
147 
151 struct MHD_IPCount
152 {
156  int family;
157 
161  union
162  {
166  struct in_addr ipv4;
167 #if HAVE_IPV6
168 
171  struct in6_addr ipv6;
172 #endif
173  } addr;
174 
178  unsigned int count;
179 };
180 
181 
187 static void
189 {
190  if (0 != pthread_mutex_lock(&daemon->per_ip_connection_mutex))
191  {
192  MHD_PANIC ("Failed to acquire IP connection limit mutex\n");
193  }
194 }
195 
196 
202 static void
204 {
205  if (0 != pthread_mutex_unlock(&daemon->per_ip_connection_mutex))
206  {
207  MHD_PANIC ("Failed to release IP connection limit mutex\n");
208  }
209 }
210 
211 
221 static int
222 MHD_ip_addr_compare (const void *a1, const void *a2)
223 {
224  return memcmp (a1, a2, offsetof (struct MHD_IPCount, count));
225 }
226 
227 
236 static int
237 MHD_ip_addr_to_key (const struct sockaddr *addr,
238  socklen_t addrlen,
239  struct MHD_IPCount *key)
240 {
241  memset(key, 0, sizeof(*key));
242 
243  /* IPv4 addresses */
244  if (sizeof (struct sockaddr_in) == addrlen)
245  {
246  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
247  key->family = AF_INET;
248  memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr));
249  return MHD_YES;
250  }
251 
252 #if HAVE_IPV6
253  /* IPv6 addresses */
254  if (sizeof (struct sockaddr_in6) == addrlen)
255  {
256  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
257  key->family = AF_INET6;
258  memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr));
259  return MHD_YES;
260  }
261 #endif
262 
263  /* Some other address */
264  return MHD_NO;
265 }
266 
267 
277 static int
278 MHD_ip_limit_add (struct MHD_Daemon *daemon,
279  const struct sockaddr *addr,
280  socklen_t addrlen)
281 {
282  struct MHD_IPCount *key;
283  void **nodep;
284  void *node;
285  int result;
286 
287  daemon = MHD_get_master (daemon);
288  /* Ignore if no connection limit assigned */
289  if (0 == daemon->per_ip_connection_limit)
290  return MHD_YES;
291 
292  if (NULL == (key = malloc (sizeof(*key))))
293  return MHD_NO;
294 
295  /* Initialize key */
296  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key))
297  {
298  /* Allow unhandled address types through */
299  free (key);
300  return MHD_YES;
301  }
302  MHD_ip_count_lock (daemon);
303 
304  /* Search for the IP address */
305  if (NULL == (nodep = TSEARCH (key,
306  &daemon->per_ip_connection_count,
308  {
309 #if HAVE_MESSAGES
310  MHD_DLOG (daemon,
311  "Failed to add IP connection count node\n");
312 #endif
313  MHD_ip_count_unlock (daemon);
314  free (key);
315  return MHD_NO;
316  }
317  node = *nodep;
318  /* If we got an existing node back, free the one we created */
319  if (node != key)
320  free(key);
321  key = (struct MHD_IPCount *) node;
322  /* Test if there is room for another connection; if so,
323  * increment count */
324  result = (key->count < daemon->per_ip_connection_limit);
325  if (MHD_YES == result)
326  ++key->count;
327 
328  MHD_ip_count_unlock (daemon);
329  return result;
330 }
331 
332 
341 static void
342 MHD_ip_limit_del (struct MHD_Daemon *daemon,
343  const struct sockaddr *addr,
344  socklen_t addrlen)
345 {
346  struct MHD_IPCount search_key;
347  struct MHD_IPCount *found_key;
348  void **nodep;
349 
350  daemon = MHD_get_master (daemon);
351  /* Ignore if no connection limit assigned */
352  if (0 == daemon->per_ip_connection_limit)
353  return;
354  /* Initialize search key */
355  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key))
356  return;
357 
358  MHD_ip_count_lock (daemon);
359 
360  /* Search for the IP address */
361  if (NULL == (nodep = TFIND (&search_key,
362  &daemon->per_ip_connection_count,
364  {
365  /* Something's wrong if we couldn't find an IP address
366  * that was previously added */
367  MHD_PANIC ("Failed to find previously-added IP address\n");
368  }
369  found_key = (struct MHD_IPCount *) *nodep;
370  /* Validate existing count for IP address */
371  if (0 == found_key->count)
372  {
373  MHD_PANIC ("Previously-added IP address had 0 count\n");
374  }
375  /* Remove the node entirely if count reduces to 0 */
376  if (0 == --found_key->count)
377  {
378  TDELETE (found_key,
379  &daemon->per_ip_connection_count,
381  free (found_key);
382  }
383 
384  MHD_ip_count_unlock (daemon);
385 }
386 
387 
388 #if HTTPS_SUPPORT
389 
397 static ssize_t
398 recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
399 {
400  int res;
401 
402  if (MHD_YES == connection->tls_read_ready)
403  {
404  connection->daemon->num_tls_read_ready--;
405  connection->tls_read_ready = MHD_NO;
406  }
407  res = gnutls_record_recv (connection->tls_session, other, i);
408  if ( (GNUTLS_E_AGAIN == res) ||
409  (GNUTLS_E_INTERRUPTED == res) )
410  {
411  errno = EINTR;
412 #if EPOLL_SUPPORT
413  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
414 #endif
415  return -1;
416  }
417  if (res < 0)
418  {
419  /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
420  disrupted); set errno to something caller will interpret
421  correctly as a hard error */
422  errno = EPIPE;
423  return res;
424  }
425  if (res == i)
426  {
427  connection->tls_read_ready = MHD_YES;
428  connection->daemon->num_tls_read_ready++;
429  }
430  return res;
431 }
432 
433 
442 static ssize_t
443 send_tls_adapter (struct MHD_Connection *connection,
444  const void *other, size_t i)
445 {
446  int res;
447 
448  res = gnutls_record_send (connection->tls_session, other, i);
449  if ( (GNUTLS_E_AGAIN == res) ||
450  (GNUTLS_E_INTERRUPTED == res) )
451  {
452  errno = EINTR;
453 #if EPOLL_SUPPORT
454  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
455 #endif
456  return -1;
457  }
458  return res;
459 }
460 
461 
468 static int
469 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
470 {
471  gnutls_datum_t key;
472  gnutls_datum_t cert;
473 
474 #if GNUTLS_VERSION_MAJOR >= 3
475  if (NULL != daemon->cert_callback)
476  {
477  gnutls_certificate_set_retrieve_function2 (daemon->x509_cred,
478  daemon->cert_callback);
479  }
480 #endif
481  if (NULL != daemon->https_mem_trust)
482  {
483  cert.data = (unsigned char *) daemon->https_mem_trust;
484  cert.size = strlen (daemon->https_mem_trust);
485  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, &cert,
486  GNUTLS_X509_FMT_PEM) < 0)
487  {
488 #if HAVE_MESSAGES
489  MHD_DLOG(daemon,
490  "Bad trust certificate format\n");
491 #endif
492  return -1;
493  }
494  }
495 
496  /* certificate & key loaded from memory */
497  if ( (NULL != daemon->https_mem_cert) &&
498  (NULL != daemon->https_mem_key) )
499  {
500  key.data = (unsigned char *) daemon->https_mem_key;
501  key.size = strlen (daemon->https_mem_key);
502  cert.data = (unsigned char *) daemon->https_mem_cert;
503  cert.size = strlen (daemon->https_mem_cert);
504 
505  return gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
506  &cert, &key,
507  GNUTLS_X509_FMT_PEM);
508  }
509 #if GNUTLS_VERSION_MAJOR >= 3
510  if (NULL != daemon->cert_callback)
511  return 0;
512 #endif
513 #if HAVE_MESSAGES
514  MHD_DLOG (daemon, "You need to specify a certificate and key location\n");
515 #endif
516  return -1;
517 }
518 
519 
526 static int
527 MHD_TLS_init (struct MHD_Daemon *daemon)
528 {
529  switch (daemon->cred_type)
530  {
531  case GNUTLS_CRD_CERTIFICATE:
532  if (0 !=
533  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
534  return GNUTLS_E_MEMORY_ERROR;
535  return MHD_init_daemon_certificate (daemon);
536  default:
537 #if HAVE_MESSAGES
538  MHD_DLOG (daemon,
539  "Error: invalid credentials type %d specified.\n",
540  daemon->cred_type);
541 #endif
542  return -1;
543  }
544 }
545 #endif
546 
547 
556 static void
558  fd_set *set,
559  int *max_fd)
560 {
561  FD_SET (fd, set);
562  if ( (NULL != max_fd) &&
563  (fd > *max_fd) )
564  *max_fd = fd;
565 }
566 
567 
582 int
583 MHD_get_fdset (struct MHD_Daemon *daemon,
584  fd_set *read_fd_set,
585  fd_set *write_fd_set,
586  fd_set *except_fd_set,
587  int *max_fd)
588 {
589  struct MHD_Connection *pos;
590  int fd;
591 
592  if ( (NULL == daemon)
593  || (NULL == read_fd_set)
594  || (NULL == write_fd_set)
595  || (NULL == except_fd_set)
596  || (NULL == max_fd)
597  || (MHD_YES == daemon->shutdown)
598  || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
599  || (0 != (daemon->options & MHD_USE_POLL)))
600  return MHD_NO;
601 #if EPOLL_SUPPORT
602  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
603  {
604  /* we're in epoll mode, use the epoll FD as a stand-in for
605  the entire event set */
606 
607  if (daemon->epoll_fd >= FD_SETSIZE)
608  return MHD_NO; /* poll fd too big, fail hard */
609  FD_SET (daemon->epoll_fd, read_fd_set);
610  if ((*max_fd) < daemon->epoll_fd)
611  *max_fd = daemon->epoll_fd;
612  return MHD_YES;
613  }
614 #endif
615  fd = daemon->socket_fd;
616  if (-1 != fd)
617  {
618  FD_SET (fd, read_fd_set);
619  /* update max file descriptor */
620  if ((*max_fd) < fd)
621  *max_fd = fd;
622  }
623  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
624  {
625  switch (pos->event_loop_info)
626  {
628  add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
629  break;
631  add_to_fd_set (pos->socket_fd, write_fd_set, max_fd);
632  if (pos->read_buffer_size > pos->read_buffer_offset)
633  add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
634  break;
636  if (pos->read_buffer_size > pos->read_buffer_offset)
637  add_to_fd_set (pos->socket_fd, read_fd_set, max_fd);
638  break;
640  /* this should never happen */
641  break;
642  }
643  }
644 #if DEBUG_CONNECT
645 #if HAVE_MESSAGES
646  MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd);
647 #endif
648 #endif
649  return MHD_YES;
650 }
651 
652 
660 static void *
662 {
663  struct MHD_Connection *con = data;
664  int num_ready;
665  fd_set rs;
666  fd_set ws;
667  int max;
668  struct timeval tv;
669  struct timeval *tvp;
670  unsigned int timeout;
671  time_t now;
672 #ifdef HAVE_POLL_H
673  struct pollfd p[1];
674 #endif
675 
676  timeout = con->daemon->connection_timeout;
677  while ( (MHD_YES != con->daemon->shutdown) &&
678  (MHD_CONNECTION_CLOSED != con->state) )
679  {
680  tvp = NULL;
681  if (timeout > 0)
682  {
683  now = MHD_monotonic_time();
684  if (now - con->last_activity > timeout)
685  tv.tv_sec = 0;
686  else
687  tv.tv_sec = timeout - (now - con->last_activity);
688  tv.tv_usec = 0;
689  tvp = &tv;
690  }
691 #if HTTPS_SUPPORT
692  if (MHD_YES == con->tls_read_ready)
693  {
694  /* do not block (more data may be inside of TLS buffers waiting for us) */
695  tv.tv_sec = 0;
696  tv.tv_usec = 0;
697  tvp = &tv;
698  }
699 #endif
700  if (0 == (con->daemon->options & MHD_USE_POLL))
701  {
702  /* use select */
703  FD_ZERO (&rs);
704  FD_ZERO (&ws);
705  max = 0;
706  switch (con->event_loop_info)
707  {
709  add_to_fd_set (con->socket_fd, &rs, &max);
710  break;
712  add_to_fd_set (con->socket_fd, &ws, &max);
713  if (con->read_buffer_size > con->read_buffer_offset)
714  add_to_fd_set (con->socket_fd, &rs, &max);
715  break;
717  if (con->read_buffer_size > con->read_buffer_offset)
718  add_to_fd_set (con->socket_fd, &rs, &max);
719  tv.tv_sec = 0;
720  tv.tv_usec = 0;
721  tvp = &tv;
722  break;
724  /* how did we get here!? */
725  goto exit;
726  }
727  num_ready = SELECT (max + 1, &rs, &ws, NULL, tvp);
728  if (num_ready < 0)
729  {
730  if (EINTR == errno)
731  continue;
732 #if HAVE_MESSAGES
733  MHD_DLOG (con->daemon,
734  "Error during select (%d): `%s'\n",
735  max,
736  STRERROR (errno));
737 #endif
738  break;
739  }
740  /* call appropriate connection handler if necessary */
741  if ( (FD_ISSET (con->socket_fd, &rs))
742 #if HTTPS_SUPPORT
743  || (MHD_YES == con->tls_read_ready)
744 #endif
745  )
746  con->read_handler (con);
747  if (FD_ISSET (con->socket_fd, &ws))
748  con->write_handler (con);
749  if (MHD_NO == con->idle_handler (con))
750  goto exit;
751  }
752 #ifdef HAVE_POLL_H
753  else
754  {
755  /* use poll */
756  memset (&p, 0, sizeof (p));
757  p[0].fd = con->socket_fd;
758  switch (con->event_loop_info)
759  {
761  p[0].events |= POLLIN;
762  break;
764  p[0].events |= POLLOUT;
765  if (con->read_buffer_size > con->read_buffer_offset)
766  p[0].events |= POLLIN;
767  break;
769  if (con->read_buffer_size > con->read_buffer_offset)
770  p[0].events |= POLLIN;
771  tv.tv_sec = 0;
772  tv.tv_usec = 0;
773  tvp = &tv;
774  break;
776  /* how did we get here!? */
777  goto exit;
778  }
779  if (poll (p, 1,
780  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
781  {
782  if (EINTR == errno)
783  continue;
784 #if HAVE_MESSAGES
785  MHD_DLOG (con->daemon, "Error during poll: `%s'\n",
786  STRERROR (errno));
787 #endif
788  break;
789  }
790  if ( (0 != (p[0].revents & POLLIN))
791 #if HTTPS_SUPPORT
792  || (MHD_YES == con->tls_read_ready)
793 #endif
794  )
795  con->read_handler (con);
796  if (0 != (p[0].revents & POLLOUT))
797  con->write_handler (con);
798  if (0 != (p[0].revents & (POLLERR | POLLHUP)))
800  if (MHD_NO == con->idle_handler (con))
801  goto exit;
802  }
803 #endif
804  }
805  if (MHD_CONNECTION_IN_CLEANUP != con->state)
806  {
807 #if DEBUG_CLOSE
808 #if HAVE_MESSAGES
809  MHD_DLOG (con->daemon,
810  "Processing thread terminating, closing connection\n");
811 #endif
812 #endif
813  if (MHD_CONNECTION_CLOSED != con->state)
816  con->idle_handler (con);
817  }
818 exit:
819  if (NULL != con->response)
820  {
822  con->response = NULL;
823  }
824  return NULL;
825 }
826 
827 
836 static ssize_t
837 recv_param_adapter (struct MHD_Connection *connection,
838  void *other,
839  size_t i)
840 {
841  ssize_t ret;
842 
843  if ( (-1 == connection->socket_fd) ||
844  (MHD_CONNECTION_CLOSED == connection->state) )
845  {
846  errno = ENOTCONN;
847  return -1;
848  }
849  ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
850 #if EPOLL_SUPPORT
851  if (ret < (ssize_t) i)
852  {
853  /* partial read --- no longer read-ready */
854  connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
855  }
856 #endif
857  return ret;
858 }
859 
860 
869 static ssize_t
870 send_param_adapter (struct MHD_Connection *connection,
871  const void *other,
872  size_t i)
873 {
874  ssize_t ret;
875 #if LINUX
876  int fd;
877  off_t offset;
878  off_t left;
879 #endif
880 
881  if ( (-1 == connection->socket_fd) ||
882  (MHD_CONNECTION_CLOSED == connection->state) )
883  {
884  errno = ENOTCONN;
885  return -1;
886  }
887  if (0 != (connection->daemon->options & MHD_USE_SSL))
888  return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
889 #if LINUX
890  if ( (connection->write_buffer_append_offset ==
891  connection->write_buffer_send_offset) &&
892  (NULL != connection->response) &&
893  (-1 != (fd = connection->response->fd)) )
894  {
895  /* can use sendfile */
896  offset = (off_t) connection->response_write_position + connection->response->fd_off;
897  left = connection->response->total_size - connection->response_write_position;
898  if (left > SSIZE_MAX)
899  left = SSIZE_MAX; /* cap at return value limit */
900  if (-1 != (ret = sendfile (connection->socket_fd,
901  fd,
902  &offset,
903  (size_t) left)))
904  {
905 #if EPOLL_SUPPORT
906  if (ret < left)
907  {
908  /* partial write --- no longer write-ready */
909  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
910  }
911 #endif
912  return ret;
913  }
914  if ( (EINTR == errno) || (EAGAIN == errno) )
915  return 0;
916  if ( (EINVAL == errno) || (EBADF == errno) )
917  return -1;
918  /* None of the 'usual' sendfile errors occurred, so we should try
919  to fall back to 'SEND'; see also this thread for info on
920  odd libc/Linux behavior with sendfile:
921  http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
922  }
923 #endif
924  ret = SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
925 #if EPOLL_SUPPORT
926  if (ret < (ssize_t) i)
927  {
928  /* partial write --- no longer write-ready */
929  connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
930  }
931 #endif
932  return ret;
933 }
934 
935 
942 typedef void *(*ThreadStartRoutine)(void *cls);
943 
944 
954 static int
955 create_thread (pthread_t *thread,
956  const struct MHD_Daemon *daemon,
957  ThreadStartRoutine start_routine,
958  void *arg)
959 {
960  pthread_attr_t attr;
961  pthread_attr_t *pattr;
962  int ret;
963 
964  if (0 != daemon->thread_stack_size)
965  {
966  if (0 != (ret = pthread_attr_init (&attr)))
967  goto ERR;
968  if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size)))
969  {
970  pthread_attr_destroy (&attr);
971  goto ERR;
972  }
973  pattr = &attr;
974  }
975  else
976  {
977  pattr = NULL;
978  }
979  ret = pthread_create (thread, pattr,
980  start_routine, arg);
981 #if (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12)
982 #if LINUX
983  (void) pthread_setname_np (*thread, "libmicrohttpd");
984 #endif
985 #endif
986  if (0 != daemon->thread_stack_size)
987  pthread_attr_destroy (&attr);
988  return ret;
989  ERR:
990 #if HAVE_MESSAGES
991  MHD_DLOG (daemon,
992  "Failed to set thread stack size\n");
993 #endif
994  errno = EINVAL;
995  return ret;
996 }
997 
998 
1025 static int
1027  int client_socket,
1028  const struct sockaddr *addr,
1029  socklen_t addrlen,
1030  int external_add)
1031 {
1032  struct MHD_Connection *connection;
1033  int res_thread_create;
1034  unsigned int i;
1035  int eno;
1036 #if OSX
1037  static int on = 1;
1038 #endif
1039  if (NULL != daemon->worker_pool)
1040  {
1041  /* have a pool, try to find a pool with capacity; we use the
1042  socket as the initial offset into the pool for load
1043  balancing */
1044  for (i=0;i<daemon->worker_pool_size;i++)
1045  if (0 < daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size].max_connections)
1046  return internal_add_connection (&daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size],
1047  client_socket,
1048  addr, addrlen,
1049  external_add);
1050  /* all pools are at their connection limit, must refuse */
1051  if (0 != CLOSE (client_socket))
1052  MHD_PANIC ("close failed\n");
1053 #if ENFILE
1054  errno = ENFILE;
1055 #endif
1056  return MHD_NO;
1057  }
1058 
1059 #ifndef WINDOWS
1060  if ( (client_socket >= FD_SETSIZE) &&
1061  (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY))) )
1062  {
1063 #if HAVE_MESSAGES
1064  MHD_DLOG (daemon,
1065  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
1066  client_socket,
1067  FD_SETSIZE);
1068 #endif
1069  if (0 != CLOSE (client_socket))
1070  MHD_PANIC ("close failed\n");
1071 #if EINVAL
1072  errno = EINVAL;
1073 #endif
1074  return MHD_NO;
1075  }
1076 #endif
1077 
1078 
1079 #if HAVE_MESSAGES
1080 #if DEBUG_CONNECT
1081  MHD_DLOG (daemon, "Accepted connection on socket %d\n", client_socket);
1082 #endif
1083 #endif
1084  if ( (0 == daemon->max_connections) ||
1085  (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) )
1086  {
1087  /* above connection limit - reject */
1088 #if HAVE_MESSAGES
1089  MHD_DLOG (daemon,
1090  "Server reached connection limit (closing inbound connection)\n");
1091 #endif
1092  if (0 != CLOSE (client_socket))
1093  MHD_PANIC ("close failed\n");
1094 #if ENFILE
1095  errno = ENFILE;
1096 #endif
1097  return MHD_NO;
1098  }
1099 
1100  /* apply connection acceptance policy if present */
1101  if ( (NULL != daemon->apc) &&
1102  (MHD_NO == daemon->apc (daemon->apc_cls,
1103  addr, addrlen)) )
1104  {
1105 #if DEBUG_CLOSE
1106 #if HAVE_MESSAGES
1107  MHD_DLOG (daemon, "Connection rejected, closing connection\n");
1108 #endif
1109 #endif
1110  if (0 != CLOSE (client_socket))
1111  MHD_PANIC ("close failed\n");
1112  MHD_ip_limit_del (daemon, addr, addrlen);
1113 #if EACCESS
1114  errno = EACCESS;
1115 #endif
1116  return MHD_NO;
1117  }
1118 
1119 #if OSX
1120 #ifdef SOL_SOCKET
1121 #ifdef SO_NOSIGPIPE
1122  setsockopt (client_socket,
1123  SOL_SOCKET, SO_NOSIGPIPE,
1124  &on, sizeof (on));
1125 #endif
1126 #endif
1127 #endif
1128 
1129  if (NULL == (connection = malloc (sizeof (struct MHD_Connection))))
1130  {
1131  eno = errno;
1132 #if HAVE_MESSAGES
1133  MHD_DLOG (daemon,
1134  "Error allocating memory: %s\n",
1135  STRERROR (errno));
1136 #endif
1137  if (0 != CLOSE (client_socket))
1138  MHD_PANIC ("close failed\n");
1139  MHD_ip_limit_del (daemon, addr, addrlen);
1140  errno = eno;
1141  return MHD_NO;
1142  }
1143  memset (connection, 0, sizeof (struct MHD_Connection));
1144  connection->pool = MHD_pool_create (daemon->pool_size);
1145  if (NULL == connection->pool)
1146  {
1147 #if HAVE_MESSAGES
1148  MHD_DLOG (daemon,
1149  "Error allocating memory: %s\n",
1150  STRERROR (errno));
1151 #endif
1152  if (0 != CLOSE (client_socket))
1153  MHD_PANIC ("close failed\n");
1154  MHD_ip_limit_del (daemon, addr, addrlen);
1155  free (connection);
1156 #if ENOMEM
1157  errno = ENOMEM;
1158 #endif
1159  return MHD_NO;
1160  }
1161 
1162  connection->connection_timeout = daemon->connection_timeout;
1163  if (NULL == (connection->addr = malloc (addrlen)))
1164  {
1165  eno = errno;
1166 #if HAVE_MESSAGES
1167  MHD_DLOG (daemon,
1168  "Error allocating memory: %s\n",
1169  STRERROR (errno));
1170 #endif
1171  if (0 != CLOSE (client_socket))
1172  MHD_PANIC ("close failed\n");
1173  MHD_ip_limit_del (daemon, addr, addrlen);
1174  MHD_pool_destroy (connection->pool);
1175  free (connection);
1176  errno = eno;
1177  return MHD_NO;
1178  }
1179  memcpy (connection->addr, addr, addrlen);
1180  connection->addr_len = addrlen;
1181  connection->socket_fd = client_socket;
1182  connection->daemon = daemon;
1183  connection->last_activity = MHD_monotonic_time();
1184 
1185  /* set default connection handlers */
1186  MHD_set_http_callbacks_ (connection);
1187  connection->recv_cls = &recv_param_adapter;
1188  connection->send_cls = &send_param_adapter;
1189 
1190  if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
1191  {
1192  /* non-blocking sockets are required on most systems and for GNUtls;
1193  however, they somehow cause serious problems on CYGWIN (#1824);
1194  in turbo mode, we assume that non-blocking was already set
1195  by 'accept4' or whoever calls 'MHD_add_connection' */
1196 #ifdef CYGWIN
1197  if (0 != (daemon->options & MHD_USE_SSL))
1198 #endif
1199  {
1200  /* make socket non-blocking */
1201 #ifndef MINGW
1202  int flags = fcntl (connection->socket_fd, F_GETFL);
1203  if ( (-1 == flags) ||
1204  (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
1205  {
1206 #if HAVE_MESSAGES
1207  MHD_DLOG (daemon,
1208  "Failed to make socket %d non-blocking: %s\n",
1209  connection->socket_fd,
1210  STRERROR (errno));
1211 #endif
1212  }
1213 #else
1214  unsigned long flags = 1;
1215  if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
1216  {
1217 #if HAVE_MESSAGES
1218  MHD_DLOG (daemon,
1219  "Failed to make socket non-blocking: %s\n",
1220  STRERROR (errno));
1221 #endif
1222  }
1223 #endif
1224  }
1225  }
1226 
1227 #if HTTPS_SUPPORT
1228  if (0 != (daemon->options & MHD_USE_SSL))
1229  {
1230  connection->recv_cls = &recv_tls_adapter;
1231  connection->send_cls = &send_tls_adapter;
1232  connection->state = MHD_TLS_CONNECTION_INIT;
1233  MHD_set_https_callbacks (connection);
1234  gnutls_init (&connection->tls_session, GNUTLS_SERVER);
1235  gnutls_priority_set (connection->tls_session,
1236  daemon->priority_cache);
1237  switch (daemon->cred_type)
1238  {
1239  /* set needed credentials for certificate authentication. */
1240  case GNUTLS_CRD_CERTIFICATE:
1241  gnutls_credentials_set (connection->tls_session,
1242  GNUTLS_CRD_CERTIFICATE,
1243  daemon->x509_cred);
1244  break;
1245  default:
1246 #if HAVE_MESSAGES
1247  MHD_DLOG (connection->daemon,
1248  "Failed to setup TLS credentials: unknown credential type %d\n",
1249  daemon->cred_type);
1250 #endif
1251  if (0 != CLOSE (client_socket))
1252  MHD_PANIC ("close failed\n");
1253  MHD_ip_limit_del (daemon, addr, addrlen);
1254  free (connection->addr);
1255  free (connection);
1256  MHD_PANIC ("Unknown credential type");
1257 #if EINVAL
1258  errno = EINVAL;
1259 #endif
1260  return MHD_NO;
1261  }
1262  gnutls_transport_set_ptr (connection->tls_session,
1263  (gnutls_transport_ptr_t) connection);
1264  gnutls_transport_set_pull_function (connection->tls_session,
1265  (gnutls_pull_func) &recv_param_adapter);
1266  gnutls_transport_set_push_function (connection->tls_session,
1267  (gnutls_push_func) &send_param_adapter);
1268 
1269  if (daemon->https_mem_trust)
1270  gnutls_certificate_server_set_request (connection->tls_session,
1271  GNUTLS_CERT_REQUEST);
1272  }
1273 #endif
1274 
1275  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1276  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1277  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1279  daemon->normal_timeout_tail,
1280  connection);
1281  DLL_insert (daemon->connections_head,
1282  daemon->connections_tail,
1283  connection);
1284  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1285  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1286  MHD_PANIC ("Failed to release cleanup mutex\n");
1287 
1288  /* attempt to create handler thread */
1289  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1290  {
1291  res_thread_create = create_thread (&connection->pid, daemon,
1292  &MHD_handle_connection, connection);
1293  if (0 != res_thread_create)
1294  {
1295  eno = errno;
1296 #if HAVE_MESSAGES
1297  MHD_DLOG (daemon, "Failed to create a thread: %s\n",
1298  STRERROR (res_thread_create));
1299 #endif
1300  goto cleanup;
1301  }
1302  }
1303  else
1304  if ( (MHD_YES == external_add) &&
1305  (-1 != daemon->wpipe[1]) &&
1306  (1 != WRITE (daemon->wpipe[1], "n", 1)) )
1307  {
1308 #if HAVE_MESSAGES
1309  MHD_DLOG (daemon,
1310  "failed to signal new connection via pipe");
1311 #endif
1312  }
1313 #if EPOLL_SUPPORT
1314  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1315  {
1316  if (0 == (daemon->options & MHD_USE_EPOLL_TURBO))
1317  {
1318  struct epoll_event event;
1319 
1320  event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1321  event.data.ptr = connection;
1322  if (0 != epoll_ctl (daemon->epoll_fd,
1323  EPOLL_CTL_ADD,
1324  client_socket,
1325  &event))
1326  {
1327  eno = errno;
1328 #if HAVE_MESSAGES
1329  MHD_DLOG (daemon,
1330  "Call to epoll_ctl failed: %s\n",
1331  STRERROR (errno));
1332 #endif
1333  goto cleanup;
1334  }
1335  connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1336  }
1337  else
1338  {
1339  connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
1341  EDLL_insert (daemon->eready_head,
1342  daemon->eready_tail,
1343  connection);
1344  }
1345  }
1346 #endif
1347  daemon->max_connections--;
1348  return MHD_YES;
1349  cleanup:
1350  if (0 != CLOSE (client_socket))
1351  MHD_PANIC ("close failed\n");
1352  MHD_ip_limit_del (daemon, addr, addrlen);
1353  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1354  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1355  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1356  DLL_remove (daemon->connections_head,
1357  daemon->connections_tail,
1358  connection);
1360  daemon->normal_timeout_tail,
1361  connection);
1362  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1363  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1364  MHD_PANIC ("Failed to release cleanup mutex\n");
1365  MHD_pool_destroy (connection->pool);
1366  free (connection->addr);
1367  free (connection);
1368 #if EINVAL
1369  errno = eno;
1370 #endif
1371  return MHD_NO;
1372 }
1373 
1374 
1402 void
1404 {
1405  struct MHD_Daemon *daemon;
1406 
1407  daemon = connection->daemon;
1409  MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1410  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1411  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1412  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1413  DLL_remove (daemon->connections_head,
1414  daemon->connections_tail,
1415  connection);
1418  connection);
1419  if (connection->connection_timeout == daemon->connection_timeout)
1421  daemon->normal_timeout_tail,
1422  connection);
1423  else
1425  daemon->manual_timeout_tail,
1426  connection);
1427 #if EPOLL_SUPPORT
1428  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1429  {
1430  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1431  {
1432  EDLL_remove (daemon->eready_head,
1433  daemon->eready_tail,
1434  connection);
1435  }
1436  if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
1437  {
1438  if (0 != epoll_ctl (daemon->epoll_fd,
1439  EPOLL_CTL_DEL,
1440  connection->socket_fd,
1441  NULL))
1442  MHD_PANIC ("Failed to remove FD from epoll set\n");
1443  connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1444  }
1445  connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
1446  }
1447 #endif
1448  connection->suspended = MHD_YES;
1449  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1450  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1451  MHD_PANIC ("Failed to release cleanup mutex\n");
1452 }
1453 
1454 
1463 void
1465 {
1466  struct MHD_Daemon *daemon;
1467 
1468  daemon = connection->daemon;
1470  MHD_PANIC ("Cannot resume connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1471  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1472  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1473  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1474  connection->resuming = MHD_YES;
1475  daemon->resuming = MHD_YES;
1476  if ( (-1 != daemon->wpipe[1]) &&
1477  (1 != WRITE (daemon->wpipe[1], "r", 1)) )
1478  {
1479 #if HAVE_MESSAGES
1480  MHD_DLOG (daemon,
1481  "failed to signal resume via pipe");
1482 #endif
1483  }
1484  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1485  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1486  MHD_PANIC ("Failed to release cleanup mutex\n");
1487 }
1488 
1495 static void
1497 {
1498  struct MHD_Connection *pos;
1499  struct MHD_Connection *next = NULL;
1500 
1501  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1502  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1503  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1504 
1505  if (MHD_YES == daemon->resuming)
1506  next = daemon->suspended_connections_head;
1507 
1508  while (NULL != (pos = next))
1509  {
1510  next = pos->next;
1511  if (MHD_NO == pos->resuming)
1512  continue;
1513 
1516  pos);
1517  DLL_insert (daemon->connections_head,
1518  daemon->connections_tail,
1519  pos);
1520  if (pos->connection_timeout == daemon->connection_timeout)
1522  daemon->normal_timeout_tail,
1523  pos);
1524  else
1526  daemon->manual_timeout_tail,
1527  pos);
1528 #if EPOLL_SUPPORT
1529  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1530  {
1531  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1532  {
1533  EDLL_insert (daemon->eready_head,
1534  daemon->eready_tail,
1535  pos);
1536  }
1537  else
1538  {
1539  struct epoll_event event;
1540 
1541  event.events = EPOLLIN | EPOLLOUT | EPOLLET;
1542  event.data.ptr = pos;
1543  if (0 != epoll_ctl (daemon->epoll_fd,
1544  EPOLL_CTL_ADD,
1545  pos->socket_fd,
1546  &event))
1547  MHD_PANIC ("Failed to add FD to epoll set\n");
1548  else
1549  pos->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
1550  }
1551  pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
1552  }
1553 #endif
1554  pos->suspended = MHD_NO;
1555  pos->resuming = MHD_NO;
1556  }
1557  daemon->resuming = MHD_NO;
1558  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1559  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1560  MHD_PANIC ("Failed to release cleanup mutex\n");
1561 }
1562 
1563 
1570 static void
1572  int sock)
1573 {
1574  int nonblock;
1575 
1576 #ifdef HAVE_SOCK_NONBLOCK
1577  nonblock = SOCK_NONBLOCK;
1578 #else
1579  nonblock = 0;
1580 #endif
1581 #ifdef CYGWIN
1582  if (0 == (daemon->options & MHD_USE_SSL))
1583  nonblock = 0;
1584 #endif
1585 
1586 #ifdef WINDOWS
1587  DWORD dwFlags;
1588  unsigned long flags = 1;
1589 
1590  if (0 != ioctlsocket (sock, FIONBIO, &flags))
1591  {
1592 #if HAVE_MESSAGES
1593  MHD_DLOG (daemon,
1594  "Failed to make socket non-blocking: %s\n",
1595  STRERROR (errno));
1596 #endif
1597  }
1598  if (!GetHandleInformation ((HANDLE) sock, &dwFlags) ||
1599  ((dwFlags != dwFlags & ~HANDLE_FLAG_INHERIT) &&
1600  !SetHandleInformation ((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)))
1601  {
1602 #if HAVE_MESSAGES
1603  SetErrnoFromWinError (GetLastError ());
1604  MHD_DLOG (daemon,
1605  "Failed to make socket non-inheritable: %s\n",
1606  STRERROR (errno));
1607 #endif
1608  }
1609 #else
1610  int flags;
1611 
1612  nonblock = O_NONBLOCK;
1613 #ifdef CYGWIN
1614  if (0 == (daemon->options & MHD_USE_SSL))
1615  nonblock = 0;
1616 #endif
1617  flags = fcntl (sock, F_GETFD);
1618  if ( ( (-1 == flags) ||
1619  ( (flags != (flags | FD_CLOEXEC)) &&
1620  (0 != fcntl (sock, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) )
1621  {
1622 #if HAVE_MESSAGES
1623  MHD_DLOG (daemon,
1624  "Failed to make socket non-inheritable: %s\n",
1625  STRERROR (errno));
1626 #endif
1627  }
1628 #endif
1629 }
1630 
1631 
1661 int
1663  int client_socket,
1664  const struct sockaddr *addr,
1665  socklen_t addrlen)
1666 {
1668  client_socket);
1669  return internal_add_connection (daemon,
1670  client_socket,
1671  addr, addrlen,
1672  MHD_YES);
1673 }
1674 
1675 
1688 static int
1690 {
1691 #if HAVE_INET6
1692  struct sockaddr_in6 addrstorage;
1693 #else
1694  struct sockaddr_in addrstorage;
1695 #endif
1696  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
1697  socklen_t addrlen;
1698  int s;
1699  int fd;
1700  int nonblock;
1701 
1702  addrlen = sizeof (addrstorage);
1703  memset (addr, 0, sizeof (addrstorage));
1704  if (-1 == (fd = daemon->socket_fd))
1705  return MHD_NO;
1706 #ifdef HAVE_SOCK_NONBLOCK
1707  nonblock = SOCK_NONBLOCK;
1708 #else
1709  nonblock = 0;
1710 #endif
1711 #ifdef CYGWIN
1712  if (0 == (daemon->options & MHD_USE_SSL))
1713  nonblock = 0;
1714 #endif
1715 #if HAVE_ACCEPT4
1716  s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock);
1717 #else
1718  s = ACCEPT (fd, addr, &addrlen);
1719 #endif
1720  if ((-1 == s) || (addrlen <= 0))
1721  {
1722 #if HAVE_MESSAGES
1723  /* This could be a common occurance with multiple worker threads */
1724  if ((EAGAIN != errno) && (EWOULDBLOCK != errno))
1725  MHD_DLOG (daemon,
1726  "Error accepting connection: %s\n",
1727  STRERROR (errno));
1728 #endif
1729  if (-1 != s)
1730  {
1731  if (0 != CLOSE (s))
1732  MHD_PANIC ("close failed\n");
1733  /* just in case */
1734  }
1735  return MHD_NO;
1736  }
1737  if ( (! HAVE_ACCEPT4) || (0 == SOCK_CLOEXEC) )
1738  make_nonblocking_noninheritable (daemon, s);
1739 #if HAVE_MESSAGES
1740 #if DEBUG_CONNECT
1741  MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
1742 #endif
1743 #endif
1744  (void) internal_add_connection (daemon, s,
1745  addr, addrlen,
1746  MHD_NO);
1747  return MHD_YES;
1748 }
1749 
1750 
1758 static void
1760 {
1761  struct MHD_Connection *pos;
1762  void *unused;
1763  int rc;
1764 
1765  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1766  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
1767  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1768  while (NULL != (pos = daemon->cleanup_head))
1769  {
1770  DLL_remove (daemon->cleanup_head,
1771  daemon->cleanup_tail,
1772  pos);
1773  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1774  (MHD_NO == pos->thread_joined) )
1775  {
1776  if (0 != (rc = pthread_join (pos->pid, &unused)))
1777  {
1778  MHD_PANIC ("Failed to join a thread\n");
1779  }
1780  }
1781  MHD_pool_destroy (pos->pool);
1782 #if HTTPS_SUPPORT
1783  if (pos->tls_session != NULL)
1784  gnutls_deinit (pos->tls_session);
1785 #endif
1786  MHD_ip_limit_del (daemon,
1787  (struct sockaddr *) pos->addr,
1788  pos->addr_len);
1789 #if EPOLL_SUPPORT
1790  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
1791  {
1792  EDLL_remove (daemon->eready_head,
1793  daemon->eready_tail,
1794  pos);
1795  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
1796  }
1797  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
1798  (-1 != daemon->epoll_fd) &&
1799  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
1800  {
1801  /* epoll documentation suggests that closing a FD
1802  automatically removes it from the epoll set; however,
1803  this is not true as if we fail to do manually remove it,
1804  we are still seeing an event for this fd in epoll,
1805  causing grief (use-after-free...) --- at least on my
1806  system. */
1807  if (0 != epoll_ctl (daemon->epoll_fd,
1808  EPOLL_CTL_DEL,
1809  pos->socket_fd,
1810  NULL))
1811  MHD_PANIC ("Failed to remove FD from epoll set\n");
1812  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
1813  }
1814 #endif
1815  if (NULL != pos->response)
1816  {
1818  pos->response = NULL;
1819  }
1820  if (-1 != pos->socket_fd)
1821  {
1822 #ifdef WINDOWS
1823  SHUTDOWN (pos->socket_fd, SHUT_WR);
1824 #endif
1825  if (0 != CLOSE (pos->socket_fd))
1826  MHD_PANIC ("close failed\n");
1827  }
1828  if (NULL != pos->addr)
1829  free (pos->addr);
1830  free (pos);
1831  daemon->max_connections++;
1832  }
1833  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1834  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
1835  MHD_PANIC ("Failed to release cleanup mutex\n");
1836 }
1837 
1838 
1853 int
1854 MHD_get_timeout (struct MHD_Daemon *daemon,
1855  MHD_UNSIGNED_LONG_LONG *timeout)
1856 {
1857  time_t earliest_deadline;
1858  time_t now;
1859  struct MHD_Connection *pos;
1860  int have_timeout;
1861 
1862  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1863  {
1864 #if HAVE_MESSAGES
1865  MHD_DLOG (daemon, "Illegal call to MHD_get_timeout\n");
1866 #endif
1867  return MHD_NO;
1868  }
1869 
1870 #if HTTPS_SUPPORT
1871  if (0 != daemon->num_tls_read_ready)
1872  {
1873  /* if there is any TLS connection with data ready for
1874  reading, we must not block in the event loop */
1875  *timeout = 0;
1876  return MHD_YES;
1877  }
1878 #endif
1879 
1880  have_timeout = MHD_NO;
1881  for (pos = daemon->manual_timeout_head; NULL != pos; pos = pos->nextX)
1882  {
1883  if (0 != pos->connection_timeout)
1884  {
1885  if ( (! have_timeout) ||
1886  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
1887  earliest_deadline = pos->last_activity + pos->connection_timeout;
1888 #if HTTPS_SUPPORT
1889  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
1890  (0 != gnutls_record_check_pending (pos->tls_session)) )
1891  earliest_deadline = 0;
1892 #endif
1893  have_timeout = MHD_YES;
1894  }
1895  }
1896  /* normal timeouts are sorted, so we only need to look at the 'head' */
1897  pos = daemon->normal_timeout_head;
1898  if ( (NULL != pos) &&
1899  (0 != pos->connection_timeout) )
1900  {
1901  if ( (! have_timeout) ||
1902  (earliest_deadline > pos->last_activity + pos->connection_timeout) )
1903  earliest_deadline = pos->last_activity + pos->connection_timeout;
1904 #if HTTPS_SUPPORT
1905  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
1906  (0 != gnutls_record_check_pending (pos->tls_session)) )
1907  earliest_deadline = 0;
1908 #endif
1909  have_timeout = MHD_YES;
1910  }
1911 
1912  if (MHD_NO == have_timeout)
1913  return MHD_NO;
1914  now = MHD_monotonic_time();
1915  if (earliest_deadline < now)
1916  *timeout = 0;
1917  else
1918  *timeout = 1000 * (1 + earliest_deadline - now);
1919  return MHD_YES;
1920 }
1921 
1922 
1942 int
1944  const fd_set *read_fd_set,
1945  const fd_set *write_fd_set,
1946  const fd_set *except_fd_set)
1947 {
1948  int ds;
1949  char tmp;
1950  struct MHD_Connection *pos;
1951  struct MHD_Connection *next;
1952 
1953 #if EPOLL_SUPPORT
1954  if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1955  {
1956  /* we're in epoll mode, the epoll FD stands for
1957  the entire event set! */
1958  if (daemon->epoll_fd >= FD_SETSIZE)
1959  return MHD_NO; /* poll fd too big, fail hard */
1960  if (FD_ISSET (daemon->epoll_fd, read_fd_set))
1961  return MHD_run (daemon);
1962  return MHD_YES;
1963  }
1964 #endif
1965 
1966  /* select connection thread handling type */
1967  if ( (-1 != (ds = daemon->socket_fd)) &&
1968  (FD_ISSET (ds, read_fd_set)) )
1969  (void) MHD_accept_connection (daemon);
1970  /* drain signaling pipe to avoid spinning select */
1971  if ( (-1 != daemon->wpipe[0]) &&
1972  (FD_ISSET (daemon->wpipe[0], read_fd_set)) )
1973  (void) read (daemon->wpipe[0], &tmp, sizeof (tmp));
1974 
1975  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1976  {
1977  /* do not have a thread per connection, process all connections now */
1978  next = daemon->connections_head;
1979  while (NULL != (pos = next))
1980  {
1981  next = pos->next;
1982  ds = pos->socket_fd;
1983  if (-1 == ds)
1984  continue;
1985  switch (pos->event_loop_info)
1986  {
1988  if ( (FD_ISSET (ds, read_fd_set))
1989 #if HTTPS_SUPPORT
1990  || (MHD_YES == pos->tls_read_ready)
1991 #endif
1992  )
1993  pos->read_handler (pos);
1994  break;
1996  if ( (FD_ISSET (ds, read_fd_set)) &&
1997  (pos->read_buffer_size > pos->read_buffer_offset) )
1998  pos->read_handler (pos);
1999  if (FD_ISSET (ds, write_fd_set))
2000  pos->write_handler (pos);
2001  break;
2003  if ( (FD_ISSET (ds, read_fd_set)) &&
2004  (pos->read_buffer_size > pos->read_buffer_offset) )
2005  pos->read_handler (pos);
2006  break;
2008  /* should never happen */
2009  break;
2010  }
2011  pos->idle_handler (pos);
2012  }
2013  }
2014  MHD_cleanup_connections (daemon);
2015  return MHD_YES;
2016 }
2017 
2018 
2027 static int
2028 MHD_select (struct MHD_Daemon *daemon,
2029  int may_block)
2030 {
2031  int num_ready;
2032  fd_set rs;
2033  fd_set ws;
2034  fd_set es;
2035  int max;
2036  struct timeval timeout;
2037  struct timeval *tv;
2038  MHD_UNSIGNED_LONG_LONG ltimeout;
2039 
2040  timeout.tv_sec = 0;
2041  timeout.tv_usec = 0;
2042  if (MHD_YES == daemon->shutdown)
2043  return MHD_NO;
2044  FD_ZERO (&rs);
2045  FD_ZERO (&ws);
2046  FD_ZERO (&es);
2047  max = -1;
2048  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2049  {
2052 
2053  /* single-threaded, go over everything */
2054  if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
2055  return MHD_NO;
2056 
2057  /* If we're at the connection limit, no need to
2058  accept new connections. */
2059  if ( (0 == daemon->max_connections) &&
2060  (-1 != daemon->socket_fd) )
2061  FD_CLR (daemon->socket_fd, &rs);
2062  }
2063  else
2064  {
2065  /* accept only, have one thread per connection */
2066  if (-1 != daemon->socket_fd)
2067  {
2068  max = daemon->socket_fd;
2069  FD_SET (daemon->socket_fd, &rs);
2070  }
2071  }
2072  if (-1 != daemon->wpipe[0])
2073  {
2074  FD_SET (daemon->wpipe[0], &rs);
2075  /* update max file descriptor */
2076  if (max < daemon->wpipe[0])
2077  max = daemon->wpipe[0];
2078  }
2079 
2080  tv = NULL;
2081  if (MHD_NO == may_block)
2082  {
2083  timeout.tv_usec = 0;
2084  timeout.tv_sec = 0;
2085  tv = &timeout;
2086  }
2087  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2088  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
2089  {
2090  /* ltimeout is in ms */
2091  timeout.tv_usec = (ltimeout % 1000) * 1000;
2092  timeout.tv_sec = ltimeout / 1000;
2093  tv = &timeout;
2094  }
2095  if (-1 == max)
2096  return MHD_YES;
2097  num_ready = SELECT (max + 1, &rs, &ws, &es, tv);
2098  if (MHD_YES == daemon->shutdown)
2099  return MHD_NO;
2100  if (num_ready < 0)
2101  {
2102  if (EINTR == errno)
2103  return MHD_YES;
2104 #if HAVE_MESSAGES
2105  MHD_DLOG (daemon, "select failed: %s\n", STRERROR (errno));
2106 #endif
2107  return MHD_NO;
2108  }
2109  return MHD_run_from_select (daemon, &rs, &ws, &es);
2110 }
2111 
2112 
2113 #ifdef HAVE_POLL_H
2114 
2122 static int
2123 MHD_poll_all (struct MHD_Daemon *daemon,
2124  int may_block)
2125 {
2126  unsigned int num_connections;
2127  struct MHD_Connection *pos;
2128  struct MHD_Connection *next;
2129 
2132 
2133  /* count number of connections and thus determine poll set size */
2134  num_connections = 0;
2135  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2136  num_connections++;
2137  {
2138  struct pollfd p[2 + num_connections];
2139  MHD_UNSIGNED_LONG_LONG ltimeout;
2140  unsigned int i;
2141  int timeout;
2142  unsigned int poll_server;
2143  int poll_listen;
2144 
2145  memset (p, 0, sizeof (p));
2146  poll_server = 0;
2147  poll_listen = -1;
2148  if ( (-1 != daemon->socket_fd) &&
2149  (0 != daemon->max_connections) )
2150  {
2151  /* only listen if we are not at the connection limit */
2152  p[poll_server].fd = daemon->socket_fd;
2153  p[poll_server].events = POLLIN;
2154  p[poll_server].revents = 0;
2155  poll_listen = (int) poll_server;
2156  poll_server++;
2157  }
2158  if (-1 != daemon->wpipe[0])
2159  {
2160  p[poll_server].fd = daemon->wpipe[0];
2161  p[poll_server].events = POLLIN;
2162  p[poll_server].revents = 0;
2163  poll_server++;
2164  }
2165  if (may_block == MHD_NO)
2166  timeout = 0;
2167  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2168  (MHD_YES != MHD_get_timeout (daemon, &ltimeout)) )
2169  timeout = -1;
2170  else
2171  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
2172 
2173  i = 0;
2174  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2175  {
2176  p[poll_server+i].fd = pos->socket_fd;
2177  switch (pos->event_loop_info)
2178  {
2180  p[poll_server+i].events |= POLLIN;
2181  break;
2183  p[poll_server+i].events |= POLLOUT;
2184  if (pos->read_buffer_size > pos->read_buffer_offset)
2185  p[poll_server+i].events |= POLLIN;
2186  break;
2188  if (pos->read_buffer_size > pos->read_buffer_offset)
2189  p[poll_server+i].events |= POLLIN;
2190  break;
2192  /* should never happen */
2193  break;
2194  }
2195  i++;
2196  }
2197  if (0 == poll_server + num_connections)
2198  return MHD_YES;
2199  if (poll (p, poll_server + num_connections, timeout) < 0)
2200  {
2201  if (EINTR == errno)
2202  return MHD_YES;
2203 #if HAVE_MESSAGES
2204  MHD_DLOG (daemon,
2205  "poll failed: %s\n",
2206  STRERROR (errno));
2207 #endif
2208  return MHD_NO;
2209  }
2210  /* handle shutdown */
2211  if (MHD_YES == daemon->shutdown)
2212  return MHD_NO;
2213  i = 0;
2214  next = daemon->connections_head;
2215  while (NULL != (pos = next))
2216  {
2217  next = pos->next;
2218  switch (pos->event_loop_info)
2219  {
2221  /* first, sanity checks */
2222  if (i >= num_connections)
2223  break; /* connection list changed somehow, retry later ... */
2224  if (p[poll_server+i].fd != pos->socket_fd)
2225  break; /* fd mismatch, something else happened, retry later ... */
2226  /* normal handling */
2227  if (0 != (p[poll_server+i].revents & POLLIN))
2228  pos->read_handler (pos);
2229  pos->idle_handler (pos);
2230  i++;
2231  break;
2233  /* first, sanity checks */
2234  if (i >= num_connections)
2235  break; /* connection list changed somehow, retry later ... */
2236  if (p[poll_server+i].fd != pos->socket_fd)
2237  break; /* fd mismatch, something else happened, retry later ... */
2238  /* normal handling */
2239  if (0 != (p[poll_server+i].revents & POLLIN))
2240  pos->read_handler (pos);
2241  if (0 != (p[poll_server+i].revents & POLLOUT))
2242  pos->write_handler (pos);
2243  pos->idle_handler (pos);
2244  i++;
2245  break;
2247  if (0 != (p[poll_server+i].revents & POLLIN))
2248  pos->read_handler (pos);
2249  pos->idle_handler (pos);
2250  break;
2252  /* should never happen */
2253  break;
2254  }
2255  }
2256  /* handle 'listen' FD */
2257  if ( (-1 != poll_listen) &&
2258  (0 != (p[poll_listen].revents & POLLIN)) )
2259  (void) MHD_accept_connection (daemon);
2260  }
2261  return MHD_YES;
2262 }
2263 
2264 
2272 static int
2273 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
2274  int may_block)
2275 {
2276  struct pollfd p[2];
2277  int timeout;
2278  unsigned int poll_count;
2279  int poll_listen;
2280 
2281  memset (&p, 0, sizeof (p));
2282  poll_count = 0;
2283  poll_listen = -1;
2284  if (-1 != daemon->socket_fd)
2285  {
2286  p[poll_count].fd = daemon->socket_fd;
2287  p[poll_count].events = POLLIN;
2288  p[poll_count].revents = 0;
2289  poll_listen = poll_count;
2290  poll_count++;
2291  }
2292  if (-1 != daemon->wpipe[0])
2293  {
2294  p[poll_count].fd = daemon->wpipe[0];
2295  p[poll_count].events = POLLIN;
2296  p[poll_count].revents = 0;
2297  poll_count++;
2298  }
2299  if (MHD_NO == may_block)
2300  timeout = 0;
2301  else
2302  timeout = -1;
2303  if (0 == poll_count)
2304  return MHD_YES;
2305  if (poll (p, poll_count, timeout) < 0)
2306  {
2307  if (EINTR == errno)
2308  return MHD_YES;
2309 #if HAVE_MESSAGES
2310  MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno));
2311 #endif
2312  return MHD_NO;
2313  }
2314  /* handle shutdown */
2315  if (MHD_YES == daemon->shutdown)
2316  return MHD_NO;
2317  if ( (-1 != poll_listen) &&
2318  (0 != (p[poll_listen].revents & POLLIN)) )
2319  (void) MHD_accept_connection (daemon);
2320  return MHD_YES;
2321 }
2322 #endif
2323 
2324 
2332 static int
2333 MHD_poll (struct MHD_Daemon *daemon,
2334  int may_block)
2335 {
2336 #ifdef HAVE_POLL_H
2337  if (MHD_YES == daemon->shutdown)
2338  return MHD_NO;
2339  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2340  return MHD_poll_all (daemon, may_block);
2341  else
2342  return MHD_poll_listen_socket (daemon, may_block);
2343 #else
2344  return MHD_NO;
2345 #endif
2346 }
2347 
2348 
2349 #if EPOLL_SUPPORT
2350 
2359 #define MAX_EVENTS 128
2360 
2361 
2370 static int
2371 MHD_epoll (struct MHD_Daemon *daemon,
2372  int may_block)
2373 {
2374  struct MHD_Connection *pos;
2375  struct MHD_Connection *next;
2376  struct epoll_event events[MAX_EVENTS];
2377  struct epoll_event event;
2378  int timeout_ms;
2379  MHD_UNSIGNED_LONG_LONG timeout_ll;
2380  int num_events;
2381  unsigned int i;
2382  unsigned int series_length;
2383  char tmp;
2384 
2385  if (-1 == daemon->epoll_fd)
2386  return MHD_NO; /* we're down! */
2387  if (MHD_YES == daemon->shutdown)
2388  return MHD_NO;
2389  if ( (-1 != daemon->socket_fd) &&
2390  (0 != daemon->max_connections) &&
2391  (MHD_NO == daemon->listen_socket_in_epoll) )
2392  {
2393  event.events = EPOLLIN;
2394  event.data.ptr = daemon;
2395  if (0 != epoll_ctl (daemon->epoll_fd,
2396  EPOLL_CTL_ADD,
2397  daemon->socket_fd,
2398  &event))
2399  {
2400 #if HAVE_MESSAGES
2401  if (0 != (daemon->options & MHD_USE_DEBUG))
2402  MHD_DLOG (daemon,
2403  "Call to epoll_ctl failed: %s\n",
2404  STRERROR (errno));
2405 #endif
2406  return MHD_NO;
2407  }
2408  daemon->listen_socket_in_epoll = MHD_YES;
2409  }
2410  if ( (MHD_YES == daemon->listen_socket_in_epoll) &&
2411  (0 == daemon->max_connections) )
2412  {
2413  /* we're at the connection limit, disable listen socket
2414  for event loop for now */
2415  if (0 != epoll_ctl (daemon->epoll_fd,
2416  EPOLL_CTL_DEL,
2417  daemon->socket_fd,
2418  NULL))
2419  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2420  daemon->listen_socket_in_epoll = MHD_NO;
2421  }
2422  if (MHD_YES == may_block)
2423  {
2424  if (MHD_YES == MHD_get_timeout (daemon,
2425  &timeout_ll))
2426  {
2427  if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
2428  timeout_ms = INT_MAX;
2429  else
2430  timeout_ms = (int) timeout_ll;
2431  }
2432  else
2433  timeout_ms = -1;
2434  }
2435  else
2436  timeout_ms = 0;
2437 
2438  /* drain 'epoll' event queue; need to iterate as we get at most
2439  MAX_EVENTS in one system call here; in practice this should
2440  pretty much mean only one round, but better an extra loop here
2441  than unfair behavior... */
2442  num_events = MAX_EVENTS;
2443  while (MAX_EVENTS == num_events)
2444  {
2445  /* update event masks */
2446  num_events = epoll_wait (daemon->epoll_fd,
2447  events, MAX_EVENTS, timeout_ms);
2448  if (-1 == num_events)
2449  {
2450  if (EINTR == errno)
2451  return MHD_YES;
2452 #if HAVE_MESSAGES
2453  if (0 != (daemon->options & MHD_USE_DEBUG))
2454  MHD_DLOG (daemon,
2455  "Call to epoll_wait failed: %s\n",
2456  STRERROR (errno));
2457 #endif
2458  return MHD_NO;
2459  }
2460  for (i=0;i<num_events;i++)
2461  {
2462  if (NULL == events[i].data.ptr)
2463  continue; /* shutdown signal! */
2464  if ( (-1 != daemon->wpipe[0]) &&
2465  (daemon->wpipe[0] == events[i].data.fd) )
2466  {
2467  (void) read (daemon->wpipe[0], &tmp, sizeof (tmp));
2468  continue;
2469  }
2470  if (daemon != events[i].data.ptr)
2471  {
2472  /* this is an event relating to a 'normal' connection,
2473  remember the event and if appropriate mark the
2474  connection as 'eready'. */
2475  pos = events[i].data.ptr;
2476  if (0 != (events[i].events & EPOLLIN))
2477  {
2478  pos->epoll_state |= MHD_EPOLL_STATE_READ_READY;
2479  if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) ||
2480  (pos->read_buffer_size > pos->read_buffer_offset) ) &&
2481  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2482  {
2483  EDLL_insert (daemon->eready_head,
2484  daemon->eready_tail,
2485  pos);
2486  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2487  }
2488  }
2489  if (0 != (events[i].events & EPOLLOUT))
2490  {
2491  pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY;
2492  if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) &&
2493  (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) )
2494  {
2495  EDLL_insert (daemon->eready_head,
2496  daemon->eready_tail,
2497  pos);
2498  pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
2499  }
2500  }
2501  }
2502  else /* must be listen socket */
2503  {
2504  /* run 'accept' until it fails or we are not allowed to take
2505  on more connections */
2506  series_length = 0;
2507  while ( (MHD_YES == MHD_accept_connection (daemon)) &&
2508  (0 != daemon->max_connections) &&
2509  (series_length < 128) )
2510  series_length++;
2511  }
2512  }
2513  }
2514 
2515  /* we handle resumes here because we may have ready connections
2516  that will not be placed into the epoll list immediately. */
2519 
2520  /* process events for connections */
2521  while (NULL != (pos = daemon->eready_tail))
2522  {
2523  EDLL_remove (daemon->eready_head,
2524  daemon->eready_tail,
2525  pos);
2526  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
2528  pos->read_handler (pos);
2530  pos->write_handler (pos);
2531  pos->idle_handler (pos);
2532  }
2533  /* Finally, handle timed-out connections; we need to do this here
2534  as the epoll mechanism won't call the 'idle_handler' on everything,
2535  as the other event loops do. As timeouts do not get an explicit
2536  event, we need to find those connections that might have timed out
2537  here.
2538 
2539  Connections with custom timeouts must all be looked at, as we
2540  do not bother to sort that (presumably very short) list. */
2541  next = daemon->manual_timeout_head;
2542  while (NULL != (pos = next))
2543  {
2544  next = pos->nextX;
2545  pos->idle_handler (pos);
2546  }
2547  /* Connections with the default timeout are sorted by prepending
2548  them to the head of the list whenever we touch the connection;
2549  thus it sufficies to iterate from the tail until the first
2550  connection is NOT timed out */
2551  next = daemon->normal_timeout_tail;
2552  while (NULL != (pos = next))
2553  {
2554  next = pos->prevX;
2555  pos->idle_handler (pos);
2556  if (MHD_CONNECTION_CLOSED != pos->state)
2557  break; /* sorted by timeout, no need to visit the rest! */
2558  }
2559  return MHD_YES;
2560 }
2561 #endif
2562 
2563 
2583 int
2584 MHD_run (struct MHD_Daemon *daemon)
2585 {
2586  if ( (MHD_YES == daemon->shutdown) ||
2587  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2588  (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2589  return MHD_NO;
2590  if (0 != (daemon->options & MHD_USE_POLL))
2591  {
2592  MHD_poll (daemon, MHD_NO);
2593  MHD_cleanup_connections (daemon);
2594  }
2595 #if EPOLL_SUPPORT
2596  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2597  {
2598  MHD_epoll (daemon, MHD_NO);
2599  MHD_cleanup_connections (daemon);
2600  }
2601 #endif
2602  else
2603  {
2604  MHD_select (daemon, MHD_NO);
2605  /* MHD_select does MHD_cleanup_connections already */
2606  }
2607  return MHD_YES;
2608 }
2609 
2610 
2618 static void *
2620 {
2621  struct MHD_Daemon *daemon = cls;
2622 
2623  while (MHD_YES != daemon->shutdown)
2624  {
2625  if (0 != (daemon->options & MHD_USE_POLL))
2626  MHD_poll (daemon, MHD_YES);
2627 #if EPOLL_SUPPORT
2628  else if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
2629  MHD_epoll (daemon, MHD_YES);
2630 #endif
2631  else
2632  MHD_select (daemon, MHD_YES);
2633  MHD_cleanup_connections (daemon);
2634  }
2635  return NULL;
2636 }
2637 
2638 
2655 struct MHD_Daemon *
2656 MHD_start_daemon (unsigned int flags,
2657  uint16_t port,
2659  void *apc_cls,
2660  MHD_AccessHandlerCallback dh, void *dh_cls, ...)
2661 {
2662  struct MHD_Daemon *daemon;
2663  va_list ap;
2664 
2665  va_start (ap, dh_cls);
2666  daemon = MHD_start_daemon_va (flags, port, apc, apc_cls, dh, dh_cls, ap);
2667  va_end (ap);
2668  return daemon;
2669 }
2670 
2671 
2691 int
2693 {
2694  unsigned int i;
2695  int ret;
2696 
2697  ret = daemon->socket_fd;
2698  if (-1 == ret)
2699  return -1;
2700  if ( (-1 == daemon->wpipe[1]) &&
2701  (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
2702  {
2703 #if HAVE_MESSAGES
2704  MHD_DLOG (daemon,
2705  "Using MHD_quiesce_daemon in this mode requires MHD_USE_PIPE_FOR_SHUTDOWN\n");
2706 #endif
2707  return -1;
2708  }
2709 
2710  if (NULL != daemon->worker_pool)
2711  for (i = 0; i < daemon->worker_pool_size; i++)
2712  {
2713  daemon->worker_pool[i].socket_fd = -1;
2714 #if EPOLL_SUPPORT
2715  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2716  (-1 != daemon->worker_pool[i].epoll_fd) &&
2717  (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) )
2718  {
2719  if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
2720  EPOLL_CTL_DEL,
2721  ret,
2722  NULL))
2723  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2724  daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO;
2725  }
2726 #endif
2727  }
2728  daemon->socket_fd = -1;
2729 #if EPOLL_SUPPORT
2730  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
2731  (-1 != daemon->epoll_fd) &&
2732  (MHD_YES == daemon->listen_socket_in_epoll) )
2733  {
2734  if (0 != epoll_ctl (daemon->epoll_fd,
2735  EPOLL_CTL_DEL,
2736  ret,
2737  NULL))
2738  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
2739  daemon->listen_socket_in_epoll = MHD_NO;
2740  }
2741 #endif
2742  return ret;
2743 }
2744 
2745 
2753 typedef void (*VfprintfFunctionPointerType)(void *cls,
2754  const char *format,
2755  va_list va);
2756 
2757 
2766 static int
2767 parse_options_va (struct MHD_Daemon *daemon,
2768  const struct sockaddr **servaddr,
2769  va_list ap);
2770 
2771 
2780 static int
2781 parse_options (struct MHD_Daemon *daemon,
2782  const struct sockaddr **servaddr,
2783  ...)
2784 {
2785  va_list ap;
2786  int ret;
2787 
2788  va_start (ap, servaddr);
2789  ret = parse_options_va (daemon, servaddr, ap);
2790  va_end (ap);
2791  return ret;
2792 }
2793 
2794 
2803 static int
2805  const struct sockaddr **servaddr,
2806  va_list ap)
2807 {
2808  enum MHD_OPTION opt;
2809  struct MHD_OptionItem *oa;
2810  unsigned int i;
2811 #if HTTPS_SUPPORT
2812  int ret;
2813  const char *pstr;
2814 #endif
2815 
2816  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
2817  {
2818  switch (opt)
2819  {
2821  daemon->pool_size = va_arg (ap, size_t);
2822  break;
2824  daemon->pool_increment= va_arg (ap, size_t);
2825  break;
2827  daemon->max_connections = va_arg (ap, unsigned int);
2828  break;
2830  daemon->connection_timeout = va_arg (ap, unsigned int);
2831  break;
2833  daemon->notify_completed =
2834  va_arg (ap, MHD_RequestCompletedCallback);
2835  daemon->notify_completed_cls = va_arg (ap, void *);
2836  break;
2838  daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
2839  break;
2840  case MHD_OPTION_SOCK_ADDR:
2841  *servaddr = va_arg (ap, const struct sockaddr *);
2842  break;
2844  daemon->uri_log_callback =
2845  va_arg (ap, LogCallback);
2846  daemon->uri_log_callback_cls = va_arg (ap, void *);
2847  break;
2849  daemon->worker_pool_size = va_arg (ap, unsigned int);
2850  if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon)))
2851  {
2852 #if HAVE_MESSAGES
2853  MHD_DLOG (daemon,
2854  "Specified thread pool size (%u) too big\n",
2855  daemon->worker_pool_size);
2856 #endif
2857  return MHD_NO;
2858  }
2859  break;
2860 #if HTTPS_SUPPORT
2862  if (0 != (daemon->options & MHD_USE_SSL))
2863  daemon->https_mem_key = va_arg (ap, const char *);
2864 #if HAVE_MESSAGES
2865  else
2866  MHD_DLOG (daemon,
2867  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
2868  opt);
2869 #endif
2870  break;
2872  if (0 != (daemon->options & MHD_USE_SSL))
2873  daemon->https_mem_cert = va_arg (ap, const char *);
2874 #if HAVE_MESSAGES
2875  else
2876  MHD_DLOG (daemon,
2877  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
2878  opt);
2879 #endif
2880  break;
2882  if (0 != (daemon->options & MHD_USE_SSL))
2883  daemon->https_mem_trust = va_arg (ap, const char *);
2884 #if HAVE_MESSAGES
2885  else
2886  MHD_DLOG (daemon,
2887  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
2888  opt);
2889 #endif
2890  break;
2892  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, int);
2893  break;
2895  if (0 != (daemon->options & MHD_USE_SSL))
2896  {
2897  gnutls_priority_deinit (daemon->priority_cache);
2898  ret = gnutls_priority_init (&daemon->priority_cache,
2899  pstr = va_arg (ap, const char*),
2900  NULL);
2901  if (ret != GNUTLS_E_SUCCESS)
2902  {
2903 #if HAVE_MESSAGES
2904  MHD_DLOG (daemon,
2905  "Setting priorities to `%s' failed: %s\n",
2906  pstr,
2907  gnutls_strerror (ret));
2908 #endif
2909  daemon->priority_cache = NULL;
2910  return MHD_NO;
2911  }
2912  }
2913  break;
2915 #if GNUTLS_VERSION_MAJOR < 3
2916 #if HAVE_MESSAGES
2917  MHD_DLOG (daemon,
2918  "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n");
2919 #endif
2920  return MHD_NO;
2921 #else
2922  if (0 != (daemon->options & MHD_USE_SSL))
2923  daemon->cert_callback = va_arg (ap, gnutls_certificate_retrieve_function2 *);
2924  break;
2925 #endif
2926 #endif
2927 #ifdef DAUTH_SUPPORT
2929  daemon->digest_auth_rand_size = va_arg (ap, size_t);
2930  daemon->digest_auth_random = va_arg (ap, const char *);
2931  break;
2933  daemon->nonce_nc_size = va_arg (ap, unsigned int);
2934  break;
2935 #endif
2937  daemon->socket_fd = va_arg (ap, int);
2938  break;
2940 #if HAVE_MESSAGES
2941  daemon->custom_error_log =
2942  va_arg (ap, VfprintfFunctionPointerType);
2943  daemon->custom_error_log_cls = va_arg (ap, void *);
2944 #else
2945  va_arg (ap, VfprintfFunctionPointerType);
2946  va_arg (ap, void *);
2947 #endif
2948  break;
2950  daemon->thread_stack_size = va_arg (ap, size_t);
2951  break;
2952  case MHD_OPTION_ARRAY:
2953  oa = va_arg (ap, struct MHD_OptionItem*);
2954  i = 0;
2955  while (MHD_OPTION_END != (opt = oa[i].option))
2956  {
2957  switch (opt)
2958  {
2959  /* all options taking 'size_t' */
2963  if (MHD_YES != parse_options (daemon,
2964  servaddr,
2965  opt,
2966  (size_t) oa[i].value,
2967  MHD_OPTION_END))
2968  return MHD_NO;
2969  break;
2970  /* all options taking 'unsigned int' */
2976  if (MHD_YES != parse_options (daemon,
2977  servaddr,
2978  opt,
2979  (unsigned int) oa[i].value,
2980  MHD_OPTION_END))
2981  return MHD_NO;
2982  break;
2983  /* all options taking 'int' or 'enum' */
2986  if (MHD_YES != parse_options (daemon,
2987  servaddr,
2988  opt,
2989  (int) oa[i].value,
2990  MHD_OPTION_END))
2991  return MHD_NO;
2992  break;
2993  /* all options taking one pointer */
2994  case MHD_OPTION_SOCK_ADDR:
2999  case MHD_OPTION_ARRAY:
3001  if (MHD_YES != parse_options (daemon,
3002  servaddr,
3003  opt,
3004  oa[i].ptr_value,
3005  MHD_OPTION_END))
3006  return MHD_NO;
3007  break;
3008  /* all options taking two pointers */
3013  if (MHD_YES != parse_options (daemon,
3014  servaddr,
3015  opt,
3016  (void *) oa[i].value,
3017  oa[i].ptr_value,
3018  MHD_OPTION_END))
3019  return MHD_NO;
3020  break;
3021  /* options taking size_t-number followed by pointer */
3023  if (MHD_YES != parse_options (daemon,
3024  servaddr,
3025  opt,
3026  (size_t) oa[i].value,
3027  oa[i].ptr_value,
3028  MHD_OPTION_END))
3029  return MHD_NO;
3030  break;
3031  default:
3032  return MHD_NO;
3033  }
3034  i++;
3035  }
3036  break;
3038  daemon->unescape_callback =
3039  va_arg (ap, UnescapeCallback);
3040  daemon->unescape_callback_cls = va_arg (ap, void *);
3041  break;
3042  default:
3043 #if HAVE_MESSAGES
3044  if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
3046  {
3047  MHD_DLOG (daemon,
3048  "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
3049  opt);
3050  }
3051  else
3052  {
3053  MHD_DLOG (daemon,
3054  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
3055  opt);
3056  }
3057 #endif
3058  return MHD_NO;
3059  }
3060  }
3061  return MHD_YES;
3062 }
3063 
3064 
3073 static int
3074 create_socket (struct MHD_Daemon *daemon,
3075  int domain, int type, int protocol)
3076 {
3077  int ctype = type | SOCK_CLOEXEC;
3078  int fd;
3079 
3080  /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
3081  * implementations do not set ai_socktype, e.g. RHL6.2. */
3082  fd = SOCKET (domain, ctype, protocol);
3083  if ( (-1 == fd) && (EINVAL == errno) && (0 != SOCK_CLOEXEC) )
3084  {
3085  ctype = type;
3086  fd = SOCKET(domain, type, protocol);
3087  }
3088  if (-1 == fd)
3089  return -1;
3090  if (type == ctype)
3091  make_nonblocking_noninheritable (daemon, fd);
3092  return fd;
3093 }
3094 
3095 
3096 #if EPOLL_SUPPORT
3097 
3104 static int
3105 setup_epoll_to_listen (struct MHD_Daemon *daemon)
3106 {
3107  struct epoll_event event;
3108 
3109  daemon->epoll_fd = epoll_create1 (EPOLL_CLOEXEC);
3110  if (-1 == daemon->epoll_fd)
3111  {
3112 #if HAVE_MESSAGES
3113  if (0 != (daemon->options & MHD_USE_DEBUG))
3114  MHD_DLOG (daemon,
3115  "Call to epoll_create1 failed: %s\n",
3116  STRERROR (errno));
3117 #endif
3118  return MHD_NO;
3119  }
3120  if (0 == EPOLL_CLOEXEC)
3122  daemon->epoll_fd);
3123  if (-1 == daemon->socket_fd)
3124  return MHD_YES; /* non-listening daemon */
3125  event.events = EPOLLIN;
3126  event.data.ptr = daemon;
3127  if (0 != epoll_ctl (daemon->epoll_fd,
3128  EPOLL_CTL_ADD,
3129  daemon->socket_fd,
3130  &event))
3131  {
3132 #if HAVE_MESSAGES
3133  if (0 != (daemon->options & MHD_USE_DEBUG))
3134  MHD_DLOG (daemon,
3135  "Call to epoll_ctl failed: %s\n",
3136  STRERROR (errno));
3137 #endif
3138  return MHD_NO;
3139  }
3140  if ( (-1 != daemon->wpipe[0]) &&
3142  {
3143  event.events = EPOLLIN | EPOLLET;
3144  event.data.ptr = NULL;
3145  event.data.fd = daemon->wpipe[0];
3146  if (0 != epoll_ctl (daemon->epoll_fd,
3147  EPOLL_CTL_ADD,
3148  daemon->wpipe[0],
3149  &event))
3150  {
3151 #if HAVE_MESSAGES
3152  if (0 != (daemon->options & MHD_USE_DEBUG))
3153  MHD_DLOG (daemon,
3154  "Call to epoll_ctl failed: %s\n",
3155  STRERROR (errno));
3156 #endif
3157  return MHD_NO;
3158  }
3159  }
3160  daemon->listen_socket_in_epoll = MHD_YES;
3161  return MHD_YES;
3162 }
3163 #endif
3164 
3165 
3183 struct MHD_Daemon *
3184 MHD_start_daemon_va (unsigned int flags,
3185  uint16_t port,
3187  void *apc_cls,
3188  MHD_AccessHandlerCallback dh, void *dh_cls,
3189  va_list ap)
3190 {
3191  const int on = 1;
3192  struct MHD_Daemon *daemon;
3193  int socket_fd;
3194  struct sockaddr_in servaddr4;
3195 #if HAVE_INET6
3196  struct sockaddr_in6 servaddr6;
3197 #endif
3198  const struct sockaddr *servaddr = NULL;
3199  socklen_t addrlen;
3200  unsigned int i;
3201  int res_thread_create;
3202  int use_pipe;
3203 
3204 #ifndef HAVE_INET6
3205  if (0 != (flags & MHD_USE_IPv6))
3206  return NULL;
3207 #endif
3208 #ifndef HAVE_POLL_H
3209  if (0 != (flags & MHD_USE_POLL))
3210  return NULL;
3211 #endif
3212 #if ! HTTPS_SUPPORT
3213  if (0 != (flags & MHD_USE_SSL))
3214  return NULL;
3215 #endif
3216  if (NULL == dh)
3217  return NULL;
3218  if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
3219  return NULL;
3220  memset (daemon, 0, sizeof (struct MHD_Daemon));
3221 #if EPOLL_SUPPORT
3222  daemon->epoll_fd = -1;
3223 #endif
3224  /* try to open listen socket */
3225 #if HTTPS_SUPPORT
3226  if (0 != (flags & MHD_USE_SSL))
3227  {
3228  gnutls_priority_init (&daemon->priority_cache,
3229  "NORMAL",
3230  NULL);
3231  }
3232 #endif
3233  daemon->socket_fd = -1;
3234  daemon->options = (enum MHD_OPTION) flags;
3235 #if WINDOWS
3236  /* Winsock is broken with respect to 'shutdown';
3237  this disables us calling 'shutdown' on W32. */
3238  daemon->options |= MHD_USE_EPOLL_TURBO;
3239 #endif
3240  daemon->port = port;
3241  daemon->apc = apc;
3242  daemon->apc_cls = apc_cls;
3243  daemon->default_handler = dh;
3244  daemon->default_handler_cls = dh_cls;
3246  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
3247  daemon->pool_increment = MHD_BUF_INC_SIZE;
3249  daemon->connection_timeout = 0; /* no timeout */
3250  daemon->wpipe[0] = -1;
3251  daemon->wpipe[1] = -1;
3252 #if HAVE_MESSAGES
3253  daemon->custom_error_log = (MHD_LogCallback) &vfprintf;
3254  daemon->custom_error_log_cls = stderr;
3255 #endif
3256 #ifdef HAVE_LISTEN_SHUTDOWN
3257  use_pipe = (0 != (daemon->options & (MHD_USE_NO_LISTEN_SOCKET | MHD_USE_PIPE_FOR_SHUTDOWN)));
3258 #else
3259  use_pipe = 1; /* yes, must use pipe to signal shutdown */
3260 #endif
3262  use_pipe = 0; /* useless if we are using 'external' select */
3263  if ( (use_pipe) &&
3264 #ifdef WINDOWS
3265  (0 != SOCKETPAIR (AF_INET, SOCK_STREAM, IPPROTO_TCP, daemon->wpipe))
3266 #else
3267  (0 != PIPE (daemon->wpipe))
3268 #endif
3269  )
3270  {
3271 #if HAVE_MESSAGES
3272  MHD_DLOG (daemon,
3273  "Failed to create control pipe: %s\n",
3274  STRERROR (errno));
3275 #endif
3276  free (daemon);
3277  return NULL;
3278  }
3279 #ifndef WINDOWS
3280  if ( (0 == (flags & MHD_USE_POLL)) &&
3281  (1 == use_pipe) &&
3282  (daemon->wpipe[0] >= FD_SETSIZE) )
3283  {
3284 #if HAVE_MESSAGES
3285  MHD_DLOG (daemon,
3286  "file descriptor for control pipe exceeds maximum value\n");
3287 #endif
3288  if (0 != CLOSE (daemon->wpipe[0]))
3289  MHD_PANIC ("close failed\n");
3290  if (0 != CLOSE (daemon->wpipe[1]))
3291  MHD_PANIC ("close failed\n");
3292  free (daemon);
3293  return NULL;
3294  }
3295 #endif
3296 #ifdef DAUTH_SUPPORT
3297  daemon->digest_auth_rand_size = 0;
3298  daemon->digest_auth_random = NULL;
3299  daemon->nonce_nc_size = 4; /* tiny */
3300 #endif
3301 #if HTTPS_SUPPORT
3302  if (0 != (flags & MHD_USE_SSL))
3303  {
3304  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
3305  }
3306 #endif
3307 
3308 
3309  if (MHD_YES != parse_options_va (daemon, &servaddr, ap))
3310  {
3311 #if HTTPS_SUPPORT
3312  if ( (0 != (flags & MHD_USE_SSL)) &&
3313  (NULL != daemon->priority_cache) )
3314  gnutls_priority_deinit (daemon->priority_cache);
3315 #endif
3316  free (daemon);
3317  return NULL;
3318  }
3319 #ifdef DAUTH_SUPPORT
3320  if (daemon->nonce_nc_size > 0)
3321  {
3322  if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) /
3323  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
3324  {
3325 #if HAVE_MESSAGES
3326  MHD_DLOG (daemon,
3327  "Specified value for NC_SIZE too large\n");
3328 #endif
3329 #if HTTPS_SUPPORT
3330  if (0 != (flags & MHD_USE_SSL))
3331  gnutls_priority_deinit (daemon->priority_cache);
3332 #endif
3333  free (daemon);
3334  return NULL;
3335  }
3336  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc));
3337  if (NULL == daemon->nnc)
3338  {
3339 #if HAVE_MESSAGES
3340  MHD_DLOG (daemon,
3341  "Failed to allocate memory for nonce-nc map: %s\n",
3342  STRERROR (errno));
3343 #endif
3344 #if HTTPS_SUPPORT
3345  if (0 != (flags & MHD_USE_SSL))
3346  gnutls_priority_deinit (daemon->priority_cache);
3347 #endif
3348  free (daemon);
3349  return NULL;
3350  }
3351  }
3352 
3353  if (0 != pthread_mutex_init (&daemon->nnc_lock, NULL))
3354  {
3355 #if HAVE_MESSAGES
3356  MHD_DLOG (daemon,
3357  "MHD failed to initialize nonce-nc mutex\n");
3358 #endif
3359 #if HTTPS_SUPPORT
3360  if (0 != (flags & MHD_USE_SSL))
3361  gnutls_priority_deinit (daemon->priority_cache);
3362 #endif
3363  free (daemon->nnc);
3364  free (daemon);
3365  return NULL;
3366  }
3367 #endif
3368 
3369  /* Thread pooling currently works only with internal select thread model */
3370  if ( (0 == (flags & MHD_USE_SELECT_INTERNALLY)) &&
3371  (daemon->worker_pool_size > 0) )
3372  {
3373 #if HAVE_MESSAGES
3374  MHD_DLOG (daemon,
3375  "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
3376 #endif
3377  goto free_and_fail;
3378  }
3379 
3380  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3381  (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) )
3382  {
3383 #if HAVE_MESSAGES
3384  MHD_DLOG (daemon,
3385  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_SUSPEND_RESUME is not supported.\n");
3386 #endif
3387  goto free_and_fail;
3388  }
3389 
3390 #ifdef __SYMBIAN32__
3391  if (0 != (flags & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
3392  {
3393 #if HAVE_MESSAGES
3394  MHD_DLOG (daemon,
3395  "Threaded operations are not supported on Symbian.\n");
3396 #endif
3397  goto free_and_fail;
3398  }
3399 #endif
3400 #if EPOLL_SUPPORT
3401  if ( (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY)) &&
3402  (0 == daemon->worker_pool_size) &&
3403  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3404  {
3405  if (0 != (flags & MHD_USE_THREAD_PER_CONNECTION))
3406  {
3407 #if HAVE_MESSAGES
3408  MHD_DLOG (daemon,
3409  "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL_LINUX_ONLY is not supported.\n");
3410 #endif
3411  goto free_and_fail;
3412  }
3413  if (MHD_YES != setup_epoll_to_listen (daemon))
3414  goto free_and_fail;
3415  }
3416 #else
3417  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3418  {
3419 #if HAVE_MESSAGES
3420  MHD_DLOG (daemon,
3421  "epoll is not supported on this platform by this build.\n");
3422 #endif
3423  goto free_and_fail;
3424  }
3425 #endif
3426  if ( (-1 == daemon->socket_fd) &&
3427  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3428  {
3429  /* try to open listen socket */
3430  if ((flags & MHD_USE_IPv6) != 0)
3431  socket_fd = create_socket (daemon,
3432  PF_INET6, SOCK_STREAM, 0);
3433  else
3434  socket_fd = create_socket (daemon,
3435  PF_INET, SOCK_STREAM, 0);
3436  if (-1 == socket_fd)
3437  {
3438 #if HAVE_MESSAGES
3439  if (0 != (flags & MHD_USE_DEBUG))
3440  MHD_DLOG (daemon,
3441  "Call to socket failed: %s\n",
3442  STRERROR (errno));
3443 #endif
3444  goto free_and_fail;
3445  }
3446  if ( (0 > SETSOCKOPT (socket_fd,
3447  SOL_SOCKET,
3448  SO_REUSEADDR,
3449  &on, sizeof (on))) &&
3450  (0 != (flags & MHD_USE_DEBUG)) )
3451  {
3452 #if HAVE_MESSAGES
3453  MHD_DLOG (daemon,
3454  "setsockopt failed: %s\n",
3455  STRERROR (errno));
3456 #endif
3457  }
3458 
3459  /* check for user supplied sockaddr */
3460 #if HAVE_INET6
3461  if (0 != (flags & MHD_USE_IPv6))
3462  addrlen = sizeof (struct sockaddr_in6);
3463  else
3464 #endif
3465  addrlen = sizeof (struct sockaddr_in);
3466  if (NULL == servaddr)
3467  {
3468 #if HAVE_INET6
3469  if (0 != (flags & MHD_USE_IPv6))
3470  {
3471  memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
3472  servaddr6.sin6_family = AF_INET6;
3473  servaddr6.sin6_port = htons (port);
3474 #if HAVE_SOCKADDR_IN_SIN_LEN
3475  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
3476 #endif
3477  servaddr = (struct sockaddr *) &servaddr6;
3478  }
3479  else
3480 #endif
3481  {
3482  memset (&servaddr4, 0, sizeof (struct sockaddr_in));
3483  servaddr4.sin_family = AF_INET;
3484  servaddr4.sin_port = htons (port);
3485 #if HAVE_SOCKADDR_IN_SIN_LEN
3486  servaddr4.sin_len = sizeof (struct sockaddr_in);
3487 #endif
3488  servaddr = (struct sockaddr *) &servaddr4;
3489  }
3490  }
3491  daemon->socket_fd = socket_fd;
3492 
3493  if ( (0 != (flags & MHD_USE_IPv6)) &&
3494  (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK)) )
3495  {
3496 #ifdef IPPROTO_IPV6
3497 #ifdef IPV6_V6ONLY
3498  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
3499  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
3500  and may also be missing on older POSIX systems; good luck if you have any of those,
3501  your IPv6 socket may then also bind against IPv4 anyway... */
3502 #ifndef WINDOWS
3503  const int on = 1;
3504 #else
3505  const char on = 1;
3506 #endif
3507  if ( (0 > SETSOCKOPT (socket_fd,
3508  IPPROTO_IPV6, IPV6_V6ONLY,
3509  &on, sizeof (on))) &&
3510  (0 != (flags & MHD_USE_DEBUG)) )
3511  {
3512 #if HAVE_MESSAGES
3513  MHD_DLOG (daemon,
3514  "setsockopt failed: %s\n",
3515  STRERROR (errno));
3516 #endif
3517  }
3518 #endif
3519 #endif
3520  }
3521  if (-1 == BIND (socket_fd, servaddr, addrlen))
3522  {
3523 #if HAVE_MESSAGES
3524  if (0 != (flags & MHD_USE_DEBUG))
3525  MHD_DLOG (daemon,
3526  "Failed to bind to port %u: %s\n",
3527  (unsigned int) port,
3528  STRERROR (errno));
3529 #endif
3530  if (0 != CLOSE (socket_fd))
3531  MHD_PANIC ("close failed\n");
3532  goto free_and_fail;
3533  }
3534 #if EPOLL_SUPPORT
3535  if (0 != (flags & MHD_USE_EPOLL_LINUX_ONLY))
3536  {
3537  int sk_flags = fcntl (socket_fd, F_GETFL);
3538  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3539  {
3540 #if HAVE_MESSAGES
3541  MHD_DLOG (daemon,
3542  "Failed to make listen socket non-blocking: %s\n",
3543  STRERROR (errno));
3544 #endif
3545  if (0 != CLOSE (socket_fd))
3546  MHD_PANIC ("close failed\n");
3547  goto free_and_fail;
3548  }
3549  }
3550 #endif
3551  if (LISTEN (socket_fd, 32) < 0)
3552  {
3553 #if HAVE_MESSAGES
3554  if (0 != (flags & MHD_USE_DEBUG))
3555  MHD_DLOG (daemon,
3556  "Failed to listen for connections: %s\n",
3557  STRERROR (errno));
3558 #endif
3559  if (0 != CLOSE (socket_fd))
3560  MHD_PANIC ("close failed\n");
3561  goto free_and_fail;
3562  }
3563  }
3564  else
3565  {
3566  socket_fd = daemon->socket_fd;
3567  }
3568 #ifndef WINDOWS
3569  if ( (socket_fd >= FD_SETSIZE) &&
3570  (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL_LINUX_ONLY)) ) )
3571  {
3572 #if HAVE_MESSAGES
3573  if ((flags & MHD_USE_DEBUG) != 0)
3574  MHD_DLOG (daemon,
3575  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
3576  socket_fd,
3577  FD_SETSIZE);
3578 #endif
3579  if (0 != CLOSE (socket_fd))
3580  MHD_PANIC ("close failed\n");
3581  goto free_and_fail;
3582  }
3583 #endif
3584 
3585  if (0 != pthread_mutex_init (&daemon->per_ip_connection_mutex, NULL))
3586  {
3587 #if HAVE_MESSAGES
3588  MHD_DLOG (daemon,
3589  "MHD failed to initialize IP connection limit mutex\n");
3590 #endif
3591  if ( (-1 != socket_fd) &&
3592  (0 != CLOSE (socket_fd)) )
3593  MHD_PANIC ("close failed\n");
3594  goto free_and_fail;
3595  }
3596  if (0 != pthread_mutex_init (&daemon->cleanup_connection_mutex, NULL))
3597  {
3598 #if HAVE_MESSAGES
3599  MHD_DLOG (daemon,
3600  "MHD failed to initialize IP connection limit mutex\n");
3601 #endif
3602  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3603  if ( (-1 != socket_fd) &&
3604  (0 != CLOSE (socket_fd)) )
3605  MHD_PANIC ("close failed\n");
3606  goto free_and_fail;
3607  }
3608 
3609 #if HTTPS_SUPPORT
3610  /* initialize HTTPS daemon certificate aspects & send / recv functions */
3611  if ((0 != (flags & MHD_USE_SSL)) && (0 != MHD_TLS_init (daemon)))
3612  {
3613 #if HAVE_MESSAGES
3614  MHD_DLOG (daemon,
3615  "Failed to initialize TLS support\n");
3616 #endif
3617  if ( (-1 != socket_fd) &&
3618  (0 != CLOSE (socket_fd)) )
3619  MHD_PANIC ("close failed\n");
3620  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3621  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
3622  goto free_and_fail;
3623  }
3624 #endif
3625  if ( ( (0 != (flags & MHD_USE_THREAD_PER_CONNECTION)) ||
3626  ( (0 != (flags & MHD_USE_SELECT_INTERNALLY)) &&
3627  (0 == daemon->worker_pool_size)) ) &&
3628  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) &&
3629  (0 != (res_thread_create =
3630  create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon))))
3631  {
3632 #if HAVE_MESSAGES
3633  MHD_DLOG (daemon,
3634  "Failed to create listen thread: %s\n",
3635  STRERROR (res_thread_create));
3636 #endif
3637  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3638  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
3639  if ( (-1 != socket_fd) &&
3640  (0 != CLOSE (socket_fd)) )
3641  MHD_PANIC ("close failed\n");
3642  goto free_and_fail;
3643  }
3644  if ( (daemon->worker_pool_size > 0) &&
3645  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
3646  {
3647 #ifndef MINGW
3648  int sk_flags;
3649 #else
3650  unsigned long sk_flags;
3651 #endif
3652 
3653  /* Coarse-grained count of connections per thread (note error
3654  * due to integer division). Also keep track of how many
3655  * connections are leftover after an equal split. */
3656  unsigned int conns_per_thread = daemon->max_connections
3657  / daemon->worker_pool_size;
3658  unsigned int leftover_conns = daemon->max_connections
3659  % daemon->worker_pool_size;
3660 
3661  i = 0; /* we need this in case fcntl or malloc fails */
3662 
3663  /* Accept must be non-blocking. Multiple children may wake up
3664  * to handle a new connection, but only one will win the race.
3665  * The others must immediately return. */
3666 #ifndef MINGW
3667  sk_flags = fcntl (socket_fd, F_GETFL);
3668  if (sk_flags < 0)
3669  goto thread_failed;
3670  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
3671  goto thread_failed;
3672 #else
3673  sk_flags = 1;
3674 #if HAVE_PLIBC_FD
3675  if (SOCKET_ERROR ==
3676  ioctlsocket (plibc_fd_get_handle (socket_fd), FIONBIO, &sk_flags))
3677  goto thread_failed;
3678 #else
3679  if (ioctlsocket (socket_fd, FIONBIO, &sk_flags) == SOCKET_ERROR)
3680  goto thread_failed;
3681 #endif // PLIBC_FD
3682 #endif // MINGW
3683 
3684  /* Allocate memory for pooled objects */
3685  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
3686  * daemon->worker_pool_size);
3687  if (NULL == daemon->worker_pool)
3688  goto thread_failed;
3689 
3690  /* Start the workers in the pool */
3691  for (i = 0; i < daemon->worker_pool_size; ++i)
3692  {
3693  /* Create copy of the Daemon object for each worker */
3694  struct MHD_Daemon *d = &daemon->worker_pool[i];
3695 
3696  memcpy (d, daemon, sizeof (struct MHD_Daemon));
3697  /* Adjust pooling params for worker daemons; note that memcpy()
3698  has already copied MHD_USE_SELECT_INTERNALLY thread model into
3699  the worker threads. */
3700  d->master = daemon;
3701  d->worker_pool_size = 0;
3702  d->worker_pool = NULL;
3703 
3704  if ( (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3705 #ifdef WINDOWS
3706  (0 != SOCKETPAIR (AF_INET, SOCK_STREAM, IPPROTO_TCP, d->wpipe))
3707 #else
3708  (0 != PIPE (d->wpipe))
3709 #endif
3710  )
3711  {
3712 #if HAVE_MESSAGES
3713  MHD_DLOG (daemon,
3714  "Failed to create worker control pipe: %s\n",
3715  STRERROR (errno));
3716 #endif
3717  goto thread_failed;
3718  }
3719 #ifndef WINDOWS
3720  if ( (0 == (flags & MHD_USE_POLL)) &&
3721  (MHD_USE_SUSPEND_RESUME == (flags & MHD_USE_SUSPEND_RESUME)) &&
3722  (d->wpipe[0] >= FD_SETSIZE) )
3723  {
3724 #if HAVE_MESSAGES
3725  MHD_DLOG (daemon,
3726  "file descriptor for worker control pipe exceeds maximum value\n");
3727 #endif
3728  if (0 != CLOSE (d->wpipe[0]))
3729  MHD_PANIC ("close failed\n");
3730  if (0 != CLOSE (d->wpipe[1]))
3731  MHD_PANIC ("close failed\n");
3732  goto thread_failed;
3733  }
3734 #endif
3735 
3736  /* Divide available connections evenly amongst the threads.
3737  * Thread indexes in [0, leftover_conns) each get one of the
3738  * leftover connections. */
3739  d->max_connections = conns_per_thread;
3740  if (i < leftover_conns)
3741  ++d->max_connections;
3742 #if EPOLL_SUPPORT
3743  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3744  (MHD_YES != setup_epoll_to_listen (d)) )
3745  goto thread_failed;
3746 #endif
3747  /* Must init cleanup connection mutex for each worker */
3748  if (0 != pthread_mutex_init (&d->cleanup_connection_mutex, NULL))
3749  {
3750 #if HAVE_MESSAGES
3751  MHD_DLOG (daemon,
3752  "MHD failed to initialize cleanup connection mutex for thread worker %d\n", i);
3753 #endif
3754  goto thread_failed;
3755  }
3756 
3757  /* Spawn the worker thread */
3758  if (0 != (res_thread_create =
3759  create_thread (&d->pid, daemon, &MHD_select_thread, d)))
3760  {
3761 #if HAVE_MESSAGES
3762  MHD_DLOG (daemon,
3763  "Failed to create pool thread: %s\n",
3764  STRERROR (res_thread_create));
3765 #endif
3766  /* Free memory for this worker; cleanup below handles
3767  * all previously-created workers. */
3768  pthread_mutex_destroy (&d->cleanup_connection_mutex);
3769  goto thread_failed;
3770  }
3771  }
3772  }
3773  return daemon;
3774 
3775 thread_failed:
3776  /* If no worker threads created, then shut down normally. Calling
3777  MHD_stop_daemon (as we do below) doesn't work here since it
3778  assumes a 0-sized thread pool means we had been in the default
3779  MHD_USE_SELECT_INTERNALLY mode. */
3780  if (0 == i)
3781  {
3782  if ( (-1 != socket_fd) &&
3783  (0 != CLOSE (socket_fd)) )
3784  MHD_PANIC ("close failed\n");
3785  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
3786  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
3787  if (NULL != daemon->worker_pool)
3788  free (daemon->worker_pool);
3789  goto free_and_fail;
3790  }
3791 
3792  /* Shutdown worker threads we've already created. Pretend
3793  as though we had fully initialized our daemon, but
3794  with a smaller number of threads than had been
3795  requested. */
3796  daemon->worker_pool_size = i - 1;
3797  MHD_stop_daemon (daemon);
3798  return NULL;
3799 
3800  free_and_fail:
3801  /* clean up basic memory state in 'daemon' and return NULL to
3802  indicate failure */
3803 #if EPOLL_SUPPORT
3804  if (-1 != daemon->epoll_fd)
3805  close (daemon->epoll_fd);
3806 #endif
3807 #ifdef DAUTH_SUPPORT
3808  free (daemon->nnc);
3809  pthread_mutex_destroy (&daemon->nnc_lock);
3810 #endif
3811 #if HTTPS_SUPPORT
3812  if (0 != (flags & MHD_USE_SSL))
3813  gnutls_priority_deinit (daemon->priority_cache);
3814 #endif
3815  free (daemon);
3816  return NULL;
3817 }
3818 
3819 
3826 static void
3828 {
3829  struct MHD_Daemon *daemon = pos->daemon;
3830 
3831  MHD_connection_close (pos,
3833  if (pos->connection_timeout == pos->daemon->connection_timeout)
3835  daemon->normal_timeout_tail,
3836  pos);
3837  else
3839  daemon->manual_timeout_tail,
3840  pos);
3841  DLL_remove (daemon->connections_head,
3842  daemon->connections_tail,
3843  pos);
3845  DLL_insert (daemon->cleanup_head,
3846  daemon->cleanup_tail,
3847  pos);
3848 }
3849 
3850 
3858 static void
3860 {
3861  struct MHD_Connection *pos;
3862  void *unused;
3863  int rc;
3864 
3865  /* first, make sure all threads are aware of shutdown; need to
3866  traverse DLLs in peace... */
3867  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3868  (0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
3869  MHD_PANIC ("Failed to acquire cleanup mutex\n");
3870  for (pos = daemon->connections_head; NULL != pos; pos = pos->nextX)
3871  SHUTDOWN (pos->socket_fd,
3872  (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
3873  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3874  (0 != pthread_mutex_unlock (&daemon->cleanup_connection_mutex)) )
3875  MHD_PANIC ("Failed to release cleanup mutex\n");
3876 
3877  /* now, collect threads from thread pool */
3878  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
3879  {
3880  while (NULL != (pos = daemon->connections_head))
3881  {
3882  if (0 != (rc = pthread_join (pos->pid, &unused)))
3883  MHD_PANIC ("Failed to join a thread\n");
3884  pos->thread_joined = MHD_YES;
3885  }
3886  }
3887 
3888  /* now that we're alone, move everyone to cleanup */
3889  while (NULL != (pos = daemon->connections_head))
3890  close_connection (pos);
3891  MHD_cleanup_connections (daemon);
3892 }
3893 
3894 
3895 #if EPOLL_SUPPORT
3896 
3901 static void
3902 epoll_shutdown (struct MHD_Daemon *daemon)
3903 {
3904  struct epoll_event event;
3905 
3906  if (-1 == daemon->wpipe[1])
3907  {
3908  /* wpipe was required in this mode, how could this happen? */
3909  MHD_PANIC ("Internal error\n");
3910  }
3911  event.events = EPOLLOUT;
3912  event.data.ptr = NULL;
3913  if (0 != epoll_ctl (daemon->epoll_fd,
3914  EPOLL_CTL_ADD,
3915  daemon->wpipe[1],
3916  &event))
3917  MHD_PANIC ("Failed to add wpipe to epoll set to signal termination\n");
3918 }
3919 #endif
3920 
3921 
3928 void
3929 MHD_stop_daemon (struct MHD_Daemon *daemon)
3930 {
3931  void *unused;
3932  int fd;
3933  unsigned int i;
3934  int rc;
3935 
3936  if (NULL == daemon)
3937  return;
3938  daemon->shutdown = MHD_YES;
3939  fd = daemon->socket_fd;
3940  daemon->socket_fd = -1;
3941  /* Prepare workers for shutdown */
3942  if (NULL != daemon->worker_pool)
3943  {
3944  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
3945  for (i = 0; i < daemon->worker_pool_size; ++i)
3946  {
3947  daemon->worker_pool[i].shutdown = MHD_YES;
3948  daemon->worker_pool[i].socket_fd = -1;
3949 #if EPOLL_SUPPORT
3950  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3951  (-1 != daemon->worker_pool[i].epoll_fd) &&
3952  (-1 == fd) )
3953  epoll_shutdown (&daemon->worker_pool[i]);
3954 #endif
3955  }
3956  }
3957  if (-1 != daemon->wpipe[1])
3958  {
3959  if (1 != WRITE (daemon->wpipe[1], "e", 1))
3960  MHD_PANIC ("failed to signal shutdown via pipe");
3961  }
3962 #ifdef HAVE_LISTEN_SHUTDOWN
3963  else
3964  {
3965  /* fd might be -1 here due to 'MHD_quiesce_daemon' */
3966  if (-1 != fd)
3967  (void) SHUTDOWN (fd, SHUT_RDWR);
3968  }
3969 #endif
3970 #if EPOLL_SUPPORT
3971  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
3972  (-1 != daemon->epoll_fd) &&
3973  (-1 == fd) )
3974  epoll_shutdown (daemon);
3975 #endif
3976 
3977 #if DEBUG_CLOSE
3978 #if HAVE_MESSAGES
3979  MHD_DLOG (daemon, "MHD listen socket shutdown\n");
3980 #endif
3981 #endif
3982 
3983 
3984  /* Signal workers to stop and clean them up */
3985  if (NULL != daemon->worker_pool)
3986  {
3987  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
3988  for (i = 0; i < daemon->worker_pool_size; ++i)
3989  {
3990  if (-1 != daemon->worker_pool[i].wpipe[1])
3991  {
3992  if (1 != WRITE (daemon->worker_pool[i].wpipe[1], "e", 1))
3993  MHD_PANIC ("failed to signal shutdown via pipe");
3994  }
3995  if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
3996  MHD_PANIC ("Failed to join a thread\n");
3997  close_all_connections (&daemon->worker_pool[i]);
3998  pthread_mutex_destroy (&daemon->worker_pool[i].cleanup_connection_mutex);
3999 #if EPOLL_SUPPORT
4000  if ( (-1 != daemon->worker_pool[i].epoll_fd) &&
4001  (0 != CLOSE (daemon->worker_pool[i].epoll_fd)) )
4002  MHD_PANIC ("close failed\n");
4003 #endif
4004  if ( (MHD_USE_SUSPEND_RESUME == (daemon->options & MHD_USE_SUSPEND_RESUME)) )
4005  {
4006  if (-1 != daemon->worker_pool[i].wpipe[1])
4007  {
4008  if (0 != CLOSE (daemon->worker_pool[i].wpipe[0]))
4009  MHD_PANIC ("close failed\n");
4010  if (0 != CLOSE (daemon->worker_pool[i].wpipe[1]))
4011  MHD_PANIC ("close failed\n");
4012  }
4013  }
4014  }
4015  free (daemon->worker_pool);
4016  }
4017  else
4018  {
4019  /* clean up master threads */
4020  if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
4021  ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
4022  && (0 == daemon->worker_pool_size)))
4023  {
4024  if (0 != (rc = pthread_join (daemon->pid, &unused)))
4025  {
4026  MHD_PANIC ("Failed to join a thread\n");
4027  }
4028  }
4029  }
4030  close_all_connections (daemon);
4031  if ( (-1 != fd) &&
4032  (0 != CLOSE (fd)) )
4033  MHD_PANIC ("close failed\n");
4034 
4035  /* TLS clean up */
4036 #if HTTPS_SUPPORT
4037  if (0 != (daemon->options & MHD_USE_SSL))
4038  {
4039  gnutls_priority_deinit (daemon->priority_cache);
4040  if (daemon->x509_cred)
4041  gnutls_certificate_free_credentials (daemon->x509_cred);
4042  }
4043 #endif
4044 #if EPOLL_SUPPORT
4045  if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
4046  (-1 != daemon->epoll_fd) &&
4047  (0 != CLOSE (daemon->epoll_fd)) )
4048  MHD_PANIC ("close failed\n");
4049 #endif
4050 
4051 #ifdef DAUTH_SUPPORT
4052  free (daemon->nnc);
4053  pthread_mutex_destroy (&daemon->nnc_lock);
4054 #endif
4055  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
4056  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
4057 
4058  if (-1 != daemon->wpipe[1])
4059  {
4060  if (0 != CLOSE (daemon->wpipe[0]))
4061  MHD_PANIC ("close failed\n");
4062  if (0 != CLOSE (daemon->wpipe[1]))
4063  MHD_PANIC ("close failed\n");
4064  }
4065  free (daemon);
4066 }
4067 
4068 
4080 const union MHD_DaemonInfo *
4082  enum MHD_DaemonInfoType info_type,
4083  ...)
4084 {
4085  switch (info_type)
4086  {
4088  return NULL; /* no longer supported */
4090  return NULL; /* no longer supported */
4092  return (const union MHD_DaemonInfo *) &daemon->socket_fd;
4093 #if EPOLL_SUPPORT
4095  return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
4096 #endif
4097  default:
4098  return NULL;
4099  };
4100 }
4101 
4102 
4119 void
4121 {
4122  mhd_panic = cb;
4123  mhd_panic_cls = cls;
4124 }
4125 
4126 
4133 const char *
4135 {
4136  return PACKAGE_VERSION;
4137 }
4138 
4139 
4140 #ifdef __GNUC__
4141 #define ATTRIBUTE_CONSTRUCTOR __attribute__ ((constructor))
4142 #define ATTRIBUTE_DESTRUCTOR __attribute__ ((destructor))
4143 #else // !__GNUC__
4144 #define ATTRIBUTE_CONSTRUCTOR
4145 #define ATTRIBUTE_DESTRUCTOR
4146 #endif // __GNUC__
4147 
4148 #if HTTPS_SUPPORT
4149 #if GCRYPT_VERSION_NUMBER < 0x010600
4150 GCRY_THREAD_OPTION_PTHREAD_IMPL;
4151 #endif
4152 #endif
4153 
4154 
4160 {
4162  mhd_panic_cls = NULL;
4163 
4164 #ifdef WINDOWS
4165  plibc_init ("GNU", "libmicrohttpd");
4166 #endif
4167 #if HTTPS_SUPPORT
4168 #if GCRYPT_VERSION_NUMBER < 0x010600
4169  gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
4170 #endif
4171  gcry_check_version (NULL);
4172  gnutls_global_init ();
4173 #endif
4174 }
4175 
4176 
4179 {
4180 #if HTTPS_SUPPORT
4181  gnutls_global_deinit ();
4182 #endif
4183 #ifdef WINDOWS
4184  plibc_shutdown ();
4185 #endif
4186 }
4187 
4188 /* end of daemon.c */
4189 
unsigned int per_ip_connection_limit
Definition: internal.h:1133
void * unescape_callback_cls
Definition: internal.h:1017
#define XDLL_insert(head, tail, element)
Definition: internal.h:1288
uint64_t total_size
Definition: internal.h:290
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:3184
static int parse_options(struct MHD_Daemon *daemon, const struct sockaddr **servaddr,...)
Definition: daemon.c:2781
pthread_mutex_t per_ip_connection_mutex
Definition: internal.h:1075
const char * MHD_get_version(void)
Definition: daemon.c:4134
pthread_mutex_t cleanup_connection_mutex
Definition: internal.h:1080
void * mhd_panic_cls
Definition: daemon.c:129
off_t fd_off
Definition: internal.h:301
static int MHD_ip_limit_add(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:278
union MHD_DaemonInfo * MHD_get_daemon_info(struct MHD_Daemon *daemon, enum MHD_DaemonInfoType info_type,...)
Definition: daemon.c:4081
int(* write_handler)(struct MHD_Connection *connection)
Definition: internal.h:801
socklen_t addr_len
Definition: internal.h:692
int thread_joined
Definition: internal.h:731
pthread_t pid
Definition: internal.h:638
enum MHD_CONNECTION_STATE state
Definition: internal.h:748
int(* idle_handler)(struct MHD_Connection *connection)
Definition: internal.h:806
uint64_t response_write_position
Definition: internal.h:681
#define EDLL_remove(head, tail, element)
Definition: internal.h:1347
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:130
enum MHD_ConnectionEventLoopInfo event_loop_info
Definition: internal.h:753
#define MHD_BUF_INC_SIZE
Definition: internal.h:60
#define DLL_remove(head, tail, element)
Definition: internal.h:1266
Methods for managing connections.
int MHD_get_timeout(struct MHD_Daemon *daemon, MHD_UNSIGNED_LONG_LONG *timeout)
Definition: daemon.c:1854
static int MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen, struct MHD_IPCount *key)
Definition: daemon.c:237
void MHD_resume_connection(struct MHD_Connection *connection)
Definition: daemon.c:1464
int socket_fd
Definition: internal.h:1085
static void MHD_cleanup_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:1759
#define SOCK_CLOEXEC
Definition: daemon.c:90
#define MHD_YES
Definition: microhttpd.h:129
static ssize_t send_param_adapter(struct MHD_Connection *connection, const void *other, size_t i)
Definition: daemon.c:870
#define MSG_NOSIGNAL
Definition: daemon.c:85
struct MHD_Response * response
Definition: internal.h:559
void(* MHD_RequestCompletedCallback)(void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
Definition: microhttpd.h:1154
struct MHD_Connection * normal_timeout_tail
Definition: internal.h:958
void *(* LogCallback)(void *cls, const char *uri, struct MHD_Connection *con)
Definition: internal.h:860
static int create_socket(struct MHD_Daemon *daemon, int domain, int type, int protocol)
Definition: daemon.c:3074
MHD_AccessHandlerCallback default_handler
Definition: internal.h:891
void(* VfprintfFunctionPointerType)(void *cls, const char *format, va_list va)
Definition: daemon.c:2753
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:2656
intptr_t value
Definition: microhttpd.h:814
platform-specific includes for libmicrohttpd
#define MHD_MAX_CONNECTIONS_DEFAULT
Definition: daemon.c:61
static ssize_t recv_param_adapter(struct MHD_Connection *connection, void *other, size_t i)
Definition: daemon.c:837
Methods for managing response objects.
void MHD_set_panic_func(MHD_PanicCallback cb, void *cls)
Definition: daemon.c:4120
#define MHD_UNSIGNED_LONG_LONG
Definition: microhttpd.h:169
void * uri_log_callback_cls
Definition: internal.h:1007
int(* read_handler)(struct MHD_Connection *connection)
Definition: internal.h:796
int wpipe[2]
Definition: internal.h:1106
struct MHD_Daemon * daemon
Definition: internal.h:544
struct MHD_Connection * manual_timeout_head
Definition: internal.h:965
static void add_to_fd_set(int fd, fd_set *set, int *max_fd)
Definition: daemon.c:557
struct MHD_Connection * cleanup_head
Definition: internal.h:921
static int internal_add_connection(struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen, int external_add)
Definition: daemon.c:1026
struct MHD_Connection * cleanup_tail
Definition: internal.h:926
static void close_connection(struct MHD_Connection *pos)
Definition: daemon.c:3827
size_t write_buffer_send_offset
Definition: internal.h:662
#define ATTRIBUTE_CONSTRUCTOR
Definition: daemon.c:4144
struct MHD_Daemon * worker_pool
Definition: internal.h:1040
static void mhd_panic_std(void *cls, const char *file, unsigned int line, const char *reason)
Definition: daemon.c:108
return NULL
Definition: tsearch.c:30
size_t read_buffer_size
Definition: internal.h:646
static void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:342
void MHD_stop_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:3929
struct MHD_Connection * nextX
Definition: internal.h:534
static void MHD_ip_count_unlock(struct MHD_Daemon *daemon)
Definition: daemon.c:203
struct MHD_Connection * manual_timeout_tail
Definition: internal.h:971
static int create_thread(pthread_t *thread, const struct MHD_Daemon *daemon, ThreadStartRoutine start_routine, void *arg)
Definition: daemon.c:955
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:2028
unsigned int worker_pool_size
Definition: internal.h:1065
time_t MHD_monotonic_time(void)
Definition: internal.c:169
static void resume_suspended_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:1496
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:1943
LogCallback uri_log_callback
Definition: internal.h:1002
void MHD_destroy_response(struct MHD_Response *response)
Definition: response.c:444
static void make_nonblocking_noninheritable(struct MHD_Daemon *daemon, int sock)
Definition: daemon.c:1571
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:1086
int shutdown
Definition: internal.h:1111
Methods for managing connections.
size_t(* UnescapeCallback)(void *cls, struct MHD_Connection *conn, char *uri)
Definition: internal.h:873
static void MHD_ip_count_lock(struct MHD_Daemon *daemon)
Definition: daemon.c:188
uint16_t port
Definition: internal.h:1143
void ATTRIBUTE_DESTRUCTOR MHD_fini()
Definition: daemon.c:4178
struct MHD_Connection * normal_timeout_head
Definition: internal.h:952
void ATTRIBUTE_CONSTRUCTOR MHD_init()
Definition: daemon.c:4159
ReceiveCallback recv_cls
Definition: internal.h:811
size_t thread_stack_size
Definition: internal.h:1060
#define HAVE_ACCEPT4
Definition: daemon.c:54
UnescapeCallback unescape_callback
Definition: internal.h:1012
pthread_t pid
Definition: internal.h:1070
static int MHD_ip_addr_compare(const void *a1, const void *a2)
Definition: daemon.c:222
static struct MHD_Daemon * MHD_get_master(struct MHD_Daemon *daemon)
Definition: daemon.c:140
int MHD_quiesce_daemon(struct MHD_Daemon *daemon)
Definition: daemon.c:2692
struct MHD_Connection * connections_head
Definition: internal.h:901
struct MHD_Daemon * master
Definition: internal.h:1035
size_t pool_size
Definition: internal.h:1050
struct MHD_Connection * next
Definition: internal.h:524
if((r=(*compar)(vkey,(*rootp) ->key))==0)
Definition: tsearch.c:35
static int MHD_poll(struct MHD_Daemon *daemon, int may_block)
Definition: daemon.c:2333
static int parse_options_va(struct MHD_Daemon *daemon, const struct sockaddr **servaddr, va_list ap)
Definition: daemon.c:2804
MHD_AcceptPolicyCallback apc
Definition: internal.h:977
time_t last_activity
Definition: internal.h:698
unsigned int connection_timeout
Definition: internal.h:704
#define MHD_PANIC(msg)
Definition: internal.h:86
size_t MHD_http_unescape(void *cls, struct MHD_Connection *connection, char *val)
Definition: internal.c:119
struct MemoryPool * pool
Definition: internal.h:571
static void * MHD_handle_connection(void *data)
Definition: daemon.c:661
void * ptr_value
Definition: microhttpd.h:820
size_t write_buffer_append_offset
Definition: internal.h:668
int resuming
Definition: internal.h:1116
#define ATTRIBUTE_DESTRUCTOR
Definition: daemon.c:4145
MHD_RequestCompletedCallback notify_completed
Definition: internal.h:988
struct MHD_Connection * prevX
Definition: internal.h:539
enum MHD_OPTION options
Definition: internal.h:1138
void MHD_set_http_callbacks_(struct MHD_Connection *connection)
Definition: connection.c:2599
#define MHD_POOL_SIZE_DEFAULT
Definition: daemon.c:69
static void close_all_connections(struct MHD_Daemon *daemon)
Definition: daemon.c:3859
void * notify_completed_cls
Definition: internal.h:993
struct MemoryPool * MHD_pool_create(size_t max)
Definition: memorypool.c:87
TransmitCallback send_cls
Definition: internal.h:816
int MHD_run(struct MHD_Daemon *daemon)
Definition: daemon.c:2584
#define XDLL_remove(head, tail, element)
Definition: internal.h:1307
#define DLL_insert(head, tail, element)
Definition: internal.h:1247
MHD_OPTION
MHD options.
Definition: microhttpd.h:548
int MHD_get_fdset(struct MHD_Daemon *daemon, fd_set *read_fd_set, fd_set *write_fd_set, fd_set *except_fd_set, int *max_fd)
Definition: daemon.c:583
#define EPOLL_CLOEXEC
Definition: daemon.c:94
void * apc_cls
Definition: internal.h:982
struct sockaddr * addr
Definition: internal.h:632
void *(* ThreadStartRoutine)(void *cls)
Definition: daemon.c:942
struct MHD_Connection * suspended_connections_tail
Definition: internal.h:916
MHD_DaemonInfoType
Definition: microhttpd.h:1036
MHD_PanicCallback mhd_panic
Definition: daemon.c:124
void * per_ip_connection_count
Definition: internal.h:1045
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:1131
int MHD_add_connection(struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon.c:1662
size_t read_buffer_offset
Definition: internal.h:652
void * default_handler_cls
Definition: internal.h:896
#define MHD_NO
Definition: microhttpd.h:134
unsigned int connection_timeout
Definition: internal.h:1127
void MHD_suspend_connection(struct MHD_Connection *connection)
Definition: daemon.c:1403
static int MHD_accept_connection(struct MHD_Daemon *daemon)
Definition: daemon.c:1689
struct MHD_Connection * connections_tail
Definition: internal.h:906
enum MHD_OPTION option
Definition: microhttpd.h:807
#define EDLL_insert(head, tail, element)
Definition: internal.h:1328
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:2619
size_t pool_increment
Definition: internal.h:1055
void(* MHD_LogCallback)(void *cls, const char *fm, va_list ap)
Definition: microhttpd.h:540
unsigned int max_connections
Definition: internal.h:1121
struct MHD_Connection * suspended_connections_head
Definition: internal.h:911
void(* MHD_PanicCallback)(void *cls, const char *file, unsigned int line, const char *reason)
Definition: microhttpd.h:1073
memory pool; mostly used for efficient (de)allocation for each connection and bounding memory use for...