aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/gnunet-service-transport.c77
-rw-r--r--src/transport/plugin_transport.h27
-rw-r--r--src/transport/plugin_transport_tcp.c293
-rw-r--r--src/transport/plugin_transport_template.c24
-rw-r--r--src/transport/plugin_transport_udp.c325
-rw-r--r--src/transport/test_plugin_transport_http.c16
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 */
1403static const char*
1404a2s (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,
4895int 4919int
4896main (int argc, char *const *argv) 4920main (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 */
361typedef 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 */
69struct 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 */
87struct 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 */
69struct Plugin; 105struct 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 */
314static const char*
315tcp_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 */
1015static int 1153static int
1016tcp_plugin_check_address (void *cls, void *addr, size_t addrlen) 1154tcp_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 */
1229static void 1383static void
1230disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client) 1384disconnect_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 */
1263static int 1421static int
1264process_interfaces (void *cls, 1422process_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 */
1324void * 1498void *
1325libgnunet_plugin_transport_tcp_init (void *cls) 1499libgnunet_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 */
261static const char*
262template_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 */
253void * 276void *
@@ -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 */
77struct 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 */
95struct 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 */
74struct PrettyPrinterContext 113struct 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 */
139static struct GNUNET_NETWORK_Handle *udp_sock; 190static 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 */
148void 199void
149udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) 200udp_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 */
158static int 212static int
159udp_transport_server_stop (void *cls) 213udp_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 */
263static int 362static int
264process_interfaces (void *cls, 363process_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 */
450static struct GNUNET_NETWORK_Handle * 594static struct GNUNET_NETWORK_Handle *
451udp_transport_server_start (void *cls) 595udp_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 */
557static int 698static int
558udp_check_address (void *cls, void *addr, size_t addrlen) 699udp_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 */
838static const char*
839udp_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 */
678void * 887void *
679libgnunet_plugin_transport_udp_init (void *cls) 888libgnunet_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 */
94static void 94static struct GNUNET_TIME_Relative
95receive (void *cls, 95receive (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
105void 107void