aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2010-07-15 16:27:48 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2010-07-15 16:27:48 +0000
commit7adcdc82792c48f2331185d9af9d56925978804a (patch)
tree192b169b1679d52cf08e8cdb7f7890b54b05a11e
parent27294d85406ed2c51b53112b42915141f866ff1e (diff)
downloadgnunet-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.c833
-rw-r--r--src/transport/test_plugin_transport.c2
-rw-r--r--src/transport/test_plugin_transport_data_http.conf4
-rw-r--r--src/transport/test_transport_api_http_peer1.conf9
-rw-r--r--src/transport/test_transport_api_http_peer2.conf1
-rw-r--r--src/transport/test_transport_api_tcp_peer1.conf3
-rw-r--r--src/transport/test_transport_api_tcp_peer2.conf5
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 */
385static 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 */
390static 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 */
399static 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 */
407static int curl_schedule(void *cls );
408
409
410
370static char * create_url(void * cls, const void * addr, size_t addrlen, size_t id) 411static 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
435static struct Session * get_Session (void * cls, struct HTTP_PeerContext *pc, const void * addr, size_t addr_len) 476int 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 */
530static int
531process_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
522static 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 */
840static 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 */
845static 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/** 1066static 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 */
978static ssize_t send_check_connections (void *cls, struct Session *ps);
979
980static 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
1030static size_t curl_put_header_function( void *ptr, size_t size, size_t nmemb, void *stream) 1116static 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
1238static 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 */
1178static 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 */
1189static 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
1323static void curl_perform (void *cls, 1282static 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 */
1506static 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
1640static 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 */
1985static int
1986process_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
2038int 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]
9PORT = 12389 9PORT = 12389
10DEBUG = NO 10DEBUG = YES
11BINDTO = 127.0.0.1
12
11 13
12[statistics] 14[statistics]
13ACCEPT_FROM6 = ::1; 15ACCEPT_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]
2PORT = 12389
3DEBUG = YES
4BINDTO = 127.0.0.1
5
1[fs] 6[fs]
2AUTOSTART = NO 7AUTOSTART = NO
3 8
@@ -85,10 +90,6 @@ HOSTNAME = localhost
85PORT = 12366 90PORT = 12366
86UNIXPATH = /tmp/gnunet-p1-service-arm.sock 91UNIXPATH = /tmp/gnunet-p1-service-arm.sock
87 92
88[transport-http]
89PORT = 12389
90DEBUG = NO
91
92[transport-tcp] 93[transport-tcp]
93PORT = 12399 94PORT = 12399
94DEBUG = YES 95DEBUG = 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]
2PORT = 22368 2PORT = 22368
3DEBUG = YES 3DEBUG = YES
4BINDTO = 127.0.0.1
4 5
5[fs] 6[fs]
6AUTOSTART = NO 7AUTOSTART = 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]
2PORT = 12368 2PORT = 12368
3BINDTO = 127.0.0.1 3#BINDTO = 127.0.0.1
4BINDTO = 131.159.20.52
4 5
5[fs] 6[fs]
6AUTOSTART = NO 7AUTOSTART = 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]
2PORT = 22368 2PORT = 22368
3BINDTO = 127.0.0.1 3#BINDTO = 127.0.0.1
4BINDTO = 131.159.20.52
4 5
5[core] 6[core]
6AUTOSTART = NO 7AUTOSTART = NO
@@ -32,7 +33,7 @@ MINIMUM-FRIENDS = 0
32 33
33[transport] 34[transport]
34PLUGINS = tcp 35PLUGINS = tcp
35#DEBUG = YES 36DEBUG = YES
36ACCEPT_FROM6 = ::1; 37ACCEPT_FROM6 = ::1;
37ACCEPT_FROM = 127.0.0.1; 38ACCEPT_FROM = 127.0.0.1;
38#PREFIX = valgrind --tool=callgrind 39#PREFIX = valgrind --tool=callgrind