diff options
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r-- | src/daemon/daemon.c | 178 |
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 | */ | ||
135 | static int | 137 | static int |
136 | MHD_TLS_init (struct MHD_Daemon *daemon) | 138 | MHD_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 | /** |
295 | static long | 297 | * Callback for receiving data from the socket (for gnutls). |
296 | gnutls_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 | */ | ||
304 | static ssize_t | ||
305 | pull_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 | ||
306 | static long | 316 | /** |
307 | gnutls_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 | */ | ||
324 | static ssize_t | ||
325 | push_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 | ||
324 | static void * | 340 | static void * |
325 | MHD_TLS_init_connection (void *data) | 341 | MHD_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 | ||