aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-07-08 16:34:31 +0000
committerChristian Grothoff <christian@grothoff.org>2016-07-08 16:34:31 +0000
commit6e3599bab213760c66f13f6103ebf650bbe5b7e9 (patch)
treef56a0bbe3ce64c818c87bae6171ba800ab05b701
parent2c0a286c8c29e135c68556658b6ac6cef48a874a (diff)
downloadgnunet-6e3599bab213760c66f13f6103ebf650bbe5b7e9.tar.gz
gnunet-6e3599bab213760c66f13f6103ebf650bbe5b7e9.zip
migrate transport_core API to MQ
-rw-r--r--src/cadet/gnunet-service-cadet_peer.c39
-rw-r--r--src/core/test_core_api.c6
-rw-r--r--src/core/test_core_api_reliability.c10
-rw-r--r--src/core/test_core_quota_compliance.c10
-rw-r--r--src/dht/gnunet-service-dht.c22
-rw-r--r--src/dht/gnunet-service-dht.h4
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c8
-rw-r--r--src/hostlist/gnunet-daemon-hostlist_client.c76
-rw-r--r--src/hostlist/test_gnunet_daemon_hostlist.c2
-rw-r--r--src/hostlist/test_gnunet_daemon_hostlist_reconnect.c2
-rw-r--r--src/include/gnunet_transport_core_service.h94
-rw-r--r--src/include/gnunet_transport_service.h15
-rw-r--r--src/peerinfo-tool/gnunet-peerinfo.c18
-rw-r--r--src/testbed/gnunet-service-testbed_connectionpool.c3
-rw-r--r--src/testbed/gnunet-service-testbed_connectionpool.h4
-rw-r--r--src/testbed/gnunet-service-testbed_oc.c35
-rw-r--r--src/topology/gnunet-daemon-topology.c55
-rw-r--r--src/transport/Makefile.am6
-rw-r--r--src/transport/transport-testing.c6
-rw-r--r--src/transport/transport_api.c1245
-rw-r--r--src/transport/transport_api_get_hello.c199
-rw-r--r--src/transport/transport_api_offer_hello.c98
22 files changed, 787 insertions, 1170 deletions
diff --git a/src/cadet/gnunet-service-cadet_peer.c b/src/cadet/gnunet-service-cadet_peer.c
index fa16db4bb..101b9e22a 100644
--- a/src/cadet/gnunet-service-cadet_peer.c
+++ b/src/cadet/gnunet-service-cadet_peer.c
@@ -245,14 +245,14 @@ static unsigned long long drop_percent;
245static struct GNUNET_CORE_Handle *core_handle; 245static struct GNUNET_CORE_Handle *core_handle;
246 246
247/** 247/**
248 * Handle to communicate with ATS. 248 * Our configuration;
249 */ 249 */
250static struct GNUNET_ATS_ConnectivityHandle *ats_ch; 250static const struct GNUNET_CONFIGURATION_Handle *cfg;
251 251
252/** 252/**
253 * Handle to try to start new connections. 253 * Handle to communicate with ATS.
254 */ 254 */
255static struct GNUNET_TRANSPORT_Handle *transport_handle; 255static struct GNUNET_ATS_ConnectivityHandle *ats_ch;
256 256
257/** 257/**
258 * Shutdown falg. 258 * Shutdown falg.
@@ -557,6 +557,7 @@ core_init (void *cls,
557 const struct GNUNET_CONFIGURATION_Handle *c = cls; 557 const struct GNUNET_CONFIGURATION_Handle *c = cls;
558 static int i = 0; 558 static int i = 0;
559 559
560 cfg = c;
560 LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n"); 561 LOG (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
561 if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id))) 562 if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)))
562 { 563 {
@@ -1841,24 +1842,6 @@ GCP_init (const struct GNUNET_CONFIGURATION_Handle *c)
1841 NULL, /* Don't notify about all outbound messages */ 1842 NULL, /* Don't notify about all outbound messages */
1842 GNUNET_NO, /* For header-only out notification */ 1843 GNUNET_NO, /* For header-only out notification */
1843 core_handlers); /* Register these handlers */ 1844 core_handlers); /* Register these handlers */
1844 if (GNUNET_YES !=
1845 GNUNET_CONFIGURATION_get_value_yesno (c, "CADET", "DISABLE_TRY_CONNECT"))
1846 {
1847 transport_handle = GNUNET_TRANSPORT_connect (c, &my_full_id, NULL, /* cls */
1848 /* Notify callbacks */
1849 NULL, NULL, NULL);
1850 }
1851 else
1852 {
1853 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1854 LOG (GNUNET_ERROR_TYPE_WARNING, "* DISABLE TRYING CONNECT in config *\n");
1855 LOG (GNUNET_ERROR_TYPE_WARNING, "* Use this only for test purposes. *\n");
1856 LOG (GNUNET_ERROR_TYPE_WARNING, "**************************************\n");
1857 transport_handle = NULL;
1858 }
1859
1860
1861
1862 if (NULL == core_handle) 1845 if (NULL == core_handle)
1863 { 1846 {
1864 GNUNET_break (0); 1847 GNUNET_break (0);
@@ -1886,11 +1869,6 @@ GCP_shutdown (void)
1886 GNUNET_CORE_disconnect (core_handle); 1869 GNUNET_CORE_disconnect (core_handle);
1887 core_handle = NULL; 1870 core_handle = NULL;
1888 } 1871 }
1889 if (NULL != transport_handle)
1890 {
1891 GNUNET_TRANSPORT_disconnect (transport_handle);
1892 transport_handle = NULL;
1893 }
1894 if (NULL != ats_ch) 1872 if (NULL != ats_ch)
1895 { 1873 {
1896 GNUNET_ATS_connectivity_done (ats_ch); 1874 GNUNET_ATS_connectivity_done (ats_ch);
@@ -2591,7 +2569,10 @@ GCP_try_connect (struct CadetPeer *peer)
2591 struct GNUNET_HELLO_Message *hello; 2569 struct GNUNET_HELLO_Message *hello;
2592 struct GNUNET_MessageHeader *mh; 2570 struct GNUNET_MessageHeader *mh;
2593 2571
2594 if (NULL == transport_handle) 2572 if (GNUNET_YES !=
2573 GNUNET_CONFIGURATION_get_value_yesno (cfg,
2574 "CADET",
2575 "DISABLE_TRY_CONNECT"))
2595 return; 2576 return;
2596 GCC_check_connections (); 2577 GCC_check_connections ();
2597 if (GNUNET_YES == GCP_is_neighbor (peer)) 2578 if (GNUNET_YES == GCP_is_neighbor (peer))
@@ -2606,7 +2587,7 @@ GCP_try_connect (struct CadetPeer *peer)
2606 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer); 2587 GNUNET_TRANSPORT_offer_hello_cancel (peer->hello_offer);
2607 peer->hello_offer = NULL; 2588 peer->hello_offer = NULL;
2608 } 2589 }
2609 peer->hello_offer = GNUNET_TRANSPORT_offer_hello (transport_handle, 2590 peer->hello_offer = GNUNET_TRANSPORT_offer_hello (cfg,
2610 mh, 2591 mh,
2611 &hello_offer_done, 2592 &hello_offer_done,
2612 peer); 2593 peer);
diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c
index 92ee038da..43f4c421e 100644
--- a/src/core/test_core_api.c
+++ b/src/core/test_core_api.c
@@ -65,9 +65,9 @@ process_hello (void *cls,
65 "Received (my) `%s' from transport service\n", "HELLO"); 65 "Received (my) `%s' from transport service\n", "HELLO");
66 GNUNET_assert (message != NULL); 66 GNUNET_assert (message != NULL);
67 if ((p == &p1) && (p2.th != NULL)) 67 if ((p == &p1) && (p2.th != NULL))
68 GNUNET_TRANSPORT_offer_hello (p2.th, message, NULL, NULL); 68 GNUNET_TRANSPORT_offer_hello (p2.cfg, message, NULL, NULL);
69 if ((p == &p2) && (p1.th != NULL)) 69 if ((p == &p2) && (p1.th != NULL))
70 GNUNET_TRANSPORT_offer_hello (p1.th, message, NULL, NULL); 70 GNUNET_TRANSPORT_offer_hello (p1.cfg, message, NULL, NULL);
71} 71}
72 72
73 73
@@ -280,7 +280,7 @@ setup_peer (struct PeerContext *p,
280 GNUNET_assert (NULL != p->th); 280 GNUNET_assert (NULL != p->th);
281 p->ats = GNUNET_ATS_connectivity_init (p->cfg); 281 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
282 GNUNET_assert (NULL != p->ats); 282 GNUNET_assert (NULL != p->ats);
283 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p); 283 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg, &process_hello, p);
284 GNUNET_free (binary); 284 GNUNET_free (binary);
285} 285}
286 286
diff --git a/src/core/test_core_api_reliability.c b/src/core/test_core_api_reliability.c
index c7672afdb..94c223b74 100644
--- a/src/core/test_core_api_reliability.c
+++ b/src/core/test_core_api_reliability.c
@@ -412,14 +412,14 @@ process_hello (void *cls,
412 GNUNET_assert (message != NULL); 412 GNUNET_assert (message != NULL);
413 p->hello = GNUNET_copy_message (message); 413 p->hello = GNUNET_copy_message (message);
414 if ((p == &p1) && (p2.th != NULL)) 414 if ((p == &p1) && (p2.th != NULL))
415 GNUNET_TRANSPORT_offer_hello (p2.th, message, NULL, NULL); 415 GNUNET_TRANSPORT_offer_hello (p2.cfg, message, NULL, NULL);
416 if ((p == &p2) && (p1.th != NULL)) 416 if ((p == &p2) && (p1.th != NULL))
417 GNUNET_TRANSPORT_offer_hello (p1.th, message, NULL, NULL); 417 GNUNET_TRANSPORT_offer_hello (p1.cfg, message, NULL, NULL);
418 418
419 if ((p == &p1) && (p2.hello != NULL)) 419 if ((p == &p1) && (p2.hello != NULL))
420 GNUNET_TRANSPORT_offer_hello (p1.th, p2.hello, NULL, NULL); 420 GNUNET_TRANSPORT_offer_hello (p1.cfg, p2.hello, NULL, NULL);
421 if ((p == &p2) && (p1.hello != NULL)) 421 if ((p == &p2) && (p1.hello != NULL))
422 GNUNET_TRANSPORT_offer_hello (p2.th, p1.hello, NULL, NULL); 422 GNUNET_TRANSPORT_offer_hello (p2.cfg, p1.hello, NULL, NULL);
423} 423}
424 424
425 425
@@ -442,7 +442,7 @@ setup_peer (struct PeerContext *p,
442 GNUNET_assert (p->th != NULL); 442 GNUNET_assert (p->th != NULL);
443 p->ats = GNUNET_ATS_connectivity_init (p->cfg); 443 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
444 GNUNET_assert (NULL != p->ats); 444 GNUNET_assert (NULL != p->ats);
445 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p); 445 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg, &process_hello, p);
446 GNUNET_free (binary); 446 GNUNET_free (binary);
447} 447}
448 448
diff --git a/src/core/test_core_quota_compliance.c b/src/core/test_core_quota_compliance.c
index 05b1ae3d9..28d836e2e 100644
--- a/src/core/test_core_quota_compliance.c
+++ b/src/core/test_core_quota_compliance.c
@@ -547,14 +547,14 @@ process_hello (void *cls, const struct GNUNET_MessageHeader *message)
547 p->hello = GNUNET_malloc (ntohs (message->size)); 547 p->hello = GNUNET_malloc (ntohs (message->size));
548 memcpy (p->hello, message, ntohs (message->size)); 548 memcpy (p->hello, message, ntohs (message->size));
549 if ((p == &p1) && (p2.th != NULL)) 549 if ((p == &p1) && (p2.th != NULL))
550 GNUNET_TRANSPORT_offer_hello (p2.th, message, NULL, NULL); 550 GNUNET_TRANSPORT_offer_hello (p2.cfg, message, NULL, NULL);
551 if ((p == &p2) && (p1.th != NULL)) 551 if ((p == &p2) && (p1.th != NULL))
552 GNUNET_TRANSPORT_offer_hello (p1.th, message, NULL, NULL); 552 GNUNET_TRANSPORT_offer_hello (p1.cfg, message, NULL, NULL);
553 553
554 if ((p == &p1) && (p2.hello != NULL)) 554 if ((p == &p1) && (p2.hello != NULL))
555 GNUNET_TRANSPORT_offer_hello (p1.th, p2.hello, NULL, NULL); 555 GNUNET_TRANSPORT_offer_hello (p1.cfg, p2.hello, NULL, NULL);
556 if ((p == &p2) && (p1.hello != NULL)) 556 if ((p == &p2) && (p1.hello != NULL))
557 GNUNET_TRANSPORT_offer_hello (p2.th, p1.hello, NULL, NULL); 557 GNUNET_TRANSPORT_offer_hello (p2.cfg, p1.hello, NULL, NULL);
558} 558}
559 559
560 560
@@ -579,7 +579,7 @@ setup_peer (struct PeerContext *p, const char *cfgname)
579 GNUNET_assert (p->th != NULL); 579 GNUNET_assert (p->th != NULL);
580 p->ats = GNUNET_ATS_connectivity_init (p->cfg); 580 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
581 GNUNET_assert (NULL != p->ats); 581 GNUNET_assert (NULL != p->ats);
582 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p); 582 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg, &process_hello, p);
583 GNUNET_free (binary); 583 GNUNET_free (binary);
584} 584}
585 585
diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c
index abdd77548..e3b9d59a4 100644
--- a/src/dht/gnunet-service-dht.c
+++ b/src/dht/gnunet-service-dht.c
@@ -67,11 +67,6 @@ struct GNUNET_SERVER_Handle *GDS_server;
67struct GNUNET_MessageHeader *GDS_my_hello; 67struct GNUNET_MessageHeader *GDS_my_hello;
68 68
69/** 69/**
70 * Handle to the transport service, for getting our hello
71 */
72struct GNUNET_TRANSPORT_Handle *GDS_transport_handle;
73
74/**
75 * Handle to get our current HELLO. 70 * Handle to get our current HELLO.
76 */ 71 */
77static struct GNUNET_TRANSPORT_GetHelloHandle *ghh; 72static struct GNUNET_TRANSPORT_GetHelloHandle *ghh;
@@ -112,11 +107,6 @@ shutdown_task (void *cls)
112 GNUNET_TRANSPORT_get_hello_cancel (ghh); 107 GNUNET_TRANSPORT_get_hello_cancel (ghh);
113 ghh = NULL; 108 ghh = NULL;
114 } 109 }
115 if (GDS_transport_handle != NULL)
116 {
117 GNUNET_TRANSPORT_disconnect (GDS_transport_handle);
118 GDS_transport_handle = NULL;
119 }
120 GDS_NEIGHBOURS_done (); 110 GDS_NEIGHBOURS_done ();
121 GDS_DATACACHE_done (); 111 GDS_DATACACHE_done ();
122 GDS_ROUTING_done (); 112 GDS_ROUTING_done ();
@@ -170,15 +160,9 @@ run (void *cls,
170 } 160 }
171 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 161 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
172 NULL); 162 NULL);
173 GDS_transport_handle = 163 ghh = GNUNET_TRANSPORT_get_hello (GDS_cfg,
174 GNUNET_TRANSPORT_connect (GDS_cfg, NULL, NULL, NULL, NULL, NULL); 164 &process_hello,
175 if (GDS_transport_handle == NULL) 165 NULL);
176 {
177 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
178 _("Failed to connect to transport service!\n"));
179 return;
180 }
181 ghh = GNUNET_TRANSPORT_get_hello (GDS_transport_handle, &process_hello, NULL);
182} 166}
183 167
184 168
diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h
index 6f641cb96..4684c2324 100644
--- a/src/dht/gnunet-service-dht.h
+++ b/src/dht/gnunet-service-dht.h
@@ -57,9 +57,5 @@ extern struct GNUNET_SERVER_Handle *GDS_server;
57 */ 57 */
58extern struct GNUNET_MessageHeader *GDS_my_hello; 58extern struct GNUNET_MessageHeader *GDS_my_hello;
59 59
60/**
61 * Handle to the transport service, for getting our hello
62 */
63extern struct GNUNET_TRANSPORT_Handle *GDS_transport_handle;
64 60
65#endif 61#endif
diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c
index 4add3c4ae..b24a95ab2 100644
--- a/src/dht/gnunet-service-dht_neighbours.c
+++ b/src/dht/gnunet-service-dht_neighbours.c
@@ -592,13 +592,11 @@ try_connect (const struct GNUNET_PeerIdentity *pid,
592 ci, 592 ci,
593 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 593 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
594 } 594 }
595 if ( (NULL != GDS_transport_handle) && 595 if ( (NULL != ci->oh) &&
596 (NULL != ci->oh) &&
597 (NULL != h) ) 596 (NULL != h) )
598 GNUNET_TRANSPORT_offer_hello_cancel (ci->oh); 597 GNUNET_TRANSPORT_offer_hello_cancel (ci->oh);
599 if ( (NULL != GDS_transport_handle) && 598 if (NULL != h)
600 (NULL != h) ) 599 ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_cfg,
601 ci->oh = GNUNET_TRANSPORT_offer_hello (GDS_transport_handle,
602 h, 600 h,
603 &offer_hello_done, 601 &offer_hello_done,
604 ci); 602 ci);
diff --git a/src/hostlist/gnunet-daemon-hostlist_client.c b/src/hostlist/gnunet-daemon-hostlist_client.c
index df0cabe1d..c8c74a9ba 100644
--- a/src/hostlist/gnunet-daemon-hostlist_client.c
+++ b/src/hostlist/gnunet-daemon-hostlist_client.c
@@ -142,6 +142,14 @@ struct Hostlist
142}; 142};
143 143
144 144
145struct HelloOffer
146{
147 struct HelloOffer *next;
148 struct HelloOffer *prev;
149 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh;
150};
151
152
145/** 153/**
146 * Our configuration. 154 * Our configuration.
147 */ 155 */
@@ -153,11 +161,6 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
153static struct GNUNET_STATISTICS_Handle *stats; 161static struct GNUNET_STATISTICS_Handle *stats;
154 162
155/** 163/**
156 * Transport handle.
157 */
158static struct GNUNET_TRANSPORT_Handle *transport;
159
160/**
161 * Proxy hostname or ip we are using (can be NULL). 164 * Proxy hostname or ip we are using (can be NULL).
162 */ 165 */
163static char *proxy; 166static char *proxy;
@@ -312,6 +315,25 @@ static unsigned int stat_hellos_obtained;
312 */ 315 */
313static unsigned int stat_connection_count; 316static unsigned int stat_connection_count;
314 317
318static struct HelloOffer *ho_head;
319
320static struct HelloOffer *ho_tail;
321
322
323/**
324 * Hello offer complete. Clean up.
325 */
326static void
327done_offer_hello (void *cls)
328{
329 struct HelloOffer *ho = cls;
330
331 GNUNET_CONTAINER_DLL_remove (ho_head,
332 ho_tail,
333 ho);
334 GNUNET_free (ho);
335}
336
315 337
316/** 338/**
317 * Process downloaded bits by calling callback on each HELLO. 339 * Process downloaded bits by calling callback on each HELLO.
@@ -331,6 +353,7 @@ callback_download (void *ptr,
331 static char download_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1]; 353 static char download_buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
332 const char *cbuf = ptr; 354 const char *cbuf = ptr;
333 const struct GNUNET_MessageHeader *msg; 355 const struct GNUNET_MessageHeader *msg;
356 struct HelloOffer *ho;
334 size_t total; 357 size_t total;
335 size_t cpy; 358 size_t cpy;
336 size_t left; 359 size_t left;
@@ -390,7 +413,22 @@ callback_download (void *ptr,
390 ("# valid HELLOs downloaded from hostlist servers"), 413 ("# valid HELLOs downloaded from hostlist servers"),
391 1, GNUNET_NO); 414 1, GNUNET_NO);
392 stat_hellos_obtained++; 415 stat_hellos_obtained++;
393 GNUNET_TRANSPORT_offer_hello (transport, msg, NULL, NULL); 416
417 ho = GNUNET_new (struct HelloOffer);
418 ho->ohh = GNUNET_TRANSPORT_offer_hello (cfg,
419 msg,
420 &done_offer_hello,
421 ho);
422 if (NULL == ho->ohh)
423 {
424 GNUNET_free (ho);
425 }
426 else
427 {
428 GNUNET_CONTAINER_DLL_insert (ho_head,
429 ho_tail,
430 ho);
431 }
394 } 432 }
395 else 433 else
396 { 434 {
@@ -405,7 +443,9 @@ callback_download (void *ptr,
405 stat_hellos_obtained++; 443 stat_hellos_obtained++;
406 return total; 444 return total;
407 } 445 }
408 memmove (download_buffer, &download_buffer[msize], download_pos - msize); 446 memmove (download_buffer,
447 &download_buffer[msize],
448 download_pos - msize);
409 download_pos -= msize; 449 download_pos -= msize;
410 } 450 }
411 return total; 451 return total;
@@ -1532,13 +1572,6 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1532 GNUNET_break (0); 1572 GNUNET_break (0);
1533 return GNUNET_SYSERR; 1573 return GNUNET_SYSERR;
1534 } 1574 }
1535 transport = GNUNET_TRANSPORT_connect (c, NULL, NULL, NULL, NULL, NULL);
1536 if (NULL == transport)
1537 {
1538 GNUNET_break (0);
1539 curl_global_cleanup ();
1540 return GNUNET_SYSERR;
1541 }
1542 cfg = c; 1575 cfg = c;
1543 stats = st; 1576 stats = st;
1544 1577
@@ -1687,8 +1720,18 @@ GNUNET_HOSTLIST_client_start (const struct GNUNET_CONFIGURATION_Handle *c,
1687void 1720void
1688GNUNET_HOSTLIST_client_stop () 1721GNUNET_HOSTLIST_client_stop ()
1689{ 1722{
1723 struct HelloOffer *ho;
1724
1690 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1725 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1691 "Hostlist client shutdown\n"); 1726 "Hostlist client shutdown\n");
1727 while (NULL != (ho = ho_head))
1728 {
1729 GNUNET_CONTAINER_DLL_remove (ho_head,
1730 ho_tail,
1731 ho);
1732 GNUNET_TRANSPORT_offer_hello_cancel (ho->ohh);
1733 GNUNET_free (ho);
1734 }
1692 if (NULL != sget) 1735 if (NULL != sget)
1693 { 1736 {
1694 GNUNET_STATISTICS_get_cancel (sget); 1737 GNUNET_STATISTICS_get_cancel (sget);
@@ -1725,11 +1768,6 @@ GNUNET_HOSTLIST_client_stop ()
1725 ti_check_download = NULL; 1768 ti_check_download = NULL;
1726 curl_global_cleanup (); 1769 curl_global_cleanup ();
1727 } 1770 }
1728 if (NULL != transport)
1729 {
1730 GNUNET_TRANSPORT_disconnect (transport);
1731 transport = NULL;
1732 }
1733 GNUNET_free_non_null (proxy); 1771 GNUNET_free_non_null (proxy);
1734 proxy = NULL; 1772 proxy = NULL;
1735 GNUNET_free_non_null (proxy_username); 1773 GNUNET_free_non_null (proxy_username);
diff --git a/src/hostlist/test_gnunet_daemon_hostlist.c b/src/hostlist/test_gnunet_daemon_hostlist.c
index 5f8ece9b8..6a5850c4d 100644
--- a/src/hostlist/test_gnunet_daemon_hostlist.c
+++ b/src/hostlist/test_gnunet_daemon_hostlist.c
@@ -147,7 +147,7 @@ setup_peer (struct PeerContext *p, const char *cfgname)
147 p->th = 147 p->th =
148 GNUNET_TRANSPORT_connect (p->cfg, NULL, p, NULL, &notify_connect, NULL); 148 GNUNET_TRANSPORT_connect (p->cfg, NULL, p, NULL, &notify_connect, NULL);
149 GNUNET_assert (p->th != NULL); 149 GNUNET_assert (p->th != NULL);
150 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p); 150 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg, &process_hello, p);
151 GNUNET_free (binary); 151 GNUNET_free (binary);
152} 152}
153 153
diff --git a/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c b/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c
index 3dad137a2..30f26717f 100644
--- a/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c
+++ b/src/hostlist/test_gnunet_daemon_hostlist_reconnect.c
@@ -116,7 +116,7 @@ setup_peer (struct PeerContext *p, const char *cfgname)
116 p->th = 116 p->th =
117 GNUNET_TRANSPORT_connect (p->cfg, NULL, p, NULL, &notify_connect, NULL); 117 GNUNET_TRANSPORT_connect (p->cfg, NULL, p, NULL, &notify_connect, NULL);
118 GNUNET_assert (p->th != NULL); 118 GNUNET_assert (p->th != NULL);
119 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, &process_hello, p); 119 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg, &process_hello, p);
120 GNUNET_free (binary); 120 GNUNET_free (binary);
121} 121}
122 122
diff --git a/src/include/gnunet_transport_core_service.h b/src/include/gnunet_transport_core_service.h
index 816d5efaa..6dada4f54 100644
--- a/src/include/gnunet_transport_core_service.h
+++ b/src/include/gnunet_transport_core_service.h
@@ -50,49 +50,41 @@ extern "C"
50 50
51 51
52/** 52/**
53 * Function called by the transport for each received message.
54 *
55 * @param cls closure
56 * @param peer (claimed) identity of the other peer
57 * @param message the message
58 */
59typedef void
60(*GNUNET_TRANSPORT_ReceiveCallback) (void *cls,
61 const struct GNUNET_PeerIdentity *peer,
62 const struct GNUNET_MessageHeader *message);
63
64
65/**
66 * Opaque handle to the service. 53 * Opaque handle to the service.
67 */ 54 */
68struct GNUNET_TRANSPORT_Handle; 55struct GNUNET_TRANSPORT_CoreHandle;
69 56
70 57
71/** 58/**
72 * Function called to notify CORE service that another 59 * Function called to notify transport users that another
73 * @a peer connected to us. 60 * peer connected to us.
74 * 61 *
75 * @param cls closure 62 * @param cls closure
76 * @param peer the peer that connected, never NULL 63 * @param peer the peer that connected
77 * @param mq message queue for sending messages to this peer 64 * @param mq message queue to use to transmit to @a peer
65 * @return closure to use in MQ handlers
78 */ 66 */
79typedef void 67typedef void *
80(*GNUNET_TRANSPORT_NotifyConnect) (void *cls, 68(*GNUNET_TRANSPORT_NotifyConnecT) (void *cls,
81 const struct GNUNET_PeerIdentity *peer, 69 const struct GNUNET_PeerIdentity *peer,
82 struct GNUNET_MQ_Handle *mq); 70 struct GNUNET_MQ_Handle *mq);
83 71
84 72
85/** 73/**
86 * Function called to notify CORE service that another 74 * Function called to notify transport users that another peer
87 * @a peer disconnected from us. The associated message 75 * disconnected from us. The message queue that was given to the
88 * queue must not be used henceforth. 76 * connect notification will be destroyed and must not be used
77 * henceforth.
89 * 78 *
90 * @param cls closure 79 * @param cls closure from #GNUNET_TRANSPORT_connecT
91 * @param peer the peer that disconnected, never NULL 80 * @param peer the peer that disconnected
81 * @param handlers_cls closure of the handlers, was returned from the
82 * connect notification callback
92 */ 83 */
93typedef void 84typedef void
94(*GNUNET_TRANSPORT_NotifyDisconnect) (void *cls, 85(*GNUNET_TRANSPORT_NotifyDisconnecT) (void *cls,
95 const struct GNUNET_PeerIdentity *peer); 86 const struct GNUNET_PeerIdentity *peer,
87 void *handler_cls);
96 88
97 89
98/** 90/**
@@ -108,34 +100,41 @@ typedef void
108 * 100 *
109 * @param cls the closure 101 * @param cls the closure
110 * @param neighbour peer that we have excess bandwidth to 102 * @param neighbour peer that we have excess bandwidth to
103 * @param handlers_cls closure of the handlers, was returned from the
104 * connect notification callback
111 */ 105 */
112typedef void 106typedef void
113(*GNUNET_TRANSPORT_NotifyExcessBandwidth)(void *cls, 107(*GNUNET_TRANSPORT_NotifyExcessBandwidtH)(void *cls,
114 const struct GNUNET_PeerIdentity *neighbour); 108 const struct GNUNET_PeerIdentity *neighbour,
109 void *handlers_cls);
110
115 111
116 112
117/** 113/**
118 * Connect to the transport service. 114 * Connect to the transport service. Note that the connection may
115 * complete (or fail) asynchronously.
119 * 116 *
120 * @param cfg configuration to use 117 * @param cfg configuration to use
121 * @param self our own identity (if API should check that it matches 118 * @param self our own identity (API should check that it matches
122 * the identity found by transport), or NULL (no check) 119 * the identity found by transport), or NULL (no check)
123 * @param cls closure for the callbacks 120 * @param handlers array of message handlers; note that the
124 * @param rec_handlers NULL-terminated array of handlers for incoming 121 * closures provided will be ignored and replaced
125 * messages, or NULL 122 * with the respective return value from @a nc
123 * @param handlers array with handlers to call when we receive messages, or NULL
124 * @param cls closure for the @a nc, @a nd and @a neb callbacks
126 * @param nc function to call on connect events, or NULL 125 * @param nc function to call on connect events, or NULL
127 * @param nd function to call on disconnect events, or NULL 126 * @param nd function to call on disconnect events, or NULL
128 * @param neb function to call if we have excess bandwidth to a peer 127 * @param neb function to call if we have excess bandwidth to a peer, or NULL
129 * @return NULL on error 128 * @return NULL on error
130 */ 129 */
131struct GNUNET_TRANSPORT_Handle * 130struct GNUNET_TRANSPORT_CoreHandle *
132GNUNET_TRANSPORT_core_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 131GNUNET_TRANSPORT_core_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
133 const struct GNUNET_PeerIdentity *self, 132 const struct GNUNET_PeerIdentity *self,
133 const struct GNUNET_MQ_MessageHandler *handlers,
134 void *cls, 134 void *cls,
135 GNUNET_MQ_MessageHandler *rec_handlers, 135 GNUNET_TRANSPORT_NotifyConnecT nc,
136 GNUNET_TRANSPORT_NotifyConnect nc, 136 GNUNET_TRANSPORT_NotifyDisconnecT nd,
137 GNUNET_TRANSPORT_NotifyDisconnect nd, 137 GNUNET_TRANSPORT_NotifyExcessBandwidtH neb);
138 GNUNET_TRANSPORT_NotifyExcessBandwidth neb);
139 138
140 139
141/** 140/**
@@ -144,22 +143,19 @@ GNUNET_TRANSPORT_core_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
144 * @param handle handle returned from connect 143 * @param handle handle returned from connect
145 */ 144 */
146void 145void
147GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle); 146GNUNET_TRANSPORT_core_disconnect (struct GNUNET_TRANSPORT_CoreHandle *handle);
148 147
149 148
150/** 149/**
151 * Checks if a given peer is connected to us. Convenience 150 * Checks if a given peer is connected to us and get the message queue.
152 * API in case a client does not track connect/disconnect
153 * events internally.
154 * 151 *
155 * @param handle connection to transport service 152 * @param handle connection to transport service
156 * @param peer the peer to check 153 * @param peer the peer to check
157 * @return #GNUNET_YES (connected) or #GNUNET_NO (disconnected) 154 * @return NULL if disconnected, otherwise message queue for @a peer
158 */ 155 */
159int 156struct GNUNET_MQ_Handle *
160GNUNET_TRANSPORT_check_peer_connected (struct GNUNET_TRANSPORT_Handle *handle, 157GNUNET_TRANSPORT_core_get_mq (struct GNUNET_TRANSPORT_CoreHandle *handle,
161 const struct GNUNET_PeerIdentity *peer); 158 const struct GNUNET_PeerIdentity *peer);
162
163 159
164 160
165#if 0 /* keep Emacsens' auto-indent happy */ 161#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h
index 96182424e..b40763b92 100644
--- a/src/include/gnunet_transport_service.h
+++ b/src/include/gnunet_transport_service.h
@@ -66,12 +66,6 @@ typedef void
66 66
67 67
68/** 68/**
69 * Opaque handle to the service.
70 */
71struct GNUNET_TRANSPORT_Handle;
72
73
74/**
75 * Function called to notify transport users that another 69 * Function called to notify transport users that another
76 * peer connected to us. 70 * peer connected to us.
77 * 71 *
@@ -82,6 +76,7 @@ typedef void
82(*GNUNET_TRANSPORT_NotifyConnect) (void *cls, 76(*GNUNET_TRANSPORT_NotifyConnect) (void *cls,
83 const struct GNUNET_PeerIdentity *peer); 77 const struct GNUNET_PeerIdentity *peer);
84 78
79
85/** 80/**
86 * Function called to notify transport users that another 81 * Function called to notify transport users that another
87 * peer disconnected from us. 82 * peer disconnected from us.
@@ -288,13 +283,13 @@ struct GNUNET_TRANSPORT_GetHelloHandle;
288 * Obtain updates on changes to the HELLO message for this peer. The callback 283 * Obtain updates on changes to the HELLO message for this peer. The callback
289 * given in this function is never called synchronously. 284 * given in this function is never called synchronously.
290 * 285 *
291 * @param handle connection to transport service 286 * @param cfg configuration
292 * @param rec function to call with the HELLO 287 * @param rec function to call with the HELLO
293 * @param rec_cls closure for @a rec 288 * @param rec_cls closure for @a rec
294 * @return handle to cancel the operation 289 * @return handle to cancel the operation
295 */ 290 */
296struct GNUNET_TRANSPORT_GetHelloHandle * 291struct GNUNET_TRANSPORT_GetHelloHandle *
297GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle, 292GNUNET_TRANSPORT_get_hello (const struct GNUNET_CONFIGURATION_Handle *cfg,
298 GNUNET_TRANSPORT_HelloUpdateCallback rec, 293 GNUNET_TRANSPORT_HelloUpdateCallback rec,
299 void *rec_cls); 294 void *rec_cls);
300 295
@@ -319,7 +314,7 @@ struct GNUNET_TRANSPORT_OfferHelloHandle;
319 * the transport service may just ignore this message if the HELLO is 314 * the transport service may just ignore this message if the HELLO is
320 * malformed or useless due to our local configuration. 315 * malformed or useless due to our local configuration.
321 * 316 *
322 * @param handle connection to transport service 317 * @param cfg configuration
323 * @param hello the hello message 318 * @param hello the hello message
324 * @param cont continuation to call when HELLO has been sent, 319 * @param cont continuation to call when HELLO has been sent,
325 * tc reason #GNUNET_SCHEDULER_REASON_TIMEOUT for fail 320 * tc reason #GNUNET_SCHEDULER_REASON_TIMEOUT for fail
@@ -330,7 +325,7 @@ struct GNUNET_TRANSPORT_OfferHelloHandle;
330 * 325 *
331 */ 326 */
332struct GNUNET_TRANSPORT_OfferHelloHandle * 327struct GNUNET_TRANSPORT_OfferHelloHandle *
333GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle, 328GNUNET_TRANSPORT_offer_hello (const struct GNUNET_CONFIGURATION_Handle *cfg,
334 const struct GNUNET_MessageHeader *hello, 329 const struct GNUNET_MessageHeader *hello,
335 GNUNET_SCHEDULER_TaskCallback cont, 330 GNUNET_SCHEDULER_TaskCallback cont,
336 void *cont_cls); 331 void *cont_cls);
diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c
index b6aa224fd..14f1e4604 100644
--- a/src/peerinfo-tool/gnunet-peerinfo.c
+++ b/src/peerinfo-tool/gnunet-peerinfo.c
@@ -183,11 +183,6 @@ static struct GNUNET_SCHEDULER_Task * tt;
183static struct GNUNET_TRANSPORT_GetHelloHandle *gh; 183static struct GNUNET_TRANSPORT_GetHelloHandle *gh;
184 184
185/** 185/**
186 * Connection to transport service.
187 */
188static struct GNUNET_TRANSPORT_Handle *transport;
189
190/**
191 * Current iterator context (if active, otherwise NULL). 186 * Current iterator context (if active, otherwise NULL).
192 */ 187 */
193static struct GNUNET_PEERINFO_IteratorContext *pic; 188static struct GNUNET_PEERINFO_IteratorContext *pic;
@@ -641,11 +636,6 @@ shutdown_task (void *cls)
641 GNUNET_TRANSPORT_get_hello_cancel (gh); 636 GNUNET_TRANSPORT_get_hello_cancel (gh);
642 gh = NULL; 637 gh = NULL;
643 } 638 }
644 if (NULL != transport)
645 {
646 GNUNET_TRANSPORT_disconnect (transport);
647 transport = NULL;
648 }
649 while (NULL != (pc = pc_head)) 639 while (NULL != (pc = pc_head))
650 { 640 {
651 GNUNET_CONTAINER_DLL_remove (pc_head, 641 GNUNET_CONTAINER_DLL_remove (pc_head,
@@ -702,8 +692,6 @@ hello_callback (void *cls,
702 &my_peer_identity)); 692 &my_peer_identity));
703 GNUNET_TRANSPORT_get_hello_cancel (gh); 693 GNUNET_TRANSPORT_get_hello_cancel (gh);
704 gh = NULL; 694 gh = NULL;
705 GNUNET_TRANSPORT_disconnect (transport);
706 transport = NULL;
707 if (NULL != dump_hello) 695 if (NULL != dump_hello)
708 dump_my_hello (); 696 dump_my_hello ();
709 tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); 697 tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
@@ -740,11 +728,7 @@ testservice_task (void *cls,
740 (GNUNET_YES == get_uri) || 728 (GNUNET_YES == get_uri) ||
741 (NULL != dump_hello) ) 729 (NULL != dump_hello) )
742 { 730 {
743 transport = GNUNET_TRANSPORT_connect (cfg, 731 gh = GNUNET_TRANSPORT_get_hello (cfg,
744 NULL,
745 NULL,
746 NULL, NULL, NULL);
747 gh = GNUNET_TRANSPORT_get_hello (transport,
748 &hello_callback, 732 &hello_callback,
749 NULL); 733 NULL);
750 } 734 }
diff --git a/src/testbed/gnunet-service-testbed_connectionpool.c b/src/testbed/gnunet-service-testbed_connectionpool.c
index 0fa2a6456..47b6fab08 100644
--- a/src/testbed/gnunet-service-testbed_connectionpool.c
+++ b/src/testbed/gnunet-service-testbed_connectionpool.c
@@ -463,7 +463,8 @@ connection_ready (void *cls)
463 entry->handle_core, 463 entry->handle_core,
464 entry->handle_transport, 464 entry->handle_transport,
465 entry->handle_ats_connectivity, 465 entry->handle_ats_connectivity,
466 entry->peer_identity); 466 entry->peer_identity,
467 entry->cfg);
467} 468}
468 469
469 470
diff --git a/src/testbed/gnunet-service-testbed_connectionpool.h b/src/testbed/gnunet-service-testbed_connectionpool.h
index 589421840..54b37f6d5 100644
--- a/src/testbed/gnunet-service-testbed_connectionpool.h
+++ b/src/testbed/gnunet-service-testbed_connectionpool.h
@@ -85,13 +85,15 @@ GST_connection_pool_destroy (void);
85 * @param ac the handle to ATS, can be NULL if it is not requested 85 * @param ac the handle to ATS, can be NULL if it is not requested
86 * @param peer_id the identity of the peer. Will be NULL if ch is NULL. In other 86 * @param peer_id the identity of the peer. Will be NULL if ch is NULL. In other
87 * cases, its value being NULL means that CORE connection has failed. 87 * cases, its value being NULL means that CORE connection has failed.
88 * @param cfg configuration of the peer
88 */ 89 */
89typedef void 90typedef void
90(*GST_connection_pool_connection_ready_cb) (void *cls, 91(*GST_connection_pool_connection_ready_cb) (void *cls,
91 struct GNUNET_CORE_Handle *ch, 92 struct GNUNET_CORE_Handle *ch,
92 struct GNUNET_TRANSPORT_Handle *th, 93 struct GNUNET_TRANSPORT_Handle *th,
93 struct GNUNET_ATS_ConnectivityHandle *ac, 94 struct GNUNET_ATS_ConnectivityHandle *ac,
94 const struct GNUNET_PeerIdentity *peer_id); 95 const struct GNUNET_PeerIdentity *peer_id,
96 const struct GNUNET_CONFIGURATION_Handle *cfg);
95 97
96 98
97/** 99/**
diff --git a/src/testbed/gnunet-service-testbed_oc.c b/src/testbed/gnunet-service-testbed_oc.c
index de462da7a..8902a359c 100644
--- a/src/testbed/gnunet-service-testbed_oc.c
+++ b/src/testbed/gnunet-service-testbed_oc.c
@@ -49,6 +49,11 @@ struct ConnectivitySuggestContext
49 struct GNUNET_TRANSPORT_Handle *th_; 49 struct GNUNET_TRANSPORT_Handle *th_;
50 50
51 /** 51 /**
52 * Configuration of the peer from cache. Do not free!
53 */
54 const struct GNUNET_CONFIGURATION_Handle *cfg;
55
56 /**
52 * The GetCacheHandle for the peer2's transport handle 57 * The GetCacheHandle for the peer2's transport handle
53 * (used to offer the HELLO to the peer). 58 * (used to offer the HELLO to the peer).
54 */ 59 */
@@ -699,13 +704,15 @@ overlay_connect_notify (void *cls,
699 * @param th the handle to TRANSPORT. Can be NULL if it is not requested 704 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
700 * @param ac the handle to ATS. Can be NULL if it is not requested 705 * @param ac the handle to ATS. Can be NULL if it is not requested
701 * @param my_identity the identity of our peer 706 * @param my_identity the identity of our peer
707 * @param cfg configuration of the peer
702 */ 708 */
703static void 709static void
704occ_cache_get_handle_ats_occ_cb (void *cls, 710occ_cache_get_handle_ats_occ_cb (void *cls,
705 struct GNUNET_CORE_Handle *ch, 711 struct GNUNET_CORE_Handle *ch,
706 struct GNUNET_TRANSPORT_Handle *th, 712 struct GNUNET_TRANSPORT_Handle *th,
707 struct GNUNET_ATS_ConnectivityHandle *ac, 713 struct GNUNET_ATS_ConnectivityHandle *ac,
708 const struct GNUNET_PeerIdentity *my_identity) 714 const struct GNUNET_PeerIdentity *my_identity,
715 const struct GNUNET_CONFIGURATION_Handle *cfg)
709{ 716{
710 struct OverlayConnectContext *occ = cls; 717 struct OverlayConnectContext *occ = cls;
711 struct LocalPeer2Context *lp2c; 718 struct LocalPeer2Context *lp2c;
@@ -754,7 +761,8 @@ occ_cache_get_handle_ats_rocc_cb (void *cls,
754 struct GNUNET_CORE_Handle *ch, 761 struct GNUNET_CORE_Handle *ch,
755 struct GNUNET_TRANSPORT_Handle *th, 762 struct GNUNET_TRANSPORT_Handle *th,
756 struct GNUNET_ATS_ConnectivityHandle *ac, 763 struct GNUNET_ATS_ConnectivityHandle *ac,
757 const struct GNUNET_PeerIdentity *my_identity) 764 const struct GNUNET_PeerIdentity *my_identity,
765 const struct GNUNET_CONFIGURATION_Handle *cfg)
758{ 766{
759 struct RemoteOverlayConnectCtx *rocc = cls; 767 struct RemoteOverlayConnectCtx *rocc = cls;
760 768
@@ -896,7 +904,7 @@ send_hello (void *cls)
896 other_peer_str); 904 other_peer_str);
897 GNUNET_free (other_peer_str); 905 GNUNET_free (other_peer_str);
898 lp2c->ohh = 906 lp2c->ohh =
899 GNUNET_TRANSPORT_offer_hello (lp2c->tcc.th_, 907 GNUNET_TRANSPORT_offer_hello (lp2c->tcc.cfg,
900 occ->hello, 908 occ->hello,
901 occ_hello_sent_cb, 909 occ_hello_sent_cb,
902 occ); 910 occ);
@@ -922,13 +930,15 @@ send_hello (void *cls)
922 * @param th the handle to TRANSPORT. Can be NULL if it is not requested 930 * @param th the handle to TRANSPORT. Can be NULL if it is not requested
923 * @param ac the handle to ATS. Can be NULL if it is not requested 931 * @param ac the handle to ATS. Can be NULL if it is not requested
924 * @param ignore_ peer identity which is ignored in this callback 932 * @param ignore_ peer identity which is ignored in this callback
925 */ 933 * @param cfg configuration of the peer
934*/
926static void 935static void
927p2_transport_connect_cache_callback (void *cls, 936p2_transport_connect_cache_callback (void *cls,
928 struct GNUNET_CORE_Handle *ch, 937 struct GNUNET_CORE_Handle *ch,
929 struct GNUNET_TRANSPORT_Handle *th, 938 struct GNUNET_TRANSPORT_Handle *th,
930 struct GNUNET_ATS_ConnectivityHandle *ac, 939 struct GNUNET_ATS_ConnectivityHandle *ac,
931 const struct GNUNET_PeerIdentity *ignore_) 940 const struct GNUNET_PeerIdentity *ignore_,
941 const struct GNUNET_CONFIGURATION_Handle *cfg)
932{ 942{
933 struct OverlayConnectContext *occ = cls; 943 struct OverlayConnectContext *occ = cls;
934 944
@@ -945,6 +955,7 @@ p2_transport_connect_cache_callback (void *cls,
945 return; 955 return;
946 } 956 }
947 occ->p2ctx.local.tcc.th_ = th; 957 occ->p2ctx.local.tcc.th_ = th;
958 occ->p2ctx.local.tcc.cfg = cfg;
948 GNUNET_asprintf (&occ->emsg, 959 GNUNET_asprintf (&occ->emsg,
949 "0x%llx: Timeout while offering HELLO to %s", 960 "0x%llx: Timeout while offering HELLO to %s",
950 occ->op_id, 961 occ->op_id,
@@ -1068,7 +1079,8 @@ p1_transport_connect_cache_callback (void *cls,
1068 struct GNUNET_CORE_Handle *ch, 1079 struct GNUNET_CORE_Handle *ch,
1069 struct GNUNET_TRANSPORT_Handle *th, 1080 struct GNUNET_TRANSPORT_Handle *th,
1070 struct GNUNET_ATS_ConnectivityHandle *ac, 1081 struct GNUNET_ATS_ConnectivityHandle *ac,
1071 const struct GNUNET_PeerIdentity *ignore_) 1082 const struct GNUNET_PeerIdentity *ignore_,
1083 const struct GNUNET_CONFIGURATION_Handle *cfg)
1072{ 1084{
1073 struct OverlayConnectContext *occ = cls; 1085 struct OverlayConnectContext *occ = cls;
1074 1086
@@ -1092,7 +1104,7 @@ p1_transport_connect_cache_callback (void *cls,
1092 "0x%llx: Timeout while acquiring HELLO of peer %s", 1104 "0x%llx: Timeout while acquiring HELLO of peer %s",
1093 occ->op_id, 1105 occ->op_id,
1094 GNUNET_i2s (&occ->peer_identity)); 1106 GNUNET_i2s (&occ->peer_identity));
1095 occ->ghh = GNUNET_TRANSPORT_get_hello (occ->p1th_, 1107 occ->ghh = GNUNET_TRANSPORT_get_hello (cfg,
1096 &hello_update_cb, 1108 &hello_update_cb,
1097 occ); 1109 occ);
1098} 1110}
@@ -1112,7 +1124,8 @@ occ_cache_get_handle_core_cb (void *cls,
1112 struct GNUNET_CORE_Handle *ch, 1124 struct GNUNET_CORE_Handle *ch,
1113 struct GNUNET_TRANSPORT_Handle *th, 1125 struct GNUNET_TRANSPORT_Handle *th,
1114 struct GNUNET_ATS_ConnectivityHandle *ac, 1126 struct GNUNET_ATS_ConnectivityHandle *ac,
1115 const struct GNUNET_PeerIdentity *my_identity) 1127 const struct GNUNET_PeerIdentity *my_identity,
1128 const struct GNUNET_CONFIGURATION_Handle *cfg)
1116{ 1129{
1117 struct OverlayConnectContext *occ = cls; 1130 struct OverlayConnectContext *occ = cls;
1118 const struct GNUNET_MessageHeader *hello; 1131 const struct GNUNET_MessageHeader *hello;
@@ -1743,7 +1756,7 @@ attempt_connect_task (void *cls)
1743 GNUNET_i2s (&rocc->a_id), 1756 GNUNET_i2s (&rocc->a_id),
1744 rocc->peer->id); 1757 rocc->peer->id);
1745 rocc->ohh = 1758 rocc->ohh =
1746 GNUNET_TRANSPORT_offer_hello (rocc->tcc.th_, 1759 GNUNET_TRANSPORT_offer_hello (rocc->tcc.cfg,
1747 rocc->hello, 1760 rocc->hello,
1748 &rocc_hello_sent_cb, 1761 &rocc_hello_sent_cb,
1749 rocc); 1762 rocc);
@@ -1772,7 +1785,8 @@ rocc_cache_get_handle_transport_cb (void *cls,
1772 struct GNUNET_CORE_Handle *ch, 1785 struct GNUNET_CORE_Handle *ch,
1773 struct GNUNET_TRANSPORT_Handle *th, 1786 struct GNUNET_TRANSPORT_Handle *th,
1774 struct GNUNET_ATS_ConnectivityHandle *ac, 1787 struct GNUNET_ATS_ConnectivityHandle *ac,
1775 const struct GNUNET_PeerIdentity *ignore_) 1788 const struct GNUNET_PeerIdentity *ignore_,
1789 const struct GNUNET_CONFIGURATION_Handle *cfg)
1776{ 1790{
1777 struct RemoteOverlayConnectCtx *rocc = cls; 1791 struct RemoteOverlayConnectCtx *rocc = cls;
1778 1792
@@ -1783,6 +1797,7 @@ rocc_cache_get_handle_transport_cb (void *cls,
1783 return; 1797 return;
1784 } 1798 }
1785 rocc->tcc.th_ = th; 1799 rocc->tcc.th_ = th;
1800 rocc->tcc.cfg = cfg;
1786 if (GNUNET_YES == 1801 if (GNUNET_YES ==
1787 GNUNET_TRANSPORT_check_peer_connected (rocc->tcc.th_, 1802 GNUNET_TRANSPORT_check_peer_connected (rocc->tcc.th_,
1788 &rocc->a_id)) 1803 &rocc->a_id))
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index eddac8c8a..9baaf513d 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -142,11 +142,6 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
142static struct GNUNET_CORE_Handle *handle; 142static struct GNUNET_CORE_Handle *handle;
143 143
144/** 144/**
145 * Handle to the TRANSPORT service.
146 */
147static struct GNUNET_TRANSPORT_Handle *transport;
148
149/**
150 * Handle to the ATS service. 145 * Handle to the ATS service.
151 */ 146 */
152static struct GNUNET_ATS_ConnectivityHandle *ats; 147static struct GNUNET_ATS_ConnectivityHandle *ats;
@@ -180,6 +175,11 @@ static struct GNUNET_TRANSPORT_Blacklist *blacklist;
180static struct GNUNET_SCHEDULER_Task *add_task; 175static struct GNUNET_SCHEDULER_Task *add_task;
181 176
182/** 177/**
178 * Active HELLO offering to transport service.
179 */
180static struct GNUNET_TRANSPORT_OfferHelloHandle *oh;
181
182/**
183 * Flag to disallow non-friend connections (pure F2F mode). 183 * Flag to disallow non-friend connections (pure F2F mode).
184 */ 184 */
185static int friends_only; 185static int friends_only;
@@ -1008,6 +1008,16 @@ read_friends_file (const struct GNUNET_CONFIGURATION_Handle *cfg)
1008 1008
1009 1009
1010/** 1010/**
1011 * Hello offer complete. Clean up.
1012 */
1013static void
1014done_offer_hello (void *cls)
1015{
1016 oh = NULL;
1017}
1018
1019
1020/**
1011 * This function is called whenever an encrypted HELLO message is 1021 * This function is called whenever an encrypted HELLO message is
1012 * received. 1022 * received.
1013 * 1023 *
@@ -1055,11 +1065,12 @@ handle_encrypted_hello (void *cls,
1055 (friend_count < minimum_friend_count)) 1065 (friend_count < minimum_friend_count))
1056 return GNUNET_OK; 1066 return GNUNET_OK;
1057 } 1067 }
1058 if (NULL != transport) 1068 if (NULL != oh)
1059 GNUNET_TRANSPORT_offer_hello (transport, 1069 GNUNET_TRANSPORT_offer_hello_cancel (oh);
1060 message, 1070 oh = GNUNET_TRANSPORT_offer_hello (cfg,
1061 NULL, 1071 message,
1062 NULL); 1072 &done_offer_hello,
1073 NULL);
1063 return GNUNET_OK; 1074 return GNUNET_OK;
1064} 1075}
1065 1076
@@ -1136,11 +1147,6 @@ cleaning_task (void *cls)
1136 GNUNET_PEERINFO_notify_cancel (peerinfo_notify); 1147 GNUNET_PEERINFO_notify_cancel (peerinfo_notify);
1137 peerinfo_notify = NULL; 1148 peerinfo_notify = NULL;
1138 } 1149 }
1139 if (NULL != transport)
1140 {
1141 GNUNET_TRANSPORT_disconnect (transport);
1142 transport = NULL;
1143 }
1144 if (NULL != handle) 1150 if (NULL != handle)
1145 { 1151 {
1146 GNUNET_CORE_disconnect (handle); 1152 GNUNET_CORE_disconnect (handle);
@@ -1152,6 +1158,11 @@ cleaning_task (void *cls)
1152 GNUNET_SCHEDULER_cancel (add_task); 1158 GNUNET_SCHEDULER_cancel (add_task);
1153 add_task = NULL; 1159 add_task = NULL;
1154 } 1160 }
1161 if (NULL != oh)
1162 {
1163 GNUNET_TRANSPORT_offer_hello_cancel (oh);
1164 oh = NULL;
1165 }
1155 GNUNET_CONTAINER_multipeermap_iterate (peers, 1166 GNUNET_CONTAINER_multipeermap_iterate (peers,
1156 &free_peer, 1167 &free_peer,
1157 NULL); 1168 NULL);
@@ -1223,12 +1234,6 @@ run (void *cls,
1223 &blacklist_check, 1234 &blacklist_check,
1224 NULL); 1235 NULL);
1225 ats = GNUNET_ATS_connectivity_init (cfg); 1236 ats = GNUNET_ATS_connectivity_init (cfg);
1226 transport = GNUNET_TRANSPORT_connect (cfg,
1227 NULL,
1228 NULL,
1229 NULL,
1230 NULL,
1231 NULL);
1232 handle = 1237 handle =
1233 GNUNET_CORE_connect (cfg, NULL, 1238 GNUNET_CORE_connect (cfg, NULL,
1234 &core_init, 1239 &core_init,
@@ -1239,14 +1244,6 @@ run (void *cls,
1239 handlers); 1244 handlers);
1240 GNUNET_SCHEDULER_add_shutdown (&cleaning_task, 1245 GNUNET_SCHEDULER_add_shutdown (&cleaning_task,
1241 NULL); 1246 NULL);
1242 if (NULL == transport)
1243 {
1244 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1245 _("Failed to connect to `%s' service.\n"),
1246 "transport");
1247 GNUNET_SCHEDULER_shutdown ();
1248 return;
1249 }
1250 if (NULL == handle) 1247 if (NULL == handle)
1251 { 1248 {
1252 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1249 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 3a1170c10..48793bd87 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -163,10 +163,12 @@ libgnunettransporttesting_la_LDFLAGS = \
163 163
164libgnunettransport_la_SOURCES = \ 164libgnunettransport_la_SOURCES = \
165 transport_api.c transport.h \ 165 transport_api.c transport.h \
166 transport_api_blacklist.c \
167 transport_api_address_to_string.c \ 166 transport_api_address_to_string.c \
167 transport_api_blacklist.c \
168 transport_api_get_hello.c \
168 transport_api_monitor_peers.c \ 169 transport_api_monitor_peers.c \
169 transport_api_monitor_plugins.c 170 transport_api_monitor_plugins.c \
171 transport_api_offer_hello.c
170 172
171libgnunettransport_la_LIBADD = \ 173libgnunettransport_la_LIBADD = \
172 $(top_builddir)/src/hello/libgnunethello.la \ 174 $(top_builddir)/src/hello/libgnunethello.la \
diff --git a/src/transport/transport-testing.c b/src/transport/transport-testing.c
index 4a514ea72..4a3bf3c3e 100644
--- a/src/transport/transport-testing.c
+++ b/src/transport/transport-testing.c
@@ -246,7 +246,7 @@ offer_hello (void *cls)
246 if (NULL != cc->oh) 246 if (NULL != cc->oh)
247 GNUNET_TRANSPORT_offer_hello_cancel (cc->oh); 247 GNUNET_TRANSPORT_offer_hello_cancel (cc->oh);
248 cc->oh = 248 cc->oh =
249 GNUNET_TRANSPORT_offer_hello (cc->p1->th, 249 GNUNET_TRANSPORT_offer_hello (cc->p1->cfg,
250 (const struct GNUNET_MessageHeader *) cc->p2->hello, 250 (const struct GNUNET_MessageHeader *) cc->p2->hello,
251 &hello_offered, 251 &hello_offered,
252 cc); 252 cc);
@@ -380,7 +380,7 @@ GNUNET_TRANSPORT_TESTING_start_peer (struct GNUNET_TRANSPORT_TESTING_handle *tth
380 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p); 380 GNUNET_TRANSPORT_TESTING_stop_peer (tth, p);
381 return NULL; 381 return NULL;
382 } 382 }
383 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, 383 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg,
384 &get_hello, 384 &get_hello,
385 p); 385 p);
386 GNUNET_assert (p->ghh != NULL); 386 GNUNET_assert (p->ghh != NULL);
@@ -465,7 +465,7 @@ GNUNET_TRANSPORT_TESTING_restart_peer (struct PeerContext *p,
465 &notify_disconnect); 465 &notify_disconnect);
466 GNUNET_assert (NULL != p->th); 466 GNUNET_assert (NULL != p->th);
467 p->ats = GNUNET_ATS_connectivity_init (p->cfg); 467 p->ats = GNUNET_ATS_connectivity_init (p->cfg);
468 p->ghh = GNUNET_TRANSPORT_get_hello (p->th, 468 p->ghh = GNUNET_TRANSPORT_get_hello (p->cfg,
469 &get_hello, 469 &get_hello,
470 p); 470 p);
471 GNUNET_assert (NULL != p->ghh); 471 GNUNET_assert (NULL != p->ghh);
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c
index 59f249686..e7db5493e 100644
--- a/src/transport/transport_api.c
+++ b/src/transport/transport_api.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V. 3 Copyright (C) 2009-2013, 2016 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -163,86 +163,6 @@ struct Neighbour
163}; 163};
164 164
165 165
166/**
167 * Linked list of functions to call whenever our HELLO is updated.
168 */
169struct GNUNET_TRANSPORT_GetHelloHandle
170{
171
172 /**
173 * This is a doubly linked list.
174 */
175 struct GNUNET_TRANSPORT_GetHelloHandle *next;
176
177 /**
178 * This is a doubly linked list.
179 */
180 struct GNUNET_TRANSPORT_GetHelloHandle *prev;
181
182 /**
183 * Transport handle.
184 */
185 struct GNUNET_TRANSPORT_Handle *handle;
186
187 /**
188 * Callback to call once we got our HELLO.
189 */
190 GNUNET_TRANSPORT_HelloUpdateCallback rec;
191
192 /**
193 * Task for calling the HelloUpdateCallback when we already have a HELLO
194 */
195 struct GNUNET_SCHEDULER_Task *notify_task;
196
197 /**
198 * Closure for @e rec.
199 */
200 void *rec_cls;
201
202};
203
204
205/**
206 * Entry in linked list for all offer-HELLO requests.
207 */
208struct GNUNET_TRANSPORT_OfferHelloHandle
209{
210 /**
211 * For the DLL.
212 */
213 struct GNUNET_TRANSPORT_OfferHelloHandle *prev;
214
215 /**
216 * For the DLL.
217 */
218 struct GNUNET_TRANSPORT_OfferHelloHandle *next;
219
220 /**
221 * Transport service handle we use for transmission.
222 */
223 struct GNUNET_TRANSPORT_Handle *th;
224
225 /**
226 * Transmission handle for this request.
227 */
228 struct GNUNET_TRANSPORT_TransmitHandle *tth;
229
230 /**
231 * Function to call once we are done.
232 */
233 GNUNET_SCHEDULER_TaskCallback cont;
234
235 /**
236 * Closure for @e cont
237 */
238 void *cls;
239
240 /**
241 * The HELLO message to be transmitted.
242 */
243 struct GNUNET_MessageHeader *msg;
244};
245
246 166
247/** 167/**
248 * Handle for the transport service (includes all of the 168 * Handle for the transport service (includes all of the
@@ -277,16 +197,6 @@ struct GNUNET_TRANSPORT_Handle
277 GNUNET_TRANSPORT_NotifyExcessBandwidth neb_cb; 197 GNUNET_TRANSPORT_NotifyExcessBandwidth neb_cb;
278 198
279 /** 199 /**
280 * Head of DLL of control messages.
281 */
282 struct GNUNET_TRANSPORT_TransmitHandle *control_head;
283
284 /**
285 * Tail of DLL of control messages.
286 */
287 struct GNUNET_TRANSPORT_TransmitHandle *control_tail;
288
289 /**
290 * The current HELLO message for this peer. Updated 200 * The current HELLO message for this peer. Updated
291 * whenever transports change their addresses. 201 * whenever transports change their addresses.
292 */ 202 */
@@ -295,32 +205,7 @@ struct GNUNET_TRANSPORT_Handle
295 /** 205 /**
296 * My client connection to the transport service. 206 * My client connection to the transport service.
297 */ 207 */
298 struct GNUNET_CLIENT_Connection *client; 208 struct GNUNET_MQ_Handle *mq;
299
300 /**
301 * Handle to our registration with the client for notification.
302 */
303 struct GNUNET_CLIENT_TransmitHandle *cth;
304
305 /**
306 * Linked list of pending requests for our HELLO.
307 */
308 struct GNUNET_TRANSPORT_GetHelloHandle *hwl_head;
309
310 /**
311 * Linked list of pending requests for our HELLO.
312 */
313 struct GNUNET_TRANSPORT_GetHelloHandle *hwl_tail;
314
315 /**
316 * Linked list of pending offer HELLO requests head
317 */
318 struct GNUNET_TRANSPORT_OfferHelloHandle *oh_head;
319
320 /**
321 * Linked list of pending offer HELLO requests tail
322 */
323 struct GNUNET_TRANSPORT_OfferHelloHandle *oh_tail;
324 209
325 /** 210 /**
326 * My configuration. 211 * My configuration.
@@ -458,7 +343,8 @@ outbound_bw_tracker_update (void *cls)
458 GNUNET_STRINGS_relative_time_to_string (delay, 343 GNUNET_STRINGS_relative_time_to_string (delay,
459 GNUNET_NO)); 344 GNUNET_NO));
460 GNUNET_CONTAINER_heap_update_cost (n->h->ready_heap, 345 GNUNET_CONTAINER_heap_update_cost (n->h->ready_heap,
461 n->hn, delay.rel_value_us); 346 n->hn,
347 delay.rel_value_us);
462 schedule_transmission (n->h); 348 schedule_transmission (n->h);
463} 349}
464 350
@@ -558,268 +444,296 @@ neighbour_delete (void *cls,
558 444
559 445
560/** 446/**
561 * Function we use for handling incoming messages. 447 * Generic error handler, called with the appropriate
448 * error code and the same closure specified at the creation of
449 * the message queue.
450 * Not every message queue implementation supports an error handler.
451 *
452 * @param cls closure with the `struct GNUNET_TRANSPORT_Handle *`
453 * @param error error code
454 */
455static void
456mq_error_handler (void *cls,
457 enum GNUNET_MQ_Error error)
458{
459 struct GNUNET_TRANSPORT_Handle *h = cls;
460
461 LOG (GNUNET_ERROR_TYPE_DEBUG,
462 "Error receiving from transport service, disconnecting temporarily.\n");
463 h->reconnecting = GNUNET_YES;
464 disconnect_and_schedule_reconnect (h);
465}
466
467
468/**
469 * Function we use for checking incoming HELLO messages.
562 * 470 *
563 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *` 471 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
564 * @param msg message received, NULL on timeout or fatal error 472 * @param msg message received
473 * @return #GNUNET_OK if message is well-formed
474 */
475static int
476check_hello (void *cls,
477 const struct GNUNET_MessageHeader *msg)
478{
479 struct GNUNET_PeerIdentity me;
480
481 if (GNUNET_OK !=
482 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) msg,
483 &me))
484 {
485 GNUNET_break (0);
486 return GNUNET_SYSERR;
487 }
488 LOG (GNUNET_ERROR_TYPE_DEBUG,
489 "Receiving (my own) HELLO message (%u bytes), I am `%s'.\n",
490 (unsigned int) ntohs (msg->size),
491 GNUNET_i2s (&me));
492 return GNUNET_OK;
493}
494
495
496/**
497 * Function we use for handling incoming HELLO messages.
498 *
499 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
500 * @param msg message received
565 */ 501 */
566static void 502static void
567demultiplexer (void *cls, 503handle_hello (void *cls,
568 const struct GNUNET_MessageHeader *msg) 504 const struct GNUNET_MessageHeader *msg)
505{
506 struct GNUNET_TRANSPORT_Handle *h = cls;
507
508 GNUNET_free_non_null (h->my_hello);
509 h->my_hello = GNUNET_copy_message (msg);
510}
511
512
513/**
514 * Function we use for handling incoming connect messages.
515 *
516 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
517 * @param cim message received
518 */
519static void
520handle_connect (void *cls,
521 const struct ConnectInfoMessage *cim)
522{
523 struct GNUNET_TRANSPORT_Handle *h = cls;
524 struct Neighbour *n;
525
526 LOG (GNUNET_ERROR_TYPE_DEBUG,
527 "Receiving CONNECT message for `%s'.\n",
528 GNUNET_i2s (&cim->id));
529 n = neighbour_find (h, &cim->id);
530 if (NULL != n)
531 {
532 GNUNET_break (0);
533 h->reconnecting = GNUNET_YES;
534 disconnect_and_schedule_reconnect (h);
535 return;
536 }
537 n = neighbour_add (h,
538 &cim->id);
539 LOG (GNUNET_ERROR_TYPE_DEBUG,
540 "Receiving CONNECT message for `%s' with quota %u\n",
541 GNUNET_i2s (&cim->id),
542 ntohl (cim->quota_out.value__));
543 GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker,
544 cim->quota_out);
545 if (NULL != h->nc_cb)
546 h->nc_cb (h->cls,
547 &n->id);
548}
549
550
551/**
552 * Function we use for handling incoming disconnect messages.
553 *
554 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
555 * @param dim message received
556 */
557static void
558handle_disconnect (void *cls,
559 const struct DisconnectInfoMessage *dim)
560{
561 struct GNUNET_TRANSPORT_Handle *h = cls;
562 struct Neighbour *n;
563
564 GNUNET_break (ntohl (dim->reserved) == 0);
565 LOG (GNUNET_ERROR_TYPE_DEBUG,
566 "Receiving DISCONNECT message for `%s'.\n",
567 GNUNET_i2s (&dim->peer));
568 n = neighbour_find (h, &dim->peer);
569 if (NULL == n)
570 {
571 GNUNET_break (0);
572 h->reconnecting = GNUNET_YES;
573 disconnect_and_schedule_reconnect (h);
574 return;
575 }
576 neighbour_delete (h,
577 &dim->peer,
578 n);
579}
580
581
582/**
583 * Function we use for handling incoming send-ok messages.
584 *
585 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
586 * @param okm message received
587 */
588static void
589handle_send_ok (void *cls,
590 const struct SendOkMessage *okm)
569{ 591{
570 struct GNUNET_TRANSPORT_Handle *h = cls; 592 struct GNUNET_TRANSPORT_Handle *h = cls;
571 const struct DisconnectInfoMessage *dim;
572 const struct ConnectInfoMessage *cim;
573 const struct InboundMessage *im;
574 const struct GNUNET_MessageHeader *imm;
575 const struct SendOkMessage *okm;
576 const struct QuotaSetMessage *qm;
577 struct GNUNET_TRANSPORT_GetHelloHandle *hwl;
578 struct GNUNET_TRANSPORT_GetHelloHandle *next_hwl;
579 struct Neighbour *n; 593 struct Neighbour *n;
580 struct GNUNET_PeerIdentity me;
581 uint16_t size;
582 uint32_t bytes_msg; 594 uint32_t bytes_msg;
583 uint32_t bytes_physical; 595 uint32_t bytes_physical;
584 596
585 GNUNET_assert (NULL != h->client); 597 bytes_msg = ntohl (okm->bytes_msg);
586 if (GNUNET_YES == h->reconnecting) 598 bytes_physical = ntohl (okm->bytes_physical);
599 LOG (GNUNET_ERROR_TYPE_DEBUG,
600 "Receiving SEND_OK message, transmission to %s %s.\n",
601 GNUNET_i2s (&okm->peer),
602 ntohl (okm->success) == GNUNET_OK ? "succeeded" : "failed");
603
604 n = neighbour_find (h,
605 &okm->peer);
606 if (NULL == n)
587 { 607 {
608 /* We should never get a 'SEND_OK' for a peer that we are not
609 connected to */
610 GNUNET_break (0);
611 h->reconnecting = GNUNET_YES;
612 disconnect_and_schedule_reconnect (h);
588 return; 613 return;
589 } 614 }
590 if (NULL == msg) 615 if (bytes_physical > bytes_msg)
591 { 616 {
592 LOG (GNUNET_ERROR_TYPE_DEBUG, 617 LOG (GNUNET_ERROR_TYPE_DEBUG,
593 "Error receiving from transport service, disconnecting temporarily.\n"); 618 "Overhead for %u byte message was %u\n",
619 bytes_msg,
620 bytes_physical - bytes_msg);
621 n->traffic_overhead += bytes_physical - bytes_msg;
622 }
623 GNUNET_break (GNUNET_NO == n->is_ready);
624 n->is_ready = GNUNET_YES;
625 if (NULL != n->unready_warn_task)
626 {
627 GNUNET_SCHEDULER_cancel (n->unready_warn_task);
628 n->unready_warn_task = NULL;
629 }
630 if ((NULL != n->th) && (NULL == n->hn))
631 {
632 GNUNET_assert (NULL != n->th->timeout_task);
633 GNUNET_SCHEDULER_cancel (n->th->timeout_task);
634 n->th->timeout_task = NULL;
635 /* we've been waiting for this (congestion, not quota,
636 * caused delayed transmission) */
637 n->hn = GNUNET_CONTAINER_heap_insert (h->ready_heap,
638 n,
639 0);
640 }
641 schedule_transmission (h);
642}
643
644
645/**
646 * Function we use for checking incoming "inbound" messages.
647 *
648 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
649 * @param im message received
650 */
651static int
652check_recv (void *cls,
653 const struct InboundMessage *im)
654{
655 const struct GNUNET_MessageHeader *imm;
656 uint16_t size;
657
658 size = ntohs (im->header.size);
659 if (size <
660 sizeof (struct InboundMessage) + sizeof (struct GNUNET_MessageHeader))
661 {
662 GNUNET_break (0);
663 return GNUNET_SYSERR;
664 }
665 imm = (const struct GNUNET_MessageHeader *) &im[1];
666 if (ntohs (imm->size) + sizeof (struct InboundMessage) != size)
667 {
668 GNUNET_break (0);
669 return GNUNET_SYSERR;
670 }
671 return GNUNET_OK;
672}
673
674
675/**
676 * Function we use for handling incoming messages.
677 *
678 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
679 * @param im message received
680 */
681static void
682handle_recv (void *cls,
683 const struct InboundMessage *im)
684{
685 struct GNUNET_TRANSPORT_Handle *h = cls;
686 const struct GNUNET_MessageHeader *imm
687 = (const struct GNUNET_MessageHeader *) &im[1];
688 struct Neighbour *n;
689
690 LOG (GNUNET_ERROR_TYPE_DEBUG,
691 "Received message of type %u with %u bytes from `%s'.\n",
692 (unsigned int) ntohs (imm->type),
693 (unsigned int) ntohs (imm->size),
694 GNUNET_i2s (&im->peer));
695 n = neighbour_find (h, &im->peer);
696 if (NULL == n)
697 {
698 GNUNET_break (0);
594 h->reconnecting = GNUNET_YES; 699 h->reconnecting = GNUNET_YES;
595 disconnect_and_schedule_reconnect (h); 700 disconnect_and_schedule_reconnect (h);
596 return; 701 return;
597 } 702 }
598 GNUNET_CLIENT_receive (h->client, 703 if (NULL != h->rec)
599 &demultiplexer, 704 h->rec (h->cls,
600 h, 705 &im->peer,
601 GNUNET_TIME_UNIT_FOREVER_REL); 706 imm);
602 size = ntohs (msg->size); 707}
603 switch (ntohs (msg->type))
604 {
605 case GNUNET_MESSAGE_TYPE_HELLO:
606 if (GNUNET_OK !=
607 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) msg,
608 &me))
609 {
610 GNUNET_break (0);
611 break;
612 }
613 LOG (GNUNET_ERROR_TYPE_DEBUG,
614 "Receiving (my own) HELLO message (%u bytes), I am `%s'.\n",
615 (unsigned int) size,
616 GNUNET_i2s (&me));
617 GNUNET_free_non_null (h->my_hello);
618 h->my_hello = NULL;
619 if (size < sizeof (struct GNUNET_MessageHeader))
620 {
621 GNUNET_break (0);
622 break;
623 }
624 h->my_hello = GNUNET_copy_message (msg);
625 hwl = h->hwl_head;
626 while (NULL != hwl)
627 {
628 next_hwl = hwl->next;
629 hwl->rec (hwl->rec_cls,
630 h->my_hello);
631 hwl = next_hwl;
632 }
633 break;
634 case GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT:
635 if (size < sizeof (struct ConnectInfoMessage))
636 {
637 GNUNET_break (0);
638 h->reconnecting = GNUNET_YES;
639 disconnect_and_schedule_reconnect (h);
640 break;
641 }
642 cim = (const struct ConnectInfoMessage *) msg;
643 if (size !=
644 sizeof (struct ConnectInfoMessage))
645 {
646 GNUNET_break (0);
647 h->reconnecting = GNUNET_YES;
648 disconnect_and_schedule_reconnect (h);
649 break;
650 }
651 LOG (GNUNET_ERROR_TYPE_DEBUG,
652 "Receiving CONNECT message for `%s'.\n",
653 GNUNET_i2s (&cim->id));
654 n = neighbour_find (h, &cim->id);
655 if (NULL != n)
656 {
657 GNUNET_break (0);
658 h->reconnecting = GNUNET_YES;
659 disconnect_and_schedule_reconnect (h);
660 break;
661 }
662 n = neighbour_add (h,
663 &cim->id);
664 LOG (GNUNET_ERROR_TYPE_DEBUG,
665 "Receiving CONNECT message for `%s' with quota %u\n",
666 GNUNET_i2s (&cim->id),
667 ntohl (cim->quota_out.value__));
668 GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker,
669 cim->quota_out);
670 if (NULL != h->nc_cb)
671 h->nc_cb (h->cls,
672 &n->id);
673 break;
674 case GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT:
675 if (size != sizeof (struct DisconnectInfoMessage))
676 {
677 GNUNET_break (0);
678 h->reconnecting = GNUNET_YES;
679 disconnect_and_schedule_reconnect (h);
680 break;
681 }
682 dim = (const struct DisconnectInfoMessage *) msg;
683 GNUNET_break (ntohl (dim->reserved) == 0);
684 LOG (GNUNET_ERROR_TYPE_DEBUG,
685 "Receiving DISCONNECT message for `%s'.\n",
686 GNUNET_i2s (&dim->peer));
687 n = neighbour_find (h, &dim->peer);
688 if (NULL == n)
689 {
690 GNUNET_break (0);
691 h->reconnecting = GNUNET_YES;
692 disconnect_and_schedule_reconnect (h);
693 break;
694 }
695 neighbour_delete (h,
696 &dim->peer,
697 n);
698 break;
699 case GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK:
700 if (size != sizeof (struct SendOkMessage))
701 {
702 GNUNET_break (0);
703 h->reconnecting = GNUNET_YES;
704 disconnect_and_schedule_reconnect (h);
705 break;
706 }
707 okm = (const struct SendOkMessage *) msg;
708 bytes_msg = ntohl (okm->bytes_msg);
709 bytes_physical = ntohl (okm->bytes_physical);
710 LOG (GNUNET_ERROR_TYPE_DEBUG,
711 "Receiving SEND_OK message, transmission to %s %s.\n",
712 GNUNET_i2s (&okm->peer),
713 ntohl (okm->success) == GNUNET_OK ? "succeeded" : "failed");
714 708
715 n = neighbour_find (h, 709
716 &okm->peer); 710/**
717 if (NULL == n) 711 * Function we use for handling incoming set quota messages.
718 { 712 *
719 /* We should never get a 'SEND_OK' for a peer that we are not 713 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
720 connected to */ 714 * @param msg message received
721 GNUNET_break (0); 715 */
722 h->reconnecting = GNUNET_YES; 716static void
723 disconnect_and_schedule_reconnect (h); 717handle_set_quota (void *cls,
724 break; 718 const struct QuotaSetMessage *qm)
725 } 719{
726 if (bytes_physical > bytes_msg) 720 struct GNUNET_TRANSPORT_Handle *h = cls;
727 { 721 struct Neighbour *n;
728 LOG (GNUNET_ERROR_TYPE_DEBUG, 722
729 "Overhead for %u byte message was %u\n", 723 n = neighbour_find (h, &qm->peer);
730 bytes_msg, 724 if (NULL == n)
731 bytes_physical - bytes_msg); 725 {
732 n->traffic_overhead += bytes_physical - bytes_msg;
733 }
734 GNUNET_break (GNUNET_NO == n->is_ready);
735 n->is_ready = GNUNET_YES;
736 if (NULL != n->unready_warn_task)
737 {
738 GNUNET_SCHEDULER_cancel (n->unready_warn_task);
739 n->unready_warn_task = NULL;
740 }
741 if ((NULL != n->th) && (NULL == n->hn))
742 {
743 GNUNET_assert (NULL != n->th->timeout_task);
744 GNUNET_SCHEDULER_cancel (n->th->timeout_task);
745 n->th->timeout_task = NULL;
746 /* we've been waiting for this (congestion, not quota,
747 * caused delayed transmission) */
748 n->hn = GNUNET_CONTAINER_heap_insert (h->ready_heap,
749 n,
750 0);
751 }
752 schedule_transmission (h);
753 break;
754 case GNUNET_MESSAGE_TYPE_TRANSPORT_RECV:
755 if (size <
756 sizeof (struct InboundMessage) + sizeof (struct GNUNET_MessageHeader))
757 {
758 GNUNET_break (0);
759 h->reconnecting = GNUNET_YES;
760 disconnect_and_schedule_reconnect (h);
761 break;
762 }
763 im = (const struct InboundMessage *) msg;
764 imm = (const struct GNUNET_MessageHeader *) &im[1];
765 if (ntohs (imm->size) + sizeof (struct InboundMessage) != size)
766 {
767 GNUNET_break (0);
768 h->reconnecting = GNUNET_YES;
769 disconnect_and_schedule_reconnect (h);
770 break;
771 }
772 LOG (GNUNET_ERROR_TYPE_DEBUG,
773 "Received message of type %u with %u bytes from `%s'.\n",
774 (unsigned int) ntohs (imm->type),
775 (unsigned int) ntohs (imm->size),
776 GNUNET_i2s (&im->peer));
777 n = neighbour_find (h, &im->peer);
778 if (NULL == n)
779 {
780 GNUNET_break (0);
781 h->reconnecting = GNUNET_YES;
782 disconnect_and_schedule_reconnect (h);
783 break;
784 }
785 if (NULL != h->rec)
786 h->rec (h->cls,
787 &im->peer,
788 imm);
789 break;
790 case GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA:
791 if (size != sizeof (struct QuotaSetMessage))
792 {
793 GNUNET_break (0);
794 h->reconnecting = GNUNET_YES;
795 disconnect_and_schedule_reconnect (h);
796 break;
797 }
798 qm = (const struct QuotaSetMessage *) msg;
799 n = neighbour_find (h, &qm->peer);
800 if (NULL == n)
801 {
802 GNUNET_break (0);
803 h->reconnecting = GNUNET_YES;
804 disconnect_and_schedule_reconnect (h);
805 break;
806 }
807 LOG (GNUNET_ERROR_TYPE_DEBUG,
808 "Receiving SET_QUOTA message for `%s' with quota %u\n",
809 GNUNET_i2s (&qm->peer),
810 ntohl (qm->quota.value__));
811 GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker,
812 qm->quota);
813 break;
814 default:
815 LOG (GNUNET_ERROR_TYPE_ERROR,
816 _("Received unexpected message of type %u in %s:%u\n"),
817 ntohs (msg->type),
818 __FILE__,
819 __LINE__);
820 GNUNET_break (0); 726 GNUNET_break (0);
821 break; 727 h->reconnecting = GNUNET_YES;
728 disconnect_and_schedule_reconnect (h);
729 return;
822 } 730 }
731 LOG (GNUNET_ERROR_TYPE_DEBUG,
732 "Receiving SET_QUOTA message for `%s' with quota %u\n",
733 GNUNET_i2s (&qm->peer),
734 ntohl (qm->quota.value__));
735 GNUNET_BANDWIDTH_tracker_update_quota (&n->out_tracker,
736 qm->quota);
823} 737}
824 738
825 739
@@ -854,104 +768,53 @@ timeout_request_due_to_congestion (void *cls)
854 768
855 769
856/** 770/**
857 * Transmit message(s) to service. 771 * Transmit ready message(s) to service.
858 * 772 *
859 * @param cls handle to transport 773 * @param h handle to transport
860 * @param size number of bytes available in @a buf
861 * @param buf where to copy the message
862 * @return number of bytes copied to @a buf
863 */ 774 */
864static size_t 775static void
865transport_notify_ready (void *cls, 776transmit_ready (struct GNUNET_TRANSPORT_Handle *h)
866 size_t size,
867 void *buf)
868{ 777{
869 struct GNUNET_TRANSPORT_Handle *h = cls;
870 struct GNUNET_TRANSPORT_TransmitHandle *th; 778 struct GNUNET_TRANSPORT_TransmitHandle *th;
871 struct GNUNET_TIME_Relative delay; 779 struct GNUNET_TIME_Relative delay;
872 struct Neighbour *n; 780 struct Neighbour *n;
873 char *cbuf; 781 struct OutboundMessage *obm;
874 struct OutboundMessage obm; 782 struct GNUNET_MQ_Envelope *env;
875 size_t ret;
876 size_t nret;
877 size_t mret; 783 size_t mret;
878 784
879 GNUNET_assert (NULL != h->client); 785 GNUNET_assert (NULL != h->mq);
880 h->cth = NULL; 786 while (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap)))
881 if (NULL == buf)
882 {
883 /* transmission failed */
884 disconnect_and_schedule_reconnect (h);
885 return 0;
886 }
887
888 cbuf = buf;
889 ret = 0;
890 /* first send control messages */
891 while ( (NULL != (th = h->control_head)) &&
892 (th->notify_size <= size) )
893 {
894 GNUNET_CONTAINER_DLL_remove (h->control_head,
895 h->control_tail,
896 th);
897 nret = th->notify (th->notify_cls,
898 size,
899 &cbuf[ret]);
900 delay = GNUNET_TIME_absolute_get_duration (th->request_start);
901 if (delay.rel_value_us > GNUNET_CONSTANTS_LATENCY_WARN.rel_value_us)
902 LOG (GNUNET_ERROR_TYPE_WARNING,
903 "Added %u bytes of control message at %u after %s delay\n",
904 nret,
905 ret,
906 GNUNET_STRINGS_relative_time_to_string (delay,
907 GNUNET_YES));
908 else
909 LOG (GNUNET_ERROR_TYPE_DEBUG,
910 "Added %u bytes of control message at %u after %s delay\n",
911 nret,
912 ret,
913 GNUNET_STRINGS_relative_time_to_string (delay,
914 GNUNET_YES));
915 GNUNET_free (th);
916 ret += nret;
917 size -= nret;
918 }
919
920 /* then, if possible and no control messages pending, send data messages */
921 while ( (NULL == h->control_head) &&
922 (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap))) )
923 { 787 {
788 th = n->th;
924 if (GNUNET_YES != n->is_ready) 789 if (GNUNET_YES != n->is_ready)
925 { 790 {
926 /* peer not ready, wait for notification! */ 791 /* peer not ready, wait for notification! */
927 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap)); 792 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap));
928 n->hn = NULL; 793 n->hn = NULL;
929 GNUNET_assert (NULL == n->th->timeout_task); 794 GNUNET_assert (NULL == n->th->timeout_task);
930 n->th->timeout_task 795 th->timeout_task
931 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining 796 = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
932 (n->th->timeout), 797 (th->timeout),
933 &timeout_request_due_to_congestion, 798 &timeout_request_due_to_congestion,
934 n->th); 799 th);
935 continue; 800 continue;
936 } 801 }
937 th = n->th; 802 if (GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker,
938 if (th->notify_size + sizeof (struct OutboundMessage) > size) 803 th->notify_size).rel_value_us > 0)
939 break; /* does not fit */
940 if (GNUNET_BANDWIDTH_tracker_get_delay
941 (&n->out_tracker,
942 th->notify_size).rel_value_us > 0)
943 break; /* too early */ 804 break; /* too early */
944 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap)); 805 GNUNET_assert (n == GNUNET_CONTAINER_heap_remove_root (h->ready_heap));
945 n->hn = NULL; 806 n->hn = NULL;
946 n->th = NULL; 807 n->th = NULL;
947 GNUNET_assert (size >= sizeof (struct OutboundMessage)); 808 env = GNUNET_MQ_msg_extra (obm,
809 th->notify_size,
810 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND);
948 mret = th->notify (th->notify_cls, 811 mret = th->notify (th->notify_cls,
949 size - sizeof (struct OutboundMessage), 812 th->notify_size,
950 &cbuf[ret + sizeof (struct OutboundMessage)]); 813 &obm[1]);
951 GNUNET_assert (mret <= size - sizeof (struct OutboundMessage));
952 if (0 == mret) 814 if (0 == mret)
953 { 815 {
954 GNUNET_free (th); 816 GNUNET_free (th);
817 GNUNET_MQ_discard (env);
955 continue; 818 continue;
956 } 819 }
957 if (NULL != n->unready_warn_task) 820 if (NULL != n->unready_warn_task)
@@ -961,20 +824,13 @@ transport_notify_ready (void *cls,
961 n); 824 n);
962 n->last_payload = GNUNET_TIME_absolute_get (); 825 n->last_payload = GNUNET_TIME_absolute_get ();
963 n->is_ready = GNUNET_NO; 826 n->is_ready = GNUNET_NO;
964 GNUNET_assert (mret + sizeof (struct OutboundMessage) < 827 obm->reserved = htonl (0);
965 GNUNET_SERVER_MAX_MESSAGE_SIZE); 828 obm->timeout =
966 obm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND);
967 obm.header.size = htons (mret + sizeof (struct OutboundMessage));
968 obm.reserved = htonl (0);
969 obm.timeout =
970 GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining 829 GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining
971 (th->timeout)); 830 (th->timeout));
972 obm.peer = n->id; 831 obm->peer = n->id;
973 memcpy (&cbuf[ret], 832 GNUNET_MQ_send (h->mq,
974 &obm, 833 env);
975 sizeof (struct OutboundMessage));
976 ret += (mret + sizeof (struct OutboundMessage));
977 size -= (mret + sizeof (struct OutboundMessage));
978 GNUNET_BANDWIDTH_tracker_consume (&n->out_tracker, 834 GNUNET_BANDWIDTH_tracker_consume (&n->out_tracker,
979 mret); 835 mret);
980 delay = GNUNET_TIME_absolute_get_duration (th->request_start); 836 delay = GNUNET_TIME_absolute_get_duration (th->request_start);
@@ -995,14 +851,9 @@ transport_notify_ready (void *cls,
995 GNUNET_YES), 851 GNUNET_YES),
996 (unsigned int) n->out_tracker.available_bytes_per_s__); 852 (unsigned int) n->out_tracker.available_bytes_per_s__);
997 GNUNET_free (th); 853 GNUNET_free (th);
998 break;
999 } 854 }
1000 /* if there are more pending messages, try to schedule those */ 855 /* if there are more pending messages, try to schedule those */
1001 schedule_transmission (h); 856 schedule_transmission (h);
1002 LOG (GNUNET_ERROR_TYPE_DEBUG,
1003 "Transmitting %u bytes to transport service\n",
1004 ret);
1005 return ret;
1006} 857}
1007 858
1008 859
@@ -1016,12 +867,11 @@ static void
1016schedule_transmission_task (void *cls) 867schedule_transmission_task (void *cls)
1017{ 868{
1018 struct GNUNET_TRANSPORT_Handle *h = cls; 869 struct GNUNET_TRANSPORT_Handle *h = cls;
1019 size_t size;
1020 struct GNUNET_TRANSPORT_TransmitHandle *th; 870 struct GNUNET_TRANSPORT_TransmitHandle *th;
1021 struct Neighbour *n; 871 struct Neighbour *n;
1022 872
1023 h->quota_task = NULL; 873 h->quota_task = NULL;
1024 GNUNET_assert (NULL != h->client); 874 GNUNET_assert (NULL != h->mq);
1025 /* destroy all requests that have timed out */ 875 /* destroy all requests that have timed out */
1026 while ( (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap))) && 876 while ( (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap))) &&
1027 (0 == GNUNET_TIME_absolute_get_remaining (n->th->timeout).rel_value_us) ) 877 (0 == GNUNET_TIME_absolute_get_remaining (n->th->timeout).rel_value_us) )
@@ -1040,29 +890,12 @@ schedule_transmission_task (void *cls)
1040 NULL)); 890 NULL));
1041 GNUNET_free (th); 891 GNUNET_free (th);
1042 } 892 }
1043 if (NULL != h->cth) 893 n = GNUNET_CONTAINER_heap_peek (h->ready_heap);
1044 return; 894 if (NULL == n)
1045 if (NULL != h->control_head) 895 return; /* no pending messages */
1046 {
1047 size = h->control_head->notify_size;
1048 }
1049 else
1050 {
1051 n = GNUNET_CONTAINER_heap_peek (h->ready_heap);
1052 if (NULL == n)
1053 return; /* no pending messages */
1054 size = n->th->notify_size + sizeof (struct OutboundMessage);
1055 }
1056 LOG (GNUNET_ERROR_TYPE_DEBUG, 896 LOG (GNUNET_ERROR_TYPE_DEBUG,
1057 "Calling notify_transmit_ready\n"); 897 "Calling notify_transmit_ready\n");
1058 h->cth 898 transmit_ready (h);
1059 = GNUNET_CLIENT_notify_transmit_ready (h->client,
1060 size,
1061 GNUNET_TIME_UNIT_FOREVER_REL,
1062 GNUNET_NO,
1063 &transport_notify_ready,
1064 h);
1065 GNUNET_assert (NULL != h->cth);
1066} 899}
1067 900
1068 901
@@ -1078,15 +911,13 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h)
1078 struct GNUNET_TIME_Relative delay; 911 struct GNUNET_TIME_Relative delay;
1079 struct Neighbour *n; 912 struct Neighbour *n;
1080 913
1081 GNUNET_assert (NULL != h->client); 914 GNUNET_assert (NULL != h->mq);
1082 if (NULL != h->quota_task) 915 if (NULL != h->quota_task)
1083 { 916 {
1084 GNUNET_SCHEDULER_cancel (h->quota_task); 917 GNUNET_SCHEDULER_cancel (h->quota_task);
1085 h->quota_task = NULL; 918 h->quota_task = NULL;
1086 } 919 }
1087 if (NULL != h->control_head) 920 if (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap)))
1088 delay = GNUNET_TIME_UNIT_ZERO;
1089 else if (NULL != (n = GNUNET_CONTAINER_heap_peek (h->ready_heap)))
1090 { 921 {
1091 delay = 922 delay =
1092 GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker, 923 GNUNET_BANDWIDTH_tracker_get_delay (&n->out_tracker,
@@ -1111,83 +942,6 @@ schedule_transmission (struct GNUNET_TRANSPORT_Handle *h)
1111 942
1112 943
1113/** 944/**
1114 * Queue control request for transmission to the transport
1115 * service.
1116 *
1117 * @param h handle to the transport service
1118 * @param size number of bytes to be transmitted
1119 * @param notify function to call to get the content
1120 * @param notify_cls closure for @a notify
1121 * @return a `struct GNUNET_TRANSPORT_TransmitHandle`
1122 */
1123static struct GNUNET_TRANSPORT_TransmitHandle *
1124schedule_control_transmit (struct GNUNET_TRANSPORT_Handle *h,
1125 size_t size,
1126 GNUNET_TRANSPORT_TransmitReadyNotify notify,
1127 void *notify_cls)
1128{
1129 struct GNUNET_TRANSPORT_TransmitHandle *th;
1130
1131 LOG (GNUNET_ERROR_TYPE_DEBUG,
1132 "Control transmit of %u bytes requested\n",
1133 size);
1134 th = GNUNET_new (struct GNUNET_TRANSPORT_TransmitHandle);
1135 th->notify = notify;
1136 th->notify_cls = notify_cls;
1137 th->notify_size = size;
1138 th->request_start = GNUNET_TIME_absolute_get ();
1139 GNUNET_CONTAINER_DLL_insert_tail (h->control_head,
1140 h->control_tail,
1141 th);
1142 schedule_transmission (h);
1143 return th;
1144}
1145
1146
1147/**
1148 * Transmit START message to service.
1149 *
1150 * @param cls unused
1151 * @param size number of bytes available in @a buf
1152 * @param buf where to copy the message
1153 * @return number of bytes copied to @a buf
1154 */
1155static size_t
1156send_start (void *cls,
1157 size_t size,
1158 void *buf)
1159{
1160 struct GNUNET_TRANSPORT_Handle *h = cls;
1161 struct StartMessage s;
1162 uint32_t options;
1163
1164 if (NULL == buf)
1165 {
1166 /* Can only be shutdown, just give up */
1167 LOG (GNUNET_ERROR_TYPE_DEBUG,
1168 "Shutdown while trying to transmit START request.\n");
1169 return 0;
1170 }
1171 LOG (GNUNET_ERROR_TYPE_DEBUG,
1172 "Transmitting START request.\n");
1173 GNUNET_assert (size >= sizeof (struct StartMessage));
1174 s.header.size = htons (sizeof (struct StartMessage));
1175 s.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_START);
1176 options = 0;
1177 if (h->check_self)
1178 options |= 1;
1179 if (NULL != h->rec)
1180 options |= 2;
1181 s.options = htonl (options);
1182 s.self = h->self;
1183 memcpy (buf, &s, sizeof (struct StartMessage));
1184 GNUNET_CLIENT_receive (h->client, &demultiplexer, h,
1185 GNUNET_TIME_UNIT_FOREVER_REL);
1186 return sizeof (struct StartMessage);
1187}
1188
1189
1190/**
1191 * Try again to connect to transport service. 945 * Try again to connect to transport service.
1192 * 946 *
1193 * @param cls the handle to the transport service 947 * @param cls the handle to the transport service
@@ -1195,20 +949,61 @@ send_start (void *cls,
1195static void 949static void
1196reconnect (void *cls) 950reconnect (void *cls)
1197{ 951{
952 GNUNET_MQ_hd_var_size (hello,
953 GNUNET_MESSAGE_TYPE_HELLO,
954 struct GNUNET_MessageHeader);
955 GNUNET_MQ_hd_fixed_size (connect,
956 GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT,
957 struct ConnectInfoMessage);
958 GNUNET_MQ_hd_fixed_size (disconnect,
959 GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT,
960 struct DisconnectInfoMessage);
961 GNUNET_MQ_hd_fixed_size (send_ok,
962 GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_OK,
963 struct SendOkMessage);
964 GNUNET_MQ_hd_var_size (recv,
965 GNUNET_MESSAGE_TYPE_TRANSPORT_RECV,
966 struct InboundMessage);
967 GNUNET_MQ_hd_fixed_size (set_quota,
968 GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA,
969 struct QuotaSetMessage);
1198 struct GNUNET_TRANSPORT_Handle *h = cls; 970 struct GNUNET_TRANSPORT_Handle *h = cls;
971 struct GNUNET_MQ_MessageHandler handlers[] = {
972 make_hello_handler (h),
973 make_connect_handler (h),
974 make_disconnect_handler (h),
975 make_send_ok_handler (h),
976 make_recv_handler (h),
977 make_set_quota_handler (h),
978 GNUNET_MQ_handler_end ()
979 };
980 struct GNUNET_MQ_Envelope *env;
981 struct StartMessage *s;
982 uint32_t options;
1199 983
1200 h->reconnect_task = NULL; 984 h->reconnect_task = NULL;
1201 LOG (GNUNET_ERROR_TYPE_DEBUG, 985 LOG (GNUNET_ERROR_TYPE_DEBUG,
1202 "Connecting to transport service.\n"); 986 "Connecting to transport service.\n");
1203 GNUNET_assert (NULL == h->client); 987 GNUNET_assert (NULL == h->mq);
1204 GNUNET_assert (NULL == h->control_head);
1205 GNUNET_assert (NULL == h->control_tail);
1206 h->reconnecting = GNUNET_NO; 988 h->reconnecting = GNUNET_NO;
1207 h->client = GNUNET_CLIENT_connect ("transport", h->cfg); 989 h->mq = GNUNET_CLIENT_connecT (h->cfg,
1208 990 "transport",
1209 GNUNET_assert (NULL != h->client); 991 handlers,
1210 schedule_control_transmit (h, sizeof (struct StartMessage), 992 &mq_error_handler,
1211 &send_start, h); 993 h);
994 if (NULL == h->mq)
995 return;
996 env = GNUNET_MQ_msg (s,
997 GNUNET_MESSAGE_TYPE_TRANSPORT_START);
998 options = 0;
999 if (h->check_self)
1000 options |= 1;
1001 if (NULL != h->rec)
1002 options |= 2;
1003 s->options = htonl (options);
1004 s->self = h->self;
1005 GNUNET_MQ_send (h->mq,
1006 env);
1212} 1007}
1213 1008
1214 1009
@@ -1221,20 +1016,11 @@ reconnect (void *cls)
1221static void 1016static void
1222disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h) 1017disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h)
1223{ 1018{
1224 struct GNUNET_TRANSPORT_TransmitHandle *th;
1225
1226 GNUNET_assert (NULL == h->reconnect_task); 1019 GNUNET_assert (NULL == h->reconnect_task);
1227 if (NULL != h->cth) 1020 if (NULL != h->mq)
1228 {
1229 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
1230 h->cth = NULL;
1231 }
1232 if (NULL != h->client)
1233 { 1021 {
1234 GNUNET_CLIENT_disconnect (h->client); 1022 GNUNET_MQ_destroy (h->mq);
1235 h->client = NULL; 1023 h->mq = NULL;
1236/* LOG (GNUNET_ERROR_TYPE_ERROR,
1237 "Client disconnect done \n");*/
1238 } 1024 }
1239 /* Forget about all neighbours that we used to be connected to */ 1025 /* Forget about all neighbours that we used to be connected to */
1240 GNUNET_CONTAINER_multipeermap_iterate (h->neighbours, 1026 GNUNET_CONTAINER_multipeermap_iterate (h->neighbours,
@@ -1245,16 +1031,6 @@ disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h)
1245 GNUNET_SCHEDULER_cancel (h->quota_task); 1031 GNUNET_SCHEDULER_cancel (h->quota_task);
1246 h->quota_task = NULL; 1032 h->quota_task = NULL;
1247 } 1033 }
1248 while ((NULL != (th = h->control_head)))
1249 {
1250 GNUNET_CONTAINER_DLL_remove (h->control_head,
1251 h->control_tail,
1252 th);
1253 th->notify (th->notify_cls,
1254 0,
1255 NULL);
1256 GNUNET_free (th);
1257 }
1258 LOG (GNUNET_ERROR_TYPE_DEBUG, 1034 LOG (GNUNET_ERROR_TYPE_DEBUG,
1259 "Scheduling task to reconnect to transport service in %s.\n", 1035 "Scheduling task to reconnect to transport service in %s.\n",
1260 GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, 1036 GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay,
@@ -1268,109 +1044,7 @@ disconnect_and_schedule_reconnect (struct GNUNET_TRANSPORT_Handle *h)
1268 1044
1269 1045
1270/** 1046/**
1271 * Cancel control request for transmission to the transport service. 1047 * Set transport metrics for a peer and a direction.
1272 *
1273 * @param th handle to the transport service
1274 * @param tth transmit handle to cancel
1275 */
1276static void
1277cancel_control_transmit (struct GNUNET_TRANSPORT_Handle *th,
1278 struct GNUNET_TRANSPORT_TransmitHandle *tth)
1279{
1280 LOG (GNUNET_ERROR_TYPE_DEBUG,
1281 "Canceling transmit of contral transmission requested\n");
1282 GNUNET_CONTAINER_DLL_remove (th->control_head,
1283 th->control_tail,
1284 tth);
1285 GNUNET_free (tth);
1286}
1287
1288
1289/**
1290 * Send HELLO message to the service.
1291 *
1292 * @param cls the HELLO message to send
1293 * @param size number of bytes available in @a buf
1294 * @param buf where to copy the message
1295 * @return number of bytes copied to @a buf
1296 */
1297static size_t
1298send_hello (void *cls,
1299 size_t size,
1300 void *buf)
1301{
1302 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh = cls;
1303 struct GNUNET_MessageHeader *msg = ohh->msg;
1304 uint16_t ssize;
1305
1306 if (NULL == buf)
1307 {
1308 LOG (GNUNET_ERROR_TYPE_DEBUG,
1309 "Timeout while trying to transmit `%s' request.\n",
1310 "HELLO");
1311 if (NULL != ohh->cont)
1312 ohh->cont (ohh->cls);
1313 GNUNET_free (msg);
1314 GNUNET_CONTAINER_DLL_remove (ohh->th->oh_head,
1315 ohh->th->oh_tail,
1316 ohh);
1317 GNUNET_free (ohh);
1318 return 0;
1319 }
1320 LOG (GNUNET_ERROR_TYPE_DEBUG,
1321 "Transmitting `%s' request.\n",
1322 "HELLO");
1323 ssize = ntohs (msg->size);
1324 GNUNET_assert (size >= ssize);
1325 memcpy (buf,
1326 msg,
1327 ssize);
1328 GNUNET_free (msg);
1329 if (NULL != ohh->cont)
1330 ohh->cont (ohh->cls);
1331 GNUNET_CONTAINER_DLL_remove (ohh->th->oh_head,
1332 ohh->th->oh_tail,
1333 ohh);
1334 GNUNET_free (ohh);
1335 return ssize;
1336}
1337
1338
1339/**
1340 * Send traffic metric message to the service.
1341 *
1342 * @param cls the message to send
1343 * @param size number of bytes available in @a buf
1344 * @param buf where to copy the message
1345 * @return number of bytes copied to @a buf
1346 */
1347static size_t
1348send_metric (void *cls,
1349 size_t size,
1350 void *buf)
1351{
1352 struct TrafficMetricMessage *msg = cls;
1353 uint16_t ssize;
1354
1355 if (NULL == buf)
1356 {
1357 LOG (GNUNET_ERROR_TYPE_DEBUG,
1358 "Timeout while trying to transmit TRAFFIC_METRIC request.\n");
1359 GNUNET_free (msg);
1360 return 0;
1361 }
1362 LOG (GNUNET_ERROR_TYPE_DEBUG,
1363 "Transmitting TRAFFIC_METRIC request.\n");
1364 ssize = ntohs (msg->header.size);
1365 GNUNET_assert (size >= ssize);
1366 memcpy (buf, msg, ssize);
1367 GNUNET_free (msg);
1368 return ssize;
1369}
1370
1371
1372/**
1373 * Set transport metrics for a peer and a direction
1374 * 1048 *
1375 * @param handle transport handle 1049 * @param handle transport handle
1376 * @param peer the peer to set the metric for 1050 * @param peer the peer to set the metric for
@@ -1388,101 +1062,21 @@ GNUNET_TRANSPORT_set_traffic_metric (struct GNUNET_TRANSPORT_Handle *handle,
1388 struct GNUNET_TIME_Relative delay_in, 1062 struct GNUNET_TIME_Relative delay_in,
1389 struct GNUNET_TIME_Relative delay_out) 1063 struct GNUNET_TIME_Relative delay_out)
1390{ 1064{
1065 struct GNUNET_MQ_Envelope *env;
1391 struct TrafficMetricMessage *msg; 1066 struct TrafficMetricMessage *msg;
1392 1067
1393 msg = GNUNET_new (struct TrafficMetricMessage); 1068 if (NULL == handle->mq)
1394 msg->header.size = htons (sizeof (struct TrafficMetricMessage)); 1069 return;
1395 msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC); 1070 env = GNUNET_MQ_msg (msg,
1071 GNUNET_MESSAGE_TYPE_TRANSPORT_TRAFFIC_METRIC);
1396 msg->reserved = htonl (0); 1072 msg->reserved = htonl (0);
1397 msg->peer = *peer; 1073 msg->peer = *peer;
1398 GNUNET_ATS_properties_hton (&msg->properties, 1074 GNUNET_ATS_properties_hton (&msg->properties,
1399 prop); 1075 prop);
1400 msg->delay_in = GNUNET_TIME_relative_hton (delay_in); 1076 msg->delay_in = GNUNET_TIME_relative_hton (delay_in);
1401 msg->delay_out = GNUNET_TIME_relative_hton (delay_out); 1077 msg->delay_out = GNUNET_TIME_relative_hton (delay_out);
1402 schedule_control_transmit (handle, 1078 GNUNET_MQ_send (handle->mq,
1403 sizeof (struct TrafficMetricMessage), 1079 env);
1404 &send_metric,
1405 msg);
1406}
1407
1408
1409/**
1410 * Offer the transport service the HELLO of another peer. Note that
1411 * the transport service may just ignore this message if the HELLO is
1412 * malformed or useless due to our local configuration.
1413 *
1414 * @param handle connection to transport service
1415 * @param hello the hello message
1416 * @param cont continuation to call when HELLO has been sent,
1417 * tc reason #GNUNET_SCHEDULER_REASON_TIMEOUT for fail
1418 * tc reasong #GNUNET_SCHEDULER_REASON_READ_READY for success
1419 * @param cont_cls closure for @a cont
1420 * @return a `struct GNUNET_TRANSPORT_OfferHelloHandle` handle or NULL on failure,
1421 * in case of failure @a cont will not be called
1422 *
1423 */
1424struct GNUNET_TRANSPORT_OfferHelloHandle *
1425GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle,
1426 const struct GNUNET_MessageHeader *hello,
1427 GNUNET_SCHEDULER_TaskCallback cont,
1428 void *cont_cls)
1429{
1430 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh;
1431 struct GNUNET_MessageHeader *msg;
1432 struct GNUNET_PeerIdentity peer;
1433 uint16_t size;
1434
1435 if (NULL == handle->client)
1436 return NULL;
1437 GNUNET_break (ntohs (hello->type) == GNUNET_MESSAGE_TYPE_HELLO);
1438 size = ntohs (hello->size);
1439 GNUNET_break (size >= sizeof (struct GNUNET_MessageHeader));
1440 if (GNUNET_OK !=
1441 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) hello,
1442 &peer))
1443 {
1444 GNUNET_break (0);
1445 return NULL;
1446 }
1447
1448 msg = GNUNET_malloc (size);
1449 memcpy (msg, hello, size);
1450 LOG (GNUNET_ERROR_TYPE_DEBUG,
1451 "Offering HELLO message of `%s' to transport for validation.\n",
1452 GNUNET_i2s (&peer));
1453
1454 ohh = GNUNET_new (struct GNUNET_TRANSPORT_OfferHelloHandle);
1455 ohh->th = handle;
1456 ohh->cont = cont;
1457 ohh->cls = cont_cls;
1458 ohh->msg = msg;
1459 ohh->tth = schedule_control_transmit (handle,
1460 size,
1461 &send_hello,
1462 ohh);
1463 GNUNET_CONTAINER_DLL_insert (handle->oh_head,
1464 handle->oh_tail,
1465 ohh);
1466 return ohh;
1467}
1468
1469
1470/**
1471 * Cancel the request to transport to offer the HELLO message
1472 *
1473 * @param ohh the handle for the operation to cancel
1474 */
1475void
1476GNUNET_TRANSPORT_offer_hello_cancel (struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
1477{
1478 struct GNUNET_TRANSPORT_Handle *th = ohh->th;
1479
1480 cancel_control_transmit (ohh->th, ohh->tth);
1481 GNUNET_CONTAINER_DLL_remove (th->oh_head,
1482 th->oh_tail,
1483 ohh);
1484 GNUNET_free (ohh->msg);
1485 GNUNET_free (ohh);
1486} 1080}
1487 1081
1488 1082
@@ -1506,76 +1100,6 @@ GNUNET_TRANSPORT_check_peer_connected (struct GNUNET_TRANSPORT_Handle *handle,
1506 1100
1507 1101
1508/** 1102/**
1509 * Task to call the HelloUpdateCallback of the GetHelloHandle
1510 *
1511 * @param cls the `struct GNUNET_TRANSPORT_GetHelloHandle`
1512 */
1513static void
1514call_hello_update_cb_async (void *cls)
1515{
1516 struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls;
1517
1518 GNUNET_assert (NULL != ghh->handle->my_hello);
1519 GNUNET_assert (NULL != ghh->notify_task);
1520 ghh->notify_task = NULL;
1521 ghh->rec (ghh->rec_cls,
1522 ghh->handle->my_hello);
1523}
1524
1525
1526/**
1527 * Obtain the HELLO message for this peer. The callback given in this function
1528 * is never called synchronously.
1529 *
1530 * @param handle connection to transport service
1531 * @param rec function to call with the HELLO, sender will be our peer
1532 * identity; message and sender will be NULL on timeout
1533 * (handshake with transport service pending/failed).
1534 * cost estimate will be 0.
1535 * @param rec_cls closure for @a rec
1536 * @return handle to cancel the operation
1537 */
1538struct GNUNET_TRANSPORT_GetHelloHandle *
1539GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle,
1540 GNUNET_TRANSPORT_HelloUpdateCallback rec,
1541 void *rec_cls)
1542{
1543 struct GNUNET_TRANSPORT_GetHelloHandle *hwl;
1544
1545 hwl = GNUNET_new (struct GNUNET_TRANSPORT_GetHelloHandle);
1546 hwl->rec = rec;
1547 hwl->rec_cls = rec_cls;
1548 hwl->handle = handle;
1549 GNUNET_CONTAINER_DLL_insert (handle->hwl_head,
1550 handle->hwl_tail,
1551 hwl);
1552 if (NULL != handle->my_hello)
1553 hwl->notify_task = GNUNET_SCHEDULER_add_now (&call_hello_update_cb_async,
1554 hwl);
1555 return hwl;
1556}
1557
1558
1559/**
1560 * Stop receiving updates about changes to our HELLO message.
1561 *
1562 * @param ghh handle to cancel
1563 */
1564void
1565GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh)
1566{
1567 struct GNUNET_TRANSPORT_Handle *handle = ghh->handle;
1568
1569 if (NULL != ghh->notify_task)
1570 GNUNET_SCHEDULER_cancel (ghh->notify_task);
1571 GNUNET_CONTAINER_DLL_remove (handle->hwl_head,
1572 handle->hwl_tail,
1573 ghh);
1574 GNUNET_free (ghh);
1575}
1576
1577
1578/**
1579 * Connect to the transport service. Note that the connection may 1103 * Connect to the transport service. Note that the connection may
1580 * complete (or fail) asynchronously. 1104 * complete (or fail) asynchronously.
1581 * 1105 *
@@ -1629,40 +1153,35 @@ GNUNET_TRANSPORT_connect2 (const struct GNUNET_CONFIGURATION_Handle *cfg,
1629 GNUNET_TRANSPORT_NotifyDisconnect nd, 1153 GNUNET_TRANSPORT_NotifyDisconnect nd,
1630 GNUNET_TRANSPORT_NotifyExcessBandwidth neb) 1154 GNUNET_TRANSPORT_NotifyExcessBandwidth neb)
1631{ 1155{
1632 struct GNUNET_TRANSPORT_Handle *ret; 1156 struct GNUNET_TRANSPORT_Handle *h;
1633 1157
1634 ret = GNUNET_new (struct GNUNET_TRANSPORT_Handle); 1158 h = GNUNET_new (struct GNUNET_TRANSPORT_Handle);
1635 if (NULL != self) 1159 if (NULL != self)
1636 { 1160 {
1637 ret->self = *self; 1161 h->self = *self;
1638 ret->check_self = GNUNET_YES; 1162 h->check_self = GNUNET_YES;
1639 } 1163 }
1640 ret->cfg = cfg; 1164 h->cfg = cfg;
1641 ret->cls = cls; 1165 h->cls = cls;
1642 ret->rec = rec; 1166 h->rec = rec;
1643 ret->nc_cb = nc; 1167 h->nc_cb = nc;
1644 ret->nd_cb = nd; 1168 h->nd_cb = nd;
1645 ret->neb_cb = neb; 1169 h->neb_cb = neb;
1646 ret->reconnect_delay = GNUNET_TIME_UNIT_ZERO; 1170 h->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
1647 LOG (GNUNET_ERROR_TYPE_DEBUG, 1171 LOG (GNUNET_ERROR_TYPE_DEBUG,
1648 "Connecting to transport service.\n"); 1172 "Connecting to transport service.\n");
1649 ret->client = GNUNET_CLIENT_connect ("transport", 1173 reconnect (h);
1650 cfg); 1174 if (NULL == h->mq)
1651 if (NULL == ret->client)
1652 { 1175 {
1653 GNUNET_free (ret); 1176 GNUNET_free (h);
1654 return NULL; 1177 return NULL;
1655 } 1178 }
1656 ret->neighbours = 1179 h->neighbours =
1657 GNUNET_CONTAINER_multipeermap_create (STARTING_NEIGHBOURS_SIZE, 1180 GNUNET_CONTAINER_multipeermap_create (STARTING_NEIGHBOURS_SIZE,
1658 GNUNET_YES); 1181 GNUNET_YES);
1659 ret->ready_heap = 1182 h->ready_heap =
1660 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 1183 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1661 schedule_control_transmit (ret, 1184 return h;
1662 sizeof (struct StartMessage),
1663 &send_start,
1664 ret);
1665 return ret;
1666} 1185}
1667 1186
1668 1187
@@ -1694,8 +1213,6 @@ GNUNET_TRANSPORT_disconnect (struct GNUNET_TRANSPORT_Handle *handle)
1694 } 1213 }
1695 GNUNET_free_non_null (handle->my_hello); 1214 GNUNET_free_non_null (handle->my_hello);
1696 handle->my_hello = NULL; 1215 handle->my_hello = NULL;
1697 GNUNET_assert (NULL == handle->hwl_head);
1698 GNUNET_assert (NULL == handle->hwl_tail);
1699 GNUNET_CONTAINER_heap_destroy (handle->ready_heap); 1216 GNUNET_CONTAINER_heap_destroy (handle->ready_heap);
1700 handle->ready_heap = NULL; 1217 handle->ready_heap = NULL;
1701 GNUNET_free (handle); 1218 GNUNET_free (handle);
diff --git a/src/transport/transport_api_get_hello.c b/src/transport/transport_api_get_hello.c
index 8087159c6..9a65616a9 100644
--- a/src/transport/transport_api_get_hello.c
+++ b/src/transport/transport_api_get_hello.c
@@ -34,25 +34,20 @@
34 34
35 35
36/** 36/**
37 * Linked list of functions to call whenever our HELLO is updated. 37 * Functions to call with this peer's HELLO.
38 */ 38 */
39struct GNUNET_TRANSPORT_GetHelloHandle 39struct GNUNET_TRANSPORT_GetHelloHandle
40{ 40{
41 41
42 /** 42 /**
43 * This is a doubly linked list. 43 * Our configuration.
44 */ 44 */
45 struct GNUNET_TRANSPORT_GetHelloHandle *next; 45 const struct GNUNET_CONFIGURATION_Handle *cfg;
46
47 /**
48 * This is a doubly linked list.
49 */
50 struct GNUNET_TRANSPORT_GetHelloHandle *prev;
51 46
52 /** 47 /**
53 * Transport handle. 48 * Transport handle.
54 */ 49 */
55 struct GNUNET_TRANSPORT_Handle *handle; 50 struct GNUNET_MQ_Handle *mq;
56 51
57 /** 52 /**
58 * Callback to call once we got our HELLO. 53 * Callback to call once we got our HELLO.
@@ -60,34 +55,158 @@ struct GNUNET_TRANSPORT_GetHelloHandle
60 GNUNET_TRANSPORT_HelloUpdateCallback rec; 55 GNUNET_TRANSPORT_HelloUpdateCallback rec;
61 56
62 /** 57 /**
58 * Closure for @e rec.
59 */
60 void *rec_cls;
61
62 /**
63 * Task for calling the HelloUpdateCallback when we already have a HELLO 63 * Task for calling the HelloUpdateCallback when we already have a HELLO
64 */ 64 */
65 struct GNUNET_SCHEDULER_Task *notify_task; 65 struct GNUNET_SCHEDULER_Task *notify_task;
66 66
67 /** 67 /**
68 * Closure for @e rec. 68 * ID of the task trying to reconnect to the service.
69 */ 69 */
70 void *rec_cls; 70 struct GNUNET_SCHEDULER_Task *reconnect_task;
71
72 /**
73 * Delay until we try to reconnect.
74 */
75 struct GNUNET_TIME_Relative reconnect_delay;
71 76
72}; 77};
73 78
74 79
80/**
81 * Function we use for checking incoming HELLO messages.
82 *
83 * @param cls closure, a `struct GNUNET_TRANSPORT_Handle *`
84 * @param msg message received
85 * @return #GNUNET_OK if message is well-formed
86 */
87static int
88check_hello (void *cls,
89 const struct GNUNET_MessageHeader *msg)
90{
91 struct GNUNET_PeerIdentity me;
92
93 if (GNUNET_OK !=
94 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) msg,
95 &me))
96 {
97 GNUNET_break (0);
98 return GNUNET_SYSERR;
99 }
100 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
101 "Receiving (my own) HELLO message (%u bytes), I am `%s'.\n",
102 (unsigned int) ntohs (msg->size),
103 GNUNET_i2s (&me));
104 return GNUNET_OK;
105}
106
75 107
76/** 108/**
77 * Task to call the HelloUpdateCallback of the GetHelloHandle 109 * Function we use for handling incoming HELLO messages.
78 * 110 *
79 * @param cls the `struct GNUNET_TRANSPORT_GetHelloHandle` 111 * @param cls closure, a `struct GNUNET_TRANSPORT_GetHelloHandle *`
112 * @param msg message received
80 */ 113 */
81static void 114static void
82call_hello_update_cb_async (void *cls) 115handle_hello (void *cls,
116 const struct GNUNET_MessageHeader *msg)
83{ 117{
84 struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls; 118 struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls;
85 119
86 GNUNET_assert (NULL != ghh->handle->my_hello);
87 GNUNET_assert (NULL != ghh->notify_task);
88 ghh->notify_task = NULL;
89 ghh->rec (ghh->rec_cls, 120 ghh->rec (ghh->rec_cls,
90 ghh->handle->my_hello); 121 msg);
122}
123
124
125/**
126 * Function that will schedule the job that will try
127 * to connect us again to the client.
128 *
129 * @param ghh transport service to reconnect
130 */
131static void
132schedule_reconnect (struct GNUNET_TRANSPORT_GetHelloHandle *ghh);
133
134
135/**
136 * Generic error handler, called with the appropriate
137 * error code and the same closure specified at the creation of
138 * the message queue.
139 * Not every message queue implementation supports an error handler.
140 *
141 * @param cls closure with the `struct GNUNET_TRANSPORT_Handle *`
142 * @param error error code
143 */
144static void
145mq_error_handler (void *cls,
146 enum GNUNET_MQ_Error error)
147{
148 struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls;
149
150 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
151 "Error receiving from transport service, disconnecting temporarily.\n");
152 GNUNET_MQ_destroy (ghh->mq);
153 ghh->mq = NULL;
154 schedule_reconnect (ghh);
155}
156
157
158/**
159 * Try again to connect to transport service.
160 *
161 * @param cls the handle to the transport service
162 */
163static void
164reconnect (void *cls)
165{
166 GNUNET_MQ_hd_var_size (hello,
167 GNUNET_MESSAGE_TYPE_HELLO,
168 struct GNUNET_MessageHeader);
169 struct GNUNET_TRANSPORT_GetHelloHandle *ghh = cls;
170 struct GNUNET_MQ_MessageHandler handlers[] = {
171 make_hello_handler (ghh),
172 GNUNET_MQ_handler_end ()
173 };
174 struct GNUNET_MQ_Envelope *env;
175 struct StartMessage *s;
176
177 ghh->reconnect_task = NULL;
178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
179 "Connecting to transport service.\n");
180 GNUNET_assert (NULL == ghh->mq);
181 ghh->mq = GNUNET_CLIENT_connecT (ghh->cfg,
182 "transport",
183 handlers,
184 &mq_error_handler,
185 ghh);
186 if (NULL == ghh->mq)
187 return;
188 env = GNUNET_MQ_msg (s,
189 GNUNET_MESSAGE_TYPE_TRANSPORT_START);
190 s->options = htonl (0);
191 GNUNET_MQ_send (ghh->mq,
192 env);
193}
194
195
196/**
197 * Function that will schedule the job that will try
198 * to connect us again to the client.
199 *
200 * @param ghh transport service to reconnect
201 */
202static void
203schedule_reconnect (struct GNUNET_TRANSPORT_GetHelloHandle *ghh)
204{
205 ghh->reconnect_task =
206 GNUNET_SCHEDULER_add_delayed (ghh->reconnect_delay,
207 &reconnect,
208 ghh);
209 ghh->reconnect_delay = GNUNET_TIME_STD_BACKOFF (ghh->reconnect_delay);
91} 210}
92 211
93 212
@@ -95,7 +214,7 @@ call_hello_update_cb_async (void *cls)
95 * Obtain the HELLO message for this peer. The callback given in this function 214 * Obtain the HELLO message for this peer. The callback given in this function
96 * is never called synchronously. 215 * is never called synchronously.
97 * 216 *
98 * @param handle connection to transport service 217 * @param cfg configuration
99 * @param rec function to call with the HELLO, sender will be our peer 218 * @param rec function to call with the HELLO, sender will be our peer
100 * identity; message and sender will be NULL on timeout 219 * identity; message and sender will be NULL on timeout
101 * (handshake with transport service pending/failed). 220 * (handshake with transport service pending/failed).
@@ -104,23 +223,23 @@ call_hello_update_cb_async (void *cls)
104 * @return handle to cancel the operation 223 * @return handle to cancel the operation
105 */ 224 */
106struct GNUNET_TRANSPORT_GetHelloHandle * 225struct GNUNET_TRANSPORT_GetHelloHandle *
107GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle, 226GNUNET_TRANSPORT_get_hello (const struct GNUNET_CONFIGURATION_Handle *cfg,
108 GNUNET_TRANSPORT_HelloUpdateCallback rec, 227 GNUNET_TRANSPORT_HelloUpdateCallback rec,
109 void *rec_cls) 228 void *rec_cls)
110{ 229{
111 struct GNUNET_TRANSPORT_GetHelloHandle *hwl; 230 struct GNUNET_TRANSPORT_GetHelloHandle *ghh;
112 231
113 hwl = GNUNET_new (struct GNUNET_TRANSPORT_GetHelloHandle); 232 ghh = GNUNET_new (struct GNUNET_TRANSPORT_GetHelloHandle);
114 hwl->rec = rec; 233 ghh->rec = rec;
115 hwl->rec_cls = rec_cls; 234 ghh->rec_cls = rec_cls;
116 hwl->handle = handle; 235 ghh->cfg = cfg;
117 GNUNET_CONTAINER_DLL_insert (handle->hwl_head, 236 reconnect (ghh);
118 handle->hwl_tail, 237 if (NULL == ghh->mq)
119 hwl); 238 {
120 if (NULL != handle->my_hello) 239 GNUNET_free (ghh);
121 hwl->notify_task = GNUNET_SCHEDULER_add_now (&call_hello_update_cb_async, 240 return NULL;
122 hwl); 241 }
123 return hwl; 242 return ghh;
124} 243}
125 244
126 245
@@ -132,15 +251,13 @@ GNUNET_TRANSPORT_get_hello (struct GNUNET_TRANSPORT_Handle *handle,
132void 251void
133GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh) 252GNUNET_TRANSPORT_get_hello_cancel (struct GNUNET_TRANSPORT_GetHelloHandle *ghh)
134{ 253{
135 struct GNUNET_TRANSPORT_Handle *handle = ghh->handle; 254 if (NULL != ghh->mq)
136 255 {
137 if (NULL != ghh->notify_task) 256 GNUNET_MQ_destroy (ghh->mq);
138 GNUNET_SCHEDULER_cancel (ghh->notify_task); 257 ghh->mq = NULL;
139 GNUNET_CONTAINER_DLL_remove (handle->hwl_head, 258 }
140 handle->hwl_tail,
141 ghh);
142 GNUNET_free (ghh); 259 GNUNET_free (ghh);
143} 260}
144 261
145 262
146/* end of transport_api_hello.c */ 263/* end of transport_api_get_hello.c */
diff --git a/src/transport/transport_api_offer_hello.c b/src/transport/transport_api_offer_hello.c
index 0abce2d62..951ab9ba4 100644
--- a/src/transport/transport_api_offer_hello.c
+++ b/src/transport/transport_api_offer_hello.c
@@ -23,31 +23,23 @@
23 * @brief library to offer HELLOs to transport service 23 * @brief library to offer HELLOs to transport service
24 * @author Christian Grothoff 24 * @author Christian Grothoff
25 */ 25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_hello_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_transport_service.h"
31
26 32
27/** 33/**
28 * Entry in linked list for all offer-HELLO requests. 34 * Entry in linked list for all offer-HELLO requests.
29 */ 35 */
30struct GNUNET_TRANSPORT_OfferHelloHandle 36struct GNUNET_TRANSPORT_OfferHelloHandle
31{ 37{
32 /**
33 * For the DLL.
34 */
35 struct GNUNET_TRANSPORT_OfferHelloHandle *prev;
36
37 /**
38 * For the DLL.
39 */
40 struct GNUNET_TRANSPORT_OfferHelloHandle *next;
41 38
42 /** 39 /**
43 * Transport service handle we use for transmission. 40 * Transport service handle we use for transmission.
44 */ 41 */
45 struct GNUNET_TRANSPORT_Handle *th; 42 struct GNUNET_MQ_Handle *mq;
46
47 /**
48 * Transmission handle for this request.
49 */
50 struct GNUNET_TRANSPORT_TransmitHandle *tth;
51 43
52 /** 44 /**
53 * Function to call once we are done. 45 * Function to call once we are done.
@@ -59,20 +51,31 @@ struct GNUNET_TRANSPORT_OfferHelloHandle
59 */ 51 */
60 void *cls; 52 void *cls;
61 53
62 /**
63 * The HELLO message to be transmitted.
64 */
65 struct GNUNET_MessageHeader *msg;
66}; 54};
67 55
68 56
57/**
58 * Done sending HELLO message to the service, notify application.
59 *
60 * @param cls the handle for the operation
61 */
62static void
63finished_hello (void *cls)
64{
65 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh = cls;
66
67 if (NULL != ohh->cont)
68 ohh->cont (ohh->cls);
69 GNUNET_TRANSPORT_offer_hello_cancel (ohh);
70}
71
69 72
70/** 73/**
71 * Offer the transport service the HELLO of another peer. Note that 74 * Offer the transport service the HELLO of another peer. Note that
72 * the transport service may just ignore this message if the HELLO is 75 * the transport service may just ignore this message if the HELLO is
73 * malformed or useless due to our local configuration. 76 * malformed or useless due to our local configuration.
74 * 77 *
75 * @param handle connection to transport service 78 * @param cfg configuration
76 * @param hello the hello message 79 * @param hello the hello message
77 * @param cont continuation to call when HELLO has been sent, 80 * @param cont continuation to call when HELLO has been sent,
78 * tc reason #GNUNET_SCHEDULER_REASON_TIMEOUT for fail 81 * tc reason #GNUNET_SCHEDULER_REASON_TIMEOUT for fail
@@ -83,46 +86,43 @@ struct GNUNET_TRANSPORT_OfferHelloHandle
83 * 86 *
84 */ 87 */
85struct GNUNET_TRANSPORT_OfferHelloHandle * 88struct GNUNET_TRANSPORT_OfferHelloHandle *
86GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle, 89GNUNET_TRANSPORT_offer_hello (const struct GNUNET_CONFIGURATION_Handle *cfg,
87 const struct GNUNET_MessageHeader *hello, 90 const struct GNUNET_MessageHeader *hello,
88 GNUNET_SCHEDULER_TaskCallback cont, 91 GNUNET_SCHEDULER_TaskCallback cont,
89 void *cont_cls) 92 void *cont_cls)
90{ 93{
91 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh; 94 struct GNUNET_TRANSPORT_OfferHelloHandle *ohh
92 struct GNUNET_MessageHeader *msg; 95 = GNUNET_new (struct GNUNET_TRANSPORT_OfferHelloHandle);
96 struct GNUNET_MQ_Envelope *env;
93 struct GNUNET_PeerIdentity peer; 97 struct GNUNET_PeerIdentity peer;
94 uint16_t size;
95 98
96 if (NULL == handle->mq)
97 return NULL;
98 GNUNET_break (ntohs (hello->type) == GNUNET_MESSAGE_TYPE_HELLO);
99 size = ntohs (hello->size);
100 GNUNET_break (size >= sizeof (struct GNUNET_MessageHeader));
101 if (GNUNET_OK != 99 if (GNUNET_OK !=
102 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) hello, 100 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *) hello,
103 &peer)) 101 &peer))
104 { 102 {
105 GNUNET_break (0); 103 GNUNET_break (0);
104 GNUNET_free (ohh);
105 return NULL;
106 }
107 ohh->mq = GNUNET_CLIENT_connecT (cfg,
108 "transport",
109 NULL,
110 NULL,
111 ohh);
112 if (NULL == ohh->mq)
113 {
114 GNUNET_free (ohh);
106 return NULL; 115 return NULL;
107 } 116 }
108
109 msg = GNUNET_malloc (size);
110 memcpy (msg, hello, size);
111 LOG (GNUNET_ERROR_TYPE_DEBUG,
112 "Offering HELLO message of `%s' to transport for validation.\n",
113 GNUNET_i2s (&peer));
114 ohh = GNUNET_new (struct GNUNET_TRANSPORT_OfferHelloHandle);
115 ohh->th = handle;
116 ohh->cont = cont; 117 ohh->cont = cont;
117 ohh->cls = cont_cls; 118 ohh->cls = cont_cls;
118 ohh->msg = msg; 119 GNUNET_break (ntohs (hello->type) == GNUNET_MESSAGE_TYPE_HELLO);
119 ohh->tth = schedule_control_transmit (handle, 120 env = GNUNET_MQ_msg_copy (hello);
120 size, 121 GNUNET_MQ_notify_sent (env,
121 &send_hello, 122 &finished_hello,
122 ohh); 123 ohh);
123 GNUNET_CONTAINER_DLL_insert (handle->oh_head, 124 GNUNET_MQ_send (ohh->mq,
124 handle->oh_tail, 125 env);
125 ohh);
126 return ohh; 126 return ohh;
127} 127}
128 128
@@ -135,13 +135,7 @@ GNUNET_TRANSPORT_offer_hello (struct GNUNET_TRANSPORT_Handle *handle,
135void 135void
136GNUNET_TRANSPORT_offer_hello_cancel (struct GNUNET_TRANSPORT_OfferHelloHandle *ohh) 136GNUNET_TRANSPORT_offer_hello_cancel (struct GNUNET_TRANSPORT_OfferHelloHandle *ohh)
137{ 137{
138 struct GNUNET_TRANSPORT_Handle *th = ohh->th; 138 GNUNET_MQ_destroy (ohh->mq);
139
140 cancel_control_transmit (ohh->th, ohh->tth);
141 GNUNET_CONTAINER_DLL_remove (th->oh_head,
142 th->oh_tail,
143 ohh);
144 GNUNET_free (ohh->msg);
145 GNUNET_free (ohh); 139 GNUNET_free (ohh);
146} 140}
147 141