diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-05-02 11:48:52 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-05-02 11:48:52 +0000 |
commit | f4b1f639e8799d29e823a7cd563a97d314d4f471 (patch) | |
tree | be4854b5c5591ea04b2de4032e554dc392f8d0e0 | |
parent | f1df9f057d50cd695ee3b86538f27306ea74369f (diff) | |
download | gnunet-f4b1f639e8799d29e823a7cd563a97d314d4f471.tar.gz gnunet-f4b1f639e8799d29e823a7cd563a97d314d4f471.zip |
fixing major issue with how IP addresses go over the network (previously ill-defined) -- thanks amatus
-rw-r--r-- | src/transport/gnunet-service-transport.c | 77 | ||||
-rw-r--r-- | src/transport/plugin_transport.h | 27 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 293 | ||||
-rw-r--r-- | src/transport/plugin_transport_template.c | 24 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.c | 325 | ||||
-rw-r--r-- | src/transport/test_plugin_transport_http.c | 16 |
6 files changed, 612 insertions, 150 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index bb6686a42..e927a11f5 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -45,9 +45,9 @@ | |||
45 | #include "plugin_transport.h" | 45 | #include "plugin_transport.h" |
46 | #include "transport.h" | 46 | #include "transport.h" |
47 | 47 | ||
48 | #define DEBUG_BLACKLIST GNUNET_NO | 48 | #define DEBUG_BLACKLIST GNUNET_YES |
49 | 49 | ||
50 | #define DEBUG_PING_PONG GNUNET_NO | 50 | #define DEBUG_PING_PONG GNUNET_YES |
51 | 51 | ||
52 | /** | 52 | /** |
53 | * Should we do some additional checks (to validate behavior | 53 | * Should we do some additional checks (to validate behavior |
@@ -1393,6 +1393,32 @@ transmit_send_continuation (void *cls, | |||
1393 | 1393 | ||
1394 | 1394 | ||
1395 | /** | 1395 | /** |
1396 | * Convert an address to a string. | ||
1397 | * | ||
1398 | * @param plugin name of the plugin responsible for the address | ||
1399 | * @param addr binary address | ||
1400 | * @param addr_len number of bytes in addr | ||
1401 | * @return NULL on error, otherwise address string | ||
1402 | */ | ||
1403 | static const char* | ||
1404 | a2s (const char *plugin, | ||
1405 | const void *addr, | ||
1406 | size_t addr_len) | ||
1407 | { | ||
1408 | struct TransportPlugin *p; | ||
1409 | |||
1410 | if (plugin == NULL) | ||
1411 | return NULL; | ||
1412 | p = find_transport (plugin); | ||
1413 | if (p == NULL) | ||
1414 | return NULL; | ||
1415 | return p->api->address_to_string (p->api->cls, | ||
1416 | addr, | ||
1417 | addr_len); | ||
1418 | } | ||
1419 | |||
1420 | |||
1421 | /** | ||
1396 | * Find an address in any of the available transports for | 1422 | * Find an address in any of the available transports for |
1397 | * the given neighbour that would be good for message | 1423 | * the given neighbour that would be good for message |
1398 | * transmission. This is essentially the transport selection | 1424 | * transmission. This is essentially the transport selection |
@@ -1439,8 +1465,9 @@ find_ready_address(struct NeighbourList *neighbour) | |||
1439 | if (addresses->addr != NULL) | 1465 | if (addresses->addr != NULL) |
1440 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1466 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1441 | "Have address `%s' for peer `%4s' (status: %d, %d, %d, %u, %llums, %u)\n", | 1467 | "Have address `%s' for peer `%4s' (status: %d, %d, %d, %u, %llums, %u)\n", |
1442 | GNUNET_a2s (addresses->addr, | 1468 | a2s (head->plugin->short_name, |
1443 | addresses->addrlen), | 1469 | addresses->addr, |
1470 | addresses->addrlen), | ||
1444 | GNUNET_i2s (&neighbour->id), | 1471 | GNUNET_i2s (&neighbour->id), |
1445 | addresses->connected, | 1472 | addresses->connected, |
1446 | addresses->in_transmit, | 1473 | addresses->in_transmit, |
@@ -1601,8 +1628,9 @@ try_transmission_to_peer (struct NeighbourList *neighbour) | |||
1601 | mq->message_buf_size, | 1628 | mq->message_buf_size, |
1602 | GNUNET_i2s (&neighbour->id), | 1629 | GNUNET_i2s (&neighbour->id), |
1603 | (mq->specific_address->addr != NULL) | 1630 | (mq->specific_address->addr != NULL) |
1604 | ? GNUNET_a2s (mq->specific_address->addr, | 1631 | ? a2s (mq->specific_address->plugin->short_name, |
1605 | mq->specific_address->addrlen) | 1632 | mq->specific_address->addr, |
1633 | mq->specific_address->addrlen) | ||
1606 | : "<inbound>", | 1634 | : "<inbound>", |
1607 | rl->plugin->short_name); | 1635 | rl->plugin->short_name); |
1608 | #endif | 1636 | #endif |
@@ -2426,7 +2454,7 @@ add_to_foreign_address_list (void *cls, | |||
2426 | #if DEBUG_TRANSPORT | 2454 | #if DEBUG_TRANSPORT |
2427 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2455 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2428 | "Adding address `%s' (%s) for peer `%4s' due to peerinfo data for %llums.\n", | 2456 | "Adding address `%s' (%s) for peer `%4s' due to peerinfo data for %llums.\n", |
2429 | GNUNET_a2s (addr, addrlen), | 2457 | a2s (tname, addr, addrlen), |
2430 | tname, | 2458 | tname, |
2431 | GNUNET_i2s (&n->id), | 2459 | GNUNET_i2s (&n->id), |
2432 | expiration.value); | 2460 | expiration.value); |
@@ -3001,8 +3029,9 @@ send_periodic_ping (void *cls, | |||
3001 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3029 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3002 | "Some validation of address `%s' via `%s' for peer `%4s' already in progress.\n", | 3030 | "Some validation of address `%s' via `%s' for peer `%4s' already in progress.\n", |
3003 | (peer_address->addr != NULL) | 3031 | (peer_address->addr != NULL) |
3004 | ? GNUNET_a2s (peer_address->addr, | 3032 | ? a2s (peer_address->plugin->short_name, |
3005 | peer_address->addrlen) | 3033 | peer_address->addr, |
3034 | peer_address->addrlen) | ||
3006 | : "<inbound>", | 3035 | : "<inbound>", |
3007 | tp->short_name, | 3036 | tp->short_name, |
3008 | GNUNET_i2s (&neighbour->id)); | 3037 | GNUNET_i2s (&neighbour->id)); |
@@ -3049,8 +3078,9 @@ send_periodic_ping (void *cls, | |||
3049 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3078 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3050 | "Performing re-validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n", | 3079 | "Performing re-validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n", |
3051 | (peer_address->addr != NULL) | 3080 | (peer_address->addr != NULL) |
3052 | ? GNUNET_a2s (peer_address->addr, | 3081 | ? a2s (peer_address->plugin->short_name, |
3053 | peer_address->addrlen) | 3082 | peer_address->addr, |
3083 | peer_address->addrlen) | ||
3054 | : "<inbound>", | 3084 | : "<inbound>", |
3055 | tp->short_name, | 3085 | tp->short_name, |
3056 | GNUNET_i2s (&neighbour->id), | 3086 | GNUNET_i2s (&neighbour->id), |
@@ -3231,8 +3261,9 @@ check_pending_validation (void *cls, | |||
3231 | "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", | 3261 | "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", |
3232 | GNUNET_h2s (key), | 3262 | GNUNET_h2s (key), |
3233 | (ve->addr != NULL) | 3263 | (ve->addr != NULL) |
3234 | ? GNUNET_a2s ((const struct sockaddr *) ve->addr, | 3264 | ? a2s (ve->transport_name, |
3235 | ve->addrlen) | 3265 | (const struct sockaddr *) ve->addr, |
3266 | ve->addrlen) | ||
3236 | : "<inbound>", | 3267 | : "<inbound>", |
3237 | ve->transport_name); | 3268 | ve->transport_name); |
3238 | #endif | 3269 | #endif |
@@ -3368,15 +3399,6 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message, | |||
3368 | return; | 3399 | return; |
3369 | } | 3400 | } |
3370 | 3401 | ||
3371 | #if 0 | ||
3372 | /* FIXME: add given address to potential pool of our addresses | ||
3373 | (for voting) */ | ||
3374 | GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, | ||
3375 | _("Another peer saw us using the address `%s' via `%s'.\n"), | ||
3376 | GNUNET_a2s ((const struct sockaddr *) &pong[1], | ||
3377 | ntohs(pong->addrlen)), | ||
3378 | va->transport_name); | ||
3379 | #endif | ||
3380 | } | 3402 | } |
3381 | 3403 | ||
3382 | 3404 | ||
@@ -3434,7 +3456,8 @@ transmit_hello_and_ping (void *cls, | |||
3434 | #if DEBUG_TRANSPORT | 3456 | #if DEBUG_TRANSPORT |
3435 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3457 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3436 | "Performing validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n", | 3458 | "Performing validation of address `%s' via `%s' for peer `%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n", |
3437 | GNUNET_a2s ((const void*) &va[1], va->addrlen), | 3459 | a2s (va->transport_name, |
3460 | (const void*) &va[1], va->addrlen), | ||
3438 | va->transport_name, | 3461 | va->transport_name, |
3439 | GNUNET_i2s (&neighbour->id), | 3462 | GNUNET_i2s (&neighbour->id), |
3440 | "HELLO", hello_size, | 3463 | "HELLO", hello_size, |
@@ -3548,7 +3571,7 @@ run_validation (void *cls, | |||
3548 | #if DEBUG_TRANSPORT > 1 | 3571 | #if DEBUG_TRANSPORT > 1 |
3549 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3572 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3550 | "Validation of address `%s' via `%s' for peer `%4s' already in progress.\n", | 3573 | "Validation of address `%s' via `%s' for peer `%4s' already in progress.\n", |
3551 | GNUNET_a2s (addr, addrlen), | 3574 | a2s (tname, addr, addrlen), |
3552 | tname, | 3575 | tname, |
3553 | GNUNET_i2s (&id)); | 3576 | GNUNET_i2s (&id)); |
3554 | #endif | 3577 | #endif |
@@ -3939,8 +3962,9 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message, | |||
3939 | "Processing `%s' from `%s'\n", | 3962 | "Processing `%s' from `%s'\n", |
3940 | "PING", | 3963 | "PING", |
3941 | (sender_address != NULL) | 3964 | (sender_address != NULL) |
3942 | ? GNUNET_a2s ((const struct sockaddr *)sender_address, | 3965 | ? a2s (plugin->short_name, |
3943 | sender_address_len) | 3966 | (const struct sockaddr *)sender_address, |
3967 | sender_address_len) | ||
3944 | : "<inbound>"); | 3968 | : "<inbound>"); |
3945 | #endif | 3969 | #endif |
3946 | GNUNET_STATISTICS_update (stats, | 3970 | GNUNET_STATISTICS_update (stats, |
@@ -4895,6 +4919,7 @@ run (void *cls, | |||
4895 | int | 4919 | int |
4896 | main (int argc, char *const *argv) | 4920 | main (int argc, char *const *argv) |
4897 | { | 4921 | { |
4922 | a2s (NULL, NULL, 0); /* make compiler happy */ | ||
4898 | return (GNUNET_OK == | 4923 | return (GNUNET_OK == |
4899 | GNUNET_SERVICE_run (argc, | 4924 | GNUNET_SERVICE_run (argc, |
4900 | argv, | 4925 | argv, |
diff --git a/src/transport/plugin_transport.h b/src/transport/plugin_transport.h index 2b7017036..034520cb3 100644 --- a/src/transport/plugin_transport.h +++ b/src/transport/plugin_transport.h | |||
@@ -346,6 +346,23 @@ typedef int | |||
346 | (*GNUNET_TRANSPORT_CheckAddress) (void *cls, | 346 | (*GNUNET_TRANSPORT_CheckAddress) (void *cls, |
347 | void *addr, size_t addrlen); | 347 | void *addr, size_t addrlen); |
348 | 348 | ||
349 | |||
350 | /** | ||
351 | * Function called for a quick conversion of the binary address to | ||
352 | * a numeric address. Note that the caller must not free the | ||
353 | * address and that the next call to this function is allowed | ||
354 | * to override the address again. | ||
355 | * | ||
356 | * @param cls closure | ||
357 | * @param addr binary address | ||
358 | * @param addr_len length of the address | ||
359 | * @return string representing the same address | ||
360 | */ | ||
361 | typedef const char* (*GNUNET_TRANSPORT_AddressToString) (void *cls, | ||
362 | const void *addr, | ||
363 | size_t addrlen); | ||
364 | |||
365 | |||
349 | /** | 366 | /** |
350 | * Each plugin is required to return a pointer to a struct of this | 367 | * Each plugin is required to return a pointer to a struct of this |
351 | * type as the return value from its entry point. | 368 | * type as the return value from its entry point. |
@@ -387,9 +404,19 @@ struct GNUNET_TRANSPORT_PluginFunctions | |||
387 | * Function that will be called to check if a binary address | 404 | * Function that will be called to check if a binary address |
388 | * for this plugin is well-formed. If clearly needed, patch | 405 | * for this plugin is well-formed. If clearly needed, patch |
389 | * up information such as port numbers. | 406 | * up information such as port numbers. |
407 | * FIXME: this API will likely change in the near future since | ||
408 | * it currently does not allow the size of the patched address | ||
409 | * to be different! | ||
390 | */ | 410 | */ |
391 | GNUNET_TRANSPORT_CheckAddress check_address; | 411 | GNUNET_TRANSPORT_CheckAddress check_address; |
392 | 412 | ||
413 | |||
414 | /** | ||
415 | * Function that will be called to convert a binary address | ||
416 | * to a string (numeric conversion only). | ||
417 | */ | ||
418 | GNUNET_TRANSPORT_AddressToString address_to_string; | ||
419 | |||
393 | }; | 420 | }; |
394 | 421 | ||
395 | 422 | ||
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index e71e751f6..2e7d3dadd 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -64,6 +64,42 @@ struct WelcomeMessage | |||
64 | 64 | ||
65 | 65 | ||
66 | /** | 66 | /** |
67 | * Network format for IPv4 addresses. | ||
68 | */ | ||
69 | struct IPv4TcpAddress | ||
70 | { | ||
71 | /** | ||
72 | * IPv4 address, in network byte order. | ||
73 | */ | ||
74 | uint32_t ipv4_addr; | ||
75 | |||
76 | /** | ||
77 | * Port number, in network byte order. | ||
78 | */ | ||
79 | uint16_t t_port; | ||
80 | |||
81 | }; | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Network format for IPv6 addresses. | ||
86 | */ | ||
87 | struct IPv6TcpAddress | ||
88 | { | ||
89 | /** | ||
90 | * IPv6 address. | ||
91 | */ | ||
92 | unsigned char ipv6_addr[16]; | ||
93 | |||
94 | /** | ||
95 | * Port number, in network byte order. | ||
96 | */ | ||
97 | uint16_t t6_port; | ||
98 | |||
99 | }; | ||
100 | |||
101 | |||
102 | /** | ||
67 | * Encapsulation of all of the state of the plugin. | 103 | * Encapsulation of all of the state of the plugin. |
68 | */ | 104 | */ |
69 | struct Plugin; | 105 | struct Plugin; |
@@ -262,6 +298,60 @@ struct Plugin | |||
262 | }; | 298 | }; |
263 | 299 | ||
264 | 300 | ||
301 | |||
302 | |||
303 | /** | ||
304 | * Function called for a quick conversion of the binary address to | ||
305 | * a numeric address. Note that the caller must not free the | ||
306 | * address and that the next call to this function is allowed | ||
307 | * to override the address again. | ||
308 | * | ||
309 | * @param cls closure ('struct Plugin*') | ||
310 | * @param addr binary address | ||
311 | * @param addr_len length of the address | ||
312 | * @return string representing the same address | ||
313 | */ | ||
314 | static const char* | ||
315 | tcp_address_to_string (void *cls, | ||
316 | const void *addr, | ||
317 | size_t addrlen) | ||
318 | { | ||
319 | static char buf[INET6_ADDRSTRLEN]; | ||
320 | const void *sb; | ||
321 | struct sockaddr_in a4; | ||
322 | struct sockaddr_in6 a6; | ||
323 | const struct IPv4TcpAddress *t4; | ||
324 | const struct IPv6TcpAddress *t6; | ||
325 | int af; | ||
326 | |||
327 | if (addrlen == sizeof (struct IPv6TcpAddress)) | ||
328 | { | ||
329 | t6 = addr; | ||
330 | af = AF_INET6; | ||
331 | memset (&a6, 0, sizeof (a6)); | ||
332 | a6.sin6_family = AF_INET6; | ||
333 | a6.sin6_port = t6->t6_port; | ||
334 | memcpy (a6.sin6_addr.s6_addr, | ||
335 | t6->ipv6_addr, | ||
336 | 16); | ||
337 | sb = &a6; | ||
338 | } | ||
339 | else if (addrlen == sizeof (struct IPv4TcpAddress)) | ||
340 | { | ||
341 | t4 = addr; | ||
342 | af = AF_INET; | ||
343 | memset (&a4, 0, sizeof (a4)); | ||
344 | a4.sin_family = AF_INET; | ||
345 | a4.sin_port = t4->t_port; | ||
346 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
347 | sb = &a4; | ||
348 | } | ||
349 | else | ||
350 | return NULL; | ||
351 | return inet_ntop (af, sb, buf, INET6_ADDRSTRLEN); | ||
352 | } | ||
353 | |||
354 | |||
265 | /** | 355 | /** |
266 | * Find the session handle for the given client. | 356 | * Find the session handle for the given client. |
267 | * | 357 | * |
@@ -520,8 +610,10 @@ disconnect_session (struct Session *session) | |||
520 | "Disconnecting from `%4s' at %s (session %p).\n", | 610 | "Disconnecting from `%4s' at %s (session %p).\n", |
521 | GNUNET_i2s (&session->target), | 611 | GNUNET_i2s (&session->target), |
522 | (session->connect_addr != NULL) ? | 612 | (session->connect_addr != NULL) ? |
523 | GNUNET_a2s (session->connect_addr, | 613 | tcp_address_to_string (session->plugin, |
524 | session->connect_alen) : "*", session); | 614 | session->connect_addr, |
615 | session->connect_alen) : "*", | ||
616 | session); | ||
525 | #endif | 617 | #endif |
526 | /* remove from session list */ | 618 | /* remove from session list */ |
527 | prev = NULL; | 619 | prev = NULL; |
@@ -680,6 +772,12 @@ tcp_plugin_send (void *cls, | |||
680 | struct PendingMessage *pm; | 772 | struct PendingMessage *pm; |
681 | struct GNUNET_CONNECTION_Handle *sa; | 773 | struct GNUNET_CONNECTION_Handle *sa; |
682 | int af; | 774 | int af; |
775 | const void *sb; | ||
776 | size_t sbs; | ||
777 | struct sockaddr_in a4; | ||
778 | struct sockaddr_in6 a6; | ||
779 | const struct IPv4TcpAddress *t4; | ||
780 | const struct IPv6TcpAddress *t6; | ||
683 | 781 | ||
684 | GNUNET_STATISTICS_update (plugin->env->stats, | 782 | GNUNET_STATISTICS_update (plugin->env->stats, |
685 | gettext_noop ("# bytes TCP was asked to transmit"), | 783 | gettext_noop ("# bytes TCP was asked to transmit"), |
@@ -746,13 +844,29 @@ tcp_plugin_send (void *cls, | |||
746 | } | 844 | } |
747 | if (session == NULL) | 845 | if (session == NULL) |
748 | { | 846 | { |
749 | if (sizeof (struct sockaddr_in) == addrlen) | 847 | if (addrlen == sizeof (struct IPv6TcpAddress)) |
750 | { | 848 | { |
751 | af = AF_INET; | 849 | t6 = addr; |
850 | af = AF_INET6; | ||
851 | memset (&a6, 0, sizeof (a6)); | ||
852 | a6.sin6_family = AF_INET6; | ||
853 | a6.sin6_port = t6->t6_port; | ||
854 | memcpy (a6.sin6_addr.s6_addr, | ||
855 | t6->ipv6_addr, | ||
856 | 16); | ||
857 | sb = &a6; | ||
858 | sbs = sizeof (a6); | ||
752 | } | 859 | } |
753 | else if (sizeof (struct sockaddr_in6) == addrlen) | 860 | else if (addrlen == sizeof (struct IPv4TcpAddress)) |
754 | { | 861 | { |
755 | af = AF_INET6; | 862 | t4 = addr; |
863 | af = AF_INET; | ||
864 | memset (&a4, 0, sizeof (a4)); | ||
865 | a4.sin_family = AF_INET; | ||
866 | a4.sin_port = t4->t_port; | ||
867 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
868 | sb = &a4; | ||
869 | sbs = sizeof (a4); | ||
756 | } | 870 | } |
757 | else | 871 | else |
758 | { | 872 | { |
@@ -760,7 +874,7 @@ tcp_plugin_send (void *cls, | |||
760 | return -1; | 874 | return -1; |
761 | } | 875 | } |
762 | sa = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched, | 876 | sa = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched, |
763 | af, addr, addrlen, | 877 | af, sb, sbs, |
764 | GNUNET_SERVER_MAX_MESSAGE_SIZE); | 878 | GNUNET_SERVER_MAX_MESSAGE_SIZE); |
765 | if (sa == NULL) | 879 | if (sa == NULL) |
766 | { | 880 | { |
@@ -769,7 +883,7 @@ tcp_plugin_send (void *cls, | |||
769 | "tcp", | 883 | "tcp", |
770 | "Failed to create connection to `%4s' at `%s'\n", | 884 | "Failed to create connection to `%4s' at `%s'\n", |
771 | GNUNET_i2s (target), | 885 | GNUNET_i2s (target), |
772 | GNUNET_a2s (addr, addrlen)); | 886 | GNUNET_a2s (sb, sbs)); |
773 | #endif | 887 | #endif |
774 | GNUNET_STATISTICS_update (plugin->env->stats, | 888 | GNUNET_STATISTICS_update (plugin->env->stats, |
775 | gettext_noop ("# bytes discarded by TCP (failed to connect)"), | 889 | gettext_noop ("# bytes discarded by TCP (failed to connect)"), |
@@ -782,7 +896,7 @@ tcp_plugin_send (void *cls, | |||
782 | "tcp", | 896 | "tcp", |
783 | "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", | 897 | "Asked to transmit to `%4s', creating fresh session using address `%s'.\n", |
784 | GNUNET_i2s (target), | 898 | GNUNET_i2s (target), |
785 | GNUNET_a2s (addr, addrlen)); | 899 | GNUNET_a2s (sb, sbs)); |
786 | #endif | 900 | #endif |
787 | session = create_session (plugin, | 901 | session = create_session (plugin, |
788 | target, | 902 | target, |
@@ -948,12 +1062,43 @@ tcp_plugin_address_pretty_printer (void *cls, | |||
948 | void *asc_cls) | 1062 | void *asc_cls) |
949 | { | 1063 | { |
950 | struct Plugin *plugin = cls; | 1064 | struct Plugin *plugin = cls; |
951 | const struct sockaddr_in *v4; | ||
952 | const struct sockaddr_in6 *v6; | ||
953 | struct PrettyPrinterContext *ppc; | 1065 | struct PrettyPrinterContext *ppc; |
1066 | const void *sb; | ||
1067 | size_t sbs; | ||
1068 | struct sockaddr_in a4; | ||
1069 | struct sockaddr_in6 a6; | ||
1070 | const struct IPv4TcpAddress *t4; | ||
1071 | const struct IPv6TcpAddress *t6; | ||
1072 | int af; | ||
1073 | uint16_t port; | ||
954 | 1074 | ||
955 | if ((addrlen != sizeof (struct sockaddr_in)) && | 1075 | if (addrlen == sizeof (struct IPv6TcpAddress)) |
956 | (addrlen != sizeof (struct sockaddr_in6))) | 1076 | { |
1077 | t6 = addr; | ||
1078 | af = AF_INET6; | ||
1079 | memset (&a6, 0, sizeof (a6)); | ||
1080 | a6.sin6_family = AF_INET6; | ||
1081 | a6.sin6_port = t6->t6_port; | ||
1082 | memcpy (a6.sin6_addr.s6_addr, | ||
1083 | t6->ipv6_addr, | ||
1084 | 16); | ||
1085 | port = ntohs (t6->t6_port); | ||
1086 | sb = &a6; | ||
1087 | sbs = sizeof (a6); | ||
1088 | } | ||
1089 | else if (addrlen == sizeof (struct IPv4TcpAddress)) | ||
1090 | { | ||
1091 | t4 = addr; | ||
1092 | af = AF_INET; | ||
1093 | memset (&a4, 0, sizeof (a4)); | ||
1094 | a4.sin_family = AF_INET; | ||
1095 | a4.sin_port = t4->t_port; | ||
1096 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
1097 | port = ntohs (t4->t_port); | ||
1098 | sb = &a4; | ||
1099 | sbs = sizeof (a4); | ||
1100 | } | ||
1101 | else | ||
957 | { | 1102 | { |
958 | /* invalid address */ | 1103 | /* invalid address */ |
959 | GNUNET_break_op (0); | 1104 | GNUNET_break_op (0); |
@@ -963,21 +1108,11 @@ tcp_plugin_address_pretty_printer (void *cls, | |||
963 | ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); | 1108 | ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); |
964 | ppc->asc = asc; | 1109 | ppc->asc = asc; |
965 | ppc->asc_cls = asc_cls; | 1110 | ppc->asc_cls = asc_cls; |
966 | if (addrlen == sizeof (struct sockaddr_in)) | 1111 | ppc->port = port; |
967 | { | ||
968 | v4 = (const struct sockaddr_in *) addr; | ||
969 | ppc->port = ntohs (v4->sin_port); | ||
970 | } | ||
971 | else | ||
972 | { | ||
973 | v6 = (const struct sockaddr_in6 *) addr; | ||
974 | ppc->port = ntohs (v6->sin6_port); | ||
975 | |||
976 | } | ||
977 | GNUNET_RESOLVER_hostname_get (plugin->env->sched, | 1112 | GNUNET_RESOLVER_hostname_get (plugin->env->sched, |
978 | plugin->env->cfg, | 1113 | plugin->env->cfg, |
979 | addr, | 1114 | sb, |
980 | addrlen, | 1115 | sbs, |
981 | !numeric, timeout, &append_port, ppc); | 1116 | !numeric, timeout, &append_port, ppc); |
982 | } | 1117 | } |
983 | 1118 | ||
@@ -1004,45 +1139,40 @@ check_port (struct Plugin *plugin, uint16_t in_port) | |||
1004 | 1139 | ||
1005 | /** | 1140 | /** |
1006 | * Another peer has suggested an address for this peer and transport | 1141 | * Another peer has suggested an address for this peer and transport |
1007 | * plugin. Check that this could be a valid address. | 1142 | * plugin. Check that this could be a valid address. This function |
1143 | * is not expected to 'validate' the address in the sense of trying to | ||
1144 | * connect to it but simply to see if the binary format is technically | ||
1145 | * legal for establishing a connection. | ||
1008 | * | 1146 | * |
1009 | * @param cls closure, our 'struct Plugin*' | 1147 | * @param cls closure, our 'struct Plugin*' |
1010 | * @param addr pointer to the address | 1148 | * @param addr pointer to the address |
1011 | * @param addrlen length of addr | 1149 | * @param addrlen length of addr |
1012 | * @return GNUNET_OK if this is a plausible address for this peer | 1150 | * @return GNUNET_OK if this is a plausible address for this peer |
1013 | * and transport | 1151 | * and transport, GNUNET_SYSERR if not |
1014 | */ | 1152 | */ |
1015 | static int | 1153 | static int |
1016 | tcp_plugin_check_address (void *cls, void *addr, size_t addrlen) | 1154 | tcp_plugin_check_address (void *cls, void *addr, size_t addrlen) |
1017 | { | 1155 | { |
1018 | struct Plugin *plugin = cls; | 1156 | struct Plugin *plugin = cls; |
1019 | char buf[sizeof (struct sockaddr_in6)]; | 1157 | struct IPv4TcpAddress *v4; |
1020 | struct sockaddr_in *v4; | 1158 | struct IPv6TcpAddress *v6; |
1021 | struct sockaddr_in6 *v6; | ||
1022 | 1159 | ||
1023 | if ((addrlen != sizeof (struct sockaddr_in)) && | 1160 | if ((addrlen != sizeof (struct IPv4TcpAddress)) && |
1024 | (addrlen != sizeof (struct sockaddr_in6))) | 1161 | (addrlen != sizeof (struct IPv6TcpAddress))) |
1025 | { | 1162 | { |
1026 | GNUNET_break_op (0); | 1163 | GNUNET_break_op (0); |
1027 | return GNUNET_SYSERR; | 1164 | return GNUNET_SYSERR; |
1028 | } | 1165 | } |
1029 | memcpy (buf, addr, sizeof (struct sockaddr_in6)); | 1166 | if (addrlen == sizeof (struct IPv4TcpAddress)) |
1030 | if (addrlen == sizeof (struct sockaddr_in)) | ||
1031 | { | 1167 | { |
1032 | v4 = (struct sockaddr_in *) buf; | 1168 | v4 = (struct IPv4TcpAddress *) addr; |
1033 | v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port))); | 1169 | v4->t_port = htons (check_port (plugin, ntohs (v4->t_port))); |
1034 | } | 1170 | } |
1035 | else | 1171 | else |
1036 | { | 1172 | { |
1037 | v6 = (struct sockaddr_in6 *) buf; | 1173 | v6 = (struct IPv6TcpAddress *) addr; |
1038 | v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port))); | 1174 | v6->t6_port = htons (check_port (plugin, ntohs (v6->t6_port))); |
1039 | } | 1175 | } |
1040 | #if DEBUG_TCP | ||
1041 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
1042 | "tcp", | ||
1043 | "Informing transport service about my address `%s'.\n", | ||
1044 | GNUNET_a2s (addr, addrlen)); | ||
1045 | #endif | ||
1046 | return GNUNET_OK; | 1176 | return GNUNET_OK; |
1047 | } | 1177 | } |
1048 | 1178 | ||
@@ -1065,6 +1195,11 @@ handle_tcp_welcome (void *cls, | |||
1065 | struct Session *session; | 1195 | struct Session *session; |
1066 | size_t alen; | 1196 | size_t alen; |
1067 | void *vaddr; | 1197 | void *vaddr; |
1198 | struct IPv4TcpAddress *t4; | ||
1199 | struct IPv6TcpAddress *t6; | ||
1200 | const struct sockaddr_in *s4; | ||
1201 | const struct sockaddr_in6 *s6; | ||
1202 | |||
1068 | 1203 | ||
1069 | #if DEBUG_TCP | 1204 | #if DEBUG_TCP |
1070 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | 1205 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1094,8 +1229,27 @@ handle_tcp_welcome (void *cls, | |||
1094 | GNUNET_a2s (vaddr, alen), | 1229 | GNUNET_a2s (vaddr, alen), |
1095 | client); | 1230 | client); |
1096 | #endif | 1231 | #endif |
1097 | session->connect_addr = vaddr; | 1232 | if (alen == sizeof (struct sockaddr_in)) |
1098 | session->connect_alen = alen; | 1233 | { |
1234 | s4 = vaddr; | ||
1235 | t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); | ||
1236 | t4->t_port = s4->sin_port; | ||
1237 | t4->ipv4_addr = s4->sin_addr.s_addr; | ||
1238 | session->connect_addr = t4; | ||
1239 | session->connect_alen = sizeof (struct IPv4TcpAddress); | ||
1240 | } | ||
1241 | else if (alen == sizeof (struct sockaddr_in6)) | ||
1242 | { | ||
1243 | s6 = vaddr; | ||
1244 | t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); | ||
1245 | t6->t6_port = s6->sin6_port; | ||
1246 | memcpy (t6->ipv6_addr, | ||
1247 | s6->sin6_addr.s6_addr, | ||
1248 | 16); | ||
1249 | session->connect_addr = t6; | ||
1250 | session->connect_alen = sizeof (struct IPv6TcpAddress); | ||
1251 | } | ||
1252 | GNUNET_free (vaddr); | ||
1099 | } | 1253 | } |
1100 | else | 1254 | else |
1101 | { | 1255 | { |
@@ -1227,7 +1381,8 @@ static struct GNUNET_SERVER_MessageHandler my_handlers[] = { | |||
1227 | * @param client identification of the client | 1381 | * @param client identification of the client |
1228 | */ | 1382 | */ |
1229 | static void | 1383 | static void |
1230 | disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) | 1384 | disconnect_notify (void *cls, |
1385 | struct GNUNET_SERVER_Client *client) | ||
1231 | { | 1386 | { |
1232 | struct Plugin *plugin = cls; | 1387 | struct Plugin *plugin = cls; |
1233 | struct Session *session; | 1388 | struct Session *session; |
@@ -1243,8 +1398,10 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) | |||
1243 | "Destroying session of `%4s' with %s (%p) due to network-level disconnect.\n", | 1398 | "Destroying session of `%4s' with %s (%p) due to network-level disconnect.\n", |
1244 | GNUNET_i2s (&session->target), | 1399 | GNUNET_i2s (&session->target), |
1245 | (session->connect_addr != NULL) ? | 1400 | (session->connect_addr != NULL) ? |
1246 | GNUNET_a2s (session->connect_addr, | 1401 | tcp_address_to_string (session->plugin, |
1247 | session->connect_alen) : "*", client); | 1402 | session->connect_addr, |
1403 | session->connect_alen) : "*", | ||
1404 | client); | ||
1248 | #endif | 1405 | #endif |
1249 | disconnect_session (session); | 1406 | disconnect_session (session); |
1250 | } | 1407 | } |
@@ -1259,6 +1416,7 @@ disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) | |||
1259 | * @param isDefault do we think this may be our default interface | 1416 | * @param isDefault do we think this may be our default interface |
1260 | * @param addr address of the interface | 1417 | * @param addr address of the interface |
1261 | * @param addrlen number of bytes in addr | 1418 | * @param addrlen number of bytes in addr |
1419 | * @return GNUNET_OK to continue iterating | ||
1262 | */ | 1420 | */ |
1263 | static int | 1421 | static int |
1264 | process_interfaces (void *cls, | 1422 | process_interfaces (void *cls, |
@@ -1268,28 +1426,41 @@ process_interfaces (void *cls, | |||
1268 | { | 1426 | { |
1269 | struct Plugin *plugin = cls; | 1427 | struct Plugin *plugin = cls; |
1270 | int af; | 1428 | int af; |
1271 | struct sockaddr_in *v4; | 1429 | struct IPv4TcpAddress t4; |
1272 | struct sockaddr_in6 *v6; | 1430 | struct IPv6TcpAddress t6; |
1431 | void *arg; | ||
1432 | uint16_t args; | ||
1273 | 1433 | ||
1274 | af = addr->sa_family; | 1434 | af = addr->sa_family; |
1275 | if (af == AF_INET) | 1435 | if (af == AF_INET) |
1276 | { | 1436 | { |
1277 | v4 = (struct sockaddr_in *) addr; | 1437 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
1278 | v4->sin_port = htons (plugin->adv_port); | 1438 | t4.t_port = htons (plugin->adv_port); |
1439 | arg = &t4; | ||
1440 | args = sizeof (t4); | ||
1441 | } | ||
1442 | else if (af == AF_INET6) | ||
1443 | { | ||
1444 | memcpy (t6.ipv6_addr, | ||
1445 | ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, | ||
1446 | 16); | ||
1447 | t6.t6_port = htons (plugin->adv_port); | ||
1448 | arg = &t6; | ||
1449 | args = sizeof (t6); | ||
1279 | } | 1450 | } |
1280 | else | 1451 | else |
1281 | { | 1452 | { |
1282 | GNUNET_assert (af == AF_INET6); | 1453 | GNUNET_break (0); |
1283 | v6 = (struct sockaddr_in6 *) addr; | 1454 | return GNUNET_OK; |
1284 | v6->sin6_port = htons (plugin->adv_port); | ||
1285 | } | 1455 | } |
1286 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | | 1456 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | |
1287 | GNUNET_ERROR_TYPE_BULK, | 1457 | GNUNET_ERROR_TYPE_BULK, |
1288 | "tcp", _("Found address `%s' (%s)\n"), | 1458 | "tcp", |
1459 | _("Found address `%s' (%s)\n"), | ||
1289 | GNUNET_a2s (addr, addrlen), name); | 1460 | GNUNET_a2s (addr, addrlen), name); |
1290 | plugin->env->notify_address (plugin->env->cls, | 1461 | plugin->env->notify_address (plugin->env->cls, |
1291 | "tcp", | 1462 | "tcp", |
1292 | addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL); | 1463 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); |
1293 | return GNUNET_OK; | 1464 | return GNUNET_OK; |
1294 | } | 1465 | } |
1295 | 1466 | ||
@@ -1320,6 +1491,9 @@ process_hostname_ips (void *cls, | |||
1320 | 1491 | ||
1321 | /** | 1492 | /** |
1322 | * Entry point for the plugin. | 1493 | * Entry point for the plugin. |
1494 | * | ||
1495 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' | ||
1496 | * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error | ||
1323 | */ | 1497 | */ |
1324 | void * | 1498 | void * |
1325 | libgnunet_plugin_transport_tcp_init (void *cls) | 1499 | libgnunet_plugin_transport_tcp_init (void *cls) |
@@ -1377,6 +1551,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) | |||
1377 | api->disconnect = &tcp_plugin_disconnect; | 1551 | api->disconnect = &tcp_plugin_disconnect; |
1378 | api->address_pretty_printer = &tcp_plugin_address_pretty_printer; | 1552 | api->address_pretty_printer = &tcp_plugin_address_pretty_printer; |
1379 | api->check_address = &tcp_plugin_check_address; | 1553 | api->check_address = &tcp_plugin_check_address; |
1554 | api->address_to_string = &tcp_address_to_string; | ||
1380 | plugin->service = service; | 1555 | plugin->service = service; |
1381 | plugin->server = GNUNET_SERVICE_get_server (service); | 1556 | plugin->server = GNUNET_SERVICE_get_server (service); |
1382 | plugin->handlers = GNUNET_malloc (sizeof (my_handlers)); | 1557 | plugin->handlers = GNUNET_malloc (sizeof (my_handlers)); |
diff --git a/src/transport/plugin_transport_template.c b/src/transport/plugin_transport_template.c index f09503b9b..1ca4d018f 100644 --- a/src/transport/plugin_transport_template.c +++ b/src/transport/plugin_transport_template.c | |||
@@ -248,6 +248,29 @@ template_plugin_address_suggested (void *cls, | |||
248 | 248 | ||
249 | 249 | ||
250 | /** | 250 | /** |
251 | * Function called for a quick conversion of the binary address to | ||
252 | * a numeric address. Note that the caller must not free the | ||
253 | * address and that the next call to this function is allowed | ||
254 | * to override the address again. | ||
255 | * | ||
256 | * @param cls closure | ||
257 | * @param addr binary address | ||
258 | * @param addr_len length of the address | ||
259 | * @return string representing the same address | ||
260 | */ | ||
261 | static const char* | ||
262 | template_plugin_address_to_string (void *cls, | ||
263 | const void *addr, | ||
264 | size_t addrlen) | ||
265 | { | ||
266 | GNUNET_break (0); | ||
267 | return NULL; | ||
268 | } | ||
269 | |||
270 | |||
271 | |||
272 | |||
273 | /** | ||
251 | * Entry point for the plugin. | 274 | * Entry point for the plugin. |
252 | */ | 275 | */ |
253 | void * | 276 | void * |
@@ -266,6 +289,7 @@ gnunet_plugin_transport_template_init (void *cls) | |||
266 | api->disconnect = &template_plugin_disconnect; | 289 | api->disconnect = &template_plugin_disconnect; |
267 | api->address_pretty_printer = &template_plugin_address_pretty_printer; | 290 | api->address_pretty_printer = &template_plugin_address_pretty_printer; |
268 | api->check_address = &template_plugin_address_suggested; | 291 | api->check_address = &template_plugin_address_suggested; |
292 | api->address_to_string = &template_plugin_address_to_string; | ||
269 | return api; | 293 | return api; |
270 | } | 294 | } |
271 | 295 | ||
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 3e59f89dc..c7be2e18e 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -71,13 +71,64 @@ struct UDPMessage | |||
71 | }; | 71 | }; |
72 | 72 | ||
73 | 73 | ||
74 | /** | ||
75 | * Network format for IPv4 addresses. | ||
76 | */ | ||
77 | struct IPv4UdpAddress | ||
78 | { | ||
79 | /** | ||
80 | * IPv4 address, in network byte order. | ||
81 | */ | ||
82 | uint32_t ipv4_addr; | ||
83 | |||
84 | /** | ||
85 | * Port number, in network byte order. | ||
86 | */ | ||
87 | uint16_t u_port; | ||
88 | |||
89 | }; | ||
90 | |||
91 | |||
92 | /** | ||
93 | * Network format for IPv6 addresses. | ||
94 | */ | ||
95 | struct IPv6UdpAddress | ||
96 | { | ||
97 | /** | ||
98 | * IPv6 address. | ||
99 | */ | ||
100 | unsigned char ipv6_addr[16]; | ||
101 | |||
102 | /** | ||
103 | * Port number, in network byte order. | ||
104 | */ | ||
105 | uint16_t u6_port; | ||
106 | |||
107 | }; | ||
108 | |||
109 | |||
110 | /** | ||
111 | * | ||
112 | */ | ||
74 | struct PrettyPrinterContext | 113 | struct PrettyPrinterContext |
75 | { | 114 | { |
115 | /** | ||
116 | * | ||
117 | */ | ||
76 | GNUNET_TRANSPORT_AddressStringCallback asc; | 118 | GNUNET_TRANSPORT_AddressStringCallback asc; |
119 | |||
120 | /** | ||
121 | * Closure for 'asc'. | ||
122 | */ | ||
77 | void *asc_cls; | 123 | void *asc_cls; |
124 | |||
125 | /** | ||
126 | * | ||
127 | */ | ||
78 | uint16_t port; | 128 | uint16_t port; |
79 | }; | 129 | }; |
80 | 130 | ||
131 | |||
81 | /** | 132 | /** |
82 | * Encapsulation of all of the state of the plugin. | 133 | * Encapsulation of all of the state of the plugin. |
83 | */ | 134 | */ |
@@ -134,7 +185,7 @@ struct Plugin | |||
134 | /* *********** globals ************* */ | 185 | /* *********** globals ************* */ |
135 | 186 | ||
136 | /** | 187 | /** |
137 | * the socket that we transmit all data with | 188 | * The socket that we transmit all data with |
138 | */ | 189 | */ |
139 | static struct GNUNET_NETWORK_Handle *udp_sock; | 190 | static struct GNUNET_NETWORK_Handle *udp_sock; |
140 | 191 | ||
@@ -146,7 +197,8 @@ static struct GNUNET_NETWORK_Handle *udp_sock; | |||
146 | * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed | 197 | * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed |
147 | */ | 198 | */ |
148 | void | 199 | void |
149 | udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | 200 | udp_disconnect (void *cls, |
201 | const struct GNUNET_PeerIdentity *target) | ||
150 | { | 202 | { |
151 | /* nothing to do, UDP is stateless */ | 203 | /* nothing to do, UDP is stateless */ |
152 | } | 204 | } |
@@ -154,6 +206,8 @@ udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | |||
154 | /** | 206 | /** |
155 | * Shutdown the server process (stop receiving inbound traffic). Maybe | 207 | * Shutdown the server process (stop receiving inbound traffic). Maybe |
156 | * restarted later! | 208 | * restarted later! |
209 | * | ||
210 | * @param cls closure, the 'struct Plugin*' | ||
157 | */ | 211 | */ |
158 | static int | 212 | static int |
159 | udp_transport_server_stop (void *cls) | 213 | udp_transport_server_stop (void *cls) |
@@ -178,7 +232,7 @@ udp_transport_server_stop (void *cls) | |||
178 | * Function that can be used by the transport service to transmit | 232 | * Function that can be used by the transport service to transmit |
179 | * a message using the plugin. | 233 | * a message using the plugin. |
180 | * | 234 | * |
181 | * @param cls closure | 235 | * @param cls closure, the 'struct Plugin*' |
182 | * @param target who should receive this message (ignored by UDP) | 236 | * @param target who should receive this message (ignored by UDP) |
183 | * @param msgbuf one or more GNUNET_MessageHeader(s) strung together | 237 | * @param msgbuf one or more GNUNET_MessageHeader(s) strung together |
184 | * @param msgbuf_size the size of the msgbuf to send | 238 | * @param msgbuf_size the size of the msgbuf to send |
@@ -217,6 +271,13 @@ udp_plugin_send (void *cls, | |||
217 | struct UDPMessage *message; | 271 | struct UDPMessage *message; |
218 | int ssize; | 272 | int ssize; |
219 | ssize_t sent; | 273 | ssize_t sent; |
274 | int af; | ||
275 | const void *sb; | ||
276 | size_t sbs; | ||
277 | struct sockaddr_in a4; | ||
278 | struct sockaddr_in6 a6; | ||
279 | const struct IPv4UdpAddress *t4; | ||
280 | const struct IPv6UdpAddress *t6; | ||
220 | 281 | ||
221 | GNUNET_assert (NULL == session); | 282 | GNUNET_assert (NULL == session); |
222 | GNUNET_assert(udp_sock != NULL); | 283 | GNUNET_assert(udp_sock != NULL); |
@@ -231,13 +292,45 @@ udp_plugin_send (void *cls, | |||
231 | if (force_address == GNUNET_SYSERR) | 292 | if (force_address == GNUNET_SYSERR) |
232 | return -1; /* never reliable */ | 293 | return -1; /* never reliable */ |
233 | 294 | ||
295 | if (addrlen == sizeof (struct IPv6UdpAddress)) | ||
296 | { | ||
297 | t6 = addr; | ||
298 | af = AF_INET6; | ||
299 | memset (&a6, 0, sizeof (a6)); | ||
300 | a6.sin6_family = AF_INET6; | ||
301 | a6.sin6_port = t6->u6_port; | ||
302 | memcpy (a6.sin6_addr.s6_addr, | ||
303 | t6->ipv6_addr, | ||
304 | 16); | ||
305 | sb = &a6; | ||
306 | sbs = sizeof (a6); | ||
307 | } | ||
308 | else if (addrlen == sizeof (struct IPv4UdpAddress)) | ||
309 | { | ||
310 | t4 = addr; | ||
311 | af = AF_INET; | ||
312 | memset (&a4, 0, sizeof (a4)); | ||
313 | a4.sin_family = AF_INET; | ||
314 | a4.sin_port = t4->u_port; | ||
315 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
316 | sb = &a4; | ||
317 | sbs = sizeof (a4); | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | GNUNET_break_op (0); | ||
322 | return -1; | ||
323 | } | ||
324 | |||
234 | /* Build the message to be sent */ | 325 | /* Build the message to be sent */ |
235 | message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size); | 326 | message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size); |
236 | ssize = sizeof (struct UDPMessage) + msgbuf_size; | 327 | ssize = sizeof (struct UDPMessage) + msgbuf_size; |
237 | 328 | ||
238 | #if DEBUG_UDP | 329 | #if DEBUG_UDP |
239 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ | 330 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", |
240 | ("In udp_send, ssize is %d, sending message to %s\n"), ssize, GNUNET_a2s((const struct sockaddr *)addr, addrlen)); | 331 | "In udp_send, ssize is %d, sending message to `%s'\n", |
332 | ssize, | ||
333 | GNUNET_a2s(sb, sbs)); | ||
241 | #endif | 334 | #endif |
242 | message->header.size = htons (ssize); | 335 | message->header.size = htons (ssize); |
243 | message->header.type = htons (0); | 336 | message->header.type = htons (0); |
@@ -246,8 +339,7 @@ udp_plugin_send (void *cls, | |||
246 | memcpy (&message[1], msgbuf, msgbuf_size); | 339 | memcpy (&message[1], msgbuf, msgbuf_size); |
247 | sent = | 340 | sent = |
248 | GNUNET_NETWORK_socket_sendto (udp_sock, message, ssize, | 341 | GNUNET_NETWORK_socket_sendto (udp_sock, message, ssize, |
249 | addr, | 342 | sb, sbs); |
250 | addrlen); | ||
251 | if ( (cont != NULL) && | 343 | if ( (cont != NULL) && |
252 | (sent != -1) ) | 344 | (sent != -1) ) |
253 | cont (cont_cls, target, GNUNET_OK); | 345 | cont (cont_cls, target, GNUNET_OK); |
@@ -259,6 +351,13 @@ udp_plugin_send (void *cls, | |||
259 | /** | 351 | /** |
260 | * Add the IP of our network interface to the list of | 352 | * Add the IP of our network interface to the list of |
261 | * our external IP addresses. | 353 | * our external IP addresses. |
354 | * | ||
355 | * @param cls closure (the 'struct Plugin*') | ||
356 | * @param name name of the interface (can be NULL for unknown) | ||
357 | * @param isDefault is this presumably the default interface | ||
358 | * @param addr address of this interface (can be NULL for unknown or unassigned) | ||
359 | * @param addrlen length of the address | ||
360 | * @return GNUNET_OK to continue iterating | ||
262 | */ | 361 | */ |
263 | static int | 362 | static int |
264 | process_interfaces (void *cls, | 363 | process_interfaces (void *cls, |
@@ -268,29 +367,42 @@ process_interfaces (void *cls, | |||
268 | { | 367 | { |
269 | struct Plugin *plugin = cls; | 368 | struct Plugin *plugin = cls; |
270 | int af; | 369 | int af; |
271 | struct sockaddr_in *v4; | 370 | struct IPv4UdpAddress t4; |
272 | struct sockaddr_in6 *v6; | 371 | struct IPv6UdpAddress t6; |
372 | void *arg; | ||
373 | uint16_t args; | ||
273 | 374 | ||
274 | af = addr->sa_family; | 375 | af = addr->sa_family; |
275 | if (af == AF_INET) | 376 | if (af == AF_INET) |
276 | { | 377 | { |
277 | v4 = (struct sockaddr_in *) addr; | 378 | t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; |
278 | v4->sin_port = htons (plugin->adv_port); | 379 | t4.u_port = htons (plugin->adv_port); |
380 | arg = &t4; | ||
381 | args = sizeof (t4); | ||
382 | } | ||
383 | else if (af == AF_INET6) | ||
384 | { | ||
385 | memcpy (t6.ipv6_addr, | ||
386 | ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr, | ||
387 | 16); | ||
388 | t6.u6_port = htons (plugin->adv_port); | ||
389 | arg = &t6; | ||
390 | args = sizeof (t6); | ||
279 | } | 391 | } |
280 | else | 392 | else |
281 | { | 393 | { |
282 | GNUNET_assert (af == AF_INET6); | 394 | GNUNET_break (0); |
283 | v6 = (struct sockaddr_in6 *) addr; | 395 | return GNUNET_OK; |
284 | v6->sin6_port = htons (plugin->adv_port); | ||
285 | } | 396 | } |
286 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | | 397 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO | |
287 | GNUNET_ERROR_TYPE_BULK, | 398 | GNUNET_ERROR_TYPE_BULK, |
288 | "udp", _("Found address `%s' (%s)\n"), | 399 | "udp", |
289 | GNUNET_a2s (addr, addrlen), name); | 400 | _("Found address `%s' (%s)\n"), |
401 | GNUNET_a2s (addr, addrlen), | ||
402 | name); | ||
290 | plugin->env->notify_address (plugin->env->cls, | 403 | plugin->env->notify_address (plugin->env->cls, |
291 | "udp", | 404 | "udp", |
292 | addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL); | 405 | arg, args, GNUNET_TIME_UNIT_FOREVER_REL); |
293 | |||
294 | return GNUNET_OK; | 406 | return GNUNET_OK; |
295 | } | 407 | } |
296 | 408 | ||
@@ -346,6 +458,12 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
346 | int tsize; | 458 | int tsize; |
347 | char *msgbuf; | 459 | char *msgbuf; |
348 | const struct GNUNET_MessageHeader *currhdr; | 460 | const struct GNUNET_MessageHeader *currhdr; |
461 | struct IPv4UdpAddress t4; | ||
462 | struct IPv6UdpAddress t6; | ||
463 | const struct sockaddr_in *s4; | ||
464 | const struct sockaddr_in6 *s6; | ||
465 | const void *ca; | ||
466 | size_t calen; | ||
349 | 467 | ||
350 | #if DEBUG_UDP | 468 | #if DEBUG_UDP |
351 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ | 469 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ |
@@ -411,6 +529,31 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
411 | ("offset is %d, tsize is %d (UDPMessage size is %d)\n"), | 529 | ("offset is %d, tsize is %d (UDPMessage size is %d)\n"), |
412 | offset, tsize, sizeof(struct UDPMessage)); | 530 | offset, tsize, sizeof(struct UDPMessage)); |
413 | #endif | 531 | #endif |
532 | |||
533 | if (fromlen == sizeof (struct sockaddr_in)) | ||
534 | { | ||
535 | s4 = (const struct sockaddr_in*) &addr; | ||
536 | t4.u_port = s4->sin_port; | ||
537 | t4.ipv4_addr = s4->sin_addr.s_addr; | ||
538 | ca = &t4; | ||
539 | calen = sizeof (struct IPv4UdpAddress); | ||
540 | } | ||
541 | else if (fromlen == sizeof (struct sockaddr_in6)) | ||
542 | { | ||
543 | s6 = (const struct sockaddr_in6*) &addr; | ||
544 | t6.u6_port = s6->sin6_port; | ||
545 | memcpy (t6.ipv6_addr, | ||
546 | s6->sin6_addr.s6_addr, | ||
547 | 16); | ||
548 | ca = &t6; | ||
549 | calen = sizeof (struct IPv6UdpAddress); | ||
550 | } | ||
551 | else | ||
552 | { | ||
553 | GNUNET_break (0); | ||
554 | ca = NULL; | ||
555 | calen = 0; | ||
556 | } | ||
414 | while (offset < tsize) | 557 | while (offset < tsize) |
415 | { | 558 | { |
416 | currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset]; | 559 | currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset]; |
@@ -421,7 +564,7 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
421 | #endif | 564 | #endif |
422 | plugin->env->receive (plugin->env->cls, | 565 | plugin->env->receive (plugin->env->cls, |
423 | sender, currhdr, UDP_DIRECT_DISTANCE, | 566 | sender, currhdr, UDP_DIRECT_DISTANCE, |
424 | NULL, (const char *)&addr, fromlen); | 567 | NULL, ca, calen); |
425 | offset += ntohs(currhdr->size); | 568 | offset += ntohs(currhdr->size); |
426 | #if DEBUG_UDP | 569 | #if DEBUG_UDP |
427 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ | 570 | GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _ |
@@ -446,6 +589,7 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
446 | /** | 589 | /** |
447 | * Create a UDP socket. If possible, use IPv6, otherwise | 590 | * Create a UDP socket. If possible, use IPv6, otherwise |
448 | * try IPv4. | 591 | * try IPv4. |
592 | * @param cls closure, the 'struct Plugin*' | ||
449 | */ | 593 | */ |
450 | static struct GNUNET_NETWORK_Handle * | 594 | static struct GNUNET_NETWORK_Handle * |
451 | udp_transport_server_start (void *cls) | 595 | udp_transport_server_start (void *cls) |
@@ -550,43 +694,30 @@ check_port (struct Plugin *plugin, uint16_t in_port) | |||
550 | * @param addrlen length of addr | 694 | * @param addrlen length of addr |
551 | * @return GNUNET_OK if this is a plausible address for this peer | 695 | * @return GNUNET_OK if this is a plausible address for this peer |
552 | * and transport, GNUNET_SYSERR if not | 696 | * and transport, GNUNET_SYSERR if not |
553 | * | ||
554 | * TODO: perhaps make everything work with sockaddr_storage, it may | ||
555 | * be a cleaner way to handle addresses in UDP | ||
556 | */ | 697 | */ |
557 | static int | 698 | static int |
558 | udp_check_address (void *cls, void *addr, size_t addrlen) | 699 | udp_check_address (void *cls, void *addr, size_t addrlen) |
559 | { | 700 | { |
560 | struct Plugin *plugin = cls; | 701 | struct Plugin *plugin = cls; |
561 | char buf[sizeof (struct sockaddr_in6)]; | 702 | struct IPv4UdpAddress *v4; |
562 | 703 | struct IPv6UdpAddress *v6; | |
563 | struct sockaddr_in *v4; | ||
564 | struct sockaddr_in6 *v6; | ||
565 | 704 | ||
566 | if ((addrlen != sizeof (struct sockaddr_in)) && | 705 | if ((addrlen != sizeof (struct IPv4UdpAddress)) && |
567 | (addrlen != sizeof (struct sockaddr_in6))) | 706 | (addrlen != sizeof (struct IPv6UdpAddress))) |
568 | { | 707 | { |
569 | GNUNET_break_op (0); | 708 | GNUNET_break_op (0); |
570 | return GNUNET_SYSERR; | 709 | return GNUNET_SYSERR; |
571 | } | 710 | } |
572 | memcpy (buf, addr, sizeof (struct sockaddr_in6)); | 711 | if (addrlen == sizeof (struct IPv4UdpAddress)) |
573 | if (addrlen == sizeof (struct sockaddr_in)) | ||
574 | { | 712 | { |
575 | v4 = (struct sockaddr_in *) buf; | 713 | v4 = (struct IPv4UdpAddress *) addr; |
576 | v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port))); | 714 | v4->u_port = htons (check_port (plugin, ntohs (v4->u_port))); |
577 | } | 715 | } |
578 | else | 716 | else |
579 | { | 717 | { |
580 | v6 = (struct sockaddr_in6 *) buf; | 718 | v6 = (struct IPv6UdpAddress *) addr; |
581 | v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port))); | 719 | v6->u6_port = htons (check_port (plugin, ntohs (v6->u6_port))); |
582 | } | 720 | } |
583 | #if DEBUG_UDP | ||
584 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, | ||
585 | "tcp", | ||
586 | "Informing transport service about my address `%s'.\n", | ||
587 | GNUNET_a2s (addr, addrlen)); | ||
588 | #endif | ||
589 | return GNUNET_OK; | ||
590 | return GNUNET_OK; | 721 | return GNUNET_OK; |
591 | } | 722 | } |
592 | 723 | ||
@@ -637,12 +768,43 @@ udp_plugin_address_pretty_printer (void *cls, | |||
637 | void *asc_cls) | 768 | void *asc_cls) |
638 | { | 769 | { |
639 | struct Plugin *plugin = cls; | 770 | struct Plugin *plugin = cls; |
640 | const struct sockaddr_in *v4; | ||
641 | const struct sockaddr_in6 *v6; | ||
642 | struct PrettyPrinterContext *ppc; | 771 | struct PrettyPrinterContext *ppc; |
772 | const void *sb; | ||
773 | struct sockaddr_in a4; | ||
774 | struct sockaddr_in6 a6; | ||
775 | const struct IPv4UdpAddress *t4; | ||
776 | const struct IPv6UdpAddress *t6; | ||
777 | int af; | ||
778 | size_t sbs; | ||
779 | uint16_t port; | ||
643 | 780 | ||
644 | if ((addrlen != sizeof (struct sockaddr_in)) && | 781 | if (addrlen == sizeof (struct IPv6UdpAddress)) |
645 | (addrlen != sizeof (struct sockaddr_in6))) | 782 | { |
783 | t6 = addr; | ||
784 | af = AF_INET6; | ||
785 | memset (&a6, 0, sizeof (a6)); | ||
786 | a6.sin6_family = AF_INET6; | ||
787 | a6.sin6_port = t6->u6_port; | ||
788 | port = ntohs (t6->u6_port); | ||
789 | memcpy (a6.sin6_addr.s6_addr, | ||
790 | t6->ipv6_addr, | ||
791 | 16); | ||
792 | sb = &a6; | ||
793 | sbs = sizeof (a6); | ||
794 | } | ||
795 | else if (addrlen == sizeof (struct IPv4UdpAddress)) | ||
796 | { | ||
797 | t4 = addr; | ||
798 | af = AF_INET; | ||
799 | memset (&a4, 0, sizeof (a4)); | ||
800 | a4.sin_family = AF_INET; | ||
801 | a4.sin_port = t4->u_port; | ||
802 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
803 | port = ntohs (t4->u_port); | ||
804 | sb = &a4; | ||
805 | sbs = sizeof (a4); | ||
806 | } | ||
807 | else | ||
646 | { | 808 | { |
647 | /* invalid address */ | 809 | /* invalid address */ |
648 | GNUNET_break_op (0); | 810 | GNUNET_break_op (0); |
@@ -652,28 +814,75 @@ udp_plugin_address_pretty_printer (void *cls, | |||
652 | ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); | 814 | ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext)); |
653 | ppc->asc = asc; | 815 | ppc->asc = asc; |
654 | ppc->asc_cls = asc_cls; | 816 | ppc->asc_cls = asc_cls; |
655 | if (addrlen == sizeof (struct sockaddr_in)) | 817 | ppc->port = port; |
818 | GNUNET_RESOLVER_hostname_get (plugin->env->sched, | ||
819 | plugin->env->cfg, | ||
820 | sb, | ||
821 | sbs, | ||
822 | !numeric, timeout, &append_port, ppc); | ||
823 | } | ||
824 | |||
825 | |||
826 | |||
827 | /** | ||
828 | * Function called for a quick conversion of the binary address to | ||
829 | * a numeric address. Note that the caller must not free the | ||
830 | * address and that the next call to this function is allowed | ||
831 | * to override the address again. | ||
832 | * | ||
833 | * @param cls closure | ||
834 | * @param addr binary address | ||
835 | * @param addr_len length of the address | ||
836 | * @return string representing the same address | ||
837 | */ | ||
838 | static const char* | ||
839 | udp_address_to_string (void *cls, | ||
840 | const void *addr, | ||
841 | size_t addrlen) | ||
842 | { | ||
843 | static char buf[INET6_ADDRSTRLEN]; | ||
844 | const void *sb; | ||
845 | struct sockaddr_in a4; | ||
846 | struct sockaddr_in6 a6; | ||
847 | const struct IPv4UdpAddress *t4; | ||
848 | const struct IPv6UdpAddress *t6; | ||
849 | int af; | ||
850 | |||
851 | if (addrlen == sizeof (struct IPv6UdpAddress)) | ||
656 | { | 852 | { |
657 | v4 = (const struct sockaddr_in *) addr; | 853 | t6 = addr; |
658 | ppc->port = ntohs (v4->sin_port); | 854 | af = AF_INET6; |
855 | memset (&a6, 0, sizeof (a6)); | ||
856 | a6.sin6_family = AF_INET6; | ||
857 | a6.sin6_port = t6->u6_port; | ||
858 | memcpy (a6.sin6_addr.s6_addr, | ||
859 | t6->ipv6_addr, | ||
860 | 16); | ||
861 | sb = &a6; | ||
659 | } | 862 | } |
660 | else | 863 | else if (addrlen == sizeof (struct IPv4UdpAddress)) |
661 | { | 864 | { |
662 | v6 = (const struct sockaddr_in6 *) addr; | 865 | t4 = addr; |
663 | ppc->port = ntohs (v6->sin6_port); | 866 | af = AF_INET; |
664 | 867 | memset (&a4, 0, sizeof (a4)); | |
868 | a4.sin_family = AF_INET; | ||
869 | a4.sin_port = t4->u_port; | ||
870 | a4.sin_addr.s_addr = t4->ipv4_addr; | ||
871 | sb = &a4; | ||
665 | } | 872 | } |
666 | GNUNET_RESOLVER_hostname_get (plugin->env->sched, | 873 | else |
667 | plugin->env->cfg, | 874 | return NULL; |
668 | addr, | 875 | |
669 | addrlen, | 876 | return inet_ntop (af, sb, buf, INET6_ADDRSTRLEN); |
670 | !numeric, timeout, &append_port, ppc); | ||
671 | } | 877 | } |
672 | 878 | ||
673 | 879 | ||
674 | /** | 880 | /** |
675 | * The exported method. Makes the core api available via a global and | 881 | * The exported method. Makes the core api available via a global and |
676 | * returns the udp transport API. | 882 | * returns the udp transport API. |
883 | * | ||
884 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' | ||
885 | * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error | ||
677 | */ | 886 | */ |
678 | void * | 887 | void * |
679 | libgnunet_plugin_transport_udp_init (void *cls) | 888 | libgnunet_plugin_transport_udp_init (void *cls) |
@@ -737,7 +946,7 @@ libgnunet_plugin_transport_udp_init (void *cls) | |||
737 | api->disconnect = &udp_disconnect; | 946 | api->disconnect = &udp_disconnect; |
738 | api->address_pretty_printer = &udp_plugin_address_pretty_printer; | 947 | api->address_pretty_printer = &udp_plugin_address_pretty_printer; |
739 | api->check_address = &udp_check_address; | 948 | api->check_address = &udp_check_address; |
740 | 949 | api->address_to_string = &udp_address_to_string; | |
741 | plugin->service = service; | 950 | plugin->service = service; |
742 | 951 | ||
743 | /* FIXME: do the two calls below periodically again and | 952 | /* FIXME: do the two calls below periodically again and |
diff --git a/src/transport/test_plugin_transport_http.c b/src/transport/test_plugin_transport_http.c index 1e9f36286..328e70683 100644 --- a/src/transport/test_plugin_transport_http.c +++ b/src/transport/test_plugin_transport_http.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "plugin_transport.h" | 36 | #include "plugin_transport.h" |
37 | #include "transport.h" | 37 | #include "transport.h" |
38 | 38 | ||
39 | #define VERBOSE GNUNET_YES | 39 | #define VERBOSE GNUNET_NO |
40 | 40 | ||
41 | /** | 41 | /** |
42 | * How long until we give up on transmitting the message? | 42 | * How long until we give up on transmitting the message? |
@@ -91,15 +91,17 @@ static int ok; | |||
91 | /** | 91 | /** |
92 | * Initialize Environment for this plugin | 92 | * Initialize Environment for this plugin |
93 | */ | 93 | */ |
94 | static void | 94 | static struct GNUNET_TIME_Relative |
95 | receive (void *cls, | 95 | receive (void *cls, |
96 | const struct GNUNET_PeerIdentity * peer, | 96 | const struct GNUNET_PeerIdentity * peer, |
97 | const struct GNUNET_MessageHeader * message, | 97 | const struct GNUNET_MessageHeader * message, |
98 | uint32_t distance, | 98 | uint32_t distance, |
99 | const char *sender_address, | 99 | struct Session *session, |
100 | size_t sender_address_len) | 100 | const char *sender_address, |
101 | size_t sender_address_len) | ||
101 | { | 102 | { |
102 | /* do nothing */ | 103 | /* do nothing */ |
104 | return GNUNET_TIME_UNIT_ZERO; | ||
103 | } | 105 | } |
104 | 106 | ||
105 | void | 107 | void |