diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-09-14 13:18:27 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-09-14 13:18:27 +0000 |
commit | 3dc71e42c0e9433f21bfa26da6fcd71a400b00b6 (patch) | |
tree | 24cffd622c19a3bc84e910ae252dbb0b517d0201 /src/transport/plugin_transport_http_client.c | |
parent | fb705a27cf904cffec275d2eef10fe41fe4a5a38 (diff) | |
download | gnunet-3dc71e42c0e9433f21bfa26da6fcd71a400b00b6.tar.gz gnunet-3dc71e42c0e9433f21bfa26da6fcd71a400b00b6.zip |
client side PUT disconnect
Diffstat (limited to 'src/transport/plugin_transport_http_client.c')
-rw-r--r-- | src/transport/plugin_transport_http_client.c | 191 |
1 files changed, 144 insertions, 47 deletions
diff --git a/src/transport/plugin_transport_http_client.c b/src/transport/plugin_transport_http_client.c index eda1f59be..db1250236 100644 --- a/src/transport/plugin_transport_http_client.c +++ b/src/transport/plugin_transport_http_client.c | |||
@@ -32,7 +32,12 @@ | |||
32 | #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_client_done | 32 | #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_http_client_done |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | #define VERBOSE_CURL GNUNET_NO | 35 | #define VERBOSE_CURL GNUNET_YES |
36 | |||
37 | #define PUT_DISCONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | ||
38 | |||
39 | #define ENABLE_PUT GNUNET_YES | ||
40 | #define ENABLE_GET GNUNET_YES | ||
36 | 41 | ||
37 | #include "platform.h" | 42 | #include "platform.h" |
38 | #include "gnunet_protocols.h" | 43 | #include "gnunet_protocols.h" |
@@ -115,6 +120,11 @@ struct Session | |||
115 | struct Session *prev; | 120 | struct Session *prev; |
116 | 121 | ||
117 | /** | 122 | /** |
123 | * The URL to connect to | ||
124 | */ | ||
125 | char *url; | ||
126 | |||
127 | /** | ||
118 | * Address | 128 | * Address |
119 | */ | 129 | */ |
120 | void *addr; | 130 | void *addr; |
@@ -141,6 +151,11 @@ struct Session | |||
141 | int client_put_paused; | 151 | int client_put_paused; |
142 | 152 | ||
143 | /** | 153 | /** |
154 | * Is client send handle to be disconnected due to inactivity | ||
155 | */ | ||
156 | int client_put_disconnect; | ||
157 | |||
158 | /** | ||
144 | * Was session given to transport service? | 159 | * Was session given to transport service? |
145 | */ | 160 | */ |
146 | // int session_passed; | 161 | // int session_passed; |
@@ -173,6 +188,11 @@ struct Session | |||
173 | /** | 188 | /** |
174 | * Session timeout task | 189 | * Session timeout task |
175 | */ | 190 | */ |
191 | GNUNET_SCHEDULER_TaskIdentifier put_disconnect_task; | ||
192 | |||
193 | /** | ||
194 | * Session timeout task | ||
195 | */ | ||
176 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 196 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
177 | 197 | ||
178 | /** | 198 | /** |
@@ -297,6 +317,8 @@ client_stop_session_timeout (struct Session *s); | |||
297 | static int | 317 | static int |
298 | client_schedule (struct HTTP_Client_Plugin *plugin, int now); | 318 | client_schedule (struct HTTP_Client_Plugin *plugin, int now); |
299 | 319 | ||
320 | static int | ||
321 | client_connect_put (struct Session *s); | ||
300 | 322 | ||
301 | /** | 323 | /** |
302 | * Does a session s exists? | 324 | * Does a session s exists? |
@@ -439,8 +461,20 @@ http_client_plugin_send (void *cls, | |||
439 | memcpy (msg->buf, msgbuf, msgbuf_size); | 461 | memcpy (msg->buf, msgbuf, msgbuf_size); |
440 | GNUNET_CONTAINER_DLL_insert_tail (session->msg_head, session->msg_tail, msg); | 462 | GNUNET_CONTAINER_DLL_insert_tail (session->msg_head, session->msg_tail, msg); |
441 | 463 | ||
442 | if (session->client_put_paused == GNUNET_YES) | 464 | if (GNUNET_YES == session->client_put_disconnect) |
465 | { | ||
466 | session->client_put_disconnect = GNUNET_NO; | ||
467 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, | ||
468 | "Session %p: Reconnecting PUT connection\n", | ||
469 | session); | ||
470 | client_connect_put (session); | ||
471 | } | ||
472 | |||
473 | if (GNUNET_YES == session->client_put_paused) | ||
443 | { | 474 | { |
475 | GNUNET_assert (session->put_disconnect_task != GNUNET_SCHEDULER_NO_TASK); | ||
476 | GNUNET_SCHEDULER_cancel (session->put_disconnect_task); | ||
477 | session->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
444 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, | 478 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, session->plugin->name, |
445 | "Session %p/connection %p: unpausing connection\n", | 479 | "Session %p/connection %p: unpausing connection\n", |
446 | session, session->client_put); | 480 | session, session->client_put); |
@@ -467,6 +501,12 @@ client_delete_session (struct Session *s) | |||
467 | 501 | ||
468 | client_stop_session_timeout (s); | 502 | client_stop_session_timeout (s); |
469 | 503 | ||
504 | if (GNUNET_SCHEDULER_NO_TASK != s->put_disconnect_task) | ||
505 | { | ||
506 | GNUNET_SCHEDULER_cancel (s->put_disconnect_task); | ||
507 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
508 | } | ||
509 | |||
470 | GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); | 510 | GNUNET_CONTAINER_DLL_remove (plugin->head, plugin->tail, s); |
471 | 511 | ||
472 | next = s->msg_head; | 512 | next = s->msg_head; |
@@ -485,6 +525,7 @@ client_delete_session (struct Session *s) | |||
485 | s->msg_tk = NULL; | 525 | s->msg_tk = NULL; |
486 | } | 526 | } |
487 | GNUNET_free (s->addr); | 527 | GNUNET_free (s->addr); |
528 | GNUNET_free (s->url); | ||
488 | GNUNET_free (s); | 529 | GNUNET_free (s); |
489 | } | 530 | } |
490 | 531 | ||
@@ -639,6 +680,19 @@ client_lookup_session (struct HTTP_Client_Plugin *plugin, | |||
639 | return NULL; | 680 | return NULL; |
640 | } | 681 | } |
641 | 682 | ||
683 | static void | ||
684 | client_put_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
685 | { | ||
686 | struct Session *s = cls; | ||
687 | s->put_disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
688 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, | ||
689 | "Session %p/connection %p: will be disconnected due to no activity\n", | ||
690 | s, s->client_put); | ||
691 | s->client_put_disconnect = GNUNET_YES; | ||
692 | s->client_put_paused = GNUNET_NO; | ||
693 | curl_easy_pause (s->client_put, CURLPAUSE_CONT); | ||
694 | client_schedule (s->plugin, GNUNET_YES); | ||
695 | } | ||
642 | 696 | ||
643 | /** | 697 | /** |
644 | * Callback method used with libcurl | 698 | * Callback method used with libcurl |
@@ -663,11 +717,21 @@ client_send_cb (void *stream, size_t size, size_t nmemb, void *cls) | |||
663 | GNUNET_break (0); | 717 | GNUNET_break (0); |
664 | return 0; | 718 | return 0; |
665 | } | 719 | } |
720 | if (GNUNET_YES == s->client_put_disconnect) | ||
721 | { | ||
722 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, s->plugin->name, | ||
723 | "Session %p/connection %p: disconnect due to inactivity\n", | ||
724 | s, s->client_put); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
666 | if (NULL == msg) | 728 | if (NULL == msg) |
667 | { | 729 | { |
668 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 730 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
669 | "Session %p/connection %p: nothing to send, suspending\n", | 731 | "Session %p/connection %p: nothing to send, suspending\n", |
670 | s, s->client_put); | 732 | s, s->client_put); |
733 | s->put_disconnect_task = GNUNET_SCHEDULER_add_delayed (PUT_DISCONNECT_TIMEOUT, &client_put_disconnect, s); | ||
734 | s->client_put_disconnect = GNUNET_NO; | ||
671 | s->client_put_paused = GNUNET_YES; | 735 | s->client_put_paused = GNUNET_YES; |
672 | return CURL_READFUNC_PAUSE; | 736 | return CURL_READFUNC_PAUSE; |
673 | } | 737 | } |
@@ -953,14 +1017,30 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
953 | GNUNET_assert (s != NULL); | 1017 | GNUNET_assert (s != NULL); |
954 | if (msg->msg == CURLMSG_DONE) | 1018 | if (msg->msg == CURLMSG_DONE) |
955 | { | 1019 | { |
956 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 1020 | if (easy_h == s->client_put) |
957 | "Session %p/connection %p: connection to `%s' ended with reason %i: `%s'\n", | 1021 | { |
958 | s, msg->easy_handle, GNUNET_i2s (&s->target), | 1022 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
959 | msg->data.result, | 1023 | "Session %p/connection %p: PUT connection to `%s' ended with reason %i: `%s'\n", |
960 | curl_easy_strerror (msg->data.result)); | 1024 | s, msg->easy_handle, GNUNET_i2s (&s->target), |
961 | 1025 | msg->data.result, | |
962 | /* Disconnect other transmission direction and tell transport */ | 1026 | curl_easy_strerror (msg->data.result)); |
963 | client_disconnect (s); | 1027 | if (s->client_get == NULL) |
1028 | { | ||
1029 | /* Disconnect other transmission direction and tell transport */ | ||
1030 | client_disconnect (s); | ||
1031 | } | ||
1032 | } | ||
1033 | if (easy_h == s->client_get) | ||
1034 | { | ||
1035 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1036 | "Session %p/connection %p: GET connection to `%s' ended with reason %i: `%s'\n", | ||
1037 | s, msg->easy_handle, GNUNET_i2s (&s->target), | ||
1038 | msg->data.result, | ||
1039 | curl_easy_strerror (msg->data.result)); | ||
1040 | |||
1041 | /* Disconnect other transmission direction and tell transport */ | ||
1042 | client_disconnect (s); | ||
1043 | } | ||
964 | } | 1044 | } |
965 | } | 1045 | } |
966 | } | 1046 | } |
@@ -969,32 +1049,9 @@ client_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
969 | } | 1049 | } |
970 | 1050 | ||
971 | static int | 1051 | static int |
972 | client_connect (struct Session *s) | 1052 | client_connect_get (struct Session *s) |
973 | { | 1053 | { |
974 | |||
975 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
976 | int res = GNUNET_OK; | ||
977 | char *url; | ||
978 | CURLMcode mret; | 1054 | CURLMcode mret; |
979 | |||
980 | /* create url */ | ||
981 | if (NULL == http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)) | ||
982 | { | ||
983 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
984 | "Invalid address peer `%s'\n", | ||
985 | GNUNET_i2s (&s->target)); | ||
986 | return GNUNET_SYSERR; | ||
987 | } | ||
988 | |||
989 | GNUNET_asprintf (&url, "%s/%s;%u", | ||
990 | http_common_plugin_address_to_string (plugin, s->addr, s->addrlen), | ||
991 | GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey), | ||
992 | plugin->last_tag); | ||
993 | plugin->last_tag++; | ||
994 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
995 | "Initiating outbound session peer `%s' using address `%s'\n", | ||
996 | GNUNET_i2s (&s->target), url); | ||
997 | |||
998 | /* create get connection */ | 1055 | /* create get connection */ |
999 | s->client_get = curl_easy_init (); | 1056 | s->client_get = curl_easy_init (); |
1000 | #if VERBOSE_CURL | 1057 | #if VERBOSE_CURL |
@@ -1007,7 +1064,7 @@ client_connect (struct Session *s) | |||
1007 | curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYPEER, 0); | 1064 | curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYPEER, 0); |
1008 | curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYHOST, 0); | 1065 | curl_easy_setopt (s->client_get, CURLOPT_SSL_VERIFYHOST, 0); |
1009 | #endif | 1066 | #endif |
1010 | curl_easy_setopt (s->client_get, CURLOPT_URL, url); | 1067 | curl_easy_setopt (s->client_get, CURLOPT_URL, s->url); |
1011 | //curl_easy_setopt (s->client_get, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); | 1068 | //curl_easy_setopt (s->client_get, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); |
1012 | //curl_easy_setopt (s->client_get, CURLOPT_WRITEHEADER, ps); | 1069 | //curl_easy_setopt (s->client_get, CURLOPT_WRITEHEADER, ps); |
1013 | curl_easy_setopt (s->client_get, CURLOPT_READFUNCTION, client_send_cb); | 1070 | curl_easy_setopt (s->client_get, CURLOPT_READFUNCTION, client_send_cb); |
@@ -1024,7 +1081,21 @@ client_connect (struct Session *s) | |||
1024 | #if CURL_TCP_NODELAY | 1081 | #if CURL_TCP_NODELAY |
1025 | curl_easy_setopt (ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1); | 1082 | curl_easy_setopt (ps->recv_endpoint, CURLOPT_TCP_NODELAY, 1); |
1026 | #endif | 1083 | #endif |
1084 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, s->client_get); | ||
1085 | if (mret != CURLM_OK) | ||
1086 | { | ||
1087 | curl_easy_cleanup (s->client_get); | ||
1088 | GNUNET_break (0); | ||
1089 | return GNUNET_SYSERR; | ||
1090 | } | ||
1091 | |||
1092 | return GNUNET_OK; | ||
1093 | } | ||
1027 | 1094 | ||
1095 | static int | ||
1096 | client_connect_put (struct Session *s) | ||
1097 | { | ||
1098 | CURLMcode mret; | ||
1028 | /* create put connection */ | 1099 | /* create put connection */ |
1029 | s->client_put = curl_easy_init (); | 1100 | s->client_put = curl_easy_init (); |
1030 | #if VERBOSE_CURL | 1101 | #if VERBOSE_CURL |
@@ -1037,7 +1108,7 @@ client_connect (struct Session *s) | |||
1037 | curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYPEER, 0); | 1108 | curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYPEER, 0); |
1038 | curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYHOST, 0); | 1109 | curl_easy_setopt (s->client_put, CURLOPT_SSL_VERIFYHOST, 0); |
1039 | #endif | 1110 | #endif |
1040 | curl_easy_setopt (s->client_put, CURLOPT_URL, url); | 1111 | curl_easy_setopt (s->client_put, CURLOPT_URL, s->url); |
1041 | curl_easy_setopt (s->client_put, CURLOPT_UPLOAD, 1L); | 1112 | curl_easy_setopt (s->client_put, CURLOPT_UPLOAD, 1L); |
1042 | /* | 1113 | /* |
1043 | struct curl_slist *m_headerlist; | 1114 | struct curl_slist *m_headerlist; |
@@ -1060,29 +1131,55 @@ client_connect (struct Session *s) | |||
1060 | #if CURL_TCP_NODELAY | 1131 | #if CURL_TCP_NODELAY |
1061 | curl_easy_setopt (s->client_put, CURLOPT_TCP_NODELAY, 1); | 1132 | curl_easy_setopt (s->client_put, CURLOPT_TCP_NODELAY, 1); |
1062 | #endif | 1133 | #endif |
1063 | GNUNET_free (url); | ||
1064 | 1134 | ||
1065 | mret = curl_multi_add_handle (plugin->curl_multi_handle, s->client_get); | 1135 | mret = curl_multi_add_handle (s->plugin->curl_multi_handle, s->client_put); |
1066 | if (mret != CURLM_OK) | 1136 | if (mret != CURLM_OK) |
1067 | { | 1137 | { |
1068 | curl_easy_cleanup (s->client_get); | 1138 | curl_easy_cleanup (s->client_put); |
1069 | GNUNET_break (0); | 1139 | GNUNET_break (0); |
1070 | return GNUNET_SYSERR; | 1140 | return GNUNET_SYSERR; |
1071 | } | 1141 | } |
1142 | return GNUNET_OK; | ||
1143 | } | ||
1072 | 1144 | ||
1073 | mret = curl_multi_add_handle (plugin->curl_multi_handle, s->client_put); | 1145 | static int |
1074 | if (mret != CURLM_OK) | 1146 | client_connect (struct Session *s) |
1147 | { | ||
1148 | |||
1149 | struct HTTP_Client_Plugin *plugin = s->plugin; | ||
1150 | int res = GNUNET_OK; | ||
1151 | |||
1152 | |||
1153 | /* create url */ | ||
1154 | if (NULL == http_common_plugin_address_to_string (NULL, s->addr, s->addrlen)) | ||
1075 | { | 1155 | { |
1076 | curl_multi_remove_handle (plugin->curl_multi_handle, s->client_get); | 1156 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
1077 | curl_easy_cleanup (s->client_get); | 1157 | "Invalid address peer `%s'\n", |
1078 | curl_easy_cleanup (s->client_put); | 1158 | GNUNET_i2s (&s->target)); |
1079 | GNUNET_break (0); | ||
1080 | return GNUNET_SYSERR; | 1159 | return GNUNET_SYSERR; |
1081 | } | 1160 | } |
1082 | 1161 | ||
1162 | GNUNET_asprintf (&s->url, "%s/%s;%u", | ||
1163 | http_common_plugin_address_to_string (plugin, s->addr, s->addrlen), | ||
1164 | GNUNET_h2s_full (&plugin->env->my_identity->hashPubKey), | ||
1165 | plugin->last_tag); | ||
1166 | |||
1167 | plugin->last_tag++; | ||
1168 | |||
1169 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | ||
1170 | "Initiating outbound session peer `%s' using address `%s'\n", | ||
1171 | GNUNET_i2s (&s->target), s->url); | ||
1172 | |||
1173 | if ((GNUNET_SYSERR == client_connect_get (s)) || | ||
1174 | (GNUNET_SYSERR == client_connect_put (s))) | ||
1175 | { | ||
1176 | GNUNET_break (0); | ||
1177 | return GNUNET_SYSERR; | ||
1178 | } | ||
1179 | |||
1083 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, | 1180 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, |
1084 | "Session %p: connected with connections GET %p and PUT %p\n", | 1181 | "Session %p: connected with connections GET %p and PUT %p\n", |
1085 | s, s->client_get, s->client_put); | 1182 | s, s->client_get, s->client_put); |
1086 | 1183 | ||
1087 | /* Perform connect */ | 1184 | /* Perform connect */ |
1088 | plugin->cur_connections += 2; | 1185 | plugin->cur_connections += 2; |