diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-24 15:18:41 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-08-24 15:18:41 +0000 |
commit | ffd9b2ac043fa379e2d289ef1a7bc9d281de92b1 (patch) | |
tree | c93983cf01271c8a866d2edb5b4ee4edd0d5fff5 /src/transport/plugin_transport_http_client.c | |
parent | 3f70e71b5e73cb6464bcdccdc69be22cfbc3af69 (diff) | |
download | gnunet-ffd9b2ac043fa379e2d289ef1a7bc9d281de92b1.tar.gz gnunet-ffd9b2ac043fa379e2d289ef1a7bc9d281de92b1.zip |
changes to address notification
Diffstat (limited to 'src/transport/plugin_transport_http_client.c')
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 305 |
1 files changed, 196 insertions, 109 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index ff148c2a6..15b6729f4 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -546,10 +546,181 @@ client_receive (void *stream, size_t size, size_t nmemb, void *cls) | |||
546 | * @param tc gnunet scheduler task context | 546 | * @param tc gnunet scheduler task context |
547 | */ | 547 | */ |
548 | static void | 548 | static void |
549 | client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
550 | |||
551 | /** | ||
552 | * Function setting up file descriptors and scheduling task to run | ||
553 | * | ||
554 | * @param plugin plugin as closure | ||
555 | * @param now schedule task in 1ms, regardless of what curl may say | ||
556 | * @return GNUNET_SYSERR for hard failure, GNUNET_OK for ok | ||
557 | */ | ||
558 | static int | ||
559 | client_schedule (struct HTTP_Client_Plugin *plugin, int now) | ||
560 | { | ||
561 | fd_set rs; | ||
562 | fd_set ws; | ||
563 | fd_set es; | ||
564 | int max; | ||
565 | struct GNUNET_NETWORK_FDSet *grs; | ||
566 | struct GNUNET_NETWORK_FDSet *gws; | ||
567 | long to; | ||
568 | CURLMcode mret; | ||
569 | struct GNUNET_TIME_Relative timeout; | ||
570 | |||
571 | /* Cancel previous scheduled task */ | ||
572 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
573 | { | ||
574 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
575 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
576 | } | ||
577 | max = -1; | ||
578 | FD_ZERO (&rs); | ||
579 | FD_ZERO (&ws); | ||
580 | FD_ZERO (&es); | ||
581 | mret = curl_multi_fdset (plugin->curl_multi_handle, &rs, &ws, &es, &max); | ||
582 | if (mret != CURLM_OK) | ||
583 | { | ||
584 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), | ||
585 | "curl_multi_fdset", __FILE__, __LINE__, | ||
586 | curl_multi_strerror (mret)); | ||
587 | return GNUNET_SYSERR; | ||
588 | } | ||
589 | mret = curl_multi_timeout (plugin->curl_multi_handle, &to); | ||
590 | if (to == -1) | ||
591 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1); | ||
592 | else | ||
593 | timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); | ||
594 | if (now == GNUNET_YES) | ||
595 | timeout = GNUNET_TIME_UNIT_MILLISECONDS; | ||
596 | |||
597 | if (mret != CURLM_OK) | ||
598 | { | ||
599 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("%s failed at %s:%d: `%s'\n"), | ||
600 | "curl_multi_timeout", __FILE__, __LINE__, | ||
601 | curl_multi_strerror (mret)); | ||
602 | return GNUNET_SYSERR; | ||
603 | } | ||
604 | |||
605 | grs = GNUNET_NETWORK_fdset_create (); | ||
606 | gws = GNUNET_NETWORK_fdset_create (); | ||
607 | GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); | ||
608 | GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); | ||
609 | |||
610 | plugin->client_perform_task = | ||
611 | GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
612 | timeout, grs, gws, | ||
613 | &client_run, plugin); | ||
614 | GNUNET_NETWORK_fdset_destroy (gws); | ||
615 | GNUNET_NETWORK_fdset_destroy (grs); | ||
616 | return GNUNET_OK; | ||
617 | } | ||
618 | |||
619 | |||
620 | |||
621 | static int | ||
622 | client_disconnect (struct Session *s) | ||
623 | { | ||
624 | |||
625 | int res = GNUNET_OK; | ||
626 | CURLMcode mret; | ||
627 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
628 | struct HTTP_Message *msg; | ||
629 | struct HTTP_Message *t; | ||
630 | |||
631 | if (GNUNET_YES != client_exist_session (plugin, s)) | ||
632 | { | ||
633 | GNUNET_break (0); | ||
634 | return GNUNET_SYSERR; | ||
635 | } | ||
636 | |||
637 | if (s->client_put != NULL) | ||
638 | { | ||
639 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
640 | "Client: %p / %p Deleting outbound PUT session to peer `%s'\n", | ||
641 | s, s->client_put, GNUNET_i2s (&s->target)); | ||
642 | |||
643 | /* remove curl handle from multi handle */ | ||
644 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_put); | ||
645 | if (mret != CURLM_OK) | ||
646 | { | ||
647 | /* clean up easy handle, handle is now invalid and free'd */ | ||
648 | res = GNUNET_SYSERR; | ||
649 | GNUNET_break (0); | ||
650 | } | ||
651 | curl_easy_cleanup (s->client_put); | ||
652 | s->client_put = NULL; | ||
653 | } | ||
654 | |||
655 | |||
656 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | ||
657 | { | ||
658 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
659 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
660 | } | ||
661 | |||
662 | if (s->client_get != NULL) | ||
663 | { | ||
664 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
665 | "Client: %p / %p Deleting outbound GET session to peer `%s'\n", | ||
666 | s, | ||
667 | s->client_get, GNUNET_i2s (&s->target)); | ||
668 | |||
669 | /* remove curl handle from multi handle */ | ||
670 | mret = curl_multi_remove_handle (plugin->curl_multi_handle, s->client_get); | ||
671 | if (mret != CURLM_OK) | ||
672 | { | ||
673 | /* clean up easy handle, handle is now invalid and free'd */ | ||
674 | res = GNUNET_SYSERR; | ||
675 | GNUNET_break (0); | ||
676 | } | ||
677 | curl_easy_cleanup (s->client_get); | ||
678 | s->client_get = NULL; | ||
679 | } | ||
680 | |||
681 | msg = s->msg_head; | ||
682 | while (msg != NULL) | ||
683 | { | ||
684 | t = msg->next; | ||
685 | if (NULL != msg->transmit_cont) | ||
686 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); | ||
687 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
688 | GNUNET_free (msg); | ||
689 | msg = t; | ||
690 | } | ||
691 | |||
692 | plugin->cur_connections -= 2; | ||
693 | plugin->env->session_end (plugin->env->cls, &s->target, s); | ||
694 | |||
695 | GNUNET_assert (plugin->cur_connections > 0); | ||
696 | plugin->cur_connections --; | ||
697 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
698 | "# HTTP client connections", | ||
699 | plugin->cur_connections, | ||
700 | GNUNET_NO); | ||
701 | |||
702 | /* Re-schedule since handles have changed */ | ||
703 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
704 | { | ||
705 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
706 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
707 | } | ||
708 | client_schedule (plugin, GNUNET_YES); | ||
709 | |||
710 | return res; | ||
711 | } | ||
712 | |||
713 | |||
714 | /** | ||
715 | * Task performing curl operations | ||
716 | * | ||
717 | * @param cls plugin as closure | ||
718 | * @param tc gnunet scheduler task context | ||
719 | */ | ||
720 | static void | ||
549 | client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 721 | client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
550 | { | 722 | { |
551 | GNUNET_break (0); | 723 | GNUNET_break (0); |
552 | #if 0 | ||
553 | struct HTTP_Client_Plugin *plugin = cls; | 724 | struct HTTP_Client_Plugin *plugin = cls; |
554 | int running; | 725 | int running; |
555 | CURLMcode mret; | 726 | CURLMcode mret; |
@@ -563,12 +734,12 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
563 | do | 734 | do |
564 | { | 735 | { |
565 | running = 0; | 736 | running = 0; |
566 | mret = curl_multi_perform (plugin->client_mh, &running); | 737 | mret = curl_multi_perform (plugin->curl_multi_handle, &running); |
567 | 738 | ||
568 | CURLMsg *msg; | 739 | CURLMsg *msg; |
569 | int msgs_left; | 740 | int msgs_left; |
570 | 741 | ||
571 | while ((msg = curl_multi_info_read (plugin->client_mh, &msgs_left))) | 742 | while ((msg = curl_multi_info_read (plugin->curl_multi_handle, &msgs_left))) |
572 | { | 743 | { |
573 | CURL *easy_h = msg->easy_handle; | 744 | CURL *easy_h = msg->easy_handle; |
574 | struct Session *s = NULL; | 745 | struct Session *s = NULL; |
@@ -588,7 +759,7 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
588 | curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); | 759 | curl_easy_getinfo (easy_h, CURLINFO_PRIVATE, &d)); |
589 | s = (struct Session *) d; | 760 | s = (struct Session *) d; |
590 | 761 | ||
591 | if (GNUNET_YES != exist_session(plugin, s)) | 762 | if (GNUNET_YES != client_exist_session(plugin, s)) |
592 | { | 763 | { |
593 | GNUNET_break (0); | 764 | GNUNET_break (0); |
594 | return; | 765 | return; |
@@ -600,7 +771,7 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
600 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 771 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
601 | "Client: %p connection to '%s' %s ended with reason %i: `%s'\n", | 772 | "Client: %p connection to '%s' %s ended with reason %i: `%s'\n", |
602 | msg->easy_handle, GNUNET_i2s (&s->target), | 773 | msg->easy_handle, GNUNET_i2s (&s->target), |
603 | http_plugin_address_to_string (NULL, s->addr, | 774 | http_common_plugin_address_to_string (NULL, s->addr, |
604 | s->addrlen), | 775 | s->addrlen), |
605 | msg->data.result, | 776 | msg->data.result, |
606 | curl_easy_strerror (msg->data.result)); | 777 | curl_easy_strerror (msg->data.result)); |
@@ -612,7 +783,6 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
612 | } | 783 | } |
613 | while (mret == CURLM_CALL_MULTI_PERFORM); | 784 | while (mret == CURLM_CALL_MULTI_PERFORM); |
614 | client_schedule (plugin, GNUNET_NO); | 785 | client_schedule (plugin, GNUNET_NO); |
615 | #endif | ||
616 | } | 786 | } |
617 | 787 | ||
618 | 788 | ||
@@ -848,102 +1018,6 @@ client_start (struct HTTP_Client_Plugin *plugin) | |||
848 | return GNUNET_OK; | 1018 | return GNUNET_OK; |
849 | } | 1019 | } |
850 | 1020 | ||
851 | static int | ||
852 | client_disconnect (struct Session *s) | ||
853 | { | ||
854 | #if 0 | ||
855 | int res = GNUNET_OK; | ||
856 | CURLMcode mret; | ||
857 | struct Plugin *plugin = s->plugin; | ||
858 | struct HTTP_Message *msg; | ||
859 | struct HTTP_Message *t; | ||
860 | |||
861 | if (GNUNET_YES != exist_session(plugin, s)) | ||
862 | { | ||
863 | GNUNET_break (0); | ||
864 | return GNUNET_SYSERR; | ||
865 | } | ||
866 | |||
867 | if (s->client_put != NULL) | ||
868 | { | ||
869 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
870 | "Client: %p / %p Deleting outbound PUT session to peer `%s'\n", | ||
871 | s, s->client_put, GNUNET_i2s (&s->target)); | ||
872 | |||
873 | /* remove curl handle from multi handle */ | ||
874 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_put); | ||
875 | if (mret != CURLM_OK) | ||
876 | { | ||
877 | /* clean up easy handle, handle is now invalid and free'd */ | ||
878 | res = GNUNET_SYSERR; | ||
879 | GNUNET_break (0); | ||
880 | } | ||
881 | curl_easy_cleanup (s->client_put); | ||
882 | s->client_put = NULL; | ||
883 | } | ||
884 | |||
885 | |||
886 | if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK) | ||
887 | { | ||
888 | GNUNET_SCHEDULER_cancel (s->recv_wakeup_task); | ||
889 | s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK; | ||
890 | } | ||
891 | |||
892 | if (s->client_get != NULL) | ||
893 | { | ||
894 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
895 | "Client: %p / %p Deleting outbound GET session to peer `%s'\n", | ||
896 | s, | ||
897 | s->client_get, GNUNET_i2s (&s->target)); | ||
898 | |||
899 | /* remove curl handle from multi handle */ | ||
900 | mret = curl_multi_remove_handle (plugin->client_mh, s->client_get); | ||
901 | if (mret != CURLM_OK) | ||
902 | { | ||
903 | /* clean up easy handle, handle is now invalid and free'd */ | ||
904 | res = GNUNET_SYSERR; | ||
905 | GNUNET_break (0); | ||
906 | } | ||
907 | curl_easy_cleanup (s->client_get); | ||
908 | s->client_get = NULL; | ||
909 | } | ||
910 | |||
911 | msg = s->msg_head; | ||
912 | while (msg != NULL) | ||
913 | { | ||
914 | t = msg->next; | ||
915 | if (NULL != msg->transmit_cont) | ||
916 | msg->transmit_cont (msg->transmit_cont_cls, &s->target, GNUNET_SYSERR); | ||
917 | GNUNET_CONTAINER_DLL_remove (s->msg_head, s->msg_tail, msg); | ||
918 | GNUNET_free (msg); | ||
919 | msg = t; | ||
920 | } | ||
921 | |||
922 | plugin->cur_connections -= 2; | ||
923 | |||
924 | notify_session_end (plugin, &s->target, s); | ||
925 | |||
926 | GNUNET_assert (plugin->outbound_sessions > 0); | ||
927 | plugin->outbound_sessions --; | ||
928 | GNUNET_STATISTICS_set (plugin->env->stats, | ||
929 | "# HTTP outbound sessions", | ||
930 | plugin->outbound_sessions, | ||
931 | GNUNET_NO); | ||
932 | |||
933 | /* Re-schedule since handles have changed */ | ||
934 | if (plugin->client_perform_task != GNUNET_SCHEDULER_NO_TASK) | ||
935 | { | ||
936 | GNUNET_SCHEDULER_cancel (plugin->client_perform_task); | ||
937 | plugin->client_perform_task = GNUNET_SCHEDULER_NO_TASK; | ||
938 | } | ||
939 | client_schedule (plugin, GNUNET_YES); | ||
940 | |||
941 | return res; | ||
942 | #endif | ||
943 | GNUNET_break (0); | ||
944 | return 0; | ||
945 | } | ||
946 | |||
947 | /** | 1021 | /** |
948 | * Session was idle, so disconnect it | 1022 | * Session was idle, so disconnect it |
949 | */ | 1023 | */ |
@@ -986,18 +1060,17 @@ client_start_session_timeout (struct Session *s) | |||
986 | static void | 1060 | static void |
987 | client_reschedule_session_timeout (struct Session *s) | 1061 | client_reschedule_session_timeout (struct Session *s) |
988 | { | 1062 | { |
989 | #if 0 | 1063 | |
990 | GNUNET_assert (NULL != s); | 1064 | GNUNET_assert (NULL != s); |
991 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); | 1065 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); |
992 | 1066 | ||
993 | GNUNET_SCHEDULER_cancel (s->timeout_task); | 1067 | GNUNET_SCHEDULER_cancel (s->timeout_task); |
994 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, | 1068 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, |
995 | &server_session_timeout, | 1069 | &client_session_timeout, |
996 | s); | 1070 | s); |
997 | GNUNET_log (TIMEOUT_LOG, | 1071 | GNUNET_log (TIMEOUT_LOG, |
998 | "Timeout rescheduled for session %p set to %llu ms\n", | 1072 | "Timeout rescheduled for session %p set to %llu ms\n", |
999 | s, (unsigned long long) TIMEOUT.rel_value); | 1073 | s, (unsigned long long) TIMEOUT.rel_value); |
1000 | #endif | ||
1001 | GNUNET_break (0); | 1074 | GNUNET_break (0); |
1002 | } | 1075 | } |
1003 | 1076 | ||
@@ -1048,6 +1121,12 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | |||
1048 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 1121 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
1049 | struct HTTP_Client_Plugin *plugin = api->cls; | 1122 | struct HTTP_Client_Plugin *plugin = api->cls; |
1050 | 1123 | ||
1124 | if (NULL == api->cls) | ||
1125 | { | ||
1126 | GNUNET_free (api); | ||
1127 | return NULL; | ||
1128 | } | ||
1129 | |||
1051 | if (NULL != plugin->curl_multi_handle) | 1130 | if (NULL != plugin->curl_multi_handle) |
1052 | { | 1131 | { |
1053 | curl_multi_cleanup (plugin->curl_multi_handle); | 1132 | curl_multi_cleanup (plugin->curl_multi_handle); |
@@ -1071,6 +1150,18 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
1071 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 1150 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
1072 | struct HTTP_Client_Plugin *plugin; | 1151 | struct HTTP_Client_Plugin *plugin; |
1073 | 1152 | ||
1153 | if (NULL == env->receive) | ||
1154 | { | ||
1155 | /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully | ||
1156 | initialze the plugin or the API */ | ||
1157 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | ||
1158 | api->cls = NULL; | ||
1159 | api->address_to_string = &http_common_plugin_address_to_string; | ||
1160 | api->string_to_address = &http_common_plugin_string_to_address; | ||
1161 | api->address_pretty_printer = &http_common_plugin_address_pretty_printer; | ||
1162 | return api; | ||
1163 | } | ||
1164 | |||
1074 | plugin = GNUNET_malloc (sizeof (struct HTTP_Client_Plugin)); | 1165 | plugin = GNUNET_malloc (sizeof (struct HTTP_Client_Plugin)); |
1075 | p = plugin; | 1166 | p = plugin; |
1076 | plugin->env = env; | 1167 | plugin->env = env; |
@@ -1081,10 +1172,6 @@ LIBGNUNET_PLUGIN_TRANSPORT_INIT (void *cls) | |||
1081 | api->check_address = &http_client_plugin_address_suggested; | 1172 | api->check_address = &http_client_plugin_address_suggested; |
1082 | api->get_session = &http_client_plugin_get_session; | 1173 | api->get_session = &http_client_plugin_get_session; |
1083 | 1174 | ||
1084 | api->address_to_string = &http_common_plugin_address_to_string; | ||
1085 | api->string_to_address = &http_common_plugin_string_to_address; | ||
1086 | api->address_pretty_printer = &http_common_plugin_address_pretty_printer; | ||
1087 | |||
1088 | #if BUILD_HTTPS | 1175 | #if BUILD_HTTPS |
1089 | plugin->name = "transport-https_client"; | 1176 | plugin->name = "transport-https_client"; |
1090 | plugin->protocol = "https"; | 1177 | plugin->protocol = "https"; |