diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2010-07-15 16:27:48 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2010-07-15 16:27:48 +0000 |
commit | 7adcdc82792c48f2331185d9af9d56925978804a (patch) | |
tree | 192b169b1679d52cf08e8cdb7f7890b54b05a11e | |
parent | 27294d85406ed2c51b53112b42915141f866ff1e (diff) | |
download | gnunet-7adcdc82792c48f2331185d9af9d56925978804a.tar.gz gnunet-7adcdc82792c48f2331185d9af9d56925978804a.zip |
Cleaned up code
Rewritten session selection
Improved session section by skipping session lookups
Added binding to interface
-rw-r--r-- | src/transport/plugin_transport_http.c | 833 | ||||
-rw-r--r-- | src/transport/test_plugin_transport.c | 2 | ||||
-rw-r--r-- | src/transport/test_plugin_transport_data_http.conf | 4 | ||||
-rw-r--r-- | src/transport/test_transport_api_http_peer1.conf | 9 | ||||
-rw-r--r-- | src/transport/test_transport_api_http_peer2.conf | 1 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_peer1.conf | 3 | ||||
-rw-r--r-- | src/transport/test_transport_api_tcp_peer2.conf | 5 |
7 files changed, 475 insertions, 382 deletions
diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index d654a0c82..da298308e 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c | |||
@@ -25,6 +25,7 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include "platform.h" | 27 | #include "platform.h" |
28 | #include "gnunet_common.h" | ||
28 | #include "gnunet_constants.h" | 29 | #include "gnunet_constants.h" |
29 | #include "gnunet_protocols.h" | 30 | #include "gnunet_protocols.h" |
30 | #include "gnunet_connection_lib.h" | 31 | #include "gnunet_connection_lib.h" |
@@ -39,9 +40,11 @@ | |||
39 | #include "microhttpd.h" | 40 | #include "microhttpd.h" |
40 | #include <curl/curl.h> | 41 | #include <curl/curl.h> |
41 | 42 | ||
43 | |||
42 | #define DEBUG_CURL GNUNET_NO | 44 | #define DEBUG_CURL GNUNET_NO |
43 | #define DEBUG_HTTP GNUNET_NO | 45 | #define DEBUG_HTTP GNUNET_NO |
44 | #define DEBUG_CONNECTIONS GNUNET_NO | 46 | #define DEBUG_CONNECTIONS GNUNET_NO |
47 | #define DEBUG_SESSION_SELECTION GNUNET_YES | ||
45 | 48 | ||
46 | #define INBOUND GNUNET_NO | 49 | #define INBOUND GNUNET_NO |
47 | #define OUTBOUND GNUNET_YES | 50 | #define OUTBOUND GNUNET_YES |
@@ -179,6 +182,11 @@ struct HTTP_PeerContext | |||
179 | * id for next session | 182 | * id for next session |
180 | */ | 183 | */ |
181 | size_t session_id_counter; | 184 | size_t session_id_counter; |
185 | |||
186 | /** | ||
187 | * Last session used to send data | ||
188 | */ | ||
189 | struct Session * last_session; | ||
182 | }; | 190 | }; |
183 | 191 | ||
184 | 192 | ||
@@ -348,6 +356,8 @@ struct Plugin | |||
348 | * This string is used to distinguish between connections and is added to the urls | 356 | * This string is used to distinguish between connections and is added to the urls |
349 | */ | 357 | */ |
350 | struct GNUNET_CRYPTO_HashAsciiEncoded my_ascii_hash_ident; | 358 | struct GNUNET_CRYPTO_HashAsciiEncoded my_ascii_hash_ident; |
359 | |||
360 | struct in_addr * bind_address; | ||
351 | }; | 361 | }; |
352 | 362 | ||
353 | 363 | ||
@@ -367,6 +377,37 @@ http_plugin_address_to_string (void *cls, | |||
367 | const void *addr, | 377 | const void *addr, |
368 | size_t addrlen); | 378 | size_t addrlen); |
369 | 379 | ||
380 | |||
381 | /** | ||
382 | * Call MHD to process pending ipv4 requests and then go back | ||
383 | * and schedule the next run. | ||
384 | */ | ||
385 | static void http_server_daemon_v4_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
386 | /** | ||
387 | * Call MHD to process pending ipv6 requests and then go back | ||
388 | * and schedule the next run. | ||
389 | */ | ||
390 | static void http_server_daemon_v6_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
391 | |||
392 | /** | ||
393 | * Function setting up curl handle and selecting message to send | ||
394 | * @param cls plugin | ||
395 | * @param ses session to send data to | ||
396 | * @param con connection | ||
397 | * @return bytes sent to peer | ||
398 | */ | ||
399 | static ssize_t send_check_connections (void *cls, struct Session *ps); | ||
400 | |||
401 | /** | ||
402 | * Function setting up file descriptors and scheduling task to run | ||
403 | * @param cls closure | ||
404 | * @param ses session to send data to | ||
405 | * @param | ||
406 | */ | ||
407 | static int curl_schedule(void *cls ); | ||
408 | |||
409 | |||
410 | |||
370 | static char * create_url(void * cls, const void * addr, size_t addrlen, size_t id) | 411 | static char * create_url(void * cls, const void * addr, size_t addrlen, size_t id) |
371 | { | 412 | { |
372 | struct Plugin *plugin = cls; | 413 | struct Plugin *plugin = cls; |
@@ -432,29 +473,120 @@ static int remove_session (struct HTTP_PeerContext * pc, struct Session * ps, i | |||
432 | return GNUNET_OK; | 473 | return GNUNET_OK; |
433 | } | 474 | } |
434 | 475 | ||
435 | static struct Session * get_Session (void * cls, struct HTTP_PeerContext *pc, const void * addr, size_t addr_len) | 476 | int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *value) |
436 | { | 477 | { |
437 | struct Session * cc = pc->head; | 478 | struct Plugin *plugin = cls; |
438 | struct Session * con = NULL; | 479 | struct HTTP_PeerContext * pc = value; |
439 | unsigned int count = 0; | 480 | struct Session * ps = pc->head; |
481 | struct Session * tmp = NULL; | ||
482 | struct HTTP_Message * msg = NULL; | ||
483 | struct HTTP_Message * msg_tmp = NULL; | ||
484 | |||
485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Freeing context for peer `%s'\n",GNUNET_i2s(&pc->identity)); | ||
440 | 486 | ||
441 | GNUNET_assert((addr_len == sizeof (struct IPv4HttpAddress)) || (addr_len == sizeof (struct IPv6HttpAddress))); | 487 | while (ps!=NULL) |
442 | while (cc!=NULL) | ||
443 | { | 488 | { |
444 | if (addr_len == cc->addrlen) | 489 | plugin->env->session_end(plugin, &pc->identity, ps); |
490 | tmp = ps->next; | ||
491 | |||
492 | GNUNET_free_non_null (ps->addr); | ||
493 | GNUNET_free(ps->url); | ||
494 | if (ps->msgtok != NULL) | ||
495 | GNUNET_SERVER_mst_destroy (ps->msgtok); | ||
496 | |||
497 | msg = ps->pending_msgs_head; | ||
498 | while (msg!=NULL) | ||
499 | { | ||
500 | msg_tmp = msg->next; | ||
501 | GNUNET_free(msg); | ||
502 | msg = msg_tmp; | ||
503 | } | ||
504 | if (ps->direction==OUTBOUND) | ||
505 | { | ||
506 | if (ps->send_endpoint!=NULL) | ||
507 | curl_easy_cleanup(ps->send_endpoint); | ||
508 | if (ps->recv_endpoint!=NULL) | ||
509 | curl_easy_cleanup(ps->recv_endpoint); | ||
510 | } | ||
511 | |||
512 | GNUNET_free(ps); | ||
513 | ps=tmp; | ||
514 | } | ||
515 | GNUNET_free(pc); | ||
516 | return GNUNET_YES; | ||
517 | } | ||
518 | |||
519 | /** | ||
520 | * Add the IP of our network interface to the list of | ||
521 | * our external IP addresses. | ||
522 | * | ||
523 | * @param cls the 'struct Plugin*' | ||
524 | * @param name name of the interface | ||
525 | * @param isDefault do we think this may be our default interface | ||
526 | * @param addr address of the interface | ||
527 | * @param addrlen number of bytes in addr | ||
528 | * @return GNUNET_OK to continue iterating | ||
529 | */ | ||
530 | static int | ||
531 | process_interfaces (void *cls, | ||
532 | const char *name, | ||
533 | int isDefault, | ||
534 | const struct sockaddr *addr, socklen_t addrlen) | ||
535 | { | ||
536 | struct Plugin *plugin = cls; | ||
537 | struct IPv4HttpAddress * t4; | ||
538 | struct IPv6HttpAddress * t6; | ||
539 | int af; | ||
540 | struct in_addr bnd_cmp = ((struct sockaddr_in *) addr)->sin_addr; | ||
541 | |||
542 | GNUNET_assert(cls !=NULL); | ||
543 | af = addr->sa_family; | ||
544 | if (af == AF_INET) | ||
445 | { | 545 | { |
446 | if (0 == memcmp(cc->addr, addr, addr_len)) | 546 | t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress)); |
547 | /* Not skipping loopback addresses | ||
548 | if (INADDR_LOOPBACK == ntohl(((struct sockaddr_in *) addr)->sin_addr.s_addr)) | ||
447 | { | 549 | { |
448 | /* connection can not be used, since it is disconnected */ | 550 | |
449 | if ((cc->recv_force_disconnect==GNUNET_NO) && (cc->send_force_disconnect==GNUNET_NO)) | 551 | return GNUNET_OK; |
450 | con = cc; | 552 | } |
451 | break; | 553 | */ |
554 | t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
555 | t4->u_port = htons (plugin->port_inbound); | ||
556 | if (plugin->bind_address != NULL) | ||
557 | { | ||
558 | if (0 == memcmp(plugin->bind_address, &bnd_cmp, sizeof (struct in_addr))) | ||
559 | plugin->env->notify_address(plugin->env->cls,"http",t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); | ||
560 | } | ||
561 | else | ||
562 | { | ||
563 | plugin->env->notify_address(plugin->env->cls,"http",t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); | ||
452 | } | 564 | } |
565 | |||
453 | } | 566 | } |
454 | count++; | 567 | else if ((af == AF_INET6) && (plugin->bind_address == NULL)) |
455 | cc=cc->next; | 568 | { |
456 | } | 569 | t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress)); |
457 | return con; | 570 | if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) |
571 | { | ||
572 | /* skip link local addresses */ | ||
573 | return GNUNET_OK; | ||
574 | } | ||
575 | /* Not skipping loopback addresses | ||
576 | if (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
577 | { | ||
578 | |||
579 | return GNUNET_OK; | ||
580 | } | ||
581 | */ | ||
582 | memcpy (&t6->ipv6_addr, | ||
583 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
584 | sizeof (struct in6_addr)); | ||
585 | t6->u6_port = htons (plugin->port_inbound); | ||
586 | plugin->env->notify_address(plugin->env->cls,"http",t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); | ||
587 | } | ||
588 | //return GNUNET_NO; | ||
589 | return GNUNET_OK; | ||
458 | } | 590 | } |
459 | 591 | ||
460 | 592 | ||
@@ -519,30 +651,6 @@ static void mhd_write_mst_cb (void *cls, | |||
519 | 0); | 651 | 0); |
520 | } | 652 | } |
521 | 653 | ||
522 | static void curl_receive_mst_cb (void *cls, | ||
523 | void *client, | ||
524 | const struct GNUNET_MessageHeader *message) | ||
525 | { | ||
526 | struct Session *ps = cls; | ||
527 | struct HTTP_PeerContext *pc = ps->peercontext; | ||
528 | GNUNET_assert(ps != NULL); | ||
529 | GNUNET_assert(pc != NULL); | ||
530 | |||
531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
532 | "Connection %X: Forwarding message to transport service, type %u and size %u from `%s' (`%s')\n", | ||
533 | ps, | ||
534 | ntohs(message->type), | ||
535 | ntohs(message->size), | ||
536 | GNUNET_i2s(&(pc->identity)),http_plugin_address_to_string(NULL,ps->addr,ps->addrlen)); | ||
537 | |||
538 | pc->plugin->env->receive (pc->plugin->env->cls, | ||
539 | &pc->identity, | ||
540 | message, 1, ps, | ||
541 | ps->addr, | ||
542 | ps->addrlen); | ||
543 | } | ||
544 | |||
545 | |||
546 | /** | 654 | /** |
547 | * Check if ip is allowed to connect. | 655 | * Check if ip is allowed to connect. |
548 | */ | 656 | */ |
@@ -688,6 +796,7 @@ mdh_access_cb (void *cls, | |||
688 | pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext)); | 796 | pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext)); |
689 | pc->plugin = plugin; | 797 | pc->plugin = plugin; |
690 | pc->session_id_counter=1; | 798 | pc->session_id_counter=1; |
799 | pc->last_session = NULL; | ||
691 | memcpy(&pc->identity, &pi_in, sizeof(struct GNUNET_PeerIdentity)); | 800 | memcpy(&pc->identity, &pi_in, sizeof(struct GNUNET_PeerIdentity)); |
692 | GNUNET_CONTAINER_multihashmap_put(plugin->peers, &pc->identity.hashPubKey, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 801 | GNUNET_CONTAINER_multihashmap_put(plugin->peers, &pc->identity.hashPubKey, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
693 | } | 802 | } |
@@ -714,8 +823,6 @@ mdh_access_cb (void *cls, | |||
714 | addr_len = sizeof(struct IPv6HttpAddress); | 823 | addr_len = sizeof(struct IPv6HttpAddress); |
715 | } | 824 | } |
716 | 825 | ||
717 | |||
718 | //ps = get_Session(plugin, pc, addr, addr_len); | ||
719 | ps = NULL; | 826 | ps = NULL; |
720 | /* only inbound sessions here */ | 827 | /* only inbound sessions here */ |
721 | 828 | ||
@@ -832,18 +939,6 @@ mdh_access_cb (void *cls, | |||
832 | return MHD_NO; | 939 | return MHD_NO; |
833 | } | 940 | } |
834 | 941 | ||
835 | |||
836 | /** | ||
837 | * Call MHD to process pending ipv4 requests and then go back | ||
838 | * and schedule the next run. | ||
839 | */ | ||
840 | static void http_server_daemon_v4_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
841 | /** | ||
842 | * Call MHD to process pending ipv6 requests and then go back | ||
843 | * and schedule the next run. | ||
844 | */ | ||
845 | static void http_server_daemon_v6_run (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
846 | |||
847 | /** | 942 | /** |
848 | * Function that queries MHD's select sets and | 943 | * Function that queries MHD's select sets and |
849 | * starts the task waiting for them. | 944 | * starts the task waiting for them. |
@@ -968,16 +1063,7 @@ static void http_server_daemon_v6_run (void *cls, | |||
968 | return; | 1063 | return; |
969 | } | 1064 | } |
970 | 1065 | ||
971 | /** | 1066 | static size_t curl_get_header_cb( void *ptr, size_t size, size_t nmemb, void *stream) |
972 | * Function setting up curl handle and selecting message to send | ||
973 | * @param cls plugin | ||
974 | * @param ses session to send data to | ||
975 | * @param con connection | ||
976 | * @return bytes sent to peer | ||
977 | */ | ||
978 | static ssize_t send_check_connections (void *cls, struct Session *ps); | ||
979 | |||
980 | static size_t curl_get_header_function( void *ptr, size_t size, size_t nmemb, void *stream) | ||
981 | { | 1067 | { |
982 | struct Session * ps = stream; | 1068 | struct Session * ps = stream; |
983 | 1069 | ||
@@ -1027,7 +1113,7 @@ static size_t curl_get_header_function( void *ptr, size_t size, size_t nmemb, vo | |||
1027 | return size * nmemb; | 1113 | return size * nmemb; |
1028 | } | 1114 | } |
1029 | 1115 | ||
1030 | static size_t curl_put_header_function( void *ptr, size_t size, size_t nmemb, void *stream) | 1116 | static size_t curl_put_header_cb( void *ptr, size_t size, size_t nmemb, void *stream) |
1031 | { | 1117 | { |
1032 | struct Session * ps = stream; | 1118 | struct Session * ps = stream; |
1033 | 1119 | ||
@@ -1149,6 +1235,30 @@ static size_t curl_send_cb(void *stream, size_t size, size_t nmemb, void *ptr) | |||
1149 | return bytes_sent; | 1235 | return bytes_sent; |
1150 | } | 1236 | } |
1151 | 1237 | ||
1238 | static void curl_receive_mst_cb (void *cls, | ||
1239 | void *client, | ||
1240 | const struct GNUNET_MessageHeader *message) | ||
1241 | { | ||
1242 | struct Session *ps = cls; | ||
1243 | struct HTTP_PeerContext *pc = ps->peercontext; | ||
1244 | GNUNET_assert(ps != NULL); | ||
1245 | GNUNET_assert(pc != NULL); | ||
1246 | |||
1247 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1248 | "Connection %X: Forwarding message to transport service, type %u and size %u from `%s' (`%s')\n", | ||
1249 | ps, | ||
1250 | ntohs(message->type), | ||
1251 | ntohs(message->size), | ||
1252 | GNUNET_i2s(&(pc->identity)),http_plugin_address_to_string(NULL,ps->addr,ps->addrlen)); | ||
1253 | |||
1254 | pc->plugin->env->receive (pc->plugin->env->cls, | ||
1255 | &pc->identity, | ||
1256 | message, 1, ps, | ||
1257 | ps->addr, | ||
1258 | ps->addrlen); | ||
1259 | } | ||
1260 | |||
1261 | |||
1152 | /** | 1262 | /** |
1153 | * Callback method used with libcurl | 1263 | * Callback method used with libcurl |
1154 | * Method is called when libcurl needs to write data during sending | 1264 | * Method is called when libcurl needs to write data during sending |
@@ -1169,157 +1279,6 @@ static size_t curl_receive_cb( void *stream, size_t size, size_t nmemb, void *pt | |||
1169 | 1279 | ||
1170 | } | 1280 | } |
1171 | 1281 | ||
1172 | /** | ||
1173 | * Function setting up file descriptors and scheduling task to run | ||
1174 | * @param cls closure | ||
1175 | * @param ses session to send data to | ||
1176 | * @param | ||
1177 | */ | ||
1178 | static int curl_schedule(void *cls ); | ||
1179 | |||
1180 | |||
1181 | |||
1182 | /** | ||
1183 | * Function setting up curl handle and selecting message to send | ||
1184 | * @param cls plugin | ||
1185 | * @param ses session to send data to | ||
1186 | * @param con connection | ||
1187 | * @return GNUNET_SYSERR on failure, GNUNET_NO if connecting, GNUNET_YES if ok | ||
1188 | */ | ||
1189 | static ssize_t send_check_connections (void *cls, struct Session *ps) | ||
1190 | { | ||
1191 | struct Plugin *plugin = cls; | ||
1192 | CURLMcode mret; | ||
1193 | struct HTTP_Message * msg; | ||
1194 | |||
1195 | struct GNUNET_TIME_Relative timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; | ||
1196 | |||
1197 | GNUNET_assert(cls !=NULL); | ||
1198 | |||
1199 | if (ps->direction == OUTBOUND) | ||
1200 | { | ||
1201 | /* RECV DIRECTION */ | ||
1202 | /* Check if session is connected to receive data, otherwise connect to peer */ | ||
1203 | if (ps->recv_connected == GNUNET_NO) | ||
1204 | { | ||
1205 | if (ps->recv_endpoint == NULL) | ||
1206 | { | ||
1207 | ps->recv_endpoint = curl_easy_init(); | ||
1208 | #if DEBUG_CURL | ||
1209 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_VERBOSE, 1L); | ||
1210 | #endif | ||
1211 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_URL, ps->url); | ||
1212 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_HEADERFUNCTION, &curl_get_header_function); | ||
1213 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEHEADER, ps); | ||
1214 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_READFUNCTION, curl_send_cb); | ||
1215 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_READDATA, ps); | ||
1216 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); | ||
1217 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEDATA, ps); | ||
1218 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_TIMEOUT, (long) timeout.value); | ||
1219 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_PRIVATE, ps); | ||
1220 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); | ||
1221 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
1222 | |||
1223 | mret = curl_multi_add_handle(plugin->multi_handle, ps->recv_endpoint); | ||
1224 | if (mret != CURLM_OK) | ||
1225 | { | ||
1226 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1227 | _("Connection: %X: %s failed at %s:%d: `%s'\n"), | ||
1228 | ps, | ||
1229 | "curl_multi_add_handle", __FILE__, __LINE__, | ||
1230 | curl_multi_strerror (mret)); | ||
1231 | return GNUNET_SYSERR; | ||
1232 | } | ||
1233 | if (curl_schedule (plugin) == GNUNET_SYSERR) | ||
1234 | return GNUNET_SYSERR; | ||
1235 | #if DEBUG_CONNECTIONS | ||
1236 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: inbound not connected, initiating connection\n",ps); | ||
1237 | #endif | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | /* waiting for receive direction */ | ||
1242 | if (ps->recv_connected==GNUNET_NO) | ||
1243 | return GNUNET_NO; | ||
1244 | |||
1245 | /* SEND DIRECTION */ | ||
1246 | /* Check if session is connected to send data, otherwise connect to peer */ | ||
1247 | if ((ps->send_connected == GNUNET_YES) && (ps->send_endpoint!= NULL)) | ||
1248 | { | ||
1249 | if (ps->send_active == GNUNET_YES) | ||
1250 | { | ||
1251 | #if DEBUG_CONNECTIONS | ||
1252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound active, enqueueing message\n",ps); | ||
1253 | #endif | ||
1254 | return GNUNET_YES; | ||
1255 | } | ||
1256 | if (ps->send_active == GNUNET_NO) | ||
1257 | { | ||
1258 | #if DEBUG_CONNECTIONS | ||
1259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound paused, unpausing existing connection and enqueueing message\n",ps); | ||
1260 | #endif | ||
1261 | if (CURLE_OK == curl_easy_pause(ps->send_endpoint,CURLPAUSE_CONT)) | ||
1262 | { | ||
1263 | ps->send_active=GNUNET_YES; | ||
1264 | return GNUNET_YES; | ||
1265 | } | ||
1266 | else | ||
1267 | return GNUNET_SYSERR; | ||
1268 | } | ||
1269 | } | ||
1270 | /* not connected, initiate connection */ | ||
1271 | if ((ps->send_connected==GNUNET_NO) && (NULL == ps->send_endpoint)) | ||
1272 | { | ||
1273 | ps->send_endpoint = curl_easy_init(); | ||
1274 | GNUNET_assert (ps->send_endpoint != NULL); | ||
1275 | GNUNET_assert (NULL != ps->pending_msgs_tail); | ||
1276 | #if DEBUG_CONNECTIONS | ||
1277 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound not connected, initiating connection\n",ps); | ||
1278 | #endif | ||
1279 | ps->send_active = GNUNET_NO; | ||
1280 | msg = ps->pending_msgs_tail; | ||
1281 | |||
1282 | #if DEBUG_CURL | ||
1283 | curl_easy_setopt(ps->send_endpoint, CURLOPT_VERBOSE, 1L); | ||
1284 | #endif | ||
1285 | curl_easy_setopt(ps->send_endpoint, CURLOPT_URL, ps->url); | ||
1286 | curl_easy_setopt(ps->send_endpoint, CURLOPT_PUT, 1L); | ||
1287 | curl_easy_setopt(ps->send_endpoint, CURLOPT_HEADERFUNCTION, &curl_put_header_function); | ||
1288 | curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEHEADER, ps); | ||
1289 | curl_easy_setopt(ps->send_endpoint, CURLOPT_READFUNCTION, curl_send_cb); | ||
1290 | curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); | ||
1291 | curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); | ||
1292 | curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); | ||
1293 | curl_easy_setopt(ps->send_endpoint, CURLOPT_TIMEOUT, (long) timeout.value); | ||
1294 | curl_easy_setopt(ps->send_endpoint, CURLOPT_PRIVATE, ps); | ||
1295 | curl_easy_setopt(ps->send_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); | ||
1296 | curl_easy_setopt(ps->send_endpoint, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
1297 | |||
1298 | mret = curl_multi_add_handle(plugin->multi_handle, ps->send_endpoint); | ||
1299 | if (mret != CURLM_OK) | ||
1300 | { | ||
1301 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1302 | _("Connection: %X: %s failed at %s:%d: `%s'\n"), | ||
1303 | ps, | ||
1304 | "curl_multi_add_handle", __FILE__, __LINE__, | ||
1305 | curl_multi_strerror (mret)); | ||
1306 | return GNUNET_SYSERR; | ||
1307 | } | ||
1308 | } | ||
1309 | if (curl_schedule (plugin) == GNUNET_SYSERR) | ||
1310 | return GNUNET_SYSERR; | ||
1311 | return GNUNET_YES; | ||
1312 | } | ||
1313 | if (ps->direction == INBOUND) | ||
1314 | { | ||
1315 | GNUNET_assert (NULL != ps->pending_msgs_tail); | ||
1316 | if ((ps->recv_connected==GNUNET_YES) && (ps->send_connected==GNUNET_YES) && | ||
1317 | (ps->recv_force_disconnect==GNUNET_NO) && (ps->recv_force_disconnect==GNUNET_NO)) | ||
1318 | return GNUNET_YES; | ||
1319 | } | ||
1320 | return GNUNET_SYSERR; | ||
1321 | } | ||
1322 | |||
1323 | static void curl_perform (void *cls, | 1282 | static void curl_perform (void *cls, |
1324 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1283 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1325 | { | 1284 | { |
@@ -1537,6 +1496,254 @@ static int curl_schedule(void *cls ) | |||
1537 | return GNUNET_OK; | 1496 | return GNUNET_OK; |
1538 | } | 1497 | } |
1539 | 1498 | ||
1499 | /** | ||
1500 | * Function setting up curl handle and selecting message to send | ||
1501 | * @param cls plugin | ||
1502 | * @param ses session to send data to | ||
1503 | * @param con connection | ||
1504 | * @return GNUNET_SYSERR on failure, GNUNET_NO if connecting, GNUNET_YES if ok | ||
1505 | */ | ||
1506 | static ssize_t send_check_connections (void *cls, struct Session *ps) | ||
1507 | { | ||
1508 | struct Plugin *plugin = cls; | ||
1509 | CURLMcode mret; | ||
1510 | struct HTTP_Message * msg; | ||
1511 | |||
1512 | struct GNUNET_TIME_Relative timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; | ||
1513 | |||
1514 | GNUNET_assert(cls !=NULL); | ||
1515 | |||
1516 | if (ps->direction == OUTBOUND) | ||
1517 | { | ||
1518 | /* RECV DIRECTION */ | ||
1519 | /* Check if session is connected to receive data, otherwise connect to peer */ | ||
1520 | if (ps->recv_connected == GNUNET_NO) | ||
1521 | { | ||
1522 | if (ps->recv_endpoint == NULL) | ||
1523 | { | ||
1524 | ps->recv_endpoint = curl_easy_init(); | ||
1525 | #if DEBUG_CURL | ||
1526 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_VERBOSE, 1L); | ||
1527 | #endif | ||
1528 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_URL, ps->url); | ||
1529 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_HEADERFUNCTION, &curl_get_header_cb); | ||
1530 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEHEADER, ps); | ||
1531 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_READFUNCTION, curl_send_cb); | ||
1532 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_READDATA, ps); | ||
1533 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); | ||
1534 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_WRITEDATA, ps); | ||
1535 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_TIMEOUT, (long) timeout.value); | ||
1536 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_PRIVATE, ps); | ||
1537 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); | ||
1538 | curl_easy_setopt(ps->recv_endpoint, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
1539 | |||
1540 | mret = curl_multi_add_handle(plugin->multi_handle, ps->recv_endpoint); | ||
1541 | if (mret != CURLM_OK) | ||
1542 | { | ||
1543 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1544 | _("Connection: %X: %s failed at %s:%d: `%s'\n"), | ||
1545 | ps, | ||
1546 | "curl_multi_add_handle", __FILE__, __LINE__, | ||
1547 | curl_multi_strerror (mret)); | ||
1548 | return GNUNET_SYSERR; | ||
1549 | } | ||
1550 | if (curl_schedule (plugin) == GNUNET_SYSERR) | ||
1551 | return GNUNET_SYSERR; | ||
1552 | #if DEBUG_CONNECTIONS | ||
1553 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: inbound not connected, initiating connection\n",ps); | ||
1554 | #endif | ||
1555 | } | ||
1556 | } | ||
1557 | |||
1558 | /* waiting for receive direction */ | ||
1559 | if (ps->recv_connected==GNUNET_NO) | ||
1560 | return GNUNET_NO; | ||
1561 | |||
1562 | /* SEND DIRECTION */ | ||
1563 | /* Check if session is connected to send data, otherwise connect to peer */ | ||
1564 | if ((ps->send_connected == GNUNET_YES) && (ps->send_endpoint!= NULL)) | ||
1565 | { | ||
1566 | if (ps->send_active == GNUNET_YES) | ||
1567 | { | ||
1568 | #if DEBUG_CONNECTIONS | ||
1569 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound active, enqueueing message\n",ps); | ||
1570 | #endif | ||
1571 | return GNUNET_YES; | ||
1572 | } | ||
1573 | if (ps->send_active == GNUNET_NO) | ||
1574 | { | ||
1575 | #if DEBUG_CONNECTIONS | ||
1576 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound paused, unpausing existing connection and enqueueing message\n",ps); | ||
1577 | #endif | ||
1578 | if (CURLE_OK == curl_easy_pause(ps->send_endpoint,CURLPAUSE_CONT)) | ||
1579 | { | ||
1580 | ps->send_active=GNUNET_YES; | ||
1581 | return GNUNET_YES; | ||
1582 | } | ||
1583 | else | ||
1584 | return GNUNET_SYSERR; | ||
1585 | } | ||
1586 | } | ||
1587 | /* not connected, initiate connection */ | ||
1588 | if ((ps->send_connected==GNUNET_NO) && (NULL == ps->send_endpoint)) | ||
1589 | { | ||
1590 | ps->send_endpoint = curl_easy_init(); | ||
1591 | GNUNET_assert (ps->send_endpoint != NULL); | ||
1592 | GNUNET_assert (NULL != ps->pending_msgs_tail); | ||
1593 | #if DEBUG_CONNECTIONS | ||
1594 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: outbound not connected, initiating connection\n",ps); | ||
1595 | #endif | ||
1596 | ps->send_active = GNUNET_NO; | ||
1597 | msg = ps->pending_msgs_tail; | ||
1598 | |||
1599 | #if DEBUG_CURL | ||
1600 | curl_easy_setopt(ps->send_endpoint, CURLOPT_VERBOSE, 1L); | ||
1601 | #endif | ||
1602 | curl_easy_setopt(ps->send_endpoint, CURLOPT_URL, ps->url); | ||
1603 | curl_easy_setopt(ps->send_endpoint, CURLOPT_PUT, 1L); | ||
1604 | curl_easy_setopt(ps->send_endpoint, CURLOPT_HEADERFUNCTION, &curl_put_header_cb); | ||
1605 | curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEHEADER, ps); | ||
1606 | curl_easy_setopt(ps->send_endpoint, CURLOPT_READFUNCTION, curl_send_cb); | ||
1607 | curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); | ||
1608 | curl_easy_setopt(ps->send_endpoint, CURLOPT_WRITEFUNCTION, curl_receive_cb); | ||
1609 | curl_easy_setopt(ps->send_endpoint, CURLOPT_READDATA, ps); | ||
1610 | curl_easy_setopt(ps->send_endpoint, CURLOPT_TIMEOUT, (long) timeout.value); | ||
1611 | curl_easy_setopt(ps->send_endpoint, CURLOPT_PRIVATE, ps); | ||
1612 | curl_easy_setopt(ps->send_endpoint, CURLOPT_CONNECTTIMEOUT, HTTP_CONNECT_TIMEOUT); | ||
1613 | curl_easy_setopt(ps->send_endpoint, CURLOPT_BUFFERSIZE, GNUNET_SERVER_MAX_MESSAGE_SIZE); | ||
1614 | |||
1615 | mret = curl_multi_add_handle(plugin->multi_handle, ps->send_endpoint); | ||
1616 | if (mret != CURLM_OK) | ||
1617 | { | ||
1618 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1619 | _("Connection: %X: %s failed at %s:%d: `%s'\n"), | ||
1620 | ps, | ||
1621 | "curl_multi_add_handle", __FILE__, __LINE__, | ||
1622 | curl_multi_strerror (mret)); | ||
1623 | return GNUNET_SYSERR; | ||
1624 | } | ||
1625 | } | ||
1626 | if (curl_schedule (plugin) == GNUNET_SYSERR) | ||
1627 | return GNUNET_SYSERR; | ||
1628 | return GNUNET_YES; | ||
1629 | } | ||
1630 | if (ps->direction == INBOUND) | ||
1631 | { | ||
1632 | GNUNET_assert (NULL != ps->pending_msgs_tail); | ||
1633 | if ((ps->recv_connected==GNUNET_YES) && (ps->send_connected==GNUNET_YES) && | ||
1634 | (ps->recv_force_disconnect==GNUNET_NO) && (ps->recv_force_disconnect==GNUNET_NO)) | ||
1635 | return GNUNET_YES; | ||
1636 | } | ||
1637 | return GNUNET_SYSERR; | ||
1638 | } | ||
1639 | |||
1640 | static struct Session * send_get_session (void * cls, struct HTTP_PeerContext *pc, const void * addr, size_t addrlen, int force_address, struct Session * session) | ||
1641 | { | ||
1642 | struct Session * tmp = NULL; | ||
1643 | int addr_given = GNUNET_NO; | ||
1644 | |||
1645 | if ((addr!=NULL) && (addrlen>0)) | ||
1646 | addr_given = GNUNET_YES; | ||
1647 | |||
1648 | if (force_address == GNUNET_YES) | ||
1649 | { | ||
1650 | /* check session given as argument */ | ||
1651 | if ((session != NULL) && (addr_given == GNUNET_YES)) | ||
1652 | { | ||
1653 | if (0 == memcmp(session->addr, addr, addrlen)) | ||
1654 | { | ||
1655 | /* connection can not be used, since it is disconnected */ | ||
1656 | if ((session->recv_force_disconnect==GNUNET_NO) && (session->send_force_disconnect==GNUNET_NO)) | ||
1657 | { | ||
1658 | #ifdef DEBUG_SESSION_SELECTION | ||
1659 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using session passed by transport to send to forced address \n", session); | ||
1660 | #endif | ||
1661 | return session; | ||
1662 | } | ||
1663 | } | ||
1664 | } | ||
1665 | /* check last session used */ | ||
1666 | if ((pc->last_session != NULL)&& (addr_given == GNUNET_YES)) | ||
1667 | { | ||
1668 | if (0 == memcmp(pc->last_session->addr, addr, addrlen)) | ||
1669 | { | ||
1670 | /* connection can not be used, since it is disconnected */ | ||
1671 | if ((pc->last_session->recv_force_disconnect==GNUNET_NO) && (pc->last_session->send_force_disconnect==GNUNET_NO)) | ||
1672 | { | ||
1673 | #ifdef DEBUG_SESSION_SELECTION | ||
1674 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using last session used to send to forced address \n", pc->last_session); | ||
1675 | #endif | ||
1676 | return pc->last_session; | ||
1677 | } | ||
1678 | } | ||
1679 | } | ||
1680 | /* find session in existing sessions */ | ||
1681 | tmp = pc->head; | ||
1682 | while ((tmp!=NULL) && (addr_given == GNUNET_YES)) | ||
1683 | { | ||
1684 | |||
1685 | if (0 == memcmp(tmp->addr, addr, addrlen)) | ||
1686 | { | ||
1687 | /* connection can not be used, since it is disconnected */ | ||
1688 | if ((tmp->recv_force_disconnect==GNUNET_NO) && (tmp->send_force_disconnect==GNUNET_NO)) | ||
1689 | { | ||
1690 | #ifdef DEBUG_SESSION_SELECTION | ||
1691 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using existing session to send to forced address \n", session); | ||
1692 | #endif | ||
1693 | return session; | ||
1694 | } | ||
1695 | |||
1696 | } | ||
1697 | tmp=tmp->next; | ||
1698 | } | ||
1699 | /* no session to use */ | ||
1700 | return NULL; | ||
1701 | } | ||
1702 | if ((force_address == GNUNET_NO) || (force_address == GNUNET_SYSERR)) | ||
1703 | { | ||
1704 | /* check session given as argument */ | ||
1705 | if (session != NULL) | ||
1706 | { | ||
1707 | /* connection can not be used, since it is disconnected */ | ||
1708 | if ((session->recv_force_disconnect==GNUNET_NO) && (session->send_force_disconnect==GNUNET_NO)) | ||
1709 | { | ||
1710 | #ifdef DEBUG_SESSION_SELECTION | ||
1711 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using session passed by transport to send not-forced address \n", session); | ||
1712 | #endif | ||
1713 | return session; | ||
1714 | } | ||
1715 | |||
1716 | } | ||
1717 | /* check last session used */ | ||
1718 | if (pc->last_session != NULL) | ||
1719 | { | ||
1720 | /* connection can not be used, since it is disconnected */ | ||
1721 | if ((pc->last_session->recv_force_disconnect==GNUNET_NO) && (pc->last_session->send_force_disconnect==GNUNET_NO)) | ||
1722 | { | ||
1723 | #ifdef DEBUG_SESSION_SELECTION | ||
1724 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using last session to send to not-forced address \n", pc->last_session); | ||
1725 | #endif | ||
1726 | return pc->last_session; | ||
1727 | } | ||
1728 | } | ||
1729 | /* find session in existing sessions */ | ||
1730 | tmp = pc->head; | ||
1731 | while (tmp!=NULL) | ||
1732 | { | ||
1733 | /* connection can not be used, since it is disconnected */ | ||
1734 | if ((tmp->recv_force_disconnect==GNUNET_NO) && (tmp->send_force_disconnect==GNUNET_NO)) | ||
1735 | { | ||
1736 | #ifdef DEBUG_SESSION_SELECTION | ||
1737 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Session %X selected: Using existing session to send to not-forced address \n", tmp); | ||
1738 | #endif | ||
1739 | return tmp; | ||
1740 | } | ||
1741 | tmp=tmp->next; | ||
1742 | } | ||
1743 | return NULL; | ||
1744 | } | ||
1745 | return NULL; | ||
1746 | } | ||
1540 | 1747 | ||
1541 | /** | 1748 | /** |
1542 | * Function that can be used by the transport service to transmit | 1749 | * Function that can be used by the transport service to transmit |
@@ -1593,7 +1800,7 @@ http_plugin_send (void *cls, | |||
1593 | 1800 | ||
1594 | struct HTTP_PeerContext * pc; | 1801 | struct HTTP_PeerContext * pc; |
1595 | struct Session * ps = NULL; | 1802 | struct Session * ps = NULL; |
1596 | struct Session * ps_tmp = NULL; | 1803 | //struct Session * ps_tmp = NULL; |
1597 | 1804 | ||
1598 | GNUNET_assert(cls !=NULL); | 1805 | GNUNET_assert(cls !=NULL); |
1599 | 1806 | ||
@@ -1619,66 +1826,24 @@ http_plugin_send (void *cls, | |||
1619 | pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext)); | 1826 | pc = GNUNET_malloc(sizeof (struct HTTP_PeerContext)); |
1620 | pc->plugin = plugin; | 1827 | pc->plugin = plugin; |
1621 | pc->session_id_counter=1; | 1828 | pc->session_id_counter=1; |
1829 | pc->last_session = NULL; | ||
1622 | memcpy(&pc->identity, target, sizeof(struct GNUNET_PeerIdentity)); | 1830 | memcpy(&pc->identity, target, sizeof(struct GNUNET_PeerIdentity)); |
1623 | GNUNET_CONTAINER_multihashmap_put(plugin->peers, &pc->identity.hashPubKey, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1831 | GNUNET_CONTAINER_multihashmap_put(plugin->peers, &pc->identity.hashPubKey, pc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); |
1624 | } | 1832 | } |
1625 | 1833 | ||
1626 | /* Search for existing session using the passed address */ | 1834 | ps = send_get_session (plugin, pc, addr, addrlen, force_address, session); |
1627 | if ((addr!=NULL) && (addrlen != 0)) | ||
1628 | { | ||
1629 | ps = get_Session(plugin, pc, addr, addrlen); | ||
1630 | } | ||
1631 | if (ps != NULL) | ||
1632 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Found existing connection to peer %s with given address, using %X\n", GNUNET_i2s(target), ps); | ||
1633 | |||
1634 | /* Search for existing session using the passed session */ | ||
1635 | if ((ps==NULL) && (force_address != GNUNET_YES)) | ||
1636 | { | ||
1637 | ps_tmp = pc->head; | ||
1638 | while (ps_tmp!=NULL) | ||
1639 | { | ||
1640 | if ((ps_tmp==session) && (ps_tmp->recv_force_disconnect==GNUNET_NO) && (ps_tmp->send_force_disconnect==GNUNET_NO) && | ||
1641 | (ps_tmp->recv_connected==GNUNET_YES) && (ps_tmp->send_connected==GNUNET_YES)) | ||
1642 | { | ||
1643 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Found existing connection to peer %s with given session, using inbound session %X\n", GNUNET_i2s(target), ps_tmp); | ||
1644 | ps = ps_tmp; | ||
1645 | break; | ||
1646 | } | ||
1647 | ps_tmp=ps_tmp->next; | ||
1648 | } | ||
1649 | } | ||
1650 | |||
1651 | /* session not existing, address not forced -> looking for other session */ | ||
1652 | if ((ps==NULL) && (force_address != GNUNET_YES)) | ||
1653 | { | ||
1654 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection, but free to choose existing, searching for existing connection to peer %s\n", GNUNET_i2s(target)); | ||
1655 | /* Choosing different session to peer when possible */ | ||
1656 | struct Session * tmp = pc->head; | ||
1657 | while (tmp!=NULL) | ||
1658 | { | ||
1659 | if ((tmp->recv_connected) && (tmp->send_connected) && (tmp->recv_force_disconnect==GNUNET_NO) && (tmp->send_force_disconnect==GNUNET_NO)) | ||
1660 | { | ||
1661 | ps = tmp; | ||
1662 | } | ||
1663 | tmp = tmp->next; | ||
1664 | } | ||
1665 | if (ps != NULL) | ||
1666 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection to peer %s, selected connection %X\n", GNUNET_i2s(target),ps); | ||
1667 | else | ||
1668 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection to peer %s, no connection found\n", GNUNET_i2s(target)); | ||
1669 | } | ||
1670 | 1835 | ||
1671 | /* session not existing, but address forced -> creating new session */ | 1836 | /* session not existing, but address forced -> creating new session */ |
1672 | if ((ps==NULL) || ((ps==NULL) && (force_address == GNUNET_YES))) | 1837 | if (ps==NULL) |
1673 | { | 1838 | { |
1674 | if ((addr!=NULL) && (addrlen!=0)) | 1839 | if ((addr!=NULL) && (addrlen!=0)) |
1675 | { | 1840 | { |
1841 | ps = GNUNET_malloc(sizeof (struct Session)); | ||
1676 | if (force_address == GNUNET_YES) | 1842 | if (force_address == GNUNET_YES) |
1677 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection & forced address: creating new connection to peer %s\n", GNUNET_i2s(target)); | 1843 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection & forced address: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); |
1678 | if (force_address != GNUNET_YES) | 1844 | if (force_address != GNUNET_YES) |
1679 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection: creating new connection to peer %s\n", GNUNET_i2s(target)); | 1845 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing connection: creating new session %X to peer %s\n", ps, GNUNET_i2s(target)); |
1680 | 1846 | ||
1681 | ps = GNUNET_malloc(sizeof (struct Session)); | ||
1682 | if ((addrlen!=0) && (addr!=NULL)) | 1847 | if ((addrlen!=0) && (addr!=NULL)) |
1683 | { | 1848 | { |
1684 | ps->addr = GNUNET_malloc(addrlen); | 1849 | ps->addr = GNUNET_malloc(addrlen); |
@@ -1707,7 +1872,7 @@ http_plugin_send (void *cls, | |||
1707 | } | 1872 | } |
1708 | else | 1873 | else |
1709 | { | 1874 | { |
1710 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing session & and no address given: no way to send this message to peer `%s'!\n", GNUNET_i2s(target)); | 1875 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"No existing session found & and no address given: no way to send this message to peer `%s'!\n", GNUNET_i2s(target)); |
1711 | return GNUNET_SYSERR; | 1876 | return GNUNET_SYSERR; |
1712 | } | 1877 | } |
1713 | } | 1878 | } |
@@ -1724,7 +1889,14 @@ http_plugin_send (void *cls, | |||
1724 | GNUNET_CONTAINER_DLL_insert(ps->pending_msgs_head,ps->pending_msgs_tail,msg); | 1889 | GNUNET_CONTAINER_DLL_insert(ps->pending_msgs_head,ps->pending_msgs_tail,msg); |
1725 | 1890 | ||
1726 | if (send_check_connections (plugin, ps) != GNUNET_SYSERR) | 1891 | if (send_check_connections (plugin, ps) != GNUNET_SYSERR) |
1892 | { | ||
1893 | if (force_address != GNUNET_YES) | ||
1894 | pc->last_session = ps; | ||
1895 | |||
1896 | if (pc->last_session==NULL) | ||
1897 | pc->last_session = ps; | ||
1727 | return msg->size; | 1898 | return msg->size; |
1899 | } | ||
1728 | else | 1900 | else |
1729 | return GNUNET_SYSERR; | 1901 | return GNUNET_SYSERR; |
1730 | } | 1902 | } |
@@ -1971,113 +2143,6 @@ http_plugin_address_to_string (void *cls, | |||
1971 | return ret; | 2143 | return ret; |
1972 | } | 2144 | } |
1973 | 2145 | ||
1974 | /** | ||
1975 | * Add the IP of our network interface to the list of | ||
1976 | * our external IP addresses. | ||
1977 | * | ||
1978 | * @param cls the 'struct Plugin*' | ||
1979 | * @param name name of the interface | ||
1980 | * @param isDefault do we think this may be our default interface | ||
1981 | * @param addr address of the interface | ||
1982 | * @param addrlen number of bytes in addr | ||
1983 | * @return GNUNET_OK to continue iterating | ||
1984 | */ | ||
1985 | static int | ||
1986 | process_interfaces (void *cls, | ||
1987 | const char *name, | ||
1988 | int isDefault, | ||
1989 | const struct sockaddr *addr, socklen_t addrlen) | ||
1990 | { | ||
1991 | struct Plugin *plugin = cls; | ||
1992 | struct IPv4HttpAddress * t4; | ||
1993 | struct IPv6HttpAddress * t6; | ||
1994 | int af; | ||
1995 | |||
1996 | GNUNET_assert(cls !=NULL); | ||
1997 | af = addr->sa_family; | ||
1998 | if (af == AF_INET) | ||
1999 | { | ||
2000 | t4 = GNUNET_malloc(sizeof(struct IPv4HttpAddress)); | ||
2001 | /* Not skipping loopback addresses | ||
2002 | if (INADDR_LOOPBACK == ntohl(((struct sockaddr_in *) addr)->sin_addr.s_addr)) | ||
2003 | { | ||
2004 | |||
2005 | return GNUNET_OK; | ||
2006 | } | ||
2007 | */ | ||
2008 | t4->ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; | ||
2009 | t4->u_port = htons (plugin->port_inbound); | ||
2010 | plugin->env->notify_address(plugin->env->cls,"http",t4, sizeof (struct IPv4HttpAddress), GNUNET_TIME_UNIT_FOREVER_REL); | ||
2011 | |||
2012 | } | ||
2013 | else if (af == AF_INET6) | ||
2014 | { | ||
2015 | t6 = GNUNET_malloc(sizeof(struct IPv6HttpAddress)); | ||
2016 | if (IN6_IS_ADDR_LINKLOCAL (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
2017 | { | ||
2018 | /* skip link local addresses */ | ||
2019 | return GNUNET_OK; | ||
2020 | } | ||
2021 | /* Not skipping loopback addresses | ||
2022 | if (IN6_IS_ADDR_LOOPBACK (&((struct sockaddr_in6 *) addr)->sin6_addr)) | ||
2023 | { | ||
2024 | |||
2025 | return GNUNET_OK; | ||
2026 | } | ||
2027 | */ | ||
2028 | memcpy (&t6->ipv6_addr, | ||
2029 | &((struct sockaddr_in6 *) addr)->sin6_addr, | ||
2030 | sizeof (struct in6_addr)); | ||
2031 | t6->u6_port = htons (plugin->port_inbound); | ||
2032 | plugin->env->notify_address(plugin->env->cls,"http",t6,sizeof (struct IPv6HttpAddress) , GNUNET_TIME_UNIT_FOREVER_REL); | ||
2033 | } | ||
2034 | return GNUNET_NO; | ||
2035 | return GNUNET_OK; | ||
2036 | } | ||
2037 | |||
2038 | int remove_peer_context_Iterator (void *cls, const GNUNET_HashCode *key, void *value) | ||
2039 | { | ||
2040 | struct Plugin *plugin = cls; | ||
2041 | struct HTTP_PeerContext * pc = value; | ||
2042 | struct Session * ps = pc->head; | ||
2043 | struct Session * tmp = NULL; | ||
2044 | struct HTTP_Message * msg = NULL; | ||
2045 | struct HTTP_Message * msg_tmp = NULL; | ||
2046 | |||
2047 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Freeing context for peer `%s'\n",GNUNET_i2s(&pc->identity)); | ||
2048 | |||
2049 | while (ps!=NULL) | ||
2050 | { | ||
2051 | plugin->env->session_end(plugin, &pc->identity, ps); | ||
2052 | tmp = ps->next; | ||
2053 | |||
2054 | GNUNET_free_non_null (ps->addr); | ||
2055 | GNUNET_free(ps->url); | ||
2056 | if (ps->msgtok != NULL) | ||
2057 | GNUNET_SERVER_mst_destroy (ps->msgtok); | ||
2058 | |||
2059 | msg = ps->pending_msgs_head; | ||
2060 | while (msg!=NULL) | ||
2061 | { | ||
2062 | msg_tmp = msg->next; | ||
2063 | GNUNET_free(msg); | ||
2064 | msg = msg_tmp; | ||
2065 | } | ||
2066 | if (ps->direction==OUTBOUND) | ||
2067 | { | ||
2068 | if (ps->send_endpoint!=NULL) | ||
2069 | curl_easy_cleanup(ps->send_endpoint); | ||
2070 | if (ps->recv_endpoint!=NULL) | ||
2071 | curl_easy_cleanup(ps->recv_endpoint); | ||
2072 | } | ||
2073 | |||
2074 | GNUNET_free(ps); | ||
2075 | ps=tmp; | ||
2076 | } | ||
2077 | GNUNET_free(pc); | ||
2078 | return GNUNET_YES; | ||
2079 | } | ||
2080 | |||
2081 | 2146 | ||
2082 | /** | 2147 | /** |
2083 | * Exit point from the plugin. | 2148 | * Exit point from the plugin. |
@@ -2137,6 +2202,7 @@ libgnunet_plugin_transport_http_done (void *cls) | |||
2137 | plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; | 2202 | plugin->http_curl_task = GNUNET_SCHEDULER_NO_TASK; |
2138 | } | 2203 | } |
2139 | 2204 | ||
2205 | GNUNET_free_non_null (plugin->bind_address); | ||
2140 | GNUNET_free (plugin); | 2206 | GNUNET_free (plugin); |
2141 | GNUNET_free (api); | 2207 | GNUNET_free (api); |
2142 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Unload http plugin complete...\n"); | 2208 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Unload http plugin complete...\n"); |
@@ -2155,6 +2221,7 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2155 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 2221 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
2156 | struct GNUNET_TIME_Relative gn_timeout; | 2222 | struct GNUNET_TIME_Relative gn_timeout; |
2157 | long long unsigned int port; | 2223 | long long unsigned int port; |
2224 | char * hostname; | ||
2158 | 2225 | ||
2159 | GNUNET_assert(cls !=NULL); | 2226 | GNUNET_assert(cls !=NULL); |
2160 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting http plugin...\n"); | 2227 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Starting http plugin...\n"); |
@@ -2163,6 +2230,7 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2163 | plugin->stats = env->stats; | 2230 | plugin->stats = env->stats; |
2164 | plugin->env = env; | 2231 | plugin->env = env; |
2165 | plugin->peers = NULL; | 2232 | plugin->peers = NULL; |
2233 | plugin->bind_address = GNUNET_malloc(sizeof(struct in_addr*)); | ||
2166 | 2234 | ||
2167 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); | 2235 | api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); |
2168 | api->cls = plugin; | 2236 | api->cls = plugin; |
@@ -2191,6 +2259,23 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2191 | libgnunet_plugin_transport_http_done (api); | 2259 | libgnunet_plugin_transport_http_done (api); |
2192 | return NULL; | 2260 | return NULL; |
2193 | } | 2261 | } |
2262 | |||
2263 | /* Reading port number from config file */ | ||
2264 | if (GNUNET_CONFIGURATION_have_value (env->cfg, | ||
2265 | "transport-http", "BINDTO")) | ||
2266 | { | ||
2267 | GNUNET_break (GNUNET_OK == | ||
2268 | GNUNET_CONFIGURATION_get_value_string (env->cfg, | ||
2269 | "transport-http", | ||
2270 | "BINDTO", | ||
2271 | &hostname)); | ||
2272 | if (inet_aton(hostname, plugin->bind_address)==0) | ||
2273 | { | ||
2274 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR,"Misconfigured address to bind to in configuration\n"); | ||
2275 | GNUNET_free(plugin->bind_address); | ||
2276 | plugin->bind_address = NULL; | ||
2277 | } | ||
2278 | } | ||
2194 | GNUNET_assert ((port > 0) && (port <= 65535)); | 2279 | GNUNET_assert ((port > 0) && (port <= 65535)); |
2195 | plugin->port_inbound = port; | 2280 | plugin->port_inbound = port; |
2196 | gn_timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; | 2281 | gn_timeout = GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT; |
@@ -2211,6 +2296,7 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2211 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (16 * 1024), | 2296 | MHD_OPTION_CONNECTION_MEMORY_LIMIT, (size_t) (16 * 1024), |
2212 | MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL, | 2297 | MHD_OPTION_NOTIFY_COMPLETED, &mhd_termination_cb, NULL, |
2213 | MHD_OPTION_END); | 2298 | MHD_OPTION_END); |
2299 | |||
2214 | plugin->http_server_daemon_v4 = MHD_start_daemon ( | 2300 | plugin->http_server_daemon_v4 = MHD_start_daemon ( |
2215 | #if DEBUG_HTTP | 2301 | #if DEBUG_HTTP |
2216 | MHD_USE_DEBUG | | 2302 | MHD_USE_DEBUG | |
@@ -2219,6 +2305,7 @@ libgnunet_plugin_transport_http_init (void *cls) | |||
2219 | port, | 2305 | port, |
2220 | &mhd_accept_cb, | 2306 | &mhd_accept_cb, |
2221 | plugin , &mdh_access_cb, plugin, | 2307 | plugin , &mdh_access_cb, plugin, |
2308 | //MHD_OPTION_SOCK_ADDR, (struct sockaddr *) &in4, | ||
2222 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, | 2309 | MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 32, |
2223 | MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, | 2310 | MHD_OPTION_PER_IP_CONNECTION_LIMIT, (unsigned int) 6, |
2224 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, | 2311 | MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) timeout, |
diff --git a/src/transport/test_plugin_transport.c b/src/transport/test_plugin_transport.c index db635aec2..ccaefd042 100644 --- a/src/transport/test_plugin_transport.c +++ b/src/transport/test_plugin_transport.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include "plugin_transport.h" | 37 | #include "plugin_transport.h" |
38 | #include "transport.h" | 38 | #include "transport.h" |
39 | 39 | ||
40 | #define VERBOSE GNUNET_NO | 40 | #define VERBOSE GNUNET_YES |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * How long until we give up on transmitting the message? | 43 | * How long until we give up on transmitting the message? |
diff --git a/src/transport/test_plugin_transport_data_http.conf b/src/transport/test_plugin_transport_data_http.conf index df1a47a36..a536b8e3a 100644 --- a/src/transport/test_plugin_transport_data_http.conf +++ b/src/transport/test_plugin_transport_data_http.conf | |||
@@ -7,7 +7,9 @@ WEAKRANDOM = YES | |||
7 | 7 | ||
8 | [transport-http] | 8 | [transport-http] |
9 | PORT = 12389 | 9 | PORT = 12389 |
10 | DEBUG = NO | 10 | DEBUG = YES |
11 | BINDTO = 127.0.0.1 | ||
12 | |||
11 | 13 | ||
12 | [statistics] | 14 | [statistics] |
13 | ACCEPT_FROM6 = ::1; | 15 | ACCEPT_FROM6 = ::1; |
diff --git a/src/transport/test_transport_api_http_peer1.conf b/src/transport/test_transport_api_http_peer1.conf index 071e3090b..2cbf82e5e 100644 --- a/src/transport/test_transport_api_http_peer1.conf +++ b/src/transport/test_transport_api_http_peer1.conf | |||
@@ -1,3 +1,8 @@ | |||
1 | [transport-http] | ||
2 | PORT = 12389 | ||
3 | DEBUG = YES | ||
4 | BINDTO = 127.0.0.1 | ||
5 | |||
1 | [fs] | 6 | [fs] |
2 | AUTOSTART = NO | 7 | AUTOSTART = NO |
3 | 8 | ||
@@ -85,10 +90,6 @@ HOSTNAME = localhost | |||
85 | PORT = 12366 | 90 | PORT = 12366 |
86 | UNIXPATH = /tmp/gnunet-p1-service-arm.sock | 91 | UNIXPATH = /tmp/gnunet-p1-service-arm.sock |
87 | 92 | ||
88 | [transport-http] | ||
89 | PORT = 12389 | ||
90 | DEBUG = NO | ||
91 | |||
92 | [transport-tcp] | 93 | [transport-tcp] |
93 | PORT = 12399 | 94 | PORT = 12399 |
94 | DEBUG = YES | 95 | DEBUG = YES |
diff --git a/src/transport/test_transport_api_http_peer2.conf b/src/transport/test_transport_api_http_peer2.conf index 174175328..15a562b6e 100644 --- a/src/transport/test_transport_api_http_peer2.conf +++ b/src/transport/test_transport_api_http_peer2.conf | |||
@@ -1,6 +1,7 @@ | |||
1 | [transport-http] | 1 | [transport-http] |
2 | PORT = 22368 | 2 | PORT = 22368 |
3 | DEBUG = YES | 3 | DEBUG = YES |
4 | BINDTO = 127.0.0.1 | ||
4 | 5 | ||
5 | [fs] | 6 | [fs] |
6 | AUTOSTART = NO | 7 | AUTOSTART = NO |
diff --git a/src/transport/test_transport_api_tcp_peer1.conf b/src/transport/test_transport_api_tcp_peer1.conf index e09a56f3a..e695cbb93 100644 --- a/src/transport/test_transport_api_tcp_peer1.conf +++ b/src/transport/test_transport_api_tcp_peer1.conf | |||
@@ -1,6 +1,7 @@ | |||
1 | [transport-tcp] | 1 | [transport-tcp] |
2 | PORT = 12368 | 2 | PORT = 12368 |
3 | BINDTO = 127.0.0.1 | 3 | #BINDTO = 127.0.0.1 |
4 | BINDTO = 131.159.20.52 | ||
4 | 5 | ||
5 | [fs] | 6 | [fs] |
6 | AUTOSTART = NO | 7 | AUTOSTART = NO |
diff --git a/src/transport/test_transport_api_tcp_peer2.conf b/src/transport/test_transport_api_tcp_peer2.conf index 4a4219d7b..09cdf7f39 100644 --- a/src/transport/test_transport_api_tcp_peer2.conf +++ b/src/transport/test_transport_api_tcp_peer2.conf | |||
@@ -1,6 +1,7 @@ | |||
1 | [transport-tcp] | 1 | [transport-tcp] |
2 | PORT = 22368 | 2 | PORT = 22368 |
3 | BINDTO = 127.0.0.1 | 3 | #BINDTO = 127.0.0.1 |
4 | BINDTO = 131.159.20.52 | ||
4 | 5 | ||
5 | [core] | 6 | [core] |
6 | AUTOSTART = NO | 7 | AUTOSTART = NO |
@@ -32,7 +33,7 @@ MINIMUM-FRIENDS = 0 | |||
32 | 33 | ||
33 | [transport] | 34 | [transport] |
34 | PLUGINS = tcp | 35 | PLUGINS = tcp |
35 | #DEBUG = YES | 36 | DEBUG = YES |
36 | ACCEPT_FROM6 = ::1; | 37 | ACCEPT_FROM6 = ::1; |
37 | ACCEPT_FROM = 127.0.0.1; | 38 | ACCEPT_FROM = 127.0.0.1; |
38 | #PREFIX = valgrind --tool=callgrind | 39 | #PREFIX = valgrind --tool=callgrind |