diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 7140 |
1 files changed, 3608 insertions, 3532 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index fb4abd5d..97e0ec30 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -115,7 +115,7 @@ close_all_connections (struct MHD_Daemon *daemon); | |||
115 | */ | 115 | */ |
116 | static int | 116 | static int |
117 | MHD_epoll (struct MHD_Daemon *daemon, | 117 | MHD_epoll (struct MHD_Daemon *daemon, |
118 | int may_block); | 118 | int may_block); |
119 | 119 | ||
120 | #endif /* EPOLL_SUPPORT */ | 120 | #endif /* EPOLL_SUPPORT */ |
121 | 121 | ||
@@ -130,21 +130,21 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
130 | */ | 130 | */ |
131 | static void | 131 | static void |
132 | mhd_panic_std (void *cls, | 132 | mhd_panic_std (void *cls, |
133 | const char *file, | 133 | const char *file, |
134 | unsigned int line, | 134 | unsigned int line, |
135 | const char *reason) | 135 | const char *reason) |
136 | { | 136 | { |
137 | (void)cls; /* Mute compiler warning. */ | 137 | (void) cls; /* Mute compiler warning. */ |
138 | #ifdef HAVE_MESSAGES | 138 | #ifdef HAVE_MESSAGES |
139 | fprintf (stderr, | 139 | fprintf (stderr, |
140 | _("Fatal error in GNU libmicrohttpd %s:%u: %s\n"), | 140 | _ ("Fatal error in GNU libmicrohttpd %s:%u: %s\n"), |
141 | file, | 141 | file, |
142 | line, | 142 | line, |
143 | reason); | 143 | reason); |
144 | #else /* ! HAVE_MESSAGES */ | 144 | #else /* ! HAVE_MESSAGES */ |
145 | (void)file; /* Mute compiler warning. */ | 145 | (void) file; /* Mute compiler warning. */ |
146 | (void)line; /* Mute compiler warning. */ | 146 | (void) line; /* Mute compiler warning. */ |
147 | (void)reason; /* Mute compiler warning. */ | 147 | (void) reason; /* Mute compiler warning. */ |
148 | #endif | 148 | #endif |
149 | abort (); | 149 | abort (); |
150 | } | 150 | } |
@@ -164,7 +164,7 @@ void *mhd_panic_cls = NULL; | |||
164 | * Globally initialise library. | 164 | * Globally initialise library. |
165 | */ | 165 | */ |
166 | void | 166 | void |
167 | MHD_init(void); | 167 | MHD_init (void); |
168 | 168 | ||
169 | 169 | ||
170 | #if defined(MHD_WINSOCK_SOCKETS) | 170 | #if defined(MHD_WINSOCK_SOCKETS) |
@@ -179,7 +179,7 @@ static int mhd_winsock_inited_ = 0; | |||
179 | * Do nothing - global initialisation is | 179 | * Do nothing - global initialisation is |
180 | * performed by library constructor. | 180 | * performed by library constructor. |
181 | */ | 181 | */ |
182 | #define MHD_check_global_init_() (void)0 | 182 | #define MHD_check_global_init_() (void) 0 |
183 | #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ | 183 | #else /* ! _AUTOINIT_FUNCS_ARE_SUPPORTED */ |
184 | /** | 184 | /** |
185 | * Track global initialisation | 185 | * Track global initialisation |
@@ -191,7 +191,7 @@ volatile int global_init_count = 0; | |||
191 | /** | 191 | /** |
192 | * Global initialisation mutex | 192 | * Global initialisation mutex |
193 | */ | 193 | */ |
194 | MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_); | 194 | MHD_MUTEX_STATIC_DEFN_INIT_ (global_init_mutex_); |
195 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 195 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
196 | #endif | 196 | #endif |
197 | 197 | ||
@@ -205,14 +205,14 @@ MHD_check_global_init_ (void) | |||
205 | { | 205 | { |
206 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 206 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
207 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ | 207 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ |
208 | MHD_mutex_lock_chk_(&global_init_mutex_); | 208 | MHD_mutex_lock_chk_ (&global_init_mutex_); |
209 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 209 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
210 | #endif | 210 | #endif |
211 | if (0 == global_init_count++) | 211 | if (0 == global_init_count++) |
212 | MHD_init (); | 212 | MHD_init (); |
213 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 213 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
214 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ | 214 | #ifdef MHD_MUTEX_STATIC_DEFN_INIT_ |
215 | MHD_mutex_unlock_chk_(&global_init_mutex_); | 215 | MHD_mutex_unlock_chk_ (&global_init_mutex_); |
216 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ | 216 | #endif /* MHD_MUTEX_STATIC_DEFN_INIT_ */ |
217 | #endif | 217 | #endif |
218 | } | 218 | } |
@@ -227,9 +227,9 @@ MHD_default_logger_ (void *cls, | |||
227 | const char *fm, | 227 | const char *fm, |
228 | va_list ap) | 228 | va_list ap) |
229 | { | 229 | { |
230 | vfprintf ((FILE*)cls, fm, ap); | 230 | vfprintf ((FILE*) cls, fm, ap); |
231 | #ifdef _DEBUG | 231 | #ifdef _DEBUG |
232 | fflush ((FILE*)cls); | 232 | fflush ((FILE*) cls); |
233 | #endif /* _DEBUG */ | 233 | #endif /* _DEBUG */ |
234 | } | 234 | } |
235 | 235 | ||
@@ -308,7 +308,7 @@ static void | |||
308 | MHD_ip_count_lock (struct MHD_Daemon *daemon) | 308 | MHD_ip_count_lock (struct MHD_Daemon *daemon) |
309 | { | 309 | { |
310 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 310 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
311 | MHD_mutex_lock_chk_(&daemon->per_ip_connection_mutex); | 311 | MHD_mutex_lock_chk_ (&daemon->per_ip_connection_mutex); |
312 | #else | 312 | #else |
313 | (void) daemon; | 313 | (void) daemon; |
314 | #endif | 314 | #endif |
@@ -324,7 +324,7 @@ static void | |||
324 | MHD_ip_count_unlock (struct MHD_Daemon *daemon) | 324 | MHD_ip_count_unlock (struct MHD_Daemon *daemon) |
325 | { | 325 | { |
326 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 326 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
327 | MHD_mutex_unlock_chk_(&daemon->per_ip_connection_mutex); | 327 | MHD_mutex_unlock_chk_ (&daemon->per_ip_connection_mutex); |
328 | #else | 328 | #else |
329 | (void) daemon; | 329 | (void) daemon; |
330 | #endif | 330 | #endif |
@@ -361,37 +361,37 @@ MHD_ip_addr_compare (const void *a1, | |||
361 | */ | 361 | */ |
362 | static int | 362 | static int |
363 | MHD_ip_addr_to_key (const struct sockaddr *addr, | 363 | MHD_ip_addr_to_key (const struct sockaddr *addr, |
364 | socklen_t addrlen, | 364 | socklen_t addrlen, |
365 | struct MHD_IPCount *key) | 365 | struct MHD_IPCount *key) |
366 | { | 366 | { |
367 | memset(key, | 367 | memset (key, |
368 | 0, | 368 | 0, |
369 | sizeof(*key)); | 369 | sizeof(*key)); |
370 | 370 | ||
371 | /* IPv4 addresses */ | 371 | /* IPv4 addresses */ |
372 | if (sizeof (struct sockaddr_in) == addrlen) | 372 | if (sizeof (struct sockaddr_in) == addrlen) |
373 | { | 373 | { |
374 | const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; | 374 | const struct sockaddr_in *addr4 = (const struct sockaddr_in*) addr; |
375 | 375 | ||
376 | key->family = AF_INET; | 376 | key->family = AF_INET; |
377 | memcpy (&key->addr.ipv4, | 377 | memcpy (&key->addr.ipv4, |
378 | &addr4->sin_addr, | 378 | &addr4->sin_addr, |
379 | sizeof(addr4->sin_addr)); | 379 | sizeof(addr4->sin_addr)); |
380 | return MHD_YES; | 380 | return MHD_YES; |
381 | } | 381 | } |
382 | 382 | ||
383 | #if HAVE_INET6 | 383 | #if HAVE_INET6 |
384 | /* IPv6 addresses */ | 384 | /* IPv6 addresses */ |
385 | if (sizeof (struct sockaddr_in6) == addrlen) | 385 | if (sizeof (struct sockaddr_in6) == addrlen) |
386 | { | 386 | { |
387 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; | 387 | const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*) addr; |
388 | 388 | ||
389 | key->family = AF_INET6; | 389 | key->family = AF_INET6; |
390 | memcpy (&key->addr.ipv6, | 390 | memcpy (&key->addr.ipv6, |
391 | &addr6->sin6_addr, | 391 | &addr6->sin6_addr, |
392 | sizeof(addr6->sin6_addr)); | 392 | sizeof(addr6->sin6_addr)); |
393 | return MHD_YES; | 393 | return MHD_YES; |
394 | } | 394 | } |
395 | #endif | 395 | #endif |
396 | 396 | ||
397 | /* Some other address */ | 397 | /* Some other address */ |
@@ -412,8 +412,8 @@ MHD_ip_addr_to_key (const struct sockaddr *addr, | |||
412 | */ | 412 | */ |
413 | static int | 413 | static int |
414 | MHD_ip_limit_add (struct MHD_Daemon *daemon, | 414 | MHD_ip_limit_add (struct MHD_Daemon *daemon, |
415 | const struct sockaddr *addr, | 415 | const struct sockaddr *addr, |
416 | socklen_t addrlen) | 416 | socklen_t addrlen) |
417 | { | 417 | { |
418 | struct MHD_IPCount *key; | 418 | struct MHD_IPCount *key; |
419 | void **nodep; | 419 | void **nodep; |
@@ -432,30 +432,30 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
432 | if (MHD_NO == MHD_ip_addr_to_key (addr, | 432 | if (MHD_NO == MHD_ip_addr_to_key (addr, |
433 | addrlen, | 433 | addrlen, |
434 | key)) | 434 | key)) |
435 | { | 435 | { |
436 | /* Allow unhandled address types through */ | 436 | /* Allow unhandled address types through */ |
437 | free (key); | 437 | free (key); |
438 | return MHD_YES; | 438 | return MHD_YES; |
439 | } | 439 | } |
440 | MHD_ip_count_lock (daemon); | 440 | MHD_ip_count_lock (daemon); |
441 | 441 | ||
442 | /* Search for the IP address */ | 442 | /* Search for the IP address */ |
443 | if (NULL == (nodep = tsearch (key, | 443 | if (NULL == (nodep = tsearch (key, |
444 | &daemon->per_ip_connection_count, | 444 | &daemon->per_ip_connection_count, |
445 | &MHD_ip_addr_compare))) | 445 | &MHD_ip_addr_compare))) |
446 | { | 446 | { |
447 | #ifdef HAVE_MESSAGES | 447 | #ifdef HAVE_MESSAGES |
448 | MHD_DLOG (daemon, | 448 | MHD_DLOG (daemon, |
449 | _("Failed to add IP connection count node\n")); | 449 | _ ("Failed to add IP connection count node\n")); |
450 | #endif | 450 | #endif |
451 | MHD_ip_count_unlock (daemon); | 451 | MHD_ip_count_unlock (daemon); |
452 | free (key); | 452 | free (key); |
453 | return MHD_NO; | 453 | return MHD_NO; |
454 | } | 454 | } |
455 | node = *nodep; | 455 | node = *nodep; |
456 | /* If we got an existing node back, free the one we created */ | 456 | /* If we got an existing node back, free the one we created */ |
457 | if (node != key) | 457 | if (node != key) |
458 | free(key); | 458 | free (key); |
459 | key = (struct MHD_IPCount *) node; | 459 | key = (struct MHD_IPCount *) node; |
460 | /* Test if there is room for another connection; if so, | 460 | /* Test if there is room for another connection; if so, |
461 | * increment count */ | 461 | * increment count */ |
@@ -478,8 +478,8 @@ MHD_ip_limit_add (struct MHD_Daemon *daemon, | |||
478 | */ | 478 | */ |
479 | static void | 479 | static void |
480 | MHD_ip_limit_del (struct MHD_Daemon *daemon, | 480 | MHD_ip_limit_del (struct MHD_Daemon *daemon, |
481 | const struct sockaddr *addr, | 481 | const struct sockaddr *addr, |
482 | socklen_t addrlen) | 482 | socklen_t addrlen) |
483 | { | 483 | { |
484 | struct MHD_IPCount search_key; | 484 | struct MHD_IPCount search_key; |
485 | struct MHD_IPCount *found_key; | 485 | struct MHD_IPCount *found_key; |
@@ -499,27 +499,27 @@ MHD_ip_limit_del (struct MHD_Daemon *daemon, | |||
499 | 499 | ||
500 | /* Search for the IP address */ | 500 | /* Search for the IP address */ |
501 | if (NULL == (nodep = tfind (&search_key, | 501 | if (NULL == (nodep = tfind (&search_key, |
502 | &daemon->per_ip_connection_count, | 502 | &daemon->per_ip_connection_count, |
503 | &MHD_ip_addr_compare))) | 503 | &MHD_ip_addr_compare))) |
504 | { | 504 | { |
505 | /* Something's wrong if we couldn't find an IP address | 505 | /* Something's wrong if we couldn't find an IP address |
506 | * that was previously added */ | 506 | * that was previously added */ |
507 | MHD_PANIC (_("Failed to find previously-added IP address\n")); | 507 | MHD_PANIC (_ ("Failed to find previously-added IP address\n")); |
508 | } | 508 | } |
509 | found_key = (struct MHD_IPCount *) *nodep; | 509 | found_key = (struct MHD_IPCount *) *nodep; |
510 | /* Validate existing count for IP address */ | 510 | /* Validate existing count for IP address */ |
511 | if (0 == found_key->count) | 511 | if (0 == found_key->count) |
512 | { | 512 | { |
513 | MHD_PANIC (_("Previously-added IP address had counter of zero\n")); | 513 | MHD_PANIC (_ ("Previously-added IP address had counter of zero\n")); |
514 | } | 514 | } |
515 | /* Remove the node entirely if count reduces to 0 */ | 515 | /* Remove the node entirely if count reduces to 0 */ |
516 | if (0 == --found_key->count) | 516 | if (0 == --found_key->count) |
517 | { | 517 | { |
518 | tdelete (found_key, | 518 | tdelete (found_key, |
519 | &daemon->per_ip_connection_count, | 519 | &daemon->per_ip_connection_count, |
520 | &MHD_ip_addr_compare); | 520 | &MHD_ip_addr_compare); |
521 | free (found_key); | 521 | free (found_key); |
522 | } | 522 | } |
523 | 523 | ||
524 | MHD_ip_count_unlock (daemon); | 524 | MHD_ip_count_unlock (daemon); |
525 | } | 525 | } |
@@ -541,103 +541,104 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon) | |||
541 | 541 | ||
542 | #if GNUTLS_VERSION_MAJOR >= 3 | 542 | #if GNUTLS_VERSION_MAJOR >= 3 |
543 | if (NULL != daemon->cert_callback) | 543 | if (NULL != daemon->cert_callback) |
544 | { | 544 | { |
545 | gnutls_certificate_set_retrieve_function2 (daemon->x509_cred, | 545 | gnutls_certificate_set_retrieve_function2 (daemon->x509_cred, |
546 | daemon->cert_callback); | 546 | daemon->cert_callback); |
547 | } | 547 | } |
548 | #endif | 548 | #endif |
549 | #if GNUTLS_VERSION_NUMBER >= 0x030603 | 549 | #if GNUTLS_VERSION_NUMBER >= 0x030603 |
550 | else if (NULL != daemon->cert_callback2) | 550 | else if (NULL != daemon->cert_callback2) |
551 | { | 551 | { |
552 | gnutls_certificate_set_retrieve_function3 (daemon->x509_cred, | 552 | gnutls_certificate_set_retrieve_function3 (daemon->x509_cred, |
553 | daemon->cert_callback2); | 553 | daemon->cert_callback2); |
554 | } | 554 | } |
555 | #endif | 555 | #endif |
556 | 556 | ||
557 | if (NULL != daemon->https_mem_trust) | 557 | if (NULL != daemon->https_mem_trust) |
558 | { | ||
559 | size_t paramlen; | ||
560 | paramlen = strlen (daemon->https_mem_trust); | ||
561 | if (UINT_MAX < paramlen) | ||
558 | { | 562 | { |
559 | size_t paramlen; | ||
560 | paramlen = strlen (daemon->https_mem_trust); | ||
561 | if (UINT_MAX < paramlen) | ||
562 | { | ||
563 | #ifdef HAVE_MESSAGES | 563 | #ifdef HAVE_MESSAGES |
564 | MHD_DLOG(daemon, | 564 | MHD_DLOG (daemon, |
565 | "Too long trust certificate\n"); | 565 | "Too long trust certificate\n"); |
566 | #endif | 566 | #endif |
567 | return -1; | 567 | return -1; |
568 | } | 568 | } |
569 | cert.data = (unsigned char *) daemon->https_mem_trust; | 569 | cert.data = (unsigned char *) daemon->https_mem_trust; |
570 | cert.size = (unsigned int) paramlen; | 570 | cert.size = (unsigned int) paramlen; |
571 | if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, | 571 | if (gnutls_certificate_set_x509_trust_mem (daemon->x509_cred, |
572 | &cert, | 572 | &cert, |
573 | GNUTLS_X509_FMT_PEM) < 0) | 573 | GNUTLS_X509_FMT_PEM) < 0) |
574 | { | 574 | { |
575 | #ifdef HAVE_MESSAGES | 575 | #ifdef HAVE_MESSAGES |
576 | MHD_DLOG(daemon, | 576 | MHD_DLOG (daemon, |
577 | "Bad trust certificate format\n"); | 577 | "Bad trust certificate format\n"); |
578 | #endif | 578 | #endif |
579 | return -1; | 579 | return -1; |
580 | } | ||
581 | } | 580 | } |
581 | } | ||
582 | 582 | ||
583 | if (daemon->have_dhparams) | 583 | if (daemon->have_dhparams) |
584 | { | 584 | { |
585 | gnutls_certificate_set_dh_params (daemon->x509_cred, | 585 | gnutls_certificate_set_dh_params (daemon->x509_cred, |
586 | daemon->https_mem_dhparams); | 586 | daemon->https_mem_dhparams); |
587 | } | 587 | } |
588 | /* certificate & key loaded from memory */ | 588 | /* certificate & key loaded from memory */ |
589 | if ( (NULL != daemon->https_mem_cert) && | 589 | if ( (NULL != daemon->https_mem_cert) && |
590 | (NULL != daemon->https_mem_key) ) | 590 | (NULL != daemon->https_mem_key) ) |
591 | { | 591 | { |
592 | size_t param1len; | 592 | size_t param1len; |
593 | size_t param2len; | 593 | size_t param2len; |
594 | 594 | ||
595 | param1len = strlen (daemon->https_mem_key); | 595 | param1len = strlen (daemon->https_mem_key); |
596 | param2len = strlen (daemon->https_mem_cert); | 596 | param2len = strlen (daemon->https_mem_cert); |
597 | if ( (UINT_MAX < param1len) || | 597 | if ( (UINT_MAX < param1len) || |
598 | (UINT_MAX < param2len) ) | 598 | (UINT_MAX < param2len) ) |
599 | { | 599 | { |
600 | #ifdef HAVE_MESSAGES | 600 | #ifdef HAVE_MESSAGES |
601 | MHD_DLOG(daemon, | 601 | MHD_DLOG (daemon, |
602 | "Too long key or certificate\n"); | 602 | "Too long key or certificate\n"); |
603 | #endif | 603 | #endif |
604 | return -1; | 604 | return -1; |
605 | } | 605 | } |
606 | key.data = (unsigned char *) daemon->https_mem_key; | 606 | key.data = (unsigned char *) daemon->https_mem_key; |
607 | key.size = (unsigned int)param1len; | 607 | key.size = (unsigned int) param1len; |
608 | cert.data = (unsigned char *) daemon->https_mem_cert; | 608 | cert.data = (unsigned char *) daemon->https_mem_cert; |
609 | cert.size = (unsigned int)param2len; | 609 | cert.size = (unsigned int) param2len; |
610 | 610 | ||
611 | if (NULL != daemon->https_key_password) { | 611 | if (NULL != daemon->https_key_password) |
612 | { | ||
612 | #if GNUTLS_VERSION_NUMBER >= 0x030111 | 613 | #if GNUTLS_VERSION_NUMBER >= 0x030111 |
613 | ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred, | 614 | ret = gnutls_certificate_set_x509_key_mem2 (daemon->x509_cred, |
614 | &cert, | 615 | &cert, |
615 | &key, | 616 | &key, |
616 | GNUTLS_X509_FMT_PEM, | 617 | GNUTLS_X509_FMT_PEM, |
617 | daemon->https_key_password, | 618 | daemon->https_key_password, |
618 | 0); | 619 | 0); |
619 | #else | 620 | #else |
620 | #ifdef HAVE_MESSAGES | 621 | #ifdef HAVE_MESSAGES |
621 | MHD_DLOG (daemon, | 622 | MHD_DLOG (daemon, |
622 | _("Failed to setup x509 certificate/key: pre 3.X.X version " \ | 623 | _ ("Failed to setup x509 certificate/key: pre 3.X.X version " \ |
623 | "of GnuTLS does not support setting key password")); | 624 | "of GnuTLS does not support setting key password")); |
624 | #endif | 625 | #endif |
625 | return -1; | 626 | return -1; |
626 | #endif | 627 | #endif |
627 | } | 628 | } |
628 | else | 629 | else |
629 | ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred, | 630 | ret = gnutls_certificate_set_x509_key_mem (daemon->x509_cred, |
630 | &cert, | 631 | &cert, |
631 | &key, | 632 | &key, |
632 | GNUTLS_X509_FMT_PEM); | 633 | GNUTLS_X509_FMT_PEM); |
633 | #ifdef HAVE_MESSAGES | 634 | #ifdef HAVE_MESSAGES |
634 | if (0 != ret) | 635 | if (0 != ret) |
635 | MHD_DLOG (daemon, | 636 | MHD_DLOG (daemon, |
636 | "GnuTLS failed to setup x509 certificate/key: %s\n", | 637 | "GnuTLS failed to setup x509 certificate/key: %s\n", |
637 | gnutls_strerror (ret)); | 638 | gnutls_strerror (ret)); |
638 | #endif | 639 | #endif |
639 | return ret; | 640 | return ret; |
640 | } | 641 | } |
641 | #if GNUTLS_VERSION_MAJOR >= 3 | 642 | #if GNUTLS_VERSION_MAJOR >= 3 |
642 | if (NULL != daemon->cert_callback) | 643 | if (NULL != daemon->cert_callback) |
643 | return 0; | 644 | return 0; |
@@ -663,25 +664,25 @@ static int | |||
663 | MHD_TLS_init (struct MHD_Daemon *daemon) | 664 | MHD_TLS_init (struct MHD_Daemon *daemon) |
664 | { | 665 | { |
665 | switch (daemon->cred_type) | 666 | switch (daemon->cred_type) |
666 | { | 667 | { |
667 | case GNUTLS_CRD_CERTIFICATE: | 668 | case GNUTLS_CRD_CERTIFICATE: |
668 | if (0 != | 669 | if (0 != |
669 | gnutls_certificate_allocate_credentials (&daemon->x509_cred)) | 670 | gnutls_certificate_allocate_credentials (&daemon->x509_cred)) |
670 | return GNUTLS_E_MEMORY_ERROR; | 671 | return GNUTLS_E_MEMORY_ERROR; |
671 | return MHD_init_daemon_certificate (daemon); | 672 | return MHD_init_daemon_certificate (daemon); |
672 | case GNUTLS_CRD_PSK: | 673 | case GNUTLS_CRD_PSK: |
673 | if (0 != | 674 | if (0 != |
674 | gnutls_psk_allocate_server_credentials (&daemon->psk_cred)) | 675 | gnutls_psk_allocate_server_credentials (&daemon->psk_cred)) |
675 | return GNUTLS_E_MEMORY_ERROR; | 676 | return GNUTLS_E_MEMORY_ERROR; |
676 | return 0; | 677 | return 0; |
677 | default: | 678 | default: |
678 | #ifdef HAVE_MESSAGES | 679 | #ifdef HAVE_MESSAGES |
679 | MHD_DLOG (daemon, | 680 | MHD_DLOG (daemon, |
680 | _("Error: invalid credentials type %d specified.\n"), | 681 | _ ("Error: invalid credentials type %d specified.\n"), |
681 | daemon->cred_type); | 682 | daemon->cred_type); |
682 | #endif | 683 | #endif |
683 | return -1; | 684 | return -1; |
684 | } | 685 | } |
685 | } | 686 | } |
686 | #endif /* HTTPS_SUPPORT */ | 687 | #endif /* HTTPS_SUPPORT */ |
687 | 688 | ||
@@ -761,55 +762,55 @@ urh_to_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
761 | /* Do not add to 'es' only if socket is closed | 762 | /* Do not add to 'es' only if socket is closed |
762 | * or not used anymore. */ | 763 | * or not used anymore. */ |
763 | if (MHD_INVALID_SOCKET != conn_sckt) | 764 | if (MHD_INVALID_SOCKET != conn_sckt) |
764 | { | 765 | { |
765 | if ( (urh->in_buffer_used < urh->in_buffer_size) && | 766 | if ( (urh->in_buffer_used < urh->in_buffer_size) && |
766 | (! MHD_add_to_fd_set_ (conn_sckt, | 767 | (! MHD_add_to_fd_set_ (conn_sckt, |
767 | rs, | 768 | rs, |
768 | max_fd, | 769 | max_fd, |
769 | fd_setsize)) ) | 770 | fd_setsize)) ) |
770 | res = false; | 771 | res = false; |
771 | if ( (0 != urh->out_buffer_used) && | 772 | if ( (0 != urh->out_buffer_used) && |
772 | (! MHD_add_to_fd_set_ (conn_sckt, | 773 | (! MHD_add_to_fd_set_ (conn_sckt, |
773 | ws, | 774 | ws, |
774 | max_fd, | 775 | max_fd, |
775 | fd_setsize)) ) | 776 | fd_setsize)) ) |
776 | res = false; | 777 | res = false; |
777 | /* Do not monitor again for errors if error was detected before as | 778 | /* Do not monitor again for errors if error was detected before as |
778 | * error state is remembered. */ | 779 | * error state is remembered. */ |
779 | if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && | 780 | if ((0 == (urh->app.celi & MHD_EPOLL_STATE_ERROR)) && |
780 | ((0 != urh->in_buffer_size) || | 781 | ((0 != urh->in_buffer_size) || |
781 | (0 != urh->out_buffer_size) || | 782 | (0 != urh->out_buffer_size) || |
782 | (0 != urh->out_buffer_used))) | 783 | (0 != urh->out_buffer_used))) |
783 | MHD_add_to_fd_set_ (conn_sckt, | 784 | MHD_add_to_fd_set_ (conn_sckt, |
784 | es, | 785 | es, |
785 | max_fd, | 786 | max_fd, |
786 | fd_setsize); | 787 | fd_setsize); |
787 | } | 788 | } |
788 | if (MHD_INVALID_SOCKET != mhd_sckt) | 789 | if (MHD_INVALID_SOCKET != mhd_sckt) |
789 | { | 790 | { |
790 | if ( (urh->out_buffer_used < urh->out_buffer_size) && | 791 | if ( (urh->out_buffer_used < urh->out_buffer_size) && |
791 | (! MHD_add_to_fd_set_ (mhd_sckt, | 792 | (! MHD_add_to_fd_set_ (mhd_sckt, |
792 | rs, | 793 | rs, |
793 | max_fd, | 794 | max_fd, |
794 | fd_setsize)) ) | 795 | fd_setsize)) ) |
795 | res = false; | 796 | res = false; |
796 | if ( (0 != urh->in_buffer_used) && | 797 | if ( (0 != urh->in_buffer_used) && |
797 | (! MHD_add_to_fd_set_ (mhd_sckt, | 798 | (! MHD_add_to_fd_set_ (mhd_sckt, |
798 | ws, | 799 | ws, |
799 | max_fd, | 800 | max_fd, |
800 | fd_setsize)) ) | 801 | fd_setsize)) ) |
801 | res = false; | 802 | res = false; |
802 | /* Do not monitor again for errors if error was detected before as | 803 | /* Do not monitor again for errors if error was detected before as |
803 | * error state is remembered. */ | 804 | * error state is remembered. */ |
804 | if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && | 805 | if ((0 == (urh->mhd.celi & MHD_EPOLL_STATE_ERROR)) && |
805 | ((0 != urh->out_buffer_size) || | 806 | ((0 != urh->out_buffer_size) || |
806 | (0 != urh->in_buffer_size) || | 807 | (0 != urh->in_buffer_size) || |
807 | (0 != urh->in_buffer_used))) | 808 | (0 != urh->in_buffer_used))) |
808 | MHD_add_to_fd_set_ (mhd_sckt, | 809 | MHD_add_to_fd_set_ (mhd_sckt, |
809 | es, | 810 | es, |
810 | max_fd, | 811 | max_fd, |
811 | fd_setsize); | 812 | fd_setsize); |
812 | } | 813 | } |
813 | 814 | ||
814 | return res; | 815 | return res; |
815 | } | 816 | } |
@@ -838,23 +839,23 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
838 | urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); | 839 | urh->mhd.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); |
839 | 840 | ||
840 | if (MHD_INVALID_SOCKET != conn_sckt) | 841 | if (MHD_INVALID_SOCKET != conn_sckt) |
841 | { | 842 | { |
842 | if (FD_ISSET (conn_sckt, rs)) | 843 | if (FD_ISSET (conn_sckt, rs)) |
843 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; | 844 | urh->app.celi |= MHD_EPOLL_STATE_READ_READY; |
844 | if (FD_ISSET (conn_sckt, ws)) | 845 | if (FD_ISSET (conn_sckt, ws)) |
845 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; | 846 | urh->app.celi |= MHD_EPOLL_STATE_WRITE_READY; |
846 | if (FD_ISSET (conn_sckt, es)) | 847 | if (FD_ISSET (conn_sckt, es)) |
847 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; | 848 | urh->app.celi |= MHD_EPOLL_STATE_ERROR; |
848 | } | 849 | } |
849 | if ((MHD_INVALID_SOCKET != mhd_sckt)) | 850 | if ((MHD_INVALID_SOCKET != mhd_sckt)) |
850 | { | 851 | { |
851 | if (FD_ISSET (mhd_sckt, rs)) | 852 | if (FD_ISSET (mhd_sckt, rs)) |
852 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 853 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
853 | if (FD_ISSET (mhd_sckt, ws)) | 854 | if (FD_ISSET (mhd_sckt, ws)) |
854 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; | 855 | urh->mhd.celi |= MHD_EPOLL_STATE_WRITE_READY; |
855 | if (FD_ISSET (mhd_sckt, es)) | 856 | if (FD_ISSET (mhd_sckt, es)) |
856 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; | 857 | urh->mhd.celi |= MHD_EPOLL_STATE_ERROR; |
857 | } | 858 | } |
858 | } | 859 | } |
859 | 860 | ||
860 | #ifdef HAVE_POLL | 861 | #ifdef HAVE_POLL |
@@ -869,7 +870,7 @@ urh_from_fdset (struct MHD_UpgradeResponseHandle *urh, | |||
869 | */ | 870 | */ |
870 | static void | 871 | static void |
871 | urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, | 872 | urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, |
872 | struct pollfd p[2]) | 873 | struct pollfd p[2]) |
873 | { | 874 | { |
874 | p[0].events = 0; | 875 | p[0].events = 0; |
875 | p[1].events = 0; | 876 | p[1].events = 0; |
@@ -910,12 +911,12 @@ urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, | |||
910 | */ | 911 | */ |
911 | static void | 912 | static void |
912 | urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, | 913 | urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, |
913 | struct pollfd p[2]) | 914 | struct pollfd p[2]) |
914 | { | 915 | { |
915 | p[0].fd = urh->connection->socket_fd; | 916 | p[0].fd = urh->connection->socket_fd; |
916 | p[1].fd = urh->mhd.socket; | 917 | p[1].fd = urh->mhd.socket; |
917 | urh_update_pollfd (urh, | 918 | urh_update_pollfd (urh, |
918 | p); | 919 | p); |
919 | } | 920 | } |
920 | 921 | ||
921 | 922 | ||
@@ -926,7 +927,7 @@ urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, | |||
926 | */ | 927 | */ |
927 | static void | 928 | static void |
928 | urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, | 929 | urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, |
929 | struct pollfd p[2]) | 930 | struct pollfd p[2]) |
930 | { | 931 | { |
931 | /* Reset read/write ready, preserve error state. */ | 932 | /* Reset read/write ready, preserve error state. */ |
932 | urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); | 933 | urh->app.celi &= (~MHD_EPOLL_STATE_READ_READY & ~MHD_EPOLL_STATE_WRITE_READY); |
@@ -998,85 +999,85 @@ internal_get_fdset2 (struct MHD_Daemon *daemon, | |||
998 | * or INFO_WRITE sockets will not fit 'except_fd_set'. */ | 999 | * or INFO_WRITE sockets will not fit 'except_fd_set'. */ |
999 | /* Start from oldest connections. Make sense for W32 FDSETs. */ | 1000 | /* Start from oldest connections. Make sense for W32 FDSETs. */ |
1000 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) | 1001 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) |
1001 | { | 1002 | { |
1002 | posn = pos->prev; | 1003 | posn = pos->prev; |
1003 | 1004 | ||
1004 | switch (pos->event_loop_info) | 1005 | switch (pos->event_loop_info) |
1005 | { | 1006 | { |
1006 | case MHD_EVENT_LOOP_INFO_READ: | 1007 | case MHD_EVENT_LOOP_INFO_READ: |
1007 | if (! MHD_add_to_fd_set_ (pos->socket_fd, | 1008 | if (! MHD_add_to_fd_set_ (pos->socket_fd, |
1008 | read_fd_set, | 1009 | read_fd_set, |
1009 | max_fd, | 1010 | max_fd, |
1010 | fd_setsize)) | 1011 | fd_setsize)) |
1011 | result = MHD_NO; | 1012 | result = MHD_NO; |
1012 | #ifdef MHD_POSIX_SOCKETS | 1013 | #ifdef MHD_POSIX_SOCKETS |
1013 | MHD_add_to_fd_set_ (pos->socket_fd, | 1014 | MHD_add_to_fd_set_ (pos->socket_fd, |
1014 | except_fd_set, | 1015 | except_fd_set, |
1015 | max_fd, | 1016 | max_fd, |
1016 | fd_setsize); | 1017 | fd_setsize); |
1017 | #endif /* MHD_POSIX_SOCKETS */ | 1018 | #endif /* MHD_POSIX_SOCKETS */ |
1018 | break; | 1019 | break; |
1019 | case MHD_EVENT_LOOP_INFO_WRITE: | 1020 | case MHD_EVENT_LOOP_INFO_WRITE: |
1020 | if (! MHD_add_to_fd_set_ (pos->socket_fd, | 1021 | if (! MHD_add_to_fd_set_ (pos->socket_fd, |
1021 | write_fd_set, | 1022 | write_fd_set, |
1022 | max_fd, | 1023 | max_fd, |
1023 | fd_setsize)) | 1024 | fd_setsize)) |
1024 | result = MHD_NO; | 1025 | result = MHD_NO; |
1025 | #ifdef MHD_POSIX_SOCKETS | 1026 | #ifdef MHD_POSIX_SOCKETS |
1026 | MHD_add_to_fd_set_ (pos->socket_fd, | 1027 | MHD_add_to_fd_set_ (pos->socket_fd, |
1027 | except_fd_set, | 1028 | except_fd_set, |
1028 | max_fd, | 1029 | max_fd, |
1029 | fd_setsize); | 1030 | fd_setsize); |
1030 | #endif /* MHD_POSIX_SOCKETS */ | 1031 | #endif /* MHD_POSIX_SOCKETS */ |
1031 | break; | 1032 | break; |
1032 | case MHD_EVENT_LOOP_INFO_BLOCK: | 1033 | case MHD_EVENT_LOOP_INFO_BLOCK: |
1033 | if ( (NULL == except_fd_set) || | 1034 | if ( (NULL == except_fd_set) || |
1034 | ! MHD_add_to_fd_set_ (pos->socket_fd, | 1035 | ! MHD_add_to_fd_set_ (pos->socket_fd, |
1035 | except_fd_set, | 1036 | except_fd_set, |
1036 | max_fd, | 1037 | max_fd, |
1037 | fd_setsize)) | 1038 | fd_setsize)) |
1038 | result = MHD_NO; | 1039 | result = MHD_NO; |
1039 | break; | 1040 | break; |
1040 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 1041 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
1041 | /* this should never happen */ | 1042 | /* this should never happen */ |
1042 | break; | 1043 | break; |
1043 | } | ||
1044 | } | 1044 | } |
1045 | } | ||
1045 | #ifdef MHD_WINSOCK_SOCKETS | 1046 | #ifdef MHD_WINSOCK_SOCKETS |
1046 | /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets | 1047 | /* W32 use limited array for fd_set so add INFO_READ/INFO_WRITE sockets |
1047 | * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will | 1048 | * only after INFO_BLOCK sockets to ensure that INFO_BLOCK sockets will |
1048 | * not be pushed out. */ | 1049 | * not be pushed out. */ |
1049 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) | 1050 | for (pos = daemon->connections_tail; NULL != pos; pos = posn) |
1050 | { | 1051 | { |
1051 | posn = pos->prev; | 1052 | posn = pos->prev; |
1052 | MHD_add_to_fd_set_ (pos->socket_fd, | 1053 | MHD_add_to_fd_set_ (pos->socket_fd, |
1053 | except_fd_set, | 1054 | except_fd_set, |
1054 | max_fd, | 1055 | max_fd, |
1055 | fd_setsize); | 1056 | fd_setsize); |
1056 | } | 1057 | } |
1057 | #endif /* MHD_WINSOCK_SOCKETS */ | 1058 | #endif /* MHD_WINSOCK_SOCKETS */ |
1058 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 1059 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
1059 | { | 1060 | { |
1060 | struct MHD_UpgradeResponseHandle *urh; | 1061 | struct MHD_UpgradeResponseHandle *urh; |
1061 | 1062 | ||
1062 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) | 1063 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) |
1063 | { | 1064 | { |
1064 | if (MHD_NO == | 1065 | if (MHD_NO == |
1065 | urh_to_fdset (urh, | 1066 | urh_to_fdset (urh, |
1066 | read_fd_set, | 1067 | read_fd_set, |
1067 | write_fd_set, | 1068 | write_fd_set, |
1068 | except_fd_set, | 1069 | except_fd_set, |
1069 | max_fd, | 1070 | max_fd, |
1070 | fd_setsize)) | 1071 | fd_setsize)) |
1071 | result = MHD_NO; | 1072 | result = MHD_NO; |
1072 | } | 1073 | } |
1073 | } | 1074 | } |
1074 | #endif | 1075 | #endif |
1075 | #if DEBUG_CONNECT | 1076 | #if DEBUG_CONNECT |
1076 | #ifdef HAVE_MESSAGES | 1077 | #ifdef HAVE_MESSAGES |
1077 | if (NULL != max_fd) | 1078 | if (NULL != max_fd) |
1078 | MHD_DLOG (daemon, | 1079 | MHD_DLOG (daemon, |
1079 | _("Maximum socket in select set: %d\n"), | 1080 | _ ("Maximum socket in select set: %d\n"), |
1080 | *max_fd); | 1081 | *max_fd); |
1081 | #endif | 1082 | #endif |
1082 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 1083 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
@@ -1118,11 +1119,11 @@ internal_get_fdset2 (struct MHD_Daemon *daemon, | |||
1118 | */ | 1119 | */ |
1119 | int | 1120 | int |
1120 | MHD_get_fdset2 (struct MHD_Daemon *daemon, | 1121 | MHD_get_fdset2 (struct MHD_Daemon *daemon, |
1121 | fd_set *read_fd_set, | 1122 | fd_set *read_fd_set, |
1122 | fd_set *write_fd_set, | 1123 | fd_set *write_fd_set, |
1123 | fd_set *except_fd_set, | 1124 | fd_set *except_fd_set, |
1124 | MHD_socket *max_fd, | 1125 | MHD_socket *max_fd, |
1125 | unsigned int fd_setsize) | 1126 | unsigned int fd_setsize) |
1126 | { | 1127 | { |
1127 | fd_set es; | 1128 | fd_set es; |
1128 | 1129 | ||
@@ -1134,38 +1135,38 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon, | |||
1134 | return MHD_NO; | 1135 | return MHD_NO; |
1135 | 1136 | ||
1136 | if (NULL == except_fd_set) | 1137 | if (NULL == except_fd_set) |
1137 | { /* Workaround to maintain backward compatibility. */ | 1138 | { /* Workaround to maintain backward compatibility. */ |
1138 | #ifdef HAVE_MESSAGES | 1139 | #ifdef HAVE_MESSAGES |
1139 | MHD_DLOG (daemon, | 1140 | MHD_DLOG (daemon, |
1140 | _("MHD_get_fdset2() called with except_fd_set " | 1141 | _ ("MHD_get_fdset2() called with except_fd_set " |
1141 | "set to NULL. Such behavior is unsupported.\n")); | 1142 | "set to NULL. Such behavior is unsupported.\n")); |
1142 | #endif | 1143 | #endif |
1143 | FD_ZERO (&es); | 1144 | FD_ZERO (&es); |
1144 | except_fd_set = &es; | 1145 | except_fd_set = &es; |
1145 | } | 1146 | } |
1146 | 1147 | ||
1147 | #ifdef EPOLL_SUPPORT | 1148 | #ifdef EPOLL_SUPPORT |
1148 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 1149 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
1149 | { | 1150 | { |
1150 | if (daemon->shutdown) | 1151 | if (daemon->shutdown) |
1151 | return MHD_NO; | 1152 | return MHD_NO; |
1152 | 1153 | ||
1153 | /* we're in epoll mode, use the epoll FD as a stand-in for | 1154 | /* we're in epoll mode, use the epoll FD as a stand-in for |
1154 | the entire event set */ | 1155 | the entire event set */ |
1155 | 1156 | ||
1156 | return MHD_add_to_fd_set_ (daemon->epoll_fd, | 1157 | return MHD_add_to_fd_set_ (daemon->epoll_fd, |
1157 | read_fd_set, | 1158 | read_fd_set, |
1158 | max_fd, | 1159 | max_fd, |
1159 | fd_setsize) ? MHD_YES : MHD_NO; | 1160 | fd_setsize) ? MHD_YES : MHD_NO; |
1160 | } | 1161 | } |
1161 | #endif | 1162 | #endif |
1162 | 1163 | ||
1163 | return internal_get_fdset2 (daemon, | 1164 | return internal_get_fdset2 (daemon, |
1164 | read_fd_set, | 1165 | read_fd_set, |
1165 | write_fd_set, | 1166 | write_fd_set, |
1166 | except_fd_set, | 1167 | except_fd_set, |
1167 | max_fd, | 1168 | max_fd, |
1168 | fd_setsize); | 1169 | fd_setsize); |
1169 | } | 1170 | } |
1170 | 1171 | ||
1171 | 1172 | ||
@@ -1197,37 +1198,37 @@ call_handlers (struct MHD_Connection *con, | |||
1197 | if (con->tls_read_ready) | 1198 | if (con->tls_read_ready) |
1198 | read_ready = true; | 1199 | read_ready = true; |
1199 | #endif /* HTTPS_SUPPORT */ | 1200 | #endif /* HTTPS_SUPPORT */ |
1200 | if (!force_close) | 1201 | if (! force_close) |
1202 | { | ||
1203 | if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) && | ||
1204 | read_ready) | ||
1201 | { | 1205 | { |
1202 | if ( (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) && | 1206 | MHD_connection_handle_read (con); |
1203 | read_ready) | 1207 | ret = MHD_connection_handle_idle (con); |
1204 | { | 1208 | states_info_processed = true; |
1205 | MHD_connection_handle_read (con); | ||
1206 | ret = MHD_connection_handle_idle (con); | ||
1207 | states_info_processed = true; | ||
1208 | } | ||
1209 | /* No need to check value of 'ret' here as closed connection | ||
1210 | * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ | ||
1211 | if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) && | ||
1212 | write_ready) | ||
1213 | { | ||
1214 | MHD_connection_handle_write (con); | ||
1215 | ret = MHD_connection_handle_idle (con); | ||
1216 | states_info_processed = true; | ||
1217 | } | ||
1218 | } | 1209 | } |
1219 | else | 1210 | /* No need to check value of 'ret' here as closed connection |
1211 | * cannot be in MHD_EVENT_LOOP_INFO_WRITE state. */ | ||
1212 | if ( (MHD_EVENT_LOOP_INFO_WRITE == con->event_loop_info) && | ||
1213 | write_ready) | ||
1220 | { | 1214 | { |
1221 | MHD_connection_close_ (con, | 1215 | MHD_connection_handle_write (con); |
1222 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 1216 | ret = MHD_connection_handle_idle (con); |
1223 | return MHD_connection_handle_idle (con); | 1217 | states_info_processed = true; |
1224 | } | 1218 | } |
1219 | } | ||
1220 | else | ||
1221 | { | ||
1222 | MHD_connection_close_ (con, | ||
1223 | MHD_REQUEST_TERMINATED_WITH_ERROR); | ||
1224 | return MHD_connection_handle_idle (con); | ||
1225 | } | ||
1225 | 1226 | ||
1226 | if (!states_info_processed) | 1227 | if (! states_info_processed) |
1227 | { /* Connection is not read or write ready, but external conditions | 1228 | { /* Connection is not read or write ready, but external conditions |
1228 | * may be changed and need to be processed. */ | 1229 | * may be changed and need to be processed. */ |
1229 | ret = MHD_connection_handle_idle (con); | 1230 | ret = MHD_connection_handle_idle (con); |
1230 | } | 1231 | } |
1231 | /* Fast track for fast connections. */ | 1232 | /* Fast track for fast connections. */ |
1232 | /* If full request was read by single read_handler() invocation | 1233 | /* If full request was read by single read_handler() invocation |
1233 | and headers were completely prepared by single MHD_connection_handle_idle() | 1234 | and headers were completely prepared by single MHD_connection_handle_idle() |
@@ -1239,23 +1240,23 @@ call_handlers (struct MHD_Connection *con, | |||
1239 | /* No need to check 'ret' as connection is always in | 1240 | /* No need to check 'ret' as connection is always in |
1240 | * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ | 1241 | * MHD_CONNECTION_CLOSED state if 'ret' is equal 'MHD_NO'. */ |
1241 | else if (on_fasttrack && con->sk_nonblck) | 1242 | else if (on_fasttrack && con->sk_nonblck) |
1243 | { | ||
1244 | if (MHD_CONNECTION_HEADERS_SENDING == con->state) | ||
1242 | { | 1245 | { |
1243 | if (MHD_CONNECTION_HEADERS_SENDING == con->state) | 1246 | MHD_connection_handle_write (con); |
1244 | { | 1247 | /* Always call 'MHD_connection_handle_idle()' after each read/write. */ |
1245 | MHD_connection_handle_write (con); | 1248 | ret = MHD_connection_handle_idle (con); |
1246 | /* Always call 'MHD_connection_handle_idle()' after each read/write. */ | ||
1247 | ret = MHD_connection_handle_idle (con); | ||
1248 | } | ||
1249 | /* If all headers were sent by single write_handler() and | ||
1250 | * response body is prepared by single MHD_connection_handle_idle() | ||
1251 | * call - continue. */ | ||
1252 | if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) || | ||
1253 | (MHD_CONNECTION_CHUNKED_BODY_READY == con->state)) | ||
1254 | { | ||
1255 | MHD_connection_handle_write (con); | ||
1256 | ret = MHD_connection_handle_idle (con); | ||
1257 | } | ||
1258 | } | 1249 | } |
1250 | /* If all headers were sent by single write_handler() and | ||
1251 | * response body is prepared by single MHD_connection_handle_idle() | ||
1252 | * call - continue. */ | ||
1253 | if ((MHD_CONNECTION_NORMAL_BODY_READY == con->state) || | ||
1254 | (MHD_CONNECTION_CHUNKED_BODY_READY == con->state)) | ||
1255 | { | ||
1256 | MHD_connection_handle_write (con); | ||
1257 | ret = MHD_connection_handle_idle (con); | ||
1258 | } | ||
1259 | } | ||
1259 | 1260 | ||
1260 | /* All connection's data and states are processed for this turn. | 1261 | /* All connection's data and states are processed for this turn. |
1261 | * If connection already has more data to be processed - use | 1262 | * If connection already has more data to be processed - use |
@@ -1267,15 +1268,15 @@ call_handlers (struct MHD_Connection *con, | |||
1267 | * without space in read buffer will be marked as 'info block'. */ | 1268 | * without space in read buffer will be marked as 'info block'. */ |
1268 | if ( (! con->daemon->data_already_pending) && | 1269 | if ( (! con->daemon->data_already_pending) && |
1269 | (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ) | 1270 | (0 == (con->daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ) |
1270 | { | 1271 | { |
1271 | if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) | 1272 | if (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) |
1272 | con->daemon->data_already_pending = true; | 1273 | con->daemon->data_already_pending = true; |
1273 | #ifdef HTTPS_SUPPORT | 1274 | #ifdef HTTPS_SUPPORT |
1274 | else if ( (con->tls_read_ready) && | 1275 | else if ( (con->tls_read_ready) && |
1275 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) | 1276 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) |
1276 | con->daemon->data_already_pending = true; | 1277 | con->daemon->data_already_pending = true; |
1277 | #endif /* HTTPS_SUPPORT */ | 1278 | #endif /* HTTPS_SUPPORT */ |
1278 | } | 1279 | } |
1279 | return ret; | 1280 | return ret; |
1280 | } | 1281 | } |
1281 | 1282 | ||
@@ -1330,55 +1331,58 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1330 | * pointers to 'connection' and 'daemon' are not changed | 1331 | * pointers to 'connection' and 'daemon' are not changed |
1331 | * during this processing, so no need to chain dereference | 1332 | * during this processing, so no need to chain dereference |
1332 | * each time. */ | 1333 | * each time. */ |
1333 | struct MHD_Connection * const connection = urh->connection; | 1334 | struct MHD_Connection *const connection = urh->connection; |
1334 | struct MHD_Daemon * const daemon = connection->daemon; | 1335 | struct MHD_Daemon *const daemon = connection->daemon; |
1335 | /* Prevent data races: use same value of 'was_closed' throughout | 1336 | /* Prevent data races: use same value of 'was_closed' throughout |
1336 | * this function. If 'was_closed' changed externally in the middle | 1337 | * this function. If 'was_closed' changed externally in the middle |
1337 | * of processing - it will be processed on next iteration. */ | 1338 | * of processing - it will be processed on next iteration. */ |
1338 | bool was_closed; | 1339 | bool was_closed; |
1339 | if (daemon->shutdown) | 1340 | if (daemon->shutdown) |
1340 | { | 1341 | { |
1341 | /* Daemon shutting down, application will not receive any more data. */ | 1342 | /* Daemon shutting down, application will not receive any more data. */ |
1342 | #ifdef HAVE_MESSAGES | 1343 | #ifdef HAVE_MESSAGES |
1343 | if (! urh->was_closed) | 1344 | if (! urh->was_closed) |
1344 | { | 1345 | { |
1345 | MHD_DLOG (daemon, | 1346 | MHD_DLOG (daemon, |
1346 | _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | 1347 | _ ( |
1347 | } | 1348 | "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); |
1348 | #endif | ||
1349 | urh->was_closed = true; | ||
1350 | } | 1349 | } |
1350 | #endif | ||
1351 | urh->was_closed = true; | ||
1352 | } | ||
1351 | was_closed = urh->was_closed; | 1353 | was_closed = urh->was_closed; |
1352 | if (was_closed) | 1354 | if (was_closed) |
1355 | { | ||
1356 | /* Application was closed connections: no more data | ||
1357 | * can be forwarded to application socket. */ | ||
1358 | if (0 < urh->in_buffer_used) | ||
1353 | { | 1359 | { |
1354 | /* Application was closed connections: no more data | ||
1355 | * can be forwarded to application socket. */ | ||
1356 | if (0 < urh->in_buffer_used) | ||
1357 | { | ||
1358 | #ifdef HAVE_MESSAGES | 1360 | #ifdef HAVE_MESSAGES |
1359 | MHD_DLOG (daemon, | 1361 | MHD_DLOG (daemon, |
1360 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 1362 | _ ( |
1361 | " bytes of data received from remote side: application shut down socket\n"), | 1363 | "Failed to forward to application " |
1362 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | 1364 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
1363 | #endif | 1365 | " bytes of data received from remote side: application shut down socket\n"), |
1364 | 1366 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used); | |
1365 | } | 1367 | #endif |
1366 | /* If application signaled MHD about socket closure then | 1368 | |
1367 | * check for any pending data even if socket is not marked | 1369 | } |
1368 | * as 'ready' (signal may arrive after poll()/select()). | 1370 | /* If application signaled MHD about socket closure then |
1369 | * Socketpair for forwarding is always in non-blocking mode | 1371 | * check for any pending data even if socket is not marked |
1370 | * so no risk that recv() will block the thread. */ | 1372 | * as 'ready' (signal may arrive after poll()/select()). |
1371 | if (0 != urh->out_buffer_size) | 1373 | * Socketpair for forwarding is always in non-blocking mode |
1372 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; | 1374 | * so no risk that recv() will block the thread. */ |
1373 | /* Discard any data received form remote. */ | 1375 | if (0 != urh->out_buffer_size) |
1374 | urh->in_buffer_used = 0; | 1376 | urh->mhd.celi |= MHD_EPOLL_STATE_READ_READY; |
1375 | /* Do not try to push data to application. */ | 1377 | /* Discard any data received form remote. */ |
1376 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1378 | urh->in_buffer_used = 0; |
1377 | /* Reading from remote client is not required anymore. */ | 1379 | /* Do not try to push data to application. */ |
1378 | urh->in_buffer_size = 0; | 1380 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1379 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1381 | /* Reading from remote client is not required anymore. */ |
1380 | connection->tls_read_ready = false; | 1382 | urh->in_buffer_size = 0; |
1381 | } | 1383 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1384 | connection->tls_read_ready = false; | ||
1385 | } | ||
1382 | 1386 | ||
1383 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always | 1387 | /* On some platforms (W32, possibly Darwin) failed send() (send() will always |
1384 | * fail after remote disconnect was detected) may discard data in system | 1388 | * fail after remote disconnect was detected) may discard data in system |
@@ -1399,237 +1403,241 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1399 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || | 1403 | if ( ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->app.celi)) || |
1400 | (connection->tls_read_ready) ) && | 1404 | (connection->tls_read_ready) ) && |
1401 | (urh->in_buffer_used < urh->in_buffer_size) ) | 1405 | (urh->in_buffer_used < urh->in_buffer_size) ) |
1402 | { | 1406 | { |
1403 | ssize_t res; | 1407 | ssize_t res; |
1404 | size_t buf_size; | 1408 | size_t buf_size; |
1405 | 1409 | ||
1406 | buf_size = urh->in_buffer_size - urh->in_buffer_used; | 1410 | buf_size = urh->in_buffer_size - urh->in_buffer_used; |
1407 | if (buf_size > SSIZE_MAX) | 1411 | if (buf_size > SSIZE_MAX) |
1408 | buf_size = SSIZE_MAX; | 1412 | buf_size = SSIZE_MAX; |
1409 | 1413 | ||
1410 | connection->tls_read_ready = false; | 1414 | connection->tls_read_ready = false; |
1411 | res = gnutls_record_recv (connection->tls_session, | 1415 | res = gnutls_record_recv (connection->tls_session, |
1412 | &urh->in_buffer[urh->in_buffer_used], | 1416 | &urh->in_buffer[urh->in_buffer_used], |
1413 | buf_size); | 1417 | buf_size); |
1414 | if (0 >= res) | 1418 | if (0 >= res) |
1415 | { | 1419 | { |
1416 | if (GNUTLS_E_INTERRUPTED != res) | 1420 | if (GNUTLS_E_INTERRUPTED != res) |
1417 | { | 1421 | { |
1418 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1422 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1419 | if (GNUTLS_E_AGAIN != res) | 1423 | if (GNUTLS_E_AGAIN != res) |
1420 | { | ||
1421 | /* Unrecoverable error on socket was detected or | ||
1422 | * socket was disconnected/shut down. */ | ||
1423 | /* Stop trying to read from this TLS socket. */ | ||
1424 | urh->in_buffer_size = 0; | ||
1425 | } | ||
1426 | } | ||
1427 | } | ||
1428 | else /* 0 < res */ | ||
1429 | { | ||
1430 | urh->in_buffer_used += res; | ||
1431 | if (buf_size > (size_t)res) | ||
1432 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1433 | else if (0 < gnutls_record_check_pending (connection->tls_session)) | ||
1434 | connection->tls_read_ready = true; | ||
1435 | } | ||
1436 | if (MHD_EPOLL_STATE_ERROR == | ||
1437 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
1438 | { | 1424 | { |
1439 | /* Unrecoverable error on socket was detected and all | 1425 | /* Unrecoverable error on socket was detected or |
1440 | * pending data was read from system buffers. */ | 1426 | * socket was disconnected/shut down. */ |
1441 | /* Stop trying to read from this TLS socket. */ | 1427 | /* Stop trying to read from this TLS socket. */ |
1442 | urh->in_buffer_size = 0; | 1428 | urh->in_buffer_size = 0; |
1443 | } | 1429 | } |
1430 | } | ||
1431 | } | ||
1432 | else /* 0 < res */ | ||
1433 | { | ||
1434 | urh->in_buffer_used += res; | ||
1435 | if (buf_size > (size_t) res) | ||
1436 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1437 | else if (0 < gnutls_record_check_pending (connection->tls_session)) | ||
1438 | connection->tls_read_ready = true; | ||
1439 | } | ||
1440 | if (MHD_EPOLL_STATE_ERROR == | ||
1441 | ((MHD_EPOLL_STATE_ERROR | MHD_EPOLL_STATE_READ_READY) & urh->app.celi)) | ||
1442 | { | ||
1443 | /* Unrecoverable error on socket was detected and all | ||
1444 | * pending data was read from system buffers. */ | ||
1445 | /* Stop trying to read from this TLS socket. */ | ||
1446 | urh->in_buffer_size = 0; | ||
1444 | } | 1447 | } |
1448 | } | ||
1445 | 1449 | ||
1446 | /* | 1450 | /* |
1447 | * handle reading from application | 1451 | * handle reading from application |
1448 | */ | 1452 | */ |
1449 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | 1453 | if ( (0 != (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && |
1450 | (urh->out_buffer_used < urh->out_buffer_size) ) | 1454 | (urh->out_buffer_used < urh->out_buffer_size) ) |
1451 | { | 1455 | { |
1452 | ssize_t res; | 1456 | ssize_t res; |
1453 | size_t buf_size; | 1457 | size_t buf_size; |
1454 | 1458 | ||
1455 | buf_size = urh->out_buffer_size - urh->out_buffer_used; | 1459 | buf_size = urh->out_buffer_size - urh->out_buffer_used; |
1456 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) | 1460 | if (buf_size > MHD_SCKT_SEND_MAX_SIZE_) |
1457 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; | 1461 | buf_size = MHD_SCKT_SEND_MAX_SIZE_; |
1458 | 1462 | ||
1459 | res = MHD_recv_ (urh->mhd.socket, | 1463 | res = MHD_recv_ (urh->mhd.socket, |
1460 | &urh->out_buffer[urh->out_buffer_used], | 1464 | &urh->out_buffer[urh->out_buffer_used], |
1461 | buf_size); | 1465 | buf_size); |
1462 | if (0 >= res) | 1466 | if (0 >= res) |
1463 | { | 1467 | { |
1464 | const int err = MHD_socket_get_error_ (); | 1468 | const int err = MHD_socket_get_error_ (); |
1465 | if ((0 == res) || | 1469 | if ((0 == res) || |
1466 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 1470 | ((! MHD_SCKT_ERR_IS_EINTR_ (err)) && |
1467 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)))) | 1471 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)))) |
1468 | { | 1472 | { |
1469 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1473 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1470 | if ((0 == res) || | 1474 | if ((0 == res) || |
1471 | (was_closed) || | 1475 | (was_closed) || |
1472 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | 1476 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || |
1473 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) | 1477 | (! MHD_SCKT_ERR_IS_EAGAIN_ (err))) |
1474 | { | ||
1475 | /* Socket disconnect/shutdown was detected; | ||
1476 | * Application signaled about closure of 'upgraded' socket; | ||
1477 | * or persistent / unrecoverable error. */ | ||
1478 | /* Do not try to pull more data from application. */ | ||
1479 | urh->out_buffer_size = 0; | ||
1480 | } | ||
1481 | } | ||
1482 | } | ||
1483 | else /* 0 < res */ | ||
1484 | { | ||
1485 | urh->out_buffer_used += res; | ||
1486 | if (buf_size > (size_t)res) | ||
1487 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1488 | } | ||
1489 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
1490 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
1491 | (was_closed) ) ) | ||
1492 | { | 1478 | { |
1493 | /* Unrecoverable error on socket was detected and all | 1479 | /* Socket disconnect/shutdown was detected; |
1494 | * pending data was read from system buffers. */ | 1480 | * Application signaled about closure of 'upgraded' socket; |
1481 | * or persistent / unrecoverable error. */ | ||
1495 | /* Do not try to pull more data from application. */ | 1482 | /* Do not try to pull more data from application. */ |
1496 | urh->out_buffer_size = 0; | 1483 | urh->out_buffer_size = 0; |
1497 | } | 1484 | } |
1485 | } | ||
1486 | } | ||
1487 | else /* 0 < res */ | ||
1488 | { | ||
1489 | urh->out_buffer_used += res; | ||
1490 | if (buf_size > (size_t) res) | ||
1491 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1492 | } | ||
1493 | if ( (0 == (MHD_EPOLL_STATE_READ_READY & urh->mhd.celi)) && | ||
1494 | ( (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) || | ||
1495 | (was_closed) ) ) | ||
1496 | { | ||
1497 | /* Unrecoverable error on socket was detected and all | ||
1498 | * pending data was read from system buffers. */ | ||
1499 | /* Do not try to pull more data from application. */ | ||
1500 | urh->out_buffer_size = 0; | ||
1498 | } | 1501 | } |
1502 | } | ||
1499 | 1503 | ||
1500 | /* | 1504 | /* |
1501 | * handle writing to remote HTTPS client | 1505 | * handle writing to remote HTTPS client |
1502 | */ | 1506 | */ |
1503 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && | 1507 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->app.celi)) && |
1504 | (urh->out_buffer_used > 0) ) | 1508 | (urh->out_buffer_used > 0) ) |
1505 | { | 1509 | { |
1506 | ssize_t res; | 1510 | ssize_t res; |
1507 | size_t data_size; | 1511 | size_t data_size; |
1508 | 1512 | ||
1509 | data_size = urh->out_buffer_used; | 1513 | data_size = urh->out_buffer_used; |
1510 | if (data_size > SSIZE_MAX) | 1514 | if (data_size > SSIZE_MAX) |
1511 | data_size = SSIZE_MAX; | 1515 | data_size = SSIZE_MAX; |
1512 | 1516 | ||
1513 | res = gnutls_record_send (connection->tls_session, | 1517 | res = gnutls_record_send (connection->tls_session, |
1514 | urh->out_buffer, | 1518 | urh->out_buffer, |
1515 | data_size); | 1519 | data_size); |
1516 | if (0 >= res) | 1520 | if (0 >= res) |
1517 | { | 1521 | { |
1518 | if (GNUTLS_E_INTERRUPTED != res) | 1522 | if (GNUTLS_E_INTERRUPTED != res) |
1519 | { | 1523 | { |
1520 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1524 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1521 | if (GNUTLS_E_AGAIN != res) | 1525 | if (GNUTLS_E_AGAIN != res) |
1522 | { | ||
1523 | /* TLS connection shut down or | ||
1524 | * persistent / unrecoverable error. */ | ||
1525 | #ifdef HAVE_MESSAGES | ||
1526 | MHD_DLOG (daemon, | ||
1527 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1528 | " bytes of data received from application: %s\n"), | ||
1529 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, | ||
1530 | gnutls_strerror(res)); | ||
1531 | #endif | ||
1532 | /* Discard any data unsent to remote. */ | ||
1533 | urh->out_buffer_used = 0; | ||
1534 | /* Do not try to pull more data from application. */ | ||
1535 | urh->out_buffer_size = 0; | ||
1536 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1537 | } | ||
1538 | } | ||
1539 | } | ||
1540 | else /* 0 < res */ | ||
1541 | { | ||
1542 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
1543 | if (0 != next_out_buffer_used) | ||
1544 | { | ||
1545 | memmove (urh->out_buffer, | ||
1546 | &urh->out_buffer[res], | ||
1547 | next_out_buffer_used); | ||
1548 | if (data_size > (size_t)res) | ||
1549 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1550 | } | ||
1551 | urh->out_buffer_used = next_out_buffer_used; | ||
1552 | } | ||
1553 | if ( (0 == urh->out_buffer_used) && | ||
1554 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
1555 | { | 1526 | { |
1556 | /* Unrecoverable error on socket was detected and all | 1527 | /* TLS connection shut down or |
1557 | * pending data was sent to remote. */ | 1528 | * persistent / unrecoverable error. */ |
1558 | /* Do not try to send to remote anymore. */ | 1529 | #ifdef HAVE_MESSAGES |
1559 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1530 | MHD_DLOG (daemon, |
1531 | _ ( | ||
1532 | "Failed to forward to remote client " | ||
1533 | MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1534 | " bytes of data received from application: %s\n"), | ||
1535 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used, | ||
1536 | gnutls_strerror (res)); | ||
1537 | #endif | ||
1538 | /* Discard any data unsent to remote. */ | ||
1539 | urh->out_buffer_used = 0; | ||
1560 | /* Do not try to pull more data from application. */ | 1540 | /* Do not try to pull more data from application. */ |
1561 | urh->out_buffer_size = 0; | 1541 | urh->out_buffer_size = 0; |
1562 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1542 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1563 | } | 1543 | } |
1544 | } | ||
1564 | } | 1545 | } |
1546 | else /* 0 < res */ | ||
1547 | { | ||
1548 | const size_t next_out_buffer_used = urh->out_buffer_used - res; | ||
1549 | if (0 != next_out_buffer_used) | ||
1550 | { | ||
1551 | memmove (urh->out_buffer, | ||
1552 | &urh->out_buffer[res], | ||
1553 | next_out_buffer_used); | ||
1554 | if (data_size > (size_t) res) | ||
1555 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1556 | } | ||
1557 | urh->out_buffer_used = next_out_buffer_used; | ||
1558 | } | ||
1559 | if ( (0 == urh->out_buffer_used) && | ||
1560 | (0 != (MHD_EPOLL_STATE_ERROR & urh->app.celi)) ) | ||
1561 | { | ||
1562 | /* Unrecoverable error on socket was detected and all | ||
1563 | * pending data was sent to remote. */ | ||
1564 | /* Do not try to send to remote anymore. */ | ||
1565 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1566 | /* Do not try to pull more data from application. */ | ||
1567 | urh->out_buffer_size = 0; | ||
1568 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1569 | } | ||
1570 | } | ||
1565 | 1571 | ||
1566 | /* | 1572 | /* |
1567 | * handle writing to application | 1573 | * handle writing to application |
1568 | */ | 1574 | */ |
1569 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && | 1575 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && |
1570 | (urh->in_buffer_used > 0) ) | 1576 | (urh->in_buffer_used > 0) ) |
1571 | { | 1577 | { |
1572 | ssize_t res; | 1578 | ssize_t res; |
1573 | size_t data_size; | 1579 | size_t data_size; |
1574 | 1580 | ||
1575 | data_size = urh->in_buffer_used; | 1581 | data_size = urh->in_buffer_used; |
1576 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) | 1582 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) |
1577 | data_size = MHD_SCKT_SEND_MAX_SIZE_; | 1583 | data_size = MHD_SCKT_SEND_MAX_SIZE_; |
1578 | 1584 | ||
1579 | res = MHD_send_ (urh->mhd.socket, | 1585 | res = MHD_send_ (urh->mhd.socket, |
1580 | urh->in_buffer, | 1586 | urh->in_buffer, |
1581 | data_size); | 1587 | data_size); |
1582 | if (0 >= res) | 1588 | if (0 >= res) |
1583 | { | 1589 | { |
1584 | const int err = MHD_socket_get_error_ (); | 1590 | const int err = MHD_socket_get_error_ (); |
1585 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && | 1591 | if ( (! MHD_SCKT_ERR_IS_EINTR_ (err)) && |
1586 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_(err)) ) | 1592 | (! MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err)) ) |
1587 | { | 1593 | { |
1588 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1594 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1589 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) | 1595 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err)) |
1590 | { | ||
1591 | /* Socketpair connection shut down or | ||
1592 | * persistent / unrecoverable error. */ | ||
1593 | #ifdef HAVE_MESSAGES | ||
1594 | MHD_DLOG (daemon, | ||
1595 | _("Failed to forward to application " MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1596 | " bytes of data received from remote side: %s\n"), | ||
1597 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | ||
1598 | MHD_socket_strerr_ (err)); | ||
1599 | #endif | ||
1600 | /* Discard any data received form remote. */ | ||
1601 | urh->in_buffer_used = 0; | ||
1602 | /* Reading from remote client is not required anymore. */ | ||
1603 | urh->in_buffer_size = 0; | ||
1604 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1605 | connection->tls_read_ready = false; | ||
1606 | } | ||
1607 | } | ||
1608 | } | ||
1609 | else /* 0 < res */ | ||
1610 | { | ||
1611 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
1612 | if (0 != next_in_buffer_used) | ||
1613 | { | ||
1614 | memmove (urh->in_buffer, | ||
1615 | &urh->in_buffer[res], | ||
1616 | next_in_buffer_used); | ||
1617 | if (data_size > (size_t)res) | ||
1618 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1619 | } | ||
1620 | urh->in_buffer_used = next_in_buffer_used; | ||
1621 | } | ||
1622 | if ( (0 == urh->in_buffer_used) && | ||
1623 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
1624 | { | 1596 | { |
1625 | /* Do not try to push data to application. */ | 1597 | /* Socketpair connection shut down or |
1626 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1598 | * persistent / unrecoverable error. */ |
1599 | #ifdef HAVE_MESSAGES | ||
1600 | MHD_DLOG (daemon, | ||
1601 | _ ( | ||
1602 | "Failed to forward to application " | ||
1603 | MHD_UNSIGNED_LONG_LONG_PRINTF \ | ||
1604 | " bytes of data received from remote side: %s\n"), | ||
1605 | (MHD_UNSIGNED_LONG_LONG) urh->in_buffer_used, | ||
1606 | MHD_socket_strerr_ (err)); | ||
1607 | #endif | ||
1608 | /* Discard any data received form remote. */ | ||
1609 | urh->in_buffer_used = 0; | ||
1627 | /* Reading from remote client is not required anymore. */ | 1610 | /* Reading from remote client is not required anymore. */ |
1628 | urh->in_buffer_size = 0; | 1611 | urh->in_buffer_size = 0; |
1629 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1612 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; |
1630 | connection->tls_read_ready = false; | 1613 | connection->tls_read_ready = false; |
1631 | } | 1614 | } |
1615 | } | ||
1616 | } | ||
1617 | else /* 0 < res */ | ||
1618 | { | ||
1619 | const size_t next_in_buffer_used = urh->in_buffer_used - res; | ||
1620 | if (0 != next_in_buffer_used) | ||
1621 | { | ||
1622 | memmove (urh->in_buffer, | ||
1623 | &urh->in_buffer[res], | ||
1624 | next_in_buffer_used); | ||
1625 | if (data_size > (size_t) res) | ||
1626 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1627 | } | ||
1628 | urh->in_buffer_used = next_in_buffer_used; | ||
1629 | } | ||
1630 | if ( (0 == urh->in_buffer_used) && | ||
1631 | (0 != (MHD_EPOLL_STATE_ERROR & urh->mhd.celi)) ) | ||
1632 | { | ||
1633 | /* Do not try to push data to application. */ | ||
1634 | urh->mhd.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | ||
1635 | /* Reading from remote client is not required anymore. */ | ||
1636 | urh->in_buffer_size = 0; | ||
1637 | urh->app.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1638 | connection->tls_read_ready = false; | ||
1632 | } | 1639 | } |
1640 | } | ||
1633 | 1641 | ||
1634 | /* Check whether data is present in TLS buffers | 1642 | /* Check whether data is present in TLS buffers |
1635 | * and incoming forward buffer have some space. */ | 1643 | * and incoming forward buffer have some space. */ |
@@ -1641,23 +1649,25 @@ process_urh (struct MHD_UpgradeResponseHandle *urh) | |||
1641 | if ( (daemon->shutdown) && | 1649 | if ( (daemon->shutdown) && |
1642 | ( (0 != urh->out_buffer_size) || | 1650 | ( (0 != urh->out_buffer_size) || |
1643 | (0 != urh->out_buffer_used) ) ) | 1651 | (0 != urh->out_buffer_used) ) ) |
1644 | { | 1652 | { |
1645 | /* Daemon shutting down, discard any remaining forward data. */ | 1653 | /* Daemon shutting down, discard any remaining forward data. */ |
1646 | #ifdef HAVE_MESSAGES | 1654 | #ifdef HAVE_MESSAGES |
1647 | if (0 < urh->out_buffer_used) | 1655 | if (0 < urh->out_buffer_used) |
1648 | MHD_DLOG (daemon, | 1656 | MHD_DLOG (daemon, |
1649 | _("Failed to forward to remote client " MHD_UNSIGNED_LONG_LONG_PRINTF \ | 1657 | _ ( |
1650 | " bytes of data received from application: daemon shut down\n"), | 1658 | "Failed to forward to remote client " |
1651 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); | 1659 | MHD_UNSIGNED_LONG_LONG_PRINTF \ |
1652 | #endif | 1660 | " bytes of data received from application: daemon shut down\n"), |
1653 | /* Discard any data unsent to remote. */ | 1661 | (MHD_UNSIGNED_LONG_LONG) urh->out_buffer_used); |
1654 | urh->out_buffer_used = 0; | 1662 | #endif |
1655 | /* Do not try to sent to remote anymore. */ | 1663 | /* Discard any data unsent to remote. */ |
1656 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; | 1664 | urh->out_buffer_used = 0; |
1657 | /* Do not try to pull more data from application. */ | 1665 | /* Do not try to sent to remote anymore. */ |
1658 | urh->out_buffer_size = 0; | 1666 | urh->app.celi &= ~MHD_EPOLL_STATE_WRITE_READY; |
1659 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | 1667 | /* Do not try to pull more data from application. */ |
1660 | } | 1668 | urh->out_buffer_size = 0; |
1669 | urh->mhd.celi &= ~MHD_EPOLL_STATE_READ_READY; | ||
1670 | } | ||
1661 | } | 1671 | } |
1662 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 1672 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
1663 | 1673 | ||
@@ -1682,128 +1692,128 @@ thread_main_connection_upgrade (struct MHD_Connection *con) | |||
1682 | until the application tells us that it is done | 1692 | until the application tells us that it is done |
1683 | with the socket; */ | 1693 | with the socket; */ |
1684 | if ( (0 != (daemon->options & MHD_USE_TLS)) && | 1694 | if ( (0 != (daemon->options & MHD_USE_TLS)) && |
1685 | (0 == (daemon->options & MHD_USE_POLL))) | 1695 | (0 == (daemon->options & MHD_USE_POLL))) |
1686 | { | 1696 | { |
1687 | while ( (0 != urh->in_buffer_size) || | 1697 | while ( (0 != urh->in_buffer_size) || |
1688 | (0 != urh->out_buffer_size) || | 1698 | (0 != urh->out_buffer_size) || |
1689 | (0 != urh->in_buffer_used) || | 1699 | (0 != urh->in_buffer_used) || |
1690 | (0 != urh->out_buffer_used) ) | 1700 | (0 != urh->out_buffer_used) ) |
1691 | { | 1701 | { |
1692 | /* use select */ | 1702 | /* use select */ |
1693 | fd_set rs; | 1703 | fd_set rs; |
1694 | fd_set ws; | 1704 | fd_set ws; |
1695 | fd_set es; | 1705 | fd_set es; |
1696 | MHD_socket max_fd; | 1706 | MHD_socket max_fd; |
1697 | int num_ready; | 1707 | int num_ready; |
1698 | bool result; | 1708 | bool result; |
1699 | 1709 | ||
1700 | FD_ZERO (&rs); | 1710 | FD_ZERO (&rs); |
1701 | FD_ZERO (&ws); | 1711 | FD_ZERO (&ws); |
1702 | FD_ZERO (&es); | 1712 | FD_ZERO (&es); |
1703 | max_fd = MHD_INVALID_SOCKET; | 1713 | max_fd = MHD_INVALID_SOCKET; |
1704 | result = urh_to_fdset (urh, | 1714 | result = urh_to_fdset (urh, |
1705 | &rs, | 1715 | &rs, |
1706 | &ws, | 1716 | &ws, |
1707 | &es, | 1717 | &es, |
1708 | &max_fd, | 1718 | &max_fd, |
1709 | FD_SETSIZE); | 1719 | FD_SETSIZE); |
1710 | if (! result) | 1720 | if (! result) |
1711 | { | 1721 | { |
1712 | #ifdef HAVE_MESSAGES | 1722 | #ifdef HAVE_MESSAGES |
1713 | MHD_DLOG (con->daemon, | 1723 | MHD_DLOG (con->daemon, |
1714 | _("Error preparing select\n")); | 1724 | _ ("Error preparing select\n")); |
1715 | #endif | 1725 | #endif |
1716 | break; | 1726 | break; |
1717 | } | 1727 | } |
1718 | /* FIXME: does this check really needed? */ | 1728 | /* FIXME: does this check really needed? */ |
1719 | if (MHD_INVALID_SOCKET != max_fd) | 1729 | if (MHD_INVALID_SOCKET != max_fd) |
1720 | { | 1730 | { |
1721 | struct timeval* tvp; | 1731 | struct timeval*tvp; |
1722 | struct timeval tv; | 1732 | struct timeval tv; |
1723 | if ( (con->tls_read_ready) && | 1733 | if ( (con->tls_read_ready) && |
1724 | (urh->in_buffer_used < urh->in_buffer_size)) | 1734 | (urh->in_buffer_used < urh->in_buffer_size)) |
1725 | { /* No need to wait if incoming data is already pending in TLS buffers. */ | 1735 | { /* No need to wait if incoming data is already pending in TLS buffers. */ |
1726 | tv.tv_sec = 0; | 1736 | tv.tv_sec = 0; |
1727 | tv.tv_usec = 0; | 1737 | tv.tv_usec = 0; |
1728 | tvp = &tv; | 1738 | tvp = &tv; |
1729 | } | ||
1730 | else | ||
1731 | tvp = NULL; | ||
1732 | num_ready = MHD_SYS_select_ (max_fd + 1, | ||
1733 | &rs, | ||
1734 | &ws, | ||
1735 | &es, | ||
1736 | tvp); | ||
1737 | } | ||
1738 | else | ||
1739 | num_ready = 0; | ||
1740 | if (num_ready < 0) | ||
1741 | { | ||
1742 | const int err = MHD_socket_get_error_(); | ||
1743 | |||
1744 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | ||
1745 | continue; | ||
1746 | #ifdef HAVE_MESSAGES | ||
1747 | MHD_DLOG (con->daemon, | ||
1748 | _("Error during select (%d): `%s'\n"), | ||
1749 | err, | ||
1750 | MHD_socket_strerr_ (err)); | ||
1751 | #endif | ||
1752 | break; | ||
1753 | } | ||
1754 | urh_from_fdset (urh, | ||
1755 | &rs, | ||
1756 | &ws, | ||
1757 | &es); | ||
1758 | process_urh (urh); | ||
1759 | } | 1739 | } |
1740 | else | ||
1741 | tvp = NULL; | ||
1742 | num_ready = MHD_SYS_select_ (max_fd + 1, | ||
1743 | &rs, | ||
1744 | &ws, | ||
1745 | &es, | ||
1746 | tvp); | ||
1747 | } | ||
1748 | else | ||
1749 | num_ready = 0; | ||
1750 | if (num_ready < 0) | ||
1751 | { | ||
1752 | const int err = MHD_socket_get_error_ (); | ||
1753 | |||
1754 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
1755 | continue; | ||
1756 | #ifdef HAVE_MESSAGES | ||
1757 | MHD_DLOG (con->daemon, | ||
1758 | _ ("Error during select (%d): `%s'\n"), | ||
1759 | err, | ||
1760 | MHD_socket_strerr_ (err)); | ||
1761 | #endif | ||
1762 | break; | ||
1763 | } | ||
1764 | urh_from_fdset (urh, | ||
1765 | &rs, | ||
1766 | &ws, | ||
1767 | &es); | ||
1768 | process_urh (urh); | ||
1760 | } | 1769 | } |
1770 | } | ||
1761 | #ifdef HAVE_POLL | 1771 | #ifdef HAVE_POLL |
1762 | else if (0 != (daemon->options & MHD_USE_TLS)) | 1772 | else if (0 != (daemon->options & MHD_USE_TLS)) |
1763 | { | 1773 | { |
1764 | /* use poll() */ | 1774 | /* use poll() */ |
1765 | struct pollfd p[2]; | 1775 | struct pollfd p[2]; |
1766 | memset (p, | 1776 | memset (p, |
1767 | 0, | 1777 | 0, |
1768 | sizeof (p)); | 1778 | sizeof (p)); |
1769 | p[0].fd = urh->connection->socket_fd; | 1779 | p[0].fd = urh->connection->socket_fd; |
1770 | p[1].fd = urh->mhd.socket; | 1780 | p[1].fd = urh->mhd.socket; |
1781 | |||
1782 | while ( (0 != urh->in_buffer_size) || | ||
1783 | (0 != urh->out_buffer_size) || | ||
1784 | (0 != urh->in_buffer_used) || | ||
1785 | (0 != urh->out_buffer_used) ) | ||
1786 | { | ||
1787 | int timeout; | ||
1788 | |||
1789 | urh_update_pollfd (urh, p); | ||
1790 | |||
1791 | if ( (con->tls_read_ready) && | ||
1792 | (urh->in_buffer_used < urh->in_buffer_size)) | ||
1793 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ | ||
1794 | else | ||
1795 | timeout = -1; | ||
1771 | 1796 | ||
1772 | while ( (0 != urh->in_buffer_size) || | 1797 | if (MHD_sys_poll_ (p, |
1773 | (0 != urh->out_buffer_size) || | 1798 | 2, |
1774 | (0 != urh->in_buffer_used) || | 1799 | timeout) < 0) |
1775 | (0 != urh->out_buffer_used) ) | 1800 | { |
1776 | { | 1801 | const int err = MHD_socket_get_error_ (); |
1777 | int timeout; | 1802 | |
1778 | 1803 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | |
1779 | urh_update_pollfd(urh, p); | 1804 | continue; |
1780 | 1805 | #ifdef HAVE_MESSAGES | |
1781 | if ( (con->tls_read_ready) && | 1806 | MHD_DLOG (con->daemon, |
1782 | (urh->in_buffer_used < urh->in_buffer_size)) | 1807 | _ ("Error during poll: `%s'\n"), |
1783 | timeout = 0; /* No need to wait if incoming data is already pending in TLS buffers. */ | 1808 | MHD_socket_strerr_ (err)); |
1784 | else | 1809 | #endif |
1785 | timeout = -1; | 1810 | break; |
1786 | 1811 | } | |
1787 | if (MHD_sys_poll_ (p, | 1812 | urh_from_pollfd (urh, |
1788 | 2, | 1813 | p); |
1789 | timeout) < 0) | 1814 | process_urh (urh); |
1790 | { | ||
1791 | const int err = MHD_socket_get_error_ (); | ||
1792 | |||
1793 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
1794 | continue; | ||
1795 | #ifdef HAVE_MESSAGES | ||
1796 | MHD_DLOG (con->daemon, | ||
1797 | _("Error during poll: `%s'\n"), | ||
1798 | MHD_socket_strerr_ (err)); | ||
1799 | #endif | ||
1800 | break; | ||
1801 | } | ||
1802 | urh_from_pollfd (urh, | ||
1803 | p); | ||
1804 | process_urh (urh); | ||
1805 | } | ||
1806 | } | 1815 | } |
1816 | } | ||
1807 | /* end POLL */ | 1817 | /* end POLL */ |
1808 | #endif | 1818 | #endif |
1809 | /* end HTTPS */ | 1819 | /* end HTTPS */ |
@@ -1854,346 +1864,348 @@ thread_main_handle_connection (void *data) | |||
1854 | const bool use_poll = 0; | 1864 | const bool use_poll = 0; |
1855 | #endif /* ! HAVE_POLL */ | 1865 | #endif /* ! HAVE_POLL */ |
1856 | bool was_suspended = false; | 1866 | bool was_suspended = false; |
1857 | MHD_thread_init_(&(con->pid)); | 1867 | MHD_thread_init_ (&(con->pid)); |
1858 | 1868 | ||
1859 | while ( (! daemon->shutdown) && | 1869 | while ( (! daemon->shutdown) && |
1860 | (MHD_CONNECTION_CLOSED != con->state) ) | 1870 | (MHD_CONNECTION_CLOSED != con->state) ) |
1861 | { | 1871 | { |
1862 | const time_t timeout = daemon->connection_timeout; | 1872 | const time_t timeout = daemon->connection_timeout; |
1863 | #ifdef UPGRADE_SUPPORT | 1873 | #ifdef UPGRADE_SUPPORT |
1864 | struct MHD_UpgradeResponseHandle * const urh = con->urh; | 1874 | struct MHD_UpgradeResponseHandle *const urh = con->urh; |
1865 | #else /* ! UPGRADE_SUPPORT */ | 1875 | #else /* ! UPGRADE_SUPPORT */ |
1866 | static const void * const urh = NULL; | 1876 | static const void *const urh = NULL; |
1867 | #endif /* ! UPGRADE_SUPPORT */ | 1877 | #endif /* ! UPGRADE_SUPPORT */ |
1868 | 1878 | ||
1869 | if ( (con->suspended) && | 1879 | if ( (con->suspended) && |
1870 | (NULL == urh) ) | 1880 | (NULL == urh) ) |
1881 | { | ||
1882 | /* Connection was suspended, wait for resume. */ | ||
1883 | was_suspended = true; | ||
1884 | if (! use_poll) | ||
1885 | { | ||
1886 | FD_ZERO (&rs); | ||
1887 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
1888 | &rs, | ||
1889 | NULL, | ||
1890 | FD_SETSIZE)) | ||
1871 | { | 1891 | { |
1872 | /* Connection was suspended, wait for resume. */ | ||
1873 | was_suspended = true; | ||
1874 | if (! use_poll) | ||
1875 | { | ||
1876 | FD_ZERO (&rs); | ||
1877 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | ||
1878 | &rs, | ||
1879 | NULL, | ||
1880 | FD_SETSIZE)) | ||
1881 | { | ||
1882 | #ifdef HAVE_MESSAGES | 1892 | #ifdef HAVE_MESSAGES |
1883 | MHD_DLOG (con->daemon, | 1893 | MHD_DLOG (con->daemon, |
1884 | _("Failed to add FD to fd_set\n")); | 1894 | _ ("Failed to add FD to fd_set\n")); |
1885 | #endif | 1895 | #endif |
1886 | goto exit; | 1896 | goto exit; |
1887 | } | 1897 | } |
1888 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, | 1898 | if (0 > MHD_SYS_select_ (MHD_itc_r_fd_ (daemon->itc) + 1, |
1889 | &rs, | 1899 | &rs, |
1890 | NULL, | 1900 | NULL, |
1891 | NULL, | 1901 | NULL, |
1892 | NULL)) | 1902 | NULL)) |
1893 | { | 1903 | { |
1894 | const int err = MHD_socket_get_error_(); | 1904 | const int err = MHD_socket_get_error_ (); |
1895 | |||
1896 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | ||
1897 | continue; | ||
1898 | #ifdef HAVE_MESSAGES | ||
1899 | MHD_DLOG (con->daemon, | ||
1900 | _("Error during select (%d): `%s'\n"), | ||
1901 | err, | ||
1902 | MHD_socket_strerr_ (err)); | ||
1903 | #endif | ||
1904 | break; | ||
1905 | } | ||
1906 | } | ||
1907 | #ifdef HAVE_POLL | ||
1908 | else /* use_poll */ | ||
1909 | { | ||
1910 | p[0].events = POLLIN; | ||
1911 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); | ||
1912 | p[0].revents = 0; | ||
1913 | if (0 > MHD_sys_poll_ (p, | ||
1914 | 1, | ||
1915 | -1)) | ||
1916 | { | ||
1917 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | ||
1918 | continue; | ||
1919 | #ifdef HAVE_MESSAGES | ||
1920 | MHD_DLOG (con->daemon, | ||
1921 | _("Error during poll: `%s'\n"), | ||
1922 | MHD_socket_last_strerr_ ()); | ||
1923 | #endif | ||
1924 | break; | ||
1925 | } | ||
1926 | } | ||
1927 | #endif /* HAVE_POLL */ | ||
1928 | MHD_itc_clear_ (daemon->itc); | ||
1929 | continue; /* Check again for resume. */ | ||
1930 | } /* End of "suspended" branch. */ | ||
1931 | 1905 | ||
1932 | if (was_suspended) | 1906 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
1907 | continue; | ||
1908 | #ifdef HAVE_MESSAGES | ||
1909 | MHD_DLOG (con->daemon, | ||
1910 | _ ("Error during select (%d): `%s'\n"), | ||
1911 | err, | ||
1912 | MHD_socket_strerr_ (err)); | ||
1913 | #endif | ||
1914 | break; | ||
1915 | } | ||
1916 | } | ||
1917 | #ifdef HAVE_POLL | ||
1918 | else /* use_poll */ | ||
1919 | { | ||
1920 | p[0].events = POLLIN; | ||
1921 | p[0].fd = MHD_itc_r_fd_ (daemon->itc); | ||
1922 | p[0].revents = 0; | ||
1923 | if (0 > MHD_sys_poll_ (p, | ||
1924 | 1, | ||
1925 | -1)) | ||
1933 | { | 1926 | { |
1934 | MHD_update_last_activity_ (con); /* Reset timeout timer. */ | 1927 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
1935 | /* Process response queued during suspend and update states. */ | 1928 | continue; |
1936 | MHD_connection_handle_idle (con); | 1929 | #ifdef HAVE_MESSAGES |
1937 | was_suspended = false; | 1930 | MHD_DLOG (con->daemon, |
1931 | _ ("Error during poll: `%s'\n"), | ||
1932 | MHD_socket_last_strerr_ ()); | ||
1933 | #endif | ||
1934 | break; | ||
1938 | } | 1935 | } |
1936 | } | ||
1937 | #endif /* HAVE_POLL */ | ||
1938 | MHD_itc_clear_ (daemon->itc); | ||
1939 | continue; /* Check again for resume. */ | ||
1940 | } /* End of "suspended" branch. */ | ||
1939 | 1941 | ||
1940 | tvp = NULL; | 1942 | if (was_suspended) |
1943 | { | ||
1944 | MHD_update_last_activity_ (con); /* Reset timeout timer. */ | ||
1945 | /* Process response queued during suspend and update states. */ | ||
1946 | MHD_connection_handle_idle (con); | ||
1947 | was_suspended = false; | ||
1948 | } | ||
1941 | 1949 | ||
1942 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) | 1950 | tvp = NULL; |
1951 | |||
1952 | if ( (MHD_EVENT_LOOP_INFO_BLOCK == con->event_loop_info) | ||
1943 | #ifdef HTTPS_SUPPORT | 1953 | #ifdef HTTPS_SUPPORT |
1944 | || ( (con->tls_read_ready) && | 1954 | || ( (con->tls_read_ready) && |
1945 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) | 1955 | (MHD_EVENT_LOOP_INFO_READ == con->event_loop_info) ) |
1946 | #endif /* HTTPS_SUPPORT */ | 1956 | #endif /* HTTPS_SUPPORT */ |
1947 | ) | 1957 | ) |
1948 | { | 1958 | { |
1949 | /* do not block: more data may be inside of TLS buffers waiting or | 1959 | /* do not block: more data may be inside of TLS buffers waiting or |
1950 | * application must provide response data */ | 1960 | * application must provide response data */ |
1951 | tv.tv_sec = 0; | 1961 | tv.tv_sec = 0; |
1952 | tv.tv_usec = 0; | 1962 | tv.tv_usec = 0; |
1953 | tvp = &tv; | 1963 | tvp = &tv; |
1954 | } | 1964 | } |
1955 | if ( (NULL == tvp) && | 1965 | if ( (NULL == tvp) && |
1956 | (timeout > 0) ) | 1966 | (timeout > 0) ) |
1957 | { | 1967 | { |
1958 | now = MHD_monotonic_sec_counter(); | 1968 | now = MHD_monotonic_sec_counter (); |
1959 | if (now - con->last_activity > timeout) | 1969 | if (now - con->last_activity > timeout) |
1960 | tv.tv_sec = 0; | 1970 | tv.tv_sec = 0; |
1961 | else | 1971 | else |
1962 | { | 1972 | { |
1963 | const time_t seconds_left = timeout - (now - con->last_activity); | 1973 | const time_t seconds_left = timeout - (now - con->last_activity); |
1964 | #if !defined(_WIN32) || defined(__CYGWIN__) | 1974 | #if ! defined(_WIN32) || defined(__CYGWIN__) |
1965 | tv.tv_sec = seconds_left; | 1975 | tv.tv_sec = seconds_left; |
1966 | #else /* _WIN32 && !__CYGWIN__ */ | 1976 | #else /* _WIN32 && !__CYGWIN__ */ |
1967 | if (seconds_left > TIMEVAL_TV_SEC_MAX) | 1977 | if (seconds_left > TIMEVAL_TV_SEC_MAX) |
1968 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; | 1978 | tv.tv_sec = TIMEVAL_TV_SEC_MAX; |
1969 | else | 1979 | else |
1970 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; | 1980 | tv.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) seconds_left; |
1971 | #endif /* _WIN32 && ! __CYGWIN__ */ | 1981 | #endif /* _WIN32 && ! __CYGWIN__ */ |
1972 | } | 1982 | } |
1973 | tv.tv_usec = 0; | 1983 | tv.tv_usec = 0; |
1974 | tvp = &tv; | 1984 | tvp = &tv; |
1975 | } | 1985 | } |
1976 | if (! use_poll) | 1986 | if (! use_poll) |
1977 | { | 1987 | { |
1978 | /* use select */ | 1988 | /* use select */ |
1979 | bool err_state = false; | 1989 | bool err_state = false; |
1980 | 1990 | ||
1981 | FD_ZERO (&rs); | 1991 | FD_ZERO (&rs); |
1982 | FD_ZERO (&ws); | 1992 | FD_ZERO (&ws); |
1983 | FD_ZERO (&es); | 1993 | FD_ZERO (&es); |
1984 | maxsock = MHD_INVALID_SOCKET; | 1994 | maxsock = MHD_INVALID_SOCKET; |
1985 | switch (con->event_loop_info) | 1995 | switch (con->event_loop_info) |
1986 | { | 1996 | { |
1987 | case MHD_EVENT_LOOP_INFO_READ: | 1997 | case MHD_EVENT_LOOP_INFO_READ: |
1988 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 1998 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
1989 | &rs, | 1999 | &rs, |
1990 | &maxsock, | 2000 | &maxsock, |
1991 | FD_SETSIZE)) | 2001 | FD_SETSIZE)) |
1992 | err_state = true; | 2002 | err_state = true; |
1993 | break; | 2003 | break; |
1994 | case MHD_EVENT_LOOP_INFO_WRITE: | 2004 | case MHD_EVENT_LOOP_INFO_WRITE: |
1995 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 2005 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
1996 | &ws, | 2006 | &ws, |
1997 | &maxsock, | 2007 | &maxsock, |
1998 | FD_SETSIZE)) | 2008 | FD_SETSIZE)) |
1999 | err_state = true; | 2009 | err_state = true; |
2000 | break; | 2010 | break; |
2001 | case MHD_EVENT_LOOP_INFO_BLOCK: | 2011 | case MHD_EVENT_LOOP_INFO_BLOCK: |
2002 | if (! MHD_add_to_fd_set_ (con->socket_fd, | 2012 | if (! MHD_add_to_fd_set_ (con->socket_fd, |
2003 | &es, | 2013 | &es, |
2004 | &maxsock, | 2014 | &maxsock, |
2005 | FD_SETSIZE)) | 2015 | FD_SETSIZE)) |
2006 | err_state = true; | 2016 | err_state = true; |
2007 | break; | 2017 | break; |
2008 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 2018 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
2009 | /* how did we get here!? */ | 2019 | /* how did we get here!? */ |
2010 | goto exit; | 2020 | goto exit; |
2011 | } | 2021 | } |
2012 | #if WINDOWS | 2022 | #if WINDOWS |
2013 | if (MHD_ITC_IS_VALID_(daemon->itc) ) | 2023 | if (MHD_ITC_IS_VALID_ (daemon->itc) ) |
2014 | { | 2024 | { |
2015 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 2025 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
2016 | &rs, | 2026 | &rs, |
2017 | &maxsock, | 2027 | &maxsock, |
2018 | FD_SETSIZE)) | 2028 | FD_SETSIZE)) |
2019 | err_state = 1; | 2029 | err_state = 1; |
2020 | } | 2030 | } |
2021 | #endif | 2031 | #endif |
2022 | if (err_state) | 2032 | if (err_state) |
2023 | { | 2033 | { |
2024 | #ifdef HAVE_MESSAGES | 2034 | #ifdef HAVE_MESSAGES |
2025 | MHD_DLOG (con->daemon, | 2035 | MHD_DLOG (con->daemon, |
2026 | _("Failed to add FD to fd_set\n")); | 2036 | _ ("Failed to add FD to fd_set\n")); |
2027 | #endif | 2037 | #endif |
2028 | goto exit; | 2038 | goto exit; |
2029 | } | 2039 | } |
2030 | 2040 | ||
2031 | num_ready = MHD_SYS_select_ (maxsock + 1, | 2041 | num_ready = MHD_SYS_select_ (maxsock + 1, |
2032 | &rs, | 2042 | &rs, |
2033 | &ws, | 2043 | &ws, |
2034 | &es, | 2044 | &es, |
2035 | tvp); | 2045 | tvp); |
2036 | if (num_ready < 0) | 2046 | if (num_ready < 0) |
2037 | { | 2047 | { |
2038 | const int err = MHD_socket_get_error_(); | 2048 | const int err = MHD_socket_get_error_ (); |
2039 | 2049 | ||
2040 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 2050 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
2041 | continue; | 2051 | continue; |
2042 | #ifdef HAVE_MESSAGES | 2052 | #ifdef HAVE_MESSAGES |
2043 | MHD_DLOG (con->daemon, | 2053 | MHD_DLOG (con->daemon, |
2044 | _("Error during select (%d): `%s'\n"), | 2054 | _ ("Error during select (%d): `%s'\n"), |
2045 | err, | 2055 | err, |
2046 | MHD_socket_strerr_ (err)); | 2056 | MHD_socket_strerr_ (err)); |
2047 | #endif | 2057 | #endif |
2048 | break; | 2058 | break; |
2049 | } | 2059 | } |
2050 | #if WINDOWS | 2060 | #if WINDOWS |
2051 | /* Clear ITC before other processing so additional | 2061 | /* Clear ITC before other processing so additional |
2052 | * signals will trigger select() again */ | 2062 | * signals will trigger select() again */ |
2053 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2063 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2054 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | 2064 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), |
2055 | &rs)) ) | 2065 | &rs)) ) |
2056 | MHD_itc_clear_ (daemon->itc); | 2066 | MHD_itc_clear_ (daemon->itc); |
2057 | #endif | 2067 | #endif |
2058 | if (MHD_NO == | 2068 | if (MHD_NO == |
2059 | call_handlers (con, | 2069 | call_handlers (con, |
2060 | FD_ISSET (con->socket_fd, | 2070 | FD_ISSET (con->socket_fd, |
2061 | &rs), | 2071 | &rs), |
2062 | FD_ISSET (con->socket_fd, | 2072 | FD_ISSET (con->socket_fd, |
2063 | &ws), | 2073 | &ws), |
2064 | FD_ISSET (con->socket_fd, | 2074 | FD_ISSET (con->socket_fd, |
2065 | &es)) ) | 2075 | &es)) ) |
2066 | goto exit; | 2076 | goto exit; |
2067 | } | 2077 | } |
2068 | #ifdef HAVE_POLL | 2078 | #ifdef HAVE_POLL |
2069 | else | 2079 | else |
2070 | { | 2080 | { |
2071 | /* use poll */ | 2081 | /* use poll */ |
2072 | memset (&p, | 2082 | memset (&p, |
2073 | 0, | 2083 | 0, |
2074 | sizeof (p)); | 2084 | sizeof (p)); |
2075 | p[0].fd = con->socket_fd; | 2085 | p[0].fd = con->socket_fd; |
2076 | switch (con->event_loop_info) | 2086 | switch (con->event_loop_info) |
2077 | { | 2087 | { |
2078 | case MHD_EVENT_LOOP_INFO_READ: | 2088 | case MHD_EVENT_LOOP_INFO_READ: |
2079 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | 2089 | p[0].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; |
2080 | break; | 2090 | break; |
2081 | case MHD_EVENT_LOOP_INFO_WRITE: | 2091 | case MHD_EVENT_LOOP_INFO_WRITE: |
2082 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | 2092 | p[0].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; |
2083 | break; | 2093 | break; |
2084 | case MHD_EVENT_LOOP_INFO_BLOCK: | 2094 | case MHD_EVENT_LOOP_INFO_BLOCK: |
2085 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; | 2095 | p[0].events |= MHD_POLL_EVENTS_ERR_DISC; |
2086 | break; | 2096 | break; |
2087 | case MHD_EVENT_LOOP_INFO_CLEANUP: | 2097 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
2088 | /* how did we get here!? */ | 2098 | /* how did we get here!? */ |
2089 | goto exit; | 2099 | goto exit; |
2090 | } | 2100 | } |
2091 | #if WINDOWS | 2101 | #if WINDOWS |
2092 | extra_slot = 0; | 2102 | extra_slot = 0; |
2093 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 2103 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
2094 | { | 2104 | { |
2095 | p[1].events |= POLLIN; | 2105 | p[1].events |= POLLIN; |
2096 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); | 2106 | p[1].fd = MHD_itc_r_fd_ (daemon->itc); |
2097 | p[1].revents = 0; | 2107 | p[1].revents = 0; |
2098 | extra_slot = 1; | 2108 | extra_slot = 1; |
2099 | } | 2109 | } |
2100 | #endif | 2110 | #endif |
2101 | if (MHD_sys_poll_ (p, | 2111 | if (MHD_sys_poll_ (p, |
2102 | #if WINDOWS | 2112 | #if WINDOWS |
2103 | 1 + extra_slot, | 2113 | 1 + extra_slot, |
2104 | #else | 2114 | #else |
2105 | 1, | 2115 | 1, |
2106 | #endif | 2116 | #endif |
2107 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) | 2117 | (NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0) |
2108 | { | 2118 | { |
2109 | if (MHD_SCKT_LAST_ERR_IS_(MHD_SCKT_EINTR_)) | 2119 | if (MHD_SCKT_LAST_ERR_IS_ (MHD_SCKT_EINTR_)) |
2110 | continue; | 2120 | continue; |
2111 | #ifdef HAVE_MESSAGES | 2121 | #ifdef HAVE_MESSAGES |
2112 | MHD_DLOG (con->daemon, | 2122 | MHD_DLOG (con->daemon, |
2113 | _("Error during poll: `%s'\n"), | 2123 | _ ("Error during poll: `%s'\n"), |
2114 | MHD_socket_last_strerr_ ()); | 2124 | MHD_socket_last_strerr_ ()); |
2115 | #endif | 2125 | #endif |
2116 | break; | 2126 | break; |
2117 | } | 2127 | } |
2118 | #if WINDOWS | 2128 | #if WINDOWS |
2119 | /* Clear ITC before other processing so additional | 2129 | /* Clear ITC before other processing so additional |
2120 | * signals will trigger poll() again */ | 2130 | * signals will trigger poll() again */ |
2121 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2131 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2122 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) | 2132 | (0 != (p[1].revents & (POLLERR | POLLHUP | POLLIN))) ) |
2123 | MHD_itc_clear_ (daemon->itc); | 2133 | MHD_itc_clear_ (daemon->itc); |
2124 | #endif | 2134 | #endif |
2125 | if (MHD_NO == | 2135 | if (MHD_NO == |
2126 | call_handlers (con, | 2136 | call_handlers (con, |
2127 | 0 != (p[0].revents & POLLIN), | 2137 | (0 != (p[0].revents & POLLIN)), |
2128 | 0 != (p[0].revents & POLLOUT), | 2138 | (0 != (p[0].revents & POLLOUT)), |
2129 | 0 != (p[0].revents & (POLLERR | MHD_POLL_REVENTS_ERR_DISC)))) | 2139 | (0 != (p[0].revents & (POLLERR |
2130 | goto exit; | 2140 | | MHD_POLL_REVENTS_ERR_DISC))) )) |
2131 | } | 2141 | goto exit; |
2142 | } | ||
2132 | #endif | 2143 | #endif |
2133 | #ifdef UPGRADE_SUPPORT | 2144 | #ifdef UPGRADE_SUPPORT |
2134 | if (MHD_CONNECTION_UPGRADE == con->state) | 2145 | if (MHD_CONNECTION_UPGRADE == con->state) |
2135 | { | 2146 | { |
2136 | /* Normal HTTP processing is finished, | 2147 | /* Normal HTTP processing is finished, |
2137 | * notify application. */ | 2148 | * notify application. */ |
2138 | if ( (NULL != daemon->notify_completed) && | 2149 | if ( (NULL != daemon->notify_completed) && |
2139 | (con->client_aware) ) | 2150 | (con->client_aware) ) |
2140 | daemon->notify_completed (daemon->notify_completed_cls, | 2151 | daemon->notify_completed (daemon->notify_completed_cls, |
2141 | con, | 2152 | con, |
2142 | &con->client_context, | 2153 | &con->client_context, |
2143 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | 2154 | MHD_REQUEST_TERMINATED_COMPLETED_OK); |
2144 | con->client_aware = false; | 2155 | con->client_aware = false; |
2145 | 2156 | ||
2146 | thread_main_connection_upgrade (con); | 2157 | thread_main_connection_upgrade (con); |
2147 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ | 2158 | /* MHD_connection_finish_forward_() was called by thread_main_connection_upgrade(). */ |
2148 | 2159 | ||
2149 | /* "Upgraded" data will not be used in this thread from this point. */ | 2160 | /* "Upgraded" data will not be used in this thread from this point. */ |
2150 | con->urh->clean_ready = true; | 2161 | con->urh->clean_ready = true; |
2151 | /* If 'urh->was_closed' set to true, connection will be | 2162 | /* If 'urh->was_closed' set to true, connection will be |
2152 | * moved immediately to cleanup list. Otherwise connection | 2163 | * moved immediately to cleanup list. Otherwise connection |
2153 | * will stay in suspended list until 'urh' will be marked | 2164 | * will stay in suspended list until 'urh' will be marked |
2154 | * with 'was_closed' by application. */ | 2165 | * with 'was_closed' by application. */ |
2155 | MHD_resume_connection(con); | 2166 | MHD_resume_connection (con); |
2156 | 2167 | ||
2157 | /* skip usual clean up */ | 2168 | /* skip usual clean up */ |
2158 | return (MHD_THRD_RTRN_TYPE_) 0; | 2169 | return (MHD_THRD_RTRN_TYPE_) 0; |
2159 | } | ||
2160 | #endif /* UPGRADE_SUPPORT */ | ||
2161 | } | 2170 | } |
2171 | #endif /* UPGRADE_SUPPORT */ | ||
2172 | } | ||
2162 | #if DEBUG_CLOSE | 2173 | #if DEBUG_CLOSE |
2163 | #ifdef HAVE_MESSAGES | 2174 | #ifdef HAVE_MESSAGES |
2164 | MHD_DLOG (con->daemon, | 2175 | MHD_DLOG (con->daemon, |
2165 | _("Processing thread terminating. Closing connection\n")); | 2176 | _ ("Processing thread terminating. Closing connection\n")); |
2166 | #endif | 2177 | #endif |
2167 | #endif | 2178 | #endif |
2168 | if (MHD_CONNECTION_CLOSED != con->state) | 2179 | if (MHD_CONNECTION_CLOSED != con->state) |
2169 | MHD_connection_close_ (con, | 2180 | MHD_connection_close_ (con, |
2170 | (daemon->shutdown) ? | 2181 | (daemon->shutdown) ? |
2171 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN: | 2182 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN : |
2172 | MHD_REQUEST_TERMINATED_WITH_ERROR); | 2183 | MHD_REQUEST_TERMINATED_WITH_ERROR); |
2173 | MHD_connection_handle_idle (con); | 2184 | MHD_connection_handle_idle (con); |
2174 | exit: | 2185 | exit: |
2175 | if (NULL != con->response) | 2186 | if (NULL != con->response) |
2176 | { | 2187 | { |
2177 | MHD_destroy_response (con->response); | 2188 | MHD_destroy_response (con->response); |
2178 | con->response = NULL; | 2189 | con->response = NULL; |
2179 | } | 2190 | } |
2180 | 2191 | ||
2181 | if (MHD_INVALID_SOCKET != con->socket_fd) | 2192 | if (MHD_INVALID_SOCKET != con->socket_fd) |
2182 | { | 2193 | { |
2183 | shutdown (con->socket_fd, | 2194 | shutdown (con->socket_fd, |
2184 | SHUT_WR); | 2195 | SHUT_WR); |
2185 | /* 'socket_fd' can be used in other thread to signal shutdown. | 2196 | /* 'socket_fd' can be used in other thread to signal shutdown. |
2186 | * To avoid data races, do not close socket here. Daemon will | 2197 | * To avoid data races, do not close socket here. Daemon will |
2187 | * use more connections only after cleanup anyway. */ | 2198 | * use more connections only after cleanup anyway. */ |
2188 | } | 2199 | } |
2189 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2200 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2190 | (! MHD_itc_activate_ (daemon->itc, "t")) ) | 2201 | (! MHD_itc_activate_ (daemon->itc, "t")) ) |
2191 | { | 2202 | { |
2192 | #ifdef HAVE_MESSAGES | 2203 | #ifdef HAVE_MESSAGES |
2193 | MHD_DLOG (daemon, | 2204 | MHD_DLOG (daemon, |
2194 | _("Failed to signal thread termination via inter-thread communication channel.")); | 2205 | _ ( |
2206 | "Failed to signal thread termination via inter-thread communication channel.")); | ||
2195 | #endif | 2207 | #endif |
2196 | } | 2208 | } |
2197 | return (MHD_THRD_RTRN_TYPE_) 0; | 2209 | return (MHD_THRD_RTRN_TYPE_) 0; |
2198 | } | 2210 | } |
2199 | #endif | 2211 | #endif |
@@ -2210,8 +2222,8 @@ static void | |||
2210 | MHD_cleanup_connections (struct MHD_Daemon *daemon); | 2222 | MHD_cleanup_connections (struct MHD_Daemon *daemon); |
2211 | 2223 | ||
2212 | #if defined(HTTPS_SUPPORT) | 2224 | #if defined(HTTPS_SUPPORT) |
2213 | #if !defined(MHD_WINSOCK_SOCKETS) && !defined(MHD_socket_nosignal_) && \ | 2225 | #if ! defined(MHD_WINSOCK_SOCKETS) && ! defined(MHD_socket_nosignal_) && \ |
2214 | (GNUTLS_VERSION_NUMBER+0 < 0x030402) && defined(MSG_NOSIGNAL) | 2226 | (GNUTLS_VERSION_NUMBER + 0 < 0x030402) && defined(MSG_NOSIGNAL) |
2215 | /** | 2227 | /** |
2216 | * Older version of GnuTLS do not support suppressing of SIGPIPE signal. | 2228 | * Older version of GnuTLS do not support suppressing of SIGPIPE signal. |
2217 | * Use push function replacement with suppressing SIGPIPE signal where necessary | 2229 | * Use push function replacement with suppressing SIGPIPE signal where necessary |
@@ -2226,15 +2238,15 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon); | |||
2226 | * for TLS library. | 2238 | * for TLS library. |
2227 | */ | 2239 | */ |
2228 | static ssize_t | 2240 | static ssize_t |
2229 | MHD_tls_push_func_(gnutls_transport_ptr_t trnsp, | 2241 | MHD_tls_push_func_ (gnutls_transport_ptr_t trnsp, |
2230 | const void *data, | 2242 | const void *data, |
2231 | size_t data_size) | 2243 | size_t data_size) |
2232 | { | 2244 | { |
2233 | #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) | 2245 | #if (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) |
2234 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) | 2246 | if (data_size > MHD_SCKT_SEND_MAX_SIZE_) |
2235 | data_size = MHD_SCKT_SEND_MAX_SIZE_; | 2247 | data_size = MHD_SCKT_SEND_MAX_SIZE_; |
2236 | #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */ | 2248 | #endif /* (MHD_SCKT_SEND_MAX_SIZE_ < SSIZE_MAX) || (0 == SSIZE_MAX) */ |
2237 | return MHD_send_ ((MHD_socket)(intptr_t)(trnsp), data, data_size); | 2249 | return MHD_send_ ((MHD_socket) (intptr_t) (trnsp), data, data_size); |
2238 | } | 2250 | } |
2239 | #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */ | 2251 | #endif /* MHD_TLSLIB_DONT_SUPPRESS_SIGPIPE */ |
2240 | 2252 | ||
@@ -2249,8 +2261,8 @@ MHD_tls_push_func_(gnutls_transport_ptr_t trnsp, | |||
2249 | */ | 2261 | */ |
2250 | static int | 2262 | static int |
2251 | psk_gnutls_adapter (gnutls_session_t session, | 2263 | psk_gnutls_adapter (gnutls_session_t session, |
2252 | const char *username, | 2264 | const char *username, |
2253 | gnutls_datum_t *key) | 2265 | gnutls_datum_t *key) |
2254 | { | 2266 | { |
2255 | struct MHD_Connection *connection; | 2267 | struct MHD_Connection *connection; |
2256 | struct MHD_Daemon *daemon; | 2268 | struct MHD_Daemon *daemon; |
@@ -2262,7 +2274,7 @@ psk_gnutls_adapter (gnutls_session_t session, | |||
2262 | { | 2274 | { |
2263 | #ifdef HAVE_MESSAGES | 2275 | #ifdef HAVE_MESSAGES |
2264 | /* Cannot use our logger, we don't even have "daemon" */ | 2276 | /* Cannot use our logger, we don't even have "daemon" */ |
2265 | MHD_PANIC (_("Internal server error. This should be impossible.\n")); | 2277 | MHD_PANIC (_ ("Internal server error. This should be impossible.\n")); |
2266 | #endif | 2278 | #endif |
2267 | return -1; | 2279 | return -1; |
2268 | } | 2280 | } |
@@ -2272,46 +2284,47 @@ psk_gnutls_adapter (gnutls_session_t session, | |||
2272 | { | 2284 | { |
2273 | #ifdef HAVE_MESSAGES | 2285 | #ifdef HAVE_MESSAGES |
2274 | MHD_DLOG (daemon, | 2286 | MHD_DLOG (daemon, |
2275 | _("PSK not supported by this server.\n")); | 2287 | _ ("PSK not supported by this server.\n")); |
2276 | #endif | 2288 | #endif |
2277 | return -1; | 2289 | return -1; |
2278 | } | 2290 | } |
2279 | if (0 != daemon->cred_callback (daemon->cred_callback_cls, | 2291 | if (0 != daemon->cred_callback (daemon->cred_callback_cls, |
2280 | connection, | 2292 | connection, |
2281 | username, | 2293 | username, |
2282 | &app_psk, | 2294 | &app_psk, |
2283 | &app_psk_size)) | 2295 | &app_psk_size)) |
2284 | return -1; | 2296 | return -1; |
2285 | if (NULL == (key->data = gnutls_malloc (app_psk_size))) | 2297 | if (NULL == (key->data = gnutls_malloc (app_psk_size))) |
2286 | { | 2298 | { |
2287 | #ifdef HAVE_MESSAGES | 2299 | #ifdef HAVE_MESSAGES |
2288 | MHD_DLOG (daemon, | 2300 | MHD_DLOG (daemon, |
2289 | _("PSK authentication failed: gnutls_malloc failed to allocate memory\n")); | 2301 | _ ( |
2302 | "PSK authentication failed: gnutls_malloc failed to allocate memory\n")); | ||
2290 | #endif | 2303 | #endif |
2291 | free (app_psk); | 2304 | free (app_psk); |
2292 | return -1; | 2305 | return -1; |
2293 | } | 2306 | } |
2294 | if (UINT_MAX < app_psk_size) | 2307 | if (UINT_MAX < app_psk_size) |
2295 | { | 2308 | { |
2296 | #ifdef HAVE_MESSAGES | 2309 | #ifdef HAVE_MESSAGES |
2297 | MHD_DLOG (daemon, | 2310 | MHD_DLOG (daemon, |
2298 | _("PSK authentication failed: PSK too long\n")); | 2311 | _ ("PSK authentication failed: PSK too long\n")); |
2299 | #endif | 2312 | #endif |
2300 | free (app_psk); | 2313 | free (app_psk); |
2301 | return -1; | 2314 | return -1; |
2302 | } | 2315 | } |
2303 | key->size = (unsigned int)app_psk_size; | 2316 | key->size = (unsigned int) app_psk_size; |
2304 | memcpy (key->data, | 2317 | memcpy (key->data, |
2305 | app_psk, | 2318 | app_psk, |
2306 | app_psk_size); | 2319 | app_psk_size); |
2307 | free (app_psk); | 2320 | free (app_psk); |
2308 | return 0; | 2321 | return 0; |
2309 | #else | 2322 | #else |
2310 | #ifdef HAVE_MESSAGES | 2323 | #ifdef HAVE_MESSAGES |
2311 | MHD_DLOG (daemon, | 2324 | MHD_DLOG (daemon, |
2312 | _("PSK not supported by this server.\n")); | 2325 | _ ("PSK not supported by this server.\n")); |
2313 | #endif | 2326 | #endif |
2314 | return -1; | 2327 | return -1; |
2315 | #endif | 2328 | #endif |
2316 | } | 2329 | } |
2317 | #endif /* HTTPS_SUPPORT */ | 2330 | #endif /* HTTPS_SUPPORT */ |
@@ -2360,71 +2373,71 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2360 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2373 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2361 | mhd_assert ((NULL == daemon->worker_pool) || (external_add)); | 2374 | mhd_assert ((NULL == daemon->worker_pool) || (external_add)); |
2362 | if ((external_add) && (NULL != daemon->worker_pool)) | 2375 | if ((external_add) && (NULL != daemon->worker_pool)) |
2363 | { | 2376 | { |
2364 | /* have a pool, try to find a pool with capacity; we use the | 2377 | /* have a pool, try to find a pool with capacity; we use the |
2365 | socket as the initial offset into the pool for load | 2378 | socket as the initial offset into the pool for load |
2366 | balancing */ | 2379 | balancing */ |
2367 | for (i = 0; i < daemon->worker_pool_size; ++i) | 2380 | for (i = 0; i < daemon->worker_pool_size; ++i) |
2368 | { | 2381 | { |
2369 | struct MHD_Daemon * const worker = | 2382 | struct MHD_Daemon *const worker = |
2370 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; | 2383 | &daemon->worker_pool[(i + client_socket) % daemon->worker_pool_size]; |
2371 | if (worker->connections < worker->connection_limit) | 2384 | if (worker->connections < worker->connection_limit) |
2372 | return internal_add_connection (worker, | 2385 | return internal_add_connection (worker, |
2373 | client_socket, | 2386 | client_socket, |
2374 | addr, | 2387 | addr, |
2375 | addrlen, | 2388 | addrlen, |
2376 | true, | 2389 | true, |
2377 | non_blck); | 2390 | non_blck); |
2378 | } | 2391 | } |
2379 | /* all pools are at their connection limit, must refuse */ | 2392 | /* all pools are at their connection limit, must refuse */ |
2380 | MHD_socket_close_chk_ (client_socket); | 2393 | MHD_socket_close_chk_ (client_socket); |
2381 | #if ENFILE | 2394 | #if ENFILE |
2382 | errno = ENFILE; | 2395 | errno = ENFILE; |
2383 | #endif | 2396 | #endif |
2384 | return MHD_NO; | 2397 | return MHD_NO; |
2385 | } | 2398 | } |
2386 | #endif | 2399 | #endif |
2387 | 2400 | ||
2388 | if ( (! MHD_SCKT_FD_FITS_FDSET_(client_socket, | 2401 | if ( (! MHD_SCKT_FD_FITS_FDSET_ (client_socket, |
2389 | NULL)) && | 2402 | NULL)) && |
2390 | (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) ) | 2403 | (0 == (daemon->options & (MHD_USE_POLL | MHD_USE_EPOLL))) ) |
2391 | { | 2404 | { |
2392 | #ifdef HAVE_MESSAGES | 2405 | #ifdef HAVE_MESSAGES |
2393 | MHD_DLOG (daemon, | 2406 | MHD_DLOG (daemon, |
2394 | _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), | 2407 | _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), |
2395 | (int) client_socket, | 2408 | (int) client_socket, |
2396 | (int) FD_SETSIZE); | 2409 | (int) FD_SETSIZE); |
2397 | #endif | 2410 | #endif |
2398 | MHD_socket_close_chk_ (client_socket); | 2411 | MHD_socket_close_chk_ (client_socket); |
2399 | #if EINVAL | 2412 | #if EINVAL |
2400 | errno = EINVAL; | 2413 | errno = EINVAL; |
2401 | #endif | 2414 | #endif |
2402 | return MHD_NO; | 2415 | return MHD_NO; |
2403 | } | 2416 | } |
2404 | 2417 | ||
2405 | #ifdef MHD_socket_nosignal_ | 2418 | #ifdef MHD_socket_nosignal_ |
2406 | if (! MHD_socket_nosignal_ (client_socket)) | 2419 | if (! MHD_socket_nosignal_ (client_socket)) |
2407 | { | 2420 | { |
2408 | #ifdef HAVE_MESSAGES | 2421 | #ifdef HAVE_MESSAGES |
2409 | MHD_DLOG (daemon, | 2422 | MHD_DLOG (daemon, |
2410 | _("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), | 2423 | _ ("Failed to set SO_NOSIGPIPE on accepted socket: %s\n"), |
2411 | MHD_socket_last_strerr_()); | 2424 | MHD_socket_last_strerr_ ()); |
2412 | #endif | 2425 | #endif |
2413 | #ifndef MSG_NOSIGNAL | 2426 | #ifndef MSG_NOSIGNAL |
2414 | /* Cannot use socket as it can produce SIGPIPE. */ | 2427 | /* Cannot use socket as it can produce SIGPIPE. */ |
2415 | #ifdef ENOTSOCK | 2428 | #ifdef ENOTSOCK |
2416 | errno = ENOTSOCK; | 2429 | errno = ENOTSOCK; |
2417 | #endif /* ENOTSOCK */ | 2430 | #endif /* ENOTSOCK */ |
2418 | return MHD_NO; | 2431 | return MHD_NO; |
2419 | #endif /* ! MSG_NOSIGNAL */ | 2432 | #endif /* ! MSG_NOSIGNAL */ |
2420 | } | 2433 | } |
2421 | #endif /* MHD_socket_nosignal_ */ | 2434 | #endif /* MHD_socket_nosignal_ */ |
2422 | 2435 | ||
2423 | 2436 | ||
2424 | #ifdef HAVE_MESSAGES | 2437 | #ifdef HAVE_MESSAGES |
2425 | #if DEBUG_CONNECT | 2438 | #if DEBUG_CONNECT |
2426 | MHD_DLOG (daemon, | 2439 | MHD_DLOG (daemon, |
2427 | _("Accepted connection on socket %d\n"), | 2440 | _ ("Accepted connection on socket %d\n"), |
2428 | client_socket); | 2441 | client_socket); |
2429 | #endif | 2442 | #endif |
2430 | #endif | 2443 | #endif |
@@ -2432,93 +2445,94 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2432 | (MHD_NO == MHD_ip_limit_add (daemon, | 2445 | (MHD_NO == MHD_ip_limit_add (daemon, |
2433 | addr, | 2446 | addr, |
2434 | addrlen)) ) | 2447 | addrlen)) ) |
2435 | { | 2448 | { |
2436 | /* above connection limit - reject */ | 2449 | /* above connection limit - reject */ |
2437 | #ifdef HAVE_MESSAGES | 2450 | #ifdef HAVE_MESSAGES |
2438 | MHD_DLOG (daemon, | 2451 | MHD_DLOG (daemon, |
2439 | _("Server reached connection limit. Closing inbound connection.\n")); | 2452 | _ ( |
2453 | "Server reached connection limit. Closing inbound connection.\n")); | ||
2440 | #endif | 2454 | #endif |
2441 | MHD_socket_close_chk_ (client_socket); | 2455 | MHD_socket_close_chk_ (client_socket); |
2442 | #if ENFILE | 2456 | #if ENFILE |
2443 | errno = ENFILE; | 2457 | errno = ENFILE; |
2444 | #endif | 2458 | #endif |
2445 | return MHD_NO; | 2459 | return MHD_NO; |
2446 | } | 2460 | } |
2447 | 2461 | ||
2448 | /* apply connection acceptance policy if present */ | 2462 | /* apply connection acceptance policy if present */ |
2449 | if ( (NULL != daemon->apc) && | 2463 | if ( (NULL != daemon->apc) && |
2450 | (MHD_NO == daemon->apc (daemon->apc_cls, | 2464 | (MHD_NO == daemon->apc (daemon->apc_cls, |
2451 | addr, | 2465 | addr, |
2452 | addrlen)) ) | 2466 | addrlen)) ) |
2453 | { | 2467 | { |
2454 | #if DEBUG_CLOSE | 2468 | #if DEBUG_CLOSE |
2455 | #ifdef HAVE_MESSAGES | 2469 | #ifdef HAVE_MESSAGES |
2456 | MHD_DLOG (daemon, | 2470 | MHD_DLOG (daemon, |
2457 | _("Connection rejected by application. Closing connection.\n")); | 2471 | _ ("Connection rejected by application. Closing connection.\n")); |
2458 | #endif | 2472 | #endif |
2459 | #endif | 2473 | #endif |
2460 | MHD_socket_close_chk_ (client_socket); | 2474 | MHD_socket_close_chk_ (client_socket); |
2461 | MHD_ip_limit_del (daemon, | 2475 | MHD_ip_limit_del (daemon, |
2462 | addr, | 2476 | addr, |
2463 | addrlen); | 2477 | addrlen); |
2464 | #if EACCESS | 2478 | #if EACCESS |
2465 | errno = EACCESS; | 2479 | errno = EACCESS; |
2466 | #endif | 2480 | #endif |
2467 | return MHD_NO; | 2481 | return MHD_NO; |
2468 | } | 2482 | } |
2469 | 2483 | ||
2470 | if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection)))) | 2484 | if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection)))) |
2471 | { | 2485 | { |
2472 | eno = errno; | 2486 | eno = errno; |
2473 | #ifdef HAVE_MESSAGES | 2487 | #ifdef HAVE_MESSAGES |
2474 | MHD_DLOG (daemon, | 2488 | MHD_DLOG (daemon, |
2475 | "Error allocating memory: %s\n", | 2489 | "Error allocating memory: %s\n", |
2476 | MHD_strerror_ (errno)); | 2490 | MHD_strerror_ (errno)); |
2477 | #endif | 2491 | #endif |
2478 | MHD_socket_close_chk_ (client_socket); | 2492 | MHD_socket_close_chk_ (client_socket); |
2479 | MHD_ip_limit_del (daemon, | 2493 | MHD_ip_limit_del (daemon, |
2480 | addr, | 2494 | addr, |
2481 | addrlen); | 2495 | addrlen); |
2482 | errno = eno; | 2496 | errno = eno; |
2483 | return MHD_NO; | 2497 | return MHD_NO; |
2484 | } | 2498 | } |
2485 | connection->pool = MHD_pool_create (daemon->pool_size); | 2499 | connection->pool = MHD_pool_create (daemon->pool_size); |
2486 | if (NULL == connection->pool) | 2500 | if (NULL == connection->pool) |
2487 | { | 2501 | { |
2488 | #ifdef HAVE_MESSAGES | 2502 | #ifdef HAVE_MESSAGES |
2489 | MHD_DLOG (daemon, | 2503 | MHD_DLOG (daemon, |
2490 | _("Error allocating memory: %s\n"), | 2504 | _ ("Error allocating memory: %s\n"), |
2491 | MHD_strerror_ (errno)); | 2505 | MHD_strerror_ (errno)); |
2492 | #endif | 2506 | #endif |
2493 | MHD_socket_close_chk_ (client_socket); | 2507 | MHD_socket_close_chk_ (client_socket); |
2494 | MHD_ip_limit_del (daemon, | 2508 | MHD_ip_limit_del (daemon, |
2495 | addr, | 2509 | addr, |
2496 | addrlen); | 2510 | addrlen); |
2497 | free (connection); | 2511 | free (connection); |
2498 | #if ENOMEM | 2512 | #if ENOMEM |
2499 | errno = ENOMEM; | 2513 | errno = ENOMEM; |
2500 | #endif | 2514 | #endif |
2501 | return MHD_NO; | 2515 | return MHD_NO; |
2502 | } | 2516 | } |
2503 | 2517 | ||
2504 | connection->connection_timeout = daemon->connection_timeout; | 2518 | connection->connection_timeout = daemon->connection_timeout; |
2505 | if (NULL == (connection->addr = malloc (addrlen))) | 2519 | if (NULL == (connection->addr = malloc (addrlen))) |
2506 | { | 2520 | { |
2507 | eno = errno; | 2521 | eno = errno; |
2508 | #ifdef HAVE_MESSAGES | 2522 | #ifdef HAVE_MESSAGES |
2509 | MHD_DLOG (daemon, | 2523 | MHD_DLOG (daemon, |
2510 | _("Error allocating memory: %s\n"), | 2524 | _ ("Error allocating memory: %s\n"), |
2511 | MHD_strerror_ (errno)); | 2525 | MHD_strerror_ (errno)); |
2512 | #endif | 2526 | #endif |
2513 | MHD_socket_close_chk_ (client_socket); | 2527 | MHD_socket_close_chk_ (client_socket); |
2514 | MHD_ip_limit_del (daemon, | 2528 | MHD_ip_limit_del (daemon, |
2515 | addr, | 2529 | addr, |
2516 | addrlen); | 2530 | addrlen); |
2517 | MHD_pool_destroy (connection->pool); | 2531 | MHD_pool_destroy (connection->pool); |
2518 | free (connection); | 2532 | free (connection); |
2519 | errno = eno; | 2533 | errno = eno; |
2520 | return MHD_NO; | 2534 | return MHD_NO; |
2521 | } | 2535 | } |
2522 | memcpy (connection->addr, | 2536 | memcpy (connection->addr, |
2523 | addr, | 2537 | addr, |
2524 | addrlen); | 2538 | addrlen); |
@@ -2526,125 +2540,127 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2526 | connection->socket_fd = client_socket; | 2540 | connection->socket_fd = client_socket; |
2527 | connection->sk_nonblck = non_blck; | 2541 | connection->sk_nonblck = non_blck; |
2528 | connection->daemon = daemon; | 2542 | connection->daemon = daemon; |
2529 | connection->last_activity = MHD_monotonic_sec_counter(); | 2543 | connection->last_activity = MHD_monotonic_sec_counter (); |
2530 | 2544 | ||
2531 | if (0 == (daemon->options & MHD_USE_TLS)) | 2545 | if (0 == (daemon->options & MHD_USE_TLS)) |
2532 | { | 2546 | { |
2533 | /* set default connection handlers */ | 2547 | /* set default connection handlers */ |
2534 | MHD_set_http_callbacks_ (connection); | 2548 | MHD_set_http_callbacks_ (connection); |
2535 | } | 2549 | } |
2536 | else | 2550 | else |
2537 | { | 2551 | { |
2538 | #ifdef HTTPS_SUPPORT | 2552 | #ifdef HTTPS_SUPPORT |
2539 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030500) | 2553 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030500) |
2540 | gnutls_init_flags_t | 2554 | gnutls_init_flags_t |
2541 | #else | 2555 | #else |
2542 | unsigned int | 2556 | unsigned int |
2543 | #endif | 2557 | #endif |
2544 | flags; | 2558 | flags; |
2545 | 2559 | ||
2546 | flags = GNUTLS_SERVER; | 2560 | flags = GNUTLS_SERVER; |
2547 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030402) | 2561 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030402) |
2548 | flags |= GNUTLS_NO_SIGNAL; | 2562 | flags |= GNUTLS_NO_SIGNAL; |
2549 | #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */ | 2563 | #endif /* GNUTLS_VERSION_NUMBER >= 0x030402 */ |
2550 | #if GNUTLS_VERSION_MAJOR >= 3 | 2564 | #if GNUTLS_VERSION_MAJOR >= 3 |
2551 | flags |= GNUTLS_NONBLOCK; | 2565 | flags |= GNUTLS_NONBLOCK; |
2552 | #endif /* GNUTLS_VERSION_MAJOR >= 3*/ | 2566 | #endif /* GNUTLS_VERSION_MAJOR >= 3*/ |
2553 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030603) | 2567 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030603) |
2554 | if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT)) | 2568 | if (0 != (daemon->options & MHD_USE_POST_HANDSHAKE_AUTH_SUPPORT)) |
2555 | flags |= GNUTLS_POST_HANDSHAKE_AUTH; | 2569 | flags |= GNUTLS_POST_HANDSHAKE_AUTH; |
2556 | #endif | 2570 | #endif |
2557 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030605) | 2571 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030605) |
2558 | if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA)) | 2572 | if (0 != (daemon->options & MHD_USE_INSECURE_TLS_EARLY_DATA)) |
2559 | flags |= GNUTLS_ENABLE_EARLY_DATA; | 2573 | flags |= GNUTLS_ENABLE_EARLY_DATA; |
2560 | #endif | 2574 | #endif |
2561 | connection->tls_state = MHD_TLS_CONN_INIT; | 2575 | connection->tls_state = MHD_TLS_CONN_INIT; |
2562 | MHD_set_https_callbacks (connection); | 2576 | MHD_set_https_callbacks (connection); |
2563 | gnutls_init (&connection->tls_session, | 2577 | gnutls_init (&connection->tls_session, |
2564 | flags); | 2578 | flags); |
2565 | gnutls_priority_set (connection->tls_session, | 2579 | gnutls_priority_set (connection->tls_session, |
2566 | daemon->priority_cache); | 2580 | daemon->priority_cache); |
2567 | gnutls_session_set_ptr (connection->tls_session, | 2581 | gnutls_session_set_ptr (connection->tls_session, |
2568 | connection); | 2582 | connection); |
2569 | switch (daemon->cred_type) | 2583 | switch (daemon->cred_type) |
2570 | { | 2584 | { |
2571 | /* set needed credentials for certificate authentication. */ | 2585 | /* set needed credentials for certificate authentication. */ |
2572 | case GNUTLS_CRD_CERTIFICATE: | 2586 | case GNUTLS_CRD_CERTIFICATE: |
2573 | gnutls_credentials_set (connection->tls_session, | 2587 | gnutls_credentials_set (connection->tls_session, |
2574 | GNUTLS_CRD_CERTIFICATE, | 2588 | GNUTLS_CRD_CERTIFICATE, |
2575 | daemon->x509_cred); | 2589 | daemon->x509_cred); |
2576 | break; | 2590 | break; |
2577 | case GNUTLS_CRD_PSK: | 2591 | case GNUTLS_CRD_PSK: |
2578 | gnutls_credentials_set (connection->tls_session, | 2592 | gnutls_credentials_set (connection->tls_session, |
2579 | GNUTLS_CRD_PSK, | 2593 | GNUTLS_CRD_PSK, |
2580 | daemon->psk_cred); | 2594 | daemon->psk_cred); |
2581 | gnutls_psk_set_server_credentials_function (daemon->psk_cred, | 2595 | gnutls_psk_set_server_credentials_function (daemon->psk_cred, |
2582 | &psk_gnutls_adapter); | 2596 | &psk_gnutls_adapter); |
2583 | break; | 2597 | break; |
2584 | default: | 2598 | default: |
2585 | #ifdef HAVE_MESSAGES | 2599 | #ifdef HAVE_MESSAGES |
2586 | MHD_DLOG (connection->daemon, | 2600 | MHD_DLOG (connection->daemon, |
2587 | _("Failed to setup TLS credentials: unknown credential type %d\n"), | 2601 | _ ( |
2588 | daemon->cred_type); | 2602 | "Failed to setup TLS credentials: unknown credential type %d\n"), |
2589 | #endif | 2603 | daemon->cred_type); |
2590 | MHD_socket_close_chk_ (client_socket); | 2604 | #endif |
2591 | MHD_ip_limit_del (daemon, | 2605 | MHD_socket_close_chk_ (client_socket); |
2592 | addr, | 2606 | MHD_ip_limit_del (daemon, |
2593 | addrlen); | 2607 | addr, |
2594 | free (connection->addr); | 2608 | addrlen); |
2595 | free (connection); | 2609 | free (connection->addr); |
2596 | MHD_PANIC (_("Unknown credential type")); | 2610 | free (connection); |
2611 | MHD_PANIC (_ ("Unknown credential type")); | ||
2597 | #if EINVAL | 2612 | #if EINVAL |
2598 | errno = EINVAL; | 2613 | errno = EINVAL; |
2599 | #endif | 2614 | #endif |
2600 | return MHD_NO; | 2615 | return MHD_NO; |
2601 | } | 2616 | } |
2602 | #if (GNUTLS_VERSION_NUMBER+0 >= 0x030109) && !defined(_WIN64) | 2617 | #if (GNUTLS_VERSION_NUMBER + 0 >= 0x030109) && ! defined(_WIN64) |
2603 | gnutls_transport_set_int (connection->tls_session, | 2618 | gnutls_transport_set_int (connection->tls_session, |
2604 | (int)(client_socket)); | 2619 | (int) (client_socket)); |
2605 | #else /* GnuTLS before 3.1.9 or Win x64 */ | 2620 | #else /* GnuTLS before 3.1.9 or Win x64 */ |
2606 | gnutls_transport_set_ptr (connection->tls_session, | 2621 | gnutls_transport_set_ptr (connection->tls_session, |
2607 | (gnutls_transport_ptr_t)(intptr_t)(client_socket)); | 2622 | (gnutls_transport_ptr_t) (intptr_t) (client_socket)); |
2608 | #endif /* GnuTLS before 3.1.9 */ | 2623 | #endif /* GnuTLS before 3.1.9 */ |
2609 | #ifdef MHD_TLSLIB_NEED_PUSH_FUNC | 2624 | #ifdef MHD_TLSLIB_NEED_PUSH_FUNC |
2610 | gnutls_transport_set_push_function (connection->tls_session, | 2625 | gnutls_transport_set_push_function (connection->tls_session, |
2611 | MHD_tls_push_func_); | 2626 | MHD_tls_push_func_); |
2612 | #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */ | 2627 | #endif /* MHD_TLSLIB_NEED_PUSH_FUNC */ |
2613 | if (daemon->https_mem_trust) | 2628 | if (daemon->https_mem_trust) |
2614 | gnutls_certificate_server_set_request (connection->tls_session, | 2629 | gnutls_certificate_server_set_request (connection->tls_session, |
2615 | GNUTLS_CERT_REQUEST); | 2630 | GNUTLS_CERT_REQUEST); |
2616 | #else /* ! HTTPS_SUPPORT */ | 2631 | #else /* ! HTTPS_SUPPORT */ |
2617 | eno = EINVAL; | 2632 | eno = EINVAL; |
2618 | goto cleanup; | 2633 | goto cleanup; |
2619 | #endif /* ! HTTPS_SUPPORT */ | 2634 | #endif /* ! HTTPS_SUPPORT */ |
2620 | } | 2635 | } |
2621 | 2636 | ||
2622 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2637 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2623 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2638 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2624 | #endif | 2639 | #endif |
2625 | /* Firm check under lock. */ | 2640 | /* Firm check under lock. */ |
2626 | if (daemon->connections >= daemon->connection_limit) | 2641 | if (daemon->connections >= daemon->connection_limit) |
2627 | { | 2642 | { |
2628 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2643 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2629 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2644 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2630 | #endif | 2645 | #endif |
2631 | /* above connection limit - reject */ | 2646 | /* above connection limit - reject */ |
2632 | #ifdef HAVE_MESSAGES | 2647 | #ifdef HAVE_MESSAGES |
2633 | MHD_DLOG (daemon, | 2648 | MHD_DLOG (daemon, |
2634 | _("Server reached connection limit. Closing inbound connection.\n")); | 2649 | _ ( |
2650 | "Server reached connection limit. Closing inbound connection.\n")); | ||
2635 | #endif | 2651 | #endif |
2636 | #if ENFILE | 2652 | #if ENFILE |
2637 | eno = ENFILE; | 2653 | eno = ENFILE; |
2638 | #endif | 2654 | #endif |
2639 | goto cleanup; | 2655 | goto cleanup; |
2640 | } | 2656 | } |
2641 | daemon->connections++; | 2657 | daemon->connections++; |
2642 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2658 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2643 | { | 2659 | { |
2644 | XDLL_insert (daemon->normal_timeout_head, | 2660 | XDLL_insert (daemon->normal_timeout_head, |
2645 | daemon->normal_timeout_tail, | 2661 | daemon->normal_timeout_tail, |
2646 | connection); | 2662 | connection); |
2647 | } | 2663 | } |
2648 | DLL_insert (daemon->connections_head, | 2664 | DLL_insert (daemon->connections_head, |
2649 | daemon->connections_tail, | 2665 | daemon->connections_tail, |
2650 | connection); | 2666 | connection); |
@@ -2659,80 +2675,82 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2659 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2675 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2660 | /* attempt to create handler thread */ | 2676 | /* attempt to create handler thread */ |
2661 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2677 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2678 | { | ||
2679 | if (! MHD_create_named_thread_ (&connection->pid, | ||
2680 | "MHD-connection", | ||
2681 | daemon->thread_stack_size, | ||
2682 | &thread_main_handle_connection, | ||
2683 | connection)) | ||
2662 | { | 2684 | { |
2663 | if (! MHD_create_named_thread_ (&connection->pid, | 2685 | eno = errno; |
2664 | "MHD-connection", | ||
2665 | daemon->thread_stack_size, | ||
2666 | &thread_main_handle_connection, | ||
2667 | connection)) | ||
2668 | { | ||
2669 | eno = errno; | ||
2670 | #ifdef HAVE_MESSAGES | 2686 | #ifdef HAVE_MESSAGES |
2671 | MHD_DLOG (daemon, | 2687 | MHD_DLOG (daemon, |
2672 | "Failed to create a thread: %s\n", | 2688 | "Failed to create a thread: %s\n", |
2673 | MHD_strerror_ (eno)); | 2689 | MHD_strerror_ (eno)); |
2674 | #endif | 2690 | #endif |
2675 | goto cleanup; | 2691 | goto cleanup; |
2676 | } | ||
2677 | } | 2692 | } |
2693 | } | ||
2678 | else | 2694 | else |
2679 | connection->pid = daemon->pid; | 2695 | connection->pid = daemon->pid; |
2680 | #endif | 2696 | #endif |
2681 | #ifdef EPOLL_SUPPORT | 2697 | #ifdef EPOLL_SUPPORT |
2682 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 2698 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
2683 | { | 2699 | { |
2684 | if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add)) | 2700 | if ((0 == (daemon->options & MHD_USE_TURBO)) || (external_add)) |
2685 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ | 2701 | { /* Do not manipulate EReady DL-list in 'external_add' mode. */ |
2686 | struct epoll_event event; | 2702 | struct epoll_event event; |
2687 | 2703 | ||
2688 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; | 2704 | event.events = EPOLLIN | EPOLLOUT | EPOLLPRI | EPOLLET; |
2689 | event.data.ptr = connection; | 2705 | event.data.ptr = connection; |
2690 | if (0 != epoll_ctl (daemon->epoll_fd, | 2706 | if (0 != epoll_ctl (daemon->epoll_fd, |
2691 | EPOLL_CTL_ADD, | 2707 | EPOLL_CTL_ADD, |
2692 | client_socket, | 2708 | client_socket, |
2693 | &event)) | 2709 | &event)) |
2694 | { | 2710 | { |
2695 | eno = errno; | 2711 | eno = errno; |
2696 | #ifdef HAVE_MESSAGES | 2712 | #ifdef HAVE_MESSAGES |
2697 | MHD_DLOG (daemon, | 2713 | MHD_DLOG (daemon, |
2698 | _("Call to epoll_ctl failed: %s\n"), | 2714 | _ ("Call to epoll_ctl failed: %s\n"), |
2699 | MHD_socket_last_strerr_ ()); | 2715 | MHD_socket_last_strerr_ ()); |
2700 | #endif | 2716 | #endif |
2701 | goto cleanup; | 2717 | goto cleanup; |
2702 | } | 2718 | } |
2703 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; | 2719 | connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET; |
2704 | } | 2720 | } |
2705 | else | 2721 | else |
2706 | { | 2722 | { |
2707 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY | 2723 | connection->epoll_state |= MHD_EPOLL_STATE_READ_READY |
2708 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2724 | | MHD_EPOLL_STATE_WRITE_READY |
2709 | EDLL_insert (daemon->eready_head, | 2725 | | MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2726 | EDLL_insert (daemon->eready_head, | ||
2710 | daemon->eready_tail, | 2727 | daemon->eready_tail, |
2711 | connection); | 2728 | connection); |
2712 | } | ||
2713 | } | 2729 | } |
2730 | } | ||
2714 | else /* This 'else' is combined with next 'if'. */ | 2731 | else /* This 'else' is combined with next 'if'. */ |
2715 | #endif | 2732 | #endif |
2716 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 2733 | if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
2717 | (external_add) && | 2734 | (external_add) && |
2718 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 2735 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2719 | (! MHD_itc_activate_ (daemon->itc, "n")) ) | 2736 | (! MHD_itc_activate_ (daemon->itc, "n")) ) |
2720 | { | 2737 | { |
2721 | #ifdef HAVE_MESSAGES | 2738 | #ifdef HAVE_MESSAGES |
2722 | MHD_DLOG (daemon, | 2739 | MHD_DLOG (daemon, |
2723 | _("Failed to signal new connection via inter-thread communication channel.")); | 2740 | _ ( |
2741 | "Failed to signal new connection via inter-thread communication channel.")); | ||
2724 | #endif | 2742 | #endif |
2725 | } | 2743 | } |
2726 | return MHD_YES; | 2744 | return MHD_YES; |
2727 | cleanup: | 2745 | cleanup: |
2728 | if (NULL != daemon->notify_connection) | 2746 | if (NULL != daemon->notify_connection) |
2729 | daemon->notify_connection (daemon->notify_connection_cls, | 2747 | daemon->notify_connection (daemon->notify_connection_cls, |
2730 | connection, | 2748 | connection, |
2731 | &connection->socket_context, | 2749 | &connection->socket_context, |
2732 | MHD_CONNECTION_NOTIFY_CLOSED); | 2750 | MHD_CONNECTION_NOTIFY_CLOSED); |
2733 | #ifdef HTTPS_SUPPORT | 2751 | #ifdef HTTPS_SUPPORT |
2734 | if (NULL != connection->tls_session) | 2752 | if (NULL != connection->tls_session) |
2735 | gnutls_deinit (connection->tls_session); | 2753 | gnutls_deinit (connection->tls_session); |
2736 | #endif /* HTTPS_SUPPORT */ | 2754 | #endif /* HTTPS_SUPPORT */ |
2737 | MHD_socket_close_chk_ (client_socket); | 2755 | MHD_socket_close_chk_ (client_socket); |
2738 | MHD_ip_limit_del (daemon, | 2756 | MHD_ip_limit_del (daemon, |
@@ -2742,14 +2760,14 @@ internal_add_connection (struct MHD_Daemon *daemon, | |||
2742 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2760 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2743 | #endif | 2761 | #endif |
2744 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2762 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2745 | { | 2763 | { |
2746 | XDLL_remove (daemon->normal_timeout_head, | 2764 | XDLL_remove (daemon->normal_timeout_head, |
2747 | daemon->normal_timeout_tail, | 2765 | daemon->normal_timeout_tail, |
2748 | connection); | 2766 | connection); |
2749 | } | 2767 | } |
2750 | DLL_remove (daemon->connections_head, | 2768 | DLL_remove (daemon->connections_head, |
2751 | daemon->connections_tail, | 2769 | daemon->connections_tail, |
2752 | connection); | 2770 | connection); |
2753 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2771 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2754 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2772 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2755 | #endif | 2773 | #endif |
@@ -2782,25 +2800,25 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
2782 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2800 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2783 | #endif | 2801 | #endif |
2784 | if (connection->resuming) | 2802 | if (connection->resuming) |
2785 | { | 2803 | { |
2786 | /* suspending again while we didn't even complete resuming yet */ | 2804 | /* suspending again while we didn't even complete resuming yet */ |
2787 | connection->resuming = false; | 2805 | connection->resuming = false; |
2788 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2806 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2789 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2807 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2790 | #endif | 2808 | #endif |
2791 | return; | 2809 | return; |
2792 | } | 2810 | } |
2793 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 2811 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
2794 | { | 2812 | { |
2795 | if (connection->connection_timeout == daemon->connection_timeout) | 2813 | if (connection->connection_timeout == daemon->connection_timeout) |
2796 | XDLL_remove (daemon->normal_timeout_head, | 2814 | XDLL_remove (daemon->normal_timeout_head, |
2797 | daemon->normal_timeout_tail, | 2815 | daemon->normal_timeout_tail, |
2798 | connection); | 2816 | connection); |
2799 | else | 2817 | else |
2800 | XDLL_remove (daemon->manual_timeout_head, | 2818 | XDLL_remove (daemon->manual_timeout_head, |
2801 | daemon->manual_timeout_tail, | 2819 | daemon->manual_timeout_tail, |
2802 | connection); | 2820 | connection); |
2803 | } | 2821 | } |
2804 | DLL_remove (daemon->connections_head, | 2822 | DLL_remove (daemon->connections_head, |
2805 | daemon->connections_tail, | 2823 | daemon->connections_tail, |
2806 | connection); | 2824 | connection); |
@@ -2811,25 +2829,25 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
2811 | connection->suspended = true; | 2829 | connection->suspended = true; |
2812 | #ifdef EPOLL_SUPPORT | 2830 | #ifdef EPOLL_SUPPORT |
2813 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 2831 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
2832 | { | ||
2833 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | ||
2814 | { | 2834 | { |
2815 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 2835 | EDLL_remove (daemon->eready_head, |
2816 | { | 2836 | daemon->eready_tail, |
2817 | EDLL_remove (daemon->eready_head, | 2837 | connection); |
2818 | daemon->eready_tail, | 2838 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
2819 | connection); | 2839 | } |
2820 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 2840 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) |
2821 | } | 2841 | { |
2822 | if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) | 2842 | if (0 != epoll_ctl (daemon->epoll_fd, |
2823 | { | 2843 | EPOLL_CTL_DEL, |
2824 | if (0 != epoll_ctl (daemon->epoll_fd, | 2844 | connection->socket_fd, |
2825 | EPOLL_CTL_DEL, | 2845 | NULL)) |
2826 | connection->socket_fd, | 2846 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
2827 | NULL)) | 2847 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; |
2828 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | ||
2829 | connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; | ||
2830 | } | ||
2831 | connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; | ||
2832 | } | 2848 | } |
2849 | connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED; | ||
2850 | } | ||
2833 | #endif | 2851 | #endif |
2834 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2852 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2835 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2853 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
@@ -2871,19 +2889,21 @@ internal_suspend_connection_ (struct MHD_Connection *connection) | |||
2871 | void | 2889 | void |
2872 | MHD_suspend_connection (struct MHD_Connection *connection) | 2890 | MHD_suspend_connection (struct MHD_Connection *connection) |
2873 | { | 2891 | { |
2874 | struct MHD_Daemon * const daemon = connection->daemon; | 2892 | struct MHD_Daemon *const daemon = connection->daemon; |
2875 | 2893 | ||
2876 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) | 2894 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) |
2877 | MHD_PANIC (_("Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | 2895 | MHD_PANIC (_ ( |
2896 | "Cannot suspend connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | ||
2878 | #ifdef UPGRADE_SUPPORT | 2897 | #ifdef UPGRADE_SUPPORT |
2879 | if (NULL != connection->urh) | 2898 | if (NULL != connection->urh) |
2880 | { | 2899 | { |
2881 | #ifdef HAVE_MESSAGES | 2900 | #ifdef HAVE_MESSAGES |
2882 | MHD_DLOG (daemon, | 2901 | MHD_DLOG (daemon, |
2883 | _("Error: connection scheduled for \"upgrade\" cannot be suspended")); | 2902 | _ ( |
2903 | "Error: connection scheduled for \"upgrade\" cannot be suspended")); | ||
2884 | #endif /* HAVE_MESSAGES */ | 2904 | #endif /* HAVE_MESSAGES */ |
2885 | return; | 2905 | return; |
2886 | } | 2906 | } |
2887 | #endif /* UPGRADE_SUPPORT */ | 2907 | #endif /* UPGRADE_SUPPORT */ |
2888 | internal_suspend_connection_ (connection); | 2908 | internal_suspend_connection_ (connection); |
2889 | } | 2909 | } |
@@ -2903,7 +2923,8 @@ MHD_resume_connection (struct MHD_Connection *connection) | |||
2903 | struct MHD_Daemon *daemon = connection->daemon; | 2923 | struct MHD_Daemon *daemon = connection->daemon; |
2904 | 2924 | ||
2905 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) | 2925 | if (0 == (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) |
2906 | MHD_PANIC (_("Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | 2926 | MHD_PANIC (_ ( |
2927 | "Cannot resume connections without enabling MHD_ALLOW_SUSPEND_RESUME!\n")); | ||
2907 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2928 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2908 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2929 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2909 | #endif | 2930 | #endif |
@@ -2912,14 +2933,15 @@ MHD_resume_connection (struct MHD_Connection *connection) | |||
2912 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2933 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2913 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 2934 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
2914 | #endif | 2935 | #endif |
2915 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 2936 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
2916 | (! MHD_itc_activate_ (daemon->itc, "r")) ) | 2937 | (! MHD_itc_activate_ (daemon->itc, "r")) ) |
2917 | { | 2938 | { |
2918 | #ifdef HAVE_MESSAGES | 2939 | #ifdef HAVE_MESSAGES |
2919 | MHD_DLOG (daemon, | 2940 | MHD_DLOG (daemon, |
2920 | _("Failed to signal resume via inter-thread communication channel.")); | 2941 | _ ( |
2942 | "Failed to signal resume via inter-thread communication channel.")); | ||
2921 | #endif | 2943 | #endif |
2922 | } | 2944 | } |
2923 | } | 2945 | } |
2924 | 2946 | ||
2925 | 2947 | ||
@@ -2938,7 +2960,8 @@ resume_suspended_connections (struct MHD_Daemon *daemon) | |||
2938 | struct MHD_Connection *pos; | 2960 | struct MHD_Connection *pos; |
2939 | struct MHD_Connection *prev = NULL; | 2961 | struct MHD_Connection *prev = NULL; |
2940 | int ret; | 2962 | int ret; |
2941 | const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)); | 2963 | const bool used_thr_p_c = (0 != (daemon->options |
2964 | & MHD_USE_THREAD_PER_CONNECTION)); | ||
2942 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 2965 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
2943 | mhd_assert (NULL == daemon->worker_pool); | 2966 | mhd_assert (NULL == daemon->worker_pool); |
2944 | #endif | 2967 | #endif |
@@ -2947,112 +2970,114 @@ resume_suspended_connections (struct MHD_Daemon *daemon) | |||
2947 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 2970 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
2948 | #endif | 2971 | #endif |
2949 | if (daemon->resuming) | 2972 | if (daemon->resuming) |
2950 | { | 2973 | { |
2951 | prev = daemon->suspended_connections_tail; | 2974 | prev = daemon->suspended_connections_tail; |
2952 | /* During shutdown check for resuming is forced. */ | 2975 | /* During shutdown check for resuming is forced. */ |
2953 | mhd_assert((NULL != prev) || (daemon->shutdown)); | 2976 | mhd_assert ((NULL != prev) || (daemon->shutdown)); |
2954 | } | 2977 | } |
2955 | 2978 | ||
2956 | daemon->resuming = false; | 2979 | daemon->resuming = false; |
2957 | 2980 | ||
2958 | while (NULL != (pos = prev)) | 2981 | while (NULL != (pos = prev)) |
2959 | { | 2982 | { |
2960 | #ifdef UPGRADE_SUPPORT | 2983 | #ifdef UPGRADE_SUPPORT |
2961 | struct MHD_UpgradeResponseHandle * const urh = pos->urh; | 2984 | struct MHD_UpgradeResponseHandle *const urh = pos->urh; |
2962 | #else /* ! UPGRADE_SUPPORT */ | 2985 | #else /* ! UPGRADE_SUPPORT */ |
2963 | static const void * const urh = NULL; | 2986 | static const void *const urh = NULL; |
2964 | #endif /* ! UPGRADE_SUPPORT */ | 2987 | #endif /* ! UPGRADE_SUPPORT */ |
2965 | prev = pos->prev; | 2988 | prev = pos->prev; |
2966 | if ( (! pos->resuming) | 2989 | if ( (! pos->resuming) |
2967 | #ifdef UPGRADE_SUPPORT | 2990 | #ifdef UPGRADE_SUPPORT |
2968 | || ( (NULL != urh) && | 2991 | || ( (NULL != urh) && |
2969 | ( (! urh->was_closed) || | 2992 | ( (! urh->was_closed) || |
2970 | (! urh->clean_ready) ) ) | 2993 | (! urh->clean_ready) ) ) |
2971 | #endif /* UPGRADE_SUPPORT */ | 2994 | #endif /* UPGRADE_SUPPORT */ |
2972 | ) | 2995 | ) |
2973 | continue; | 2996 | continue; |
2974 | ret = MHD_YES; | 2997 | ret = MHD_YES; |
2975 | mhd_assert (pos->suspended); | 2998 | mhd_assert (pos->suspended); |
2976 | DLL_remove (daemon->suspended_connections_head, | 2999 | DLL_remove (daemon->suspended_connections_head, |
2977 | daemon->suspended_connections_tail, | 3000 | daemon->suspended_connections_tail, |
3001 | pos); | ||
3002 | pos->suspended = false; | ||
3003 | if (NULL == urh) | ||
3004 | { | ||
3005 | DLL_insert (daemon->connections_head, | ||
3006 | daemon->connections_tail, | ||
2978 | pos); | 3007 | pos); |
2979 | pos->suspended = false; | 3008 | if (! used_thr_p_c) |
2980 | if (NULL == urh) | 3009 | { |
2981 | { | 3010 | /* Reset timeout timer on resume. */ |
2982 | DLL_insert (daemon->connections_head, | 3011 | if (0 != pos->connection_timeout) |
2983 | daemon->connections_tail, | 3012 | pos->last_activity = MHD_monotonic_sec_counter (); |
2984 | pos); | 3013 | |
2985 | if (! used_thr_p_c) | 3014 | if (pos->connection_timeout == daemon->connection_timeout) |
2986 | { | 3015 | XDLL_insert (daemon->normal_timeout_head, |
2987 | /* Reset timeout timer on resume. */ | 3016 | daemon->normal_timeout_tail, |
2988 | if (0 != pos->connection_timeout) | 3017 | pos); |
2989 | pos->last_activity = MHD_monotonic_sec_counter(); | 3018 | else |
2990 | 3019 | XDLL_insert (daemon->manual_timeout_head, | |
2991 | if (pos->connection_timeout == daemon->connection_timeout) | 3020 | daemon->manual_timeout_tail, |
2992 | XDLL_insert (daemon->normal_timeout_head, | 3021 | pos); |
2993 | daemon->normal_timeout_tail, | 3022 | } |
2994 | pos); | ||
2995 | else | ||
2996 | XDLL_insert (daemon->manual_timeout_head, | ||
2997 | daemon->manual_timeout_tail, | ||
2998 | pos); | ||
2999 | } | ||
3000 | #ifdef EPOLL_SUPPORT | 3023 | #ifdef EPOLL_SUPPORT |
3001 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 3024 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
3002 | { | 3025 | { |
3003 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 3026 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
3004 | MHD_PANIC ("Resumed connection was already in EREADY set\n"); | 3027 | MHD_PANIC ("Resumed connection was already in EREADY set\n"); |
3005 | /* we always mark resumed connections as ready, as we | 3028 | /* we always mark resumed connections as ready, as we |
3006 | might have missed the edge poll event during suspension */ | 3029 | might have missed the edge poll event during suspension */ |
3007 | EDLL_insert (daemon->eready_head, | 3030 | EDLL_insert (daemon->eready_head, |
3008 | daemon->eready_tail, | 3031 | daemon->eready_tail, |
3009 | pos); | 3032 | pos); |
3010 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \ | 3033 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL \ |
3011 | MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; | 3034 | | MHD_EPOLL_STATE_READ_READY |
3012 | pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; | 3035 | | MHD_EPOLL_STATE_WRITE_READY; |
3013 | } | 3036 | pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED; |
3037 | } | ||
3014 | #endif | 3038 | #endif |
3015 | } | 3039 | } |
3016 | #ifdef UPGRADE_SUPPORT | 3040 | #ifdef UPGRADE_SUPPORT |
3017 | else | 3041 | else |
3018 | { | 3042 | { |
3019 | /* Data forwarding was finished (for TLS connections) AND | 3043 | /* Data forwarding was finished (for TLS connections) AND |
3020 | * application was closed upgraded connection. | 3044 | * application was closed upgraded connection. |
3021 | * Insert connection into cleanup list. */ | 3045 | * Insert connection into cleanup list. */ |
3022 | 3046 | ||
3023 | if ( (NULL != daemon->notify_completed) && | 3047 | if ( (NULL != daemon->notify_completed) && |
3024 | (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 3048 | (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
3025 | (pos->client_aware) ) | 3049 | (pos->client_aware) ) |
3026 | { | 3050 | { |
3027 | daemon->notify_completed (daemon->notify_completed_cls, | 3051 | daemon->notify_completed (daemon->notify_completed_cls, |
3028 | pos, | 3052 | pos, |
3029 | &pos->client_context, | 3053 | &pos->client_context, |
3030 | MHD_REQUEST_TERMINATED_COMPLETED_OK); | 3054 | MHD_REQUEST_TERMINATED_COMPLETED_OK); |
3031 | pos->client_aware = false; | 3055 | pos->client_aware = false; |
3032 | } | 3056 | } |
3033 | DLL_insert (daemon->cleanup_head, | 3057 | DLL_insert (daemon->cleanup_head, |
3034 | daemon->cleanup_tail, | 3058 | daemon->cleanup_tail, |
3035 | pos); | 3059 | pos); |
3036 | 3060 | ||
3037 | } | ||
3038 | #endif /* UPGRADE_SUPPORT */ | ||
3039 | pos->resuming = false; | ||
3040 | } | 3061 | } |
3062 | #endif /* UPGRADE_SUPPORT */ | ||
3063 | pos->resuming = false; | ||
3064 | } | ||
3041 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3065 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3042 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3066 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3043 | #endif | 3067 | #endif |
3044 | if ( (used_thr_p_c) && | 3068 | if ( (used_thr_p_c) && |
3045 | (MHD_NO != ret) ) | 3069 | (MHD_NO != ret) ) |
3046 | { /* Wake up suspended connections. */ | 3070 | { /* Wake up suspended connections. */ |
3047 | if (! MHD_itc_activate_(daemon->itc, | 3071 | if (! MHD_itc_activate_ (daemon->itc, |
3048 | "w")) | 3072 | "w")) |
3049 | { | 3073 | { |
3050 | #ifdef HAVE_MESSAGES | 3074 | #ifdef HAVE_MESSAGES |
3051 | MHD_DLOG (daemon, | 3075 | MHD_DLOG (daemon, |
3052 | _("Failed to signal resume of connection via inter-thread communication channel.")); | 3076 | _ ( |
3077 | "Failed to signal resume of connection via inter-thread communication channel.")); | ||
3053 | #endif | 3078 | #endif |
3054 | } | ||
3055 | } | 3079 | } |
3080 | } | ||
3056 | return ret; | 3081 | return ret; |
3057 | } | 3082 | } |
3058 | 3083 | ||
@@ -3093,34 +3118,34 @@ MHD_add_connection (struct MHD_Daemon *daemon, | |||
3093 | bool sk_nonbl; | 3118 | bool sk_nonbl; |
3094 | 3119 | ||
3095 | if (! MHD_socket_nonblocking_ (client_socket)) | 3120 | if (! MHD_socket_nonblocking_ (client_socket)) |
3096 | { | 3121 | { |
3097 | #ifdef HAVE_MESSAGES | 3122 | #ifdef HAVE_MESSAGES |
3098 | MHD_DLOG (daemon, | 3123 | MHD_DLOG (daemon, |
3099 | _("Failed to set nonblocking mode on new client socket: %s\n"), | 3124 | _ ("Failed to set nonblocking mode on new client socket: %s\n"), |
3100 | MHD_socket_last_strerr_()); | 3125 | MHD_socket_last_strerr_ ()); |
3101 | #endif | 3126 | #endif |
3102 | sk_nonbl = 0; | 3127 | sk_nonbl = 0; |
3103 | } | 3128 | } |
3104 | else | 3129 | else |
3105 | sk_nonbl = !0; | 3130 | sk_nonbl = ! 0; |
3106 | 3131 | ||
3107 | if ( (0 != (daemon->options & MHD_USE_TURBO)) && | 3132 | if ( (0 != (daemon->options & MHD_USE_TURBO)) && |
3108 | (! MHD_socket_noninheritable_ (client_socket)) ) | 3133 | (! MHD_socket_noninheritable_ (client_socket)) ) |
3109 | { | 3134 | { |
3110 | #ifdef HAVE_MESSAGES | 3135 | #ifdef HAVE_MESSAGES |
3111 | MHD_DLOG (daemon, | 3136 | MHD_DLOG (daemon, |
3112 | _("Failed to set noninheritable mode on new client socket.\n")); | 3137 | _ ("Failed to set noninheritable mode on new client socket.\n")); |
3113 | #endif | 3138 | #endif |
3114 | } | 3139 | } |
3115 | 3140 | ||
3116 | if ( (0 == (daemon->options & MHD_USE_TURBO)) && | 3141 | if ( (0 == (daemon->options & MHD_USE_TURBO)) && |
3117 | (! MHD_socket_buffering_reset_ (client_socket)) ) | 3142 | (! MHD_socket_buffering_reset_ (client_socket)) ) |
3118 | { | 3143 | { |
3119 | #ifdef HAVE_MESSAGES | 3144 | #ifdef HAVE_MESSAGES |
3120 | MHD_DLOG (daemon, | 3145 | MHD_DLOG (daemon, |
3121 | _("Failed to reset buffering mode on new client socket.\n")); | 3146 | _ ("Failed to reset buffering mode on new client socket.\n")); |
3122 | #endif | 3147 | #endif |
3123 | } | 3148 | } |
3124 | return internal_add_connection (daemon, | 3149 | return internal_add_connection (daemon, |
3125 | client_socket, | 3150 | client_socket, |
3126 | addr, | 3151 | addr, |
@@ -3179,94 +3204,98 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3179 | #endif /* ! USE_ACCEPT4 */ | 3204 | #endif /* ! USE_ACCEPT4 */ |
3180 | if ( (MHD_INVALID_SOCKET == s) || | 3205 | if ( (MHD_INVALID_SOCKET == s) || |
3181 | (addrlen <= 0) ) | 3206 | (addrlen <= 0) ) |
3182 | { | 3207 | { |
3183 | const int err = MHD_socket_get_error_ (); | 3208 | const int err = MHD_socket_get_error_ (); |
3184 | 3209 | ||
3185 | /* This could be a common occurance with multiple worker threads */ | 3210 | /* This could be a common occurance with multiple worker threads */ |
3186 | if (MHD_SCKT_ERR_IS_ (err, | 3211 | if (MHD_SCKT_ERR_IS_ (err, |
3187 | MHD_SCKT_EINVAL_)) | 3212 | MHD_SCKT_EINVAL_)) |
3188 | return MHD_NO; /* can happen during shutdown */ | 3213 | return MHD_NO; /* can happen during shutdown */ |
3189 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_(err)) | 3214 | if (MHD_SCKT_ERR_IS_DISCNN_BEFORE_ACCEPT_ (err)) |
3190 | return MHD_NO; /* do not print error if client just disconnected early */ | 3215 | return MHD_NO; /* do not print error if client just disconnected early */ |
3216 | #ifdef HAVE_MESSAGES | ||
3217 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) ) | ||
3218 | MHD_DLOG (daemon, | ||
3219 | _ ("Error accepting connection: %s\n"), | ||
3220 | MHD_socket_strerr_ (err)); | ||
3221 | #endif | ||
3222 | if (MHD_INVALID_SOCKET != s) | ||
3223 | { | ||
3224 | MHD_socket_close_chk_ (s); | ||
3225 | } | ||
3226 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) | ||
3227 | { | ||
3228 | /* system/process out of resources */ | ||
3229 | if (0 == daemon->connections) | ||
3230 | { | ||
3191 | #ifdef HAVE_MESSAGES | 3231 | #ifdef HAVE_MESSAGES |
3192 | if (! MHD_SCKT_ERR_IS_EAGAIN_ (err) ) | 3232 | /* Not setting 'at_limit' flag, as there is no way it |
3233 | would ever be cleared. Instead trying to produce | ||
3234 | bit fat ugly warning. */ | ||
3193 | MHD_DLOG (daemon, | 3235 | MHD_DLOG (daemon, |
3194 | _("Error accepting connection: %s\n"), | 3236 | _ ( |
3195 | MHD_socket_strerr_(err)); | 3237 | "Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); |
3196 | #endif | 3238 | #endif |
3197 | if (MHD_INVALID_SOCKET != s) | 3239 | } |
3198 | { | 3240 | else |
3199 | MHD_socket_close_chk_ (s); | 3241 | { |
3200 | } | ||
3201 | if ( MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) | ||
3202 | { | ||
3203 | /* system/process out of resources */ | ||
3204 | if (0 == daemon->connections) | ||
3205 | { | ||
3206 | #ifdef HAVE_MESSAGES | ||
3207 | /* Not setting 'at_limit' flag, as there is no way it | ||
3208 | would ever be cleared. Instead trying to produce | ||
3209 | bit fat ugly warning. */ | ||
3210 | MHD_DLOG (daemon, | ||
3211 | _("Hit process or system resource limit at FIRST connection. This is really bad as there is no sane way to proceed. Will try busy waiting for system resources to become magically available.\n")); | ||
3212 | #endif | ||
3213 | } | ||
3214 | else | ||
3215 | { | ||
3216 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3242 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3217 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3243 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
3218 | #endif | 3244 | #endif |
3219 | daemon->at_limit = true; | 3245 | daemon->at_limit = true; |
3220 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3246 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3221 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3247 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3222 | #endif | 3248 | #endif |
3223 | #ifdef HAVE_MESSAGES | 3249 | #ifdef HAVE_MESSAGES |
3224 | MHD_DLOG (daemon, | 3250 | MHD_DLOG (daemon, |
3225 | _("Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), | 3251 | _ ( |
3226 | (unsigned int) daemon->connections); | 3252 | "Hit process or system resource limit at %u connections, temporarily suspending accept(). Consider setting a lower MHD_OPTION_CONNECTION_LIMIT.\n"), |
3253 | (unsigned int) daemon->connections); | ||
3227 | #endif | 3254 | #endif |
3228 | } | 3255 | } |
3229 | } | ||
3230 | return MHD_NO; | ||
3231 | } | 3256 | } |
3257 | return MHD_NO; | ||
3258 | } | ||
3232 | #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE) | 3259 | #if defined(MHD_TCP_CORK_NOPUSH) || defined(HAVE_MSG_MORE) |
3233 | /* We will use TCP_CORK or TCP_NOPUSH or MSG_MORE to control | 3260 | /* We will use TCP_CORK or TCP_NOPUSH or MSG_MORE to control |
3234 | transmission, disable Nagle's algorithm (always) */ | 3261 | transmission, disable Nagle's algorithm (always) */ |
3235 | if (0 != MHD_socket_set_nodelay_ (s, | 3262 | if (0 != MHD_socket_set_nodelay_ (s, |
3236 | true)) | 3263 | true)) |
3237 | { | 3264 | { |
3238 | #ifdef HAVE_MESSAGES | 3265 | #ifdef HAVE_MESSAGES |
3239 | MHD_DLOG (daemon, | 3266 | MHD_DLOG (daemon, |
3240 | _("Failed to disable TCP Nagle on socket: %s\n"), | 3267 | _ ("Failed to disable TCP Nagle on socket: %s\n"), |
3241 | MHD_socket_last_strerr_()); | 3268 | MHD_socket_last_strerr_ ()); |
3242 | } | 3269 | } |
3243 | #endif | 3270 | #endif |
3244 | #endif | 3271 | #endif |
3245 | #if !defined(USE_ACCEPT4) || !defined(HAVE_SOCK_NONBLOCK) | 3272 | #if ! defined(USE_ACCEPT4) || ! defined(HAVE_SOCK_NONBLOCK) |
3246 | if (! MHD_socket_nonblocking_ (s)) | 3273 | if (! MHD_socket_nonblocking_ (s)) |
3247 | { | 3274 | { |
3248 | #ifdef HAVE_MESSAGES | 3275 | #ifdef HAVE_MESSAGES |
3249 | MHD_DLOG (daemon, | 3276 | MHD_DLOG (daemon, |
3250 | _("Failed to set nonblocking mode on incoming connection socket: %s\n"), | 3277 | _ ( |
3251 | MHD_socket_last_strerr_()); | 3278 | "Failed to set nonblocking mode on incoming connection socket: %s\n"), |
3279 | MHD_socket_last_strerr_ ()); | ||
3252 | #endif | 3280 | #endif |
3253 | } | 3281 | } |
3254 | else | 3282 | else |
3255 | sk_nonbl = !0; | 3283 | sk_nonbl = ! 0; |
3256 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ | 3284 | #endif /* !USE_ACCEPT4 || !HAVE_SOCK_NONBLOCK */ |
3257 | #if !defined(USE_ACCEPT4) || !defined(SOCK_CLOEXEC) | 3285 | #if ! defined(USE_ACCEPT4) || ! defined(SOCK_CLOEXEC) |
3258 | if (! MHD_socket_noninheritable_ (s)) | 3286 | if (! MHD_socket_noninheritable_ (s)) |
3259 | { | 3287 | { |
3260 | #ifdef HAVE_MESSAGES | 3288 | #ifdef HAVE_MESSAGES |
3261 | MHD_DLOG (daemon, | 3289 | MHD_DLOG (daemon, |
3262 | _("Failed to set noninheritable mode on incoming connection socket.\n")); | 3290 | _ ( |
3291 | "Failed to set noninheritable mode on incoming connection socket.\n")); | ||
3263 | #endif | 3292 | #endif |
3264 | } | 3293 | } |
3265 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ | 3294 | #endif /* !USE_ACCEPT4 || !SOCK_CLOEXEC */ |
3266 | #ifdef HAVE_MESSAGES | 3295 | #ifdef HAVE_MESSAGES |
3267 | #if DEBUG_CONNECT | 3296 | #if DEBUG_CONNECT |
3268 | MHD_DLOG (daemon, | 3297 | MHD_DLOG (daemon, |
3269 | _("Accepted connection on socket %d\n"), | 3298 | _ ("Accepted connection on socket %d\n"), |
3270 | s); | 3299 | s); |
3271 | #endif | 3300 | #endif |
3272 | #endif | 3301 | #endif |
@@ -3298,80 +3327,80 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) | |||
3298 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3327 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
3299 | #endif | 3328 | #endif |
3300 | while (NULL != (pos = daemon->cleanup_tail)) | 3329 | while (NULL != (pos = daemon->cleanup_tail)) |
3301 | { | 3330 | { |
3302 | DLL_remove (daemon->cleanup_head, | 3331 | DLL_remove (daemon->cleanup_head, |
3303 | daemon->cleanup_tail, | 3332 | daemon->cleanup_tail, |
3304 | pos); | 3333 | pos); |
3305 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3334 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3306 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3335 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3307 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 3336 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
3308 | (! pos->thread_joined) && | 3337 | (! pos->thread_joined) && |
3309 | (! MHD_join_thread_ (pos->pid.handle)) ) | 3338 | (! MHD_join_thread_ (pos->pid.handle)) ) |
3310 | MHD_PANIC (_("Failed to join a thread\n")); | 3339 | MHD_PANIC (_ ("Failed to join a thread\n")); |
3311 | #endif | 3340 | #endif |
3312 | #ifdef UPGRADE_SUPPORT | 3341 | #ifdef UPGRADE_SUPPORT |
3313 | cleanup_upgraded_connection (pos); | 3342 | cleanup_upgraded_connection (pos); |
3314 | #endif /* UPGRADE_SUPPORT */ | 3343 | #endif /* UPGRADE_SUPPORT */ |
3315 | MHD_pool_destroy (pos->pool); | 3344 | MHD_pool_destroy (pos->pool); |
3316 | #ifdef HTTPS_SUPPORT | 3345 | #ifdef HTTPS_SUPPORT |
3317 | if (NULL != pos->tls_session) | 3346 | if (NULL != pos->tls_session) |
3318 | gnutls_deinit (pos->tls_session); | 3347 | gnutls_deinit (pos->tls_session); |
3319 | #endif /* HTTPS_SUPPORT */ | 3348 | #endif /* HTTPS_SUPPORT */ |
3320 | 3349 | ||
3321 | /* clean up the connection */ | 3350 | /* clean up the connection */ |
3322 | if (NULL != daemon->notify_connection) | 3351 | if (NULL != daemon->notify_connection) |
3323 | daemon->notify_connection (daemon->notify_connection_cls, | 3352 | daemon->notify_connection (daemon->notify_connection_cls, |
3324 | pos, | 3353 | pos, |
3325 | &pos->socket_context, | 3354 | &pos->socket_context, |
3326 | MHD_CONNECTION_NOTIFY_CLOSED); | 3355 | MHD_CONNECTION_NOTIFY_CLOSED); |
3327 | MHD_ip_limit_del (daemon, | 3356 | MHD_ip_limit_del (daemon, |
3328 | pos->addr, | 3357 | pos->addr, |
3329 | pos->addr_len); | 3358 | pos->addr_len); |
3330 | #ifdef EPOLL_SUPPORT | 3359 | #ifdef EPOLL_SUPPORT |
3331 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 3360 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
3332 | { | 3361 | { |
3333 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | 3362 | if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) |
3334 | { | 3363 | { |
3335 | EDLL_remove (daemon->eready_head, | 3364 | EDLL_remove (daemon->eready_head, |
3336 | daemon->eready_tail, | 3365 | daemon->eready_tail, |
3337 | pos); | 3366 | pos); |
3338 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 3367 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
3339 | } | 3368 | } |
3340 | if ( (-1 != daemon->epoll_fd) && | 3369 | if ( (-1 != daemon->epoll_fd) && |
3341 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) | 3370 | (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) ) |
3342 | { | 3371 | { |
3343 | /* epoll documentation suggests that closing a FD | 3372 | /* epoll documentation suggests that closing a FD |
3344 | automatically removes it from the epoll set; however, | 3373 | automatically removes it from the epoll set; however, |
3345 | this is not true as if we fail to do manually remove it, | 3374 | this is not true as if we fail to do manually remove it, |
3346 | we are still seeing an event for this fd in epoll, | 3375 | we are still seeing an event for this fd in epoll, |
3347 | causing grief (use-after-free...) --- at least on my | 3376 | causing grief (use-after-free...) --- at least on my |
3348 | system. */ | 3377 | system. */ |
3349 | if (0 != epoll_ctl (daemon->epoll_fd, | 3378 | if (0 != epoll_ctl (daemon->epoll_fd, |
3350 | EPOLL_CTL_DEL, | 3379 | EPOLL_CTL_DEL, |
3351 | pos->socket_fd, | 3380 | pos->socket_fd, |
3352 | NULL)) | 3381 | NULL)) |
3353 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | 3382 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
3354 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; | 3383 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET; |
3355 | } | 3384 | } |
3356 | } | 3385 | } |
3357 | #endif | 3386 | #endif |
3358 | if (NULL != pos->response) | 3387 | if (NULL != pos->response) |
3359 | { | 3388 | { |
3360 | MHD_destroy_response (pos->response); | 3389 | MHD_destroy_response (pos->response); |
3361 | pos->response = NULL; | 3390 | pos->response = NULL; |
3362 | } | 3391 | } |
3363 | if (MHD_INVALID_SOCKET != pos->socket_fd) | 3392 | if (MHD_INVALID_SOCKET != pos->socket_fd) |
3364 | MHD_socket_close_chk_ (pos->socket_fd); | 3393 | MHD_socket_close_chk_ (pos->socket_fd); |
3365 | if (NULL != pos->addr) | 3394 | if (NULL != pos->addr) |
3366 | free (pos->addr); | 3395 | free (pos->addr); |
3367 | free (pos); | 3396 | free (pos); |
3368 | 3397 | ||
3369 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3398 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3370 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 3399 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
3371 | #endif | 3400 | #endif |
3372 | daemon->connections--; | 3401 | daemon->connections--; |
3373 | daemon->at_limit = false; | 3402 | daemon->at_limit = false; |
3374 | } | 3403 | } |
3375 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 3404 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
3376 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 3405 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
3377 | #endif | 3406 | #endif |
@@ -3408,71 +3437,71 @@ MHD_get_timeout (struct MHD_Daemon *daemon, | |||
3408 | bool have_timeout; | 3437 | bool have_timeout; |
3409 | 3438 | ||
3410 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3439 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3411 | { | 3440 | { |
3412 | #ifdef HAVE_MESSAGES | 3441 | #ifdef HAVE_MESSAGES |
3413 | MHD_DLOG (daemon, | 3442 | MHD_DLOG (daemon, |
3414 | _("Illegal call to MHD_get_timeout\n")); | 3443 | _ ("Illegal call to MHD_get_timeout\n")); |
3415 | #endif | 3444 | #endif |
3416 | return MHD_NO; | 3445 | return MHD_NO; |
3417 | } | 3446 | } |
3418 | 3447 | ||
3419 | if (daemon->data_already_pending) | 3448 | if (daemon->data_already_pending) |
3420 | { | 3449 | { |
3421 | /* Some data already waiting to be processed. */ | 3450 | /* Some data already waiting to be processed. */ |
3422 | *timeout = 0; | 3451 | *timeout = 0; |
3423 | return MHD_YES; | 3452 | return MHD_YES; |
3424 | } | 3453 | } |
3425 | 3454 | ||
3426 | #ifdef EPOLL_SUPPORT | 3455 | #ifdef EPOLL_SUPPORT |
3427 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | 3456 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && |
3428 | ((NULL != daemon->eready_head) | 3457 | ((NULL != daemon->eready_head) |
3429 | #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) | 3458 | #if defined(UPGRADE_SUPPORT) && defined(HTTPS_SUPPORT) |
3430 | || (NULL != daemon->eready_urh_head) | 3459 | || (NULL != daemon->eready_urh_head) |
3431 | #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ | 3460 | #endif /* UPGRADE_SUPPORT && HTTPS_SUPPORT */ |
3432 | ) ) | 3461 | ) ) |
3433 | { | 3462 | { |
3434 | /* Some connection(s) already have some data pending. */ | 3463 | /* Some connection(s) already have some data pending. */ |
3435 | *timeout = 0; | 3464 | *timeout = 0; |
3436 | return MHD_YES; | 3465 | return MHD_YES; |
3437 | } | 3466 | } |
3438 | #endif /* EPOLL_SUPPORT */ | 3467 | #endif /* EPOLL_SUPPORT */ |
3439 | 3468 | ||
3440 | have_timeout = false; | 3469 | have_timeout = false; |
3441 | earliest_deadline = 0; /* avoid compiler warnings */ | 3470 | earliest_deadline = 0; /* avoid compiler warnings */ |
3442 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) | 3471 | for (pos = daemon->manual_timeout_tail; NULL != pos; pos = pos->prevX) |
3472 | { | ||
3473 | if (0 != pos->connection_timeout) | ||
3443 | { | 3474 | { |
3444 | if (0 != pos->connection_timeout) | 3475 | if ( (! have_timeout) || |
3445 | { | 3476 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) |
3446 | if ( (! have_timeout) || | 3477 | earliest_deadline = pos->last_activity + pos->connection_timeout; |
3447 | (earliest_deadline - pos->last_activity > pos->connection_timeout) ) | 3478 | have_timeout = true; |
3448 | earliest_deadline = pos->last_activity + pos->connection_timeout; | ||
3449 | have_timeout = true; | ||
3450 | } | ||
3451 | } | 3479 | } |
3480 | } | ||
3452 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ | 3481 | /* normal timeouts are sorted, so we only need to look at the 'tail' (oldest) */ |
3453 | pos = daemon->normal_timeout_tail; | 3482 | pos = daemon->normal_timeout_tail; |
3454 | if ( (NULL != pos) && | 3483 | if ( (NULL != pos) && |
3455 | (0 != pos->connection_timeout) ) | 3484 | (0 != pos->connection_timeout) ) |
3456 | { | 3485 | { |
3457 | if ( (! have_timeout) || | 3486 | if ( (! have_timeout) || |
3458 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) | 3487 | (earliest_deadline - pos->connection_timeout > pos->last_activity) ) |
3459 | earliest_deadline = pos->last_activity + pos->connection_timeout; | 3488 | earliest_deadline = pos->last_activity + pos->connection_timeout; |
3460 | have_timeout = true; | 3489 | have_timeout = true; |
3461 | } | 3490 | } |
3462 | 3491 | ||
3463 | if (! have_timeout) | 3492 | if (! have_timeout) |
3464 | return MHD_NO; | 3493 | return MHD_NO; |
3465 | now = MHD_monotonic_sec_counter(); | 3494 | now = MHD_monotonic_sec_counter (); |
3466 | if (earliest_deadline < now) | 3495 | if (earliest_deadline < now) |
3467 | *timeout = 0; | 3496 | *timeout = 0; |
3468 | else | 3497 | else |
3469 | { | 3498 | { |
3470 | const time_t second_left = earliest_deadline - now; | 3499 | const time_t second_left = earliest_deadline - now; |
3471 | 3500 | ||
3472 | if (((unsigned long long)second_left) > ULLONG_MAX / 1000) | 3501 | if (((unsigned long long) second_left) > ULLONG_MAX / 1000) |
3473 | *timeout = ULLONG_MAX; | 3502 | *timeout = ULLONG_MAX; |
3474 | else | 3503 | else |
3475 | *timeout = 1000LLU * (unsigned long long) second_left; | 3504 | *timeout = 1000LLU * (unsigned long long) second_left; |
3476 | } | 3505 | } |
3477 | return MHD_YES; | 3506 | return MHD_YES; |
3478 | } | 3507 | } |
@@ -3508,7 +3537,7 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
3508 | /* Clear ITC to avoid spinning select */ | 3537 | /* Clear ITC to avoid spinning select */ |
3509 | /* Do it before any other processing so new signals | 3538 | /* Do it before any other processing so new signals |
3510 | will trigger select again and will be processed */ | 3539 | will trigger select again and will be processed */ |
3511 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 3540 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
3512 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), | 3541 | (FD_ISSET (MHD_itc_r_fd_ (daemon->itc), |
3513 | read_fd_set)) ) | 3542 | read_fd_set)) ) |
3514 | MHD_itc_clear_ (daemon->itc); | 3543 | MHD_itc_clear_ (daemon->itc); |
@@ -3521,49 +3550,49 @@ internal_run_from_select (struct MHD_Daemon *daemon, | |||
3521 | (void) MHD_accept_connection (daemon); | 3550 | (void) MHD_accept_connection (daemon); |
3522 | 3551 | ||
3523 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3552 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3553 | { | ||
3554 | /* do not have a thread per connection, process all connections now */ | ||
3555 | prev = daemon->connections_tail; | ||
3556 | while (NULL != (pos = prev)) | ||
3524 | { | 3557 | { |
3525 | /* do not have a thread per connection, process all connections now */ | 3558 | prev = pos->prev; |
3526 | prev = daemon->connections_tail; | 3559 | ds = pos->socket_fd; |
3527 | while (NULL != (pos = prev)) | 3560 | if (MHD_INVALID_SOCKET == ds) |
3528 | { | 3561 | continue; |
3529 | prev = pos->prev; | 3562 | call_handlers (pos, |
3530 | ds = pos->socket_fd; | 3563 | FD_ISSET (ds, |
3531 | if (MHD_INVALID_SOCKET == ds) | 3564 | read_fd_set), |
3532 | continue; | 3565 | FD_ISSET (ds, |
3533 | call_handlers (pos, | 3566 | write_fd_set), |
3534 | FD_ISSET (ds, | 3567 | FD_ISSET (ds, |
3535 | read_fd_set), | 3568 | except_fd_set)); |
3536 | FD_ISSET (ds, | ||
3537 | write_fd_set), | ||
3538 | FD_ISSET (ds, | ||
3539 | except_fd_set)); | ||
3540 | } | ||
3541 | } | 3569 | } |
3570 | } | ||
3542 | 3571 | ||
3543 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 3572 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
3544 | /* handle upgraded HTTPS connections */ | 3573 | /* handle upgraded HTTPS connections */ |
3545 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 3574 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
3575 | { | ||
3576 | urhn = urh->prev; | ||
3577 | /* update urh state based on select() output */ | ||
3578 | urh_from_fdset (urh, | ||
3579 | read_fd_set, | ||
3580 | write_fd_set, | ||
3581 | except_fd_set); | ||
3582 | /* call generic forwarding function for passing data */ | ||
3583 | process_urh (urh); | ||
3584 | /* Finished forwarding? */ | ||
3585 | if ( (0 == urh->in_buffer_size) && | ||
3586 | (0 == urh->out_buffer_size) && | ||
3587 | (0 == urh->in_buffer_used) && | ||
3588 | (0 == urh->out_buffer_used) ) | ||
3546 | { | 3589 | { |
3547 | urhn = urh->prev; | 3590 | MHD_connection_finish_forward_ (urh->connection); |
3548 | /* update urh state based on select() output */ | 3591 | urh->clean_ready = true; |
3549 | urh_from_fdset (urh, | 3592 | /* Resuming will move connection to cleanup list. */ |
3550 | read_fd_set, | 3593 | MHD_resume_connection (urh->connection); |
3551 | write_fd_set, | ||
3552 | except_fd_set); | ||
3553 | /* call generic forwarding function for passing data */ | ||
3554 | process_urh (urh); | ||
3555 | /* Finished forwarding? */ | ||
3556 | if ( (0 == urh->in_buffer_size) && | ||
3557 | (0 == urh->out_buffer_size) && | ||
3558 | (0 == urh->in_buffer_used) && | ||
3559 | (0 == urh->out_buffer_used) ) | ||
3560 | { | ||
3561 | MHD_connection_finish_forward_ (urh->connection); | ||
3562 | urh->clean_ready = true; | ||
3563 | /* Resuming will move connection to cleanup list. */ | ||
3564 | MHD_resume_connection(urh->connection); | ||
3565 | } | ||
3566 | } | 3594 | } |
3595 | } | ||
3567 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 3596 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
3568 | MHD_cleanup_connections (daemon); | 3597 | MHD_cleanup_connections (daemon); |
3569 | return MHD_YES; | 3598 | return MHD_YES; |
@@ -3599,33 +3628,33 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
3599 | const fd_set *except_fd_set) | 3628 | const fd_set *except_fd_set) |
3600 | { | 3629 | { |
3601 | fd_set es; | 3630 | fd_set es; |
3602 | if (0 != (daemon->options & | 3631 | if (0 != (daemon->options |
3603 | (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_POLL)) ) | 3632 | & (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_POLL)) ) |
3604 | return MHD_NO; | 3633 | return MHD_NO; |
3605 | if (NULL == read_fd_set || NULL == write_fd_set) | 3634 | if ((NULL == read_fd_set)||(NULL == write_fd_set)) |
3606 | return MHD_NO; | 3635 | return MHD_NO; |
3607 | if (NULL == except_fd_set) | 3636 | if (NULL == except_fd_set) |
3608 | { /* Workaround to maintain backward compatibility. */ | 3637 | { /* Workaround to maintain backward compatibility. */ |
3609 | #ifdef HAVE_MESSAGES | 3638 | #ifdef HAVE_MESSAGES |
3610 | MHD_DLOG (daemon, | 3639 | MHD_DLOG (daemon, |
3611 | _("MHD_run_from_select() called with except_fd_set " | 3640 | _ ("MHD_run_from_select() called with except_fd_set " |
3612 | "set to NULL. Such behavior is deprecated.\n")); | 3641 | "set to NULL. Such behavior is deprecated.\n")); |
3613 | #endif | 3642 | #endif |
3614 | FD_ZERO (&es); | 3643 | FD_ZERO (&es); |
3615 | except_fd_set = &es; | 3644 | except_fd_set = &es; |
3616 | } | 3645 | } |
3617 | if (0 != (daemon->options & MHD_USE_EPOLL)) | 3646 | if (0 != (daemon->options & MHD_USE_EPOLL)) |
3618 | { | 3647 | { |
3619 | #ifdef EPOLL_SUPPORT | 3648 | #ifdef EPOLL_SUPPORT |
3620 | int ret = MHD_epoll (daemon, | 3649 | int ret = MHD_epoll (daemon, |
3621 | MHD_NO); | 3650 | MHD_NO); |
3622 | 3651 | ||
3623 | MHD_cleanup_connections (daemon); | 3652 | MHD_cleanup_connections (daemon); |
3624 | return ret; | 3653 | return ret; |
3625 | #else /* ! EPOLL_SUPPORT */ | 3654 | #else /* ! EPOLL_SUPPORT */ |
3626 | return MHD_NO; | 3655 | return MHD_NO; |
3627 | #endif /* ! EPOLL_SUPPORT */ | 3656 | #endif /* ! EPOLL_SUPPORT */ |
3628 | } | 3657 | } |
3629 | 3658 | ||
3630 | /* Resuming external connections when using an extern mainloop */ | 3659 | /* Resuming external connections when using an extern mainloop */ |
3631 | if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) | 3660 | if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) |
@@ -3648,7 +3677,7 @@ MHD_run_from_select (struct MHD_Daemon *daemon, | |||
3648 | */ | 3677 | */ |
3649 | static int | 3678 | static int |
3650 | MHD_select (struct MHD_Daemon *daemon, | 3679 | MHD_select (struct MHD_Daemon *daemon, |
3651 | int may_block) | 3680 | int may_block) |
3652 | { | 3681 | { |
3653 | int num_ready; | 3682 | int num_ready; |
3654 | fd_set rs; | 3683 | fd_set rs; |
@@ -3676,71 +3705,72 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3676 | may_block = MHD_NO; | 3705 | may_block = MHD_NO; |
3677 | 3706 | ||
3678 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 3707 | if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
3708 | { | ||
3709 | /* single-threaded, go over everything */ | ||
3710 | if (MHD_NO == | ||
3711 | internal_get_fdset2 (daemon, | ||
3712 | &rs, | ||
3713 | &ws, | ||
3714 | &es, | ||
3715 | &maxsock, | ||
3716 | FD_SETSIZE)) | ||
3679 | { | 3717 | { |
3680 | /* single-threaded, go over everything */ | ||
3681 | if (MHD_NO == | ||
3682 | internal_get_fdset2 (daemon, | ||
3683 | &rs, | ||
3684 | &ws, | ||
3685 | &es, | ||
3686 | &maxsock, | ||
3687 | FD_SETSIZE)) | ||
3688 | { | ||
3689 | #ifdef HAVE_MESSAGES | 3718 | #ifdef HAVE_MESSAGES |
3690 | MHD_DLOG (daemon, | 3719 | MHD_DLOG (daemon, |
3691 | _("Could not obtain daemon fdsets")); | 3720 | _ ("Could not obtain daemon fdsets")); |
3692 | #endif | 3721 | #endif |
3693 | err_state = MHD_YES; | 3722 | err_state = MHD_YES; |
3694 | } | ||
3695 | } | 3723 | } |
3724 | } | ||
3696 | else | 3725 | else |
3726 | { | ||
3727 | /* accept only, have one thread per connection */ | ||
3728 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && | ||
3729 | (! daemon->was_quiesced) && | ||
3730 | (! MHD_add_to_fd_set_ (ls, | ||
3731 | &rs, | ||
3732 | &maxsock, | ||
3733 | FD_SETSIZE)) ) | ||
3697 | { | 3734 | { |
3698 | /* accept only, have one thread per connection */ | ||
3699 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && | ||
3700 | (! daemon->was_quiesced) && | ||
3701 | (! MHD_add_to_fd_set_ (ls, | ||
3702 | &rs, | ||
3703 | &maxsock, | ||
3704 | FD_SETSIZE)) ) | ||
3705 | { | ||
3706 | #ifdef HAVE_MESSAGES | 3735 | #ifdef HAVE_MESSAGES |
3707 | MHD_DLOG (daemon, | 3736 | MHD_DLOG (daemon, |
3708 | _("Could not add listen socket to fdset")); | 3737 | _ ("Could not add listen socket to fdset")); |
3709 | #endif | 3738 | #endif |
3710 | return MHD_NO; | 3739 | return MHD_NO; |
3711 | } | ||
3712 | } | 3740 | } |
3713 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 3741 | } |
3742 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && | ||
3714 | (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), | 3743 | (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
3715 | &rs, | 3744 | &rs, |
3716 | &maxsock, | 3745 | &maxsock, |
3717 | FD_SETSIZE)) ) | 3746 | FD_SETSIZE)) ) |
3718 | { | 3747 | { |
3719 | #if defined(MHD_WINSOCK_SOCKETS) | 3748 | #if defined(MHD_WINSOCK_SOCKETS) |
3720 | /* fdset limit reached, new connections | 3749 | /* fdset limit reached, new connections |
3721 | cannot be handled. Remove listen socket FD | 3750 | cannot be handled. Remove listen socket FD |
3722 | from fdset and retry to add ITC FD. */ | 3751 | from fdset and retry to add ITC FD. */ |
3723 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && | 3752 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && |
3724 | (! daemon->was_quiesced) ) | 3753 | (! daemon->was_quiesced) ) |
3725 | { | 3754 | { |
3726 | FD_CLR (ls, | 3755 | FD_CLR (ls, |
3727 | &rs); | 3756 | &rs); |
3728 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_(daemon->itc), | 3757 | if (! MHD_add_to_fd_set_ (MHD_itc_r_fd_ (daemon->itc), |
3729 | &rs, | 3758 | &rs, |
3730 | &maxsock, | 3759 | &maxsock, |
3731 | FD_SETSIZE)) | 3760 | FD_SETSIZE)) |
3732 | { | 3761 | { |
3733 | #endif /* MHD_WINSOCK_SOCKETS */ | 3762 | #endif /* MHD_WINSOCK_SOCKETS */ |
3734 | #ifdef HAVE_MESSAGES | 3763 | #ifdef HAVE_MESSAGES |
3735 | MHD_DLOG (daemon, | 3764 | MHD_DLOG (daemon, |
3736 | _("Could not add control inter-thread communication channel FD to fdset")); | 3765 | _ ( |
3766 | "Could not add control inter-thread communication channel FD to fdset")); | ||
3737 | #endif | 3767 | #endif |
3738 | err_state = MHD_YES; | 3768 | err_state = MHD_YES; |
3739 | #if defined(MHD_WINSOCK_SOCKETS) | 3769 | #if defined(MHD_WINSOCK_SOCKETS) |
3740 | } | 3770 | } |
3741 | } | 3771 | } |
3742 | #endif /* MHD_WINSOCK_SOCKETS */ | 3772 | #endif /* MHD_WINSOCK_SOCKETS */ |
3743 | } | 3773 | } |
3744 | /* Stop listening if we are at the configured connection limit */ | 3774 | /* Stop listening if we are at the configured connection limit */ |
3745 | /* If we're at the connection limit, no point in really | 3775 | /* If we're at the connection limit, no point in really |
3746 | accepting new connections; however, make sure we do not miss | 3776 | accepting new connections; however, make sure we do not miss |
@@ -3748,33 +3778,33 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3748 | only do this optimization if we have a signaling ITC in | 3778 | only do this optimization if we have a signaling ITC in |
3749 | place. */ | 3779 | place. */ |
3750 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && | 3780 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && |
3751 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 3781 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
3752 | ( (daemon->connections == daemon->connection_limit) || | 3782 | ( (daemon->connections == daemon->connection_limit) || |
3753 | (daemon->at_limit) ) ) | 3783 | (daemon->at_limit) ) ) |
3754 | { | 3784 | { |
3755 | FD_CLR (ls, | 3785 | FD_CLR (ls, |
3756 | &rs); | 3786 | &rs); |
3757 | } | 3787 | } |
3758 | tv = NULL; | 3788 | tv = NULL; |
3759 | if (MHD_YES == err_state) | 3789 | if (MHD_YES == err_state) |
3760 | may_block = MHD_NO; | 3790 | may_block = MHD_NO; |
3761 | if (MHD_NO == may_block) | 3791 | if (MHD_NO == may_block) |
3762 | { | 3792 | { |
3763 | timeout.tv_usec = 0; | 3793 | timeout.tv_usec = 0; |
3764 | timeout.tv_sec = 0; | 3794 | timeout.tv_sec = 0; |
3765 | tv = &timeout; | 3795 | tv = &timeout; |
3766 | } | 3796 | } |
3767 | else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 3797 | else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
3768 | (MHD_YES == MHD_get_timeout (daemon, <imeout)) ) | 3798 | (MHD_YES == MHD_get_timeout (daemon, <imeout)) ) |
3769 | { | 3799 | { |
3770 | /* ltimeout is in ms */ | 3800 | /* ltimeout is in ms */ |
3771 | timeout.tv_usec = (ltimeout % 1000) * 1000; | 3801 | timeout.tv_usec = (ltimeout % 1000) * 1000; |
3772 | if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX) | 3802 | if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX) |
3773 | timeout.tv_sec = TIMEVAL_TV_SEC_MAX; | 3803 | timeout.tv_sec = TIMEVAL_TV_SEC_MAX; |
3774 | else | 3804 | else |
3775 | timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE)(ltimeout / 1000); | 3805 | timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000); |
3776 | tv = &timeout; | 3806 | tv = &timeout; |
3777 | } | 3807 | } |
3778 | num_ready = MHD_SYS_select_ (maxsock + 1, | 3808 | num_ready = MHD_SYS_select_ (maxsock + 1, |
3779 | &rs, | 3809 | &rs, |
3780 | &ws, | 3810 | &ws, |
@@ -3783,17 +3813,17 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3783 | if (daemon->shutdown) | 3813 | if (daemon->shutdown) |
3784 | return MHD_NO; | 3814 | return MHD_NO; |
3785 | if (num_ready < 0) | 3815 | if (num_ready < 0) |
3786 | { | 3816 | { |
3787 | const int err = MHD_socket_get_error_ (); | 3817 | const int err = MHD_socket_get_error_ (); |
3788 | if (MHD_SCKT_ERR_IS_EINTR_(err)) | 3818 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
3789 | return (MHD_NO == err_state) ? MHD_YES : MHD_NO; | 3819 | return (MHD_NO == err_state) ? MHD_YES : MHD_NO; |
3790 | #ifdef HAVE_MESSAGES | 3820 | #ifdef HAVE_MESSAGES |
3791 | MHD_DLOG (daemon, | 3821 | MHD_DLOG (daemon, |
3792 | _("select failed: %s\n"), | 3822 | _ ("select failed: %s\n"), |
3793 | MHD_socket_strerr_ (err)); | 3823 | MHD_socket_strerr_ (err)); |
3794 | #endif | 3824 | #endif |
3795 | return MHD_NO; | 3825 | return MHD_NO; |
3796 | } | 3826 | } |
3797 | if (MHD_YES == internal_run_from_select (daemon, | 3827 | if (MHD_YES == internal_run_from_select (daemon, |
3798 | &rs, | 3828 | &rs, |
3799 | &ws, | 3829 | &ws, |
@@ -3814,7 +3844,7 @@ MHD_select (struct MHD_Daemon *daemon, | |||
3814 | */ | 3844 | */ |
3815 | static int | 3845 | static int |
3816 | MHD_poll_all (struct MHD_Daemon *daemon, | 3846 | MHD_poll_all (struct MHD_Daemon *daemon, |
3817 | int may_block) | 3847 | int may_block) |
3818 | { | 3848 | { |
3819 | unsigned int num_connections; | 3849 | unsigned int num_connections; |
3820 | struct MHD_Connection *pos; | 3850 | struct MHD_Connection *pos; |
@@ -3846,44 +3876,44 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
3846 | struct pollfd *p; | 3876 | struct pollfd *p; |
3847 | MHD_socket ls; | 3877 | MHD_socket ls; |
3848 | 3878 | ||
3849 | p = MHD_calloc_ ((2 + (size_t)num_connections), | 3879 | p = MHD_calloc_ ((2 + (size_t) num_connections), |
3850 | sizeof (struct pollfd)); | 3880 | sizeof (struct pollfd)); |
3851 | if (NULL == p) | 3881 | if (NULL == p) |
3852 | { | 3882 | { |
3853 | #ifdef HAVE_MESSAGES | 3883 | #ifdef HAVE_MESSAGES |
3854 | MHD_DLOG (daemon, | 3884 | MHD_DLOG (daemon, |
3855 | _("Error allocating memory: %s\n"), | 3885 | _ ("Error allocating memory: %s\n"), |
3856 | MHD_strerror_(errno)); | 3886 | MHD_strerror_ (errno)); |
3857 | #endif | 3887 | #endif |
3858 | return MHD_NO; | 3888 | return MHD_NO; |
3859 | } | 3889 | } |
3860 | poll_server = 0; | 3890 | poll_server = 0; |
3861 | poll_listen = -1; | 3891 | poll_listen = -1; |
3862 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && | 3892 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && |
3863 | (! daemon->was_quiesced) && | 3893 | (! daemon->was_quiesced) && |
3864 | (daemon->connections < daemon->connection_limit) && | 3894 | (daemon->connections < daemon->connection_limit) && |
3865 | (! daemon->at_limit) ) | 3895 | (! daemon->at_limit) ) |
3866 | { | 3896 | { |
3867 | /* only listen if we are not at the connection limit */ | 3897 | /* only listen if we are not at the connection limit */ |
3868 | p[poll_server].fd = ls; | 3898 | p[poll_server].fd = ls; |
3869 | p[poll_server].events = POLLIN; | 3899 | p[poll_server].events = POLLIN; |
3870 | p[poll_server].revents = 0; | 3900 | p[poll_server].revents = 0; |
3871 | poll_listen = (int) poll_server; | 3901 | poll_listen = (int) poll_server; |
3872 | poll_server++; | 3902 | poll_server++; |
3873 | } | 3903 | } |
3874 | poll_itc_idx = -1; | 3904 | poll_itc_idx = -1; |
3875 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 3905 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
3876 | { | 3906 | { |
3877 | p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc); | 3907 | p[poll_server].fd = MHD_itc_r_fd_ (daemon->itc); |
3878 | p[poll_server].events = POLLIN; | 3908 | p[poll_server].events = POLLIN; |
3879 | p[poll_server].revents = 0; | 3909 | p[poll_server].revents = 0; |
3880 | poll_itc_idx = (int) poll_server; | 3910 | poll_itc_idx = (int) poll_server; |
3881 | poll_server++; | 3911 | poll_server++; |
3882 | } | 3912 | } |
3883 | if (may_block == MHD_NO) | 3913 | if (may_block == MHD_NO) |
3884 | timeout = 0; | 3914 | timeout = 0; |
3885 | else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || | 3915 | else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) || |
3886 | (MHD_YES != MHD_get_timeout (daemon, | 3916 | (MHD_YES != MHD_get_timeout (daemon, |
3887 | <imeout)) ) | 3917 | <imeout)) ) |
3888 | timeout = -1; | 3918 | timeout = -1; |
3889 | else | 3919 | else |
@@ -3891,55 +3921,55 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
3891 | 3921 | ||
3892 | i = 0; | 3922 | i = 0; |
3893 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) | 3923 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) |
3924 | { | ||
3925 | p[poll_server + i].fd = pos->socket_fd; | ||
3926 | switch (pos->event_loop_info) | ||
3894 | { | 3927 | { |
3895 | p[poll_server+i].fd = pos->socket_fd; | 3928 | case MHD_EVENT_LOOP_INFO_READ: |
3896 | switch (pos->event_loop_info) | 3929 | p[poll_server + i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; |
3897 | { | 3930 | break; |
3898 | case MHD_EVENT_LOOP_INFO_READ: | 3931 | case MHD_EVENT_LOOP_INFO_WRITE: |
3899 | p[poll_server+i].events |= POLLIN | MHD_POLL_EVENTS_ERR_DISC; | 3932 | p[poll_server + i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; |
3900 | break; | 3933 | break; |
3901 | case MHD_EVENT_LOOP_INFO_WRITE: | 3934 | case MHD_EVENT_LOOP_INFO_BLOCK: |
3902 | p[poll_server+i].events |= POLLOUT | MHD_POLL_EVENTS_ERR_DISC; | 3935 | p[poll_server + i].events |= MHD_POLL_EVENTS_ERR_DISC; |
3903 | break; | 3936 | break; |
3904 | case MHD_EVENT_LOOP_INFO_BLOCK: | 3937 | case MHD_EVENT_LOOP_INFO_CLEANUP: |
3905 | p[poll_server+i].events |= MHD_POLL_EVENTS_ERR_DISC; | 3938 | timeout = 0; /* clean up "pos" immediately */ |
3906 | break; | 3939 | break; |
3907 | case MHD_EVENT_LOOP_INFO_CLEANUP: | ||
3908 | timeout = 0; /* clean up "pos" immediately */ | ||
3909 | break; | ||
3910 | } | ||
3911 | i++; | ||
3912 | } | 3940 | } |
3941 | i++; | ||
3942 | } | ||
3913 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 3943 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
3914 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) | 3944 | for (urh = daemon->urh_tail; NULL != urh; urh = urh->prev) |
3915 | { | 3945 | { |
3916 | urh_to_pollfd(urh, &(p[poll_server+i])); | 3946 | urh_to_pollfd (urh, &(p[poll_server + i])); |
3917 | i += 2; | 3947 | i += 2; |
3918 | } | 3948 | } |
3919 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 3949 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
3920 | if (0 == poll_server + num_connections) | 3950 | if (0 == poll_server + num_connections) |
3951 | { | ||
3952 | free (p); | ||
3953 | return MHD_YES; | ||
3954 | } | ||
3955 | if (MHD_sys_poll_ (p, | ||
3956 | poll_server + num_connections, | ||
3957 | timeout) < 0) | ||
3958 | { | ||
3959 | const int err = MHD_socket_get_error_ (); | ||
3960 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
3921 | { | 3961 | { |
3922 | free(p); | 3962 | free (p); |
3923 | return MHD_YES; | ||
3924 | } | ||
3925 | if (MHD_sys_poll_(p, | ||
3926 | poll_server + num_connections, | ||
3927 | timeout) < 0) | ||
3928 | { | ||
3929 | const int err = MHD_socket_get_error_ (); | ||
3930 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
3931 | { | ||
3932 | free(p); | ||
3933 | return MHD_YES; | 3963 | return MHD_YES; |
3934 | } | 3964 | } |
3935 | #ifdef HAVE_MESSAGES | 3965 | #ifdef HAVE_MESSAGES |
3936 | MHD_DLOG (daemon, | 3966 | MHD_DLOG (daemon, |
3937 | _("poll failed: %s\n"), | 3967 | _ ("poll failed: %s\n"), |
3938 | MHD_socket_strerr_ (err)); | 3968 | MHD_socket_strerr_ (err)); |
3939 | #endif | 3969 | #endif |
3940 | free(p); | 3970 | free (p); |
3941 | return MHD_NO; | 3971 | return MHD_NO; |
3942 | } | 3972 | } |
3943 | 3973 | ||
3944 | /* Reset. New value will be set when connections are processed. */ | 3974 | /* Reset. New value will be set when connections are processed. */ |
3945 | daemon->data_already_pending = false; | 3975 | daemon->data_already_pending = false; |
@@ -3953,67 +3983,68 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
3953 | 3983 | ||
3954 | /* handle shutdown */ | 3984 | /* handle shutdown */ |
3955 | if (daemon->shutdown) | 3985 | if (daemon->shutdown) |
3956 | { | 3986 | { |
3957 | free(p); | 3987 | free (p); |
3958 | return MHD_NO; | 3988 | return MHD_NO; |
3959 | } | 3989 | } |
3960 | i = 0; | 3990 | i = 0; |
3961 | prev = daemon->connections_tail; | 3991 | prev = daemon->connections_tail; |
3962 | while (NULL != (pos = prev)) | 3992 | while (NULL != (pos = prev)) |
3963 | { | 3993 | { |
3964 | prev = pos->prev; | 3994 | prev = pos->prev; |
3965 | /* first, sanity checks */ | 3995 | /* first, sanity checks */ |
3966 | if (i >= num_connections) | 3996 | if (i >= num_connections) |
3967 | break; /* connection list changed somehow, retry later ... */ | 3997 | break; /* connection list changed somehow, retry later ... */ |
3968 | if (p[poll_server+i].fd != pos->socket_fd) | 3998 | if (p[poll_server + i].fd != pos->socket_fd) |
3969 | continue; /* fd mismatch, something else happened, retry later ... */ | 3999 | continue; /* fd mismatch, something else happened, retry later ... */ |
3970 | call_handlers (pos, | 4000 | call_handlers (pos, |
3971 | 0 != (p[poll_server+i].revents & POLLIN), | 4001 | 0 != (p[poll_server + i].revents & POLLIN), |
3972 | 0 != (p[poll_server+i].revents & POLLOUT), | 4002 | 0 != (p[poll_server + i].revents & POLLOUT), |
3973 | 0 != (p[poll_server+i].revents & MHD_POLL_REVENTS_ERR_DISC)); | 4003 | 0 != (p[poll_server + i].revents |
3974 | i++; | 4004 | & MHD_POLL_REVENTS_ERR_DISC)); |
3975 | } | 4005 | i++; |
4006 | } | ||
3976 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 4007 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
3977 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 4008 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
4009 | { | ||
4010 | if (i >= num_connections) | ||
4011 | break; /* connection list changed somehow, retry later ... */ | ||
4012 | |||
4013 | /* Get next connection here as connection can be removed | ||
4014 | * from 'daemon->urh_head' list. */ | ||
4015 | urhn = urh->prev; | ||
4016 | /* Check for fd mismatch. FIXME: required for safety? */ | ||
4017 | if ((p[poll_server + i].fd != urh->connection->socket_fd) || | ||
4018 | (p[poll_server + i + 1].fd != urh->mhd.socket)) | ||
4019 | break; | ||
4020 | urh_from_pollfd (urh, | ||
4021 | &p[poll_server + i]); | ||
4022 | i += 2; | ||
4023 | process_urh (urh); | ||
4024 | /* Finished forwarding? */ | ||
4025 | if ( (0 == urh->in_buffer_size) && | ||
4026 | (0 == urh->out_buffer_size) && | ||
4027 | (0 == urh->in_buffer_used) && | ||
4028 | (0 == urh->out_buffer_used) ) | ||
3978 | { | 4029 | { |
3979 | if (i >= num_connections) | 4030 | /* MHD_connection_finish_forward_() will remove connection from |
3980 | break; /* connection list changed somehow, retry later ... */ | 4031 | * 'daemon->urh_head' list. */ |
3981 | 4032 | MHD_connection_finish_forward_ (urh->connection); | |
3982 | /* Get next connection here as connection can be removed | 4033 | urh->clean_ready = true; |
3983 | * from 'daemon->urh_head' list. */ | 4034 | /* If 'urh->was_closed' already was set to true, connection will be |
3984 | urhn = urh->prev; | 4035 | * moved immediately to cleanup list. Otherwise connection |
3985 | /* Check for fd mismatch. FIXME: required for safety? */ | 4036 | * will stay in suspended list until 'urh' will be marked |
3986 | if ((p[poll_server+i].fd != urh->connection->socket_fd) || | 4037 | * with 'was_closed' by application. */ |
3987 | (p[poll_server+i+1].fd != urh->mhd.socket)) | 4038 | MHD_resume_connection (urh->connection); |
3988 | break; | ||
3989 | urh_from_pollfd (urh, | ||
3990 | &p[poll_server+i]); | ||
3991 | i += 2; | ||
3992 | process_urh (urh); | ||
3993 | /* Finished forwarding? */ | ||
3994 | if ( (0 == urh->in_buffer_size) && | ||
3995 | (0 == urh->out_buffer_size) && | ||
3996 | (0 == urh->in_buffer_used) && | ||
3997 | (0 == urh->out_buffer_used) ) | ||
3998 | { | ||
3999 | /* MHD_connection_finish_forward_() will remove connection from | ||
4000 | * 'daemon->urh_head' list. */ | ||
4001 | MHD_connection_finish_forward_ (urh->connection); | ||
4002 | urh->clean_ready = true; | ||
4003 | /* If 'urh->was_closed' already was set to true, connection will be | ||
4004 | * moved immediately to cleanup list. Otherwise connection | ||
4005 | * will stay in suspended list until 'urh' will be marked | ||
4006 | * with 'was_closed' by application. */ | ||
4007 | MHD_resume_connection(urh->connection); | ||
4008 | } | ||
4009 | } | 4039 | } |
4040 | } | ||
4010 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 4041 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
4011 | /* handle 'listen' FD */ | 4042 | /* handle 'listen' FD */ |
4012 | if ( (-1 != poll_listen) && | 4043 | if ( (-1 != poll_listen) && |
4013 | (0 != (p[poll_listen].revents & POLLIN)) ) | 4044 | (0 != (p[poll_listen].revents & POLLIN)) ) |
4014 | (void) MHD_accept_connection (daemon); | 4045 | (void) MHD_accept_connection (daemon); |
4015 | 4046 | ||
4016 | free(p); | 4047 | free (p); |
4017 | } | 4048 | } |
4018 | return MHD_YES; | 4049 | return MHD_YES; |
4019 | } | 4050 | } |
@@ -4028,7 +4059,7 @@ MHD_poll_all (struct MHD_Daemon *daemon, | |||
4028 | */ | 4059 | */ |
4029 | static int | 4060 | static int |
4030 | MHD_poll_listen_socket (struct MHD_Daemon *daemon, | 4061 | MHD_poll_listen_socket (struct MHD_Daemon *daemon, |
4031 | int may_block) | 4062 | int may_block) |
4032 | { | 4063 | { |
4033 | struct pollfd p[2]; | 4064 | struct pollfd p[2]; |
4034 | int timeout; | 4065 | int timeout; |
@@ -4046,21 +4077,21 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon, | |||
4046 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && | 4077 | if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) && |
4047 | (! daemon->was_quiesced) ) | 4078 | (! daemon->was_quiesced) ) |
4048 | 4079 | ||
4049 | { | 4080 | { |
4050 | p[poll_count].fd = ls; | 4081 | p[poll_count].fd = ls; |
4051 | p[poll_count].events = POLLIN; | 4082 | p[poll_count].events = POLLIN; |
4052 | p[poll_count].revents = 0; | 4083 | p[poll_count].revents = 0; |
4053 | poll_listen = poll_count; | 4084 | poll_listen = poll_count; |
4054 | poll_count++; | 4085 | poll_count++; |
4055 | } | 4086 | } |
4056 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 4087 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
4057 | { | 4088 | { |
4058 | p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc); | 4089 | p[poll_count].fd = MHD_itc_r_fd_ (daemon->itc); |
4059 | p[poll_count].events = POLLIN; | 4090 | p[poll_count].events = POLLIN; |
4060 | p[poll_count].revents = 0; | 4091 | p[poll_count].revents = 0; |
4061 | poll_itc_idx = poll_count; | 4092 | poll_itc_idx = poll_count; |
4062 | poll_count++; | 4093 | poll_count++; |
4063 | } | 4094 | } |
4064 | 4095 | ||
4065 | if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) | 4096 | if (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) |
4066 | (void) resume_suspended_connections (daemon); | 4097 | (void) resume_suspended_connections (daemon); |
@@ -4071,21 +4102,21 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon, | |||
4071 | timeout = -1; | 4102 | timeout = -1; |
4072 | if (0 == poll_count) | 4103 | if (0 == poll_count) |
4073 | return MHD_YES; | 4104 | return MHD_YES; |
4074 | if (MHD_sys_poll_(p, | 4105 | if (MHD_sys_poll_ (p, |
4075 | poll_count, | 4106 | poll_count, |
4076 | timeout) < 0) | 4107 | timeout) < 0) |
4077 | { | 4108 | { |
4078 | const int err = MHD_socket_get_error_ (); | 4109 | const int err = MHD_socket_get_error_ (); |
4079 | 4110 | ||
4080 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | 4111 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
4081 | return MHD_YES; | 4112 | return MHD_YES; |
4082 | #ifdef HAVE_MESSAGES | 4113 | #ifdef HAVE_MESSAGES |
4083 | MHD_DLOG (daemon, | 4114 | MHD_DLOG (daemon, |
4084 | _("poll failed: %s\n"), | 4115 | _ ("poll failed: %s\n"), |
4085 | MHD_socket_strerr_ (err)); | 4116 | MHD_socket_strerr_ (err)); |
4086 | #endif | 4117 | #endif |
4087 | return MHD_NO; | 4118 | return MHD_NO; |
4088 | } | 4119 | } |
4089 | if ( (-1 != poll_itc_idx) && | 4120 | if ( (-1 != poll_itc_idx) && |
4090 | (0 != (p[poll_itc_idx].revents & POLLIN)) ) | 4121 | (0 != (p[poll_itc_idx].revents & POLLIN)) ) |
4091 | MHD_itc_clear_ (daemon->itc); | 4122 | MHD_itc_clear_ (daemon->itc); |
@@ -4110,7 +4141,7 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon, | |||
4110 | */ | 4141 | */ |
4111 | static int | 4142 | static int |
4112 | MHD_poll (struct MHD_Daemon *daemon, | 4143 | MHD_poll (struct MHD_Daemon *daemon, |
4113 | int may_block) | 4144 | int may_block) |
4114 | { | 4145 | { |
4115 | #ifdef HAVE_POLL | 4146 | #ifdef HAVE_POLL |
4116 | if (daemon->shutdown) | 4147 | if (daemon->shutdown) |
@@ -4151,9 +4182,9 @@ MHD_poll (struct MHD_Daemon *daemon, | |||
4151 | * 'false' otherwise | 4182 | * 'false' otherwise |
4152 | */ | 4183 | */ |
4153 | static bool | 4184 | static bool |
4154 | is_urh_ready(struct MHD_UpgradeResponseHandle * const urh) | 4185 | is_urh_ready (struct MHD_UpgradeResponseHandle *const urh) |
4155 | { | 4186 | { |
4156 | const struct MHD_Connection * const connection = urh->connection; | 4187 | const struct MHD_Connection *const connection = urh->connection; |
4157 | 4188 | ||
4158 | if ( (0 == urh->in_buffer_size) && | 4189 | if ( (0 == urh->in_buffer_size) && |
4159 | (0 == urh->out_buffer_size) && | 4190 | (0 == urh->out_buffer_size) && |
@@ -4173,7 +4204,7 @@ is_urh_ready(struct MHD_UpgradeResponseHandle * const urh) | |||
4173 | (urh->out_buffer_used > 0) ) | 4204 | (urh->out_buffer_used > 0) ) |
4174 | return true; | 4205 | return true; |
4175 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && | 4206 | if ( (0 != (MHD_EPOLL_STATE_WRITE_READY & urh->mhd.celi)) && |
4176 | (urh->in_buffer_used > 0) ) | 4207 | (urh->in_buffer_used > 0) ) |
4177 | return true; | 4208 | return true; |
4178 | return false; | 4209 | return false; |
4179 | } | 4210 | } |
@@ -4192,98 +4223,98 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
4192 | { | 4223 | { |
4193 | struct epoll_event events[MAX_EVENTS]; | 4224 | struct epoll_event events[MAX_EVENTS]; |
4194 | int num_events; | 4225 | int num_events; |
4195 | struct MHD_UpgradeResponseHandle * pos; | 4226 | struct MHD_UpgradeResponseHandle *pos; |
4196 | struct MHD_UpgradeResponseHandle * prev; | 4227 | struct MHD_UpgradeResponseHandle *prev; |
4197 | 4228 | ||
4198 | num_events = MAX_EVENTS; | 4229 | num_events = MAX_EVENTS; |
4199 | while (0 != num_events) | 4230 | while (0 != num_events) |
4231 | { | ||
4232 | unsigned int i; | ||
4233 | /* update event masks */ | ||
4234 | num_events = epoll_wait (daemon->epoll_upgrade_fd, | ||
4235 | events, | ||
4236 | MAX_EVENTS, | ||
4237 | 0); | ||
4238 | if (-1 == num_events) | ||
4200 | { | 4239 | { |
4201 | unsigned int i; | 4240 | const int err = MHD_socket_get_error_ (); |
4202 | /* update event masks */ | ||
4203 | num_events = epoll_wait (daemon->epoll_upgrade_fd, | ||
4204 | events, | ||
4205 | MAX_EVENTS, | ||
4206 | 0); | ||
4207 | if (-1 == num_events) | ||
4208 | { | ||
4209 | const int err = MHD_socket_get_error_ (); | ||
4210 | 4241 | ||
4211 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | 4242 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
4212 | return MHD_YES; | 4243 | return MHD_YES; |
4213 | #ifdef HAVE_MESSAGES | 4244 | #ifdef HAVE_MESSAGES |
4214 | MHD_DLOG (daemon, | 4245 | MHD_DLOG (daemon, |
4215 | _("Call to epoll_wait failed: %s\n"), | 4246 | _ ("Call to epoll_wait failed: %s\n"), |
4216 | MHD_socket_strerr_ (err)); | 4247 | MHD_socket_strerr_ (err)); |
4217 | #endif | 4248 | #endif |
4218 | return MHD_NO; | 4249 | return MHD_NO; |
4219 | } | 4250 | } |
4220 | for (i = 0; i < (unsigned int) num_events; i++) | 4251 | for (i = 0; i < (unsigned int) num_events; i++) |
4221 | { | 4252 | { |
4222 | struct UpgradeEpollHandle * const ueh = events[i].data.ptr; | 4253 | struct UpgradeEpollHandle *const ueh = events[i].data.ptr; |
4223 | struct MHD_UpgradeResponseHandle * const urh = ueh->urh; | 4254 | struct MHD_UpgradeResponseHandle *const urh = ueh->urh; |
4224 | bool new_err_state = false; | 4255 | bool new_err_state = false; |
4225 | 4256 | ||
4226 | if (urh->clean_ready) | 4257 | if (urh->clean_ready) |
4227 | continue; | 4258 | continue; |
4259 | |||
4260 | /* Update ueh state based on what is ready according to epoll() */ | ||
4261 | if (0 != (events[i].events & EPOLLIN)) | ||
4262 | ueh->celi |= MHD_EPOLL_STATE_READ_READY; | ||
4263 | if (0 != (events[i].events & EPOLLOUT)) | ||
4264 | ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; | ||
4265 | if (0 != (events[i].events & EPOLLHUP)) | ||
4266 | ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; | ||
4228 | 4267 | ||
4229 | /* Update ueh state based on what is ready according to epoll() */ | 4268 | if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && |
4230 | if (0 != (events[i].events & EPOLLIN)) | 4269 | (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) |
4231 | ueh->celi |= MHD_EPOLL_STATE_READ_READY; | 4270 | { |
4232 | if (0 != (events[i].events & EPOLLOUT)) | 4271 | /* Process new error state only one time |
4233 | ueh->celi |= MHD_EPOLL_STATE_WRITE_READY; | 4272 | * and avoid continuously marking this connection |
4234 | if (0 != (events[i].events & EPOLLHUP)) | 4273 | * as 'ready'. */ |
4235 | ueh->celi |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY; | 4274 | ueh->celi |= MHD_EPOLL_STATE_ERROR; |
4236 | 4275 | new_err_state = true; | |
4237 | if ( (0 == (ueh->celi & MHD_EPOLL_STATE_ERROR)) && | 4276 | } |
4238 | (0 != (events[i].events & (EPOLLERR | EPOLLPRI))) ) | 4277 | |
4239 | { | 4278 | if (! urh->in_eready_list) |
4240 | /* Process new error state only one time | 4279 | { |
4241 | * and avoid continuously marking this connection | 4280 | if (new_err_state || |
4242 | * as 'ready'. */ | 4281 | is_urh_ready (urh)) |
4243 | ueh->celi |= MHD_EPOLL_STATE_ERROR; | 4282 | { |
4244 | new_err_state = true; | 4283 | EDLL_insert (daemon->eready_urh_head, |
4245 | } | 4284 | daemon->eready_urh_tail, |
4246 | 4285 | urh); | |
4247 | if (! urh->in_eready_list) | 4286 | urh->in_eready_list = true; |
4248 | { | ||
4249 | if (new_err_state || | ||
4250 | is_urh_ready(urh)) | ||
4251 | { | ||
4252 | EDLL_insert (daemon->eready_urh_head, | ||
4253 | daemon->eready_urh_tail, | ||
4254 | urh); | ||
4255 | urh->in_eready_list = true; | ||
4256 | } | ||
4257 | } | ||
4258 | } | 4287 | } |
4288 | } | ||
4259 | } | 4289 | } |
4290 | } | ||
4260 | prev = daemon->eready_urh_tail; | 4291 | prev = daemon->eready_urh_tail; |
4261 | while (NULL != (pos = prev)) | 4292 | while (NULL != (pos = prev)) |
4262 | { | 4293 | { |
4263 | prev = pos->prevE; | 4294 | prev = pos->prevE; |
4264 | process_urh (pos); | 4295 | process_urh (pos); |
4265 | if (! is_urh_ready(pos)) | 4296 | if (! is_urh_ready (pos)) |
4266 | { | 4297 | { |
4267 | EDLL_remove (daemon->eready_urh_head, | 4298 | EDLL_remove (daemon->eready_urh_head, |
4268 | daemon->eready_urh_tail, | 4299 | daemon->eready_urh_tail, |
4269 | pos); | 4300 | pos); |
4270 | pos->in_eready_list = false; | 4301 | pos->in_eready_list = false; |
4271 | } | 4302 | } |
4272 | /* Finished forwarding? */ | 4303 | /* Finished forwarding? */ |
4273 | if ( (0 == pos->in_buffer_size) && | 4304 | if ( (0 == pos->in_buffer_size) && |
4274 | (0 == pos->out_buffer_size) && | 4305 | (0 == pos->out_buffer_size) && |
4275 | (0 == pos->in_buffer_used) && | 4306 | (0 == pos->in_buffer_used) && |
4276 | (0 == pos->out_buffer_used) ) | 4307 | (0 == pos->out_buffer_used) ) |
4277 | { | 4308 | { |
4278 | MHD_connection_finish_forward_ (pos->connection); | 4309 | MHD_connection_finish_forward_ (pos->connection); |
4279 | pos->clean_ready = true; | 4310 | pos->clean_ready = true; |
4280 | /* If 'pos->was_closed' already was set to true, connection | 4311 | /* If 'pos->was_closed' already was set to true, connection |
4281 | * will be moved immediately to cleanup list. Otherwise | 4312 | * will be moved immediately to cleanup list. Otherwise |
4282 | * connection will stay in suspended list until 'pos' will | 4313 | * connection will stay in suspended list until 'pos' will |
4283 | * be marked with 'was_closed' by application. */ | 4314 | * be marked with 'was_closed' by application. */ |
4284 | MHD_resume_connection (pos->connection); | 4315 | MHD_resume_connection (pos->connection); |
4285 | } | ||
4286 | } | 4316 | } |
4317 | } | ||
4287 | 4318 | ||
4288 | return MHD_YES; | 4319 | return MHD_YES; |
4289 | } | 4320 | } |
@@ -4293,7 +4324,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon) | |||
4293 | /** | 4324 | /** |
4294 | * Pointer-marker to distinguish ITC slot in epoll sets. | 4325 | * Pointer-marker to distinguish ITC slot in epoll sets. |
4295 | */ | 4326 | */ |
4296 | static const char * const epoll_itc_marker = "itc_marker"; | 4327 | static const char *const epoll_itc_marker = "itc_marker"; |
4297 | 4328 | ||
4298 | 4329 | ||
4299 | /** | 4330 | /** |
@@ -4309,7 +4340,7 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
4309 | int may_block) | 4340 | int may_block) |
4310 | { | 4341 | { |
4311 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 4342 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
4312 | static const char * const upgrade_marker = "upgrade_ptr"; | 4343 | static const char *const upgrade_marker = "upgrade_ptr"; |
4313 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 4344 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
4314 | struct MHD_Connection *pos; | 4345 | struct MHD_Connection *pos; |
4315 | struct MHD_Connection *prev; | 4346 | struct MHD_Connection *prev; |
@@ -4333,89 +4364,89 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
4333 | (daemon->connections < daemon->connection_limit) && | 4364 | (daemon->connections < daemon->connection_limit) && |
4334 | (! daemon->listen_socket_in_epoll) && | 4365 | (! daemon->listen_socket_in_epoll) && |
4335 | (! daemon->at_limit) ) | 4366 | (! daemon->at_limit) ) |
4367 | { | ||
4368 | event.events = EPOLLIN; | ||
4369 | event.data.ptr = daemon; | ||
4370 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
4371 | EPOLL_CTL_ADD, | ||
4372 | ls, | ||
4373 | &event)) | ||
4336 | { | 4374 | { |
4337 | event.events = EPOLLIN; | ||
4338 | event.data.ptr = daemon; | ||
4339 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
4340 | EPOLL_CTL_ADD, | ||
4341 | ls, | ||
4342 | &event)) | ||
4343 | { | ||
4344 | #ifdef HAVE_MESSAGES | 4375 | #ifdef HAVE_MESSAGES |
4345 | MHD_DLOG (daemon, | 4376 | MHD_DLOG (daemon, |
4346 | _("Call to epoll_ctl failed: %s\n"), | 4377 | _ ("Call to epoll_ctl failed: %s\n"), |
4347 | MHD_socket_last_strerr_ ()); | 4378 | MHD_socket_last_strerr_ ()); |
4348 | #endif | 4379 | #endif |
4349 | return MHD_NO; | 4380 | return MHD_NO; |
4350 | } | ||
4351 | daemon->listen_socket_in_epoll = true; | ||
4352 | } | 4381 | } |
4382 | daemon->listen_socket_in_epoll = true; | ||
4383 | } | ||
4353 | if ( (daemon->was_quiesced) && | 4384 | if ( (daemon->was_quiesced) && |
4354 | (daemon->listen_socket_in_epoll) ) | 4385 | (daemon->listen_socket_in_epoll) ) |
4355 | { | 4386 | { |
4356 | if ( (0 != epoll_ctl (daemon->epoll_fd, | 4387 | if ( (0 != epoll_ctl (daemon->epoll_fd, |
4357 | EPOLL_CTL_DEL, | 4388 | EPOLL_CTL_DEL, |
4358 | ls, | 4389 | ls, |
4359 | NULL)) && | 4390 | NULL)) && |
4360 | (ENOENT != errno) ) /* ENOENT can happen due to race with | 4391 | (ENOENT != errno) ) /* ENOENT can happen due to race with |
4361 | #MHD_quiesce_daemon() */ | 4392 | #MHD_quiesce_daemon() */ |
4362 | MHD_PANIC ("Failed to remove listen FD from epoll set\n"); | 4393 | MHD_PANIC ("Failed to remove listen FD from epoll set\n"); |
4363 | daemon->listen_socket_in_epoll = false; | 4394 | daemon->listen_socket_in_epoll = false; |
4364 | } | 4395 | } |
4365 | 4396 | ||
4366 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 4397 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
4367 | if ( ( (! daemon->upgrade_fd_in_epoll) && | 4398 | if ( ( (! daemon->upgrade_fd_in_epoll) && |
4368 | (-1 != daemon->epoll_upgrade_fd) ) ) | 4399 | (-1 != daemon->epoll_upgrade_fd) ) ) |
4400 | { | ||
4401 | event.events = EPOLLIN | EPOLLOUT; | ||
4402 | event.data.ptr = (void *) upgrade_marker; | ||
4403 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
4404 | EPOLL_CTL_ADD, | ||
4405 | daemon->epoll_upgrade_fd, | ||
4406 | &event)) | ||
4369 | { | 4407 | { |
4370 | event.events = EPOLLIN | EPOLLOUT; | ||
4371 | event.data.ptr = (void *) upgrade_marker; | ||
4372 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
4373 | EPOLL_CTL_ADD, | ||
4374 | daemon->epoll_upgrade_fd, | ||
4375 | &event)) | ||
4376 | { | ||
4377 | #ifdef HAVE_MESSAGES | 4408 | #ifdef HAVE_MESSAGES |
4378 | MHD_DLOG (daemon, | 4409 | MHD_DLOG (daemon, |
4379 | _("Call to epoll_ctl failed: %s\n"), | 4410 | _ ("Call to epoll_ctl failed: %s\n"), |
4380 | MHD_socket_last_strerr_ ()); | 4411 | MHD_socket_last_strerr_ ()); |
4381 | #endif | 4412 | #endif |
4382 | return MHD_NO; | 4413 | return MHD_NO; |
4383 | } | ||
4384 | daemon->upgrade_fd_in_epoll = true; | ||
4385 | } | 4414 | } |
4415 | daemon->upgrade_fd_in_epoll = true; | ||
4416 | } | ||
4386 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 4417 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
4387 | if ( (daemon->listen_socket_in_epoll) && | 4418 | if ( (daemon->listen_socket_in_epoll) && |
4388 | ( (daemon->connections == daemon->connection_limit) || | 4419 | ( (daemon->connections == daemon->connection_limit) || |
4389 | (daemon->at_limit) || | 4420 | (daemon->at_limit) || |
4390 | (daemon->was_quiesced) ) ) | 4421 | (daemon->was_quiesced) ) ) |
4391 | { | 4422 | { |
4392 | /* we're at the connection limit, disable listen socket | 4423 | /* we're at the connection limit, disable listen socket |
4393 | for event loop for now */ | 4424 | for event loop for now */ |
4394 | if (0 != epoll_ctl (daemon->epoll_fd, | 4425 | if (0 != epoll_ctl (daemon->epoll_fd, |
4395 | EPOLL_CTL_DEL, | 4426 | EPOLL_CTL_DEL, |
4396 | ls, | 4427 | ls, |
4397 | NULL)) | 4428 | NULL)) |
4398 | MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); | 4429 | MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n")); |
4399 | daemon->listen_socket_in_epoll = false; | 4430 | daemon->listen_socket_in_epoll = false; |
4400 | } | 4431 | } |
4401 | 4432 | ||
4402 | if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && | 4433 | if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) && |
4403 | (MHD_YES == resume_suspended_connections (daemon)) ) | 4434 | (MHD_YES == resume_suspended_connections (daemon)) ) |
4404 | may_block = MHD_NO; | 4435 | may_block = MHD_NO; |
4405 | 4436 | ||
4406 | if (MHD_YES == may_block) | 4437 | if (MHD_YES == may_block) |
4438 | { | ||
4439 | if (MHD_YES == MHD_get_timeout (daemon, | ||
4440 | &timeout_ll)) | ||
4407 | { | 4441 | { |
4408 | if (MHD_YES == MHD_get_timeout (daemon, | 4442 | if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) |
4409 | &timeout_ll)) | 4443 | timeout_ms = INT_MAX; |
4410 | { | ||
4411 | if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX) | ||
4412 | timeout_ms = INT_MAX; | ||
4413 | else | ||
4414 | timeout_ms = (int) timeout_ll; | ||
4415 | } | ||
4416 | else | 4444 | else |
4417 | timeout_ms = -1; | 4445 | timeout_ms = (int) timeout_ll; |
4418 | } | 4446 | } |
4447 | else | ||
4448 | timeout_ms = -1; | ||
4449 | } | ||
4419 | else | 4450 | else |
4420 | timeout_ms = 0; | 4451 | timeout_ms = 0; |
4421 | 4452 | ||
@@ -4430,111 +4461,111 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
4430 | than unfair behavior... */ | 4461 | than unfair behavior... */ |
4431 | num_events = MAX_EVENTS; | 4462 | num_events = MAX_EVENTS; |
4432 | while (MAX_EVENTS == num_events) | 4463 | while (MAX_EVENTS == num_events) |
4464 | { | ||
4465 | /* update event masks */ | ||
4466 | num_events = epoll_wait (daemon->epoll_fd, | ||
4467 | events, | ||
4468 | MAX_EVENTS, | ||
4469 | timeout_ms); | ||
4470 | if (-1 == num_events) | ||
4433 | { | 4471 | { |
4434 | /* update event masks */ | 4472 | const int err = MHD_socket_get_error_ (); |
4435 | num_events = epoll_wait (daemon->epoll_fd, | 4473 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) |
4436 | events, | 4474 | return MHD_YES; |
4437 | MAX_EVENTS, | ||
4438 | timeout_ms); | ||
4439 | if (-1 == num_events) | ||
4440 | { | ||
4441 | const int err = MHD_socket_get_error_ (); | ||
4442 | if (MHD_SCKT_ERR_IS_EINTR_ (err)) | ||
4443 | return MHD_YES; | ||
4444 | #ifdef HAVE_MESSAGES | 4475 | #ifdef HAVE_MESSAGES |
4445 | MHD_DLOG (daemon, | 4476 | MHD_DLOG (daemon, |
4446 | _("Call to epoll_wait failed: %s\n"), | 4477 | _ ("Call to epoll_wait failed: %s\n"), |
4447 | MHD_socket_strerr_ (err)); | 4478 | MHD_socket_strerr_ (err)); |
4448 | #endif | 4479 | #endif |
4449 | return MHD_NO; | 4480 | return MHD_NO; |
4450 | } | 4481 | } |
4451 | for (i=0;i<(unsigned int) num_events;i++) | 4482 | for (i = 0; i<(unsigned int) num_events; i++) |
4452 | { | 4483 | { |
4453 | /* First, check for the values of `ptr` that would indicate | 4484 | /* First, check for the values of `ptr` that would indicate |
4454 | that this event is not about a normal connection. */ | 4485 | that this event is not about a normal connection. */ |
4455 | if (NULL == events[i].data.ptr) | 4486 | if (NULL == events[i].data.ptr) |
4456 | continue; /* shutdown signal! */ | 4487 | continue; /* shutdown signal! */ |
4457 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 4488 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
4458 | if (upgrade_marker == events[i].data.ptr) | 4489 | if (upgrade_marker == events[i].data.ptr) |
4459 | { | 4490 | { |
4460 | /* activity on an upgraded connection, we process | 4491 | /* activity on an upgraded connection, we process |
4461 | those in a separate epoll() */ | 4492 | those in a separate epoll() */ |
4462 | run_upgraded = true; | 4493 | run_upgraded = true; |
4463 | continue; | 4494 | continue; |
4464 | } | 4495 | } |
4465 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 4496 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
4466 | if (epoll_itc_marker == events[i].data.ptr) | 4497 | if (epoll_itc_marker == events[i].data.ptr) |
4467 | { | 4498 | { |
4468 | /* It's OK to clear ITC here as all external | 4499 | /* It's OK to clear ITC here as all external |
4469 | conditions will be processed later. */ | 4500 | conditions will be processed later. */ |
4470 | MHD_itc_clear_ (daemon->itc); | 4501 | MHD_itc_clear_ (daemon->itc); |
4471 | continue; | 4502 | continue; |
4472 | } | 4503 | } |
4473 | if (daemon == events[i].data.ptr) | 4504 | if (daemon == events[i].data.ptr) |
4474 | { | 4505 | { |
4475 | /* Check for error conditions on listen socket. */ | 4506 | /* Check for error conditions on listen socket. */ |
4476 | /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ | 4507 | /* FIXME: Initiate MHD_quiesce_daemon() to prevent busy waiting? */ |
4477 | if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) | 4508 | if (0 == (events[i].events & (EPOLLERR | EPOLLHUP))) |
4478 | { | 4509 | { |
4479 | unsigned int series_length = 0; | 4510 | unsigned int series_length = 0; |
4480 | /* Run 'accept' until it fails or daemon at limit of connections. | 4511 | /* Run 'accept' until it fails or daemon at limit of connections. |
4481 | * Do not accept more then 10 connections at once. The rest will | 4512 | * Do not accept more then 10 connections at once. The rest will |
4482 | * be accepted on next turn (level trigger is used for listen | 4513 | * be accepted on next turn (level trigger is used for listen |
4483 | * socket). */ | 4514 | * socket). */ |
4484 | while ( (MHD_YES == MHD_accept_connection (daemon)) && | 4515 | while ( (MHD_YES == MHD_accept_connection (daemon)) && |
4485 | (series_length < 10) && | 4516 | (series_length < 10) && |
4486 | (daemon->connections < daemon->connection_limit) && | 4517 | (daemon->connections < daemon->connection_limit) && |
4487 | (! daemon->at_limit) ) | 4518 | (! daemon->at_limit) ) |
4488 | series_length++; | 4519 | series_length++; |
4489 | } | ||
4490 | continue; | ||
4491 | } | ||
4492 | /* this is an event relating to a 'normal' connection, | ||
4493 | remember the event and if appropriate mark the | ||
4494 | connection as 'eready'. */ | ||
4495 | pos = events[i].data.ptr; | ||
4496 | /* normal processing: update read/write data */ | ||
4497 | if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) | ||
4498 | { | ||
4499 | pos->epoll_state |= MHD_EPOLL_STATE_ERROR; | ||
4500 | if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | ||
4501 | { | ||
4502 | EDLL_insert (daemon->eready_head, | ||
4503 | daemon->eready_tail, | ||
4504 | pos); | ||
4505 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
4506 | } | ||
4507 | } | ||
4508 | else | ||
4509 | { | ||
4510 | if (0 != (events[i].events & EPOLLIN)) | ||
4511 | { | ||
4512 | pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; | ||
4513 | if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) || | ||
4514 | (pos->read_buffer_size > pos->read_buffer_offset) ) && | ||
4515 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | ||
4516 | { | ||
4517 | EDLL_insert (daemon->eready_head, | ||
4518 | daemon->eready_tail, | ||
4519 | pos); | ||
4520 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
4521 | } | ||
4522 | } | ||
4523 | if (0 != (events[i].events & EPOLLOUT)) | ||
4524 | { | ||
4525 | pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; | ||
4526 | if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && | ||
4527 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | ||
4528 | { | ||
4529 | EDLL_insert (daemon->eready_head, | ||
4530 | daemon->eready_tail, | ||
4531 | pos); | ||
4532 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
4533 | } | ||
4534 | } | ||
4535 | } | ||
4536 | } | 4520 | } |
4521 | continue; | ||
4522 | } | ||
4523 | /* this is an event relating to a 'normal' connection, | ||
4524 | remember the event and if appropriate mark the | ||
4525 | connection as 'eready'. */ | ||
4526 | pos = events[i].data.ptr; | ||
4527 | /* normal processing: update read/write data */ | ||
4528 | if (0 != (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))) | ||
4529 | { | ||
4530 | pos->epoll_state |= MHD_EPOLL_STATE_ERROR; | ||
4531 | if (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) | ||
4532 | { | ||
4533 | EDLL_insert (daemon->eready_head, | ||
4534 | daemon->eready_tail, | ||
4535 | pos); | ||
4536 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
4537 | } | ||
4538 | } | ||
4539 | else | ||
4540 | { | ||
4541 | if (0 != (events[i].events & EPOLLIN)) | ||
4542 | { | ||
4543 | pos->epoll_state |= MHD_EPOLL_STATE_READ_READY; | ||
4544 | if ( ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) || | ||
4545 | (pos->read_buffer_size > pos->read_buffer_offset) ) && | ||
4546 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | ||
4547 | { | ||
4548 | EDLL_insert (daemon->eready_head, | ||
4549 | daemon->eready_tail, | ||
4550 | pos); | ||
4551 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
4552 | } | ||
4553 | } | ||
4554 | if (0 != (events[i].events & EPOLLOUT)) | ||
4555 | { | ||
4556 | pos->epoll_state |= MHD_EPOLL_STATE_WRITE_READY; | ||
4557 | if ( (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && | ||
4558 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL) ) ) | ||
4559 | { | ||
4560 | EDLL_insert (daemon->eready_head, | ||
4561 | daemon->eready_tail, | ||
4562 | pos); | ||
4563 | pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL; | ||
4564 | } | ||
4565 | } | ||
4566 | } | ||
4537 | } | 4567 | } |
4568 | } | ||
4538 | 4569 | ||
4539 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 4570 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
4540 | if (run_upgraded || (NULL != daemon->eready_urh_head)) | 4571 | if (run_upgraded || (NULL != daemon->eready_urh_head)) |
@@ -4544,28 +4575,29 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
4544 | /* process events for connections */ | 4575 | /* process events for connections */ |
4545 | prev = daemon->eready_tail; | 4576 | prev = daemon->eready_tail; |
4546 | while (NULL != (pos = prev)) | 4577 | while (NULL != (pos = prev)) |
4547 | { | 4578 | { |
4548 | prev = pos->prevE; | 4579 | prev = pos->prevE; |
4549 | call_handlers (pos, | 4580 | call_handlers (pos, |
4550 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY), | 4581 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_READ_READY), |
4551 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY), | 4582 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY), |
4552 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR)); | 4583 | 0 != (pos->epoll_state & MHD_EPOLL_STATE_ERROR)); |
4553 | if (MHD_EPOLL_STATE_IN_EREADY_EDLL == | 4584 | if (MHD_EPOLL_STATE_IN_EREADY_EDLL == |
4554 | (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED | MHD_EPOLL_STATE_IN_EREADY_EDLL))) | 4585 | (pos->epoll_state & (MHD_EPOLL_STATE_SUSPENDED |
4555 | { | 4586 | | MHD_EPOLL_STATE_IN_EREADY_EDLL))) |
4556 | if ( (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info && | 4587 | { |
4557 | 0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY) ) || | 4588 | if ( ((MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info) && |
4558 | (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info && | 4589 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_READ_READY)) ) || |
4559 | 0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY) ) || | 4590 | ((MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info) && |
4560 | MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info) | 4591 | (0 == (pos->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ) || |
4561 | { | 4592 | (MHD_EVENT_LOOP_INFO_CLEANUP == pos->event_loop_info) ) |
4562 | EDLL_remove (daemon->eready_head, | 4593 | { |
4563 | daemon->eready_tail, | 4594 | EDLL_remove (daemon->eready_head, |
4564 | pos); | 4595 | daemon->eready_tail, |
4565 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; | 4596 | pos); |
4566 | } | 4597 | pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL; |
4567 | } | 4598 | } |
4568 | } | 4599 | } |
4600 | } | ||
4569 | 4601 | ||
4570 | /* Finally, handle timed-out connections; we need to do this here | 4602 | /* Finally, handle timed-out connections; we need to do this here |
4571 | as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything, | 4603 | as the epoll mechanism won't call the 'MHD_connection_handle_idle()' on everything, |
@@ -4577,22 +4609,22 @@ MHD_epoll (struct MHD_Daemon *daemon, | |||
4577 | do not bother to sort that (presumably very short) list. */ | 4609 | do not bother to sort that (presumably very short) list. */ |
4578 | prev = daemon->manual_timeout_tail; | 4610 | prev = daemon->manual_timeout_tail; |
4579 | while (NULL != (pos = prev)) | 4611 | while (NULL != (pos = prev)) |
4580 | { | 4612 | { |
4581 | prev = pos->prevX; | 4613 | prev = pos->prevX; |
4582 | MHD_connection_handle_idle (pos); | 4614 | MHD_connection_handle_idle (pos); |
4583 | } | 4615 | } |
4584 | /* Connections with the default timeout are sorted by prepending | 4616 | /* Connections with the default timeout are sorted by prepending |
4585 | them to the head of the list whenever we touch the connection; | 4617 | them to the head of the list whenever we touch the connection; |
4586 | thus it suffices to iterate from the tail until the first | 4618 | thus it suffices to iterate from the tail until the first |
4587 | connection is NOT timed out */ | 4619 | connection is NOT timed out */ |
4588 | prev = daemon->normal_timeout_tail; | 4620 | prev = daemon->normal_timeout_tail; |
4589 | while (NULL != (pos = prev)) | 4621 | while (NULL != (pos = prev)) |
4590 | { | 4622 | { |
4591 | prev = pos->prevX; | 4623 | prev = pos->prevX; |
4592 | MHD_connection_handle_idle (pos); | 4624 | MHD_connection_handle_idle (pos); |
4593 | if (MHD_CONNECTION_CLOSED != pos->state) | 4625 | if (MHD_CONNECTION_CLOSED != pos->state) |
4594 | break; /* sorted by timeout, no need to visit the rest! */ | 4626 | break; /* sorted by timeout, no need to visit the rest! */ |
4595 | } | 4627 | } |
4596 | return MHD_YES; | 4628 | return MHD_YES; |
4597 | } | 4629 | } |
4598 | #endif | 4630 | #endif |
@@ -4625,22 +4657,22 @@ MHD_run (struct MHD_Daemon *daemon) | |||
4625 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ) | 4657 | (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) ) |
4626 | return MHD_NO; | 4658 | return MHD_NO; |
4627 | if (0 != (daemon->options & MHD_USE_POLL)) | 4659 | if (0 != (daemon->options & MHD_USE_POLL)) |
4628 | { | 4660 | { |
4629 | MHD_poll (daemon, MHD_NO); | 4661 | MHD_poll (daemon, MHD_NO); |
4630 | MHD_cleanup_connections (daemon); | 4662 | MHD_cleanup_connections (daemon); |
4631 | } | 4663 | } |
4632 | #ifdef EPOLL_SUPPORT | 4664 | #ifdef EPOLL_SUPPORT |
4633 | else if (0 != (daemon->options & MHD_USE_EPOLL)) | 4665 | else if (0 != (daemon->options & MHD_USE_EPOLL)) |
4634 | { | 4666 | { |
4635 | MHD_epoll (daemon, MHD_NO); | 4667 | MHD_epoll (daemon, MHD_NO); |
4636 | MHD_cleanup_connections (daemon); | 4668 | MHD_cleanup_connections (daemon); |
4637 | } | 4669 | } |
4638 | #endif | 4670 | #endif |
4639 | else | 4671 | else |
4640 | { | 4672 | { |
4641 | MHD_select (daemon, MHD_NO); | 4673 | MHD_select (daemon, MHD_NO); |
4642 | /* MHD_select does MHD_cleanup_connections already */ | 4674 | /* MHD_select does MHD_cleanup_connections already */ |
4643 | } | 4675 | } |
4644 | return MHD_YES; | 4676 | return MHD_YES; |
4645 | } | 4677 | } |
4646 | 4678 | ||
@@ -4659,10 +4691,10 @@ close_connection (struct MHD_Connection *pos) | |||
4659 | struct MHD_Daemon *daemon = pos->daemon; | 4691 | struct MHD_Daemon *daemon = pos->daemon; |
4660 | 4692 | ||
4661 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | 4693 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
4662 | { | 4694 | { |
4663 | MHD_connection_mark_closed_ (pos); | 4695 | MHD_connection_mark_closed_ (pos); |
4664 | return; /* must let thread to do the rest */ | 4696 | return; /* must let thread to do the rest */ |
4665 | } | 4697 | } |
4666 | MHD_connection_close_ (pos, | 4698 | MHD_connection_close_ (pos, |
4667 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); | 4699 | MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN); |
4668 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 4700 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
@@ -4672,18 +4704,18 @@ close_connection (struct MHD_Connection *pos) | |||
4672 | mhd_assert (! pos->resuming); | 4704 | mhd_assert (! pos->resuming); |
4673 | if (pos->connection_timeout == daemon->connection_timeout) | 4705 | if (pos->connection_timeout == daemon->connection_timeout) |
4674 | XDLL_remove (daemon->normal_timeout_head, | 4706 | XDLL_remove (daemon->normal_timeout_head, |
4675 | daemon->normal_timeout_tail, | 4707 | daemon->normal_timeout_tail, |
4676 | pos); | 4708 | pos); |
4677 | else | 4709 | else |
4678 | XDLL_remove (daemon->manual_timeout_head, | 4710 | XDLL_remove (daemon->manual_timeout_head, |
4679 | daemon->manual_timeout_tail, | 4711 | daemon->manual_timeout_tail, |
4680 | pos); | 4712 | pos); |
4681 | DLL_remove (daemon->connections_head, | 4713 | DLL_remove (daemon->connections_head, |
4682 | daemon->connections_tail, | 4714 | daemon->connections_tail, |
4683 | pos); | 4715 | pos); |
4684 | DLL_insert (daemon->cleanup_head, | 4716 | DLL_insert (daemon->cleanup_head, |
4685 | daemon->cleanup_tail, | 4717 | daemon->cleanup_tail, |
4686 | pos); | 4718 | pos); |
4687 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 4719 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
4688 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 4720 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
4689 | #endif | 4721 | #endif |
@@ -4703,19 +4735,19 @@ MHD_polling_thread (void *cls) | |||
4703 | { | 4735 | { |
4704 | struct MHD_Daemon *daemon = cls; | 4736 | struct MHD_Daemon *daemon = cls; |
4705 | 4737 | ||
4706 | MHD_thread_init_(&(daemon->pid)); | 4738 | MHD_thread_init_ (&(daemon->pid)); |
4707 | while (! daemon->shutdown) | 4739 | while (! daemon->shutdown) |
4708 | { | 4740 | { |
4709 | if (0 != (daemon->options & MHD_USE_POLL)) | 4741 | if (0 != (daemon->options & MHD_USE_POLL)) |
4710 | MHD_poll (daemon, MHD_YES); | 4742 | MHD_poll (daemon, MHD_YES); |
4711 | #ifdef EPOLL_SUPPORT | 4743 | #ifdef EPOLL_SUPPORT |
4712 | else if (0 != (daemon->options & MHD_USE_EPOLL)) | 4744 | else if (0 != (daemon->options & MHD_USE_EPOLL)) |
4713 | MHD_epoll (daemon, MHD_YES); | 4745 | MHD_epoll (daemon, MHD_YES); |
4714 | #endif | 4746 | #endif |
4715 | else | 4747 | else |
4716 | MHD_select (daemon, MHD_YES); | 4748 | MHD_select (daemon, MHD_YES); |
4717 | MHD_cleanup_connections (daemon); | 4749 | MHD_cleanup_connections (daemon); |
4718 | } | 4750 | } |
4719 | 4751 | ||
4720 | /* Resume any pending for resume connections, join | 4752 | /* Resume any pending for resume connections, join |
4721 | * all connection's threads (if any) and finally cleanup | 4753 | * all connection's threads (if any) and finally cleanup |
@@ -4724,7 +4756,7 @@ MHD_polling_thread (void *cls) | |||
4724 | resume_suspended_connections (daemon); | 4756 | resume_suspended_connections (daemon); |
4725 | close_all_connections (daemon); | 4757 | close_all_connections (daemon); |
4726 | 4758 | ||
4727 | return (MHD_THRD_RTRN_TYPE_)0; | 4759 | return (MHD_THRD_RTRN_TYPE_) 0; |
4728 | } | 4760 | } |
4729 | #endif | 4761 | #endif |
4730 | 4762 | ||
@@ -4830,59 +4862,61 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon) | |||
4830 | return MHD_INVALID_SOCKET; | 4862 | return MHD_INVALID_SOCKET; |
4831 | if ( (0 == (daemon->options & (MHD_USE_ITC))) && | 4863 | if ( (0 == (daemon->options & (MHD_USE_ITC))) && |
4832 | (0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) ) | 4864 | (0 != (daemon->options & (MHD_USE_INTERNAL_POLLING_THREAD))) ) |
4833 | { | 4865 | { |
4834 | #ifdef HAVE_MESSAGES | 4866 | #ifdef HAVE_MESSAGES |
4835 | MHD_DLOG (daemon, | 4867 | MHD_DLOG (daemon, |
4836 | "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n"); | 4868 | "Using MHD_quiesce_daemon in this mode requires MHD_USE_ITC\n"); |
4837 | #endif | 4869 | #endif |
4838 | return MHD_INVALID_SOCKET; | 4870 | return MHD_INVALID_SOCKET; |
4839 | } | 4871 | } |
4840 | 4872 | ||
4841 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 4873 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
4842 | if (NULL != daemon->worker_pool) | 4874 | if (NULL != daemon->worker_pool) |
4843 | for (i = 0; i < daemon->worker_pool_size; i++) | 4875 | for (i = 0; i < daemon->worker_pool_size; i++) |
4844 | { | 4876 | { |
4845 | daemon->worker_pool[i].was_quiesced = true; | 4877 | daemon->worker_pool[i].was_quiesced = true; |
4846 | #ifdef EPOLL_SUPPORT | 4878 | #ifdef EPOLL_SUPPORT |
4847 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | 4879 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && |
4848 | (-1 != daemon->worker_pool[i].epoll_fd) && | 4880 | (-1 != daemon->worker_pool[i].epoll_fd) && |
4849 | (daemon->worker_pool[i].listen_socket_in_epoll) ) | 4881 | (daemon->worker_pool[i].listen_socket_in_epoll) ) |
4850 | { | 4882 | { |
4851 | if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd, | 4883 | if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd, |
4852 | EPOLL_CTL_DEL, | 4884 | EPOLL_CTL_DEL, |
4853 | ret, | 4885 | ret, |
4854 | NULL)) | 4886 | NULL)) |
4855 | MHD_PANIC (_("Failed to remove listen FD from epoll set\n")); | 4887 | MHD_PANIC (_ ("Failed to remove listen FD from epoll set\n")); |
4856 | daemon->worker_pool[i].listen_socket_in_epoll = false; | 4888 | daemon->worker_pool[i].listen_socket_in_epoll = false; |
4857 | } | 4889 | } |
4858 | else | 4890 | else |
4859 | #endif | 4891 | #endif |
4860 | if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc)) | 4892 | if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc)) |
4861 | { | 4893 | { |
4862 | if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q")) | 4894 | if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, "q")) |
4863 | MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel")); | 4895 | MHD_PANIC (_ ( |
4864 | } | 4896 | "Failed to signal quiesce via inter-thread communication channel")); |
4865 | } | 4897 | } |
4898 | } | ||
4866 | #endif | 4899 | #endif |
4867 | daemon->was_quiesced = true; | 4900 | daemon->was_quiesced = true; |
4868 | #ifdef EPOLL_SUPPORT | 4901 | #ifdef EPOLL_SUPPORT |
4869 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | 4902 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && |
4870 | (-1 != daemon->epoll_fd) && | 4903 | (-1 != daemon->epoll_fd) && |
4871 | (daemon->listen_socket_in_epoll) ) | 4904 | (daemon->listen_socket_in_epoll) ) |
4872 | { | 4905 | { |
4873 | if ( (0 != epoll_ctl (daemon->epoll_fd, | 4906 | if ( (0 != epoll_ctl (daemon->epoll_fd, |
4874 | EPOLL_CTL_DEL, | 4907 | EPOLL_CTL_DEL, |
4875 | ret, | 4908 | ret, |
4876 | NULL)) && | 4909 | NULL)) && |
4877 | (ENOENT != errno) ) /* ENOENT can happen due to race with | 4910 | (ENOENT != errno) ) /* ENOENT can happen due to race with |
4878 | #MHD_epoll() */ | 4911 | #MHD_epoll() */ |
4879 | MHD_PANIC ("Failed to remove listen FD from epoll set\n"); | 4912 | MHD_PANIC ("Failed to remove listen FD from epoll set\n"); |
4880 | daemon->listen_socket_in_epoll = false; | 4913 | daemon->listen_socket_in_epoll = false; |
4881 | } | 4914 | } |
4882 | #endif | 4915 | #endif |
4883 | if ( (MHD_ITC_IS_VALID_(daemon->itc)) && | 4916 | if ( (MHD_ITC_IS_VALID_ (daemon->itc)) && |
4884 | (! MHD_itc_activate_ (daemon->itc, "q")) ) | 4917 | (! MHD_itc_activate_ (daemon->itc, "q")) ) |
4885 | MHD_PANIC (_("failed to signal quiesce via inter-thread communication channel")); | 4918 | MHD_PANIC (_ ( |
4919 | "failed to signal quiesce via inter-thread communication channel")); | ||
4886 | return ret; | 4920 | return ret; |
4887 | } | 4921 | } |
4888 | 4922 | ||
@@ -4924,8 +4958,8 @@ parse_options_va (struct MHD_Daemon *daemon, | |||
4924 | */ | 4958 | */ |
4925 | static int | 4959 | static int |
4926 | parse_options (struct MHD_Daemon *daemon, | 4960 | parse_options (struct MHD_Daemon *daemon, |
4927 | const struct sockaddr **servaddr, | 4961 | const struct sockaddr **servaddr, |
4928 | ...) | 4962 | ...) |
4929 | { | 4963 | { |
4930 | va_list ap; | 4964 | va_list ap; |
4931 | int ret; | 4965 | int ret; |
@@ -4968,521 +5002,537 @@ parse_options_va (struct MHD_Daemon *daemon, | |||
4968 | #endif /* HTTPS_SUPPORT */ | 5002 | #endif /* HTTPS_SUPPORT */ |
4969 | 5003 | ||
4970 | while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int))) | 5004 | while (MHD_OPTION_END != (opt = (enum MHD_OPTION) va_arg (ap, int))) |
4971 | { | 5005 | { |
4972 | switch (opt) | 5006 | switch (opt) |
4973 | { | 5007 | { |
4974 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: | 5008 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: |
4975 | daemon->pool_size = va_arg (ap, | 5009 | daemon->pool_size = va_arg (ap, |
4976 | size_t); | 5010 | size_t); |
4977 | break; | 5011 | break; |
4978 | case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: | 5012 | case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: |
4979 | daemon->pool_increment= va_arg (ap, | 5013 | daemon->pool_increment = va_arg (ap, |
4980 | size_t); | 5014 | size_t); |
4981 | break; | 5015 | break; |
4982 | case MHD_OPTION_CONNECTION_LIMIT: | 5016 | case MHD_OPTION_CONNECTION_LIMIT: |
4983 | daemon->connection_limit = va_arg (ap, | 5017 | daemon->connection_limit = va_arg (ap, |
4984 | unsigned int); | 5018 | unsigned int); |
4985 | break; | 5019 | break; |
4986 | case MHD_OPTION_CONNECTION_TIMEOUT: | 5020 | case MHD_OPTION_CONNECTION_TIMEOUT: |
4987 | uv = va_arg (ap, | 5021 | uv = va_arg (ap, |
4988 | unsigned int); | 5022 | unsigned int); |
4989 | daemon->connection_timeout = (time_t)uv; | 5023 | daemon->connection_timeout = (time_t) uv; |
4990 | /* Next comparison could be always false on some platforms and whole branch will | 5024 | /* Next comparison could be always false on some platforms and whole branch will |
4991 | * be optimized out on those platforms. On others it will be compiled into real | 5025 | * be optimized out on those platforms. On others it will be compiled into real |
4992 | * check. */ | 5026 | * check. */ |
4993 | if ( ( (MHD_TYPE_IS_SIGNED_(time_t)) && | 5027 | if ( ( (MHD_TYPE_IS_SIGNED_ (time_t)) && |
4994 | (daemon->connection_timeout < 0) ) || /* Compiler may warn on some platforms, ignore warning. */ | 5028 | (daemon->connection_timeout < 0) ) || /* Compiler may warn on some platforms, ignore warning. */ |
4995 | (uv != (unsigned int)daemon->connection_timeout) ) | 5029 | (uv != (unsigned int) daemon->connection_timeout) ) |
4996 | { | 5030 | { |
4997 | #ifdef HAVE_MESSAGES | 5031 | #ifdef HAVE_MESSAGES |
4998 | MHD_DLOG (daemon, | 5032 | MHD_DLOG (daemon, |
4999 | _("Warning: Too large timeout value, ignored.\n")); | 5033 | _ ("Warning: Too large timeout value, ignored.\n")); |
5000 | #endif | 5034 | #endif |
5001 | daemon->connection_timeout = 0; | 5035 | daemon->connection_timeout = 0; |
5002 | } | 5036 | } |
5003 | break; | 5037 | break; |
5004 | case MHD_OPTION_NOTIFY_COMPLETED: | 5038 | case MHD_OPTION_NOTIFY_COMPLETED: |
5005 | daemon->notify_completed = va_arg (ap, | 5039 | daemon->notify_completed = va_arg (ap, |
5006 | MHD_RequestCompletedCallback); | 5040 | MHD_RequestCompletedCallback); |
5007 | daemon->notify_completed_cls = va_arg (ap, | 5041 | daemon->notify_completed_cls = va_arg (ap, |
5008 | void *); | 5042 | void *); |
5009 | break; | 5043 | break; |
5010 | case MHD_OPTION_NOTIFY_CONNECTION: | 5044 | case MHD_OPTION_NOTIFY_CONNECTION: |
5011 | daemon->notify_connection = va_arg (ap, | 5045 | daemon->notify_connection = va_arg (ap, |
5012 | MHD_NotifyConnectionCallback); | 5046 | MHD_NotifyConnectionCallback); |
5013 | daemon->notify_connection_cls = va_arg (ap, | 5047 | daemon->notify_connection_cls = va_arg (ap, |
5014 | void *); | 5048 | void *); |
5015 | break; | 5049 | break; |
5016 | case MHD_OPTION_PER_IP_CONNECTION_LIMIT: | 5050 | case MHD_OPTION_PER_IP_CONNECTION_LIMIT: |
5017 | daemon->per_ip_connection_limit = va_arg (ap, | 5051 | daemon->per_ip_connection_limit = va_arg (ap, |
5018 | unsigned int); | 5052 | unsigned int); |
5019 | break; | 5053 | break; |
5020 | case MHD_OPTION_SOCK_ADDR: | 5054 | case MHD_OPTION_SOCK_ADDR: |
5021 | *servaddr = va_arg (ap, | 5055 | *servaddr = va_arg (ap, |
5022 | const struct sockaddr *); | 5056 | const struct sockaddr *); |
5023 | break; | 5057 | break; |
5024 | case MHD_OPTION_URI_LOG_CALLBACK: | 5058 | case MHD_OPTION_URI_LOG_CALLBACK: |
5025 | daemon->uri_log_callback = va_arg (ap, | 5059 | daemon->uri_log_callback = va_arg (ap, |
5026 | LogCallback); | 5060 | LogCallback); |
5027 | daemon->uri_log_callback_cls = va_arg (ap, | 5061 | daemon->uri_log_callback_cls = va_arg (ap, |
5028 | void *); | 5062 | void *); |
5029 | break; | 5063 | break; |
5030 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 5064 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
5031 | case MHD_OPTION_THREAD_POOL_SIZE: | 5065 | case MHD_OPTION_THREAD_POOL_SIZE: |
5032 | daemon->worker_pool_size = va_arg (ap, | 5066 | daemon->worker_pool_size = va_arg (ap, |
5033 | unsigned int); | 5067 | unsigned int); |
5034 | if (0 == daemon->worker_pool_size) | 5068 | if (0 == daemon->worker_pool_size) |
5035 | { | 5069 | { |
5036 | #ifdef HAVE_MESSAGES | 5070 | #ifdef HAVE_MESSAGES |
5037 | MHD_DLOG (daemon, | 5071 | MHD_DLOG (daemon, |
5038 | _("Warning: Zero size, specified for thread pool size, is ignored. " | 5072 | _ ( |
5039 | "Thread pool is not used.\n")); | 5073 | "Warning: Zero size, specified for thread pool size, is ignored. " |
5040 | #endif | 5074 | "Thread pool is not used.\n")); |
5041 | } | ||
5042 | else if (1 == daemon->worker_pool_size) | ||
5043 | { | ||
5044 | #ifdef HAVE_MESSAGES | ||
5045 | MHD_DLOG (daemon, | ||
5046 | _("Warning: \"1\", specified for thread pool size, is ignored. " | ||
5047 | "Thread pool is not used.\n")); | ||
5048 | #endif | ||
5049 | daemon->worker_pool_size = 0; | ||
5050 | } | ||
5051 | /* Next comparison could be always false on some platforms and whole branch will | ||
5052 | * be optimized out on those platforms. On others it will be compiled into real | ||
5053 | * check. */ | ||
5054 | else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */ | ||
5055 | { | ||
5056 | #ifdef HAVE_MESSAGES | ||
5057 | MHD_DLOG (daemon, | ||
5058 | _("Specified thread pool size (%u) too big\n"), | ||
5059 | daemon->worker_pool_size); | ||
5060 | #endif | ||
5061 | return MHD_NO; | ||
5062 | } | ||
5063 | else | ||
5064 | { | ||
5065 | if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) | ||
5066 | { | ||
5067 | #ifdef HAVE_MESSAGES | ||
5068 | MHD_DLOG (daemon, | ||
5069 | _("MHD_OPTION_THREAD_POOL_SIZE option is specified but " | ||
5070 | "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n")); | ||
5071 | #endif | ||
5072 | return MHD_NO; | ||
5073 | } | ||
5074 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) | ||
5075 | { | ||
5076 | #ifdef HAVE_MESSAGES | ||
5077 | MHD_DLOG (daemon, | ||
5078 | _("Both MHD_OPTION_THREAD_POOL_SIZE option and " | ||
5079 | "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n")); | ||
5080 | #endif | ||
5081 | return MHD_NO; | ||
5082 | } | ||
5083 | } | ||
5084 | break; | ||
5085 | #endif | 5075 | #endif |
5086 | #ifdef HTTPS_SUPPORT | 5076 | } |
5087 | case MHD_OPTION_HTTPS_MEM_KEY: | 5077 | else if (1 == daemon->worker_pool_size) |
5088 | pstr = va_arg (ap, | 5078 | { |
5089 | const char *); | ||
5090 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
5091 | daemon->https_mem_key = pstr; | ||
5092 | #ifdef HAVE_MESSAGES | 5079 | #ifdef HAVE_MESSAGES |
5093 | else | 5080 | MHD_DLOG (daemon, |
5094 | MHD_DLOG (daemon, | 5081 | _ ( |
5095 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | 5082 | "Warning: \"1\", specified for thread pool size, is ignored. " |
5096 | opt); | 5083 | "Thread pool is not used.\n")); |
5097 | #endif | 5084 | #endif |
5098 | break; | 5085 | daemon->worker_pool_size = 0; |
5099 | case MHD_OPTION_HTTPS_KEY_PASSWORD: | 5086 | } |
5100 | pstr = va_arg (ap, | 5087 | /* Next comparison could be always false on some platforms and whole branch will |
5101 | const char *); | 5088 | * be optimized out on those platforms. On others it will be compiled into real |
5102 | if (0 != (daemon->options & MHD_USE_TLS)) | 5089 | * check. */ |
5103 | daemon->https_key_password = pstr; | 5090 | else if (daemon->worker_pool_size >= (SIZE_MAX / sizeof (struct |
5091 | MHD_Daemon))) /* Compiler may warn on some platforms, ignore warning. */ | ||
5092 | { | ||
5104 | #ifdef HAVE_MESSAGES | 5093 | #ifdef HAVE_MESSAGES |
5105 | else | 5094 | MHD_DLOG (daemon, |
5106 | MHD_DLOG (daemon, | 5095 | _ ("Specified thread pool size (%u) too big\n"), |
5107 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | 5096 | daemon->worker_pool_size); |
5108 | opt); | ||
5109 | #endif | 5097 | #endif |
5110 | break; | 5098 | return MHD_NO; |
5111 | case MHD_OPTION_HTTPS_MEM_CERT: | 5099 | } |
5112 | pstr = va_arg (ap, | 5100 | else |
5113 | const char *); | 5101 | { |
5114 | if (0 != (daemon->options & MHD_USE_TLS)) | 5102 | if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) |
5115 | daemon->https_mem_cert = pstr; | 5103 | { |
5116 | #ifdef HAVE_MESSAGES | 5104 | #ifdef HAVE_MESSAGES |
5117 | else | 5105 | MHD_DLOG (daemon, |
5118 | MHD_DLOG (daemon, | 5106 | _ ("MHD_OPTION_THREAD_POOL_SIZE option is specified but " |
5119 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | 5107 | "MHD_USE_INTERNAL_POLLING_THREAD flag is not specified.\n")); |
5120 | opt); | ||
5121 | #endif | 5108 | #endif |
5122 | break; | 5109 | return MHD_NO; |
5123 | case MHD_OPTION_HTTPS_MEM_TRUST: | 5110 | } |
5124 | pstr = va_arg (ap, | 5111 | if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) |
5125 | const char *); | 5112 | { |
5126 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
5127 | daemon->https_mem_trust = pstr; | ||
5128 | #ifdef HAVE_MESSAGES | 5113 | #ifdef HAVE_MESSAGES |
5129 | else | 5114 | MHD_DLOG (daemon, |
5130 | MHD_DLOG (daemon, | 5115 | _ ("Both MHD_OPTION_THREAD_POOL_SIZE option and " |
5131 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | 5116 | "MHD_USE_THREAD_PER_CONNECTION flag are specified.\n")); |
5132 | opt); | ||
5133 | #endif | 5117 | #endif |
5134 | break; | 5118 | return MHD_NO; |
5135 | case MHD_OPTION_HTTPS_CRED_TYPE: | 5119 | } |
5136 | daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, | 5120 | } |
5137 | int); | 5121 | break; |
5138 | break; | ||
5139 | case MHD_OPTION_HTTPS_MEM_DHPARAMS: | ||
5140 | pstr = va_arg (ap, | ||
5141 | const char *); | ||
5142 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
5143 | { | ||
5144 | gnutls_datum_t dhpar; | ||
5145 | size_t pstr_len; | ||
5146 | |||
5147 | if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0) | ||
5148 | { | ||
5149 | #ifdef HAVE_MESSAGES | ||
5150 | MHD_DLOG (daemon, | ||
5151 | _("Error initializing DH parameters\n")); | ||
5152 | #endif | ||
5153 | return MHD_NO; | ||
5154 | } | ||
5155 | dhpar.data = (unsigned char *) pstr; | ||
5156 | pstr_len = strlen (pstr); | ||
5157 | if (UINT_MAX < pstr_len) | ||
5158 | { | ||
5159 | #ifdef HAVE_MESSAGES | ||
5160 | MHD_DLOG (daemon, | ||
5161 | _("Diffie-Hellman parameters string too long\n")); | ||
5162 | #endif | ||
5163 | return MHD_NO; | ||
5164 | } | ||
5165 | dhpar.size = (unsigned int) pstr_len; | ||
5166 | if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, | ||
5167 | &dhpar, | ||
5168 | GNUTLS_X509_FMT_PEM) < 0) | ||
5169 | { | ||
5170 | #ifdef HAVE_MESSAGES | ||
5171 | MHD_DLOG (daemon, | ||
5172 | _("Bad Diffie-Hellman parameters format\n")); | ||
5173 | #endif | ||
5174 | gnutls_dh_params_deinit (daemon->https_mem_dhparams); | ||
5175 | return MHD_NO; | ||
5176 | } | ||
5177 | daemon->have_dhparams = true; | ||
5178 | } | ||
5179 | #ifdef HAVE_MESSAGES | ||
5180 | else | ||
5181 | MHD_DLOG (daemon, | ||
5182 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | ||
5183 | opt); | ||
5184 | #endif | 5122 | #endif |
5185 | break; | 5123 | #ifdef HTTPS_SUPPORT |
5186 | case MHD_OPTION_HTTPS_PRIORITIES: | 5124 | case MHD_OPTION_HTTPS_MEM_KEY: |
5187 | pstr = va_arg (ap, | 5125 | pstr = va_arg (ap, |
5188 | const char *); | 5126 | const char *); |
5189 | if (0 != (daemon->options & MHD_USE_TLS)) | 5127 | if (0 != (daemon->options & MHD_USE_TLS)) |
5190 | { | 5128 | daemon->https_mem_key = pstr; |
5191 | gnutls_priority_deinit (daemon->priority_cache); | 5129 | #ifdef HAVE_MESSAGES |
5192 | ret = gnutls_priority_init (&daemon->priority_cache, | 5130 | else |
5193 | pstr, | 5131 | MHD_DLOG (daemon, |
5194 | NULL); | 5132 | _ ( |
5195 | if (GNUTLS_E_SUCCESS != ret) | 5133 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), |
5196 | { | 5134 | opt); |
5197 | #ifdef HAVE_MESSAGES | 5135 | #endif |
5198 | MHD_DLOG (daemon, | 5136 | break; |
5199 | _("Setting priorities to `%s' failed: %s\n"), | 5137 | case MHD_OPTION_HTTPS_KEY_PASSWORD: |
5200 | pstr, | 5138 | pstr = va_arg (ap, |
5201 | gnutls_strerror (ret)); | 5139 | const char *); |
5202 | #endif | 5140 | if (0 != (daemon->options & MHD_USE_TLS)) |
5203 | daemon->priority_cache = NULL; | 5141 | daemon->https_key_password = pstr; |
5204 | return MHD_NO; | 5142 | #ifdef HAVE_MESSAGES |
5205 | } | 5143 | else |
5206 | } | 5144 | MHD_DLOG (daemon, |
5207 | #ifdef HAVE_MESSAGES | 5145 | _ ( |
5208 | else | 5146 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), |
5209 | MHD_DLOG (daemon, | 5147 | opt); |
5210 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | 5148 | #endif |
5211 | opt); | 5149 | break; |
5150 | case MHD_OPTION_HTTPS_MEM_CERT: | ||
5151 | pstr = va_arg (ap, | ||
5152 | const char *); | ||
5153 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
5154 | daemon->https_mem_cert = pstr; | ||
5155 | #ifdef HAVE_MESSAGES | ||
5156 | else | ||
5157 | MHD_DLOG (daemon, | ||
5158 | _ ( | ||
5159 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | ||
5160 | opt); | ||
5161 | #endif | ||
5162 | break; | ||
5163 | case MHD_OPTION_HTTPS_MEM_TRUST: | ||
5164 | pstr = va_arg (ap, | ||
5165 | const char *); | ||
5166 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
5167 | daemon->https_mem_trust = pstr; | ||
5168 | #ifdef HAVE_MESSAGES | ||
5169 | else | ||
5170 | MHD_DLOG (daemon, | ||
5171 | _ ( | ||
5172 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | ||
5173 | opt); | ||
5174 | #endif | ||
5175 | break; | ||
5176 | case MHD_OPTION_HTTPS_CRED_TYPE: | ||
5177 | daemon->cred_type = (gnutls_credentials_type_t) va_arg (ap, | ||
5178 | int); | ||
5179 | break; | ||
5180 | case MHD_OPTION_HTTPS_MEM_DHPARAMS: | ||
5181 | pstr = va_arg (ap, | ||
5182 | const char *); | ||
5183 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
5184 | { | ||
5185 | gnutls_datum_t dhpar; | ||
5186 | size_t pstr_len; | ||
5187 | |||
5188 | if (gnutls_dh_params_init (&daemon->https_mem_dhparams) < 0) | ||
5189 | { | ||
5190 | #ifdef HAVE_MESSAGES | ||
5191 | MHD_DLOG (daemon, | ||
5192 | _ ("Error initializing DH parameters\n")); | ||
5212 | #endif | 5193 | #endif |
5213 | break; | 5194 | return MHD_NO; |
5214 | case MHD_OPTION_HTTPS_CERT_CALLBACK: | 5195 | } |
5215 | #if GNUTLS_VERSION_MAJOR < 3 | 5196 | dhpar.data = (unsigned char *) pstr; |
5197 | pstr_len = strlen (pstr); | ||
5198 | if (UINT_MAX < pstr_len) | ||
5199 | { | ||
5200 | #ifdef HAVE_MESSAGES | ||
5201 | MHD_DLOG (daemon, | ||
5202 | _ ("Diffie-Hellman parameters string too long\n")); | ||
5203 | #endif | ||
5204 | return MHD_NO; | ||
5205 | } | ||
5206 | dhpar.size = (unsigned int) pstr_len; | ||
5207 | if (gnutls_dh_params_import_pkcs3 (daemon->https_mem_dhparams, | ||
5208 | &dhpar, | ||
5209 | GNUTLS_X509_FMT_PEM) < 0) | ||
5210 | { | ||
5216 | #ifdef HAVE_MESSAGES | 5211 | #ifdef HAVE_MESSAGES |
5217 | MHD_DLOG (daemon, | 5212 | MHD_DLOG (daemon, |
5218 | _("MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n")); | 5213 | _ ("Bad Diffie-Hellman parameters format\n")); |
5219 | #endif | 5214 | #endif |
5215 | gnutls_dh_params_deinit (daemon->https_mem_dhparams); | ||
5220 | return MHD_NO; | 5216 | return MHD_NO; |
5217 | } | ||
5218 | daemon->have_dhparams = true; | ||
5219 | } | ||
5220 | #ifdef HAVE_MESSAGES | ||
5221 | else | ||
5222 | MHD_DLOG (daemon, | ||
5223 | _ ( | ||
5224 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | ||
5225 | opt); | ||
5226 | #endif | ||
5227 | break; | ||
5228 | case MHD_OPTION_HTTPS_PRIORITIES: | ||
5229 | pstr = va_arg (ap, | ||
5230 | const char *); | ||
5231 | if (0 != (daemon->options & MHD_USE_TLS)) | ||
5232 | { | ||
5233 | gnutls_priority_deinit (daemon->priority_cache); | ||
5234 | ret = gnutls_priority_init (&daemon->priority_cache, | ||
5235 | pstr, | ||
5236 | NULL); | ||
5237 | if (GNUTLS_E_SUCCESS != ret) | ||
5238 | { | ||
5239 | #ifdef HAVE_MESSAGES | ||
5240 | MHD_DLOG (daemon, | ||
5241 | _ ("Setting priorities to `%s' failed: %s\n"), | ||
5242 | pstr, | ||
5243 | gnutls_strerror (ret)); | ||
5244 | #endif | ||
5245 | daemon->priority_cache = NULL; | ||
5246 | return MHD_NO; | ||
5247 | } | ||
5248 | } | ||
5249 | #ifdef HAVE_MESSAGES | ||
5250 | else | ||
5251 | MHD_DLOG (daemon, | ||
5252 | _ ( | ||
5253 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | ||
5254 | opt); | ||
5255 | #endif | ||
5256 | break; | ||
5257 | case MHD_OPTION_HTTPS_CERT_CALLBACK: | ||
5258 | #if GNUTLS_VERSION_MAJOR < 3 | ||
5259 | #ifdef HAVE_MESSAGES | ||
5260 | MHD_DLOG (daemon, | ||
5261 | _ ( | ||
5262 | "MHD_OPTION_HTTPS_CERT_CALLBACK requires building MHD with GnuTLS >= 3.0\n")); | ||
5263 | #endif | ||
5264 | return MHD_NO; | ||
5221 | #else | 5265 | #else |
5222 | pgcrf = va_arg (ap, | 5266 | pgcrf = va_arg (ap, |
5223 | gnutls_certificate_retrieve_function2 *); | 5267 | gnutls_certificate_retrieve_function2 *); |
5224 | if (0 != (daemon->options & MHD_USE_TLS)) | 5268 | if (0 != (daemon->options & MHD_USE_TLS)) |
5225 | daemon->cert_callback = pgcrf; | 5269 | daemon->cert_callback = pgcrf; |
5226 | else | 5270 | else |
5227 | #ifdef HAVE_MESSAGES | 5271 | #ifdef HAVE_MESSAGES |
5228 | MHD_DLOG (daemon, | 5272 | MHD_DLOG (daemon, |
5229 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | 5273 | _ ( |
5230 | opt); | 5274 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), |
5275 | opt); | ||
5231 | #endif | 5276 | #endif |
5232 | break; | 5277 | break; |
5233 | #endif | 5278 | #endif |
5234 | case MHD_OPTION_HTTPS_CERT_CALLBACK2: | 5279 | case MHD_OPTION_HTTPS_CERT_CALLBACK2: |
5235 | #if GNUTLS_VERSION_NUMBER < 0x030603 | 5280 | #if GNUTLS_VERSION_NUMBER < 0x030603 |
5236 | #ifdef HAVE_MESSAGES | 5281 | #ifdef HAVE_MESSAGES |
5237 | MHD_DLOG (daemon, | 5282 | MHD_DLOG (daemon, |
5238 | _("MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n")); | 5283 | _ ( |
5284 | "MHD_OPTION_HTTPS_CERT_CALLBACK2 requires building MHD with GnuTLS >= 3.6.3\n")); | ||
5239 | #endif | 5285 | #endif |
5240 | return MHD_NO; | 5286 | return MHD_NO; |
5241 | #else | 5287 | #else |
5242 | pgcrf2 = va_arg (ap, | 5288 | pgcrf2 = va_arg (ap, |
5243 | gnutls_certificate_retrieve_function3 *); | 5289 | gnutls_certificate_retrieve_function3 *); |
5244 | if (0 != (daemon->options & MHD_USE_TLS)) | 5290 | if (0 != (daemon->options & MHD_USE_TLS)) |
5245 | daemon->cert_callback2 = pgcrf2; | 5291 | daemon->cert_callback2 = pgcrf2; |
5246 | else | 5292 | else |
5247 | #ifdef HAVE_MESSAGES | 5293 | #ifdef HAVE_MESSAGES |
5248 | MHD_DLOG (daemon, | 5294 | MHD_DLOG (daemon, |
5249 | _("MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), | 5295 | _ ( |
5250 | opt); | 5296 | "MHD HTTPS option %d passed to MHD but MHD_USE_TLS not set\n"), |
5297 | opt); | ||
5251 | #endif | 5298 | #endif |
5252 | break; | 5299 | break; |
5253 | #endif | 5300 | #endif |
5254 | #endif /* HTTPS_SUPPORT */ | 5301 | #endif /* HTTPS_SUPPORT */ |
5255 | #ifdef DAUTH_SUPPORT | 5302 | #ifdef DAUTH_SUPPORT |
5256 | case MHD_OPTION_DIGEST_AUTH_RANDOM: | 5303 | case MHD_OPTION_DIGEST_AUTH_RANDOM: |
5257 | daemon->digest_auth_rand_size = va_arg (ap, | 5304 | daemon->digest_auth_rand_size = va_arg (ap, |
5258 | size_t); | 5305 | size_t); |
5259 | daemon->digest_auth_random = va_arg (ap, | 5306 | daemon->digest_auth_random = va_arg (ap, |
5260 | const char *); | 5307 | const char *); |
5261 | break; | 5308 | break; |
5262 | case MHD_OPTION_NONCE_NC_SIZE: | 5309 | case MHD_OPTION_NONCE_NC_SIZE: |
5263 | daemon->nonce_nc_size = va_arg (ap, | 5310 | daemon->nonce_nc_size = va_arg (ap, |
5264 | unsigned int); | 5311 | unsigned int); |
5265 | break; | 5312 | break; |
5266 | #endif | 5313 | #endif |
5267 | case MHD_OPTION_LISTEN_SOCKET: | 5314 | case MHD_OPTION_LISTEN_SOCKET: |
5268 | if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) | 5315 | if (0 != (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) |
5269 | { | 5316 | { |
5270 | #ifdef HAVE_MESSAGES | ||
5271 | MHD_DLOG (daemon, | ||
5272 | _("MHD_OPTION_LISTEN_SOCKET specified for daemon " | ||
5273 | "with MHD_USE_NO_LISTEN_SOCKET flag set.\n")); | ||
5274 | #endif | ||
5275 | return MHD_NO; | ||
5276 | } | ||
5277 | else | ||
5278 | daemon->listen_fd = va_arg (ap, | ||
5279 | MHD_socket); | ||
5280 | break; | ||
5281 | case MHD_OPTION_EXTERNAL_LOGGER: | ||
5282 | #ifdef HAVE_MESSAGES | 5317 | #ifdef HAVE_MESSAGES |
5283 | daemon->custom_error_log = va_arg (ap, | 5318 | MHD_DLOG (daemon, |
5284 | VfprintfFunctionPointerType); | 5319 | _ ("MHD_OPTION_LISTEN_SOCKET specified for daemon " |
5285 | daemon->custom_error_log_cls = va_arg (ap, | 5320 | "with MHD_USE_NO_LISTEN_SOCKET flag set.\n")); |
5286 | void *); | 5321 | #endif |
5322 | return MHD_NO; | ||
5323 | } | ||
5324 | else | ||
5325 | daemon->listen_fd = va_arg (ap, | ||
5326 | MHD_socket); | ||
5327 | break; | ||
5328 | case MHD_OPTION_EXTERNAL_LOGGER: | ||
5329 | #ifdef HAVE_MESSAGES | ||
5330 | daemon->custom_error_log = va_arg (ap, | ||
5331 | VfprintfFunctionPointerType); | ||
5332 | daemon->custom_error_log_cls = va_arg (ap, | ||
5333 | void *); | ||
5287 | #else | 5334 | #else |
5288 | va_arg (ap, | 5335 | va_arg (ap, |
5289 | VfprintfFunctionPointerType); | 5336 | VfprintfFunctionPointerType); |
5290 | va_arg (ap, | 5337 | va_arg (ap, |
5291 | void *); | 5338 | void *); |
5292 | #endif | 5339 | #endif |
5293 | break; | 5340 | break; |
5294 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 5341 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
5295 | case MHD_OPTION_THREAD_STACK_SIZE: | 5342 | case MHD_OPTION_THREAD_STACK_SIZE: |
5296 | daemon->thread_stack_size = va_arg (ap, | 5343 | daemon->thread_stack_size = va_arg (ap, |
5297 | size_t); | 5344 | size_t); |
5298 | break; | 5345 | break; |
5299 | #endif | 5346 | #endif |
5300 | case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: | 5347 | case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: |
5301 | #ifdef TCP_FASTOPEN | 5348 | #ifdef TCP_FASTOPEN |
5302 | daemon->fastopen_queue_size = va_arg (ap, | 5349 | daemon->fastopen_queue_size = va_arg (ap, |
5303 | unsigned int); | 5350 | unsigned int); |
5304 | break; | 5351 | break; |
5305 | #else /* ! TCP_FASTOPEN */ | 5352 | #else /* ! TCP_FASTOPEN */ |
5306 | #ifdef HAVE_MESSAGES | 5353 | #ifdef HAVE_MESSAGES |
5307 | MHD_DLOG (daemon, | 5354 | MHD_DLOG (daemon, |
5308 | _("TCP fastopen is not supported on this platform\n")); | 5355 | _ ("TCP fastopen is not supported on this platform\n")); |
5309 | return MHD_NO; | 5356 | return MHD_NO; |
5310 | #endif /* HAVE_MESSAGES */ | 5357 | #endif /* HAVE_MESSAGES */ |
5311 | #endif /* ! TCP_FASTOPEN */ | 5358 | #endif /* ! TCP_FASTOPEN */ |
5312 | case MHD_OPTION_LISTENING_ADDRESS_REUSE: | 5359 | case MHD_OPTION_LISTENING_ADDRESS_REUSE: |
5313 | daemon->listening_address_reuse = va_arg (ap, | 5360 | daemon->listening_address_reuse = va_arg (ap, |
5314 | unsigned int) ? 1 : -1; | 5361 | unsigned int) ? 1 : -1; |
5315 | break; | 5362 | break; |
5316 | case MHD_OPTION_LISTEN_BACKLOG_SIZE: | 5363 | case MHD_OPTION_LISTEN_BACKLOG_SIZE: |
5317 | daemon->listen_backlog_size = va_arg (ap, | 5364 | daemon->listen_backlog_size = va_arg (ap, |
5318 | unsigned int); | 5365 | unsigned int); |
5319 | break; | 5366 | break; |
5320 | case MHD_OPTION_STRICT_FOR_CLIENT: | 5367 | case MHD_OPTION_STRICT_FOR_CLIENT: |
5321 | daemon->strict_for_client = va_arg (ap, int); | 5368 | daemon->strict_for_client = va_arg (ap, int); |
5322 | #ifdef HAVE_MESSAGES | 5369 | #ifdef HAVE_MESSAGES |
5323 | if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) && | 5370 | if ( (0 != (daemon->options & MHD_USE_PEDANTIC_CHECKS)) && |
5324 | (1 != daemon->strict_for_client) ) | 5371 | (1 != daemon->strict_for_client) ) |
5325 | { | 5372 | { |
5326 | MHD_DLOG (daemon, | 5373 | MHD_DLOG (daemon, |
5327 | _("Flag MHD_USE_PEDANTIC_CHECKS is ignored because " | 5374 | _ ("Flag MHD_USE_PEDANTIC_CHECKS is ignored because " |
5328 | "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n")); | 5375 | "another behavior is specified by MHD_OPTION_STRICT_CLIENT.\n")); |
5329 | } | 5376 | } |
5330 | #endif /* HAVE_MESSAGES */ | 5377 | #endif /* HAVE_MESSAGES */ |
5331 | break; | 5378 | break; |
5332 | case MHD_OPTION_ARRAY: | 5379 | case MHD_OPTION_ARRAY: |
5333 | oa = va_arg (ap, struct MHD_OptionItem*); | 5380 | oa = va_arg (ap, struct MHD_OptionItem*); |
5334 | i = 0; | 5381 | i = 0; |
5335 | while (MHD_OPTION_END != (opt = oa[i].option)) | 5382 | while (MHD_OPTION_END != (opt = oa[i].option)) |
5336 | { | 5383 | { |
5337 | switch (opt) | 5384 | switch (opt) |
5338 | { | 5385 | { |
5339 | /* all options taking 'size_t' */ | 5386 | /* all options taking 'size_t' */ |
5340 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: | 5387 | case MHD_OPTION_CONNECTION_MEMORY_LIMIT: |
5341 | case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: | 5388 | case MHD_OPTION_CONNECTION_MEMORY_INCREMENT: |
5342 | case MHD_OPTION_THREAD_STACK_SIZE: | 5389 | case MHD_OPTION_THREAD_STACK_SIZE: |
5343 | if (MHD_YES != parse_options (daemon, | 5390 | if (MHD_YES != parse_options (daemon, |
5344 | servaddr, | 5391 | servaddr, |
5345 | opt, | 5392 | opt, |
5346 | (size_t) oa[i].value, | 5393 | (size_t) oa[i].value, |
5347 | MHD_OPTION_END)) | 5394 | MHD_OPTION_END)) |
5348 | return MHD_NO; | 5395 | return MHD_NO; |
5349 | break; | 5396 | break; |
5350 | /* all options taking 'unsigned int' */ | 5397 | /* all options taking 'unsigned int' */ |
5351 | case MHD_OPTION_NONCE_NC_SIZE: | 5398 | case MHD_OPTION_NONCE_NC_SIZE: |
5352 | case MHD_OPTION_CONNECTION_LIMIT: | 5399 | case MHD_OPTION_CONNECTION_LIMIT: |
5353 | case MHD_OPTION_CONNECTION_TIMEOUT: | 5400 | case MHD_OPTION_CONNECTION_TIMEOUT: |
5354 | case MHD_OPTION_PER_IP_CONNECTION_LIMIT: | 5401 | case MHD_OPTION_PER_IP_CONNECTION_LIMIT: |
5355 | case MHD_OPTION_THREAD_POOL_SIZE: | 5402 | case MHD_OPTION_THREAD_POOL_SIZE: |
5356 | case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: | 5403 | case MHD_OPTION_TCP_FASTOPEN_QUEUE_SIZE: |
5357 | case MHD_OPTION_LISTENING_ADDRESS_REUSE: | 5404 | case MHD_OPTION_LISTENING_ADDRESS_REUSE: |
5358 | case MHD_OPTION_LISTEN_BACKLOG_SIZE: | 5405 | case MHD_OPTION_LISTEN_BACKLOG_SIZE: |
5359 | if (MHD_YES != parse_options (daemon, | 5406 | if (MHD_YES != parse_options (daemon, |
5360 | servaddr, | 5407 | servaddr, |
5361 | opt, | 5408 | opt, |
5362 | (unsigned int) oa[i].value, | 5409 | (unsigned int) oa[i].value, |
5363 | MHD_OPTION_END)) | 5410 | MHD_OPTION_END)) |
5364 | return MHD_NO; | 5411 | return MHD_NO; |
5365 | break; | 5412 | break; |
5366 | /* all options taking 'enum' */ | 5413 | /* all options taking 'enum' */ |
5367 | #ifdef HTTPS_SUPPORT | 5414 | #ifdef HTTPS_SUPPORT |
5368 | case MHD_OPTION_HTTPS_CRED_TYPE: | 5415 | case MHD_OPTION_HTTPS_CRED_TYPE: |
5369 | if (MHD_YES != parse_options (daemon, | 5416 | if (MHD_YES != parse_options (daemon, |
5370 | servaddr, | 5417 | servaddr, |
5371 | opt, | 5418 | opt, |
5372 | (gnutls_credentials_type_t) oa[i].value, | 5419 | (gnutls_credentials_type_t) oa[i].value, |
5373 | MHD_OPTION_END)) | 5420 | MHD_OPTION_END)) |
5374 | return MHD_NO; | 5421 | return MHD_NO; |
5375 | break; | 5422 | break; |
5376 | #endif /* HTTPS_SUPPORT */ | 5423 | #endif /* HTTPS_SUPPORT */ |
5377 | /* all options taking 'MHD_socket' */ | 5424 | /* all options taking 'MHD_socket' */ |
5378 | case MHD_OPTION_LISTEN_SOCKET: | 5425 | case MHD_OPTION_LISTEN_SOCKET: |
5379 | if (MHD_YES != parse_options (daemon, | 5426 | if (MHD_YES != parse_options (daemon, |
5380 | servaddr, | 5427 | servaddr, |
5381 | opt, | 5428 | opt, |
5382 | (MHD_socket) oa[i].value, | 5429 | (MHD_socket) oa[i].value, |
5383 | MHD_OPTION_END)) | 5430 | MHD_OPTION_END)) |
5384 | return MHD_NO; | 5431 | return MHD_NO; |
5385 | break; | 5432 | break; |
5386 | /* all options taking 'int' */ | 5433 | /* all options taking 'int' */ |
5387 | case MHD_OPTION_STRICT_FOR_CLIENT: | 5434 | case MHD_OPTION_STRICT_FOR_CLIENT: |
5388 | if (MHD_YES != parse_options (daemon, | 5435 | if (MHD_YES != parse_options (daemon, |
5389 | servaddr, | 5436 | servaddr, |
5390 | opt, | 5437 | opt, |
5391 | (int) oa[i].value, | 5438 | (int) oa[i].value, |
5392 | MHD_OPTION_END)) | 5439 | MHD_OPTION_END)) |
5393 | return MHD_NO; | 5440 | return MHD_NO; |
5394 | break; | 5441 | break; |
5395 | /* all options taking one pointer */ | 5442 | /* all options taking one pointer */ |
5396 | case MHD_OPTION_SOCK_ADDR: | 5443 | case MHD_OPTION_SOCK_ADDR: |
5397 | case MHD_OPTION_HTTPS_MEM_KEY: | 5444 | case MHD_OPTION_HTTPS_MEM_KEY: |
5398 | case MHD_OPTION_HTTPS_KEY_PASSWORD: | 5445 | case MHD_OPTION_HTTPS_KEY_PASSWORD: |
5399 | case MHD_OPTION_HTTPS_MEM_CERT: | 5446 | case MHD_OPTION_HTTPS_MEM_CERT: |
5400 | case MHD_OPTION_HTTPS_MEM_TRUST: | 5447 | case MHD_OPTION_HTTPS_MEM_TRUST: |
5401 | case MHD_OPTION_HTTPS_MEM_DHPARAMS: | 5448 | case MHD_OPTION_HTTPS_MEM_DHPARAMS: |
5402 | case MHD_OPTION_HTTPS_PRIORITIES: | 5449 | case MHD_OPTION_HTTPS_PRIORITIES: |
5403 | case MHD_OPTION_ARRAY: | 5450 | case MHD_OPTION_ARRAY: |
5404 | case MHD_OPTION_HTTPS_CERT_CALLBACK: | 5451 | case MHD_OPTION_HTTPS_CERT_CALLBACK: |
5405 | case MHD_OPTION_HTTPS_CERT_CALLBACK2: | 5452 | case MHD_OPTION_HTTPS_CERT_CALLBACK2: |
5406 | if (MHD_YES != parse_options (daemon, | 5453 | if (MHD_YES != parse_options (daemon, |
5407 | servaddr, | 5454 | servaddr, |
5408 | opt, | 5455 | opt, |
5409 | oa[i].ptr_value, | 5456 | oa[i].ptr_value, |
5410 | MHD_OPTION_END)) | 5457 | MHD_OPTION_END)) |
5411 | return MHD_NO; | 5458 | return MHD_NO; |
5412 | break; | 5459 | break; |
5413 | /* all options taking two pointers */ | 5460 | /* all options taking two pointers */ |
5414 | case MHD_OPTION_NOTIFY_COMPLETED: | 5461 | case MHD_OPTION_NOTIFY_COMPLETED: |
5415 | case MHD_OPTION_NOTIFY_CONNECTION: | 5462 | case MHD_OPTION_NOTIFY_CONNECTION: |
5416 | case MHD_OPTION_URI_LOG_CALLBACK: | 5463 | case MHD_OPTION_URI_LOG_CALLBACK: |
5417 | case MHD_OPTION_EXTERNAL_LOGGER: | 5464 | case MHD_OPTION_EXTERNAL_LOGGER: |
5418 | case MHD_OPTION_UNESCAPE_CALLBACK: | ||
5419 | case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: | ||
5420 | if (MHD_YES != parse_options (daemon, | ||
5421 | servaddr, | ||
5422 | opt, | ||
5423 | (void *) oa[i].value, | ||
5424 | oa[i].ptr_value, | ||
5425 | MHD_OPTION_END)) | ||
5426 | return MHD_NO; | ||
5427 | break; | ||
5428 | /* options taking size_t-number followed by pointer */ | ||
5429 | case MHD_OPTION_DIGEST_AUTH_RANDOM: | ||
5430 | if (MHD_YES != parse_options (daemon, | ||
5431 | servaddr, | ||
5432 | opt, | ||
5433 | (size_t) oa[i].value, | ||
5434 | oa[i].ptr_value, | ||
5435 | MHD_OPTION_END)) | ||
5436 | return MHD_NO; | ||
5437 | break; | ||
5438 | default: | ||
5439 | return MHD_NO; | ||
5440 | } | ||
5441 | i++; | ||
5442 | } | ||
5443 | break; | ||
5444 | case MHD_OPTION_UNESCAPE_CALLBACK: | 5465 | case MHD_OPTION_UNESCAPE_CALLBACK: |
5445 | daemon->unescape_callback = va_arg (ap, | 5466 | case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: |
5446 | UnescapeCallback); | 5467 | if (MHD_YES != parse_options (daemon, |
5447 | daemon->unescape_callback_cls = va_arg (ap, | 5468 | servaddr, |
5448 | void *); | 5469 | opt, |
5470 | (void *) oa[i].value, | ||
5471 | oa[i].ptr_value, | ||
5472 | MHD_OPTION_END)) | ||
5473 | return MHD_NO; | ||
5449 | break; | 5474 | break; |
5475 | /* options taking size_t-number followed by pointer */ | ||
5476 | case MHD_OPTION_DIGEST_AUTH_RANDOM: | ||
5477 | if (MHD_YES != parse_options (daemon, | ||
5478 | servaddr, | ||
5479 | opt, | ||
5480 | (size_t) oa[i].value, | ||
5481 | oa[i].ptr_value, | ||
5482 | MHD_OPTION_END)) | ||
5483 | return MHD_NO; | ||
5484 | break; | ||
5485 | default: | ||
5486 | return MHD_NO; | ||
5487 | } | ||
5488 | i++; | ||
5489 | } | ||
5490 | break; | ||
5491 | case MHD_OPTION_UNESCAPE_CALLBACK: | ||
5492 | daemon->unescape_callback = va_arg (ap, | ||
5493 | UnescapeCallback); | ||
5494 | daemon->unescape_callback_cls = va_arg (ap, | ||
5495 | void *); | ||
5496 | break; | ||
5450 | #ifdef HTTPS_SUPPORT | 5497 | #ifdef HTTPS_SUPPORT |
5451 | case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: | 5498 | case MHD_OPTION_GNUTLS_PSK_CRED_HANDLER: |
5452 | #if GNUTLS_VERSION_MAJOR >= 3 | 5499 | #if GNUTLS_VERSION_MAJOR >= 3 |
5453 | daemon->cred_callback = va_arg (ap, | 5500 | daemon->cred_callback = va_arg (ap, |
5454 | MHD_PskServerCredentialsCallback); | 5501 | MHD_PskServerCredentialsCallback); |
5455 | daemon->cred_callback_cls = va_arg (ap, | 5502 | daemon->cred_callback_cls = va_arg (ap, |
5456 | void *); | 5503 | void *); |
5457 | break; | 5504 | break; |
5458 | #else | 5505 | #else |
5459 | MHD_DLOG (daemon, | 5506 | MHD_DLOG (daemon, |
5460 | _("MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"), | 5507 | _ ( |
5461 | opt); | 5508 | "MHD HTTPS option %d passed to MHD compiled without GNUtls >= 3\n"), |
5462 | return MHD_NO; | 5509 | opt); |
5510 | return MHD_NO; | ||
5463 | #endif | 5511 | #endif |
5464 | #endif /* HTTPS_SUPPORT */ | 5512 | #endif /* HTTPS_SUPPORT */ |
5465 | default: | 5513 | default: |
5466 | #ifdef HAVE_MESSAGES | 5514 | #ifdef HAVE_MESSAGES |
5467 | if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) && | 5515 | if ( ( (opt >= MHD_OPTION_HTTPS_MEM_KEY) && |
5468 | (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) || | 5516 | (opt <= MHD_OPTION_HTTPS_PRIORITIES) ) || |
5469 | (opt == MHD_OPTION_HTTPS_MEM_TRUST) || | 5517 | (opt == MHD_OPTION_HTTPS_MEM_TRUST) || |
5470 | (opt == MHD_OPTION_GNUTLS_PSK_CRED_HANDLER) ) | 5518 | (opt == MHD_OPTION_GNUTLS_PSK_CRED_HANDLER) ) |
5471 | { | 5519 | { |
5472 | MHD_DLOG (daemon, | 5520 | MHD_DLOG (daemon, |
5473 | _("MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"), | 5521 | _ ( |
5474 | opt); | 5522 | "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n"), |
5475 | } | 5523 | opt); |
5476 | else | 5524 | } |
5477 | { | 5525 | else |
5478 | MHD_DLOG (daemon, | 5526 | { |
5479 | _("Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"), | 5527 | MHD_DLOG (daemon, |
5480 | opt); | 5528 | _ ( |
5481 | } | 5529 | "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n"), |
5482 | #endif | 5530 | opt); |
5483 | return MHD_NO; | 5531 | } |
5484 | } | 5532 | #endif |
5533 | return MHD_NO; | ||
5485 | } | 5534 | } |
5535 | } | ||
5486 | return MHD_YES; | 5536 | return MHD_YES; |
5487 | } | 5537 | } |
5488 | 5538 | ||
@@ -5494,7 +5544,7 @@ setup_epoll_fd (struct MHD_Daemon *daemon) | |||
5494 | int fd; | 5544 | int fd; |
5495 | 5545 | ||
5496 | #ifndef HAVE_MESSAGES | 5546 | #ifndef HAVE_MESSAGES |
5497 | (void)daemon; /* Mute compiler warning. */ | 5547 | (void) daemon; /* Mute compiler warning. */ |
5498 | #endif /* ! HAVE_MESSAGES */ | 5548 | #endif /* ! HAVE_MESSAGES */ |
5499 | 5549 | ||
5500 | #ifdef USE_EPOLL_CREATE1 | 5550 | #ifdef USE_EPOLL_CREATE1 |
@@ -5503,22 +5553,22 @@ setup_epoll_fd (struct MHD_Daemon *daemon) | |||
5503 | fd = epoll_create (MAX_EVENTS); | 5553 | fd = epoll_create (MAX_EVENTS); |
5504 | #endif /* ! USE_EPOLL_CREATE1 */ | 5554 | #endif /* ! USE_EPOLL_CREATE1 */ |
5505 | if (MHD_INVALID_SOCKET == fd) | 5555 | if (MHD_INVALID_SOCKET == fd) |
5506 | { | 5556 | { |
5507 | #ifdef HAVE_MESSAGES | 5557 | #ifdef HAVE_MESSAGES |
5508 | MHD_DLOG (daemon, | 5558 | MHD_DLOG (daemon, |
5509 | _("Call to epoll_create1 failed: %s\n"), | 5559 | _ ("Call to epoll_create1 failed: %s\n"), |
5510 | MHD_socket_last_strerr_ ()); | 5560 | MHD_socket_last_strerr_ ()); |
5511 | #endif | 5561 | #endif |
5512 | return MHD_INVALID_SOCKET; | 5562 | return MHD_INVALID_SOCKET; |
5513 | } | 5563 | } |
5514 | #if !defined(USE_EPOLL_CREATE1) | 5564 | #if ! defined(USE_EPOLL_CREATE1) |
5515 | if (! MHD_socket_noninheritable_ (fd)) | 5565 | if (! MHD_socket_noninheritable_ (fd)) |
5516 | { | 5566 | { |
5517 | #ifdef HAVE_MESSAGES | 5567 | #ifdef HAVE_MESSAGES |
5518 | MHD_DLOG (daemon, | 5568 | MHD_DLOG (daemon, |
5519 | _("Failed to set noninheritable mode on epoll FD.\n")); | 5569 | _ ("Failed to set noninheritable mode on epoll FD.\n")); |
5520 | #endif | 5570 | #endif |
5521 | } | 5571 | } |
5522 | #endif /* ! USE_EPOLL_CREATE1 */ | 5572 | #endif /* ! USE_EPOLL_CREATE1 */ |
5523 | return fd; | 5573 | return fd; |
5524 | } | 5574 | } |
@@ -5544,11 +5594,11 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) | |||
5544 | return MHD_NO; | 5594 | return MHD_NO; |
5545 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 5595 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
5546 | if (0 != (MHD_ALLOW_UPGRADE & daemon->options)) | 5596 | if (0 != (MHD_ALLOW_UPGRADE & daemon->options)) |
5547 | { | 5597 | { |
5548 | daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); | 5598 | daemon->epoll_upgrade_fd = setup_epoll_fd (daemon); |
5549 | if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) | 5599 | if (MHD_INVALID_SOCKET == daemon->epoll_upgrade_fd) |
5550 | return MHD_NO; | 5600 | return MHD_NO; |
5551 | } | 5601 | } |
5552 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 5602 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
5553 | if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) || | 5603 | if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) || |
5554 | (daemon->was_quiesced) ) | 5604 | (daemon->was_quiesced) ) |
@@ -5556,35 +5606,35 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon) | |||
5556 | event.events = EPOLLIN; | 5606 | event.events = EPOLLIN; |
5557 | event.data.ptr = daemon; | 5607 | event.data.ptr = daemon; |
5558 | if (0 != epoll_ctl (daemon->epoll_fd, | 5608 | if (0 != epoll_ctl (daemon->epoll_fd, |
5559 | EPOLL_CTL_ADD, | 5609 | EPOLL_CTL_ADD, |
5560 | ls, | 5610 | ls, |
5561 | &event)) | 5611 | &event)) |
5562 | { | 5612 | { |
5563 | #ifdef HAVE_MESSAGES | 5613 | #ifdef HAVE_MESSAGES |
5564 | MHD_DLOG (daemon, | 5614 | MHD_DLOG (daemon, |
5565 | _("Call to epoll_ctl failed: %s\n"), | 5615 | _ ("Call to epoll_ctl failed: %s\n"), |
5566 | MHD_socket_last_strerr_ ()); | 5616 | MHD_socket_last_strerr_ ()); |
5567 | #endif | 5617 | #endif |
5568 | return MHD_NO; | 5618 | return MHD_NO; |
5569 | } | 5619 | } |
5570 | daemon->listen_socket_in_epoll = true; | 5620 | daemon->listen_socket_in_epoll = true; |
5571 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 5621 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
5622 | { | ||
5623 | event.events = EPOLLIN; | ||
5624 | event.data.ptr = (void *) epoll_itc_marker; | ||
5625 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
5626 | EPOLL_CTL_ADD, | ||
5627 | MHD_itc_r_fd_ (daemon->itc), | ||
5628 | &event)) | ||
5572 | { | 5629 | { |
5573 | event.events = EPOLLIN; | ||
5574 | event.data.ptr = (void *) epoll_itc_marker; | ||
5575 | if (0 != epoll_ctl (daemon->epoll_fd, | ||
5576 | EPOLL_CTL_ADD, | ||
5577 | MHD_itc_r_fd_ (daemon->itc), | ||
5578 | &event)) | ||
5579 | { | ||
5580 | #ifdef HAVE_MESSAGES | 5630 | #ifdef HAVE_MESSAGES |
5581 | MHD_DLOG (daemon, | 5631 | MHD_DLOG (daemon, |
5582 | _("Call to epoll_ctl failed: %s\n"), | 5632 | _ ("Call to epoll_ctl failed: %s\n"), |
5583 | MHD_socket_last_strerr_ ()); | 5633 | MHD_socket_last_strerr_ ()); |
5584 | #endif | 5634 | #endif |
5585 | return MHD_NO; | 5635 | return MHD_NO; |
5586 | } | ||
5587 | } | 5636 | } |
5637 | } | ||
5588 | return MHD_YES; | 5638 | return MHD_YES; |
5589 | } | 5639 | } |
5590 | #endif | 5640 | #endif |
@@ -5618,7 +5668,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
5618 | void *apc_cls, | 5668 | void *apc_cls, |
5619 | MHD_AccessHandlerCallback dh, | 5669 | MHD_AccessHandlerCallback dh, |
5620 | void *dh_cls, | 5670 | void *dh_cls, |
5621 | va_list ap) | 5671 | va_list ap) |
5622 | { | 5672 | { |
5623 | const MHD_SCKT_OPT_BOOL_ on = 1; | 5673 | const MHD_SCKT_OPT_BOOL_ on = 1; |
5624 | struct MHD_Daemon *daemon; | 5674 | struct MHD_Daemon *daemon; |
@@ -5635,7 +5685,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
5635 | enum MHD_FLAG eflags; /* same type as in MHD_Daemon */ | 5685 | enum MHD_FLAG eflags; /* same type as in MHD_Daemon */ |
5636 | enum MHD_FLAG *pflags; | 5686 | enum MHD_FLAG *pflags; |
5637 | 5687 | ||
5638 | MHD_check_global_init_(); | 5688 | MHD_check_global_init_ (); |
5639 | eflags = (enum MHD_FLAG) flags; | 5689 | eflags = (enum MHD_FLAG) flags; |
5640 | pflags = &eflags; | 5690 | pflags = &eflags; |
5641 | #ifndef HAVE_INET6 | 5691 | #ifndef HAVE_INET6 |
@@ -5659,56 +5709,61 @@ MHD_start_daemon_va (unsigned int flags, | |||
5659 | return NULL; | 5709 | return NULL; |
5660 | #endif | 5710 | #endif |
5661 | if (0 != (*pflags & MHD_ALLOW_UPGRADE)) | 5711 | if (0 != (*pflags & MHD_ALLOW_UPGRADE)) |
5662 | { | 5712 | { |
5663 | #ifdef UPGRADE_SUPPORT | 5713 | #ifdef UPGRADE_SUPPORT |
5664 | *pflags |= MHD_ALLOW_SUSPEND_RESUME; | 5714 | *pflags |= MHD_ALLOW_SUSPEND_RESUME; |
5665 | #else /* ! UPGRADE_SUPPORT */ | 5715 | #else /* ! UPGRADE_SUPPORT */ |
5666 | return NULL; | 5716 | return NULL; |
5667 | #endif /* ! UPGRADE_SUPPORT */ | 5717 | #endif /* ! UPGRADE_SUPPORT */ |
5668 | } | 5718 | } |
5669 | if (NULL == dh) | 5719 | if (NULL == dh) |
5670 | return NULL; | 5720 | return NULL; |
5671 | 5721 | ||
5672 | /* Check for invalid combinations of flags. */ | 5722 | /* Check for invalid combinations of flags. */ |
5673 | if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) || | 5723 | if ( ((0 != (*pflags & MHD_USE_POLL)) && (0 != (*pflags & MHD_USE_EPOLL))) || |
5674 | ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION))) || | 5724 | ((0 != (*pflags & MHD_USE_EPOLL)) && (0 != (*pflags |
5725 | & | ||
5726 | MHD_USE_THREAD_PER_CONNECTION))) | ||
5727 | || | ||
5675 | ((0 != (*pflags & MHD_USE_POLL)) && | 5728 | ((0 != (*pflags & MHD_USE_POLL)) && |
5676 | (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION)))) || | 5729 | (0 == (*pflags & (MHD_USE_INTERNAL_POLLING_THREAD |
5677 | ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)))) ) | 5730 | | MHD_USE_THREAD_PER_CONNECTION)))) || |
5731 | ((0 != (*pflags & MHD_USE_AUTO)) && (0 != (*pflags & (MHD_USE_POLL | ||
5732 | | MHD_USE_EPOLL)))) ) | ||
5678 | return NULL; | 5733 | return NULL; |
5679 | 5734 | ||
5680 | if (0 != (*pflags & MHD_USE_AUTO)) | 5735 | if (0 != (*pflags & MHD_USE_AUTO)) |
5736 | { | ||
5737 | if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) | ||
5681 | { | 5738 | { |
5682 | if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) | 5739 | /* Thread per connection with internal polling thread. */ |
5683 | { | ||
5684 | /* Thread per connection with internal polling thread. */ | ||
5685 | #ifdef HAVE_POLL | 5740 | #ifdef HAVE_POLL |
5686 | *pflags |= MHD_USE_POLL; | 5741 | *pflags |= MHD_USE_POLL; |
5687 | #else /* ! HAVE_POLL */ | 5742 | #else /* ! HAVE_POLL */ |
5688 | /* use select() - do not modify flags */ | 5743 | /* use select() - do not modify flags */ |
5689 | #endif /* ! HAVE_POLL */ | 5744 | #endif /* ! HAVE_POLL */ |
5690 | } | 5745 | } |
5691 | else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) | 5746 | else if (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) |
5692 | { | 5747 | { |
5693 | /* Internal polling thread. */ | 5748 | /* Internal polling thread. */ |
5694 | #if defined(EPOLL_SUPPORT) | 5749 | #if defined(EPOLL_SUPPORT) |
5695 | *pflags |= MHD_USE_EPOLL; | 5750 | *pflags |= MHD_USE_EPOLL; |
5696 | #elif defined(HAVE_POLL) | 5751 | #elif defined(HAVE_POLL) |
5697 | *pflags |= MHD_USE_POLL; | 5752 | *pflags |= MHD_USE_POLL; |
5698 | #else /* !HAVE_POLL && !EPOLL_SUPPORT */ | 5753 | #else /* !HAVE_POLL && !EPOLL_SUPPORT */ |
5699 | /* use select() - do not modify flags */ | 5754 | /* use select() - do not modify flags */ |
5700 | #endif /* !HAVE_POLL && !EPOLL_SUPPORT */ | 5755 | #endif /* !HAVE_POLL && !EPOLL_SUPPORT */ |
5701 | } | 5756 | } |
5702 | else | 5757 | else |
5703 | { | 5758 | { |
5704 | /* Internal threads are not used - "external" polling mode. */ | 5759 | /* Internal threads are not used - "external" polling mode. */ |
5705 | #if defined(EPOLL_SUPPORT) | 5760 | #if defined(EPOLL_SUPPORT) |
5706 | *pflags |= MHD_USE_EPOLL; | 5761 | *pflags |= MHD_USE_EPOLL; |
5707 | #else /* ! EPOLL_SUPPORT */ | 5762 | #else /* ! EPOLL_SUPPORT */ |
5708 | /* use select() - do not modify flags */ | 5763 | /* use select() - do not modify flags */ |
5709 | #endif /* ! EPOLL_SUPPORT */ | 5764 | #endif /* ! EPOLL_SUPPORT */ |
5710 | } | ||
5711 | } | 5765 | } |
5766 | } | ||
5712 | 5767 | ||
5713 | if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon)))) | 5768 | if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon)))) |
5714 | return NULL; | 5769 | return NULL; |
@@ -5722,17 +5777,18 @@ MHD_start_daemon_va (unsigned int flags, | |||
5722 | #ifdef HTTPS_SUPPORT | 5777 | #ifdef HTTPS_SUPPORT |
5723 | daemon->priority_cache = NULL; | 5778 | daemon->priority_cache = NULL; |
5724 | if (0 != (*pflags & MHD_USE_TLS)) | 5779 | if (0 != (*pflags & MHD_USE_TLS)) |
5725 | { | 5780 | { |
5726 | gnutls_priority_init (&daemon->priority_cache, | 5781 | gnutls_priority_init (&daemon->priority_cache, |
5727 | "NORMAL", | 5782 | "NORMAL", |
5728 | NULL); | 5783 | NULL); |
5729 | } | 5784 | } |
5730 | #endif /* HTTPS_SUPPORT */ | 5785 | #endif /* HTTPS_SUPPORT */ |
5731 | daemon->listen_fd = MHD_INVALID_SOCKET; | 5786 | daemon->listen_fd = MHD_INVALID_SOCKET; |
5732 | daemon->listening_address_reuse = 0; | 5787 | daemon->listening_address_reuse = 0; |
5733 | daemon->options = *pflags; | 5788 | daemon->options = *pflags; |
5734 | pflags = &daemon->options; | 5789 | pflags = &daemon->options; |
5735 | daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 : 0; | 5790 | daemon->strict_for_client = (0 != (*pflags & MHD_USE_PEDANTIC_CHECKS)) ? 1 : |
5791 | 0; | ||
5736 | daemon->port = port; | 5792 | daemon->port = port; |
5737 | daemon->apc = apc; | 5793 | daemon->apc = apc; |
5738 | daemon->apc_cls = apc_cls; | 5794 | daemon->apc_cls = apc_cls; |
@@ -5756,24 +5812,25 @@ MHD_start_daemon_va (unsigned int flags, | |||
5756 | #endif | 5812 | #endif |
5757 | if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) && | 5813 | if ( (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) && |
5758 | (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) ) | 5814 | (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) ) |
5759 | { | 5815 | { |
5760 | #ifdef HAVE_MESSAGES | 5816 | #ifdef HAVE_MESSAGES |
5761 | MHD_DLOG (daemon, | 5817 | MHD_DLOG (daemon, |
5762 | _("Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " | 5818 | _ ( |
5763 | "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " | 5819 | "Warning: MHD_USE_THREAD_PER_CONNECTION must be used only with " |
5764 | "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n")); | 5820 | "MHD_USE_INTERNAL_POLLING_THREAD. Flag MHD_USE_INTERNAL_POLLING_THREAD " |
5821 | "was added. Consider setting MHD_USE_INTERNAL_POLLING_THREAD explicitly.\n")); | ||
5765 | #endif | 5822 | #endif |
5766 | *pflags |= MHD_USE_INTERNAL_POLLING_THREAD; | 5823 | *pflags |= MHD_USE_INTERNAL_POLLING_THREAD; |
5767 | } | 5824 | } |
5768 | if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) | 5825 | if (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) |
5769 | *pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */ | 5826 | *pflags &= ~MHD_USE_ITC; /* useless if we are using 'external' select */ |
5770 | else | 5827 | else |
5771 | { | 5828 | { |
5772 | #ifdef HAVE_LISTEN_SHUTDOWN | 5829 | #ifdef HAVE_LISTEN_SHUTDOWN |
5773 | if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET)) | 5830 | if (0 != (*pflags & MHD_USE_NO_LISTEN_SOCKET)) |
5774 | #endif | 5831 | #endif |
5775 | *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */ | 5832 | *pflags |= MHD_USE_ITC; /* yes, must use ITC to signal thread */ |
5776 | } | 5833 | } |
5777 | #ifdef DAUTH_SUPPORT | 5834 | #ifdef DAUTH_SUPPORT |
5778 | daemon->digest_auth_rand_size = 0; | 5835 | daemon->digest_auth_rand_size = 0; |
5779 | daemon->digest_auth_random = NULL; | 5836 | daemon->digest_auth_random = NULL; |
@@ -5781,24 +5838,24 @@ MHD_start_daemon_va (unsigned int flags, | |||
5781 | #endif | 5838 | #endif |
5782 | #ifdef HTTPS_SUPPORT | 5839 | #ifdef HTTPS_SUPPORT |
5783 | if (0 != (*pflags & MHD_USE_TLS)) | 5840 | if (0 != (*pflags & MHD_USE_TLS)) |
5784 | { | 5841 | { |
5785 | daemon->cred_type = GNUTLS_CRD_CERTIFICATE; | 5842 | daemon->cred_type = GNUTLS_CRD_CERTIFICATE; |
5786 | } | 5843 | } |
5787 | #endif /* HTTPS_SUPPORT */ | 5844 | #endif /* HTTPS_SUPPORT */ |
5788 | 5845 | ||
5789 | 5846 | ||
5790 | if (MHD_YES != parse_options_va (daemon, | 5847 | if (MHD_YES != parse_options_va (daemon, |
5791 | &servaddr, | 5848 | &servaddr, |
5792 | ap)) | 5849 | ap)) |
5793 | { | 5850 | { |
5794 | #ifdef HTTPS_SUPPORT | 5851 | #ifdef HTTPS_SUPPORT |
5795 | if ( (0 != (*pflags & MHD_USE_TLS)) && | 5852 | if ( (0 != (*pflags & MHD_USE_TLS)) && |
5796 | (NULL != daemon->priority_cache) ) | 5853 | (NULL != daemon->priority_cache) ) |
5797 | gnutls_priority_deinit (daemon->priority_cache); | 5854 | gnutls_priority_deinit (daemon->priority_cache); |
5798 | #endif /* HTTPS_SUPPORT */ | 5855 | #endif /* HTTPS_SUPPORT */ |
5799 | free (daemon); | 5856 | free (daemon); |
5800 | return NULL; | 5857 | return NULL; |
5801 | } | 5858 | } |
5802 | 5859 | ||
5803 | if ( (NULL != daemon->notify_completed) && | 5860 | if ( (NULL != daemon->notify_completed) && |
5804 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ) | 5861 | (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ) |
@@ -5807,7 +5864,7 @@ MHD_start_daemon_va (unsigned int flags, | |||
5807 | #ifndef NDEBUG | 5864 | #ifndef NDEBUG |
5808 | #ifdef HAVE_MESSAGES | 5865 | #ifdef HAVE_MESSAGES |
5809 | MHD_DLOG (daemon, | 5866 | MHD_DLOG (daemon, |
5810 | _("Using debug build of libmicrohttpd.\n") ); | 5867 | _ ("Using debug build of libmicrohttpd.\n") ); |
5811 | #endif /* HAVE_MESSAGES */ | 5868 | #endif /* HAVE_MESSAGES */ |
5812 | #endif /* ! NDEBUG */ | 5869 | #endif /* ! NDEBUG */ |
5813 | 5870 | ||
@@ -5816,466 +5873,471 @@ MHD_start_daemon_va (unsigned int flags, | |||
5816 | && (0 == daemon->worker_pool_size) | 5873 | && (0 == daemon->worker_pool_size) |
5817 | #endif | 5874 | #endif |
5818 | ) | 5875 | ) |
5876 | { | ||
5877 | if (! MHD_itc_init_ (daemon->itc)) | ||
5819 | { | 5878 | { |
5820 | if (! MHD_itc_init_ (daemon->itc)) | ||
5821 | { | ||
5822 | #ifdef HAVE_MESSAGES | 5879 | #ifdef HAVE_MESSAGES |
5823 | MHD_DLOG (daemon, | 5880 | MHD_DLOG (daemon, |
5824 | _("Failed to create inter-thread communication channel: %s\n"), | 5881 | _ ("Failed to create inter-thread communication channel: %s\n"), |
5825 | MHD_itc_last_strerror_ ()); | 5882 | MHD_itc_last_strerror_ ()); |
5826 | #endif | 5883 | #endif |
5827 | #ifdef HTTPS_SUPPORT | 5884 | #ifdef HTTPS_SUPPORT |
5828 | if (NULL != daemon->priority_cache) | 5885 | if (NULL != daemon->priority_cache) |
5829 | gnutls_priority_deinit (daemon->priority_cache); | 5886 | gnutls_priority_deinit (daemon->priority_cache); |
5830 | #endif /* HTTPS_SUPPORT */ | 5887 | #endif /* HTTPS_SUPPORT */ |
5831 | free (daemon); | 5888 | free (daemon); |
5832 | return NULL; | 5889 | return NULL; |
5833 | } | 5890 | } |
5834 | if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) && | 5891 | if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) && |
5835 | (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (daemon->itc), | 5892 | (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (daemon->itc), |
5836 | NULL)) ) | 5893 | NULL)) ) |
5837 | { | 5894 | { |
5838 | #ifdef HAVE_MESSAGES | 5895 | #ifdef HAVE_MESSAGES |
5839 | MHD_DLOG (daemon, | 5896 | MHD_DLOG (daemon, |
5840 | _("file descriptor for inter-thread communication channel exceeds maximum value\n")); | 5897 | _ ( |
5898 | "file descriptor for inter-thread communication channel exceeds maximum value\n")); | ||
5841 | #endif | 5899 | #endif |
5842 | MHD_itc_destroy_chk_ (daemon->itc); | 5900 | MHD_itc_destroy_chk_ (daemon->itc); |
5843 | #ifdef HTTPS_SUPPORT | 5901 | #ifdef HTTPS_SUPPORT |
5844 | if (NULL != daemon->priority_cache) | 5902 | if (NULL != daemon->priority_cache) |
5845 | gnutls_priority_deinit (daemon->priority_cache); | 5903 | gnutls_priority_deinit (daemon->priority_cache); |
5846 | #endif /* HTTPS_SUPPORT */ | 5904 | #endif /* HTTPS_SUPPORT */ |
5847 | free (daemon); | 5905 | free (daemon); |
5848 | return NULL; | 5906 | return NULL; |
5849 | } | ||
5850 | } | 5907 | } |
5908 | } | ||
5851 | 5909 | ||
5852 | #ifdef DAUTH_SUPPORT | 5910 | #ifdef DAUTH_SUPPORT |
5853 | if (daemon->nonce_nc_size > 0) | 5911 | if (daemon->nonce_nc_size > 0) |
5912 | { | ||
5913 | if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) | ||
5914 | / sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size) | ||
5854 | { | 5915 | { |
5855 | if ( ( (size_t) (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc))) / | ||
5856 | sizeof(struct MHD_NonceNc) != daemon->nonce_nc_size) | ||
5857 | { | ||
5858 | #ifdef HAVE_MESSAGES | 5916 | #ifdef HAVE_MESSAGES |
5859 | MHD_DLOG (daemon, | 5917 | MHD_DLOG (daemon, |
5860 | _("Specified value for NC_SIZE too large\n")); | 5918 | _ ("Specified value for NC_SIZE too large\n")); |
5861 | #endif | 5919 | #endif |
5862 | #ifdef HTTPS_SUPPORT | 5920 | #ifdef HTTPS_SUPPORT |
5863 | if (0 != (*pflags & MHD_USE_TLS)) | 5921 | if (0 != (*pflags & MHD_USE_TLS)) |
5864 | gnutls_priority_deinit (daemon->priority_cache); | 5922 | gnutls_priority_deinit (daemon->priority_cache); |
5865 | #endif /* HTTPS_SUPPORT */ | 5923 | #endif /* HTTPS_SUPPORT */ |
5866 | free (daemon); | 5924 | free (daemon); |
5867 | return NULL; | 5925 | return NULL; |
5868 | } | 5926 | } |
5869 | daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)); | 5927 | daemon->nnc = malloc (daemon->nonce_nc_size * sizeof (struct MHD_NonceNc)); |
5870 | if (NULL == daemon->nnc) | 5928 | if (NULL == daemon->nnc) |
5871 | { | 5929 | { |
5872 | #ifdef HAVE_MESSAGES | 5930 | #ifdef HAVE_MESSAGES |
5873 | MHD_DLOG (daemon, | 5931 | MHD_DLOG (daemon, |
5874 | _("Failed to allocate memory for nonce-nc map: %s\n"), | 5932 | _ ("Failed to allocate memory for nonce-nc map: %s\n"), |
5875 | MHD_strerror_ (errno)); | 5933 | MHD_strerror_ (errno)); |
5876 | #endif | 5934 | #endif |
5877 | #ifdef HTTPS_SUPPORT | 5935 | #ifdef HTTPS_SUPPORT |
5878 | if (0 != (*pflags & MHD_USE_TLS)) | 5936 | if (0 != (*pflags & MHD_USE_TLS)) |
5879 | gnutls_priority_deinit (daemon->priority_cache); | 5937 | gnutls_priority_deinit (daemon->priority_cache); |
5880 | #endif /* HTTPS_SUPPORT */ | 5938 | #endif /* HTTPS_SUPPORT */ |
5881 | free (daemon); | 5939 | free (daemon); |
5882 | return NULL; | 5940 | return NULL; |
5883 | } | ||
5884 | } | 5941 | } |
5942 | } | ||
5885 | 5943 | ||
5886 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 5944 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
5887 | if (! MHD_mutex_init_ (&daemon->nnc_lock)) | 5945 | if (! MHD_mutex_init_ (&daemon->nnc_lock)) |
5888 | { | 5946 | { |
5889 | #ifdef HAVE_MESSAGES | 5947 | #ifdef HAVE_MESSAGES |
5890 | MHD_DLOG (daemon, | 5948 | MHD_DLOG (daemon, |
5891 | _("MHD failed to initialize nonce-nc mutex\n")); | 5949 | _ ("MHD failed to initialize nonce-nc mutex\n")); |
5892 | #endif | 5950 | #endif |
5893 | #ifdef HTTPS_SUPPORT | 5951 | #ifdef HTTPS_SUPPORT |
5894 | if (0 != (*pflags & MHD_USE_TLS)) | 5952 | if (0 != (*pflags & MHD_USE_TLS)) |
5895 | gnutls_priority_deinit (daemon->priority_cache); | 5953 | gnutls_priority_deinit (daemon->priority_cache); |
5896 | #endif /* HTTPS_SUPPORT */ | 5954 | #endif /* HTTPS_SUPPORT */ |
5897 | free (daemon->nnc); | 5955 | free (daemon->nnc); |
5898 | free (daemon); | 5956 | free (daemon); |
5899 | return NULL; | 5957 | return NULL; |
5900 | } | 5958 | } |
5901 | #endif | 5959 | #endif |
5902 | #endif | 5960 | #endif |
5903 | 5961 | ||
5904 | /* Thread pooling currently works only with internal select thread mode */ | 5962 | /* Thread pooling currently works only with internal select thread mode */ |
5905 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 5963 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
5906 | if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) && | 5964 | if ( (0 == (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) && |
5907 | (daemon->worker_pool_size > 0) ) | 5965 | (daemon->worker_pool_size > 0) ) |
5908 | { | 5966 | { |
5909 | #ifdef HAVE_MESSAGES | 5967 | #ifdef HAVE_MESSAGES |
5910 | MHD_DLOG (daemon, | 5968 | MHD_DLOG (daemon, |
5911 | _("MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n")); | 5969 | _ ( |
5970 | "MHD thread pooling only works with MHD_USE_INTERNAL_POLLING_THREAD\n")); | ||
5912 | #endif | 5971 | #endif |
5913 | goto free_and_fail; | 5972 | goto free_and_fail; |
5914 | } | 5973 | } |
5915 | #endif | 5974 | #endif |
5916 | if ( (MHD_INVALID_SOCKET == daemon->listen_fd) && | 5975 | if ( (MHD_INVALID_SOCKET == daemon->listen_fd) && |
5917 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) | 5976 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) |
5918 | { | 5977 | { |
5919 | /* try to open listen socket */ | 5978 | /* try to open listen socket */ |
5920 | int domain; | 5979 | int domain; |
5921 | 5980 | ||
5922 | #ifdef HAVE_INET6 | 5981 | #ifdef HAVE_INET6 |
5923 | domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET; | 5982 | domain = (*pflags & MHD_USE_IPv6) ? PF_INET6 : PF_INET; |
5924 | #else /* ! HAVE_INET6 */ | 5983 | #else /* ! HAVE_INET6 */ |
5925 | if (*pflags & MHD_USE_IPv6) | 5984 | if (*pflags & MHD_USE_IPv6) |
5926 | goto free_and_fail; | 5985 | goto free_and_fail; |
5927 | domain = PF_INET; | 5986 | domain = PF_INET; |
5928 | #endif /* ! HAVE_INET6 */ | 5987 | #endif /* ! HAVE_INET6 */ |
5929 | 5988 | ||
5930 | listen_fd = MHD_socket_create_listen_(domain); | 5989 | listen_fd = MHD_socket_create_listen_ (domain); |
5931 | if (MHD_INVALID_SOCKET == listen_fd) | 5990 | if (MHD_INVALID_SOCKET == listen_fd) |
5932 | { | 5991 | { |
5933 | #ifdef HAVE_MESSAGES | 5992 | #ifdef HAVE_MESSAGES |
5934 | MHD_DLOG (daemon, | 5993 | MHD_DLOG (daemon, |
5935 | _("Failed to create socket for listening: %s\n"), | 5994 | _ ("Failed to create socket for listening: %s\n"), |
5936 | MHD_socket_last_strerr_ ()); | 5995 | MHD_socket_last_strerr_ ()); |
5937 | #endif | 5996 | #endif |
5938 | goto free_and_fail; | 5997 | goto free_and_fail; |
5939 | } | 5998 | } |
5940 | 5999 | ||
5941 | /* Apply the socket options according to listening_address_reuse. */ | 6000 | /* Apply the socket options according to listening_address_reuse. */ |
5942 | if (0 == daemon->listening_address_reuse) | 6001 | if (0 == daemon->listening_address_reuse) |
5943 | { | 6002 | { |
5944 | #ifndef MHD_WINSOCK_SOCKETS | 6003 | #ifndef MHD_WINSOCK_SOCKETS |
5945 | /* No user requirement, use "traditional" default SO_REUSEADDR | 6004 | /* No user requirement, use "traditional" default SO_REUSEADDR |
5946 | * on non-W32 platforms, and do not fail if it doesn't work. | 6005 | * on non-W32 platforms, and do not fail if it doesn't work. |
5947 | * Don't use it on W32, because on W32 it will allow multiple | 6006 | * Don't use it on W32, because on W32 it will allow multiple |
5948 | * bind to the same address:port, like SO_REUSEPORT on others. */ | 6007 | * bind to the same address:port, like SO_REUSEPORT on others. */ |
5949 | if (0 > setsockopt (listen_fd, | 6008 | if (0 > setsockopt (listen_fd, |
5950 | SOL_SOCKET, | 6009 | SOL_SOCKET, |
5951 | SO_REUSEADDR, | 6010 | SO_REUSEADDR, |
5952 | (void*)&on, sizeof (on))) | 6011 | (void*) &on, sizeof (on))) |
5953 | { | 6012 | { |
5954 | #ifdef HAVE_MESSAGES | 6013 | #ifdef HAVE_MESSAGES |
5955 | MHD_DLOG (daemon, | 6014 | MHD_DLOG (daemon, |
5956 | _("setsockopt failed: %s\n"), | 6015 | _ ("setsockopt failed: %s\n"), |
5957 | MHD_socket_last_strerr_ ()); | 6016 | MHD_socket_last_strerr_ ()); |
5958 | #endif | 6017 | #endif |
5959 | } | 6018 | } |
5960 | #endif /* ! MHD_WINSOCK_SOCKETS */ | 6019 | #endif /* ! MHD_WINSOCK_SOCKETS */ |
5961 | } | 6020 | } |
5962 | else if (daemon->listening_address_reuse > 0) | 6021 | else if (daemon->listening_address_reuse > 0) |
5963 | { | 6022 | { |
5964 | /* User requested to allow reusing listening address:port. */ | 6023 | /* User requested to allow reusing listening address:port. */ |
5965 | #ifndef MHD_WINSOCK_SOCKETS | 6024 | #ifndef MHD_WINSOCK_SOCKETS |
5966 | /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if | 6025 | /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if |
5967 | * it doesn't work. */ | 6026 | * it doesn't work. */ |
5968 | if (0 > setsockopt (listen_fd, | 6027 | if (0 > setsockopt (listen_fd, |
5969 | SOL_SOCKET, | 6028 | SOL_SOCKET, |
5970 | SO_REUSEADDR, | 6029 | SO_REUSEADDR, |
5971 | (void*)&on, sizeof (on))) | 6030 | (void*) &on, sizeof (on))) |
5972 | { | 6031 | { |
5973 | #ifdef HAVE_MESSAGES | 6032 | #ifdef HAVE_MESSAGES |
5974 | MHD_DLOG (daemon, | 6033 | MHD_DLOG (daemon, |
5975 | _("setsockopt failed: %s\n"), | 6034 | _ ("setsockopt failed: %s\n"), |
5976 | MHD_socket_last_strerr_ ()); | 6035 | MHD_socket_last_strerr_ ()); |
5977 | #endif | 6036 | #endif |
5978 | } | 6037 | } |
5979 | #endif /* ! MHD_WINSOCK_SOCKETS */ | 6038 | #endif /* ! MHD_WINSOCK_SOCKETS */ |
5980 | /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. | 6039 | /* Use SO_REUSEADDR on Windows and SO_REUSEPORT on most platforms. |
5981 | * Fail if SO_REUSEPORT is not defined or setsockopt fails. | 6040 | * Fail if SO_REUSEPORT is not defined or setsockopt fails. |
5982 | */ | 6041 | */ |
5983 | /* SO_REUSEADDR on W32 has the same semantics | 6042 | /* SO_REUSEADDR on W32 has the same semantics |
5984 | as SO_REUSEPORT on BSD/Linux */ | 6043 | as SO_REUSEPORT on BSD/Linux */ |
5985 | #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) | 6044 | #if defined(MHD_WINSOCK_SOCKETS) || defined(SO_REUSEPORT) |
5986 | if (0 > setsockopt (listen_fd, | 6045 | if (0 > setsockopt (listen_fd, |
5987 | SOL_SOCKET, | 6046 | SOL_SOCKET, |
5988 | #ifndef MHD_WINSOCK_SOCKETS | 6047 | #ifndef MHD_WINSOCK_SOCKETS |
5989 | SO_REUSEPORT, | 6048 | SO_REUSEPORT, |
5990 | #else /* MHD_WINSOCK_SOCKETS */ | 6049 | #else /* MHD_WINSOCK_SOCKETS */ |
5991 | SO_REUSEADDR, | 6050 | SO_REUSEADDR, |
5992 | #endif /* MHD_WINSOCK_SOCKETS */ | 6051 | #endif /* MHD_WINSOCK_SOCKETS */ |
5993 | (void *) &on, | 6052 | (void *) &on, |
5994 | sizeof (on))) | 6053 | sizeof (on))) |
5995 | { | 6054 | { |
5996 | #ifdef HAVE_MESSAGES | 6055 | #ifdef HAVE_MESSAGES |
5997 | MHD_DLOG (daemon, | 6056 | MHD_DLOG (daemon, |
5998 | _("setsockopt failed: %s\n"), | 6057 | _ ("setsockopt failed: %s\n"), |
5999 | MHD_socket_last_strerr_ ()); | 6058 | MHD_socket_last_strerr_ ()); |
6000 | #endif | 6059 | #endif |
6001 | goto free_and_fail; | 6060 | goto free_and_fail; |
6002 | } | 6061 | } |
6003 | #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ | 6062 | #else /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ |
6004 | /* we're supposed to allow address:port re-use, but | 6063 | /* we're supposed to allow address:port re-use, but |
6005 | on this platform we cannot; fail hard */ | 6064 | on this platform we cannot; fail hard */ |
6006 | #ifdef HAVE_MESSAGES | 6065 | #ifdef HAVE_MESSAGES |
6007 | MHD_DLOG (daemon, | 6066 | MHD_DLOG (daemon, |
6008 | _("Cannot allow listening address reuse: SO_REUSEPORT not defined\n")); | 6067 | _ ( |
6068 | "Cannot allow listening address reuse: SO_REUSEPORT not defined\n")); | ||
6009 | #endif | 6069 | #endif |
6010 | goto free_and_fail; | 6070 | goto free_and_fail; |
6011 | #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ | 6071 | #endif /* !MHD_WINSOCK_SOCKETS && !SO_REUSEPORT */ |
6012 | } | 6072 | } |
6013 | else /* if (daemon->listening_address_reuse < 0) */ | 6073 | else /* if (daemon->listening_address_reuse < 0) */ |
6014 | { | 6074 | { |
6015 | /* User requested to disallow reusing listening address:port. | 6075 | /* User requested to disallow reusing listening address:port. |
6016 | * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE | 6076 | * Do nothing except for Windows where SO_EXCLUSIVEADDRUSE |
6017 | * is used and Solaris with SO_EXCLBIND. | 6077 | * is used and Solaris with SO_EXCLBIND. |
6018 | * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE | 6078 | * Fail if MHD was compiled for W32 without SO_EXCLUSIVEADDRUSE |
6019 | * or setsockopt fails. | 6079 | * or setsockopt fails. |
6020 | */ | 6080 | */ |
6021 | #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ | 6081 | #if (defined(MHD_WINSOCK_SOCKETS) && defined(SO_EXCLUSIVEADDRUSE)) || \ |
6022 | (defined(__sun) && defined(SO_EXCLBIND)) | 6082 | (defined(__sun) && defined(SO_EXCLBIND)) |
6023 | if (0 > setsockopt (listen_fd, | 6083 | if (0 > setsockopt (listen_fd, |
6024 | SOL_SOCKET, | 6084 | SOL_SOCKET, |
6025 | #ifdef SO_EXCLUSIVEADDRUSE | 6085 | #ifdef SO_EXCLUSIVEADDRUSE |
6026 | SO_EXCLUSIVEADDRUSE, | 6086 | SO_EXCLUSIVEADDRUSE, |
6027 | #else /* SO_EXCLBIND */ | 6087 | #else /* SO_EXCLBIND */ |
6028 | SO_EXCLBIND, | 6088 | SO_EXCLBIND, |
6029 | #endif /* SO_EXCLBIND */ | 6089 | #endif /* SO_EXCLBIND */ |
6030 | (void *) &on, | 6090 | (void *) &on, |
6031 | sizeof (on))) | 6091 | sizeof (on))) |
6032 | { | 6092 | { |
6033 | #ifdef HAVE_MESSAGES | 6093 | #ifdef HAVE_MESSAGES |
6034 | MHD_DLOG (daemon, | 6094 | MHD_DLOG (daemon, |
6035 | _("setsockopt failed: %s\n"), | 6095 | _ ("setsockopt failed: %s\n"), |
6036 | MHD_socket_last_strerr_ ()); | 6096 | MHD_socket_last_strerr_ ()); |
6037 | #endif | 6097 | #endif |
6038 | goto free_and_fail; | 6098 | goto free_and_fail; |
6039 | } | 6099 | } |
6040 | #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ | 6100 | #elif defined(MHD_WINSOCK_SOCKETS) /* SO_EXCLUSIVEADDRUSE not defined on W32? */ |
6041 | #ifdef HAVE_MESSAGES | 6101 | #ifdef HAVE_MESSAGES |
6042 | MHD_DLOG (daemon, | 6102 | MHD_DLOG (daemon, |
6043 | _("Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n")); | 6103 | _ ( |
6104 | "Cannot disallow listening address reuse: SO_EXCLUSIVEADDRUSE not defined\n")); | ||
6044 | #endif | 6105 | #endif |
6045 | goto free_and_fail; | 6106 | goto free_and_fail; |
6046 | #endif /* MHD_WINSOCK_SOCKETS */ | 6107 | #endif /* MHD_WINSOCK_SOCKETS */ |
6047 | } | 6108 | } |
6048 | 6109 | ||
6049 | /* check for user supplied sockaddr */ | 6110 | /* check for user supplied sockaddr */ |
6050 | #if HAVE_INET6 | 6111 | #if HAVE_INET6 |
6051 | if (0 != (*pflags & MHD_USE_IPv6)) | 6112 | if (0 != (*pflags & MHD_USE_IPv6)) |
6052 | addrlen = sizeof (struct sockaddr_in6); | 6113 | addrlen = sizeof (struct sockaddr_in6); |
6053 | else | 6114 | else |
6054 | #endif | 6115 | #endif |
6055 | addrlen = sizeof (struct sockaddr_in); | 6116 | addrlen = sizeof (struct sockaddr_in); |
6056 | if (NULL == servaddr) | 6117 | if (NULL == servaddr) |
6057 | { | 6118 | { |
6058 | #if HAVE_INET6 | 6119 | #if HAVE_INET6 |
6059 | if (0 != (*pflags & MHD_USE_IPv6)) | 6120 | if (0 != (*pflags & MHD_USE_IPv6)) |
6060 | { | 6121 | { |
6061 | #ifdef IN6ADDR_ANY_INIT | 6122 | #ifdef IN6ADDR_ANY_INIT |
6062 | static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT; | 6123 | static const struct in6_addr static_in6any = IN6ADDR_ANY_INIT; |
6063 | #endif | 6124 | #endif |
6064 | memset (&servaddr6, | 6125 | memset (&servaddr6, |
6065 | 0, | 6126 | 0, |
6066 | sizeof (struct sockaddr_in6)); | 6127 | sizeof (struct sockaddr_in6)); |
6067 | servaddr6.sin6_family = AF_INET6; | 6128 | servaddr6.sin6_family = AF_INET6; |
6068 | servaddr6.sin6_port = htons (port); | 6129 | servaddr6.sin6_port = htons (port); |
6069 | #ifdef IN6ADDR_ANY_INIT | 6130 | #ifdef IN6ADDR_ANY_INIT |
6070 | servaddr6.sin6_addr = static_in6any; | 6131 | servaddr6.sin6_addr = static_in6any; |
6071 | #endif | 6132 | #endif |
6072 | #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN | 6133 | #if HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN |
6073 | servaddr6.sin6_len = sizeof (struct sockaddr_in6); | 6134 | servaddr6.sin6_len = sizeof (struct sockaddr_in6); |
6074 | #endif | 6135 | #endif |
6075 | servaddr = (struct sockaddr *) &servaddr6; | 6136 | servaddr = (struct sockaddr *) &servaddr6; |
6076 | } | 6137 | } |
6077 | else | 6138 | else |
6078 | #endif | 6139 | #endif |
6079 | { | 6140 | { |
6080 | memset (&servaddr4, | 6141 | memset (&servaddr4, |
6081 | 0, | 6142 | 0, |
6082 | sizeof (struct sockaddr_in)); | 6143 | sizeof (struct sockaddr_in)); |
6083 | servaddr4.sin_family = AF_INET; | 6144 | servaddr4.sin_family = AF_INET; |
6084 | servaddr4.sin_port = htons (port); | 6145 | servaddr4.sin_port = htons (port); |
6085 | if (0 != INADDR_ANY) | 6146 | if (0 != INADDR_ANY) |
6086 | servaddr4.sin_addr.s_addr = htonl (INADDR_ANY); | 6147 | servaddr4.sin_addr.s_addr = htonl (INADDR_ANY); |
6087 | #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN | 6148 | #if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN |
6088 | servaddr4.sin_len = sizeof (struct sockaddr_in); | 6149 | servaddr4.sin_len = sizeof (struct sockaddr_in); |
6089 | #endif | 6150 | #endif |
6090 | servaddr = (struct sockaddr *) &servaddr4; | 6151 | servaddr = (struct sockaddr *) &servaddr4; |
6091 | } | 6152 | } |
6092 | } | 6153 | } |
6093 | daemon->listen_fd = listen_fd; | 6154 | daemon->listen_fd = listen_fd; |
6094 | 6155 | ||
6095 | if (0 != (*pflags & MHD_USE_IPv6)) | 6156 | if (0 != (*pflags & MHD_USE_IPv6)) |
6096 | { | 6157 | { |
6097 | #ifdef IPPROTO_IPV6 | 6158 | #ifdef IPPROTO_IPV6 |
6098 | #ifdef IPV6_V6ONLY | 6159 | #ifdef IPV6_V6ONLY |
6099 | /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" | 6160 | /* Note: "IPV6_V6ONLY" is declared by Windows Vista ff., see "IPPROTO_IPV6 Socket Options" |
6100 | (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); | 6161 | (http://msdn.microsoft.com/en-us/library/ms738574%28v=VS.85%29.aspx); |
6101 | and may also be missing on older POSIX systems; good luck if you have any of those, | 6162 | and may also be missing on older POSIX systems; good luck if you have any of those, |
6102 | your IPv6 socket may then also bind against IPv4 anyway... */ | 6163 | your IPv6 socket may then also bind against IPv4 anyway... */ |
6103 | const MHD_SCKT_OPT_BOOL_ v6_only = | 6164 | const MHD_SCKT_OPT_BOOL_ v6_only = |
6104 | (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK)); | 6165 | (MHD_USE_DUAL_STACK != (*pflags & MHD_USE_DUAL_STACK)); |
6105 | if (0 > setsockopt (listen_fd, | 6166 | if (0 > setsockopt (listen_fd, |
6106 | IPPROTO_IPV6, IPV6_V6ONLY, | 6167 | IPPROTO_IPV6, IPV6_V6ONLY, |
6107 | (const void *) &v6_only, | 6168 | (const void *) &v6_only, |
6108 | sizeof (v6_only))) | 6169 | sizeof (v6_only))) |
6109 | { | 6170 | { |
6110 | #ifdef HAVE_MESSAGES | 6171 | #ifdef HAVE_MESSAGES |
6111 | MHD_DLOG (daemon, | 6172 | MHD_DLOG (daemon, |
6112 | _("setsockopt failed: %s\n"), | 6173 | _ ("setsockopt failed: %s\n"), |
6113 | MHD_socket_last_strerr_ ()); | 6174 | MHD_socket_last_strerr_ ()); |
6114 | #endif | 6175 | #endif |
6115 | } | 6176 | } |
6116 | #endif | 6177 | #endif |
6117 | #endif | 6178 | #endif |
6118 | } | 6179 | } |
6119 | if (-1 == bind (listen_fd, servaddr, addrlen)) | 6180 | if (-1 == bind (listen_fd, servaddr, addrlen)) |
6120 | { | 6181 | { |
6121 | #ifdef HAVE_MESSAGES | 6182 | #ifdef HAVE_MESSAGES |
6122 | MHD_DLOG (daemon, | 6183 | MHD_DLOG (daemon, |
6123 | _("Failed to bind to port %u: %s\n"), | 6184 | _ ("Failed to bind to port %u: %s\n"), |
6124 | (unsigned int) port, | 6185 | (unsigned int) port, |
6125 | MHD_socket_last_strerr_ ()); | 6186 | MHD_socket_last_strerr_ ()); |
6126 | #endif | 6187 | #endif |
6127 | MHD_socket_close_chk_ (listen_fd); | 6188 | MHD_socket_close_chk_ (listen_fd); |
6128 | goto free_and_fail; | 6189 | goto free_and_fail; |
6129 | } | 6190 | } |
6130 | #ifdef TCP_FASTOPEN | 6191 | #ifdef TCP_FASTOPEN |
6131 | if (0 != (*pflags & MHD_USE_TCP_FASTOPEN)) | 6192 | if (0 != (*pflags & MHD_USE_TCP_FASTOPEN)) |
6193 | { | ||
6194 | if (0 == daemon->fastopen_queue_size) | ||
6195 | daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT; | ||
6196 | if (0 != setsockopt (listen_fd, | ||
6197 | IPPROTO_TCP, | ||
6198 | TCP_FASTOPEN, | ||
6199 | (const void*) &daemon->fastopen_queue_size, | ||
6200 | sizeof (daemon->fastopen_queue_size))) | ||
6132 | { | 6201 | { |
6133 | if (0 == daemon->fastopen_queue_size) | ||
6134 | daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT; | ||
6135 | if (0 != setsockopt (listen_fd, | ||
6136 | IPPROTO_TCP, | ||
6137 | TCP_FASTOPEN, | ||
6138 | (const void*)&daemon->fastopen_queue_size, | ||
6139 | sizeof (daemon->fastopen_queue_size))) | ||
6140 | { | ||
6141 | #ifdef HAVE_MESSAGES | 6202 | #ifdef HAVE_MESSAGES |
6142 | MHD_DLOG (daemon, | 6203 | MHD_DLOG (daemon, |
6143 | _("setsockopt failed: %s\n"), | 6204 | _ ("setsockopt failed: %s\n"), |
6144 | MHD_socket_last_strerr_ ()); | 6205 | MHD_socket_last_strerr_ ()); |
6145 | #endif | 6206 | #endif |
6146 | } | ||
6147 | } | 6207 | } |
6208 | } | ||
6148 | #endif | 6209 | #endif |
6149 | if (listen (listen_fd, | 6210 | if (listen (listen_fd, |
6150 | daemon->listen_backlog_size) < 0) | 6211 | daemon->listen_backlog_size) < 0) |
6151 | { | 6212 | { |
6152 | #ifdef HAVE_MESSAGES | 6213 | #ifdef HAVE_MESSAGES |
6153 | MHD_DLOG (daemon, | 6214 | MHD_DLOG (daemon, |
6154 | _("Failed to listen for connections: %s\n"), | 6215 | _ ("Failed to listen for connections: %s\n"), |
6155 | MHD_socket_last_strerr_ ()); | 6216 | MHD_socket_last_strerr_ ()); |
6156 | #endif | 6217 | #endif |
6157 | MHD_socket_close_chk_ (listen_fd); | 6218 | MHD_socket_close_chk_ (listen_fd); |
6158 | goto free_and_fail; | 6219 | goto free_and_fail; |
6159 | } | ||
6160 | } | 6220 | } |
6221 | } | ||
6161 | else | 6222 | else |
6162 | { | 6223 | { |
6163 | listen_fd = daemon->listen_fd; | 6224 | listen_fd = daemon->listen_fd; |
6164 | } | 6225 | } |
6165 | 6226 | ||
6166 | #ifdef HAVE_GETSOCKNAME | 6227 | #ifdef HAVE_GETSOCKNAME |
6167 | if ( (0 == daemon->port) && | 6228 | if ( (0 == daemon->port) && |
6168 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) | 6229 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) |
6169 | { /* Get port number. */ | 6230 | { /* Get port number. */ |
6170 | struct sockaddr_storage bindaddr; | 6231 | struct sockaddr_storage bindaddr; |
6171 | 6232 | ||
6172 | memset (&bindaddr, | 6233 | memset (&bindaddr, |
6173 | 0, | 6234 | 0, |
6174 | sizeof (struct sockaddr_storage)); | 6235 | sizeof (struct sockaddr_storage)); |
6175 | addrlen = sizeof (struct sockaddr_storage); | 6236 | addrlen = sizeof (struct sockaddr_storage); |
6176 | #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN | 6237 | #ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN |
6177 | bindaddr.ss_len = addrlen; | 6238 | bindaddr.ss_len = addrlen; |
6178 | #endif | 6239 | #endif |
6179 | if (0 != getsockname (listen_fd, | 6240 | if (0 != getsockname (listen_fd, |
6180 | (struct sockaddr *) &bindaddr, | 6241 | (struct sockaddr *) &bindaddr, |
6181 | &addrlen)) | 6242 | &addrlen)) |
6182 | { | 6243 | { |
6183 | #ifdef HAVE_MESSAGES | 6244 | #ifdef HAVE_MESSAGES |
6184 | MHD_DLOG (daemon, | 6245 | MHD_DLOG (daemon, |
6185 | _("Failed to get listen port number: %s\n"), | 6246 | _ ("Failed to get listen port number: %s\n"), |
6186 | MHD_socket_last_strerr_ ()); | 6247 | MHD_socket_last_strerr_ ()); |
6187 | #endif /* HAVE_MESSAGES */ | 6248 | #endif /* HAVE_MESSAGES */ |
6188 | } | 6249 | } |
6189 | #ifdef MHD_POSIX_SOCKETS | 6250 | #ifdef MHD_POSIX_SOCKETS |
6190 | else if (sizeof (bindaddr) < addrlen) | 6251 | else if (sizeof (bindaddr) < addrlen) |
6191 | { | 6252 | { |
6192 | /* should be impossible with `struct sockaddr_storage` */ | 6253 | /* should be impossible with `struct sockaddr_storage` */ |
6193 | #ifdef HAVE_MESSAGES | 6254 | #ifdef HAVE_MESSAGES |
6194 | MHD_DLOG (daemon, | 6255 | MHD_DLOG (daemon, |
6195 | _("Failed to get listen port number (`struct sockaddr_storage` too small!?)\n")); | 6256 | _ ( |
6257 | "Failed to get listen port number (`struct sockaddr_storage` too small!?)\n")); | ||
6196 | #endif /* HAVE_MESSAGES */ | 6258 | #endif /* HAVE_MESSAGES */ |
6197 | } | 6259 | } |
6198 | #ifndef __linux__ | 6260 | #ifndef __linux__ |
6199 | else if (0 == addrlen) | 6261 | else if (0 == addrlen) |
6200 | { | 6262 | { |
6201 | /* Many non-Linux-based platforms return zero addrlen | 6263 | /* Many non-Linux-based platforms return zero addrlen |
6202 | * for AF_UNIX sockets */ | 6264 | * for AF_UNIX sockets */ |
6203 | daemon->port = 0; /* special value for UNIX domain sockets */ | 6265 | daemon->port = 0; /* special value for UNIX domain sockets */ |
6204 | } | 6266 | } |
6205 | #endif /* __linux__ */ | 6267 | #endif /* __linux__ */ |
6206 | #endif /* MHD_POSIX_SOCKETS */ | 6268 | #endif /* MHD_POSIX_SOCKETS */ |
6207 | else | 6269 | else |
6270 | { | ||
6271 | switch (bindaddr.ss_family) | ||
6272 | { | ||
6273 | case AF_INET: | ||
6208 | { | 6274 | { |
6209 | switch (bindaddr.ss_family) | 6275 | struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr; |
6210 | { | ||
6211 | case AF_INET: | ||
6212 | { | ||
6213 | struct sockaddr_in *s4 = (struct sockaddr_in *) &bindaddr; | ||
6214 | 6276 | ||
6215 | daemon->port = ntohs (s4->sin_port); | 6277 | daemon->port = ntohs (s4->sin_port); |
6216 | break; | 6278 | break; |
6217 | } | 6279 | } |
6218 | #ifdef HAVE_INET6 | 6280 | #ifdef HAVE_INET6 |
6219 | case AF_INET6: | 6281 | case AF_INET6: |
6220 | { | 6282 | { |
6221 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr; | 6283 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) &bindaddr; |
6222 | 6284 | ||
6223 | daemon->port = ntohs(s6->sin6_port); | 6285 | daemon->port = ntohs (s6->sin6_port); |
6224 | mhd_assert (0 != (*pflags & MHD_USE_IPv6)); | 6286 | mhd_assert (0 != (*pflags & MHD_USE_IPv6)); |
6225 | break; | 6287 | break; |
6226 | } | 6288 | } |
6227 | #endif /* HAVE_INET6 */ | 6289 | #endif /* HAVE_INET6 */ |
6228 | #ifdef AF_UNIX | 6290 | #ifdef AF_UNIX |
6229 | case AF_UNIX: | 6291 | case AF_UNIX: |
6230 | daemon->port = 0; /* special value for UNIX domain sockets */ | 6292 | daemon->port = 0; /* special value for UNIX domain sockets */ |
6231 | break; | 6293 | break; |
6232 | #endif | 6294 | #endif |
6233 | default: | 6295 | default: |
6234 | #ifdef HAVE_MESSAGES | 6296 | #ifdef HAVE_MESSAGES |
6235 | MHD_DLOG (daemon, | 6297 | MHD_DLOG (daemon, |
6236 | _("Unknown address family!\n")); | 6298 | _ ("Unknown address family!\n")); |
6237 | #endif | 6299 | #endif |
6238 | daemon->port = 0; /* ugh */ | 6300 | daemon->port = 0; /* ugh */ |
6239 | break; | 6301 | break; |
6240 | } | 6302 | } |
6241 | } | ||
6242 | } | 6303 | } |
6304 | } | ||
6243 | #endif /* HAVE_GETSOCKNAME */ | 6305 | #endif /* HAVE_GETSOCKNAME */ |
6244 | if ( (MHD_INVALID_SOCKET != listen_fd) && | 6306 | if ( (MHD_INVALID_SOCKET != listen_fd) && |
6245 | (! MHD_socket_nonblocking_ (listen_fd)) ) | 6307 | (! MHD_socket_nonblocking_ (listen_fd)) ) |
6246 | { | 6308 | { |
6247 | #ifdef HAVE_MESSAGES | 6309 | #ifdef HAVE_MESSAGES |
6248 | MHD_DLOG (daemon, | 6310 | MHD_DLOG (daemon, |
6249 | _("Failed to set nonblocking mode on listening socket: %s\n"), | 6311 | _ ("Failed to set nonblocking mode on listening socket: %s\n"), |
6250 | MHD_socket_last_strerr_()); | 6312 | MHD_socket_last_strerr_ ()); |
6251 | #endif | 6313 | #endif |
6252 | if (0 != (*pflags & MHD_USE_EPOLL) | 6314 | if (0 != (*pflags & MHD_USE_EPOLL) |
6253 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6315 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6254 | || (daemon->worker_pool_size > 0) | 6316 | || (daemon->worker_pool_size > 0) |
6255 | #endif | 6317 | #endif |
6256 | ) | 6318 | ) |
6257 | { | 6319 | { |
6258 | /* Accept must be non-blocking. Multiple children may wake up | 6320 | /* Accept must be non-blocking. Multiple children may wake up |
6259 | * to handle a new connection, but only one will win the race. | 6321 | * to handle a new connection, but only one will win the race. |
6260 | * The others must immediately return. */ | 6322 | * The others must immediately return. */ |
6261 | MHD_socket_close_chk_ (listen_fd); | 6323 | MHD_socket_close_chk_ (listen_fd); |
6262 | goto free_and_fail; | 6324 | goto free_and_fail; |
6263 | } | ||
6264 | } | 6325 | } |
6326 | } | ||
6265 | if ( (MHD_INVALID_SOCKET != listen_fd) && | 6327 | if ( (MHD_INVALID_SOCKET != listen_fd) && |
6266 | (! MHD_SCKT_FD_FITS_FDSET_(listen_fd, | 6328 | (! MHD_SCKT_FD_FITS_FDSET_ (listen_fd, |
6267 | NULL)) && | 6329 | NULL)) && |
6268 | (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) ) | 6330 | (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) ) |
6269 | { | 6331 | { |
6270 | #ifdef HAVE_MESSAGES | 6332 | #ifdef HAVE_MESSAGES |
6271 | MHD_DLOG (daemon, | 6333 | MHD_DLOG (daemon, |
6272 | _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), | 6334 | _ ("Socket descriptor larger than FD_SETSIZE: %d > %d\n"), |
6273 | listen_fd, | 6335 | listen_fd, |
6274 | FD_SETSIZE); | 6336 | FD_SETSIZE); |
6275 | #endif | 6337 | #endif |
6276 | MHD_socket_close_chk_ (listen_fd); | 6338 | MHD_socket_close_chk_ (listen_fd); |
6277 | goto free_and_fail; | 6339 | goto free_and_fail; |
6278 | } | 6340 | } |
6279 | 6341 | ||
6280 | #ifdef EPOLL_SUPPORT | 6342 | #ifdef EPOLL_SUPPORT |
6281 | if ( (0 != (*pflags & MHD_USE_EPOLL)) | 6343 | if ( (0 != (*pflags & MHD_USE_EPOLL)) |
@@ -6283,193 +6345,197 @@ MHD_start_daemon_va (unsigned int flags, | |||
6283 | && (0 == daemon->worker_pool_size) | 6345 | && (0 == daemon->worker_pool_size) |
6284 | #endif | 6346 | #endif |
6285 | ) | 6347 | ) |
6348 | { | ||
6349 | if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) | ||
6286 | { | 6350 | { |
6287 | if (0 != (*pflags & MHD_USE_THREAD_PER_CONNECTION)) | ||
6288 | { | ||
6289 | #ifdef HAVE_MESSAGES | 6351 | #ifdef HAVE_MESSAGES |
6290 | MHD_DLOG (daemon, | 6352 | MHD_DLOG (daemon, |
6291 | _("Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n")); | 6353 | _ ( |
6354 | "Combining MHD_USE_THREAD_PER_CONNECTION and MHD_USE_EPOLL is not supported.\n")); | ||
6292 | #endif | 6355 | #endif |
6293 | goto free_and_fail; | 6356 | goto free_and_fail; |
6294 | } | ||
6295 | if (MHD_YES != setup_epoll_to_listen (daemon)) | ||
6296 | goto free_and_fail; | ||
6297 | } | 6357 | } |
6358 | if (MHD_YES != setup_epoll_to_listen (daemon)) | ||
6359 | goto free_and_fail; | ||
6360 | } | ||
6298 | #endif /* EPOLL_SUPPORT */ | 6361 | #endif /* EPOLL_SUPPORT */ |
6299 | 6362 | ||
6300 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6363 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6301 | if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) | 6364 | if (! MHD_mutex_init_ (&daemon->per_ip_connection_mutex)) |
6302 | { | 6365 | { |
6303 | #ifdef HAVE_MESSAGES | 6366 | #ifdef HAVE_MESSAGES |
6304 | MHD_DLOG (daemon, | 6367 | MHD_DLOG (daemon, |
6305 | _("MHD failed to initialize IP connection limit mutex\n")); | 6368 | _ ("MHD failed to initialize IP connection limit mutex\n")); |
6306 | #endif | 6369 | #endif |
6307 | if (MHD_INVALID_SOCKET != listen_fd) | 6370 | if (MHD_INVALID_SOCKET != listen_fd) |
6308 | MHD_socket_close_chk_ (listen_fd); | 6371 | MHD_socket_close_chk_ (listen_fd); |
6309 | goto free_and_fail; | 6372 | goto free_and_fail; |
6310 | } | 6373 | } |
6311 | if (0 == daemon->worker_pool_size) | 6374 | if (0 == daemon->worker_pool_size) |
6312 | { /* Initialise connection mutex only if this daemon will handle | 6375 | { /* Initialise connection mutex only if this daemon will handle |
6313 | * any connections by itself. */ | 6376 | * any connections by itself. */ |
6314 | if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) | 6377 | if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex)) |
6315 | { | 6378 | { |
6316 | #ifdef HAVE_MESSAGES | 6379 | #ifdef HAVE_MESSAGES |
6317 | MHD_DLOG (daemon, | 6380 | MHD_DLOG (daemon, |
6318 | _("MHD failed to initialize IP connection limit mutex\n")); | 6381 | _ ("MHD failed to initialize IP connection limit mutex\n")); |
6319 | #endif | 6382 | #endif |
6320 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6383 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6321 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); | 6384 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); |
6322 | #endif | 6385 | #endif |
6323 | if (MHD_INVALID_SOCKET != listen_fd) | 6386 | if (MHD_INVALID_SOCKET != listen_fd) |
6324 | MHD_socket_close_chk_ (listen_fd); | 6387 | MHD_socket_close_chk_ (listen_fd); |
6325 | goto free_and_fail; | 6388 | goto free_and_fail; |
6326 | } | ||
6327 | } | 6389 | } |
6390 | } | ||
6328 | #endif | 6391 | #endif |
6329 | 6392 | ||
6330 | #ifdef HTTPS_SUPPORT | 6393 | #ifdef HTTPS_SUPPORT |
6331 | /* initialize HTTPS daemon certificate aspects & send / recv functions */ | 6394 | /* initialize HTTPS daemon certificate aspects & send / recv functions */ |
6332 | if ( (0 != (*pflags & MHD_USE_TLS)) && | 6395 | if ( (0 != (*pflags & MHD_USE_TLS)) && |
6333 | (0 != MHD_TLS_init (daemon)) ) | 6396 | (0 != MHD_TLS_init (daemon)) ) |
6334 | { | 6397 | { |
6335 | #ifdef HAVE_MESSAGES | 6398 | #ifdef HAVE_MESSAGES |
6336 | MHD_DLOG (daemon, | 6399 | MHD_DLOG (daemon, |
6337 | _("Failed to initialize TLS support\n")); | 6400 | _ ("Failed to initialize TLS support\n")); |
6338 | #endif | 6401 | #endif |
6339 | if (MHD_INVALID_SOCKET != listen_fd) | 6402 | if (MHD_INVALID_SOCKET != listen_fd) |
6340 | MHD_socket_close_chk_ (listen_fd); | 6403 | MHD_socket_close_chk_ (listen_fd); |
6341 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6404 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6342 | if (0 == daemon->worker_pool_size) | 6405 | if (0 == daemon->worker_pool_size) |
6343 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); | 6406 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); |
6344 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); | 6407 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); |
6345 | #endif | 6408 | #endif |
6346 | goto free_and_fail; | 6409 | goto free_and_fail; |
6347 | } | 6410 | } |
6348 | #endif /* HTTPS_SUPPORT */ | 6411 | #endif /* HTTPS_SUPPORT */ |
6349 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6412 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6350 | if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) && | 6413 | if ( (0 != (*pflags & MHD_USE_INTERNAL_POLLING_THREAD)) && |
6351 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) | 6414 | (0 == (*pflags & MHD_USE_NO_LISTEN_SOCKET)) ) |
6415 | { | ||
6416 | if (0 == daemon->worker_pool_size) | ||
6352 | { | 6417 | { |
6353 | if (0 == daemon->worker_pool_size) | 6418 | if (! MHD_create_named_thread_ (&daemon->pid, |
6419 | (*pflags | ||
6420 | & MHD_USE_THREAD_PER_CONNECTION) ? | ||
6421 | "MHD-listen" : "MHD-single", | ||
6422 | daemon->thread_stack_size, | ||
6423 | &MHD_polling_thread, | ||
6424 | daemon) ) | ||
6425 | { | ||
6426 | #ifdef HAVE_MESSAGES | ||
6427 | MHD_DLOG (daemon, | ||
6428 | _ ("Failed to create listen thread: %s\n"), | ||
6429 | MHD_strerror_ (errno)); | ||
6430 | #endif | ||
6431 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); | ||
6432 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); | ||
6433 | if (MHD_INVALID_SOCKET != listen_fd) | ||
6434 | MHD_socket_close_chk_ (listen_fd); | ||
6435 | goto free_and_fail; | ||
6436 | } | ||
6437 | } | ||
6438 | else /* 0 < daemon->worker_pool_size */ | ||
6439 | { | ||
6440 | /* Coarse-grained count of connections per thread (note error | ||
6441 | * due to integer division). Also keep track of how many | ||
6442 | * connections are leftover after an equal split. */ | ||
6443 | unsigned int conns_per_thread = daemon->connection_limit | ||
6444 | / daemon->worker_pool_size; | ||
6445 | unsigned int leftover_conns = daemon->connection_limit | ||
6446 | % daemon->worker_pool_size; | ||
6447 | |||
6448 | i = 0; /* we need this in case fcntl or malloc fails */ | ||
6449 | |||
6450 | /* Allocate memory for pooled objects */ | ||
6451 | daemon->worker_pool = malloc (sizeof (struct MHD_Daemon) | ||
6452 | * daemon->worker_pool_size); | ||
6453 | if (NULL == daemon->worker_pool) | ||
6454 | goto thread_failed; | ||
6455 | |||
6456 | /* Start the workers in the pool */ | ||
6457 | for (i = 0; i < daemon->worker_pool_size; ++i) | ||
6458 | { | ||
6459 | /* Create copy of the Daemon object for each worker */ | ||
6460 | struct MHD_Daemon *d = &daemon->worker_pool[i]; | ||
6461 | |||
6462 | memcpy (d, daemon, sizeof (struct MHD_Daemon)); | ||
6463 | /* Adjust pooling params for worker daemons; note that memcpy() | ||
6464 | has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into | ||
6465 | the worker threads. */ | ||
6466 | d->master = daemon; | ||
6467 | d->worker_pool_size = 0; | ||
6468 | d->worker_pool = NULL; | ||
6469 | |||
6470 | if (0 != (*pflags & MHD_USE_ITC)) | ||
6354 | { | 6471 | { |
6355 | if (! MHD_create_named_thread_ (&daemon->pid, | 6472 | if (! MHD_itc_init_ (d->itc)) |
6356 | (*pflags & MHD_USE_THREAD_PER_CONNECTION) ? | 6473 | { |
6357 | "MHD-listen" : "MHD-single", | 6474 | #ifdef HAVE_MESSAGES |
6358 | daemon->thread_stack_size, | 6475 | MHD_DLOG (daemon, |
6359 | &MHD_polling_thread, | 6476 | _ ( |
6360 | daemon) ) | 6477 | "Failed to create worker inter-thread communication channel: %s\n"), |
6361 | { | 6478 | MHD_itc_last_strerror_ () ); |
6362 | #ifdef HAVE_MESSAGES | 6479 | #endif |
6363 | MHD_DLOG (daemon, | 6480 | goto thread_failed; |
6364 | _("Failed to create listen thread: %s\n"), | 6481 | } |
6365 | MHD_strerror_ (errno)); | 6482 | if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) && |
6366 | #endif | 6483 | (! MHD_SCKT_FD_FITS_FDSET_ (MHD_itc_r_fd_ (d->itc), |
6367 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); | 6484 | NULL)) ) |
6368 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); | 6485 | { |
6369 | if (MHD_INVALID_SOCKET != listen_fd) | 6486 | #ifdef HAVE_MESSAGES |
6370 | MHD_socket_close_chk_ (listen_fd); | 6487 | MHD_DLOG (daemon, |
6371 | goto free_and_fail; | 6488 | _ ( |
6372 | } | 6489 | "File descriptor for worker inter-thread communication channel exceeds maximum value\n")); |
6490 | #endif | ||
6491 | MHD_itc_destroy_chk_ (d->itc); | ||
6492 | goto thread_failed; | ||
6493 | } | ||
6373 | } | 6494 | } |
6374 | else /* 0 < daemon->worker_pool_size */ | 6495 | else |
6496 | MHD_itc_set_invalid_ (d->itc); | ||
6497 | |||
6498 | /* Divide available connections evenly amongst the threads. | ||
6499 | * Thread indexes in [0, leftover_conns) each get one of the | ||
6500 | * leftover connections. */ | ||
6501 | d->connection_limit = conns_per_thread; | ||
6502 | if (i < leftover_conns) | ||
6503 | ++d->connection_limit; | ||
6504 | #ifdef EPOLL_SUPPORT | ||
6505 | if ( (0 != (*pflags & MHD_USE_EPOLL)) && | ||
6506 | (MHD_YES != setup_epoll_to_listen (d)) ) | ||
6507 | goto thread_failed; | ||
6508 | #endif | ||
6509 | /* Must init cleanup connection mutex for each worker */ | ||
6510 | if (! MHD_mutex_init_ (&d->cleanup_connection_mutex)) | ||
6375 | { | 6511 | { |
6376 | /* Coarse-grained count of connections per thread (note error | 6512 | #ifdef HAVE_MESSAGES |
6377 | * due to integer division). Also keep track of how many | 6513 | MHD_DLOG (daemon, |
6378 | * connections are leftover after an equal split. */ | 6514 | _ ("MHD failed to initialize cleanup connection mutex\n")); |
6379 | unsigned int conns_per_thread = daemon->connection_limit | 6515 | #endif |
6380 | / daemon->worker_pool_size; | 6516 | goto thread_failed; |
6381 | unsigned int leftover_conns = daemon->connection_limit | 6517 | } |
6382 | % daemon->worker_pool_size; | ||
6383 | |||
6384 | i = 0; /* we need this in case fcntl or malloc fails */ | ||
6385 | |||
6386 | /* Allocate memory for pooled objects */ | ||
6387 | daemon->worker_pool = malloc (sizeof (struct MHD_Daemon) | ||
6388 | * daemon->worker_pool_size); | ||
6389 | if (NULL == daemon->worker_pool) | ||
6390 | goto thread_failed; | ||
6391 | 6518 | ||
6392 | /* Start the workers in the pool */ | 6519 | /* Spawn the worker thread */ |
6393 | for (i = 0; i < daemon->worker_pool_size; ++i) | 6520 | if (! MHD_create_named_thread_ (&d->pid, |
6394 | { | 6521 | "MHD-worker", |
6395 | /* Create copy of the Daemon object for each worker */ | 6522 | daemon->thread_stack_size, |
6396 | struct MHD_Daemon *d = &daemon->worker_pool[i]; | 6523 | &MHD_polling_thread, |
6397 | 6524 | d)) | |
6398 | memcpy (d, daemon, sizeof (struct MHD_Daemon)); | 6525 | { |
6399 | /* Adjust pooling params for worker daemons; note that memcpy() | 6526 | #ifdef HAVE_MESSAGES |
6400 | has already copied MHD_USE_INTERNAL_POLLING_THREAD thread mode into | 6527 | MHD_DLOG (daemon, |
6401 | the worker threads. */ | 6528 | _ ("Failed to create pool thread: %s\n"), |
6402 | d->master = daemon; | 6529 | MHD_strerror_ (errno)); |
6403 | d->worker_pool_size = 0; | 6530 | #endif |
6404 | d->worker_pool = NULL; | 6531 | /* Free memory for this worker; cleanup below handles |
6405 | 6532 | * all previously-created workers. */ | |
6406 | if (0 != (*pflags & MHD_USE_ITC)) | 6533 | MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); |
6407 | { | 6534 | goto thread_failed; |
6408 | if (! MHD_itc_init_ (d->itc)) | ||
6409 | { | ||
6410 | #ifdef HAVE_MESSAGES | ||
6411 | MHD_DLOG (daemon, | ||
6412 | _("Failed to create worker inter-thread communication channel: %s\n"), | ||
6413 | MHD_itc_last_strerror_() ); | ||
6414 | #endif | ||
6415 | goto thread_failed; | ||
6416 | } | ||
6417 | if ( (0 == (*pflags & (MHD_USE_POLL | MHD_USE_EPOLL))) && | ||
6418 | (! MHD_SCKT_FD_FITS_FDSET_(MHD_itc_r_fd_ (d->itc), | ||
6419 | NULL)) ) | ||
6420 | { | ||
6421 | #ifdef HAVE_MESSAGES | ||
6422 | MHD_DLOG (daemon, | ||
6423 | _("File descriptor for worker inter-thread communication channel exceeds maximum value\n")); | ||
6424 | #endif | ||
6425 | MHD_itc_destroy_chk_ (d->itc); | ||
6426 | goto thread_failed; | ||
6427 | } | ||
6428 | } | ||
6429 | else | ||
6430 | MHD_itc_set_invalid_ (d->itc); | ||
6431 | |||
6432 | /* Divide available connections evenly amongst the threads. | ||
6433 | * Thread indexes in [0, leftover_conns) each get one of the | ||
6434 | * leftover connections. */ | ||
6435 | d->connection_limit = conns_per_thread; | ||
6436 | if (i < leftover_conns) | ||
6437 | ++d->connection_limit; | ||
6438 | #ifdef EPOLL_SUPPORT | ||
6439 | if ( (0 != (*pflags & MHD_USE_EPOLL)) && | ||
6440 | (MHD_YES != setup_epoll_to_listen (d)) ) | ||
6441 | goto thread_failed; | ||
6442 | #endif | ||
6443 | /* Must init cleanup connection mutex for each worker */ | ||
6444 | if (! MHD_mutex_init_ (&d->cleanup_connection_mutex)) | ||
6445 | { | ||
6446 | #ifdef HAVE_MESSAGES | ||
6447 | MHD_DLOG (daemon, | ||
6448 | _("MHD failed to initialize cleanup connection mutex\n")); | ||
6449 | #endif | ||
6450 | goto thread_failed; | ||
6451 | } | ||
6452 | |||
6453 | /* Spawn the worker thread */ | ||
6454 | if (! MHD_create_named_thread_ (&d->pid, | ||
6455 | "MHD-worker", | ||
6456 | daemon->thread_stack_size, | ||
6457 | &MHD_polling_thread, | ||
6458 | d)) | ||
6459 | { | ||
6460 | #ifdef HAVE_MESSAGES | ||
6461 | MHD_DLOG (daemon, | ||
6462 | _("Failed to create pool thread: %s\n"), | ||
6463 | MHD_strerror_ (errno)); | ||
6464 | #endif | ||
6465 | /* Free memory for this worker; cleanup below handles | ||
6466 | * all previously-created workers. */ | ||
6467 | MHD_mutex_destroy_chk_ (&d->cleanup_connection_mutex); | ||
6468 | goto thread_failed; | ||
6469 | } | ||
6470 | } | ||
6471 | } | 6535 | } |
6536 | } | ||
6472 | } | 6537 | } |
6538 | } | ||
6473 | #endif | 6539 | #endif |
6474 | #ifdef HTTPS_SUPPORT | 6540 | #ifdef HTTPS_SUPPORT |
6475 | /* API promises to never use the password after initialization, | 6541 | /* API promises to never use the password after initialization, |
@@ -6486,14 +6552,14 @@ thread_failed: | |||
6486 | assumes a 0-sized thread pool means we had been in the default | 6552 | assumes a 0-sized thread pool means we had been in the default |
6487 | MHD_USE_INTERNAL_POLLING_THREAD mode. */ | 6553 | MHD_USE_INTERNAL_POLLING_THREAD mode. */ |
6488 | if (0 == i) | 6554 | if (0 == i) |
6489 | { | 6555 | { |
6490 | if (MHD_INVALID_SOCKET != listen_fd) | 6556 | if (MHD_INVALID_SOCKET != listen_fd) |
6491 | MHD_socket_close_chk_ (listen_fd); | 6557 | MHD_socket_close_chk_ (listen_fd); |
6492 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); | 6558 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); |
6493 | if (NULL != daemon->worker_pool) | 6559 | if (NULL != daemon->worker_pool) |
6494 | free (daemon->worker_pool); | 6560 | free (daemon->worker_pool); |
6495 | goto free_and_fail; | 6561 | goto free_and_fail; |
6496 | } | 6562 | } |
6497 | 6563 | ||
6498 | /* Shutdown worker threads we've already created. Pretend | 6564 | /* Shutdown worker threads we've already created. Pretend |
6499 | as though we had fully initialized our daemon, but | 6565 | as though we had fully initialized our daemon, but |
@@ -6504,20 +6570,20 @@ thread_failed: | |||
6504 | return NULL; | 6570 | return NULL; |
6505 | #endif | 6571 | #endif |
6506 | 6572 | ||
6507 | free_and_fail: | 6573 | free_and_fail: |
6508 | /* clean up basic memory state in 'daemon' and return NULL to | 6574 | /* clean up basic memory state in 'daemon' and return NULL to |
6509 | indicate failure */ | 6575 | indicate failure */ |
6510 | #ifdef EPOLL_SUPPORT | 6576 | #ifdef EPOLL_SUPPORT |
6511 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 6577 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
6512 | if (daemon->upgrade_fd_in_epoll) | 6578 | if (daemon->upgrade_fd_in_epoll) |
6513 | { | 6579 | { |
6514 | if (0 != epoll_ctl (daemon->epoll_fd, | 6580 | if (0 != epoll_ctl (daemon->epoll_fd, |
6515 | EPOLL_CTL_DEL, | 6581 | EPOLL_CTL_DEL, |
6516 | daemon->epoll_upgrade_fd, | 6582 | daemon->epoll_upgrade_fd, |
6517 | NULL)) | 6583 | NULL)) |
6518 | MHD_PANIC (_("Failed to remove FD from epoll set\n")); | 6584 | MHD_PANIC (_ ("Failed to remove FD from epoll set\n")); |
6519 | daemon->upgrade_fd_in_epoll = false; | 6585 | daemon->upgrade_fd_in_epoll = false; |
6520 | } | 6586 | } |
6521 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 6587 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
6522 | if (-1 != daemon->epoll_fd) | 6588 | if (-1 != daemon->epoll_fd) |
6523 | close (daemon->epoll_fd); | 6589 | close (daemon->epoll_fd); |
@@ -6542,7 +6608,7 @@ thread_failed: | |||
6542 | gnutls_psk_free_server_credentials (daemon->psk_cred); | 6608 | gnutls_psk_free_server_credentials (daemon->psk_cred); |
6543 | } | 6609 | } |
6544 | #endif /* HTTPS_SUPPORT */ | 6610 | #endif /* HTTPS_SUPPORT */ |
6545 | if (MHD_ITC_IS_VALID_(daemon->itc)) | 6611 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
6546 | MHD_itc_destroy_chk_ (daemon->itc); | 6612 | MHD_itc_destroy_chk_ (daemon->itc); |
6547 | free (daemon); | 6613 | free (daemon); |
6548 | return NULL; | 6614 | return NULL; |
@@ -6561,7 +6627,8 @@ static void | |||
6561 | close_all_connections (struct MHD_Daemon *daemon) | 6627 | close_all_connections (struct MHD_Daemon *daemon) |
6562 | { | 6628 | { |
6563 | struct MHD_Connection *pos; | 6629 | struct MHD_Connection *pos; |
6564 | const bool used_thr_p_c = (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)); | 6630 | const bool used_thr_p_c = (0 != (daemon->options |
6631 | & MHD_USE_THREAD_PER_CONNECTION)); | ||
6565 | #ifdef UPGRADE_SUPPORT | 6632 | #ifdef UPGRADE_SUPPORT |
6566 | const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE)); | 6633 | const bool upg_allowed = (0 != (daemon->options & MHD_ALLOW_UPGRADE)); |
6567 | #endif /* UPGRADE_SUPPORT */ | 6634 | #endif /* UPGRADE_SUPPORT */ |
@@ -6577,16 +6644,16 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
6577 | /* give upgraded HTTPS connections a chance to finish */ | 6644 | /* give upgraded HTTPS connections a chance to finish */ |
6578 | /* 'daemon->urh_head' is not used in thread-per-connection mode. */ | 6645 | /* 'daemon->urh_head' is not used in thread-per-connection mode. */ |
6579 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) | 6646 | for (urh = daemon->urh_tail; NULL != urh; urh = urhn) |
6580 | { | 6647 | { |
6581 | urhn = urh->prev; | 6648 | urhn = urh->prev; |
6582 | /* call generic forwarding function for passing data | 6649 | /* call generic forwarding function for passing data |
6583 | with chance to detect that application is done. */ | 6650 | with chance to detect that application is done. */ |
6584 | process_urh (urh); | 6651 | process_urh (urh); |
6585 | MHD_connection_finish_forward_ (urh->connection); | 6652 | MHD_connection_finish_forward_ (urh->connection); |
6586 | urh->clean_ready = true; | 6653 | urh->clean_ready = true; |
6587 | /* Resuming will move connection to cleanup list. */ | 6654 | /* Resuming will move connection to cleanup list. */ |
6588 | MHD_resume_connection(urh->connection); | 6655 | MHD_resume_connection (urh->connection); |
6589 | } | 6656 | } |
6590 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 6657 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
6591 | 6658 | ||
6592 | /* Give suspended connections a chance to resume to avoid | 6659 | /* Give suspended connections a chance to resume to avoid |
@@ -6594,10 +6661,10 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
6594 | connections left in case of a tight race with a recently | 6661 | connections left in case of a tight race with a recently |
6595 | resumed connection. */ | 6662 | resumed connection. */ |
6596 | if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) | 6663 | if (0 != (MHD_TEST_ALLOW_SUSPEND_RESUME & daemon->options)) |
6597 | { | 6664 | { |
6598 | daemon->resuming = true; /* Force check for pending resume. */ | 6665 | daemon->resuming = true; /* Force check for pending resume. */ |
6599 | resume_suspended_connections (daemon); | 6666 | resume_suspended_connections (daemon); |
6600 | } | 6667 | } |
6601 | /* first, make sure all threads are aware of shutdown; need to | 6668 | /* first, make sure all threads are aware of shutdown; need to |
6602 | traverse DLLs in peace... */ | 6669 | traverse DLLs in peace... */ |
6603 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6670 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
@@ -6605,79 +6672,83 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
6605 | #endif | 6672 | #endif |
6606 | #ifdef UPGRADE_SUPPORT | 6673 | #ifdef UPGRADE_SUPPORT |
6607 | if (upg_allowed) | 6674 | if (upg_allowed) |
6608 | { | 6675 | { |
6609 | struct MHD_Connection * susp; | 6676 | struct MHD_Connection *susp; |
6610 | 6677 | ||
6611 | susp = daemon->suspended_connections_tail; | 6678 | susp = daemon->suspended_connections_tail; |
6612 | while (NULL != susp) | 6679 | while (NULL != susp) |
6613 | { | 6680 | { |
6614 | if (NULL == susp->urh) /* "Upgraded" connection? */ | 6681 | if (NULL == susp->urh) /* "Upgraded" connection? */ |
6615 | MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); | 6682 | MHD_PANIC (_ ( |
6683 | "MHD_stop_daemon() called while we have suspended connections.\n")); | ||
6616 | #ifdef HTTPS_SUPPORT | 6684 | #ifdef HTTPS_SUPPORT |
6617 | else if (used_tls && | 6685 | else if (used_tls && |
6618 | used_thr_p_c && | 6686 | used_thr_p_c && |
6619 | (! susp->urh->clean_ready) ) | 6687 | (! susp->urh->clean_ready) ) |
6620 | shutdown (susp->urh->app.socket, | 6688 | shutdown (susp->urh->app.socket, |
6621 | SHUT_RDWR); /* Wake thread by shutdown of app socket. */ | 6689 | SHUT_RDWR); /* Wake thread by shutdown of app socket. */ |
6622 | #endif /* HTTPS_SUPPORT */ | 6690 | #endif /* HTTPS_SUPPORT */ |
6623 | else | 6691 | else |
6624 | { | 6692 | { |
6625 | #ifdef HAVE_MESSAGES | 6693 | #ifdef HAVE_MESSAGES |
6626 | if (! susp->urh->was_closed) | 6694 | if (! susp->urh->was_closed) |
6627 | MHD_DLOG (daemon, | 6695 | MHD_DLOG (daemon, |
6628 | _("Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); | 6696 | _ ( |
6629 | #endif | 6697 | "Initiated daemon shutdown while \"upgraded\" connection was not closed.\n")); |
6630 | susp->urh->was_closed = true; | 6698 | #endif |
6631 | /* If thread-per-connection is used, connection's thread | 6699 | susp->urh->was_closed = true; |
6632 | * may still processing "upgrade" (exiting). */ | 6700 | /* If thread-per-connection is used, connection's thread |
6633 | if (! used_thr_p_c) | 6701 | * may still processing "upgrade" (exiting). */ |
6634 | MHD_connection_finish_forward_ (susp); | 6702 | if (! used_thr_p_c) |
6635 | /* Do not use MHD_resume_connection() as mutex is | 6703 | MHD_connection_finish_forward_ (susp); |
6636 | * already locked. */ | 6704 | /* Do not use MHD_resume_connection() as mutex is |
6637 | susp->resuming = true; | 6705 | * already locked. */ |
6638 | daemon->resuming = true; | 6706 | susp->resuming = true; |
6639 | } | 6707 | daemon->resuming = true; |
6640 | susp = susp->prev; | 6708 | } |
6641 | } | 6709 | susp = susp->prev; |
6642 | } | 6710 | } |
6711 | } | ||
6643 | else /* This 'else' is combined with next 'if' */ | 6712 | else /* This 'else' is combined with next 'if' */ |
6644 | #endif /* UPGRADE_SUPPORT */ | 6713 | #endif /* UPGRADE_SUPPORT */ |
6645 | if (NULL != daemon->suspended_connections_head) | 6714 | if (NULL != daemon->suspended_connections_head) |
6646 | MHD_PANIC (_("MHD_stop_daemon() called while we have suspended connections.\n")); | 6715 | MHD_PANIC (_ ( |
6716 | "MHD_stop_daemon() called while we have suspended connections.\n")); | ||
6647 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) | 6717 | for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev) |
6648 | { | 6718 | { |
6649 | shutdown (pos->socket_fd, | 6719 | shutdown (pos->socket_fd, |
6650 | SHUT_RDWR); | 6720 | SHUT_RDWR); |
6651 | #if MHD_WINSOCK_SOCKETS | 6721 | #if MHD_WINSOCK_SOCKETS |
6652 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 6722 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
6653 | (MHD_ITC_IS_VALID_(daemon->itc)) && | 6723 | (MHD_ITC_IS_VALID_ (daemon->itc)) && |
6654 | (! MHD_itc_activate_ (daemon->itc, "e")) ) | 6724 | (! MHD_itc_activate_ (daemon->itc, "e")) ) |
6655 | MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); | 6725 | MHD_PANIC (_ ( |
6726 | "Failed to signal shutdown via inter-thread communication channel")); | ||
6656 | #endif | 6727 | #endif |
6657 | } | 6728 | } |
6658 | 6729 | ||
6659 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6730 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6660 | /* now, collect per-connection threads */ | 6731 | /* now, collect per-connection threads */ |
6661 | if (used_thr_p_c) | 6732 | if (used_thr_p_c) |
6733 | { | ||
6734 | pos = daemon->connections_tail; | ||
6735 | while (NULL != pos) | ||
6662 | { | 6736 | { |
6663 | pos = daemon->connections_tail; | 6737 | if (! pos->thread_joined) |
6664 | while (NULL != pos) | ||
6665 | { | 6738 | { |
6666 | if (! pos->thread_joined) | 6739 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
6667 | { | 6740 | if (! MHD_join_thread_ (pos->pid.handle)) |
6668 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 6741 | MHD_PANIC (_ ("Failed to join a thread\n")); |
6669 | if (! MHD_join_thread_ (pos->pid.handle)) | 6742 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); |
6670 | MHD_PANIC (_("Failed to join a thread\n")); | 6743 | pos->thread_joined = true; |
6671 | MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex); | 6744 | /* The thread may have concurrently modified the DLL, |
6672 | pos->thread_joined = true; | 6745 | need to restart from the beginning */ |
6673 | /* The thread may have concurrently modified the DLL, | 6746 | pos = daemon->connections_tail; |
6674 | need to restart from the beginning */ | 6747 | continue; |
6675 | pos = daemon->connections_tail; | ||
6676 | continue; | ||
6677 | } | ||
6678 | pos = pos->prev; | ||
6679 | } | 6748 | } |
6749 | pos = pos->prev; | ||
6680 | } | 6750 | } |
6751 | } | ||
6681 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); | 6752 | MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex); |
6682 | #endif | 6753 | #endif |
6683 | 6754 | ||
@@ -6687,10 +6758,10 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
6687 | /* "Upgraded" connections that were not closed explicitly by | 6758 | /* "Upgraded" connections that were not closed explicitly by |
6688 | * application should be moved to cleanup list too. */ | 6759 | * application should be moved to cleanup list too. */ |
6689 | if (upg_allowed) | 6760 | if (upg_allowed) |
6690 | { | 6761 | { |
6691 | daemon->resuming = true; /* Force check for pending resume. */ | 6762 | daemon->resuming = true; /* Force check for pending resume. */ |
6692 | resume_suspended_connections (daemon); | 6763 | resume_suspended_connections (daemon); |
6693 | } | 6764 | } |
6694 | #endif /* UPGRADE_SUPPORT */ | 6765 | #endif /* UPGRADE_SUPPORT */ |
6695 | 6766 | ||
6696 | /* now that we're alone, move everyone to cleanup */ | 6767 | /* now that we're alone, move everyone to cleanup */ |
@@ -6699,7 +6770,7 @@ close_all_connections (struct MHD_Daemon *daemon) | |||
6699 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6770 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6700 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && | 6771 | if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && |
6701 | (! pos->thread_joined) ) | 6772 | (! pos->thread_joined) ) |
6702 | MHD_PANIC (_("Failed to join a thread\n")); | 6773 | MHD_PANIC (_ ("Failed to join a thread\n")); |
6703 | #endif | 6774 | #endif |
6704 | close_connection (pos); | 6775 | close_connection (pos); |
6705 | } | 6776 | } |
@@ -6732,137 +6803,139 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
6732 | 6803 | ||
6733 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6804 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6734 | if (NULL != daemon->worker_pool) | 6805 | if (NULL != daemon->worker_pool) |
6735 | { /* Master daemon with worker pool. */ | 6806 | { /* Master daemon with worker pool. */ |
6736 | mhd_assert (1 < daemon->worker_pool_size); | 6807 | mhd_assert (1 < daemon->worker_pool_size); |
6737 | mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)); | 6808 | mhd_assert (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)); |
6738 | 6809 | ||
6739 | /* Let workers shutdown in parallel. */ | 6810 | /* Let workers shutdown in parallel. */ |
6740 | for (i = 0; i < daemon->worker_pool_size; ++i) | 6811 | for (i = 0; i < daemon->worker_pool_size; ++i) |
6741 | { | 6812 | { |
6742 | daemon->worker_pool[i].shutdown = true; | 6813 | daemon->worker_pool[i].shutdown = true; |
6743 | if (MHD_ITC_IS_VALID_(daemon->worker_pool[i].itc)) | 6814 | if (MHD_ITC_IS_VALID_ (daemon->worker_pool[i].itc)) |
6744 | { | 6815 | { |
6745 | if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, | 6816 | if (! MHD_itc_activate_ (daemon->worker_pool[i].itc, |
6746 | "e")) | 6817 | "e")) |
6747 | MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel.")); | 6818 | MHD_PANIC (_ ( |
6748 | } | 6819 | "Failed to signal shutdown via inter-thread communication channel.")); |
6749 | else | 6820 | } |
6750 | mhd_assert (MHD_INVALID_SOCKET != fd); | 6821 | else |
6751 | } | 6822 | mhd_assert (MHD_INVALID_SOCKET != fd); |
6823 | } | ||
6752 | #ifdef HAVE_LISTEN_SHUTDOWN | 6824 | #ifdef HAVE_LISTEN_SHUTDOWN |
6753 | if (MHD_INVALID_SOCKET != fd) | 6825 | if (MHD_INVALID_SOCKET != fd) |
6754 | { | 6826 | { |
6755 | (void) shutdown (fd, | 6827 | (void) shutdown (fd, |
6756 | SHUT_RDWR); | 6828 | SHUT_RDWR); |
6757 | } | 6829 | } |
6758 | #endif /* HAVE_LISTEN_SHUTDOWN */ | 6830 | #endif /* HAVE_LISTEN_SHUTDOWN */ |
6759 | for (i = 0; i < daemon->worker_pool_size; ++i) | 6831 | for (i = 0; i < daemon->worker_pool_size; ++i) |
6760 | { | 6832 | { |
6761 | MHD_stop_daemon (&daemon->worker_pool[i]); | 6833 | MHD_stop_daemon (&daemon->worker_pool[i]); |
6762 | } | 6834 | } |
6763 | free (daemon->worker_pool); | 6835 | free (daemon->worker_pool); |
6764 | mhd_assert (MHD_ITC_IS_INVALID_(daemon->itc)); | 6836 | mhd_assert (MHD_ITC_IS_INVALID_ (daemon->itc)); |
6765 | #ifdef EPOLL_SUPPORT | 6837 | #ifdef EPOLL_SUPPORT |
6766 | mhd_assert (-1 == daemon->epoll_fd); | 6838 | mhd_assert (-1 == daemon->epoll_fd); |
6767 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 6839 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
6768 | mhd_assert (-1 == daemon->epoll_upgrade_fd); | 6840 | mhd_assert (-1 == daemon->epoll_upgrade_fd); |
6769 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 6841 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
6770 | #endif /* EPOLL_SUPPORT */ | 6842 | #endif /* EPOLL_SUPPORT */ |
6771 | } | 6843 | } |
6772 | else | 6844 | else |
6773 | #endif | 6845 | #endif |
6774 | { /* Worker daemon or single daemon. */ | 6846 | { /* Worker daemon or single daemon. */ |
6775 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6847 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6776 | if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) | 6848 | if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) |
6777 | { /* Worker daemon or single daemon with internal thread(s). */ | 6849 | { /* Worker daemon or single daemon with internal thread(s). */ |
6778 | mhd_assert (0 == daemon->worker_pool_size); | 6850 | mhd_assert (0 == daemon->worker_pool_size); |
6779 | /* Separate thread(s) is used for polling sockets. */ | 6851 | /* Separate thread(s) is used for polling sockets. */ |
6780 | if (MHD_ITC_IS_VALID_ (daemon->itc)) | 6852 | if (MHD_ITC_IS_VALID_ (daemon->itc)) |
6781 | { | 6853 | { |
6782 | if (! MHD_itc_activate_ (daemon->itc, | 6854 | if (! MHD_itc_activate_ (daemon->itc, |
6783 | "e")) | 6855 | "e")) |
6784 | MHD_PANIC (_("Failed to signal shutdown via inter-thread communication channel")); | 6856 | MHD_PANIC (_ ( |
6785 | } | 6857 | "Failed to signal shutdown via inter-thread communication channel")); |
6786 | else | 6858 | } |
6787 | { | ||
6788 | #ifdef HAVE_LISTEN_SHUTDOWN | ||
6789 | if (MHD_INVALID_SOCKET != fd) | ||
6790 | { | ||
6791 | if (NULL == daemon->master) | ||
6792 | (void) shutdown (fd, | ||
6793 | SHUT_RDWR); | ||
6794 | } | ||
6795 | else | ||
6796 | #endif /* HAVE_LISTEN_SHUTDOWN */ | ||
6797 | mhd_assert (false); /* Should never happen */ | ||
6798 | } | ||
6799 | |||
6800 | if (! MHD_join_thread_ (daemon->pid.handle)) | ||
6801 | { | ||
6802 | MHD_PANIC (_("Failed to join a thread\n")); | ||
6803 | } | ||
6804 | /* close_all_connections() was called in daemon thread. */ | ||
6805 | } | ||
6806 | else | 6859 | else |
6807 | #endif | 6860 | { |
6861 | #ifdef HAVE_LISTEN_SHUTDOWN | ||
6862 | if (MHD_INVALID_SOCKET != fd) | ||
6808 | { | 6863 | { |
6809 | /* No internal threads are used for polling sockets. */ | 6864 | if (NULL == daemon->master) |
6810 | close_all_connections (daemon); | 6865 | (void) shutdown (fd, |
6866 | SHUT_RDWR); | ||
6811 | } | 6867 | } |
6812 | if (MHD_ITC_IS_VALID_ (daemon->itc)) | 6868 | else |
6813 | MHD_itc_destroy_chk_ (daemon->itc); | 6869 | #endif /* HAVE_LISTEN_SHUTDOWN */ |
6870 | mhd_assert (false); /* Should never happen */ | ||
6871 | } | ||
6872 | |||
6873 | if (! MHD_join_thread_ (daemon->pid.handle)) | ||
6874 | { | ||
6875 | MHD_PANIC (_ ("Failed to join a thread\n")); | ||
6876 | } | ||
6877 | /* close_all_connections() was called in daemon thread. */ | ||
6878 | } | ||
6879 | else | ||
6880 | #endif | ||
6881 | { | ||
6882 | /* No internal threads are used for polling sockets. */ | ||
6883 | close_all_connections (daemon); | ||
6884 | } | ||
6885 | if (MHD_ITC_IS_VALID_ (daemon->itc)) | ||
6886 | MHD_itc_destroy_chk_ (daemon->itc); | ||
6814 | 6887 | ||
6815 | #ifdef EPOLL_SUPPORT | 6888 | #ifdef EPOLL_SUPPORT |
6816 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | 6889 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && |
6817 | (-1 != daemon->epoll_fd) ) | 6890 | (-1 != daemon->epoll_fd) ) |
6818 | MHD_socket_close_chk_ (daemon->epoll_fd); | 6891 | MHD_socket_close_chk_ (daemon->epoll_fd); |
6819 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) | 6892 | #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) |
6820 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && | 6893 | if ( (0 != (daemon->options & MHD_USE_EPOLL)) && |
6821 | (-1 != daemon->epoll_upgrade_fd) ) | 6894 | (-1 != daemon->epoll_upgrade_fd) ) |
6822 | MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); | 6895 | MHD_socket_close_chk_ (daemon->epoll_upgrade_fd); |
6823 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ | 6896 | #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */ |
6824 | #endif /* EPOLL_SUPPORT */ | 6897 | #endif /* EPOLL_SUPPORT */ |
6825 | 6898 | ||
6826 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6899 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6827 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); | 6900 | MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex); |
6828 | #endif | 6901 | #endif |
6829 | } | 6902 | } |
6830 | 6903 | ||
6831 | if (NULL == daemon->master) | 6904 | if (NULL == daemon->master) |
6832 | { /* Cleanup that should be done only one time in master/single daemon. | 6905 | { /* Cleanup that should be done only one time in master/single daemon. |
6833 | * Do not perform this cleanup in worker daemons. */ | 6906 | * Do not perform this cleanup in worker daemons. */ |
6834 | 6907 | ||
6835 | if (MHD_INVALID_SOCKET != fd) | 6908 | if (MHD_INVALID_SOCKET != fd) |
6836 | MHD_socket_close_chk_ (fd); | 6909 | MHD_socket_close_chk_ (fd); |
6837 | 6910 | ||
6838 | /* TLS clean up */ | 6911 | /* TLS clean up */ |
6839 | #ifdef HTTPS_SUPPORT | 6912 | #ifdef HTTPS_SUPPORT |
6840 | if (daemon->have_dhparams) | 6913 | if (daemon->have_dhparams) |
6841 | { | 6914 | { |
6842 | gnutls_dh_params_deinit (daemon->https_mem_dhparams); | 6915 | gnutls_dh_params_deinit (daemon->https_mem_dhparams); |
6843 | daemon->have_dhparams = false; | 6916 | daemon->have_dhparams = false; |
6844 | } | 6917 | } |
6845 | if (0 != (daemon->options & MHD_USE_TLS)) | 6918 | if (0 != (daemon->options & MHD_USE_TLS)) |
6846 | { | 6919 | { |
6847 | gnutls_priority_deinit (daemon->priority_cache); | 6920 | gnutls_priority_deinit (daemon->priority_cache); |
6848 | if (daemon->x509_cred) | 6921 | if (daemon->x509_cred) |
6849 | gnutls_certificate_free_credentials (daemon->x509_cred); | 6922 | gnutls_certificate_free_credentials (daemon->x509_cred); |
6850 | if (daemon->psk_cred) | 6923 | if (daemon->psk_cred) |
6851 | gnutls_psk_free_server_credentials (daemon->psk_cred); | 6924 | gnutls_psk_free_server_credentials (daemon->psk_cred); |
6852 | } | 6925 | } |
6853 | #endif /* HTTPS_SUPPORT */ | 6926 | #endif /* HTTPS_SUPPORT */ |
6854 | 6927 | ||
6855 | #ifdef DAUTH_SUPPORT | 6928 | #ifdef DAUTH_SUPPORT |
6856 | free (daemon->nnc); | 6929 | free (daemon->nnc); |
6857 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6930 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6858 | MHD_mutex_destroy_chk_ (&daemon->nnc_lock); | 6931 | MHD_mutex_destroy_chk_ (&daemon->nnc_lock); |
6859 | #endif | 6932 | #endif |
6860 | #endif | 6933 | #endif |
6861 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6934 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6862 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); | 6935 | MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex); |
6863 | #endif | 6936 | #endif |
6864 | free (daemon); | 6937 | free (daemon); |
6865 | } | 6938 | } |
6866 | } | 6939 | } |
6867 | 6940 | ||
6868 | 6941 | ||
@@ -6879,51 +6952,51 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) | |||
6879 | */ | 6952 | */ |
6880 | const union MHD_DaemonInfo * | 6953 | const union MHD_DaemonInfo * |
6881 | MHD_get_daemon_info (struct MHD_Daemon *daemon, | 6954 | MHD_get_daemon_info (struct MHD_Daemon *daemon, |
6882 | enum MHD_DaemonInfoType info_type, | 6955 | enum MHD_DaemonInfoType info_type, |
6883 | ...) | 6956 | ...) |
6884 | { | 6957 | { |
6885 | if (NULL == daemon) | 6958 | if (NULL == daemon) |
6886 | return NULL; | 6959 | return NULL; |
6887 | switch (info_type) | 6960 | switch (info_type) |
6888 | { | 6961 | { |
6889 | case MHD_DAEMON_INFO_KEY_SIZE: | 6962 | case MHD_DAEMON_INFO_KEY_SIZE: |
6890 | return NULL; /* no longer supported */ | 6963 | return NULL; /* no longer supported */ |
6891 | case MHD_DAEMON_INFO_MAC_KEY_SIZE: | 6964 | case MHD_DAEMON_INFO_MAC_KEY_SIZE: |
6892 | return NULL; /* no longer supported */ | 6965 | return NULL; /* no longer supported */ |
6893 | case MHD_DAEMON_INFO_LISTEN_FD: | 6966 | case MHD_DAEMON_INFO_LISTEN_FD: |
6894 | return (const union MHD_DaemonInfo *) &daemon->listen_fd; | 6967 | return (const union MHD_DaemonInfo *) &daemon->listen_fd; |
6895 | #ifdef EPOLL_SUPPORT | 6968 | #ifdef EPOLL_SUPPORT |
6896 | case MHD_DAEMON_INFO_EPOLL_FD: | 6969 | case MHD_DAEMON_INFO_EPOLL_FD: |
6897 | return (const union MHD_DaemonInfo *) &daemon->epoll_fd; | 6970 | return (const union MHD_DaemonInfo *) &daemon->epoll_fd; |
6898 | #endif | 6971 | #endif |
6899 | case MHD_DAEMON_INFO_CURRENT_CONNECTIONS: | 6972 | case MHD_DAEMON_INFO_CURRENT_CONNECTIONS: |
6900 | if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) | 6973 | if (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) |
6901 | { | 6974 | { |
6902 | /* Assume that MHD_run() in not called in other thread | 6975 | /* Assume that MHD_run() in not called in other thread |
6903 | * at the same time. */ | 6976 | * at the same time. */ |
6904 | MHD_cleanup_connections (daemon); | 6977 | MHD_cleanup_connections (daemon); |
6905 | } | 6978 | } |
6906 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 6979 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
6907 | else if (daemon->worker_pool) | 6980 | else if (daemon->worker_pool) |
6908 | { | 6981 | { |
6909 | unsigned int i; | 6982 | unsigned int i; |
6910 | /* Collect the connection information stored in the workers. */ | 6983 | /* Collect the connection information stored in the workers. */ |
6911 | daemon->connections = 0; | 6984 | daemon->connections = 0; |
6912 | for (i = 0; i < daemon->worker_pool_size; i++) | 6985 | for (i = 0; i < daemon->worker_pool_size; i++) |
6913 | { | 6986 | { |
6914 | /* FIXME: next line is thread-safe only if read is atomic. */ | 6987 | /* FIXME: next line is thread-safe only if read is atomic. */ |
6915 | daemon->connections += daemon->worker_pool[i].connections; | 6988 | daemon->connections += daemon->worker_pool[i].connections; |
6916 | } | 6989 | } |
6917 | } | ||
6918 | #endif | ||
6919 | return (const union MHD_DaemonInfo *) &daemon->connections; | ||
6920 | case MHD_DAEMON_INFO_FLAGS: | ||
6921 | return (const union MHD_DaemonInfo *) &daemon->options; | ||
6922 | case MHD_DAEMON_INFO_BIND_PORT: | ||
6923 | return (const union MHD_DaemonInfo *) &daemon->port; | ||
6924 | default: | ||
6925 | return NULL; | ||
6926 | } | 6990 | } |
6991 | #endif | ||
6992 | return (const union MHD_DaemonInfo *) &daemon->connections; | ||
6993 | case MHD_DAEMON_INFO_FLAGS: | ||
6994 | return (const union MHD_DaemonInfo *) &daemon->options; | ||
6995 | case MHD_DAEMON_INFO_BIND_PORT: | ||
6996 | return (const union MHD_DaemonInfo *) &daemon->port; | ||
6997 | default: | ||
6998 | return NULL; | ||
6999 | } | ||
6927 | } | 7000 | } |
6928 | 7001 | ||
6929 | 7002 | ||
@@ -6967,13 +7040,13 @@ MHD_get_version (void) | |||
6967 | static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; | 7040 | static char ver[12] = "\0\0\0\0\0\0\0\0\0\0\0"; |
6968 | if (0 == ver[0]) | 7041 | if (0 == ver[0]) |
6969 | { | 7042 | { |
6970 | int res = MHD_snprintf_(ver, | 7043 | int res = MHD_snprintf_ (ver, |
6971 | sizeof(ver), | 7044 | sizeof(ver), |
6972 | "%x.%x.%x", | 7045 | "%x.%x.%x", |
6973 | (((int)MHD_VERSION >> 24) & 0xFF), | 7046 | (((int) MHD_VERSION >> 24) & 0xFF), |
6974 | (((int)MHD_VERSION >> 16) & 0xFF), | 7047 | (((int) MHD_VERSION >> 16) & 0xFF), |
6975 | (((int)MHD_VERSION >> 8) & 0xFF)); | 7048 | (((int) MHD_VERSION >> 8) & 0xFF)); |
6976 | if (0 >= res || sizeof(ver) <= res) | 7049 | if ((0 >= res)||(sizeof(ver) <= res)) |
6977 | return "0.0.0"; /* Can't return real version*/ | 7050 | return "0.0.0"; /* Can't return real version*/ |
6978 | } | 7051 | } |
6979 | return ver; | 7052 | return ver; |
@@ -6993,154 +7066,155 @@ MHD_get_version (void) | |||
6993 | * @ingroup specialized | 7066 | * @ingroup specialized |
6994 | */ | 7067 | */ |
6995 | _MHD_EXTERN int | 7068 | _MHD_EXTERN int |
6996 | MHD_is_feature_supported(enum MHD_FEATURE feature) | 7069 | MHD_is_feature_supported (enum MHD_FEATURE feature) |
6997 | { | 7070 | { |
6998 | switch(feature) | 7071 | switch (feature) |
6999 | { | 7072 | { |
7000 | case MHD_FEATURE_MESSAGES: | 7073 | case MHD_FEATURE_MESSAGES: |
7001 | #ifdef HAVE_MESSAGES | 7074 | #ifdef HAVE_MESSAGES |
7002 | return MHD_YES; | 7075 | return MHD_YES; |
7003 | #else | 7076 | #else |
7004 | return MHD_NO; | 7077 | return MHD_NO; |
7005 | #endif | 7078 | #endif |
7006 | case MHD_FEATURE_TLS: | 7079 | case MHD_FEATURE_TLS: |
7007 | #ifdef HTTPS_SUPPORT | 7080 | #ifdef HTTPS_SUPPORT |
7008 | return MHD_YES; | 7081 | return MHD_YES; |
7009 | #else /* ! HTTPS_SUPPORT */ | 7082 | #else /* ! HTTPS_SUPPORT */ |
7010 | return MHD_NO; | 7083 | return MHD_NO; |
7011 | #endif /* ! HTTPS_SUPPORT */ | 7084 | #endif /* ! HTTPS_SUPPORT */ |
7012 | case MHD_FEATURE_HTTPS_CERT_CALLBACK: | 7085 | case MHD_FEATURE_HTTPS_CERT_CALLBACK: |
7013 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 | 7086 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_MAJOR >= 3 |
7014 | return MHD_YES; | 7087 | return MHD_YES; |
7015 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ | 7088 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ |
7016 | return MHD_NO; | 7089 | return MHD_NO; |
7017 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ | 7090 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_MAJOR < 3 */ |
7018 | case MHD_FEATURE_HTTPS_CERT_CALLBACK2: | 7091 | case MHD_FEATURE_HTTPS_CERT_CALLBACK2: |
7019 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603 | 7092 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030603 |
7020 | return MHD_YES; | 7093 | return MHD_YES; |
7021 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ | 7094 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ |
7022 | return MHD_NO; | 7095 | return MHD_NO; |
7023 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ | 7096 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030603 */ |
7024 | case MHD_FEATURE_IPv6: | 7097 | case MHD_FEATURE_IPv6: |
7025 | #ifdef HAVE_INET6 | 7098 | #ifdef HAVE_INET6 |
7026 | return MHD_YES; | 7099 | return MHD_YES; |
7027 | #else | 7100 | #else |
7028 | return MHD_NO; | 7101 | return MHD_NO; |
7029 | #endif | 7102 | #endif |
7030 | case MHD_FEATURE_IPv6_ONLY: | 7103 | case MHD_FEATURE_IPv6_ONLY: |
7031 | #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) | 7104 | #if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY) |
7032 | return MHD_YES; | 7105 | return MHD_YES; |
7033 | #else | 7106 | #else |
7034 | return MHD_NO; | 7107 | return MHD_NO; |
7035 | #endif | 7108 | #endif |
7036 | case MHD_FEATURE_POLL: | 7109 | case MHD_FEATURE_POLL: |
7037 | #ifdef HAVE_POLL | 7110 | #ifdef HAVE_POLL |
7038 | return MHD_YES; | 7111 | return MHD_YES; |
7039 | #else | 7112 | #else |
7040 | return MHD_NO; | 7113 | return MHD_NO; |
7041 | #endif | 7114 | #endif |
7042 | case MHD_FEATURE_EPOLL: | 7115 | case MHD_FEATURE_EPOLL: |
7043 | #ifdef EPOLL_SUPPORT | 7116 | #ifdef EPOLL_SUPPORT |
7044 | return MHD_YES; | 7117 | return MHD_YES; |
7045 | #else | 7118 | #else |
7046 | return MHD_NO; | 7119 | return MHD_NO; |
7047 | #endif | 7120 | #endif |
7048 | case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: | 7121 | case MHD_FEATURE_SHUTDOWN_LISTEN_SOCKET: |
7049 | #ifdef HAVE_LISTEN_SHUTDOWN | 7122 | #ifdef HAVE_LISTEN_SHUTDOWN |
7050 | return MHD_YES; | 7123 | return MHD_YES; |
7051 | #else | 7124 | #else |
7052 | return MHD_NO; | 7125 | return MHD_NO; |
7053 | #endif | 7126 | #endif |
7054 | case MHD_FEATURE_SOCKETPAIR: | 7127 | case MHD_FEATURE_SOCKETPAIR: |
7055 | #ifdef _MHD_ITC_SOCKETPAIR | 7128 | #ifdef _MHD_ITC_SOCKETPAIR |
7056 | return MHD_YES; | 7129 | return MHD_YES; |
7057 | #else | 7130 | #else |
7058 | return MHD_NO; | 7131 | return MHD_NO; |
7059 | #endif | 7132 | #endif |
7060 | case MHD_FEATURE_TCP_FASTOPEN: | 7133 | case MHD_FEATURE_TCP_FASTOPEN: |
7061 | #ifdef TCP_FASTOPEN | 7134 | #ifdef TCP_FASTOPEN |
7062 | return MHD_YES; | 7135 | return MHD_YES; |
7063 | #else | 7136 | #else |
7064 | return MHD_NO; | 7137 | return MHD_NO; |
7065 | #endif | 7138 | #endif |
7066 | case MHD_FEATURE_BASIC_AUTH: | 7139 | case MHD_FEATURE_BASIC_AUTH: |
7067 | #ifdef BAUTH_SUPPORT | 7140 | #ifdef BAUTH_SUPPORT |
7068 | return MHD_YES; | 7141 | return MHD_YES; |
7069 | #else | 7142 | #else |
7070 | return MHD_NO; | 7143 | return MHD_NO; |
7071 | #endif | 7144 | #endif |
7072 | case MHD_FEATURE_DIGEST_AUTH: | 7145 | case MHD_FEATURE_DIGEST_AUTH: |
7073 | #ifdef DAUTH_SUPPORT | 7146 | #ifdef DAUTH_SUPPORT |
7074 | return MHD_YES; | 7147 | return MHD_YES; |
7075 | #else | 7148 | #else |
7076 | return MHD_NO; | 7149 | return MHD_NO; |
7077 | #endif | 7150 | #endif |
7078 | case MHD_FEATURE_POSTPROCESSOR: | 7151 | case MHD_FEATURE_POSTPROCESSOR: |
7079 | #ifdef HAVE_POSTPROCESSOR | 7152 | #ifdef HAVE_POSTPROCESSOR |
7080 | return MHD_YES; | 7153 | return MHD_YES; |
7081 | #else | 7154 | #else |
7082 | return MHD_NO; | 7155 | return MHD_NO; |
7083 | #endif | 7156 | #endif |
7084 | case MHD_FEATURE_HTTPS_KEY_PASSWORD: | 7157 | case MHD_FEATURE_HTTPS_KEY_PASSWORD: |
7085 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 | 7158 | #if defined(HTTPS_SUPPORT) && GNUTLS_VERSION_NUMBER >= 0x030111 |
7086 | return MHD_YES; | 7159 | return MHD_YES; |
7087 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ | 7160 | #else /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ |
7088 | return MHD_NO; | 7161 | return MHD_NO; |
7089 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ | 7162 | #endif /* !HTTPS_SUPPORT || GNUTLS_VERSION_NUMBER < 0x030111 */ |
7090 | case MHD_FEATURE_LARGE_FILE: | 7163 | case MHD_FEATURE_LARGE_FILE: |
7091 | #if defined(HAVE_PREAD64) || defined(_WIN32) | 7164 | #if defined(HAVE_PREAD64) || defined(_WIN32) |
7092 | return MHD_YES; | 7165 | return MHD_YES; |
7093 | #elif defined(HAVE_PREAD) | 7166 | #elif defined(HAVE_PREAD) |
7094 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; | 7167 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; |
7095 | #elif defined(HAVE_LSEEK64) | 7168 | #elif defined(HAVE_LSEEK64) |
7096 | return MHD_YES; | 7169 | return MHD_YES; |
7097 | #else | 7170 | #else |
7098 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; | 7171 | return (sizeof(uint64_t) > sizeof(off_t)) ? MHD_NO : MHD_YES; |
7099 | #endif | 7172 | #endif |
7100 | case MHD_FEATURE_THREAD_NAMES: | 7173 | case MHD_FEATURE_THREAD_NAMES: |
7101 | #if defined(MHD_USE_THREAD_NAME_) | 7174 | #if defined(MHD_USE_THREAD_NAME_) |
7102 | return MHD_YES; | 7175 | return MHD_YES; |
7103 | #else | 7176 | #else |
7104 | return MHD_NO; | 7177 | return MHD_NO; |
7105 | #endif | 7178 | #endif |
7106 | case MHD_FEATURE_UPGRADE: | 7179 | case MHD_FEATURE_UPGRADE: |
7107 | #if defined(UPGRADE_SUPPORT) | 7180 | #if defined(UPGRADE_SUPPORT) |
7108 | return MHD_YES; | 7181 | return MHD_YES; |
7109 | #else | 7182 | #else |
7110 | return MHD_NO; | 7183 | return MHD_NO; |
7111 | #endif | 7184 | #endif |
7112 | case MHD_FEATURE_RESPONSES_SHARED_FD: | 7185 | case MHD_FEATURE_RESPONSES_SHARED_FD: |
7113 | #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) | 7186 | #if defined(HAVE_PREAD64) || defined(HAVE_PREAD) || defined(_WIN32) |
7114 | return MHD_YES; | 7187 | return MHD_YES; |
7115 | #else | 7188 | #else |
7116 | return MHD_NO; | 7189 | return MHD_NO; |
7117 | #endif | 7190 | #endif |
7118 | case MHD_FEATURE_AUTODETECT_BIND_PORT: | 7191 | case MHD_FEATURE_AUTODETECT_BIND_PORT: |
7119 | #ifdef MHD_USE_GETSOCKNAME | 7192 | #ifdef MHD_USE_GETSOCKNAME |
7120 | return MHD_YES; | 7193 | return MHD_YES; |
7121 | #else | 7194 | #else |
7122 | return MHD_NO; | 7195 | return MHD_NO; |
7123 | #endif | 7196 | #endif |
7124 | case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE: | 7197 | case MHD_FEATURE_AUTOSUPPRESS_SIGPIPE: |
7125 | #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || defined (MSG_NOSIGNAL) | 7198 | #if defined(MHD_WINSOCK_SOCKETS) || defined(MHD_socket_nosignal_) || \ |
7126 | return MHD_YES; | 7199 | defined (MSG_NOSIGNAL) |
7200 | return MHD_YES; | ||
7127 | #else | 7201 | #else |
7128 | return MHD_NO; | 7202 | return MHD_NO; |
7129 | #endif | 7203 | #endif |
7130 | case MHD_FEATURE_SENDFILE: | 7204 | case MHD_FEATURE_SENDFILE: |
7131 | #ifdef _MHD_HAVE_SENDFILE | 7205 | #ifdef _MHD_HAVE_SENDFILE |
7132 | return MHD_YES; | 7206 | return MHD_YES; |
7133 | #else | 7207 | #else |
7134 | return MHD_NO; | 7208 | return MHD_NO; |
7135 | #endif | 7209 | #endif |
7136 | case MHD_FEATURE_THREADS: | 7210 | case MHD_FEATURE_THREADS: |
7137 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) | 7211 | #if defined(MHD_USE_POSIX_THREADS) || defined(MHD_USE_W32_THREADS) |
7138 | return MHD_YES; | 7212 | return MHD_YES; |
7139 | #else | 7213 | #else |
7140 | return MHD_NO; | 7214 | return MHD_NO; |
7141 | #endif | 7215 | #endif |
7142 | 7216 | ||
7143 | } | 7217 | } |
7144 | return MHD_NO; | 7218 | return MHD_NO; |
7145 | } | 7219 | } |
7146 | 7220 | ||
@@ -7158,12 +7232,12 @@ gcry_w32_mutex_init (void **ppmtx) | |||
7158 | 7232 | ||
7159 | if (NULL == *ppmtx) | 7233 | if (NULL == *ppmtx) |
7160 | return ENOMEM; | 7234 | return ENOMEM; |
7161 | if (!MHD_mutex_init_ ((MHD_mutex_*)*ppmtx)) | 7235 | if (! MHD_mutex_init_ ((MHD_mutex_*) *ppmtx)) |
7162 | { | 7236 | { |
7163 | free (*ppmtx); | 7237 | free (*ppmtx); |
7164 | *ppmtx = NULL; | 7238 | *ppmtx = NULL; |
7165 | return EPERM; | 7239 | return EPERM; |
7166 | } | 7240 | } |
7167 | 7241 | ||
7168 | return 0; | 7242 | return 0; |
7169 | } | 7243 | } |
@@ -7172,7 +7246,7 @@ gcry_w32_mutex_init (void **ppmtx) | |||
7172 | static int | 7246 | static int |
7173 | gcry_w32_mutex_destroy (void **ppmtx) | 7247 | gcry_w32_mutex_destroy (void **ppmtx) |
7174 | { | 7248 | { |
7175 | int res = (MHD_mutex_destroy_ ((MHD_mutex_*)*ppmtx)) ? 0 : EINVAL; | 7249 | int res = (MHD_mutex_destroy_ ((MHD_mutex_*) *ppmtx)) ? 0 : EINVAL; |
7176 | free (*ppmtx); | 7250 | free (*ppmtx); |
7177 | return res; | 7251 | return res; |
7178 | } | 7252 | } |
@@ -7181,14 +7255,14 @@ gcry_w32_mutex_destroy (void **ppmtx) | |||
7181 | static int | 7255 | static int |
7182 | gcry_w32_mutex_lock (void **ppmtx) | 7256 | gcry_w32_mutex_lock (void **ppmtx) |
7183 | { | 7257 | { |
7184 | return MHD_mutex_lock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL; | 7258 | return MHD_mutex_lock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL; |
7185 | } | 7259 | } |
7186 | 7260 | ||
7187 | 7261 | ||
7188 | static int | 7262 | static int |
7189 | gcry_w32_mutex_unlock (void **ppmtx) | 7263 | gcry_w32_mutex_unlock (void **ppmtx) |
7190 | { | 7264 | { |
7191 | return MHD_mutex_unlock_ ((MHD_mutex_*)*ppmtx) ? 0 : EINVAL; | 7265 | return MHD_mutex_unlock_ ((MHD_mutex_*) *ppmtx) ? 0 : EINVAL; |
7192 | } | 7266 | } |
7193 | 7267 | ||
7194 | 7268 | ||
@@ -7196,7 +7270,8 @@ static struct gcry_thread_cbs gcry_threads_w32 = { | |||
7196 | (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)), | 7270 | (GCRY_THREAD_OPTION_USER | (GCRY_THREAD_OPTION_VERSION << 8)), |
7197 | NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy, | 7271 | NULL, gcry_w32_mutex_init, gcry_w32_mutex_destroy, |
7198 | gcry_w32_mutex_lock, gcry_w32_mutex_unlock, | 7272 | gcry_w32_mutex_lock, gcry_w32_mutex_unlock, |
7199 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; | 7273 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL |
7274 | }; | ||
7200 | 7275 | ||
7201 | #endif /* defined(MHD_W32_MUTEX_) */ | 7276 | #endif /* defined(MHD_W32_MUTEX_) */ |
7202 | #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */ | 7277 | #endif /* HTTPS_SUPPORT && GCRYPT_VERSION_NUMBER < 0x010600 */ |
@@ -7206,7 +7281,7 @@ static struct gcry_thread_cbs gcry_threads_w32 = { | |||
7206 | * Initialize do setup work. | 7281 | * Initialize do setup work. |
7207 | */ | 7282 | */ |
7208 | void | 7283 | void |
7209 | MHD_init(void) | 7284 | MHD_init (void) |
7210 | { | 7285 | { |
7211 | #if defined(MHD_WINSOCK_SOCKETS) | 7286 | #if defined(MHD_WINSOCK_SOCKETS) |
7212 | WSADATA wsd; | 7287 | WSADATA wsd; |
@@ -7216,11 +7291,11 @@ MHD_init(void) | |||
7216 | mhd_panic = &mhd_panic_std; | 7291 | mhd_panic = &mhd_panic_std; |
7217 | 7292 | ||
7218 | #if defined(MHD_WINSOCK_SOCKETS) | 7293 | #if defined(MHD_WINSOCK_SOCKETS) |
7219 | if (0 != WSAStartup(MAKEWORD(2, 2), &wsd)) | 7294 | if (0 != WSAStartup (MAKEWORD (2, 2), &wsd)) |
7220 | MHD_PANIC (_("Failed to initialize winsock\n")); | 7295 | MHD_PANIC (_ ("Failed to initialize winsock\n")); |
7221 | mhd_winsock_inited_ = 1; | 7296 | mhd_winsock_inited_ = 1; |
7222 | if (2 != LOBYTE(wsd.wVersion) && 2 != HIBYTE(wsd.wVersion)) | 7297 | if ((2 != LOBYTE (wsd.wVersion))&&(2 != HIBYTE (wsd.wVersion))) |
7223 | MHD_PANIC (_("Winsock version 2.2 is not available\n")); | 7298 | MHD_PANIC (_ ("Winsock version 2.2 is not available\n")); |
7224 | #endif /* MHD_WINSOCK_SOCKETS */ | 7299 | #endif /* MHD_WINSOCK_SOCKETS */ |
7225 | #ifdef HTTPS_SUPPORT | 7300 | #ifdef HTTPS_SUPPORT |
7226 | #ifdef MHD_HTTPS_REQUIRE_GRYPT | 7301 | #ifdef MHD_HTTPS_REQUIRE_GRYPT |
@@ -7228,21 +7303,22 @@ MHD_init(void) | |||
7228 | #if defined(MHD_USE_POSIX_THREADS) | 7303 | #if defined(MHD_USE_POSIX_THREADS) |
7229 | if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, | 7304 | if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, |
7230 | &gcry_threads_pthread)) | 7305 | &gcry_threads_pthread)) |
7231 | MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n")); | 7306 | MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt\n")); |
7232 | #elif defined(MHD_W32_MUTEX_) | 7307 | #elif defined(MHD_W32_MUTEX_) |
7233 | if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, | 7308 | if (0 != gcry_control (GCRYCTL_SET_THREAD_CBS, |
7234 | &gcry_threads_w32)) | 7309 | &gcry_threads_w32)) |
7235 | MHD_PANIC (_("Failed to initialise multithreading in libgcrypt\n")); | 7310 | MHD_PANIC (_ ("Failed to initialise multithreading in libgcrypt\n")); |
7236 | #endif /* defined(MHD_W32_MUTEX_) */ | 7311 | #endif /* defined(MHD_W32_MUTEX_) */ |
7237 | gcry_check_version (NULL); | 7312 | gcry_check_version (NULL); |
7238 | #else | 7313 | #else |
7239 | if (NULL == gcry_check_version ("1.6.0")) | 7314 | if (NULL == gcry_check_version ("1.6.0")) |
7240 | MHD_PANIC (_("libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n")); | 7315 | MHD_PANIC (_ ( |
7316 | "libgcrypt is too old. MHD was compiled for libgcrypt 1.6.0 or newer\n")); | ||
7241 | #endif | 7317 | #endif |
7242 | #endif /* MHD_HTTPS_REQUIRE_GRYPT */ | 7318 | #endif /* MHD_HTTPS_REQUIRE_GRYPT */ |
7243 | gnutls_global_init (); | 7319 | gnutls_global_init (); |
7244 | #endif /* HTTPS_SUPPORT */ | 7320 | #endif /* HTTPS_SUPPORT */ |
7245 | MHD_monotonic_sec_counter_init(); | 7321 | MHD_monotonic_sec_counter_init (); |
7246 | #ifdef HAVE_FREEBSD_SENDFILE | 7322 | #ifdef HAVE_FREEBSD_SENDFILE |
7247 | MHD_conn_init_static_ (); | 7323 | MHD_conn_init_static_ (); |
7248 | #endif /* HAVE_FREEBSD_SENDFILE */ | 7324 | #endif /* HAVE_FREEBSD_SENDFILE */ |
@@ -7251,20 +7327,20 @@ MHD_init(void) | |||
7251 | 7327 | ||
7252 | 7328 | ||
7253 | void | 7329 | void |
7254 | MHD_fini(void) | 7330 | MHD_fini (void) |
7255 | { | 7331 | { |
7256 | #ifdef HTTPS_SUPPORT | 7332 | #ifdef HTTPS_SUPPORT |
7257 | gnutls_global_deinit (); | 7333 | gnutls_global_deinit (); |
7258 | #endif /* HTTPS_SUPPORT */ | 7334 | #endif /* HTTPS_SUPPORT */ |
7259 | #if defined(MHD_WINSOCK_SOCKETS) | 7335 | #if defined(MHD_WINSOCK_SOCKETS) |
7260 | if (mhd_winsock_inited_) | 7336 | if (mhd_winsock_inited_) |
7261 | WSACleanup(); | 7337 | WSACleanup (); |
7262 | #endif /* MHD_WINSOCK_SOCKETS */ | 7338 | #endif /* MHD_WINSOCK_SOCKETS */ |
7263 | MHD_monotonic_sec_counter_finish(); | 7339 | MHD_monotonic_sec_counter_finish (); |
7264 | } | 7340 | } |
7265 | 7341 | ||
7266 | #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED | 7342 | #ifdef _AUTOINIT_FUNCS_ARE_SUPPORTED |
7267 | _SET_INIT_AND_DEINIT_FUNCS(MHD_init, MHD_fini); | 7343 | _SET_INIT_AND_DEINIT_FUNCS (MHD_init, MHD_fini); |
7268 | #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */ | 7344 | #endif /* _AUTOINIT_FUNCS_ARE_SUPPORTED */ |
7269 | 7345 | ||
7270 | /* end of daemon.c */ | 7346 | /* end of daemon.c */ |