aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_client.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-09-14 13:18:27 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-09-14 13:18:27 +0000
commit3dc71e42c0e9433f21bfa26da6fcd71a400b00b6 (patch)
tree24cffd622c19a3bc84e910ae252dbb0b517d0201 /src/transport/plugin_transport_http_client.c
parentfb705a27cf904cffec275d2eef10fe41fe4a5a38 (diff)
downloadgnunet-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.c191
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);
297static int 317static int
298client_schedule (struct HTTP_Client_Plugin *plugin, int now); 318client_schedule (struct HTTP_Client_Plugin *plugin, int now);
299 319
320static int
321client_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
683static void
684client_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
971static int 1051static int
972client_connect (struct Session *s) 1052client_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
1095static int
1096client_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); 1145static int
1074 if (mret != CURLM_OK) 1146client_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;