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.c105
1 files changed, 62 insertions, 43 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index e00d21e7..1c058da0 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -572,16 +572,33 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
572 * @param fd file descriptor to add to the @a set 572 * @param fd file descriptor to add to the @a set
573 * @param set set to modify 573 * @param set set to modify
574 * @param max_fd maximum value to potentially update 574 * @param max_fd maximum value to potentially update
575 * @return #MHD_YES on success, #MHD_NO otherwise
575 */ 576 */
576static void 577static int
577add_to_fd_set (MHD_socket fd, 578add_to_fd_set (MHD_socket fd,
578 fd_set *set, 579 fd_set *set,
579 MHD_socket *max_fd) 580 MHD_socket *max_fd)
580{ 581{
582 if (NULL == set)
583 return MHD_NO;
584#ifdef MHD_WINSOCK_SOCKETS
585 if (set->fd_count >= FD_SETSIZE)
586 {
587 if (FD_ISSET(fd, set))
588 return MHD_YES;
589 else
590 return MHD_NO;
591 }
592#else // ! MHD_WINSOCK_SOCKETS
593 if (fd >= FD_SETSIZE)
594 return MHD_NO;
595#endif // ! MHD_WINSOCK_SOCKETS
581 FD_SET (fd, set); 596 FD_SET (fd, set);
582 if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) && 597 if ( (NULL != max_fd) && (MHD_INVALID_SOCKET != fd) &&
583 ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) ) 598 ((fd > *max_fd) || (MHD_INVALID_SOCKET == *max_fd)) )
584 *max_fd = fd; 599 *max_fd = fd;
600
601 return MHD_YES;
585} 602}
586 603
587 604
@@ -599,7 +616,8 @@ add_to_fd_set (MHD_socket fd,
599 * than existing value); can be NULL 616 * than existing value); can be NULL
600 * @return #MHD_YES on success, #MHD_NO if this 617 * @return #MHD_YES on success, #MHD_NO if this
601 * daemon was not started with the right 618 * daemon was not started with the right
602 * options for this call. 619 * options for this call or any FD didn't
620 * fit fd_set.
603 * @ingroup event 621 * @ingroup event
604 */ 622 */
605int 623int
@@ -610,7 +628,6 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
610 MHD_socket *max_fd) 628 MHD_socket *max_fd)
611{ 629{
612 struct MHD_Connection *pos; 630 struct MHD_Connection *pos;
613 MHD_socket fd;
614 631
615 if ( (NULL == daemon) 632 if ( (NULL == daemon)
616 || (NULL == read_fd_set) 633 || (NULL == read_fd_set)
@@ -626,38 +643,32 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
626 /* we're in epoll mode, use the epoll FD as a stand-in for 643 /* we're in epoll mode, use the epoll FD as a stand-in for
627 the entire event set */ 644 the entire event set */
628 645
629 if (daemon->epoll_fd >= FD_SETSIZE) 646 return add_to_fd_set (daemon->epoll_fd, read_fd_set, max_fd);
630 return MHD_NO; /* poll fd too big, fail hard */
631 FD_SET (daemon->epoll_fd, read_fd_set);
632 if ( (NULL != max_fd) && ((*max_fd) < daemon->epoll_fd) )
633 *max_fd = daemon->epoll_fd;
634 return MHD_YES;
635 } 647 }
636#endif 648#endif
637 fd = daemon->socket_fd; 649 if (MHD_INVALID_SOCKET != daemon->socket_fd &&
638 if (MHD_INVALID_SOCKET != fd) 650 MHD_YES != add_to_fd_set (daemon->socket_fd, read_fd_set, max_fd))
639 { 651 return MHD_NO;
640 FD_SET (fd, read_fd_set); 652
641 /* update max file descriptor */
642 if ( (NULL != max_fd) &&
643 ((*max_fd) < fd || MHD_INVALID_SOCKET == (*max_fd)))
644 *max_fd = fd;
645 }
646 for (pos = daemon->connections_head; NULL != pos; pos = pos->next) 653 for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
647 { 654 {
648 switch (pos->event_loop_info) 655 switch (pos->event_loop_info)
649 { 656 {
650 case MHD_EVENT_LOOP_INFO_READ: 657 case MHD_EVENT_LOOP_INFO_READ:
651 add_to_fd_set (pos->socket_fd, read_fd_set, max_fd); 658 if (MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
659 return MHD_NO;
652 break; 660 break;
653 case MHD_EVENT_LOOP_INFO_WRITE: 661 case MHD_EVENT_LOOP_INFO_WRITE:
654 add_to_fd_set (pos->socket_fd, write_fd_set, max_fd); 662 if (MHD_YES != add_to_fd_set (pos->socket_fd, write_fd_set, max_fd))
655 if (pos->read_buffer_size > pos->read_buffer_offset) 663 return MHD_NO;
656 add_to_fd_set (pos->socket_fd, read_fd_set, max_fd); 664 if (pos->read_buffer_size > pos->read_buffer_offset &&
665 MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
666 return MHD_NO;
657 break; 667 break;
658 case MHD_EVENT_LOOP_INFO_BLOCK: 668 case MHD_EVENT_LOOP_INFO_BLOCK:
659 if (pos->read_buffer_size > pos->read_buffer_offset) 669 if (pos->read_buffer_size > pos->read_buffer_offset &&
660 add_to_fd_set (pos->socket_fd, read_fd_set, max_fd); 670 MHD_YES != add_to_fd_set (pos->socket_fd, read_fd_set, max_fd))
671 return MHD_NO;
661 break; 672 break;
662 case MHD_EVENT_LOOP_INFO_CLEANUP: 673 case MHD_EVENT_LOOP_INFO_CLEANUP:
663 /* this should never happen */ 674 /* this should never happen */
@@ -724,22 +735,27 @@ MHD_handle_connection (void *data)
724 if (0 == (con->daemon->options & MHD_USE_POLL)) 735 if (0 == (con->daemon->options & MHD_USE_POLL))
725 { 736 {
726 /* use select */ 737 /* use select */
738 int err_state = 0;
727 FD_ZERO (&rs); 739 FD_ZERO (&rs);
728 FD_ZERO (&ws); 740 FD_ZERO (&ws);
729 max = 0; 741 max = 0;
730 switch (con->event_loop_info) 742 switch (con->event_loop_info)
731 { 743 {
732 case MHD_EVENT_LOOP_INFO_READ: 744 case MHD_EVENT_LOOP_INFO_READ:
733 add_to_fd_set (con->socket_fd, &rs, &max); 745 if (MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
746 err_state = 1;
734 break; 747 break;
735 case MHD_EVENT_LOOP_INFO_WRITE: 748 case MHD_EVENT_LOOP_INFO_WRITE:
736 add_to_fd_set (con->socket_fd, &ws, &max); 749 if (MHD_YES != add_to_fd_set (con->socket_fd, &ws, &max))
737 if (con->read_buffer_size > con->read_buffer_offset) 750 err_state = 1;
738 add_to_fd_set (con->socket_fd, &rs, &max); 751 if (con->read_buffer_size > con->read_buffer_offset &&
752 MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
753 err_state = 1;
739 break; 754 break;
740 case MHD_EVENT_LOOP_INFO_BLOCK: 755 case MHD_EVENT_LOOP_INFO_BLOCK:
741 if (con->read_buffer_size > con->read_buffer_offset) 756 if (con->read_buffer_size > con->read_buffer_offset &&
742 add_to_fd_set (con->socket_fd, &rs, &max); 757 MHD_YES != add_to_fd_set (con->socket_fd, &rs, &max))
758 err_state = 1;
743 tv.tv_sec = 0; 759 tv.tv_sec = 0;
744 tv.tv_usec = 0; 760 tv.tv_usec = 0;
745 tvp = &tv; 761 tvp = &tv;
@@ -748,6 +764,15 @@ MHD_handle_connection (void *data)
748 /* how did we get here!? */ 764 /* how did we get here!? */
749 goto exit; 765 goto exit;
750 } 766 }
767 if (0 != err_state)
768 {
769#if HAVE_MESSAGES
770 MHD_DLOG (con->daemon,
771 "Can't add FD to fd_set\n");
772#endif
773 goto exit;
774 }
775
751 num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp); 776 num_ready = MHD_SYS_select_ (max + 1, &rs, &ws, NULL, tvp);
752 if (num_ready < 0) 777 if (num_ready < 0)
753 { 778 {
@@ -756,7 +781,7 @@ MHD_handle_connection (void *data)
756#if HAVE_MESSAGES 781#if HAVE_MESSAGES
757 MHD_DLOG (con->daemon, 782 MHD_DLOG (con->daemon,
758 "Error during select (%d): `%s'\n", 783 "Error during select (%d): `%s'\n",
759 max, 784 MHD_socket_errno_,
760 MHD_socket_last_strerr_ ()); 785 MHD_socket_last_strerr_ ());
761#endif 786#endif
762 break; 787 break;
@@ -2078,19 +2103,13 @@ MHD_select (struct MHD_Daemon *daemon,
2078 else 2103 else
2079 { 2104 {
2080 /* accept only, have one thread per connection */ 2105 /* accept only, have one thread per connection */
2081 if (MHD_INVALID_SOCKET != daemon->socket_fd) 2106 if (MHD_INVALID_SOCKET != daemon->socket_fd &&
2082 { 2107 MHD_YES != add_to_fd_set(daemon->socket_fd, &rs, &max))
2083 max = daemon->socket_fd; 2108 return MHD_NO;
2084 FD_SET (daemon->socket_fd, &rs);
2085 }
2086 }
2087 if (MHD_INVALID_PIPE_ != daemon->wpipe[0])
2088 {
2089 FD_SET (daemon->wpipe[0], &rs);
2090 /* update max file descriptor */
2091 if (max < daemon->wpipe[0] || max == MHD_INVALID_SOCKET)
2092 max = daemon->wpipe[0];
2093 } 2109 }
2110 if (MHD_INVALID_PIPE_ != daemon->wpipe[0] &&
2111 MHD_YES != add_to_fd_set(daemon->wpipe[0], &rs, &max))
2112 return MHD_NO;
2094 2113
2095 tv = NULL; 2114 tv = NULL;
2096 if (MHD_NO == may_block) 2115 if (MHD_NO == may_block)