aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r--src/daemon/daemon.c178
1 files changed, 79 insertions, 99 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 6f8f6b17..7911be33 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -1,22 +1,22 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 (C) 2007 Daniel Pittman and Christian Grothoff 3 (C) 2007 Daniel Pittman and Christian Grothoff
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version. 8 version 2.1 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details. 13 Lesser General Public License for more details.
14 14
15 You should have received a copy of the GNU Lesser General Public 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 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 17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 18
19 */ 19*/
20 20
21/** 21/**
22 * @file daemon.c 22 * @file daemon.c
@@ -131,7 +131,9 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
131 return -1; 131 return -1;
132} 132}
133 133
134/* initialize security aspects of the HTTPS daemon */ 134/**
135 * initialize security aspects of the HTTPS daemon
136 */
135static int 137static int
136MHD_TLS_init (struct MHD_Daemon *daemon) 138MHD_TLS_init (struct MHD_Daemon *daemon)
137{ 139{
@@ -290,52 +292,60 @@ MHD_handle_connection (void *data)
290 return NULL; 292 return NULL;
291} 293}
292 294
293#if 0 295#if HTTPS_SUPPORT
294/* TODO rm if unused - gnutls parameter adapter , used to set gnutls pull function */ 296/**
295static long 297 * Callback for receiving data from the socket (for gnutls).
296gnutls_pull_param_adapter (void *connection, void *other, unsigned long i) 298 *
299 * @param conn the MHD connection structure
300 * @param other where to write received data to
301 * @param i maximum size of other (in bytes)
302 * @return number of bytes actually received
303 */
304static ssize_t
305pull_param_adapter (gnutls_transport_ptr_t conn,
306 void *other,
307 size_t i)
297{ 308{
298 ssize_t bytes; 309 struct MHD_Connection * connection = (struct MHD_Connection*) conn;
299 bytes = ((struct MHD_Connection *) connection)->read_buffer_offset;
300 MHD_handle_connection (connection);
301 bytes = ((struct MHD_Connection *) connection)->read_buffer_offset - bytes;
302 return bytes;
303 310
311 if (connection->socket_fd == -1)
312 return -1;
313 return RECV(connection->socket_fd, other, i, MSG_NOSIGNAL);
304} 314}
305 315
306static long 316/**
307gnutls_push_param_adapter (void *connection, 317 * Callback for writing data to the socket (for gnutls).
308 const void *other, unsigned long i) 318 *
319 * @param conn the MHD connection structure
320 * @param other data to write
321 * @param i number of bytes to write
322 * @return actual number of bytes written
323 */
324static ssize_t
325push_param_adapter (void *conn,
326 const void *other,
327 size_t i)
309{ 328{
310 ssize_t bytes; 329 struct MHD_Connection * connection = (struct MHD_Connection*) conn;
311 bytes = ((struct MHD_Connection *) connection)->write_buffer_send_offset;
312 MHD_handle_connection (connection);
313 bytes = ((struct MHD_Connection *) connection)->write_buffer_send_offset
314 - bytes;
315 return bytes;
316}
317#endif
318 330
331 if (connection->socket_fd == -1)
332 return -1;
333 return SEND(connection->socket_fd, other, i, MSG_NOSIGNAL);
334}
319 335
320/** 336/**
321 * Handle an individual TLS connection. 337 * Handle an individual TLS connection (main function
338 * of the thread handling a TLS connection).
322 */ 339 */
323#if HTTPS_SUPPORT
324static void * 340static void *
325MHD_TLS_init_connection (void *data) 341MHD_TLS_init_connection (void *data)
326{ 342{
327 struct MHD_Connection *con = data; 343 struct MHD_Connection *con = data;
328 344
329 if (con == NULL) 345 EXTRA_CHECK (con->state == MHD_CONNECTION_INIT);
330 abort ();
331
332 /* initialize connection state */
333 con->state = MHD_TLS_CONNECTION_INIT; 346 con->state = MHD_TLS_CONNECTION_INIT;
334 MHD_gnutls_init (&con->tls_session, GNUTLS_SERVER); 347 MHD_gnutls_init (&con->tls_session, GNUTLS_SERVER);
335
336 /* sets cipher priorities */
337 MHD_gnutls_priority_set (con->tls_session, con->daemon->priority_cache); 348 MHD_gnutls_priority_set (con->tls_session, con->daemon->priority_cache);
338
339 switch (con->daemon->cred_type) 349 switch (con->daemon->cred_type)
340 { 350 {
341 /* set needed credentials for certificate authentication. */ 351 /* set needed credentials for certificate authentication. */
@@ -351,24 +361,17 @@ MHD_TLS_init_connection (void *data)
351 MHD_gnutls_dh_set_prime_bits (con->tls_session, 1024); 361 MHD_gnutls_dh_set_prime_bits (con->tls_session, 1024);
352 break; 362 break;
353 default: 363 default:
354
355#if HAVE_MESSAGES 364#if HAVE_MESSAGES
356 MHD_DLOG (con->daemon, 365 MHD_DLOG (con->daemon,
357 "Error: couldn't init HTTPS session. no appropriate KX algorithm found. f: %s, l: %d\n", 366 "Failed to setup TLS credentials: unknown credential type %d\n",
358 __FUNCTION__, __LINE__); 367 con->daemon->cred_type);
359#endif 368#endif
360 break; 369 abort();
361 } 370 }
362
363 /* TODO avoid gnutls blocking recv / write calls
364 MHD_gnutls_transport_set_pull_function(tls_session, &recv);
365 MHD_gnutls_transport_set_push_function(tls_session, &send);
366 */
367
368 MHD_gnutls_transport_set_ptr (con->tls_session, 371 MHD_gnutls_transport_set_ptr (con->tls_session,
369 (gnutls_transport_ptr_t) ((void *) 372 (gnutls_transport_ptr_t) con);
370 con->socket_fd)); 373 MHD_gnutls_transport_set_pull_function(con->tls_session, &pull_param_adapter);
371 374 MHD_gnutls_transport_set_push_function(con->tls_session, &push_param_adapter);
372 return MHD_handle_connection (data); 375 return MHD_handle_connection (data);
373} 376}
374#endif 377#endif
@@ -512,32 +515,25 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
512 connection->addr_len = addrlen; 515 connection->addr_len = addrlen;
513 connection->socket_fd = s; 516 connection->socket_fd = s;
514 connection->daemon = daemon; 517 connection->daemon = daemon;
518 connection->last_activity = time (NULL);
515 519
516 /* set default connection handlers */ 520 /* set default connection handlers */
517 MHD_set_http_calbacks (connection); 521 MHD_set_http_calbacks (connection);
518
519#if HTTPS_SUPPORT 522#if HTTPS_SUPPORT
520 if (daemon->options & MHD_USE_SSL) 523 if (0 != (daemon->options & MHD_USE_SSL))
521 { 524 MHD_set_https_calbacks (connection);
522 MHD_set_https_calbacks (connection);
523 }
524#endif 525#endif
525 526
526 /* attempt to create handler thread */ 527 /* attempt to create handler thread */
527 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 528 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
528 { 529 {
530 res_thread_create = pthread_create (&connection->pid, NULL,
529#if HTTPS_SUPPORT 531#if HTTPS_SUPPORT
530 if (daemon->options & MHD_USE_SSL) 532 (0 != (daemon->options & MHD_USE_SSL)) ?
531 res_thread_create = pthread_create (&connection->pid, NULL, 533 &MHD_TLS_init_connection :
532 &MHD_TLS_init_connection,
533 connection);
534 else
535#endif 534#endif
536 { 535 &MHD_handle_connection,
537 res_thread_create = pthread_create (&connection->pid, NULL, 536 connection);
538 &MHD_handle_connection,
539 connection);
540 }
541 if (res_thread_create != 0) 537 if (res_thread_create != 0)
542 { 538 {
543#if HAVE_MESSAGES 539#if HAVE_MESSAGES
@@ -550,11 +546,8 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
550 free (connection); 546 free (connection);
551 return MHD_NO; 547 return MHD_NO;
552 } 548 }
553 } 549 }
554
555 connection->last_activity = time (NULL);
556 connection->next = daemon->connections; 550 connection->next = daemon->connections;
557
558 daemon->connections = connection; 551 daemon->connections = connection;
559 daemon->max_connections--; 552 daemon->max_connections--;
560 return MHD_YES; 553 return MHD_YES;
@@ -720,7 +713,7 @@ MHD_select (struct MHD_Daemon *daemon, int may_block)
720 if (errno == EINTR) 713 if (errno == EINTR)
721 return MHD_YES; 714 return MHD_YES;
722#if HAVE_MESSAGES 715#if HAVE_MESSAGES
723 MHD_DLOG (daemon, "Select failed: %s\n", STRERROR (errno)); 716 MHD_DLOG (daemon, "select failed: %s\n", STRERROR (errno));
724#endif 717#endif
725 return MHD_NO; 718 return MHD_NO;
726 } 719 }
@@ -876,9 +869,6 @@ MHD_start_daemon_va (unsigned int options,
876 } 869 }
877#endif 870#endif
878 871
879 /*
880 * analyze daemon options
881 */
882 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) 872 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
883 { 873 {
884 switch (opt) 874 switch (opt)
@@ -981,13 +971,9 @@ MHD_start_daemon_va (unsigned int options,
981 971
982 /* check for user supplied sockaddr */ 972 /* check for user supplied sockaddr */
983 if ((options & MHD_USE_IPv6) != 0) 973 if ((options & MHD_USE_IPv6) != 0)
984 { 974 addrlen = sizeof (struct sockaddr_in6);
985 addrlen = sizeof (struct sockaddr_in6);
986 }
987 else 975 else
988 { 976 addrlen = sizeof (struct sockaddr_in);
989 addrlen = sizeof (struct sockaddr_in);
990 }
991 if (NULL == servaddr) 977 if (NULL == servaddr)
992 { 978 {
993 if ((options & MHD_USE_IPv6) != 0) 979 if ((options & MHD_USE_IPv6) != 0)
@@ -1036,7 +1022,7 @@ MHD_start_daemon_va (unsigned int options,
1036 if ((options & MHD_USE_SSL) && MHD_TLS_init (retVal)) 1022 if ((options & MHD_USE_SSL) && MHD_TLS_init (retVal))
1037 { 1023 {
1038#if HAVE_MESSAGES 1024#if HAVE_MESSAGES
1039 MHD_DLOG (retVal, "Failed to initialize HTTPS daemon\n"); 1025 MHD_DLOG (retVal, "Failed to initialize TLS support\n");
1040#endif 1026#endif
1041 CLOSE (socket_fd); 1027 CLOSE (socket_fd);
1042 free (retVal); 1028 free (retVal);
@@ -1079,11 +1065,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
1079#endif 1065#endif
1080#endif 1066#endif
1081 CLOSE (fd); 1067 CLOSE (fd);
1082 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || (0 1068 if ((0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
1083 != 1069 (0 != (daemon->options & MHD_USE_SELECT_INTERNALLY)))
1084 (daemon->
1085 options &
1086 MHD_USE_SELECT_INTERNALLY)))
1087 { 1070 {
1088 pthread_kill (daemon->pid, SIGALRM); 1071 pthread_kill (daemon->pid, SIGALRM);
1089 pthread_join (daemon->pid, &unused); 1072 pthread_join (daemon->pid, &unused);
@@ -1114,19 +1097,16 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
1114 if (daemon->options & MHD_USE_SSL) 1097 if (daemon->options & MHD_USE_SSL)
1115 { 1098 {
1116 MHD_gnutls_priority_deinit (daemon->priority_cache); 1099 MHD_gnutls_priority_deinit (daemon->priority_cache);
1117
1118 if (daemon->x509_cred) 1100 if (daemon->x509_cred)
1119 MHD_gnutls_certificate_free_credentials (daemon->x509_cred); 1101 MHD_gnutls_certificate_free_credentials (daemon->x509_cred);
1120 if (daemon->anon_cred) 1102 if (daemon->anon_cred)
1121 MHD_gnutls_anon_free_server_credentials (daemon->anon_cred); 1103 MHD_gnutls_anon_free_server_credentials (daemon->anon_cred);
1122
1123 /* lock gnutls_global mutex since it uses reference counting */ 1104 /* lock gnutls_global mutex since it uses reference counting */
1124 pthread_mutex_lock (&gnutls_init_mutex); 1105 pthread_mutex_lock (&gnutls_init_mutex);
1125 MHD_gnutls_global_deinit (); 1106 MHD_gnutls_global_deinit ();
1126 pthread_mutex_unlock (&gnutls_init_mutex); 1107 pthread_mutex_unlock (&gnutls_init_mutex);
1127 } 1108 }
1128#endif 1109#endif
1129
1130 free (daemon); 1110 free (daemon);
1131} 1111}
1132 1112