aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r--src/microhttpd/daemon.c7140
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 */
116static int 116static int
117MHD_epoll (struct MHD_Daemon *daemon, 117MHD_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 */
131static void 131static void
132mhd_panic_std (void *cls, 132mhd_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 */
166void 166void
167MHD_init(void); 167MHD_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 */
194MHD_MUTEX_STATIC_DEFN_INIT_(global_init_mutex_); 194MHD_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
308MHD_ip_count_lock (struct MHD_Daemon *daemon) 308MHD_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
324MHD_ip_count_unlock (struct MHD_Daemon *daemon) 324MHD_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 */
362static int 362static int
363MHD_ip_addr_to_key (const struct sockaddr *addr, 363MHD_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 */
413static int 413static int
414MHD_ip_limit_add (struct MHD_Daemon *daemon, 414MHD_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 */
479static void 479static void
480MHD_ip_limit_del (struct MHD_Daemon *daemon, 480MHD_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
663MHD_TLS_init (struct MHD_Daemon *daemon) 664MHD_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 */
870static void 871static void
871urh_update_pollfd (struct MHD_UpgradeResponseHandle *urh, 872urh_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 */
911static void 912static void
912urh_to_pollfd (struct MHD_UpgradeResponseHandle *urh, 913urh_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 */
927static void 928static void
928urh_from_pollfd (struct MHD_UpgradeResponseHandle *urh, 929urh_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 */
1119int 1120int
1120MHD_get_fdset2 (struct MHD_Daemon *daemon, 1121MHD_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);
2174exit: 2185exit:
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
2210MHD_cleanup_connections (struct MHD_Daemon *daemon); 2222MHD_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 */
2228static ssize_t 2240static ssize_t
2229MHD_tls_push_func_(gnutls_transport_ptr_t trnsp, 2241MHD_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 */
2250static int 2262static int
2251psk_gnutls_adapter (gnutls_session_t session, 2263psk_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: 2745cleanup:
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)
2871void 2889void
2872MHD_suspend_connection (struct MHD_Connection *connection) 2890MHD_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 */
3649static int 3678static int
3650MHD_select (struct MHD_Daemon *daemon, 3679MHD_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, &ltimeout)) ) 3798 (MHD_YES == MHD_get_timeout (daemon, &ltimeout)) )
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 */
3815static int 3845static int
3816MHD_poll_all (struct MHD_Daemon *daemon, 3846MHD_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 &ltimeout)) ) 3917 &ltimeout)) )
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 */
4029static int 4060static int
4030MHD_poll_listen_socket (struct MHD_Daemon *daemon, 4061MHD_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 */
4111static int 4142static int
4112MHD_poll (struct MHD_Daemon *daemon, 4143MHD_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 */
4153static bool 4184static bool
4154is_urh_ready(struct MHD_UpgradeResponseHandle * const urh) 4185is_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 */
4296static const char * const epoll_itc_marker = "itc_marker"; 4327static 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 */
4925static int 4959static int
4926parse_options (struct MHD_Daemon *daemon, 4960parse_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: 6573free_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
6561close_all_connections (struct MHD_Daemon *daemon) 6627close_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 */
6880const union MHD_DaemonInfo * 6953const union MHD_DaemonInfo *
6881MHD_get_daemon_info (struct MHD_Daemon *daemon, 6954MHD_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
6996MHD_is_feature_supported(enum MHD_FEATURE feature) 7069MHD_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)
7172static int 7246static int
7173gcry_w32_mutex_destroy (void **ppmtx) 7247gcry_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)
7181static int 7255static int
7182gcry_w32_mutex_lock (void **ppmtx) 7256gcry_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
7188static int 7262static int
7189gcry_w32_mutex_unlock (void **ppmtx) 7263gcry_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 */
7208void 7283void
7209MHD_init(void) 7284MHD_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
7253void 7329void
7254MHD_fini(void) 7330MHD_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 */