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 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 
33 #if HTTPS_SUPPORT
34 #include "connection_https.h"
35 #include <gnutls/gnutls.h>
36 #include <gcrypt.h>
37 #endif
38 
39 #ifdef HAVE_POLL_H
40 #include <poll.h>
41 #endif
42 
43 #ifdef LINUX
44 #include <sys/sendfile.h>
45 #endif
46 
50 #ifndef WINDOWS
51 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE -4
52 #else
53 #define MHD_MAX_CONNECTIONS_DEFAULT FD_SETSIZE
54 #endif
55 
59 #define MHD_POOL_SIZE_DEFAULT (32 * 1024)
60 
65 #define DEBUG_CLOSE MHD_NO
66 
71 #define DEBUG_CONNECT MHD_NO
72 
73 #ifndef LINUX
74 #ifndef MSG_NOSIGNAL
75 #define MSG_NOSIGNAL 0
76 #endif
77 #ifndef MSG_DONTWAIT
78 #define MSG_DONTWAIT 0
79 #endif
80 #endif
81 
82 #ifdef __SYMBIAN32__
83 static void pthread_kill (int, int) {
84  // Symbian doesn't have signals. The user of the library is required to
85  // run it in an external select loop.
86  abort();
87 }
88 #endif // __SYMBIAN32__
89 
93 static void
94 mhd_panic_std(void *cls,
95  const char *file,
96  unsigned int line,
97  const char *reason)
98 {
99  abort ();
100 }
101 
102 
107 
112 
113 
121 static struct MHD_Daemon*
122 MHD_get_master (struct MHD_Daemon *daemon)
123 {
124  while (NULL != daemon->master)
125  daemon = daemon->master;
126  return daemon;
127 }
128 
132 struct MHD_IPCount
133 {
137  int family;
138 
142  union
143  {
147  struct in_addr ipv4;
148 #if HAVE_IPV6
149 
152  struct in6_addr ipv6;
153 #endif
154  } addr;
155 
159  unsigned int count;
160 };
161 
167 static void
169 {
170  if (0 != pthread_mutex_lock(&daemon->per_ip_connection_mutex))
171  {
172 #if HAVE_MESSAGES
173  MHD_DLOG (daemon, "Failed to acquire IP connection limit mutex\n");
174 #endif
175  abort();
176  }
177 }
178 
184 static void
186 {
187  if (0 != pthread_mutex_unlock(&daemon->per_ip_connection_mutex))
188  {
189 #if HAVE_MESSAGES
190  MHD_DLOG (daemon, "Failed to release IP connection limit mutex\n");
191 #endif
192  abort();
193  }
194 }
195 
205 static int
206 MHD_ip_addr_compare(const void *a1, const void *a2)
207 {
208  return memcmp (a1, a2, offsetof(struct MHD_IPCount, count));
209 }
210 
219 static int
220 MHD_ip_addr_to_key(const struct sockaddr *addr, socklen_t addrlen,
221  struct MHD_IPCount *key)
222 {
223  memset(key, 0, sizeof(*key));
224 
225  /* IPv4 addresses */
226  if (addrlen == sizeof(struct sockaddr_in))
227  {
228  const struct sockaddr_in *addr4 = (const struct sockaddr_in*)addr;
229  key->family = AF_INET;
230  memcpy (&key->addr.ipv4, &addr4->sin_addr, sizeof(addr4->sin_addr));
231  return MHD_YES;
232  }
233 
234 #if HAVE_IPV6
235  /* IPv6 addresses */
236  if (addrlen == sizeof (struct sockaddr_in6))
237  {
238  const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)addr;
239  key->family = AF_INET6;
240  memcpy (&key->addr.ipv6, &addr6->sin6_addr, sizeof(addr6->sin6_addr));
241  return MHD_YES;
242  }
243 #endif
244 
245  /* Some other address */
246  return MHD_NO;
247 }
248 
258 static int
260  const struct sockaddr *addr,
261  socklen_t addrlen)
262 {
263  struct MHD_IPCount *key;
264  void *node;
265  int result;
266 
267  daemon = MHD_get_master (daemon);
268 
269  /* Ignore if no connection limit assigned */
270  if (daemon->per_ip_connection_limit == 0)
271  return MHD_YES;
272 
273  key = malloc (sizeof(*key));
274  if (NULL == key)
275  return MHD_NO;
276 
277  /* Initialize key */
278  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, key))
279  {
280  /* Allow unhandled address types through */
281  free (key);
282  return MHD_YES;
283  }
284 
285  MHD_ip_count_lock (daemon);
286 
287  /* Search for the IP address */
288  node = (void*)TSEARCH (key, &daemon->per_ip_connection_count, MHD_ip_addr_compare);
289  if (!node)
290  {
291 #if HAVE_MESSAGES
292  MHD_DLOG(daemon,
293  "Failed to add IP connection count node\n");
294 #endif
295  MHD_ip_count_unlock (daemon);
296  free (key);
297  return MHD_NO;
298  }
299  node = *(void**)node;
300 
301  /* If we got an existing node back, free the one we created */
302  if (node != key)
303  free(key);
304  key = (struct MHD_IPCount*)node;
305 
306  /* Test if there is room for another connection; if so,
307  * increment count */
308  result = (key->count < daemon->per_ip_connection_limit);
309  if (result == MHD_YES)
310  ++key->count;
311 
312  MHD_ip_count_unlock (daemon);
313  return result;
314 }
315 
324 static void
326  const struct sockaddr *addr,
327  socklen_t addrlen)
328 {
329  struct MHD_IPCount search_key;
330  struct MHD_IPCount *found_key;
331  void *node;
332 
333  daemon = MHD_get_master (daemon);
334 
335  /* Ignore if no connection limit assigned */
336  if (daemon->per_ip_connection_limit == 0)
337  return;
338 
339  /* Initialize search key */
340  if (MHD_NO == MHD_ip_addr_to_key (addr, addrlen, &search_key))
341  return;
342 
343  MHD_ip_count_lock (daemon);
344 
345  /* Search for the IP address */
346  node = (void*)TFIND (&search_key, &daemon->per_ip_connection_count, MHD_ip_addr_compare);
347 
348  /* Something's wrong if we couldn't find an IP address
349  * that was previously added */
350  if (!node)
351  {
352 #if HAVE_MESSAGES
353  MHD_DLOG (daemon,
354  "Failed to find previously-added IP address\n");
355 #endif
356  abort();
357  }
358  found_key = (struct MHD_IPCount*)*(void**)node;
359 
360  /* Validate existing count for IP address */
361  if (found_key->count == 0)
362  {
363 #if HAVE_MESSAGES
364  MHD_DLOG (daemon,
365  "Previously-added IP address had 0 count\n");
366 #endif
367  abort();
368  }
369 
370  /* Remove the node entirely if count reduces to 0 */
371  if (--found_key->count == 0)
372  {
373  TDELETE (found_key, &daemon->per_ip_connection_count, MHD_ip_addr_compare);
374  free (found_key);
375  }
376 
377  MHD_ip_count_unlock (daemon);
378 }
379 
380 #if HTTPS_SUPPORT
381 static pthread_mutex_t MHD_gnutls_init_mutex;
382 
391 static ssize_t
392 recv_tls_adapter (struct MHD_Connection *connection, void *other, size_t i)
393 {
394  int res;
395  res = gnutls_record_recv (connection->tls_session, other, i);
396  if ( (res == GNUTLS_E_AGAIN) ||
397  (res == GNUTLS_E_INTERRUPTED) )
398  {
399  errno = EINTR;
400  return -1;
401  }
402  if (res < 0)
403  {
404  /* Likely 'GNUTLS_E_INVALID_SESSION' (client communication
405  disrupted); set errno to something caller will interpret
406  correctly as a hard error*/
407  errno = EPIPE;
408  return res;
409  }
410  return res;
411 }
412 
413 
422 static ssize_t
423 send_tls_adapter (struct MHD_Connection *connection,
424  const void *other, size_t i)
425 {
426  int res;
427  res = gnutls_record_send (connection->tls_session, other, i);
428  if ( (res == GNUTLS_E_AGAIN) ||
429  (res == GNUTLS_E_INTERRUPTED) )
430  {
431  errno = EINTR;
432  return -1;
433  }
434  return res;
435 }
436 
437 
444 static int
445 MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
446 {
447  gnutls_datum_t key;
448  gnutls_datum_t cert;
449 
450  if (daemon->https_mem_trust) {
451  cert.data = (unsigned char *) daemon->https_mem_trust;
452  cert.size = strlen(daemon->https_mem_trust);
453  if (gnutls_certificate_set_x509_trust_mem(daemon->x509_cred, &cert,
454  GNUTLS_X509_FMT_PEM) < 0) {
455 #if HAVE_MESSAGES
456  MHD_DLOG(daemon,
457  "Bad trust certificate format\n");
458 #endif
459  return -1;
460  }
461  }
462 
463  /* certificate & key loaded from memory */
464  if (daemon->https_mem_cert && daemon->https_mem_key)
465  {
466  key.data = (unsigned char *) daemon->https_mem_key;
467  key.size = strlen (daemon->https_mem_key);
468  cert.data = (unsigned char *) daemon->https_mem_cert;
469  cert.size = strlen (daemon->https_mem_cert);
470 
471  return gnutls_certificate_set_x509_key_mem (daemon->x509_cred,
472  &cert, &key,
473  GNUTLS_X509_FMT_PEM);
474  }
475 #if HAVE_MESSAGES
476  MHD_DLOG (daemon, "You need to specify a certificate and key location\n");
477 #endif
478  return -1;
479 }
480 
487 static int
488 MHD_TLS_init (struct MHD_Daemon *daemon)
489 {
490  switch (daemon->cred_type)
491  {
492  case GNUTLS_CRD_CERTIFICATE:
493  if (0 !=
494  gnutls_certificate_allocate_credentials (&daemon->x509_cred))
495  return GNUTLS_E_MEMORY_ERROR;
496  return MHD_init_daemon_certificate (daemon);
497  default:
498 #if HAVE_MESSAGES
499  MHD_DLOG (daemon,
500  "Error: invalid credentials type %d specified.\n",
501  daemon->cred_type);
502 #endif
503  return -1;
504  }
505 }
506 #endif
507 
521 int
522 MHD_get_fdset (struct MHD_Daemon *daemon,
523  fd_set * read_fd_set,
524  fd_set * write_fd_set, fd_set * except_fd_set, int *max_fd)
525 {
526  struct MHD_Connection *con_itr;
527  int fd;
528 
529  if ((daemon == NULL) || (read_fd_set == NULL) || (write_fd_set == NULL)
530  || (except_fd_set == NULL) || (max_fd == NULL)
531  || (-1 == (fd = daemon->socket_fd)) || (daemon->shutdown == MHD_YES)
532  || ((daemon->options & MHD_USE_THREAD_PER_CONNECTION) != 0)
533  || ((daemon->options & MHD_USE_POLL) != 0))
534  return MHD_NO;
535 
536  FD_SET (fd, read_fd_set);
537  /* update max file descriptor */
538  if ((*max_fd) < fd)
539  *max_fd = fd;
540 
541  con_itr = daemon->connections;
542  while (con_itr != NULL)
543  {
544  if (MHD_YES != MHD_connection_get_fdset (con_itr,
545  read_fd_set,
546  write_fd_set,
547  except_fd_set, max_fd))
548  return MHD_NO;
549  con_itr = con_itr->next;
550  }
551 #if DEBUG_CONNECT
552  MHD_DLOG (daemon, "Maximum socket in select set: %d\n", *max_fd);
553 #endif
554  return MHD_YES;
555 }
556 
564 static void *
566 {
567  struct MHD_Connection *con = data;
568  int num_ready;
569  fd_set rs;
570  fd_set ws;
571  fd_set es;
572  int max;
573  struct timeval tv;
574  unsigned int timeout;
575 #ifdef HAVE_POLL_H
576  struct MHD_Pollfd mp;
577  struct pollfd p;
578 #endif
579 
580  timeout = con->daemon->connection_timeout;
581  while ((!con->daemon->shutdown) && (con->socket_fd != -1)) {
582  tv.tv_usec = 0;
583  if ( (timeout > (time (NULL) - con->last_activity)) ||
584  (timeout == 0) )
585  {
586  /* in case we are missing the SIGALRM, keep going after
587  at most 1s; see http://lists.gnu.org/archive/html/libmicrohttpd/2009-10/msg00013.html */
588  tv.tv_sec = 1;
591  {
592  /* do not block (we're waiting for our callback to succeed) */
593  tv.tv_sec = 0;
594  }
595  }
596  else
597  {
598  tv.tv_sec = 0;
599  }
600 #ifdef HAVE_POLL_H
601  if (0 == (con->daemon->options & MHD_USE_POLL)) {
602 #else
603  {
604 #endif
605  /* use select */
606  FD_ZERO (&rs);
607  FD_ZERO (&ws);
608  FD_ZERO (&es);
609  max = 0;
610  MHD_connection_get_fdset (con, &rs, &ws, &es, &max);
611  num_ready = SELECT (max + 1, &rs, &ws, &es, &tv);
612  if (num_ready < 0) {
613  if (errno == EINTR)
614  continue;
615 #if HAVE_MESSAGES
616  MHD_DLOG (con->daemon, "Error during select (%d): `%s'\n", max,
617  STRERROR (errno));
618 #endif
619  break;
620  }
621  /* call appropriate connection handler if necessary */
622  if ((con->socket_fd != -1) && (FD_ISSET (con->socket_fd, &rs)))
623  con->read_handler (con);
624  if ((con->socket_fd != -1) && (FD_ISSET (con->socket_fd, &ws)))
625  con->write_handler (con);
626  if (con->socket_fd != -1)
627  con->idle_handler (con);
628  }
629 #ifdef HAVE_POLL_H
630  else
631  {
632  /* use poll */
633  memset(&mp, 0, sizeof (struct MHD_Pollfd));
634  MHD_connection_get_pollfd(con, &mp);
635  memset(&p, 0, sizeof (struct pollfd));
636  p.fd = mp.fd;
637  if (mp.events & MHD_POLL_ACTION_IN)
638  p.events |= POLLIN;
639  if (mp.events & MHD_POLL_ACTION_OUT)
640  p.events |= POLLOUT;
641  /* in case we are missing the SIGALRM, keep going after
642  at most 1s */
643  if (poll (&p, 1, 1000) < 0) {
644  if (errno == EINTR)
645  continue;
646 #if HAVE_MESSAGES
647  MHD_DLOG (con->daemon, "Error during poll: `%s'\n",
648  STRERROR (errno));
649 #endif
650  break;
651  }
652  if ( (con->socket_fd != -1) &&
653  (0 != (p.revents & POLLIN)) )
654  con->read_handler (con);
655  if ( (con->socket_fd != -1) &&
656  (0 != (p.revents & POLLOUT)) )
657  con->write_handler (con);
658  if (con->socket_fd != -1)
659  con->idle_handler (con);
660  if ( (con->socket_fd != -1) &&
661  (0 != (p.revents & (POLLERR | POLLHUP))) )
663  }
664 #endif
665  }
666  if (con->socket_fd != -1)
667  {
668 #if DEBUG_CLOSE
669 #if HAVE_MESSAGES
670  MHD_DLOG (con->daemon,
671  "Processing thread terminating, closing connection\n");
672 #endif
673 #endif
675  }
676  return NULL;
677 }
678 
687 static ssize_t
688 recv_param_adapter (struct MHD_Connection *connection, void *other, size_t i)
689 {
690  if (connection->socket_fd == -1)
691  return -1;
692  if (0 != (connection->daemon->options & MHD_USE_SSL))
693  return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
694  return RECV (connection->socket_fd, other, i, MSG_NOSIGNAL | MSG_DONTWAIT);
695 }
696 
705 static ssize_t
706 send_param_adapter (struct MHD_Connection *connection,
707  const void *other, size_t i)
708 {
709 #if LINUX
710  int fd;
711  off_t offset;
712  int ret;
713 #endif
714  if (connection->socket_fd == -1)
715  return -1;
716  if (0 != (connection->daemon->options & MHD_USE_SSL))
717  return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
718 #if LINUX
719  if ( (connection->write_buffer_append_offset ==
720  connection->write_buffer_send_offset) &&
721  (NULL != connection->response) &&
722  (-1 != (fd = connection->response->fd)) )
723  {
724  /* can use sendfile */
725  offset = (off_t) connection->response_write_position + connection->response->fd_off;
726  ret = sendfile (connection->socket_fd,
727  fd,
728  &offset,
729  connection->response->total_size - offset);
730  if ( (ret == -1) &&
731  (errno == EINTR) )
732  return 0;
733  return ret;
734  }
735 #endif
736  return SEND (connection->socket_fd, other, i, MSG_NOSIGNAL | MSG_DONTWAIT);
737 }
738 
739 
740 #if HTTPS_SUPPORT
741 
745 static void
746 socket_set_nonblocking (int fd)
747 {
748 #if MINGW
749  u_long mode;
750  mode = 1;
751  if (ioctlsocket (fd, FIONBIO, &mode) == SOCKET_ERROR)
752  {
753  SetErrnoFromWinsockError (WSAGetLastError ());
754 #if HAVE_MESSAGES
755  FPRINTF(stderr, "Failed to make socket non-blocking: %s\n",
756  STRERROR (errno));
757 #endif
758  }
759 #else
760 
761  /* not MINGW */
762  int flags = fcntl (fd, F_GETFL);
763  if ( (flags == -1) ||
764  (0 != fcntl (fd, F_SETFL, flags | O_NONBLOCK)) )
765  {
766 #if HAVE_MESSAGES
767  FPRINTF(stderr, "Failed to make socket non-blocking: %s\n",
768  STRERROR (errno));
769 #endif
770  }
771 #endif
772 }
773 #endif
774 
775 
785 static int
786 create_thread (pthread_t * thread,
787  const struct MHD_Daemon *daemon,
788  void *(*start_routine)(void*),
789  void *arg)
790 {
791  pthread_attr_t attr;
792  pthread_attr_t *pattr;
793  int ret;
794 
795  if (daemon->thread_stack_size != 0)
796  {
797  if (0 != (ret = pthread_attr_init (&attr)))
798  goto ERR;
799  if (0 != (ret = pthread_attr_setstacksize (&attr, daemon->thread_stack_size)))
800  {
801  pthread_attr_destroy (&attr);
802  goto ERR;
803  }
804  pattr = &attr;
805  }
806  else
807  {
808  pattr = NULL;
809  }
810  ret = pthread_create (thread, pattr,
811  start_routine, arg);
812  if (daemon->thread_stack_size != 0)
813  pthread_attr_destroy (&attr);
814  return ret;
815  ERR:
816 #if HAVE_MESSAGES
817  MHD_DLOG (daemon,
818  "Failed to set thread stack size\n");
819 #endif
820  errno = EINVAL;
821  return ret;
822 }
823 
824 
825 
834 static int
836 {
837  struct MHD_Connection *connection;
838 #if HAVE_INET6
839  struct sockaddr_in6 addrstorage;
840 #else
841  struct sockaddr_in addrstorage;
842 #endif
843  struct sockaddr *addr = (struct sockaddr *) &addrstorage;
844  socklen_t addrlen;
845  int s;
846  int res_thread_create;
847 #if OSX
848  static int on = 1;
849 #endif
850 
851  addrlen = sizeof (addrstorage);
852  memset (addr, 0, sizeof (addrstorage));
853 
854  s = ACCEPT (daemon->socket_fd, addr, &addrlen);
855  if ((s == -1) || (addrlen <= 0))
856  {
857 #if HAVE_MESSAGES
858  /* This could be a common occurance with multiple worker threads */
859  if ((EAGAIN != errno) && (EWOULDBLOCK != errno))
860  MHD_DLOG (daemon, "Error accepting connection: %s\n", STRERROR (errno));
861 #endif
862  if (s != -1)
863  {
864  SHUTDOWN (s, SHUT_RDWR);
865  CLOSE (s);
866  /* just in case */
867  }
868  return MHD_NO;
869  }
870 #ifndef WINDOWS
871  if ( (s >= FD_SETSIZE) &&
872  (0 == (daemon->options & MHD_USE_POLL)) )
873  {
874 #if HAVE_MESSAGES
875  MHD_DLOG (daemon,
876  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
877  s,
878  FD_SETSIZE);
879 #endif
880  CLOSE (s);
881  return MHD_NO;
882  }
883 #endif
884 
885 
886 #if HAVE_MESSAGES
887 #if DEBUG_CONNECT
888  MHD_DLOG (daemon, "Accepted connection on socket %d\n", s);
889 #endif
890 #endif
891  if ((daemon->max_connections == 0)
892  || (MHD_ip_limit_add (daemon, addr, addrlen) == MHD_NO))
893  {
894  /* above connection limit - reject */
895 #if HAVE_MESSAGES
896  MHD_DLOG (daemon,
897  "Server reached connection limit (closing inbound connection)\n");
898 #endif
899  SHUTDOWN (s, SHUT_RDWR);
900  CLOSE (s);
901  return MHD_NO;
902  }
903 
904  /* apply connection acceptance policy if present */
905  if ((daemon->apc != NULL)
906  && (MHD_NO == daemon->apc (daemon->apc_cls, addr, addrlen)))
907  {
908 #if DEBUG_CLOSE
909 #if HAVE_MESSAGES
910  MHD_DLOG (daemon, "Connection rejected, closing connection\n");
911 #endif
912 #endif
913  SHUTDOWN (s, SHUT_RDWR);
914  CLOSE (s);
915  MHD_ip_limit_del (daemon, addr, addrlen);
916  return MHD_YES;
917  }
918 #if OSX
919 #ifdef SOL_SOCKET
920 #ifdef SO_NOSIGPIPE
921  setsockopt (s, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof (on));
922 #endif
923 #endif
924 #endif
925  connection = malloc (sizeof (struct MHD_Connection));
926  if (NULL == connection)
927  {
928 #if HAVE_MESSAGES
929  MHD_DLOG (daemon, "Error allocating memory: %s\n", STRERROR (errno));
930 #endif
931  SHUTDOWN (s, SHUT_RDWR);
932  CLOSE (s);
933  MHD_ip_limit_del (daemon, addr, addrlen);
934  return MHD_NO;
935  }
936  memset (connection, 0, sizeof (struct MHD_Connection));
937  connection->pool = NULL;
938  connection->addr = malloc (addrlen);
939  if (connection->addr == NULL)
940  {
941 #if HAVE_MESSAGES
942  MHD_DLOG (daemon, "Error allocating memory: %s\n", STRERROR (errno));
943 #endif
944  SHUTDOWN (s, SHUT_RDWR);
945  CLOSE (s);
946  MHD_ip_limit_del (daemon, addr, addrlen);
947  free (connection);
948  return MHD_NO;
949  }
950  memcpy (connection->addr, addr, addrlen);
951  connection->addr_len = addrlen;
952  connection->socket_fd = s;
953  connection->daemon = daemon;
954  connection->last_activity = time (NULL);
955 
956  /* set default connection handlers */
957  MHD_set_http_callbacks_ (connection);
958  connection->recv_cls = &recv_param_adapter;
959  connection->send_cls = &send_param_adapter;
960 #if HTTPS_SUPPORT
961  if (0 != (daemon->options & MHD_USE_SSL))
962  {
963  connection->recv_cls = &recv_tls_adapter;
964  connection->send_cls = &send_tls_adapter;
965  connection->state = MHD_TLS_CONNECTION_INIT;
966  MHD_set_https_callbacks (connection);
967  gnutls_init (&connection->tls_session, GNUTLS_SERVER);
968  gnutls_priority_set (connection->tls_session,
969  daemon->priority_cache);
970  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
971  {
972  /* use non-blocking IO for gnutls */
973  socket_set_nonblocking (connection->socket_fd);
974  }
975  switch (connection->daemon->cred_type)
976  {
977  /* set needed credentials for certificate authentication. */
978  case GNUTLS_CRD_CERTIFICATE:
979  gnutls_credentials_set (connection->tls_session,
980  GNUTLS_CRD_CERTIFICATE,
981  connection->daemon->x509_cred);
982  break;
983  default:
984 #if HAVE_MESSAGES
985  MHD_DLOG (connection->daemon,
986  "Failed to setup TLS credentials: unknown credential type %d\n",
987  connection->daemon->cred_type);
988 #endif
989  SHUTDOWN (s, SHUT_RDWR);
990  CLOSE (s);
991  MHD_ip_limit_del (daemon, addr, addrlen);
992  free (connection->addr);
993  free (connection);
994  mhd_panic (mhd_panic_cls, __FILE__, __LINE__,
995 #if HAVE_MESSAGES
996  "Unknown credential type"
997 #else
998  NULL
999 #endif
1000  );
1001  return MHD_NO;
1002  }
1003  gnutls_transport_set_ptr (connection->tls_session,
1004  (gnutls_transport_ptr_t) connection);
1005  gnutls_transport_set_pull_function (connection->tls_session,
1006  (gnutls_pull_func) &
1008  gnutls_transport_set_push_function (connection->tls_session,
1009  (gnutls_push_func) &
1011 
1012  if (daemon->https_mem_trust){
1013  gnutls_certificate_server_set_request(connection->tls_session, GNUTLS_CERT_REQUEST);
1014  }
1015  }
1016 #endif
1017 
1018  /* attempt to create handler thread */
1019  if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1020  {
1021  res_thread_create = create_thread (&connection->pid, daemon,
1022  &MHD_handle_connection, connection);
1023  if (res_thread_create != 0)
1024  {
1025 #if HAVE_MESSAGES
1026  MHD_DLOG (daemon, "Failed to create a thread: %s\n",
1027  STRERROR (res_thread_create));
1028 #endif
1029  SHUTDOWN (s, SHUT_RDWR);
1030  CLOSE (s);
1031  MHD_ip_limit_del (daemon, addr, addrlen);
1032  free (connection->addr);
1033  free (connection);
1034  return MHD_NO;
1035  }
1036  }
1037  connection->next = daemon->connections;
1038  daemon->connections = connection;
1039  daemon->max_connections--;
1040  return MHD_YES;
1041 }
1042 
1050 static void
1052 {
1053  struct MHD_Connection *pos;
1054  struct MHD_Connection *prev;
1055  void *unused;
1056  int rc;
1057 
1058  pos = daemon->connections;
1059  prev = NULL;
1060  while (pos != NULL)
1061  {
1062  if ((pos->socket_fd == -1) ||
1063  (((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1064  (daemon->shutdown) && (pos->socket_fd != -1))))
1065  {
1066  if (prev == NULL)
1067  daemon->connections = pos->next;
1068  else
1069  prev->next = pos->next;
1070  if (0 != (pos->daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1071  {
1072  pthread_kill (pos->pid, SIGALRM);
1073  if (0 != (rc = pthread_join (pos->pid, &unused)))
1074  {
1075 #if HAVE_MESSAGES
1076  MHD_DLOG (daemon, "Failed to join a thread: %s\n",
1077  STRERROR (rc));
1078 #endif
1079  abort();
1080  }
1081  }
1082  MHD_pool_destroy (pos->pool);
1083 #if HTTPS_SUPPORT
1084  if (pos->tls_session != NULL)
1085  gnutls_deinit (pos->tls_session);
1086 #endif
1087  MHD_ip_limit_del (daemon, (struct sockaddr*)pos->addr, pos->addr_len);
1088  if (pos->response != NULL)
1089  {
1091  pos->response = NULL;
1092  }
1093  free (pos->addr);
1094  free (pos);
1095  daemon->max_connections++;
1096  if (prev == NULL)
1097  pos = daemon->connections;
1098  else
1099  pos = prev->next;
1100  continue;
1101  }
1102  prev = pos;
1103  pos = pos->next;
1104  }
1105 }
1106 
1119 int
1120 MHD_get_timeout (struct MHD_Daemon *daemon, unsigned MHD_LONG_LONG *timeout)
1121 {
1122  time_t earliest_deadline;
1123  time_t now;
1124  struct MHD_Connection *pos;
1125  unsigned int dto;
1126 
1127  dto = daemon->connection_timeout;
1128  if (0 == dto)
1129  return MHD_NO;
1130  pos = daemon->connections;
1131  if (pos == NULL)
1132  return MHD_NO; /* no connections */
1133  now = time (NULL);
1134  /* start with conservative estimate */
1135  earliest_deadline = now + dto;
1136  while (pos != NULL)
1137  {
1138  if (earliest_deadline > pos->last_activity + dto)
1139  earliest_deadline = pos->last_activity + dto;
1140 #if HTTPS_SUPPORT
1141  if ( (0 != (daemon->options & MHD_USE_SSL)) &&
1142  (0 != gnutls_record_check_pending (pos->tls_session)) )
1143  earliest_deadline = now;
1144 #endif
1145  pos = pos->next;
1146  }
1147  if (earliest_deadline < now)
1148  *timeout = 0;
1149  else
1150  *timeout = (earliest_deadline - now);
1151  return MHD_YES;
1152 }
1153 
1154 
1162 static int
1163 MHD_select (struct MHD_Daemon *daemon, int may_block)
1164 {
1165  struct MHD_Connection *pos;
1166  int num_ready;
1167  fd_set rs;
1168  fd_set ws;
1169  fd_set es;
1170  int max;
1171  struct timeval timeout;
1172  unsigned MHD_LONG_LONG ltimeout;
1173  int ds;
1174 
1175  timeout.tv_sec = 0;
1176  timeout.tv_usec = 0;
1177  if (daemon->shutdown == MHD_YES)
1178  return MHD_NO;
1179  FD_ZERO (&rs);
1180  FD_ZERO (&ws);
1181  FD_ZERO (&es);
1182  max = 0;
1183 
1184  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1185  {
1186  /* single-threaded, go over everything */
1187  if (MHD_NO == MHD_get_fdset (daemon, &rs, &ws, &es, &max))
1188  return MHD_NO;
1189 
1190  /* If we're at the connection limit, no need to
1191  accept new connections. */
1192  if ( (daemon->max_connections == 0) && (daemon->socket_fd != -1) )
1193  FD_CLR(daemon->socket_fd, &rs);
1194  }
1195  else
1196  {
1197  /* accept only, have one thread per connection */
1198  max = daemon->socket_fd;
1199  if (max == -1)
1200  return MHD_NO;
1201  FD_SET (max, &rs);
1202  }
1203 
1204  /* in case we are missing the SIGALRM, keep going after
1205  at most 1s; see http://lists.gnu.org/archive/html/libmicrohttpd/2009-10/msg00013.html */
1206  timeout.tv_usec = 0;
1207  timeout.tv_sec = 1;
1208  if (may_block == MHD_NO)
1209  {
1210  timeout.tv_usec = 0;
1211  timeout.tv_sec = 0;
1212  }
1213  else
1214  {
1215  /* ltimeout is in ms */
1216  if ( (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) &&
1217  (ltimeout < 1000) )
1218  {
1219  timeout.tv_usec = ltimeout * 1000;
1220  timeout.tv_sec = 0;
1221  }
1222  }
1223  num_ready = SELECT (max + 1, &rs, &ws, &es, &timeout);
1224 
1225  if (daemon->shutdown == MHD_YES)
1226  return MHD_NO;
1227  if (num_ready < 0)
1228  {
1229  if (errno == EINTR)
1230  return MHD_YES;
1231 #if HAVE_MESSAGES
1232  MHD_DLOG (daemon, "select failed: %s\n", STRERROR (errno));
1233 #endif
1234  return MHD_NO;
1235  }
1236  ds = daemon->socket_fd;
1237  if (ds == -1)
1238  return MHD_YES;
1239 
1240  /* select connection thread handling type */
1241  if (FD_ISSET (ds, &rs))
1242  MHD_accept_connection (daemon);
1243  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1244  {
1245  /* do not have a thread per connection, process all connections now */
1246  pos = daemon->connections;
1247  while (pos != NULL)
1248  {
1249  ds = pos->socket_fd;
1250  if (ds != -1)
1251  {
1252  /* TODO call con->read handler */
1253  if (FD_ISSET (ds, &rs))
1254  pos->read_handler (pos);
1255  if ((pos->socket_fd != -1) && (FD_ISSET (ds, &ws)))
1256  pos->write_handler (pos);
1257  if (pos->socket_fd != -1)
1258  pos->idle_handler (pos);
1259  }
1260  pos = pos->next;
1261  }
1262  }
1263  return MHD_YES;
1264 }
1265 
1271 static int
1272 MHD_poll (struct MHD_Daemon *daemon)
1273 {
1274 #ifdef HAVE_POLL_H
1275  struct pollfd p;
1276 
1277  if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1278  return MHD_NO;
1279  p.fd = daemon->socket_fd;
1280  p.events = POLLIN;
1281  p.revents = 0;
1282 
1283  if (poll(&p, 1, 1000) < 0) {
1284  if (errno == EINTR)
1285  return MHD_YES;
1286 #if HAVE_MESSAGES
1287  MHD_DLOG (daemon, "poll failed: %s\n", STRERROR (errno));
1288 #endif
1289  return MHD_NO;
1290  }
1291  /* handle shutdown cases */
1292  if (daemon->shutdown == MHD_YES)
1293  return MHD_NO;
1294  if (daemon->socket_fd < 0)
1295  return MHD_YES;
1296  if (0 != (p.revents & POLLIN))
1297  MHD_accept_connection (daemon);
1298  return MHD_YES;
1299 #else
1300  return MHD_NO;
1301 #endif
1302 }
1303 
1304 
1315 int
1316 MHD_run (struct MHD_Daemon *daemon)
1317 {
1318  if ((daemon->shutdown != MHD_NO) || (0 != (daemon->options
1320  || (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)))
1321  return MHD_NO;
1322  MHD_select (daemon, MHD_NO);
1323  MHD_cleanup_connections (daemon);
1324  return MHD_YES;
1325 }
1326 
1327 
1335 static void *
1337 {
1338  struct MHD_Daemon *daemon = cls;
1339  while (daemon->shutdown == MHD_NO)
1340  {
1341  if ((daemon->options & MHD_USE_POLL) == 0)
1342  MHD_select (daemon, MHD_YES);
1343  else
1344  MHD_poll(daemon);
1345  MHD_cleanup_connections (daemon);
1346  }
1347  return NULL;
1348 }
1349 
1350 
1362 struct MHD_Daemon *
1364  uint16_t port,
1366  void *apc_cls,
1367  MHD_AccessHandlerCallback dh, void *dh_cls, ...)
1368 {
1369  struct MHD_Daemon *ret;
1370  va_list ap;
1371 
1372  va_start (ap, dh_cls);
1373  ret = MHD_start_daemon_va (options, port, apc, apc_cls, dh, dh_cls, ap);
1374  va_end (ap);
1375  return ret;
1376 }
1377 
1378 
1379 typedef void (*VfprintfFunctionPointerType)(void *, const char *, va_list);
1380 
1381 
1390 static int
1391 parse_options_va (struct MHD_Daemon *daemon,
1392  const struct sockaddr **servaddr,
1393  va_list ap);
1394 
1395 
1404 static int
1405 parse_options (struct MHD_Daemon *daemon,
1406  const struct sockaddr **servaddr,
1407  ...)
1408 {
1409  va_list ap;
1410  int ret;
1411 
1412  va_start (ap, servaddr);
1413  ret = parse_options_va (daemon, servaddr, ap);
1414  va_end (ap);
1415  return ret;
1416 }
1417 
1418 
1427 static int
1429  const struct sockaddr **servaddr,
1430  va_list ap)
1431 {
1432  enum MHD_OPTION opt;
1433  struct MHD_OptionItem *oa;
1434  unsigned int i;
1435 #if HTTPS_SUPPORT
1436  int ret;
1437  const char *pstr;
1438 #endif
1439 
1440  while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
1441  {
1442  switch (opt)
1443  {
1445  daemon->pool_size = va_arg (ap, size_t);
1446  break;
1448  daemon->max_connections = va_arg (ap, unsigned int);
1449  break;
1451  daemon->connection_timeout = va_arg (ap, unsigned int);
1452  break;
1454  daemon->notify_completed =
1455  va_arg (ap, MHD_RequestCompletedCallback);
1456  daemon->notify_completed_cls = va_arg (ap, void *);
1457  break;
1459  daemon->per_ip_connection_limit = va_arg (ap, unsigned int);
1460  break;
1461  case MHD_OPTION_SOCK_ADDR:
1462  *servaddr = va_arg (ap, const struct sockaddr *);
1463  break;
1465  daemon->uri_log_callback =
1466  va_arg (ap, LogCallback);
1467  daemon->uri_log_callback_cls = va_arg (ap, void *);
1468  break;
1470  daemon->worker_pool_size = va_arg (ap, unsigned int);
1471  if (daemon->worker_pool_size >= SIZE_MAX / sizeof (struct MHD_Daemon))
1472  {
1473 #if HAVE_MESSAGES
1474  FPRINTF (stderr,
1475  "Specified thread pool size (%u) too big\n",
1476  daemon->worker_pool_size);
1477 #endif
1478  return MHD_NO;
1479  }
1480  break;
1481 #if HTTPS_SUPPORT
1483  if (0 != (daemon->options & MHD_USE_SSL))
1484  daemon->https_mem_key = va_arg (ap, const char *);
1485 #if HAVE_MESSAGES
1486  else
1487  FPRINTF (stderr,
1488  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
1489  opt);
1490 #endif
1491  break;
1493  if (0 != (daemon->options & MHD_USE_SSL))
1494  daemon->https_mem_cert = va_arg (ap, const char *);
1495 #if HAVE_MESSAGES
1496  else
1497  FPRINTF (stderr,
1498  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
1499  opt);
1500 #endif
1501  break;
1503  if (0 != (daemon->options & MHD_USE_SSL))
1504  daemon->https_mem_trust = va_arg (ap, const char *);
1505 #if HAVE_MESSAGES
1506  else
1507  FPRINTF (stderr,
1508  "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
1509  opt);
1510 #endif
1511  break;
1513  daemon->cred_type = va_arg (ap, gnutls_credentials_type_t);
1514  break;
1516  ret = gnutls_priority_init (&daemon->priority_cache,
1517  pstr = va_arg (ap, const char*),
1518  NULL);
1519 #if HAVE_MESSAGES
1520  if (ret != GNUTLS_E_SUCCESS)
1521  FPRINTF (stderr,
1522  "Setting priorities to `%s' failed: %s\n",
1523  pstr,
1524  gnutls_strerror (ret));
1525 #endif
1526  if (ret != GNUTLS_E_SUCCESS)
1527  return MHD_NO;
1528  break;
1529 #endif
1530 #ifdef DAUTH_SUPPORT
1532  daemon->digest_auth_rand_size = va_arg (ap, size_t);
1533  daemon->digest_auth_random = va_arg (ap, const char *);
1534  break;
1536  daemon->nonce_nc_size = va_arg (ap, unsigned int);
1537  break;
1538 #endif
1540  daemon->socket_fd = va_arg (ap, int);
1541  break;
1543 #if HAVE_MESSAGES
1544  daemon->custom_error_log =
1545  va_arg (ap, VfprintfFunctionPointerType);
1546  daemon->custom_error_log_cls = va_arg (ap, void *);
1547 #else
1548  va_arg (ap, VfprintfFunctionPointerType);
1549  va_arg (ap, void *);
1550 #endif
1551  break;
1553  daemon->thread_stack_size = va_arg (ap, size_t);
1554  break;
1555  case MHD_OPTION_ARRAY:
1556  oa = va_arg (ap, struct MHD_OptionItem*);
1557  i = 0;
1558  while (MHD_OPTION_END != (opt = oa[i].option))
1559  {
1560  switch (opt)
1561  {
1562  /* all options taking 'size_t' */
1565  if (MHD_YES != parse_options (daemon,
1566  servaddr,
1567  opt,
1568  (size_t) oa[i].value,
1569  MHD_OPTION_END))
1570  return MHD_NO;
1571  break;
1572  /* all options taking 'unsigned int' */
1578  if (MHD_YES != parse_options (daemon,
1579  servaddr,
1580  opt,
1581  (unsigned int) oa[i].value,
1582  MHD_OPTION_END))
1583  return MHD_NO;
1584  break;
1585  /* all options taking 'int' or 'enum' */
1588  if (MHD_YES != parse_options (daemon,
1589  servaddr,
1590  opt,
1591  (int) oa[i].value,
1592  MHD_OPTION_END))
1593  return MHD_NO;
1594  break;
1595  /* all options taking one pointer */
1596  case MHD_OPTION_SOCK_ADDR:
1601  case MHD_OPTION_ARRAY:
1602  if (MHD_YES != parse_options (daemon,
1603  servaddr,
1604  opt,
1605  oa[i].ptr_value,
1606  MHD_OPTION_END))
1607  return MHD_NO;
1608  break;
1609  /* all options taking two pointers */
1614  if (MHD_YES != parse_options (daemon,
1615  servaddr,
1616  opt,
1617  (void *) oa[i].value,
1618  oa[i].ptr_value,
1619  MHD_OPTION_END))
1620  return MHD_NO;
1621  break;
1622  /* options taking size_t-number followed by pointer */
1624  if (MHD_YES != parse_options (daemon,
1625  servaddr,
1626  opt,
1627  (size_t) oa[i].value,
1628  oa[i].ptr_value,
1629  MHD_OPTION_END))
1630  return MHD_NO;
1631  break;
1632  default:
1633  return MHD_NO;
1634  }
1635  i++;
1636  }
1637  break;
1639  daemon->unescape_callback =
1640  va_arg (ap, UnescapeCallback);
1641  daemon->unescape_callback_cls = va_arg (ap, void *);
1642  break;
1643  default:
1644 #if HAVE_MESSAGES
1645  if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
1647  {
1648  FPRINTF (stderr,
1649  "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
1650  opt);
1651  }
1652  else
1653  {
1654  FPRINTF (stderr,
1655  "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
1656  opt);
1657  }
1658 #endif
1659  return MHD_NO;
1660  }
1661  }
1662  return MHD_YES;
1663 }
1664 
1665 
1677 struct MHD_Daemon *
1679  uint16_t port,
1681  void *apc_cls,
1682  MHD_AccessHandlerCallback dh, void *dh_cls,
1683  va_list ap)
1684 {
1685  const int on = 1;
1686  struct MHD_Daemon *retVal;
1687  int socket_fd;
1688  struct sockaddr_in servaddr4;
1689 #if HAVE_INET6
1690  struct sockaddr_in6 servaddr6;
1691 #endif
1692  const struct sockaddr *servaddr = NULL;
1693  socklen_t addrlen;
1694  unsigned int i;
1695  int res_thread_create;
1696 
1697  if ((port == 0) || (dh == NULL))
1698  return NULL;
1699  retVal = malloc (sizeof (struct MHD_Daemon));
1700  if (retVal == NULL)
1701  return NULL;
1702  memset (retVal, 0, sizeof (struct MHD_Daemon));
1703 #if HTTPS_SUPPORT
1704  if (options & MHD_USE_SSL)
1705  {
1706  gnutls_priority_init (&retVal->priority_cache,
1707  "NORMAL",
1708  NULL);
1709  }
1710 #endif
1711  retVal->socket_fd = -1;
1712  retVal->options = (enum MHD_OPTION)options;
1713  retVal->port = port;
1714  retVal->apc = apc;
1715  retVal->apc_cls = apc_cls;
1716  retVal->default_handler = dh;
1717  retVal->default_handler_cls = dh_cls;
1719  retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
1721  retVal->connection_timeout = 0; /* no timeout */
1722 #ifdef DAUTH_SUPPORT
1723  retVal->digest_auth_rand_size = 0;
1724  retVal->digest_auth_random = NULL;
1725  retVal->nonce_nc_size = 4; /* tiny */
1726 #endif
1727 #if HAVE_MESSAGES
1728  retVal->custom_error_log =
1729  (void (*)(void *, const char *, va_list)) &vfprintf;
1730  retVal->custom_error_log_cls = stderr;
1731 #endif
1732 #if HTTPS_SUPPORT
1733  if (options & MHD_USE_SSL)
1734  {
1735  /* lock MHD_gnutls_global mutex since it uses reference counting */
1736  if (0 != pthread_mutex_lock (&MHD_gnutls_init_mutex))
1737  {
1738 #if HAVE_MESSAGES
1739  MHD_DLOG (retVal, "Failed to aquire gnutls mutex\n");
1740 #endif
1741  mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
1742  }
1743  if (0 != pthread_mutex_unlock (&MHD_gnutls_init_mutex))
1744  {
1745 #if HAVE_MESSAGES
1746  MHD_DLOG (retVal, "Failed to release gnutls mutex\n");
1747 #endif
1748  mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
1749  }
1750  retVal->cred_type = GNUTLS_CRD_CERTIFICATE;
1751  }
1752 #endif
1753 
1754  if (MHD_YES != parse_options_va (retVal, &servaddr, ap))
1755  {
1756  free (retVal);
1757  return NULL;
1758  }
1759 
1760 #ifdef DAUTH_SUPPORT
1761  if (retVal->nonce_nc_size > 0)
1762  {
1763  if ( ( (size_t) (retVal->nonce_nc_size * sizeof(struct MHD_NonceNc))) /
1764  sizeof(struct MHD_NonceNc) != retVal->nonce_nc_size)
1765  {
1766 #if HAVE_MESSAGES
1767  MHD_DLOG (retVal,
1768  "Specified value for NC_SIZE too large\n");
1769 #endif
1770  free (retVal);
1771  return NULL;
1772  }
1773  retVal->nnc = malloc (retVal->nonce_nc_size * sizeof(struct MHD_NonceNc));
1774  if (NULL == retVal->nnc)
1775  {
1776 #if HAVE_MESSAGES
1777  MHD_DLOG (retVal,
1778  "Failed to allocate memory for nonce-nc map: %s\n",
1779  STRERROR (errno));
1780 #endif
1781  free (retVal);
1782  return NULL;
1783  }
1784  }
1785  if (0 != pthread_mutex_init (&retVal->nnc_lock, NULL))
1786  {
1787 #if HAVE_MESSAGES
1788  MHD_DLOG (retVal,
1789  "MHD failed to initialize nonce-nc mutex\n");
1790 #endif
1791  free (retVal);
1792  return NULL;
1793  }
1794 #endif
1795 
1796  /* poll support currently only works with MHD_USE_THREAD_PER_CONNECTION */
1797  if ( (0 != (options & MHD_USE_POLL)) &&
1798  (0 == (options & MHD_USE_THREAD_PER_CONNECTION)) )
1799  {
1800 #if HAVE_MESSAGES
1801  MHD_DLOG (retVal,
1802  "MHD poll support only works with MHD_USE_THREAD_PER_CONNECTION\n");
1803 #endif
1804 #if DAUTH_SUPPORT
1805  free (retVal->nnc);
1806  pthread_mutex_destroy (&retVal->nnc_lock);
1807 #endif
1808  free (retVal);
1809  return NULL;
1810  }
1811 
1812  /* Thread pooling currently works only with internal select thread model */
1813  if ( (0 == (options & MHD_USE_SELECT_INTERNALLY)) &&
1814  (retVal->worker_pool_size > 0) )
1815  {
1816 #if HAVE_MESSAGES
1817  MHD_DLOG (retVal,
1818  "MHD thread pooling only works with MHD_USE_SELECT_INTERNALLY\n");
1819 #endif
1820  free (retVal);
1821  return NULL;
1822  }
1823 
1824 #ifdef __SYMBIAN32__
1825  if (0 != (options & (MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION)))
1826  {
1827 #if HAVE_MESSAGES
1828  MHD_DLOG (retVal,
1829  "Threaded operations are not supported on Symbian.\n");
1830 #endif
1831  free (retVal);
1832  return NULL;
1833  }
1834 #endif
1835  if (retVal->socket_fd == -1)
1836  {
1837  if ((options & MHD_USE_IPv6) != 0)
1838 #if HAVE_INET6
1839  socket_fd = SOCKET (PF_INET6, SOCK_STREAM, 0);
1840 #else
1841  {
1842 #if HAVE_MESSAGES
1843  MHD_DLOG (retVal,
1844  "AF_INET6 not supported\n");
1845 #endif
1846  free (retVal);
1847  return NULL;
1848  }
1849 #endif
1850  else
1851  socket_fd = SOCKET (PF_INET, SOCK_STREAM, 0);
1852  if (socket_fd == -1)
1853  {
1854 #if HAVE_MESSAGES
1855  if ((options & MHD_USE_DEBUG) != 0)
1856  MHD_DLOG (retVal,
1857  "Call to socket failed: %s\n",
1858  STRERROR (errno));
1859 #endif
1860  free (retVal);
1861  return NULL;
1862  }
1863  if ((SETSOCKOPT (socket_fd,
1864  SOL_SOCKET,
1865  SO_REUSEADDR,
1866  &on, sizeof (on)) < 0) && ((options & MHD_USE_DEBUG) != 0))
1867  {
1868 #if HAVE_MESSAGES
1869  MHD_DLOG (retVal,
1870  "setsockopt failed: %s\n",
1871  STRERROR (errno));
1872 #endif
1873  }
1874 
1875  /* check for user supplied sockaddr */
1876 #if HAVE_INET6
1877  if ((options & MHD_USE_IPv6) != 0)
1878  addrlen = sizeof (struct sockaddr_in6);
1879  else
1880 #endif
1881  addrlen = sizeof (struct sockaddr_in);
1882  if (NULL == servaddr)
1883  {
1884 #if HAVE_INET6
1885  if ((options & MHD_USE_IPv6) != 0)
1886  {
1887  memset (&servaddr6, 0, sizeof (struct sockaddr_in6));
1888  servaddr6.sin6_family = AF_INET6;
1889  servaddr6.sin6_port = htons (port);
1890  servaddr = (struct sockaddr *) &servaddr6;
1891  }
1892  else
1893 #endif
1894  {
1895  memset (&servaddr4, 0, sizeof (struct sockaddr_in));
1896  servaddr4.sin_family = AF_INET;
1897  servaddr4.sin_port = htons (port);
1898  servaddr = (struct sockaddr *) &servaddr4;
1899  }
1900  }
1901  retVal->socket_fd = socket_fd;
1902 
1903  if ((options & MHD_USE_IPv6) != 0)
1904  {
1905 #ifdef IPPROTO_IPV6
1906 #ifdef IPV6_V6ONLY
1907  /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options"
1908  (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx);
1909  and may also be missing on older POSIX systems; good luck if you have any of those,
1910  your IPv6 socket may then also bind against IPv4... */
1911 #ifndef WINDOWS
1912  const int on = 1;
1913  setsockopt (socket_fd,
1914  IPPROTO_IPV6, IPV6_V6ONLY,
1915  &on, sizeof (on));
1916 #else
1917  const char on = 1;
1918  setsockopt (socket_fd,
1919  IPPROTO_IPV6, IPV6_V6ONLY,
1920  &on, sizeof (on));
1921 #endif
1922 #endif
1923 #endif
1924  }
1925  if (BIND (socket_fd, servaddr, addrlen) == -1)
1926  {
1927 #if HAVE_MESSAGES
1928  if ((options & MHD_USE_DEBUG) != 0)
1929  MHD_DLOG (retVal,
1930  "Failed to bind to port %u: %s\n",
1931  (unsigned int) port,
1932  STRERROR (errno));
1933 #endif
1934  CLOSE (socket_fd);
1935  free (retVal);
1936  return NULL;
1937  }
1938 
1939  if (LISTEN (socket_fd, 20) < 0)
1940  {
1941 #if HAVE_MESSAGES
1942  if ((options & MHD_USE_DEBUG) != 0)
1943  MHD_DLOG (retVal,
1944  "Failed to listen for connections: %s\n",
1945  STRERROR (errno));
1946 #endif
1947  CLOSE (socket_fd);
1948  free (retVal);
1949  return NULL;
1950  }
1951  }
1952  else
1953  {
1954  socket_fd = retVal->socket_fd;
1955  }
1956 #ifndef WINDOWS
1957  if ( (socket_fd >= FD_SETSIZE) &&
1958  (0 == (options & MHD_USE_POLL)) )
1959  {
1960 #if HAVE_MESSAGES
1961  if ((options & MHD_USE_DEBUG) != 0)
1962  MHD_DLOG (retVal,
1963  "Socket descriptor larger than FD_SETSIZE: %d > %d\n",
1964  socket_fd,
1965  FD_SETSIZE);
1966 #endif
1967  CLOSE (socket_fd);
1968  free (retVal);
1969  return NULL;
1970  }
1971 #endif
1972 
1973  if (0 != pthread_mutex_init (&retVal->per_ip_connection_mutex, NULL))
1974  {
1975 #if HAVE_MESSAGES
1976  MHD_DLOG (retVal,
1977  "MHD failed to initialize IP connection limit mutex\n");
1978 #endif
1979  CLOSE (socket_fd);
1980  free (retVal);
1981  return NULL;
1982  }
1983 
1984 #if HTTPS_SUPPORT
1985  /* initialize HTTPS daemon certificate aspects & send / recv functions */
1986  if ((0 != (options & MHD_USE_SSL)) && (0 != MHD_TLS_init (retVal)))
1987  {
1988 #if HAVE_MESSAGES
1989  MHD_DLOG (retVal,
1990  "Failed to initialize TLS support\n");
1991 #endif
1992  CLOSE (socket_fd);
1993 #ifdef DAUTH_SUPPORT
1994  pthread_mutex_destroy (&retVal->nnc_lock);
1995  free (retVal->nnc);
1996 #endif
1997  pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
1998  free (retVal);
1999  return NULL;
2000  }
2001 #endif
2002  if ( ( (0 != (options & MHD_USE_THREAD_PER_CONNECTION)) ||
2003  ( (0 != (options & MHD_USE_SELECT_INTERNALLY)) &&
2004  (0 == retVal->worker_pool_size)) ) &&
2005  (0 != (res_thread_create =
2006  create_thread (&retVal->pid, retVal, &MHD_select_thread, retVal))))
2007  {
2008 #if HAVE_MESSAGES
2009  MHD_DLOG (retVal,
2010  "Failed to create listen thread: %s\n",
2011  STRERROR (res_thread_create));
2012 #endif
2013 #ifdef DAUTH_SUPPORT
2014  pthread_mutex_destroy (&retVal->nnc_lock);
2015  free (retVal->nnc);
2016 #endif
2017  pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
2018  free (retVal);
2019  CLOSE (socket_fd);
2020  return NULL;
2021  }
2022  if (retVal->worker_pool_size > 0)
2023  {
2024 #ifndef MINGW
2025  int sk_flags;
2026 #else
2027  unsigned long sk_flags;
2028 #endif
2029 
2030  /* Coarse-grained count of connections per thread (note error
2031  * due to integer division). Also keep track of how many
2032  * connections are leftover after an equal split. */
2033  unsigned int conns_per_thread = retVal->max_connections
2034  / retVal->worker_pool_size;
2035  unsigned int leftover_conns = retVal->max_connections
2036  % retVal->worker_pool_size;
2037 
2038  i = 0; /* we need this in case fcntl or malloc fails */
2039 
2040  /* Accept must be non-blocking. Multiple children may wake up
2041  * to handle a new connection, but only one will win the race.
2042  * The others must immediately return. */
2043 #ifndef MINGW
2044  sk_flags = fcntl (socket_fd, F_GETFL);
2045  if (sk_flags < 0)
2046  goto thread_failed;
2047  if (fcntl (socket_fd, F_SETFL, sk_flags | O_NONBLOCK) < 0)
2048  goto thread_failed;
2049 #else
2050  sk_flags = 1;
2051 #if HAVE_PLIBC_FD
2052  if (ioctlsocket (plibc_fd_get_handle (socket_fd), FIONBIO, &sk_flags) ==
2053  SOCKET_ERROR)
2054 #else
2055  if (ioctlsocket (socket_fd, FIONBIO, &sk_flags) == SOCKET_ERROR)
2056 #endif // PLIBC_FD
2057  goto thread_failed;
2058 #endif // MINGW
2059 
2060  /* Allocate memory for pooled objects */
2061  retVal->worker_pool = malloc (sizeof (struct MHD_Daemon)
2062  * retVal->worker_pool_size);
2063  if (NULL == retVal->worker_pool)
2064  goto thread_failed;
2065 
2066  /* Start the workers in the pool */
2067  for (i = 0; i < retVal->worker_pool_size; ++i)
2068  {
2069  /* Create copy of the Daemon object for each worker */
2070  struct MHD_Daemon *d = &retVal->worker_pool[i];
2071  memcpy (d, retVal, sizeof (struct MHD_Daemon));
2072 
2073  /* Adjust pooling params for worker daemons; note that memcpy()
2074  has already copied MHD_USE_SELECT_INTERNALLY thread model into
2075  the worker threads. */
2076  d->master = retVal;
2077  d->worker_pool_size = 0;
2078  d->worker_pool = NULL;
2079 
2080  /* Divide available connections evenly amongst the threads.
2081  * Thread indexes in [0, leftover_conns) each get one of the
2082  * leftover connections. */
2083  d->max_connections = conns_per_thread;
2084  if (i < leftover_conns)
2085  ++d->max_connections;
2086 
2087  /* Spawn the worker thread */
2088  if (0 != (res_thread_create = create_thread (&d->pid, retVal, &MHD_select_thread, d)))
2089  {
2090 #if HAVE_MESSAGES
2091  MHD_DLOG (retVal,
2092  "Failed to create pool thread: %s\n",
2093  STRERROR (res_thread_create));
2094 #endif
2095  /* Free memory for this worker; cleanup below handles
2096  * all previously-created workers. */
2097  goto thread_failed;
2098  }
2099  }
2100  }
2101  return retVal;
2102 
2103 thread_failed:
2104  /* If no worker threads created, then shut down normally. Calling
2105  MHD_stop_daemon (as we do below) doesn't work here since it
2106  assumes a 0-sized thread pool means we had been in the default
2107  MHD_USE_SELECT_INTERNALLY mode. */
2108  if (i == 0)
2109  {
2110  CLOSE (socket_fd);
2111  pthread_mutex_destroy (&retVal->per_ip_connection_mutex);
2112  if (NULL != retVal->worker_pool)
2113  free (retVal->worker_pool);
2114  free (retVal);
2115  return NULL;
2116  }
2117 
2118  /* Shutdown worker threads we've already created. Pretend
2119  as though we had fully initialized our daemon, but
2120  with a smaller number of threads than had been
2121  requested. */
2122  retVal->worker_pool_size = i - 1;
2123  MHD_stop_daemon (retVal);
2124  return NULL;
2125 }
2126 
2130 static void
2132 {
2133  while (daemon->connections != NULL)
2134  {
2135  if (-1 != daemon->connections->socket_fd)
2136  {
2137 #if DEBUG_CLOSE
2138 #if HAVE_MESSAGES
2139  MHD_DLOG (daemon, "MHD shutdown, closing active connections\n");
2140 #endif
2141 #endif
2144  }
2145  MHD_cleanup_connections (daemon);
2146  }
2147 }
2148 
2152 void
2153 MHD_stop_daemon (struct MHD_Daemon *daemon)
2154 {
2155  void *unused;
2156  int fd;
2157  unsigned int i;
2158  int rc;
2159 
2160  if (daemon == NULL)
2161  return;
2162  daemon->shutdown = MHD_YES;
2163  fd = daemon->socket_fd;
2164  daemon->socket_fd = -1;
2165 
2166  /* Prepare workers for shutdown */
2167  for (i = 0; i < daemon->worker_pool_size; ++i)
2168  {
2169  daemon->worker_pool[i].shutdown = MHD_YES;
2170  daemon->worker_pool[i].socket_fd = -1;
2171  }
2172 
2173 #if OSX
2174  /* without this, either (thread pool = 0) threads would get stuck or
2175  * CLOSE would get stuck if attempted before (thread pool > 0)
2176  * threads have ended */
2177  SHUTDOWN (fd, SHUT_RDWR);
2178 #else
2179 #if DEBUG_CLOSE
2180 #if HAVE_MESSAGES
2181  MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n");
2182 #endif
2183 #endif
2184  CLOSE (fd);
2185 #endif
2186 
2187  /* Signal workers to stop and clean them up */
2188  for (i = 0; i < daemon->worker_pool_size; ++i)
2189  pthread_kill (daemon->worker_pool[i].pid, SIGALRM);
2190  for (i = 0; i < daemon->worker_pool_size; ++i)
2191  {
2192  if (0 != (rc = pthread_join (daemon->worker_pool[i].pid, &unused)))
2193  {
2194 #if HAVE_MESSAGES
2195  MHD_DLOG (daemon, "Failed to join a thread: %s\n",
2196  STRERROR (rc));
2197 #endif
2198  abort();
2199  }
2200  MHD_close_connections (&daemon->worker_pool[i]);
2201  }
2202  free (daemon->worker_pool);
2203 
2204  if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
2205  ((0 != (daemon->options & MHD_USE_SELECT_INTERNALLY))
2206  && (0 == daemon->worker_pool_size)))
2207  {
2208  pthread_kill (daemon->pid, SIGALRM);
2209  if (0 != (rc = pthread_join (daemon->pid, &unused)))
2210  {
2211 #if HAVE_MESSAGES
2212  MHD_DLOG (daemon, "Failed to join a thread: %s\n",
2213  STRERROR (rc));
2214 #endif
2215  abort();
2216  }
2217  }
2218  MHD_close_connections (daemon);
2219 
2220 #if OSX
2221 #if DEBUG_CLOSE
2222 #if HAVE_MESSAGES
2223  MHD_DLOG (daemon, "MHD shutdown, closing listen socket\n");
2224 #endif
2225 #endif
2226  CLOSE (fd);
2227 #endif
2228 
2229  /* TLS clean up */
2230 #if HTTPS_SUPPORT
2231  if (daemon->options & MHD_USE_SSL)
2232  {
2233  gnutls_priority_deinit (daemon->priority_cache);
2234  if (daemon->x509_cred)
2235  gnutls_certificate_free_credentials (daemon->x509_cred);
2236  /* lock MHD_gnutls_global mutex since it uses reference counting */
2237  if (0 != pthread_mutex_lock (&MHD_gnutls_init_mutex))
2238  {
2239 #if HAVE_MESSAGES
2240  MHD_DLOG (daemon, "Failed to aquire gnutls mutex\n");
2241 #endif
2242  abort();
2243  }
2244  if (0 != pthread_mutex_unlock (&MHD_gnutls_init_mutex))
2245  {
2246 #if HAVE_MESSAGES
2247  MHD_DLOG (daemon, "Failed to release gnutls mutex\n");
2248 #endif
2249  abort();
2250  }
2251  }
2252 #endif
2253 
2254 #ifdef DAUTH_SUPPORT
2255  free (daemon->nnc);
2256  pthread_mutex_destroy (&daemon->nnc_lock);
2257 #endif
2258  pthread_mutex_destroy (&daemon->per_ip_connection_mutex);
2259  free (daemon);
2260 }
2261 
2272 const union MHD_DaemonInfo *
2274  enum MHD_DaemonInfoType infoType, ...)
2275 {
2276  switch (infoType)
2277  {
2279  return (const union MHD_DaemonInfo *) &daemon->socket_fd;
2280  default:
2281  return NULL;
2282  };
2283 }
2284 
2301 {
2302  mhd_panic = cb;
2303  mhd_panic_cls = cls;
2304 }
2305 
2311 const char *
2313 {
2314  return PACKAGE_VERSION;
2315 }
2316 
2317 #ifndef WINDOWS
2318 
2319 static struct sigaction sig;
2320 
2321 static struct sigaction old;
2322 
2323 static void
2325 {
2326 }
2327 #endif
2328 
2329 #ifdef __GNUC__
2330 #define ATTRIBUTE_CONSTRUCTOR __attribute__ ((constructor))
2331 #define ATTRIBUTE_DESTRUCTOR __attribute__ ((destructor))
2332 #else // !__GNUC__
2333 #define ATTRIBUTE_CONSTRUCTOR
2334 #define ATTRIBUTE_DESTRUCTOR
2335 #endif // __GNUC__
2336 
2337 #if HTTPS_SUPPORT
2338 GCRY_THREAD_OPTION_PTHREAD_IMPL;
2339 #endif
2340 
2346 {
2348  mhd_panic_cls = NULL;
2349 
2350 #ifndef WINDOWS
2351  /* make sure SIGALRM does not kill us */
2352  memset (&sig, 0, sizeof (struct sigaction));
2353  memset (&old, 0, sizeof (struct sigaction));
2354  sig.sa_flags = SA_NODEFER;
2355  sig.sa_handler = &sigalrmHandler;
2356  sigaction (SIGALRM, &sig, &old);
2357 #else
2358  plibc_init ("GNU", "libmicrohttpd");
2359 #endif
2360 #if HTTPS_SUPPORT
2361  gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
2362  gnutls_global_init ();
2363  if (0 != pthread_mutex_init(&MHD_gnutls_init_mutex, NULL))
2364  abort();
2365 #endif
2366 }
2367 
2369 {
2370 #if HTTPS_SUPPORT
2371  gnutls_global_deinit ();
2372  if (0 != pthread_mutex_destroy(&MHD_gnutls_init_mutex))
2373  mhd_panic (mhd_panic_cls, __FILE__, __LINE__, NULL);
2374 #endif
2375 #ifndef WINDOWS
2376  sigaction (SIGALRM, &old, &sig);
2377 #else
2378  plibc_shutdown ();
2379 #endif
2380 }
2381 
2382 /* end of daemon.c */