GNU libmicrohttpd  0.9.5
daemon.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  (C) 2007, 2008, 2009, 2010, 2011, 2012 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 HTTPS_SUPPORT
35 #include "connection_https.h"
36 #include <gnutls/gnutls.h>
37 #include <gcrypt.h>
38 #endif
39 
40 #ifdef HAVE_POLL_H
41 #include <poll.h>
42 #endif
43 
44 #ifdef LINUX
45 #include <sys/sendfile.h>
46 #endif
47 
51 #ifndef WINDOWS
52 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE - 4
53 #else
54 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
55 #endif
56 
60 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
61 
66 #define DEBUG_CLOSE MHD_NO
67 
72 #define DEBUG_CONNECT MHD_NO
73 
74 #ifndef LINUX
75 #ifndef MSG_NOSIGNAL
76 #define MSG_NOSIGNAL 0
77 #endif
78 #endif
79 
80 #ifndef SOCK_CLOEXEC
81 #define SOCK_CLOEXEC 0
82 #endif
83 
84 
94 static void
95 mhd_panic_std (void *cls,
96  const char *file,
97  unsigned int line,
98  const char *reason)
99 {
100 #if HAVE_MESSAGES
101  fprintf (stderr, "Fatal error in GNU libmicrohttpd %s:%u: %s\n",
102  file, line, reason);
103 #endif
104  abort ();
105 }
106 
107 
112 
117 
118 
126 static struct MHD_Daemon*
127 MHD_get_master (struct MHD_Daemon *daemon)
128 {
129  while (NULL != daemon->master)
130  daemon = daemon->master;
131  return daemon;
132 }
133 
134 
138 struct MHD_IPCount
139 {
143  int family;
144 
148  union
149  {
153  struct in_addr ipv4;
154 #if HAVE_IPV6
155 
158  struct in6_addr ipv6;
159 #endif
160  } addr;
161 
165  unsigned int count;
166 };
167 
168 
174 static void
176 {
177  if (0 != pthread_mutex_lock(&daemon->per_ip_connection_mutex))
178  {
179  MHD_PANIC ("Failed to acquire IP connection limit mutex\n");
180  }
181 }
182 
183 
189 static void
191 {
192  if (0 != pthread_mutex_unlock(&daemon->per_ip_connection_mutex))
193  {
194  MHD_PANIC ("Failed to release IP connection limit mutex\n");
195  }
196 }
197 
198 
208 static int
209 MHD_ip_addr_compare(const void *a1, const void *a2)
210 {
211  return memcmp (a1, a2, offsetof (struct MHD_IPCount, count));
212 }
213 
214 
223 static int
224 MHD_ip_addr_to_key(const struct sockaddr *addr,
225  socklen_t addrlen,
226  struct MHD_IPCount *key)
227 {
228  memset(key, 0, sizeof(*key));
229 
230  /* IPv4 addresses */
231  if (sizeof (struct sockaddr_in) == addrlen)
232  {
233  const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr;
234  key->family = AF_INET;
235  memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr));
236  return MHD_YES;
237  }
238 
239 #if HAVE_IPV6
240  /* IPv6 addresses */
241  if (sizeof (struct sockaddr_in6) == addrlen)
242  {
243  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr;
244  key->family = AF_INET6;
245  memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr));
246  return MHD_YES;
247  }
248 #endif
249 
250  /* Some other address */
251  return MHD_NO;
252 }
253 
254 
264 static int
266  const struct sockaddr *addr,
267  socklen_t addrlen)
268 {
269  struct MHD_IPCount *key;
270  void **nodep;
271  void *node;
272  int result;
273 
274  daemon = MHD_get_master (daemon);
275  /* Ignore if no connection limit assigned */
276  if (0 == daemon->per_ip_connection_limit)
277  return MHD_YES;
278 
279  if (NULL == (key = malloc (sizeof(*key))))
280  return MHD_NO;
281 
282  /* Initialize key */
283  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key))
284  {
285  /* Allow unhandled address types through */
286  free (key);
287  return MHD_YES;
288  }
289  MHD_ip_count_lock (daemon);
290 
291  /* Search for the IP address */
292  if (NULL == (nodep = TSEARCH (key,
293  &daemon->per_ip_connection_count,
295  {
296 #if HAVE_MESSAGES
297  MHD_DLOG (daemon,
298  "Failed to add IP connection count node\n");
299 #endif
300  MHD_ip_count_unlock (daemon);
301  free (key);
302  return MHD_NO;
303  }
304  node = *nodep;
305  /* If we got an existing node back, free the one we created */
306  if (node != key)
307  free(key);
308  key = (struct MHD_IPCount *) node;
309  /* Test if there is room for another connection; if so,
310  * increment count */
311  result = (key->count < daemon->per_ip_connection_limit);
312  if (MHD_YES == result)
313  ++key->count;
314 
315  MHD_ip_count_unlock (daemon);
316  return result;
317 }
318 
319 
328 static void
330  const struct sockaddr *addr,
331  socklen_t addrlen)
332 {
333  struct MHD_IPCount search_key;
334  struct MHD_IPCount *found_key;
335  void **nodep;
336 
337  daemon = MHD_get_master (daemon);
338  /* Ignore if no connection limit assigned */
339  if (0 == daemon->per_ip_connection_limit)
340  return;
341  /* Initialize search key */
342  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key))
343  return;
344 
345  MHD_ip_count_lock (daemon);
346 
347  /* Search for the IP address */
348  if (NULL == (nodep = TFIND (&search_key,
349  &daemon->per_ip_connection_count,
351  {
352  /* Something's wrong if we couldn't find an IP address
353  * that was previously added */
354  MHD_PANIC ("Failed to find previously-added IP address\n");
355  }
356  found_key = (struct MHD_IPCount *) *nodep;
357  /* Validate existing count for IP address */
358  if (0 == found_key->count)
359  {
360  MHD_PANIC ("Previously-added IP address had 0 count\n");
361  }
362  /* Remove the node entirely if count reduces to 0 */
363  if (0 == --found_key->count)
364  {
365  TDELETE (found_key,
366  &daemon->per_ip_connection_count,
368  free (found_key);
369  }
370 
371  MHD_ip_count_unlock (daemon);
372 }
373 
374 
375 #if HTTPS_SUPPORT
376 
384 static ssize_t
385 recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
386 {
387  int res;
388 
389  res = gnutls_record_recv (connection->tls_session, other, i);
390  if ( (GNUTLS_E_AGAIN == res) ||
391  (GNUTLS_E_INTERRUPTED == res) )
392  {
393  errno = EINTR;
394  return -1;
395  }
396  if (res < 0)
397  {
398  /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
399  disrupted); set errno to something caller will interpret
400  correctly as a hard error*/
401  errno = EPIPE;
402  return res;
403  }
404  return res;
405 }
406 
407 
416 static ssize_t
417 send_tls_adapter (struct MHD_Connection *connection,
418  const void *other, size_t i)
419 {
420  int res;
421 
422  res = gnutls_record_send (connection->tls_session, other, i);
423  if ( (GNUTLS_E_AGAIN == res) ||
424  (GNUTLS_E_INTERRUPTED == res) )
425  {
426  errno = EINTR;
427  return -1;
428  }
429  return res;
430 }
431 
432 
439 static int
440 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
441 {
442  gnutls_datum_t key;
443  gnutls_datum_t cert;
444 
445  if (NULL != daemon->https_mem_trust)
446  {
447  cert.data = (unsigned char *) daemon->https_mem_trust;
448  cert.size = strlen (daemon->https_mem_trust);
449  if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, &cert,
450  GNUTLS_X509_FMT_PEM) < 0)
451  {
452 #if HAVE_MESSAGES
453  MHD_DLOG(daemon,
454  "Bad trust certificate format\n");
455 #endif
456  return -1;
457  }
458  }
459 
460  /* certificate & key loaded from memory */
461  if ( (NULL != daemon->https_mem_cert) &&
462  (NULL != daemon->https_mem_key) )
463  {
464  key.data = (unsigned char *) daemon->https_mem_key;
465  key.size = strlen (daemon->https_mem_key);
466  cert.data = (unsigned char *) daemon->https_mem_cert;
467  cert.size = strlen (daemon->https_mem_cert);
468 
469  return gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
470  &cert, &key,
471  GNUTLS_X509_FMT_PEM);
472  }
473 #if HAVE_MESSAGES
474  MHD_DLOG (daemon, "You need to specify a certificate and key location\n");
475 #endif
476  return -1;
477 }
478 
479 
486 static int
487 MHD_TLS_init (struct MHD_Daemon *daemon)
488 {
489  switch (daemon->cred_type)
490  {
491  case GNUTLS_CRD_CERTIFICATE:
492  if (0 !=
493  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
494  return GNUTLS_E_MEMORY_ERROR;
495  return MHD_init_daemon_certificate (daemon);
496  default:
497 #if HAVE_MESSAGES
498  MHD_DLOG (daemon,
499  "Error: invalid credentials type %d specified.\n",
500  daemon->cred_type);
501 #endif
502  return -1;
503  }
504 }
505 #endif
506 
507 
521 int
522 MHD_get_fdset (struct MHD_Daemon *daemon,
523  fd_set *read_fd_set,
524  fd_set *write_fd_set,
525  fd_set *except_fd_set,
526  int *max_fd)
527 {
528  struct MHD_Connection *pos;
529  int fd;
530 
531  if ( (NULL == daemon)
532  || (NULL == read_fd_set)
533  || (NULL == write_fd_set)
534  || (NULL == except_fd_set)
535  || (NULL == max_fd)
536  || (MHD_YES == daemon->shutdown)
537  || (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
538  || (0 != (daemon->options & MHD_USE_POLL)))
539  return MHD_NO;
540  fd = daemon->socket_fd;
541  if (-1 != fd)
542  {
543  FD_SET (fd, read_fd_set);
544  /* update max file descriptor */
545  if ((*max_fd) < fd)
546  *max_fd = fd;
547  }
548  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
549  if (MHD_YES != MHD_connection_get_fdset (pos,
550  read_fd_set,
551  write_fd_set,
552  except_fd_set, max_fd))
553  return MHD_NO;
554 #if DEBUG_CONNECT
555  MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd);
556 #endif
557  return MHD_YES;
558 }
559 
560 
568 static void *
570 {
571  struct MHD_Connection *con = data;
572  int num_ready;
573  fd_set rs;
574  fd_set ws;
575  fd_set es;
576  int max;
577  struct timeval tv;
578  struct timeval *tvp;
579  unsigned int timeout;
580  time_t now;
581 #ifdef HAVE_POLL_H
582  struct MHD_Pollfd mp;
583  struct pollfd p[1];
584 #endif
585 
586  timeout = con->daemon->connection_timeout;
587  while ( (MHD_YES != con->daemon->shutdown) &&
588  (MHD_CONNECTION_CLOSED != con->state) )
589  {
590  tvp = NULL;
591  if (timeout > 0)
592  {
593  now = MHD_monotonic_time();
594  if (now - con->last_activity > timeout)
595  tv.tv_sec = 0;
596  else
597  tv.tv_sec = timeout - (now - con->last_activity);
598  tv.tv_usec = 0;
599  tvp = &tv;
600  }
601  if ( (MHD_CONNECTION_NORMAL_BODY_UNREADY == con->state) ||
603  {
604  /* do not block (we're waiting for our callback to succeed) */
605  tv.tv_sec = 0;
606  tv.tv_usec = 0;
607  tvp = &tv;
608  }
609 #ifdef HAVE_POLL_H
610  if (0 == (con->daemon->options & MHD_USE_POLL))
611  {
612 #else
613  {
614 #endif
615  /* use select */
616  FD_ZERO (&rs);
617  FD_ZERO (&ws);
618  FD_ZERO (&es);
619  max = 0;
620  MHD_connection_get_fdset (con, &rs, &ws, &es, &max);
621  num_ready = SELECT (max + 1, &rs, &ws, &es, tvp);
622  if (num_ready < 0)
623  {
624  if (EINTR == errno)
625  continue;
626 #if HAVE_MESSAGES
627  MHD_DLOG (con->daemon,
628  "Error during select (%d): `%s'\n",
629  max,
630  STRERROR (errno));
631 #endif
632  break;
633  }
634  /* call appropriate connection handler if necessary */
635  if (FD_ISSET (con->socket_fd, &rs))
636  con->read_handler (con);
637  if (FD_ISSET (con->socket_fd, &ws))
638  con->write_handler (con);
639  if (MHD_NO == con->idle_handler (con))
640  goto exit;
641  }
642 #ifdef HAVE_POLL_H
643  else
644  {
645  /* use poll */
646  memset(&mp, 0, sizeof (struct MHD_Pollfd));
647  MHD_connection_get_pollfd(con, &mp);
648  memset(&p, 0, sizeof (p));
649  p[0].fd = mp.fd;
650  if (mp.events & MHD_POLL_ACTION_IN)
651  p[0].events |= POLLIN;
652  if (mp.events & MHD_POLL_ACTION_OUT)
653  p[0].events |= POLLOUT;
654  if (poll (p,
655  1,
656  (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
657  {
658  if (EINTR == errno)
659  continue;
660 #if HAVE_MESSAGES
661  MHD_DLOG (con->daemon, "Error during poll: `%s'\n",
662  STRERROR (errno));
663 #endif
664  break;
665  }
666  if (0 != (p[0].revents & POLLIN))
667  con->read_handler (con);
668  if (0 != (p[0].revents & POLLOUT))
669  con->write_handler (con);
670  if (0 != (p[0].revents & (POLLERR | POLLHUP)))
672  if (MHD_NO == con->idle_handler (con))
673  goto exit;
674  }
675 #endif
676  }
677  if (MHD_CONNECTION_IN_CLEANUP != con->state)
678  {
679 #if DEBUG_CLOSE
680 #if HAVE_MESSAGES
681  MHD_DLOG (con->daemon,
682  "Processing thread terminating, closing connection\n");
683 #endif
684 #endif
685  if (MHD_CONNECTION_CLOSED != con->state)
686  MHD_connection_close (con,
688  con->idle_handler (con);
689  }
690 exit:
691  if (NULL != con->response)
692  {
694  con->response = NULL;
695  }
696  return NULL;
697 }
698 
699 
708 static ssize_t
709 recv_param_adapter (struct MHD_Connection *connection,
710  void *other,
711  size_t i)
712 {
713  if ( (-1 == connection->socket_fd) ||
714  (MHD_CONNECTION_CLOSED == connection->state) )
715  {
716  errno = ENOTCONN;
717  return -1;
718  }
719  if (0 != (connection->daemon->options & MHD_USE_SSL))
720  return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
721  return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
722 }
723 
724 
733 static ssize_t
734 send_param_adapter (struct MHD_Connection *connection,
735  const void *other,
736  size_t i)
737 {
738 #if LINUX
739  int fd;
740  off_t offset;
741  off_t left;
742  ssize_t ret;
743 #endif
744  if ( (-1 == connection->socket_fd) ||
745  (MHD_CONNECTION_CLOSED == connection->state) )
746  {
747  errno = ENOTCONN;
748  return -1;
749  }
750  if (0 != (connection->daemon->options & MHD_USE_SSL))
751  return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
752 #if LINUX
753  if ( (connection->write_buffer_append_offset ==
754  connection->write_buffer_send_offset) &&
755  (NULL != connection->response) &&
756  (-1 != (fd = connection->response->fd)) )
757  {
758  /* can use sendfile */
759  offset = (off_t) connection->response_write_position + connection->response->fd_off;
760  left = connection->response->total_size - connection->response_write_position;
761  if (left > SSIZE_MAX)
762  left = SSIZE_MAX; /* cap at return value limit */
763  if (-1 != (ret = sendfile (connection->socket_fd,
764  fd,
765  &offset,
766  (size_t) left)))
767  return ret;
768  if ( (EINTR == errno) || (EAGAIN == errno) )
769  return 0;
770  if ( (EINVAL == errno) || (EBADF == errno) )
771  return -1;
772  /* None of the 'usual' sendfile errors occurred, so we should try
773  to fall back to 'SEND'; see also this thread for info on
774  odd libc/Linux behavior with sendfile:
775  http://lists.gnu.org/archive/html/libmicrohttpd/2011-02/msg00015.html */
776  }
777 #endif
778  return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
779 }
780 
781 
791 static int
792 create_thread (pthread_t * thread,
793  const struct MHD_Daemon *daemon,
794  void *(*start_routine)(void*),
795  void *arg)
796 {
797  pthread_attr_t attr;
798  pthread_attr_t *pattr;
799  int ret;
800 
801  if (0 != daemon->thread_stack_size)
802  {
803  if (0 != (ret = pthread_attr_init (&attr)))
804  goto ERR;
805  if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size)))
806  {
807  pthread_attr_destroy (&attr);
808  goto ERR;
809  }
810  pattr = &attr;
811  }
812  else
813  {
814  pattr = NULL;
815  }
816  ret = pthread_create (thread, pattr,
817  start_routine, arg);
818  if (0 != daemon->thread_stack_size)
819  pthread_attr_destroy (&attr);
820  return ret;
821  ERR:
822 #if HAVE_MESSAGES
823  MHD_DLOG (daemon,
824  "Failed to set thread stack size\n");
825 #endif
826  errno = EINVAL;
827  return ret;
828 }
829 
830 
854 int
856  int client_socket,
857  const struct sockaddr *addr,
858  socklen_t addrlen)
859 {
860  struct MHD_Connection *connection;
861  int res_thread_create;
862 #if OSX
863  static int on = 1;
864 #endif
865 
866 #ifndef WINDOWS
867  if ( (client_socket >= FD_SETSIZE) &&
868  (0 == (daemon->options & MHD_USE_POLL)) )
869  {
870 #if HAVE_MESSAGES
871  MHD_DLOG (daemon,
872  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
873  client_socket,
874  FD_SETSIZE);
875 #endif
876  SHUTDOWN (client_socket, SHUT_RDWR);
877  CLOSE (client_socket);
878  return MHD_NO;
879  }
880 #endif
881 
882 
883 #if HAVE_MESSAGES
884 #if DEBUG_CONNECT
885  MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
886 #endif
887 #endif
888  if ( (0 == daemon->max_connections) ||
889  (MHD_NO == MHD_ip_limit_add (daemon, addr, addrlen)) )
890  {
891  /* above connection limit - reject */
892 #if HAVE_MESSAGES
893  MHD_DLOG (daemon,
894  "Server reached connection limit (closing inbound connection)\n");
895 #endif
896  SHUTDOWN (client_socket, SHUT_RDWR);
897  CLOSE (client_socket);
898  return MHD_NO;
899  }
900 
901  /* apply connection acceptance policy if present */
902  if ( (NULL != daemon->apc) &&
903  (MHD_NO == daemon->apc (daemon->apc_cls,
904  addr, addrlen)) )
905  {
906 #if DEBUG_CLOSE
907 #if HAVE_MESSAGES
908  MHD_DLOG (daemon, "Connection rejected, closing connection\n");
909 #endif
910 #endif
911  SHUTDOWN (client_socket, SHUT_RDWR);
912  CLOSE (client_socket);
913  MHD_ip_limit_del (daemon, addr, addrlen);
914  return MHD_YES;
915  }
916 
917 #if OSX
918 #ifdef SOL_SOCKET
919 #ifdef SO_NOSIGPIPE
920  setsockopt (client_socket,
921  SOL_SOCKET, SO_NOSIGPIPE,
922  &on, sizeof (on));
923 #endif
924 #endif
925 #endif
926 
927  if (NULL == (connection = malloc (sizeof (struct MHD_Connection))))
928  {
929 #if HAVE_MESSAGES
930  MHD_DLOG (daemon,
931  "Error allocating memory: %s\n",
932  STRERROR (errno));
933 #endif
934  SHUTDOWN (client_socket, SHUT_RDWR);
935  CLOSE (client_socket);
936  MHD_ip_limit_del (daemon, addr, addrlen);
937  return MHD_NO;
938  }
939  memset (connection, 0, sizeof (struct MHD_Connection));
940  connection->connection_timeout = daemon->connection_timeout;
941  connection->pool = NULL;
942  if (NULL == (connection->addr = malloc (addrlen)))
943  {
944 #if HAVE_MESSAGES
945  MHD_DLOG (daemon,
946  "Error allocating memory: %s\n",
947  STRERROR (errno));
948 #endif
949  SHUTDOWN (client_socket, SHUT_RDWR);
950  CLOSE (client_socket);
951  MHD_ip_limit_del (daemon, addr, addrlen);
952  free (connection);
953  return MHD_NO;
954  }
955  memcpy (connection->addr, addr, addrlen);
956  connection->addr_len = addrlen;
957  connection->socket_fd = client_socket;
958  connection->daemon = daemon;
959  connection->last_activity = MHD_monotonic_time();
960 
961  /* set default connection handlers */
962  MHD_set_http_callbacks_ (connection);
963  connection->recv_cls = &recv_param_adapter;
964  connection->send_cls = &send_param_adapter;
965  /* non-blocking sockets are required on most systems and for GNUtls;
966  however, they somehow cause serious problems on CYGWIN (#1824) */
967 #ifdef CYGWIN
968  if
969 #if HTTPS_SUPPORT
970  (0 != (daemon->options & MHD_USE_SSL))
971 #else
972  (0)
973 #endif
974 #endif
975  {
976  /* make socket non-blocking */
977 #ifndef MINGW
978  int flags = fcntl (connection->socket_fd, F_GETFL);
979  if ( (-1 == flags) ||
980  (0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
981  {
982 #if HAVE_MESSAGES
983  MHD_DLOG (daemon,
984  "Failed to make socket %d non-blocking: %s\n",
985  connection->socket_fd,
986  STRERROR (errno));
987 #endif
988  }
989 #else
990  unsigned long flags = 1;
991  if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
992  {
993 #if HAVE_MESSAGES
994  MHD_DLOG (daemon,
995  "Failed to make socket non-blocking: %s\n",
996  STRERROR (errno));
997 #endif
998  }
999 #endif
1000  }
1001 
1002 #if HTTPS_SUPPORT
1003  if (0 != (daemon->options & MHD_USE_SSL))
1004  {
1005  connection->recv_cls = &recv_tls_adapter;
1006  connection->send_cls = &send_tls_adapter;
1007  connection->state = MHD_TLS_CONNECTION_INIT;
1008  MHD_set_https_callbacks (connection);
1009  gnutls_init (&connection->tls_session, GNUTLS_SERVER);
1010  gnutls_priority_set (connection->tls_session,
1011  daemon->priority_cache);
1012  switch (daemon->cred_type)
1013  {
1014  /* set needed credentials for certificate authentication. */
1015  case GNUTLS_CRD_CERTIFICATE:
1016  gnutls_credentials_set (connection->tls_session,
1017  GNUTLS_CRD_CERTIFICATE,
1018  daemon->x509_cred);
1019  break;
1020  default:
1021 #if HAVE_MESSAGES
1022  MHD_DLOG (connection->daemon,
1023  "Failed to setup TLS credentials: unknown credential type %d\n",
1024  daemon->cred_type);
1025 #endif
1026  SHUTDOWN (client_socket, SHUT_RDWR);
1027  CLOSE (client_socket);
1028  MHD_ip_limit_del (daemon, addr, addrlen);
1029  free (connection->addr);
1030  free (connection);
1031  MHD_PANIC ("Unknown credential type");
1032  return MHD_NO;
1033  }
1034  gnutls_transport_set_ptr (connection->tls_session,
1035  (gnutls_transport_ptr_t) connection);
1036  gnutls_transport_set_pull_function (connection->tls_session,
1037  (gnutls_pull_func) &
1039  gnutls_transport_set_push_function (connection->tls_session,
1040  (gnutls_push_func) &
1042 
1043  if (daemon->https_mem_trust){
1044  gnutls_certificate_server_set_request(connection->tls_session, GNUTLS_CERT_REQUEST);
1045  }
1046  }
1047 #endif
1048 
1049  if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex))
1050  {
1051  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1052  }
1053  DLL_insert (daemon->connections_head,
1054  daemon->connections_tail,
1055  connection);
1056  if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex))
1057  {
1058  MHD_PANIC ("Failed to release cleanup mutex\n");
1059  }
1060 
1061  /* attempt to create handler thread */
1062  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1063  {
1064  res_thread_create = create_thread (&connection->pid, daemon,
1065  &MHD_handle_connection, connection);
1066  if (0 != res_thread_create)
1067  {
1068 #if HAVE_MESSAGES
1069  MHD_DLOG (daemon, "Failed to create a thread: %s\n",
1070  STRERROR (res_thread_create));
1071 #endif
1072  SHUTDOWN (client_socket, SHUT_RDWR);
1073  CLOSE (client_socket);
1074  MHD_ip_limit_del (daemon, addr, addrlen);
1075  if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex))
1076  {
1077  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1078  }
1079  DLL_remove (daemon->connections_head,
1080  daemon->connections_tail,
1081  connection);
1082  if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex))
1083  {
1084  MHD_PANIC ("Failed to release cleanup mutex\n");
1085  }
1086  free (connection->addr);
1087  free (connection);
1088  return MHD_NO;
1089  }
1090  }
1091  daemon->max_connections--;
1092  return MHD_YES;
1093 }
1094 
1095 
1104 static int
1106 {
1107 #if HAVE_INET6
1108  struct sockaddr_in6 addrstorage;
1109 #else
1110  struct sockaddr_in addrstorage;
1111 #endif
1112  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
1113  socklen_t addrlen;
1114  int s;
1115  int flags;
1116  int need_fcntl;
1117 
1118  addrlen = sizeof (addrstorage);
1119  memset (addr, 0, sizeof (addrstorage));
1120 #if HAVE_ACCEPT4
1121  s = accept4 (daemon->socket_fd, addr, &addrlen, SOCK_CLOEXEC);
1122  need_fcntl = MHD_NO;
1123 #else
1124  s = -1;
1125  need_fcntl = MHD_YES;
1126 #endif
1127  if (-1 == s)
1128  {
1129  s = ACCEPT (daemon->socket_fd, addr, &addrlen);
1130  need_fcntl = MHD_YES;
1131  }
1132  if ((-1 == s) || (addrlen <= 0))
1133  {
1134 #if HAVE_MESSAGES
1135  /* This could be a common occurance with multiple worker threads */
1136  if ((EAGAIN != errno) && (EWOULDBLOCK != errno))
1137  MHD_DLOG (daemon,
1138  "Error accepting connection: %s\n",
1139  STRERROR (errno));
1140 #endif
1141  if (-1 != s)
1142  {
1143  SHUTDOWN (s, SHUT_RDWR);
1144  CLOSE (s);
1145  /* just in case */
1146  }
1147  return MHD_NO;
1148  }
1149  if (MHD_YES == need_fcntl)
1150  {
1151  /* make socket non-inheritable */
1152 #if !WINDOWS
1153  flags = fcntl (s, F_GETFD);
1154  if ( ( (-1 == flags) ||
1155  ( (flags != (flags | FD_CLOEXEC)) &&
1156  (0 != fcntl (s, F_SETFD, flags | FD_CLOEXEC)) ) ) )
1157 #else
1158  DWORD dwFlags;
1159  if (!GetHandleInformation ((HANDLE) s, &dwFlags) ||
1160  ((dwFlags != dwFlags & ~HANDLE_FLAG_INHERIT) &&
1161  !SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0)))
1162 #endif
1163  {
1164 #if HAVE_MESSAGES
1165 #if WINDOWS
1166  SetErrnoFromWinError (GetLastError ());
1167 #endif
1168  MHD_DLOG (daemon,
1169  "Failed to make socket non-inheritable: %s\n",
1170  STRERROR (errno));
1171 #endif
1172  }
1173  }
1174 #if HAVE_MESSAGES
1175 #if DEBUG_CONNECT
1176  MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
1177 #endif
1178 #endif
1179  return MHD_add_connection (daemon, s,
1180  addr, addrlen);
1181 }
1182 
1183 
1191 static void
1193 {
1194  struct MHD_Connection *pos;
1195  void *unused;
1196  int rc;
1197 
1198  if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex))
1199  {
1200  MHD_PANIC ("Failed to acquire cleanup mutex\n");
1201  }
1202  while (NULL != (pos = daemon->cleanup_head))
1203  {
1204  DLL_remove (daemon->cleanup_head,
1205  daemon->cleanup_tail,
1206  pos);
1207  if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1208  (MHD_NO == pos->thread_joined) )
1209  {
1210  if (0 != (rc = pthread_join (pos->pid, &unused)))
1211  {
1212  MHD_PANIC ("Failed to join a thread\n");
1213  }
1214  }
1215  MHD_pool_destroy (pos->pool);
1216 #if HTTPS_SUPPORT
1217  if (pos->tls_session != NULL)
1218  gnutls_deinit (pos->tls_session);
1219 #endif
1220  MHD_ip_limit_del (daemon, (struct sockaddr*)pos->addr, pos->addr_len);
1221  if (NULL != pos->response)
1222  {
1224  pos->response = NULL;
1225  }
1226  if (-1 != pos->socket_fd)
1227  CLOSE (pos->socket_fd);
1228  if (NULL != pos->addr)
1229  free (pos->addr);
1230  free (pos);
1231  daemon->max_connections++;
1232  }
1233  if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex))
1234  {
1235  MHD_PANIC ("Failed to release cleanup mutex\n");
1236  }
1237 }
1238 
1239 
1252 int
1253 MHD_get_timeout (struct MHD_Daemon *daemon,
1254  unsigned MHD_LONG_LONG *timeout)
1255 {
1256  time_t earliest_deadline;
1257  time_t now;
1258  struct MHD_Connection *pos;
1259  int have_timeout;
1260 
1261  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1262  {
1263 #if HAVE_MESSAGES
1264  MHD_DLOG (daemon, "Illegal call to MHD_get_timeout\n");
1265 #endif
1266  return MHD_NO;
1267  }
1268  have_timeout = MHD_NO;
1269  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
1270  {
1271  if (0 != pos->connection_timeout) {
1272  if (!have_timeout ||
1273  earliest_deadline > pos->last_activity + pos->connection_timeout)
1274  earliest_deadline = pos->last_activity + pos->connection_timeout;
1275 #if HTTPS_SUPPORT
1276  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
1277  (0 != gnutls_record_check_pending (pos->tls_session)) )
1278  earliest_deadline = 0;
1279 #endif
1280  have_timeout = MHD_YES;
1281  }
1282  }
1283  if (MHD_NO == have_timeout)
1284  return MHD_NO;
1285  now = MHD_monotonic_time();
1286  if (earliest_deadline < now)
1287  *timeout = 0;
1288  else
1289  *timeout = 1000 * (1 + earliest_deadline - now);
1290  return MHD_YES;
1291 }
1292 
1293 
1301 static int
1302 MHD_select (struct MHD_Daemon *daemon,
1303  int may_block)
1304 {
1305  struct MHD_Connection *pos;
1306  struct MHD_Connection *next;
1307  int num_ready;
1308  fd_set rs;
1309  fd_set ws;
1310  fd_set es;
1311  int max;
1312  struct timeval timeout;
1313  struct timeval *tv;
1314  unsigned MHD_LONG_LONG ltimeout;
1315  int ds;
1316 
1317  timeout.tv_sec = 0;
1318  timeout.tv_usec = 0;
1319  if (MHD_YES == daemon->shutdown)
1320  return MHD_NO;
1321  FD_ZERO (&rs);
1322  FD_ZERO (&ws);
1323  FD_ZERO (&es);
1324  max = -1;
1325  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1326  {
1327  /* single-threaded, go over everything */
1328  if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
1329  return MHD_NO;
1330 
1331  /* If we're at the connection limit, no need to
1332  accept new connections. */
1333  if ( (0 == daemon->max_connections) &&
1334  (-1 != daemon->socket_fd) )
1335  FD_CLR (daemon->socket_fd, &rs);
1336  }
1337  else
1338  {
1339  /* accept only, have one thread per connection */
1340  if (-1 != daemon->socket_fd)
1341  {
1342  max = daemon->socket_fd;
1343  FD_SET (daemon->socket_fd, &rs);
1344  }
1345  }
1346  if (-1 != daemon->wpipe[0])
1347  {
1348  FD_SET (daemon->wpipe[0], &rs);
1349  /* update max file descriptor */
1350  if (max < daemon->wpipe[0])
1351  max = daemon->wpipe[0];
1352  }
1353 
1354  tv = NULL;
1355  if (MHD_NO == may_block)
1356  {
1357  timeout.tv_usec = 0;
1358  timeout.tv_sec = 0;
1359  tv = &timeout;
1360  }
1361  else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1362  (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
1363  {
1364  /* ltimeout is in ms */
1365  timeout.tv_usec = (ltimeout % 1000) * 1000;
1366  timeout.tv_sec = ltimeout / 1000;
1367  tv = &timeout;
1368  }
1369  num_ready = SELECT (max + 1, &rs, &ws, &es, tv);
1370 
1371  if (MHD_YES == daemon->shutdown)
1372  return MHD_NO;
1373  if (num_ready < 0)
1374  {
1375  if (EINTR == errno)
1376  return MHD_YES;
1377 #if HAVE_MESSAGES
1378  MHD_DLOG (daemon, "select failed: %s\n", STRERROR (errno));
1379 #endif
1380  return MHD_NO;
1381  }
1382  /* select connection thread handling type */
1383  if ( (-1 != (ds = daemon->socket_fd)) &&
1384  (FD_ISSET (ds, &rs)) )
1385  MHD_accept_connection (daemon);
1386  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1387  {
1388  /* do not have a thread per connection, process all connections now */
1389  next = daemon->connections_head;
1390  while (NULL != (pos = next))
1391  {
1392  next = pos->next;
1393  ds = pos->socket_fd;
1394  if (ds != -1)
1395  {
1396  if (FD_ISSET (ds, &rs))
1397  pos->read_handler (pos);
1398  if (FD_ISSET (ds, &ws))
1399  pos->write_handler (pos);
1400  pos->idle_handler (pos);
1401  }
1402  }
1403  }
1404  return MHD_YES;
1405 }
1406 
1407 
1408 #ifdef HAVE_POLL_H
1409 
1417 static int
1418 MHD_poll_all (struct MHD_Daemon *daemon,
1419  int may_block)
1420 {
1421  unsigned int num_connections;
1422  struct MHD_Connection *pos;
1423  struct MHD_Connection *next;
1424 
1425  /* count number of connections and thus determine poll set size */
1426  num_connections = 0;
1427  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
1428  num_connections++;
1429 
1430  {
1431  struct pollfd p[2 + num_connections];
1432  struct MHD_Pollfd mp;
1433  unsigned MHD_LONG_LONG ltimeout;
1434  unsigned int i;
1435  int timeout;
1436  unsigned int poll_server;
1437  int poll_listen;
1438 
1439  memset (p, 0, sizeof (p));
1440  poll_server = 0;
1441  poll_listen = -1;
1442  if ( (-1 != daemon->socket_fd) &&
1443  (0 != daemon->max_connections) )
1444  {
1445  /* only listen if we are not at the connection limit */
1446  p[poll_server].fd = daemon->socket_fd;
1447  p[poll_server].events = POLLIN;
1448  p[poll_server].revents = 0;
1449  poll_listen = (int) poll_server;
1450  poll_server++;
1451  }
1452  if (-1 != daemon->wpipe[0])
1453  {
1454  p[poll_server].fd = daemon->wpipe[0];
1455  p[poll_server].events = POLLIN;
1456  p[poll_server].revents = 0;
1457  poll_server++;
1458  }
1459  if (may_block == MHD_NO)
1460  timeout = 0;
1461  else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
1462  (MHD_YES != MHD_get_timeout (daemon, &ltimeout)) )
1463  timeout = -1;
1464  else
1465  timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
1466 
1467  i = 0;
1468  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
1469  {
1470  memset(&mp, 0, sizeof (struct MHD_Pollfd));
1471  MHD_connection_get_pollfd (pos, &mp);
1472  p[poll_server+i].fd = mp.fd;
1473  if (mp.events & MHD_POLL_ACTION_IN)
1474  p[poll_server+i].events |= POLLIN;
1475  if (mp.events & MHD_POLL_ACTION_OUT)
1476  p[poll_server+i].events |= POLLOUT;
1477  i++;
1478  }
1479  if (poll (p, poll_server + num_connections, timeout) < 0)
1480  {
1481  if (EINTR == errno)
1482  return MHD_YES;
1483 #if HAVE_MESSAGES
1484  MHD_DLOG (daemon,
1485  "poll failed: %s\n",
1486  STRERROR (errno));
1487 #endif
1488  return MHD_NO;
1489  }
1490  /* handle shutdown */
1491  if (MHD_YES == daemon->shutdown)
1492  return MHD_NO;
1493  i = 0;
1494  next = daemon->connections_head;
1495  while (NULL != (pos = next))
1496  {
1497  next = pos->next;
1498  /* first, sanity checks */
1499  if (i >= num_connections)
1500  break; /* connection list changed somehow, retry later ... */
1501  MHD_connection_get_pollfd (pos, &mp);
1502  if (p[poll_server+i].fd != mp.fd)
1503  break; /* fd mismatch, something else happened, retry later ... */
1504 
1505  /* normal handling */
1506  if (0 != (p[poll_server+i].revents & POLLIN))
1507  pos->read_handler (pos);
1508  if (0 != (p[poll_server+i].revents & POLLOUT))
1509  pos->write_handler (pos);
1510  pos->idle_handler (pos);
1511  i++;
1512  }
1513  if ( (-1 != poll_listen) &&
1514  (0 != (p[poll_listen].revents & POLLIN)) )
1515  MHD_accept_connection (daemon);
1516  }
1517  return MHD_YES;
1518 }
1519 
1520 
1528 static int
1529 MHD_poll_listen_socket (struct MHD_Daemon *daemon,
1530  int may_block)
1531 {
1532  struct pollfd p[2];
1533  int timeout;
1534  unsigned int poll_count;
1535  int poll_listen;
1536 
1537  memset (&p, 0, sizeof (p));
1538  poll_count = 0;
1539  poll_listen = -1;
1540  if (-1 != daemon->socket_fd)
1541  {
1542  p[poll_count].fd = daemon->socket_fd;
1543  p[poll_count].events = POLLIN;
1544  p[poll_count].revents = 0;
1545  poll_listen = poll_count;
1546  poll_count++;
1547  }
1548  if (-1 != daemon->wpipe[0])
1549  {
1550  p[poll_count].fd = daemon->wpipe[0];
1551  p[poll_count].events = POLLIN;
1552  p[poll_count].revents = 0;
1553  poll_count++;
1554  }
1555  if (MHD_NO == may_block)
1556  timeout = 0;
1557  else
1558  timeout = -1;
1559  if (poll (p, poll_count, timeout) < 0)
1560  {
1561  if (EINTR == errno)
1562  return MHD_YES;
1563 #if HAVE_MESSAGES
1564  MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno));
1565 #endif
1566  return MHD_NO;
1567  }
1568  /* handle shutdown */
1569  if (MHD_YES == daemon->shutdown)
1570  return MHD_NO;
1571  if ( (-1 != poll_listen) &&
1572  (0 != (p[poll_listen].revents & POLLIN)) )
1573  MHD_accept_connection (daemon);
1574  return MHD_YES;
1575 }
1576 #endif
1577 
1578 
1586 static int
1587 MHD_poll (struct MHD_Daemon *daemon,
1588  int may_block)
1589 {
1590 #ifdef HAVE_POLL_H
1591  if (MHD_YES == daemon->shutdown)
1592  return MHD_NO;
1593  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1594  return MHD_poll_all (daemon, may_block);
1595  else
1596  return MHD_poll_listen_socket (daemon, may_block);
1597 #else
1598  return MHD_NO;
1599 #endif
1600 }
1601 
1602 
1613 int
1614 MHD_run (struct MHD_Daemon *daemon)
1615 {
1616  if ( (MHD_YES == daemon->shutdown) ||
1617  (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
1618  (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)) )
1619  return MHD_NO;
1620  if (0 == (daemon->options & MHD_USE_POLL))
1621  MHD_select (daemon, MHD_NO);
1622  else
1623  MHD_poll (daemon, MHD_NO);
1624  MHD_cleanup_connections (daemon);
1625  return MHD_YES;
1626 }
1627 
1628 
1636 static void *
1638 {
1639  struct MHD_Daemon *daemon = cls;
1640 
1641  while (MHD_YES != daemon->shutdown)
1642  {
1643  if (0 == (daemon->options & MHD_USE_POLL))
1644  MHD_select (daemon, MHD_YES);
1645  else
1646  MHD_poll (daemon, MHD_YES);
1647  MHD_cleanup_connections (daemon);
1648  }
1649  return NULL;
1650 }
1651 
1652 
1664 struct MHD_Daemon *
1666  uint16_t port,
1668  void *apc_cls,
1669  MHD_AccessHandlerCallback dh, void *dh_cls, ...)
1670 {
1671  struct MHD_Daemon *daemon;
1672  va_list ap;
1673 
1674  va_start (ap, dh_cls);
1675  daemon = MHD_start_daemon_va (options, port, apc, apc_cls, dh, dh_cls, ap);
1676  va_end (ap);
1677  return daemon;
1678 }
1679 
1680 
1688 typedef void (*VfprintfFunctionPointerType)(void *cls,
1689  const char *format,
1690  va_list va);
1691 
1692 
1701 static int
1702 parse_options_va (struct MHD_Daemon *daemon,
1703  const struct sockaddr **servaddr,
1704  va_list ap);
1705 
1706 
1715 static int
1716 parse_options (struct MHD_Daemon *daemon,
1717  const struct sockaddr **servaddr,
1718  ...)
1719 {
1720  va_list ap;
1721  int ret;
1722 
1723  va_start (ap, servaddr);
1724  ret = parse_options_va (daemon, servaddr, ap);
1725  va_end (ap);
1726  return ret;
1727 }
1728 
1729 
1738 static int
1740  const struct sockaddr **servaddr,
1741  va_list ap)
1742 {
1743  enum MHD_OPTION opt;
1744  struct MHD_OptionItem *oa;
1745  unsigned int i;
1746 #if HTTPS_SUPPORT
1747  int ret;
1748  const char *pstr;
1749 #endif
1750 
1751  while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int)))
1752  {
1753  switch (opt)
1754  {
1756  daemon->pool_size = va_arg (ap, size_t);
1757  break;
1759  daemon->max_connections = va_arg (ap, unsigned int);
1760  break;
1762  daemon->connection_timeout = va_arg (ap, unsigned int);
1763  break;
1765  daemon->notify_completed =
1766  va_arg (ap, MHD_RequestCompletedCallback);
1767  daemon->notify_completed_cls = va_arg (ap, void *);
1768  break;
1770  daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
1771  break;
1772  case MHD_OPTION_SOCK_ADDR:
1773  *servaddr = va_arg (ap, const struct sockaddr *);
1774  break;
1776  daemon->uri_log_callback =
1777  va_arg (ap, LogCallback);
1778  daemon->uri_log_callback_cls = va_arg (ap, void *);
1779  break;
1781  daemon->worker_pool_size = va_arg (ap, unsigned int);
1782  if (daemon->worker_pool_size >= SIZE_MAX / sizeof (struct MHD_Daemon))
1783  {
1784 #if HAVE_MESSAGES
1785  MHD_DLOG (daemon,
1786  "Specified thread pool size (%u) too big\n",
1787  daemon->worker_pool_size);
1788 #endif
1789  return MHD_NO;
1790  }
1791  break;
1792 #if HTTPS_SUPPORT
1794  if (0 != (daemon->options & MHD_USE_SSL))
1795  daemon->https_mem_key = va_arg (ap, const char *);
1796 #if HAVE_MESSAGES
1797  else
1798  MHD_DLOG (daemon,
1799  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
1800  opt);
1801 #endif
1802  break;
1804  if (0 != (daemon->options & MHD_USE_SSL))
1805  daemon->https_mem_cert = va_arg (ap, const char *);
1806 #if HAVE_MESSAGES
1807  else
1808  MHD_DLOG (daemon,
1809  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
1810  opt);
1811 #endif
1812  break;
1814  if (0 != (daemon->options & MHD_USE_SSL))
1815  daemon->https_mem_trust = va_arg (ap, const char *);
1816 #if HAVE_MESSAGES
1817  else
1818  MHD_DLOG (daemon,
1819  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
1820  opt);
1821 #endif
1822  break;
1824  daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, int);
1825  break;
1827  if (0 != (daemon->options & MHD_USE_SSL))
1828  {
1829  gnutls_priority_deinit (daemon->priority_cache);
1830  ret = gnutls_priority_init (&daemon->priority_cache,
1831  pstr = va_arg (ap, const char*),
1832  NULL);
1833  if (ret != GNUTLS_E_SUCCESS)
1834  {
1835 #if HAVE_MESSAGES
1836  MHD_DLOG (daemon,
1837  "Setting priorities to `%s' failed: %s\n",
1838  pstr,
1839  gnutls_strerror (ret));
1840 #endif
1841  daemon->priority_cache = NULL;
1842  return MHD_NO;
1843  }
1844  }
1845  break;
1846 #endif
1847 #ifdef DAUTH_SUPPORT
1849  daemon->digest_auth_rand_size = va_arg (ap, size_t);
1850  daemon->digest_auth_random = va_arg (ap, const char *);
1851  break;
1853  daemon->nonce_nc_size = va_arg (ap, unsigned int);
1854  break;
1855 #endif
1857  daemon->socket_fd = va_arg (ap, int);
1858  break;
1860 #if HAVE_MESSAGES
1861  daemon->custom_error_log =
1862  va_arg (ap, VfprintfFunctionPointerType);
1863  daemon->custom_error_log_cls = va_arg (ap, void *);
1864 #else
1865  va_arg (ap, VfprintfFunctionPointerType);
1866  va_arg (ap, void *);
1867 #endif
1868  break;
1870  daemon->thread_stack_size = va_arg (ap, size_t);
1871  break;
1872  case MHD_OPTION_ARRAY:
1873  oa = va_arg (ap, struct MHD_OptionItem*);
1874  i = 0;
1875  while (MHD_OPTION_END != (opt = oa[i].option))
1876  {
1877  switch (opt)
1878  {
1879  /* all options taking 'size_t' */
1882  if (MHD_YES != parse_options (daemon,
1883  servaddr,
1884  opt,
1885  (size_t) oa[i].value,
1886  MHD_OPTION_END))
1887  return MHD_NO;
1888  break;
1889  /* all options taking 'unsigned int' */
1895  if (MHD_YES != parse_options (daemon,
1896  servaddr,
1897  opt,
1898  (unsigned int) oa[i].value,
1899  MHD_OPTION_END))
1900  return MHD_NO;
1901  break;
1902  /* all options taking 'int' or 'enum' */
1905  if (MHD_YES != parse_options (daemon,
1906  servaddr,
1907  opt,
1908  (int) oa[i].value,
1909  MHD_OPTION_END))
1910  return MHD_NO;
1911  break;
1912  /* all options taking one pointer */
1913  case MHD_OPTION_SOCK_ADDR:
1918  case MHD_OPTION_ARRAY:
1919  if (MHD_YES != parse_options (daemon,
1920  servaddr,
1921  opt,
1922  oa[i].ptr_value,
1923  MHD_OPTION_END))
1924  return MHD_NO;
1925  break;
1926  /* all options taking two pointers */
1931  if (MHD_YES != parse_options (daemon,
1932  servaddr,
1933  opt,
1934  (void *) oa[i].value,
1935  oa[i].ptr_value,
1936  MHD_OPTION_END))
1937  return MHD_NO;
1938  break;
1939  /* options taking size_t-number followed by pointer */
1941  if (MHD_YES != parse_options (daemon,
1942  servaddr,
1943  opt,
1944  (size_t) oa[i].value,
1945  oa[i].ptr_value,
1946  MHD_OPTION_END))
1947  return MHD_NO;
1948  break;
1949  default:
1950  return MHD_NO;
1951  }
1952  i++;
1953  }
1954  break;
1956  daemon->unescape_callback =
1957  va_arg (ap, UnescapeCallback);
1958  daemon->unescape_callback_cls = va_arg (ap, void *);
1959  break;
1960  default:
1961 #if HAVE_MESSAGES
1962  if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
1964  {
1965  MHD_DLOG (daemon,
1966  "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
1967  opt);
1968  }
1969  else
1970  {
1971  MHD_DLOG (daemon,
1972  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
1973  opt);
1974  }
1975 #endif
1976  return MHD_NO;
1977  }
1978  }
1979  return MHD_YES;
1980 }
1981 
1982 
1990 static int
1991 create_socket (int domain, int type, int protocol)
1992 {
1993  static int sock_cloexec = SOCK_CLOEXEC;
1994  int ctype = SOCK_STREAM | sock_cloexec;
1995  int fd;
1996  int flags;
1997 #if WINDOWS
1998  DWORD dwFlags;
1999 #endif
2000 
2001  /* use SOCK_STREAM rather than ai_socktype: some getaddrinfo
2002  * implementations do not set ai_socktype, e.g. RHL6.2. */
2003  fd = SOCKET (domain, ctype, protocol);
2004  if ( (-1 == fd) && (EINVAL == errno) && (0 != sock_cloexec) )
2005  {
2006  sock_cloexec = 0;
2007  fd = SOCKET(domain, type, protocol);
2008  }
2009  if (-1 == fd)
2010  return -1;
2011  if (0 != sock_cloexec)
2012  return fd; /* this is it */
2013  /* flag was not set during 'socket' call, let's try setting it manually */
2014 #if !WINDOWS
2015  flags = fcntl (fd, F_GETFD);
2016  if (flags < 0)
2017 #else
2018  if (!GetHandleInformation ((HANDLE) fd, &dwFlags))
2019 #endif
2020  {
2021 #if WINDOWS
2022  SetErrnoFromWinError (GetLastError ());
2023 #endif
2024  return fd; /* good luck */
2025  }
2026 #if !WINDOWS
2027  if (flags == (flags | FD_CLOEXEC))
2028  return fd; /* already set */
2029  flags |= FD_CLOEXEC;
2030  if (0 != fcntl (fd, F_SETFD, flags))
2031 #else
2032  if (dwFlags != (dwFlags | HANDLE_FLAG_INHERIT))
2033  return fd; /* already unset */
2034  if (!SetHandleInformation ((HANDLE) fd, HANDLE_FLAG_INHERIT, 0))
2035 #endif
2036  {
2037 #if WINDOWS
2038  SetErrnoFromWinError (GetLastError ());
2039 #endif
2040  return fd; /* good luck */
2041  }
2042  return fd;
2043 }
2044 
2045 
2057 struct MHD_Daemon *
2059  uint16_t port,
2061  void *apc_cls,
2062  MHD_AccessHandlerCallback dh, void *dh_cls,
2063  va_list ap)
2064 {
2065  const int on = 1;
2066  struct MHD_Daemon *daemon;
2067  int socket_fd;
2068  struct sockaddr_in servaddr4;
2069 #if HAVE_INET6
2070  struct sockaddr_in6 servaddr6;
2071 #endif
2072  const struct sockaddr *servaddr = NULL;
2073  socklen_t addrlen;
2074  unsigned int i;
2075  int res_thread_create;
2076  int use_pipe;
2077 
2078  if (NULL == dh)
2079  return NULL;
2080  if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon))))
2081  return NULL;
2082  memset (daemon, 0, sizeof (struct MHD_Daemon));
2083 #if HTTPS_SUPPORT
2084  if (0 != (options & MHD_USE_SSL))
2085  {
2086  gnutls_priority_init (&daemon->priority_cache,
2087  "NORMAL",
2088  NULL);
2089  }
2090 #endif
2091  daemon->socket_fd = -1;
2092  daemon->options = (enum MHD_OPTION) options;
2093  daemon->port = port;
2094  daemon->apc = apc;
2095  daemon->apc_cls = apc_cls;
2096  daemon->default_handler = dh;
2097  daemon->default_handler_cls = dh_cls;
2099  daemon->pool_size = MHD_POOL_SIZE_DEFAULT;
2101  daemon->connection_timeout = 0; /* no timeout */
2102  daemon->wpipe[0] = -1;
2103  daemon->wpipe[1] = -1;
2104 #if HAVE_MESSAGES
2105  daemon->custom_error_log =
2106  (void (*)(void *, const char *, va_list)) &vfprintf;
2107  daemon->custom_error_log_cls = stderr;
2108 #endif
2109 #ifdef HAVE_LISTEN_SHUTDOWN
2110  use_pipe = (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET));
2111 #else
2112  use_pipe = 1; /* yes, must use pipe to signal shutdown */
2113 #endif
2114  if ( (use_pipe) &&
2115  (0 != PIPE (daemon->wpipe)) )
2116  {
2117 #if HAVE_MESSAGES
2118  MHD_DLOG (daemon,
2119  "Failed to create control pipe: %s\n",
2120  STRERROR (errno));
2121 #endif
2122  free (daemon);
2123  return NULL;
2124  }
2125 #ifndef WINDOWS
2126  if ( (0 == (options & MHD_USE_POLL)) &&
2127  (daemon->wpipe[0] >= FD_SETSIZE) )
2128  {
2129 #if HAVE_MESSAGES
2130  MHD_DLOG (daemon,
2131  "file descriptor for control pipe exceeds maximum value\n");
2132 #endif
2133  CLOSE (daemon->wpipe[0]);
2134  CLOSE (daemon->wpipe[1]);
2135  free (daemon);
2136  return NULL;
2137  }
2138 #endif
2139 #ifdef DAUTH_SUPPORT
2140  daemon->digest_auth_rand_size = 0;
2141  daemon->digest_auth_random = NULL;
2142  daemon->nonce_nc_size = 4; /* tiny */
2143 #endif
2144 #if HTTPS_SUPPORT
2145  if (0 != (options & MHD_USE_SSL))
2146  {
2147  daemon->cred_type = GNUTLS_CRD_CERTIFICATE;
2148  }
2149 #endif
2150 
2151  if (MHD_YES != parse_options_va (daemon, &servaddr, ap))
2152  {
2153 #if HTTPS_SUPPORT
2154  if ( (0 != (options & MHD_USE_SSL)) &&
2155  (NULL != daemon->priority_cache) )
2156  gnutls_priority_deinit (daemon->priority_cache);
2157 #endif
2158  free (daemon);
2159  return NULL;
2160  }
2161 
2162 #ifdef DAUTH_SUPPORT
2163  if (daemon->nonce_nc_size > 0)
2164  {
2165  if ( ( (size_t) (daemon->nonce_nc_size * sizeof(struct MHD_NonceNc))) /
2166  sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size)
2167  {
2168 #if HAVE_MESSAGES
2169  MHD_DLOG (daemon,
2170  "Specified value for NC_SIZE too large\n");
2171 #endif
2172 #if HTTPS_SUPPORT
2173  if (0 != (options & MHD_USE_SSL))
2174  gnutls_priority_deinit (daemon->priority_cache);
2175 #endif
2176  free (daemon);
2177  return NULL;
2178  }
2179  daemon->nnc = malloc (daemon->nonce_nc_size * sizeof(struct MHD_NonceNc));
2180  if (NULL == daemon->nnc)
2181  {
2182 #if HAVE_MESSAGES
2183  MHD_DLOG (daemon,
2184  "Failed to allocate memory for nonce-nc map: %s\n",
2185  STRERROR (errno));
2186 #endif
2187 #if HTTPS_SUPPORT
2188  if (0 != (options & MHD_USE_SSL))
2189  gnutls_priority_deinit (daemon->priority_cache);
2190 #endif
2191  free (daemon);
2192  return NULL;
2193  }
2194  }
2195 
2196  if (0 != pthread_mutex_init (&daemon->nnc_lock, NULL))
2197  {
2198 #if HAVE_MESSAGES
2199  MHD_DLOG (daemon,
2200  "MHD failed to initialize nonce-nc mutex\n");
2201 #endif
2202 #if HTTPS_SUPPORT
2203  if (0 != (options & MHD_USE_SSL))
2204  gnutls_priority_deinit (daemon->priority_cache);
2205 #endif
2206  free (daemon->nnc);
2207  free (daemon);
2208  return NULL;
2209  }
2210 #endif
2211 
2212  /* Thread pooling currently works only with internal select thread model */
2213  if ( (0 == (options & MHD_USE_SELECT_INTERNALLY)) &&
2214  (daemon->worker_pool_size > 0) )
2215  {
2216 #if HAVE_MESSAGES
2217  MHD_DLOG (daemon,
2218  "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
2219 #endif
2220  goto free_and_fail;
2221  }
2222 
2223 #ifdef __SYMBIAN32__
2224  if (0 != (options & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
2225  {
2226 #if HAVE_MESSAGES
2227  MHD_DLOG (daemon,
2228  "Threaded operations are not supported on Symbian.\n");
2229 #endif
2230  goto free_and_fail;
2231  }
2232 #endif
2233  if ( (-1 == daemon->socket_fd) &&
2234  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
2235  {
2236  /* try to open listen socket */
2237  if ((options & MHD_USE_IPv6) != 0)
2238 #if HAVE_INET6
2239  socket_fd = create_socket (PF_INET6, SOCK_STREAM, 0);
2240 #else
2241  {
2242 #if HAVE_MESSAGES
2243  MHD_DLOG (daemon,
2244  "AF_INET6 not supported\n");
2245 #endif
2246  goto free_and_fail;
2247  }
2248 #endif
2249  else
2250  socket_fd = create_socket (PF_INET, SOCK_STREAM, 0);
2251  if (-1 == socket_fd)
2252  {
2253 #if HAVE_MESSAGES
2254  if (0 != (options & MHD_USE_DEBUG))
2255  MHD_DLOG (daemon,
2256  "Call to socket failed: %s\n",
2257  STRERROR (errno));
2258 #endif
2259  goto free_and_fail;
2260  }
2261  if ((SETSOCKOPT (socket_fd,
2262  SOL_SOCKET,
2263  SO_REUSEADDR,
2264  &on, sizeof (on)) < 0) && ((options & MHD_USE_DEBUG) != 0))
2265  {
2266 #if HAVE_MESSAGES
2267  MHD_DLOG (daemon,
2268  "setsockopt failed: %s\n",
2269  STRERROR (errno));
2270 #endif
2271  }
2272 
2273  /* check for user supplied sockaddr */
2274 #if HAVE_INET6
2275  if (0 != (options & MHD_USE_IPv6))
2276  addrlen = sizeof (struct sockaddr_in6);
2277  else
2278 #endif
2279  addrlen = sizeof (struct sockaddr_in);
2280  if (NULL == servaddr)
2281  {
2282 #if HAVE_INET6
2283  if (0 != (options & MHD_USE_IPv6))
2284  {
2285  memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
2286  servaddr6.sin6_family = AF_INET6;
2287  servaddr6.sin6_port = htons (port);
2288 #if HAVE_SOCKADDR_IN_SIN_LEN
2289  servaddr6.sin6_len = sizeof (struct sockaddr_in6);
2290 #endif
2291  servaddr = (struct sockaddr *) &servaddr6;
2292  }
2293  else
2294 #endif
2295  {
2296  memset (&servaddr4, 0, sizeof (struct sockaddr_in));
2297  servaddr4.sin_family = AF_INET;
2298  servaddr4.sin_port = htons (port);
2299 #if HAVE_SOCKADDR_IN_SIN_LEN
2300  servaddr4.sin_len = sizeof (struct sockaddr_in);
2301 #endif
2302  servaddr = (struct sockaddr *) &servaddr4;
2303  }
2304  }
2305  daemon->socket_fd = socket_fd;
2306 
2307  if (0 != (options & MHD_USE_IPv6))
2308  {
2309 #ifdef IPPROTO_IPV6
2310 #ifdef IPV6_V6ONLY
2311  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
2312  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
2313  and may also be missing on older POSIX systems; good luck if you have any of those,
2314  your IPv6 socket may then also bind against IPv4... */
2315 #ifndef WINDOWS
2316  const int on = 1;
2317  setsockopt (socket_fd,
2318  IPPROTO_IPV6, IPV6_V6ONLY,
2319  &on, sizeof (on));
2320 #else
2321  const char on = 1;
2322  setsockopt (socket_fd,
2323  IPPROTO_IPV6, IPV6_V6ONLY,
2324  &on, sizeof (on));
2325 #endif
2326 #endif
2327 #endif
2328  }
2329  if (-1 == BIND (socket_fd, servaddr, addrlen))
2330  {
2331 #if HAVE_MESSAGES
2332  if (0 != (options & MHD_USE_DEBUG))
2333  MHD_DLOG (daemon,
2334  "Failed to bind to port %u: %s\n",
2335  (unsigned int) port,
2336  STRERROR (errno));
2337 #endif
2338  CLOSE (socket_fd);
2339  goto free_and_fail;
2340  }
2341 
2342  if (LISTEN (socket_fd, 20) < 0)
2343  {
2344 #if HAVE_MESSAGES
2345  if (0 != (options & MHD_USE_DEBUG))
2346  MHD_DLOG (daemon,
2347  "Failed to listen for connections: %s\n",
2348  STRERROR (errno));
2349 #endif
2350  CLOSE (socket_fd);
2351  goto free_and_fail;
2352  }
2353  }
2354  else
2355  {
2356  socket_fd = daemon->socket_fd;
2357  }
2358 #ifndef WINDOWS
2359  if ( (socket_fd >= FD_SETSIZE) &&
2360  (0 == (options & MHD_USE_POLL)) )
2361  {
2362 #if HAVE_MESSAGES
2363  if ((options & MHD_USE_DEBUG) != 0)
2364  MHD_DLOG (daemon,
2365  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
2366  socket_fd,
2367  FD_SETSIZE);
2368 #endif
2369  CLOSE (socket_fd);
2370  goto free_and_fail;
2371  }
2372 #endif
2373 
2374  if (0 != pthread_mutex_init (&daemon->per_ip_connection_mutex, NULL))
2375  {
2376 #if HAVE_MESSAGES
2377  MHD_DLOG (daemon,
2378  "MHD failed to initialize IP connection limit mutex\n");
2379 #endif
2380  if (-1 != socket_fd)
2381  CLOSE (socket_fd);
2382  goto free_and_fail;
2383  }
2384  if (0 != pthread_mutex_init (&daemon->cleanup_connection_mutex, NULL))
2385  {
2386 #if HAVE_MESSAGES
2387  MHD_DLOG (daemon,
2388  "MHD failed to initialize IP connection limit mutex\n");
2389 #endif
2390  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2391  if (-1 != socket_fd)
2392  CLOSE (socket_fd);
2393  goto free_and_fail;
2394  }
2395 
2396 #if HTTPS_SUPPORT
2397  /* initialize HTTPS daemon certificate aspects & send / recv functions */
2398  if ((0 != (options & MHD_USE_SSL)) && (0 != MHD_TLS_init (daemon)))
2399  {
2400 #if HAVE_MESSAGES
2401  MHD_DLOG (daemon,
2402  "Failed to initialize TLS support\n");
2403 #endif
2404  if (-1 != socket_fd)
2405  CLOSE (socket_fd);
2406  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2407  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2408  goto free_and_fail;
2409  }
2410 #endif
2411  if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
2412  ( (0 != (options & MHD_USE_SELECT_INTERNALLY)) &&
2413  (0 == daemon->worker_pool_size)) ) &&
2414  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) &&
2415  (0 != (res_thread_create =
2416  create_thread (&daemon->pid, daemon, &MHD_select_thread, daemon))))
2417  {
2418 #if HAVE_MESSAGES
2419  MHD_DLOG (daemon,
2420  "Failed to create listen thread: %s\n",
2421  STRERROR (res_thread_create));
2422 #endif
2423  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2424  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2425  if (-1 != socket_fd)
2426  CLOSE (socket_fd);
2427  goto free_and_fail;
2428  }
2429  if ( (daemon->worker_pool_size > 0) &&
2430  (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
2431  {
2432 #ifndef MINGW
2433  int sk_flags;
2434 #else
2435  unsigned long sk_flags;
2436 #endif
2437 
2438  /* Coarse-grained count of connections per thread (note error
2439  * due to integer division). Also keep track of how many
2440  * connections are leftover after an equal split. */
2441  unsigned int conns_per_thread = daemon->max_connections
2442  / daemon->worker_pool_size;
2443  unsigned int leftover_conns = daemon->max_connections
2444  % daemon->worker_pool_size;
2445 
2446  i = 0; /* we need this in case fcntl or malloc fails */
2447 
2448  /* Accept must be non-blocking. Multiple children may wake up
2449  * to handle a new connection, but only one will win the race.
2450  * The others must immediately return. */
2451 #ifndef MINGW
2452  sk_flags = fcntl (socket_fd, F_GETFL);
2453  if (sk_flags < 0)
2454  goto thread_failed;
2455  if (0 != fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK))
2456  goto thread_failed;
2457 #else
2458  sk_flags = 1;
2459 #if HAVE_PLIBC_FD
2460  if (SOCKET_ERROR ==
2461  ioctlsocket (plibc_fd_get_handle (socket_fd), FIONBIO, &sk_flags))
2462 #else
2463  if (ioctlsocket (socket_fd, FIONBIO, &sk_flags) == SOCKET_ERROR)
2464 #endif // PLIBC_FD
2465  goto thread_failed;
2466 #endif // MINGW
2467 
2468  /* Allocate memory for pooled objects */
2469  daemon->worker_pool = malloc (sizeof (struct MHD_Daemon)
2470  * daemon->worker_pool_size);
2471  if (NULL == daemon->worker_pool)
2472  goto thread_failed;
2473 
2474  /* Start the workers in the pool */
2475  for (i = 0; i < daemon->worker_pool_size; ++i)
2476  {
2477  /* Create copy of the Daemon object for each worker */
2478  struct MHD_Daemon *d = &daemon->worker_pool[i];
2479  memcpy (d, daemon, sizeof (struct MHD_Daemon));
2480 
2481  /* Adjust pooling params for worker daemons; note that memcpy()
2482  has already copied MHD_USE_SELECT_INTERNALLY thread model into
2483  the worker threads. */
2484  d->master = daemon;
2485  d->worker_pool_size = 0;
2486  d->worker_pool = NULL;
2487 
2488  /* Divide available connections evenly amongst the threads.
2489  * Thread indexes in [0, leftover_conns) each get one of the
2490  * leftover connections. */
2491  d->max_connections = conns_per_thread;
2492  if (i < leftover_conns)
2493  ++d->max_connections;
2494 
2495  /* Spawn the worker thread */
2496  if (0 != (res_thread_create = create_thread (&d->pid, daemon, &MHD_select_thread, d)))
2497  {
2498 #if HAVE_MESSAGES
2499  MHD_DLOG (daemon,
2500  "Failed to create pool thread: %s\n",
2501  STRERROR (res_thread_create));
2502 #endif
2503  /* Free memory for this worker; cleanup below handles
2504  * all previously-created workers. */
2505  goto thread_failed;
2506  }
2507  }
2508  }
2509  return daemon;
2510 
2511 thread_failed:
2512  /* If no worker threads created, then shut down normally. Calling
2513  MHD_stop_daemon (as we do below) doesn't work here since it
2514  assumes a 0-sized thread pool means we had been in the default
2515  MHD_USE_SELECT_INTERNALLY mode. */
2516  if (0 == i)
2517  {
2518  if (-1 != socket_fd)
2519  CLOSE (socket_fd);
2520  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2521  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2522  if (NULL != daemon->worker_pool)
2523  free (daemon->worker_pool);
2524  goto free_and_fail;
2525  }
2526 
2527  /* Shutdown worker threads we've already created. Pretend
2528  as though we had fully initialized our daemon, but
2529  with a smaller number of threads than had been
2530  requested. */
2531  daemon->worker_pool_size = i - 1;
2532  MHD_stop_daemon (daemon);
2533  return NULL;
2534 
2535  free_and_fail:
2536  /* clean up basic memory state in 'daemon' and return NULL to
2537  indicate failure */
2538 #ifdef DAUTH_SUPPORT
2539  free (daemon->nnc);
2540  pthread_mutex_destroy (&daemon->nnc_lock);
2541 #endif
2542 #if HTTPS_SUPPORT
2543  if (0 != (options & MHD_USE_SSL))
2544  gnutls_priority_deinit (daemon->priority_cache);
2545 #endif
2546  free (daemon);
2547  return NULL;
2548 }
2549 
2550 
2558 static void
2560 {
2561  struct MHD_Connection *pos;
2562  void *unused;
2563  int rc;
2564 
2565  /* first, make sure all threads are aware of shutdown; need to
2566  traverse DLLs in peace... */
2567  if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex))
2568  {
2569  MHD_PANIC ("Failed to acquire cleanup mutex\n");
2570  }
2571  for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
2572  SHUTDOWN (pos->socket_fd,
2573  (pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
2574  if (0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex))
2575  {
2576  MHD_PANIC ("Failed to release cleanup mutex\n");
2577  }
2578 
2579  /* now, collect threads */
2580  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2581  {
2582  while (NULL != (pos = daemon->connections_head))
2583  {
2584  if (0 != (rc = pthread_join (pos->pid, &unused)))
2585  {
2586  MHD_PANIC ("Failed to join a thread\n");
2587  }
2588  pos->thread_joined = MHD_YES;
2589  }
2590  }
2591 
2592  /* now that we're alone, move everyone to cleanup */
2593  while (NULL != (pos = daemon->connections_head))
2594  {
2595  MHD_connection_close (pos,
2597  DLL_remove (daemon->connections_head,
2598  daemon->connections_tail,
2599  pos);
2600  DLL_insert (daemon->cleanup_head,
2601  daemon->cleanup_tail,
2602  pos);
2603  }
2604  MHD_cleanup_connections (daemon);
2605 }
2606 
2607 
2613 void
2614 MHD_stop_daemon (struct MHD_Daemon *daemon)
2615 {
2616  void *unused;
2617  int fd;
2618  unsigned int i;
2619  int rc;
2620 
2621  if (NULL == daemon)
2622  return;
2623  daemon->shutdown = MHD_YES;
2624  fd = daemon->socket_fd;
2625  daemon->socket_fd = -1;
2626  /* Prepare workers for shutdown */
2627  if (NULL != daemon->worker_pool)
2628  {
2629  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
2630  for (i = 0; i < daemon->worker_pool_size; ++i)
2631  {
2632  daemon->worker_pool[i].shutdown = MHD_YES;
2633  daemon->worker_pool[i].socket_fd = -1;
2634  }
2635  }
2636  if (-1 != daemon->wpipe[1])
2637  {
2638  if (1 != WRITE (daemon->wpipe[1], "e", 1))
2639  MHD_PANIC ("failed to signal shutdownn via pipe");
2640  }
2641 #ifdef HAVE_LISTEN_SHUTDOWN
2642  else
2643  {
2644  /* fd must not be -1 here, otherwise we'd have used the wpipe */
2645  SHUTDOWN (fd, SHUT_RDWR);
2646  }
2647 #endif
2648 #if DEBUG_CLOSE
2649 #if HAVE_MESSAGES
2650  MHD_DLOG (daemon, "MHD listen socket shutdown\n");
2651 #endif
2652 #endif
2653 
2654 
2655  /* Signal workers to stop and clean them up */
2656  if (NULL != daemon->worker_pool)
2657  {
2658  /* MHD_USE_NO_LISTEN_SOCKET disables thread pools, hence we need to check */
2659  for (i = 0; i < daemon->worker_pool_size; ++i)
2660  {
2661  if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
2662  {
2663  MHD_PANIC ("Failed to join a thread\n");
2664  }
2665  close_all_connections (&daemon->worker_pool[i]);
2666  }
2667  free (daemon->worker_pool);
2668  }
2669  else
2670  {
2671  /* clean up master threads */
2672  if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2673  ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
2674  && (0 == daemon->worker_pool_size)))
2675  {
2676  if (0 != (rc = pthread_join (daemon->pid, &unused)))
2677  {
2678  MHD_PANIC ("Failed to join a thread\n");
2679  }
2680  }
2681  }
2682  close_all_connections (daemon);
2683  if (-1 != fd)
2684  CLOSE (fd);
2685 
2686  /* TLS clean up */
2687 #if HTTPS_SUPPORT
2688  if (0 != (daemon->options & MHD_USE_SSL))
2689  {
2690  gnutls_priority_deinit (daemon->priority_cache);
2691  if (daemon->x509_cred)
2692  gnutls_certificate_free_credentials (daemon->x509_cred);
2693  }
2694 #endif
2695 
2696 #ifdef DAUTH_SUPPORT
2697  free (daemon->nnc);
2698  pthread_mutex_destroy (&daemon->nnc_lock);
2699 #endif
2700  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2701  pthread_mutex_destroy (&daemon->cleanup_connection_mutex);
2702 
2703  if (-1 != daemon->wpipe[1])
2704  {
2705  CLOSE (daemon->wpipe[0]);
2706  CLOSE (daemon->wpipe[1]);
2707  }
2708 
2709  free (daemon);
2710 }
2711 
2712 
2723 const union MHD_DaemonInfo *
2725  enum MHD_DaemonInfoType infoType, ...)
2726 {
2727  switch (infoType)
2728  {
2730  return (const union MHD_DaemonInfo *) &daemon->socket_fd;
2731  default:
2732  return NULL;
2733  };
2734 }
2735 
2736 
2752 void
2754 {
2755  mhd_panic = cb;
2756  mhd_panic_cls = cls;
2757 }
2758 
2759 
2765 const char *
2767 {
2768  return PACKAGE_VERSION;
2769 }
2770 
2771 
2772 #ifdef __GNUC__
2773 #define ATTRIBUTE_CONSTRUCTOR __attribute__ ((constructor))
2774 #define ATTRIBUTE_DESTRUCTOR __attribute__ ((destructor))
2775 #else // !__GNUC__
2776 #define ATTRIBUTE_CONSTRUCTOR
2777 #define ATTRIBUTE_DESTRUCTOR
2778 #endif // __GNUC__
2779 
2780 #if HTTPS_SUPPORT
2781 GCRY_THREAD_OPTION_PTHREAD_IMPL;
2782 #endif
2783 
2784 
2790 {
2792  mhd_panic_cls = NULL;
2793 
2794 #ifdef WINDOWS
2795  plibc_init_utf8 ("GNU", "libmicrohttpd", 1);
2796 #endif
2797 #if HTTPS_SUPPORT
2798  gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
2799  gnutls_global_init ();
2800 #endif
2801 }
2802 
2803 
2806 {
2807 #if HTTPS_SUPPORT
2808  gnutls_global_deinit ();
2809 #endif
2810 #ifdef WINDOWS
2811  plibc_shutdown ();
2812 #endif
2813 }
2814 
2815 /* end of daemon.c */