diff options
Diffstat (limited to 'src/microhttpd/daemon.c')
-rw-r--r-- | src/microhttpd/daemon.c | 105 |
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 | */ |
576 | static void | 577 | static int |
577 | add_to_fd_set (MHD_socket fd, | 578 | add_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 | */ |
605 | int | 623 | int |
@@ -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) |