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,