diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-09-30 15:11:34 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-09-30 15:11:34 +0000 |
commit | ba5dd9b5260f0c59476e47b4cbf89ab211afd3c5 (patch) | |
tree | c9eb24162c98dc4655df9d35a24fd28aab5df7a6 /src/transport/plugin_transport_http_server.c | |
parent | 737167bff883a978f98c15216d1bfa82068072d0 (diff) | |
download | gnunet-ba5dd9b5260f0c59476e47b4cbf89ab211afd3c5.tar.gz gnunet-ba5dd9b5260f0c59476e47b4cbf89ab211afd3c5.zip |
added functionality: immediate server rescheduling
+ debugging functionality to find server disconnect problem
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 143 |
1 files changed, 85 insertions, 58 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index 629ea9524..73c964ceb 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c | |||
@@ -30,16 +30,6 @@ | |||
30 | #define _RECEIVE 0 | 30 | #define _RECEIVE 0 |
31 | #define _SEND 1 | 31 | #define _SEND 1 |
32 | 32 | ||
33 | static void | ||
34 | server_log (void *arg, const char *fmt, va_list ap) | ||
35 | { | ||
36 | char text[1024]; | ||
37 | |||
38 | vsnprintf (text, sizeof (text), fmt, ap); | ||
39 | va_end (ap); | ||
40 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Server: %s\n", text); | ||
41 | } | ||
42 | |||
43 | struct ServerConnection | 33 | struct ServerConnection |
44 | { | 34 | { |
45 | /* _RECV or _SEND */ | 35 | /* _RECV or _SEND */ |
@@ -53,6 +43,26 @@ struct ServerConnection | |||
53 | }; | 43 | }; |
54 | 44 | ||
55 | /** | 45 | /** |
46 | * Function that queries MHD's select sets and | ||
47 | * starts the task waiting for them. | ||
48 | * @param plugin plugin | ||
49 | * @param daemon_handle the MHD daemon handle | ||
50 | * @return gnunet task identifier | ||
51 | */ | ||
52 | static GNUNET_SCHEDULER_TaskIdentifier | ||
53 | server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, int now); | ||
54 | |||
55 | static void | ||
56 | server_log (void *arg, const char *fmt, va_list ap) | ||
57 | { | ||
58 | char text[1024]; | ||
59 | |||
60 | vsnprintf (text, sizeof (text), fmt, ap); | ||
61 | va_end (ap); | ||
62 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Server: %s\n", text); | ||
63 | } | ||
64 | |||
65 | /** | ||
56 | * Check if incoming connection is accepted. | 66 | * Check if incoming connection is accepted. |
57 | * NOTE: Here every connection is accepted | 67 | * NOTE: Here every connection is accepted |
58 | * @param cls plugin as closure | 68 | * @param cls plugin as closure |
@@ -212,6 +222,36 @@ server_load_certificate (struct Plugin *plugin) | |||
212 | } | 222 | } |
213 | #endif | 223 | #endif |
214 | 224 | ||
225 | /** | ||
226 | * Reschedule the execution of both IPv4 and IPv6 server | ||
227 | * @param plugin the plugin | ||
228 | * @param now GNUNET_YES to schedule execution immediately, GNUNET_NO to wait | ||
229 | * until timeout | ||
230 | */ | ||
231 | |||
232 | static void | ||
233 | server_reschedule (struct Plugin *plugin, int now) | ||
234 | { | ||
235 | if (plugin->server_v4 != NULL) | ||
236 | { | ||
237 | if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK) | ||
238 | { | ||
239 | GNUNET_SCHEDULER_cancel(plugin->server_v4_task); | ||
240 | plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK; | ||
241 | } | ||
242 | plugin->server_v4_task = server_schedule (plugin, plugin->server_v4, now); | ||
243 | } | ||
244 | |||
245 | if (plugin->server_v6 != NULL) | ||
246 | { | ||
247 | if (plugin->server_v6_task != GNUNET_SCHEDULER_NO_TASK) | ||
248 | { | ||
249 | GNUNET_SCHEDULER_cancel(plugin->server_v6_task); | ||
250 | plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; | ||
251 | } | ||
252 | plugin->server_v6_task = server_schedule (plugin, plugin->server_v6, now); | ||
253 | } | ||
254 | } | ||
215 | 255 | ||
216 | /** | 256 | /** |
217 | * Callback called by MessageStreamTokenizer when a message has arrived | 257 | * Callback called by MessageStreamTokenizer when a message has arrived |
@@ -453,7 +493,6 @@ create: | |||
453 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) | 493 | if (0 == strcmp (MHD_HTTP_METHOD_GET, method)) |
454 | s->server_send = s; | 494 | s->server_send = s; |
455 | GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s); | 495 | GNUNET_CONTAINER_DLL_insert (plugin->server_semi_head, plugin->server_semi_tail, s); |
456 | |||
457 | goto found; | 496 | goto found; |
458 | 497 | ||
459 | error: | 498 | error: |
@@ -473,22 +512,18 @@ found: | |||
473 | if (direction == _RECEIVE) | 512 | if (direction == _RECEIVE) |
474 | s->server_recv = sc; | 513 | s->server_recv = sc; |
475 | 514 | ||
515 | #if MHD_VERSION >= 0x00090E00 | ||
476 | int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); | 516 | int to = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value / 1000); |
477 | #if VERBOSE_SERVER | 517 | #if VERBOSE_SERVER |
478 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
479 | "Server: Setting Timeout to %u\n", to); | ||
480 | #endif | ||
481 | #if MHD_VERSION >= 0x00090E00 | ||
482 | #if 0 | ||
483 | struct ServerConnection *stc = NULL; | ||
484 | stc = s->server_send; | ||
485 | /* Set timeout for this connection */ | ||
486 | MHD_set_connection_option (stc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, to); | ||
487 | /* set timeout for other semi connection */ | ||
488 | stc = s->server_recv; | ||
489 | MHD_set_connection_option (stc->mhd_conn, MHD_CONNECTION_OPTION_TIMEOUT, to); | ||
490 | #endif | 518 | #endif |
519 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
520 | "Server: Setting timeout for %X to %u sec.\n", sc, to); | ||
521 | |||
522 | MHD_set_connection_option (mhd_connection, MHD_CONNECTION_OPTION_TIMEOUT, to); | ||
523 | server_reschedule (plugin, GNUNET_NO); | ||
491 | #endif | 524 | #endif |
525 | |||
526 | |||
492 | return sc; | 527 | return sc; |
493 | } | 528 | } |
494 | 529 | ||
@@ -610,16 +645,6 @@ server_access_cb (void *cls, struct MHD_Connection *mhd_connection, | |||
610 | return res; | 645 | return res; |
611 | } | 646 | } |
612 | 647 | ||
613 | /** | ||
614 | * Function that queries MHD's select sets and | ||
615 | * starts the task waiting for them. | ||
616 | * @param plugin plugin | ||
617 | * @param daemon_handle the MHD daemon handle | ||
618 | * @return gnunet task identifier | ||
619 | */ | ||
620 | static GNUNET_SCHEDULER_TaskIdentifier | ||
621 | server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle); | ||
622 | |||
623 | static void | 648 | static void |
624 | server_disconnect_cb (void *cls, struct MHD_Connection *connection, | 649 | server_disconnect_cb (void *cls, struct MHD_Connection *connection, |
625 | void **httpSessionCache) | 650 | void **httpSessionCache) |
@@ -638,8 +663,9 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, | |||
638 | if (sc->direction == _SEND) | 663 | if (sc->direction == _SEND) |
639 | { | 664 | { |
640 | #if VERBOSE_SERVER | 665 | #if VERBOSE_SERVER |
641 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 666 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, |
642 | "Server: peer `%s' GET on address `%s' disconnected\n", | 667 | "Server: %X peer `%s' GET on address `%s' disconnected\n", |
668 | s->server_send, | ||
643 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen)); | 669 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen)); |
644 | #endif | 670 | #endif |
645 | s->server_send = NULL; | 671 | s->server_send = NULL; |
@@ -656,8 +682,9 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, | |||
656 | if (sc->direction == _RECEIVE) | 682 | if (sc->direction == _RECEIVE) |
657 | { | 683 | { |
658 | #if VERBOSE_SERVER | 684 | #if VERBOSE_SERVER |
659 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 685 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, |
660 | "Server: peer `%s' PUT on address `%s' disconnected\n", | 686 | "Server: %X peer `%s' PUT on address `%s' disconnected\n", |
687 | s->server_recv, | ||
661 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen)); | 688 | GNUNET_i2s (&s->target), GNUNET_a2s (s->addr, s->addrlen)); |
662 | #endif | 689 | #endif |
663 | s->server_recv = NULL; | 690 | s->server_recv = NULL; |
@@ -689,21 +716,9 @@ server_disconnect_cb (void *cls, struct MHD_Connection *connection, | |||
689 | t = t->next; | 716 | t = t->next; |
690 | } | 717 | } |
691 | plugin->cur_connections--; | 718 | plugin->cur_connections--; |
692 | /* | ||
693 | if (plugin->server_v4_task != GNUNET_SCHEDULER_NO_TASK) | ||
694 | { | ||
695 | GNUNET_SCHEDULER_cancel(plugin->server_v4_task); | ||
696 | plugin->server_v4_task = GNUNET_SCHEDULER_NO_TASK; | ||
697 | } | ||
698 | plugin->server_v4_task = server_schedule (plugin, plugin->server_v4); | ||
699 | 719 | ||
700 | if (plugin->server_v6_task != GNUNET_SCHEDULER_NO_TASK) | 720 | server_reschedule (plugin, GNUNET_NO); |
701 | { | 721 | |
702 | GNUNET_SCHEDULER_cancel(plugin->server_v6_task); | ||
703 | plugin->server_v6_task = GNUNET_SCHEDULER_NO_TASK; | ||
704 | } | ||
705 | plugin->server_v6_task = server_schedule (plugin, plugin->server_v6); | ||
706 | */ | ||
707 | if ((s->server_send == NULL) && (s->server_recv == NULL)) | 722 | if ((s->server_send == NULL) && (s->server_recv == NULL)) |
708 | { | 723 | { |
709 | #if VERBOSE_SERVER | 724 | #if VERBOSE_SERVER |
@@ -751,6 +766,7 @@ int | |||
751 | server_send (struct Session *s, struct HTTP_Message * msg) | 766 | server_send (struct Session *s, struct HTTP_Message * msg) |
752 | { | 767 | { |
753 | GNUNET_CONTAINER_DLL_insert (s->msg_head, s->msg_tail, msg); | 768 | GNUNET_CONTAINER_DLL_insert (s->msg_head, s->msg_tail, msg); |
769 | server_reschedule (s->plugin, GNUNET_YES); | ||
754 | return GNUNET_OK; | 770 | return GNUNET_OK; |
755 | } | 771 | } |
756 | 772 | ||
@@ -775,7 +791,7 @@ server_v4_run (void *cls, | |||
775 | return; | 791 | return; |
776 | 792 | ||
777 | GNUNET_assert (MHD_YES == MHD_run (plugin->server_v4)); | 793 | GNUNET_assert (MHD_YES == MHD_run (plugin->server_v4)); |
778 | plugin->server_v4_task = server_schedule (plugin, plugin->server_v4); | 794 | plugin->server_v4_task = server_schedule (plugin, plugin->server_v4, GNUNET_NO); |
779 | } | 795 | } |
780 | 796 | ||
781 | 797 | ||
@@ -798,7 +814,7 @@ server_v6_run (void *cls, | |||
798 | return; | 814 | return; |
799 | 815 | ||
800 | GNUNET_assert (MHD_YES == MHD_run (plugin->server_v6)); | 816 | GNUNET_assert (MHD_YES == MHD_run (plugin->server_v6)); |
801 | plugin->server_v6_task = server_schedule (plugin, plugin->server_v6); | 817 | plugin->server_v6_task = server_schedule (plugin, plugin->server_v6, GNUNET_NO); |
802 | } | 818 | } |
803 | 819 | ||
804 | /** | 820 | /** |
@@ -809,7 +825,7 @@ server_v6_run (void *cls, | |||
809 | * @return gnunet task identifier | 825 | * @return gnunet task identifier |
810 | */ | 826 | */ |
811 | static GNUNET_SCHEDULER_TaskIdentifier | 827 | static GNUNET_SCHEDULER_TaskIdentifier |
812 | server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle) | 828 | server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle, int now) |
813 | { | 829 | { |
814 | GNUNET_SCHEDULER_TaskIdentifier ret; | 830 | GNUNET_SCHEDULER_TaskIdentifier ret; |
815 | fd_set rs; | 831 | fd_set rs; |
@@ -820,7 +836,9 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle) | |||
820 | struct GNUNET_NETWORK_FDSet *wes; | 836 | struct GNUNET_NETWORK_FDSet *wes; |
821 | int max; | 837 | int max; |
822 | unsigned long long timeout; | 838 | unsigned long long timeout; |
839 | static unsigned long long last_timeout = 0; | ||
823 | int haveto; | 840 | int haveto; |
841 | |||
824 | struct GNUNET_TIME_Relative tv; | 842 | struct GNUNET_TIME_Relative tv; |
825 | 843 | ||
826 | ret = GNUNET_SCHEDULER_NO_TASK; | 844 | ret = GNUNET_SCHEDULER_NO_TASK; |
@@ -834,9 +852,21 @@ server_schedule (struct Plugin *plugin, struct MHD_Daemon *daemon_handle) | |||
834 | GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &max)); | 852 | GNUNET_assert (MHD_YES == MHD_get_fdset (daemon_handle, &rs, &ws, &es, &max)); |
835 | haveto = MHD_get_timeout (daemon_handle, &timeout); | 853 | haveto = MHD_get_timeout (daemon_handle, &timeout); |
836 | if (haveto == MHD_YES) | 854 | if (haveto == MHD_YES) |
855 | { | ||
856 | if (timeout != last_timeout) | ||
857 | { | ||
858 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, plugin->name, | ||
859 | "SELECT Timeout changed from %llu to %llu\n", | ||
860 | last_timeout, timeout); | ||
861 | last_timeout = timeout; | ||
862 | } | ||
837 | tv.rel_value = (uint64_t) timeout; | 863 | tv.rel_value = (uint64_t) timeout; |
864 | } | ||
838 | else | 865 | else |
839 | tv = GNUNET_TIME_UNIT_SECONDS; | 866 | tv = GNUNET_TIME_UNIT_SECONDS; |
867 | /* Force immediate run, since we have outbound data to send */ | ||
868 | if (now == GNUNET_YES) | ||
869 | tv = GNUNET_TIME_UNIT_MILLISECONDS; | ||
840 | GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); | 870 | GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); |
841 | GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); | 871 | GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); |
842 | GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); | 872 | GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); |
@@ -978,10 +1008,7 @@ server_start (struct Plugin *plugin) | |||
978 | res = GNUNET_SYSERR; | 1008 | res = GNUNET_SYSERR; |
979 | } | 1009 | } |
980 | 1010 | ||
981 | if (plugin->server_v4 != NULL) | 1011 | server_reschedule (plugin, GNUNET_NO); |
982 | plugin->server_v4_task = server_schedule (plugin, plugin->server_v4); | ||
983 | if (plugin->server_v6 != NULL) | ||
984 | plugin->server_v6_task = server_schedule (plugin, plugin->server_v6); | ||
985 | 1012 | ||
986 | #if DEBUG_HTTP | 1013 | #if DEBUG_HTTP |
987 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 1014 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |