[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r11148 - gnunet/src/transport
From: |
gnunet |
Subject: |
[GNUnet-SVN] r11148 - gnunet/src/transport |
Date: |
Sun, 2 May 2010 13:48:52 +0200 |
Author: grothoff
Date: 2010-05-02 13:48:52 +0200 (Sun, 02 May 2010)
New Revision: 11148
Modified:
gnunet/src/transport/gnunet-service-transport.c
gnunet/src/transport/plugin_transport.h
gnunet/src/transport/plugin_transport_tcp.c
gnunet/src/transport/plugin_transport_template.c
gnunet/src/transport/plugin_transport_udp.c
gnunet/src/transport/test_plugin_transport_http.c
Log:
fixing major issue with how IP addresses go over the network (previously
ill-defined) -- thanks amatus
Modified: gnunet/src/transport/gnunet-service-transport.c
===================================================================
--- gnunet/src/transport/gnunet-service-transport.c 2010-05-01 12:17:38 UTC
(rev 11147)
+++ gnunet/src/transport/gnunet-service-transport.c 2010-05-02 11:48:52 UTC
(rev 11148)
@@ -45,9 +45,9 @@
#include "plugin_transport.h"
#include "transport.h"
-#define DEBUG_BLACKLIST GNUNET_NO
+#define DEBUG_BLACKLIST GNUNET_YES
-#define DEBUG_PING_PONG GNUNET_NO
+#define DEBUG_PING_PONG GNUNET_YES
/**
* Should we do some additional checks (to validate behavior
@@ -1393,6 +1393,32 @@
/**
+ * Convert an address to a string.
+ *
+ * @param plugin name of the plugin responsible for the address
+ * @param addr binary address
+ * @param addr_len number of bytes in addr
+ * @return NULL on error, otherwise address string
+ */
+static const char*
+a2s (const char *plugin,
+ const void *addr,
+ size_t addr_len)
+{
+ struct TransportPlugin *p;
+
+ if (plugin == NULL)
+ return NULL;
+ p = find_transport (plugin);
+ if (p == NULL)
+ return NULL;
+ return p->api->address_to_string (p->api->cls,
+ addr,
+ addr_len);
+}
+
+
+/**
* Find an address in any of the available transports for
* the given neighbour that would be good for message
* transmission. This is essentially the transport selection
@@ -1439,8 +1465,9 @@
if (addresses->addr != NULL)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Have address `%s' for peer `%4s' (status: %d, %d, %d,
%u, %llums, %u)\n",
- GNUNET_a2s (addresses->addr,
- addresses->addrlen),
+ a2s (head->plugin->short_name,
+ addresses->addr,
+ addresses->addrlen),
GNUNET_i2s (&neighbour->id),
addresses->connected,
addresses->in_transmit,
@@ -1601,8 +1628,9 @@
mq->message_buf_size,
GNUNET_i2s (&neighbour->id),
(mq->specific_address->addr != NULL)
- ? GNUNET_a2s (mq->specific_address->addr,
- mq->specific_address->addrlen)
+ ? a2s (mq->specific_address->plugin->short_name,
+ mq->specific_address->addr,
+ mq->specific_address->addrlen)
: "<inbound>",
rl->plugin->short_name);
#endif
@@ -2426,7 +2454,7 @@
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Adding address `%s' (%s) for peer `%4s' due to peerinfo data
for %llums.\n",
- GNUNET_a2s (addr, addrlen),
+ a2s (tname, addr, addrlen),
tname,
GNUNET_i2s (&n->id),
expiration.value);
@@ -3001,8 +3029,9 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Some validation of address `%s' via `%s' for peer `%4s'
already in progress.\n",
(peer_address->addr != NULL)
- ? GNUNET_a2s (peer_address->addr,
- peer_address->addrlen)
+ ? a2s (peer_address->plugin->short_name,
+ peer_address->addr,
+ peer_address->addrlen)
: "<inbound>",
tp->short_name,
GNUNET_i2s (&neighbour->id));
@@ -3049,8 +3078,9 @@
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Performing re-validation of address `%s' via `%s' for peer
`%4s' sending `%s' (%u bytes) and `%s' (%u bytes)\n",
(peer_address->addr != NULL)
- ? GNUNET_a2s (peer_address->addr,
- peer_address->addrlen)
+ ? a2s (peer_address->plugin->short_name,
+ peer_address->addr,
+ peer_address->addrlen)
: "<inbound>",
tp->short_name,
GNUNET_i2s (&neighbour->id),
@@ -3231,8 +3261,9 @@
"Confirmed validity of address, peer `%4s' has address `%s'
(%s).\n",
GNUNET_h2s (key),
(ve->addr != NULL)
- ? GNUNET_a2s ((const struct sockaddr *) ve->addr,
- ve->addrlen)
+ ? a2s (ve->transport_name,
+ (const struct sockaddr *) ve->addr,
+ ve->addrlen)
: "<inbound>",
ve->transport_name);
#endif
@@ -3368,15 +3399,6 @@
return;
}
-#if 0
- /* FIXME: add given address to potential pool of our addresses
- (for voting) */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
- _("Another peer saw us using the address `%s' via `%s'.\n"),
- GNUNET_a2s ((const struct sockaddr *) &pong[1],
- ntohs(pong->addrlen)),
- va->transport_name);
-#endif
}
@@ -3434,7 +3456,8 @@
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Performing validation of address `%s' via `%s' for peer `%4s'
sending `%s' (%u bytes) and `%s' (%u bytes)\n",
- GNUNET_a2s ((const void*) &va[1], va->addrlen),
+ a2s (va->transport_name,
+ (const void*) &va[1], va->addrlen),
va->transport_name,
GNUNET_i2s (&neighbour->id),
"HELLO", hello_size,
@@ -3548,7 +3571,7 @@
#if DEBUG_TRANSPORT > 1
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Validation of address `%s' via `%s' for peer `%4s' already
in progress.\n",
- GNUNET_a2s (addr, addrlen),
+ a2s (tname, addr, addrlen),
tname,
GNUNET_i2s (&id));
#endif
@@ -3939,8 +3962,9 @@
"Processing `%s' from `%s'\n",
"PING",
(sender_address != NULL)
- ? GNUNET_a2s ((const struct sockaddr *)sender_address,
- sender_address_len)
+ ? a2s (plugin->short_name,
+ (const struct sockaddr *)sender_address,
+ sender_address_len)
: "<inbound>");
#endif
GNUNET_STATISTICS_update (stats,
@@ -4895,6 +4919,7 @@
int
main (int argc, char *const *argv)
{
+ a2s (NULL, NULL, 0); /* make compiler happy */
return (GNUNET_OK ==
GNUNET_SERVICE_run (argc,
argv,
Modified: gnunet/src/transport/plugin_transport.h
===================================================================
--- gnunet/src/transport/plugin_transport.h 2010-05-01 12:17:38 UTC (rev
11147)
+++ gnunet/src/transport/plugin_transport.h 2010-05-02 11:48:52 UTC (rev
11148)
@@ -346,7 +346,24 @@
(*GNUNET_TRANSPORT_CheckAddress) (void *cls,
void *addr, size_t addrlen);
+
/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address. Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure
+ * @param addr binary address
+ * @param addr_len length of the address
+ * @return string representing the same address
+ */
+typedef const char* (*GNUNET_TRANSPORT_AddressToString) (void *cls,
+ const void *addr,
+ size_t addrlen);
+
+
+/**
* Each plugin is required to return a pointer to a struct of this
* type as the return value from its entry point.
*/
@@ -387,9 +404,19 @@
* Function that will be called to check if a binary address
* for this plugin is well-formed. If clearly needed, patch
* up information such as port numbers.
+ * FIXME: this API will likely change in the near future since
+ * it currently does not allow the size of the patched address
+ * to be different!
*/
GNUNET_TRANSPORT_CheckAddress check_address;
+
+ /**
+ * Function that will be called to convert a binary address
+ * to a string (numeric conversion only).
+ */
+ GNUNET_TRANSPORT_AddressToString address_to_string;
+
};
Modified: gnunet/src/transport/plugin_transport_tcp.c
===================================================================
--- gnunet/src/transport/plugin_transport_tcp.c 2010-05-01 12:17:38 UTC (rev
11147)
+++ gnunet/src/transport/plugin_transport_tcp.c 2010-05-02 11:48:52 UTC (rev
11148)
@@ -64,6 +64,42 @@
/**
+ * Network format for IPv4 addresses.
+ */
+struct IPv4TcpAddress
+{
+ /**
+ * IPv4 address, in network byte order.
+ */
+ uint32_t ipv4_addr;
+
+ /**
+ * Port number, in network byte order.
+ */
+ uint16_t t_port;
+
+};
+
+
+/**
+ * Network format for IPv6 addresses.
+ */
+struct IPv6TcpAddress
+{
+ /**
+ * IPv6 address.
+ */
+ unsigned char ipv6_addr[16];
+
+ /**
+ * Port number, in network byte order.
+ */
+ uint16_t t6_port;
+
+};
+
+
+/**
* Encapsulation of all of the state of the plugin.
*/
struct Plugin;
@@ -262,7 +298,61 @@
};
+
+
/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address. Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure ('struct Plugin*')
+ * @param addr binary address
+ * @param addr_len length of the address
+ * @return string representing the same address
+ */
+static const char*
+tcp_address_to_string (void *cls,
+ const void *addr,
+ size_t addrlen)
+{
+ static char buf[INET6_ADDRSTRLEN];
+ const void *sb;
+ struct sockaddr_in a4;
+ struct sockaddr_in6 a6;
+ const struct IPv4TcpAddress *t4;
+ const struct IPv6TcpAddress *t6;
+ int af;
+
+ if (addrlen == sizeof (struct IPv6TcpAddress))
+ {
+ t6 = addr;
+ af = AF_INET6;
+ memset (&a6, 0, sizeof (a6));
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = t6->t6_port;
+ memcpy (a6.sin6_addr.s6_addr,
+ t6->ipv6_addr,
+ 16);
+ sb = &a6;
+ }
+ else if (addrlen == sizeof (struct IPv4TcpAddress))
+ {
+ t4 = addr;
+ af = AF_INET;
+ memset (&a4, 0, sizeof (a4));
+ a4.sin_family = AF_INET;
+ a4.sin_port = t4->t_port;
+ a4.sin_addr.s_addr = t4->ipv4_addr;
+ sb = &a4;
+ }
+ else
+ return NULL;
+ return inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
+}
+
+
+/**
* Find the session handle for the given client.
*
* @return NULL if no matching session exists
@@ -520,8 +610,10 @@
"Disconnecting from `%4s' at %s (session %p).\n",
GNUNET_i2s (&session->target),
(session->connect_addr != NULL) ?
- GNUNET_a2s (session->connect_addr,
- session->connect_alen) : "*", session);
+ tcp_address_to_string (session->plugin,
+ session->connect_addr,
+ session->connect_alen) : "*",
+ session);
#endif
/* remove from session list */
prev = NULL;
@@ -680,6 +772,12 @@
struct PendingMessage *pm;
struct GNUNET_CONNECTION_Handle *sa;
int af;
+ const void *sb;
+ size_t sbs;
+ struct sockaddr_in a4;
+ struct sockaddr_in6 a6;
+ const struct IPv4TcpAddress *t4;
+ const struct IPv6TcpAddress *t6;
GNUNET_STATISTICS_update (plugin->env->stats,
gettext_noop ("# bytes TCP was asked to transmit"),
@@ -746,13 +844,29 @@
}
if (session == NULL)
{
- if (sizeof (struct sockaddr_in) == addrlen)
+ if (addrlen == sizeof (struct IPv6TcpAddress))
{
- af = AF_INET;
+ t6 = addr;
+ af = AF_INET6;
+ memset (&a6, 0, sizeof (a6));
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = t6->t6_port;
+ memcpy (a6.sin6_addr.s6_addr,
+ t6->ipv6_addr,
+ 16);
+ sb = &a6;
+ sbs = sizeof (a6);
}
- else if (sizeof (struct sockaddr_in6) == addrlen)
+ else if (addrlen == sizeof (struct IPv4TcpAddress))
{
- af = AF_INET6;
+ t4 = addr;
+ af = AF_INET;
+ memset (&a4, 0, sizeof (a4));
+ a4.sin_family = AF_INET;
+ a4.sin_port = t4->t_port;
+ a4.sin_addr.s_addr = t4->ipv4_addr;
+ sb = &a4;
+ sbs = sizeof (a4);
}
else
{
@@ -760,7 +874,7 @@
return -1;
}
sa = GNUNET_CONNECTION_create_from_sockaddr (plugin->env->sched,
- af, addr, addrlen,
+ af, sb, sbs,
GNUNET_SERVER_MAX_MESSAGE_SIZE);
if (sa == NULL)
{
@@ -769,7 +883,7 @@
"tcp",
"Failed to create connection to `%4s' at `%s'\n",
GNUNET_i2s (target),
- GNUNET_a2s (addr, addrlen));
+ GNUNET_a2s (sb, sbs));
#endif
GNUNET_STATISTICS_update (plugin->env->stats,
gettext_noop ("# bytes discarded by TCP
(failed to connect)"),
@@ -782,7 +896,7 @@
"tcp",
"Asked to transmit to `%4s', creating fresh session
using address `%s'.\n",
GNUNET_i2s (target),
- GNUNET_a2s (addr, addrlen));
+ GNUNET_a2s (sb, sbs));
#endif
session = create_session (plugin,
target,
@@ -948,13 +1062,44 @@
void *asc_cls)
{
struct Plugin *plugin = cls;
- const struct sockaddr_in *v4;
- const struct sockaddr_in6 *v6;
struct PrettyPrinterContext *ppc;
+ const void *sb;
+ size_t sbs;
+ struct sockaddr_in a4;
+ struct sockaddr_in6 a6;
+ const struct IPv4TcpAddress *t4;
+ const struct IPv6TcpAddress *t6;
+ int af;
+ uint16_t port;
- if ((addrlen != sizeof (struct sockaddr_in)) &&
- (addrlen != sizeof (struct sockaddr_in6)))
+ if (addrlen == sizeof (struct IPv6TcpAddress))
{
+ t6 = addr;
+ af = AF_INET6;
+ memset (&a6, 0, sizeof (a6));
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = t6->t6_port;
+ memcpy (a6.sin6_addr.s6_addr,
+ t6->ipv6_addr,
+ 16);
+ port = ntohs (t6->t6_port);
+ sb = &a6;
+ sbs = sizeof (a6);
+ }
+ else if (addrlen == sizeof (struct IPv4TcpAddress))
+ {
+ t4 = addr;
+ af = AF_INET;
+ memset (&a4, 0, sizeof (a4));
+ a4.sin_family = AF_INET;
+ a4.sin_port = t4->t_port;
+ a4.sin_addr.s_addr = t4->ipv4_addr;
+ port = ntohs (t4->t_port);
+ sb = &a4;
+ sbs = sizeof (a4);
+ }
+ else
+ {
/* invalid address */
GNUNET_break_op (0);
asc (asc_cls, NULL);
@@ -963,21 +1108,11 @@
ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
ppc->asc = asc;
ppc->asc_cls = asc_cls;
- if (addrlen == sizeof (struct sockaddr_in))
- {
- v4 = (const struct sockaddr_in *) addr;
- ppc->port = ntohs (v4->sin_port);
- }
- else
- {
- v6 = (const struct sockaddr_in6 *) addr;
- ppc->port = ntohs (v6->sin6_port);
-
- }
+ ppc->port = port;
GNUNET_RESOLVER_hostname_get (plugin->env->sched,
plugin->env->cfg,
- addr,
- addrlen,
+ sb,
+ sbs,
!numeric, timeout, &append_port, ppc);
}
@@ -1004,45 +1139,40 @@
/**
* Another peer has suggested an address for this peer and transport
- * plugin. Check that this could be a valid address.
+ * plugin. Check that this could be a valid address. This function
+ * is not expected to 'validate' the address in the sense of trying to
+ * connect to it but simply to see if the binary format is technically
+ * legal for establishing a connection.
*
* @param cls closure, our 'struct Plugin*'
* @param addr pointer to the address
* @param addrlen length of addr
* @return GNUNET_OK if this is a plausible address for this peer
- * and transport
+ * and transport, GNUNET_SYSERR if not
*/
static int
tcp_plugin_check_address (void *cls, void *addr, size_t addrlen)
{
struct Plugin *plugin = cls;
- char buf[sizeof (struct sockaddr_in6)];
- struct sockaddr_in *v4;
- struct sockaddr_in6 *v6;
+ struct IPv4TcpAddress *v4;
+ struct IPv6TcpAddress *v6;
- if ((addrlen != sizeof (struct sockaddr_in)) &&
- (addrlen != sizeof (struct sockaddr_in6)))
+ if ((addrlen != sizeof (struct IPv4TcpAddress)) &&
+ (addrlen != sizeof (struct IPv6TcpAddress)))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- memcpy (buf, addr, sizeof (struct sockaddr_in6));
- if (addrlen == sizeof (struct sockaddr_in))
+ if (addrlen == sizeof (struct IPv4TcpAddress))
{
- v4 = (struct sockaddr_in *) buf;
- v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port)));
+ v4 = (struct IPv4TcpAddress *) addr;
+ v4->t_port = htons (check_port (plugin, ntohs (v4->t_port)));
}
else
{
- v6 = (struct sockaddr_in6 *) buf;
- v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port)));
+ v6 = (struct IPv6TcpAddress *) addr;
+ v6->t6_port = htons (check_port (plugin, ntohs (v6->t6_port)));
}
-#if DEBUG_TCP
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
- "tcp",
- "Informing transport service about my address `%s'.\n",
- GNUNET_a2s (addr, addrlen));
-#endif
return GNUNET_OK;
}
@@ -1065,7 +1195,12 @@
struct Session *session;
size_t alen;
void *vaddr;
+ struct IPv4TcpAddress *t4;
+ struct IPv6TcpAddress *t6;
+ const struct sockaddr_in *s4;
+ const struct sockaddr_in6 *s6;
+
#if DEBUG_TCP
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
"tcp",
@@ -1094,8 +1229,27 @@
GNUNET_a2s (vaddr, alen),
client);
#endif
- session->connect_addr = vaddr;
- session->connect_alen = alen;
+ if (alen == sizeof (struct sockaddr_in))
+ {
+ s4 = vaddr;
+ t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
+ t4->t_port = s4->sin_port;
+ t4->ipv4_addr = s4->sin_addr.s_addr;
+ session->connect_addr = t4;
+ session->connect_alen = sizeof (struct IPv4TcpAddress);
+ }
+ else if (alen == sizeof (struct sockaddr_in6))
+ {
+ s6 = vaddr;
+ t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
+ t6->t6_port = s6->sin6_port;
+ memcpy (t6->ipv6_addr,
+ s6->sin6_addr.s6_addr,
+ 16);
+ session->connect_addr = t6;
+ session->connect_alen = sizeof (struct IPv6TcpAddress);
+ }
+ GNUNET_free (vaddr);
}
else
{
@@ -1227,7 +1381,8 @@
* @param client identification of the client
*/
static void
-disconnect_notify (void *cls, struct GNUNET_SERVER_Client *client)
+disconnect_notify (void *cls,
+ struct GNUNET_SERVER_Client *client)
{
struct Plugin *plugin = cls;
struct Session *session;
@@ -1243,8 +1398,10 @@
"Destroying session of `%4s' with %s (%p) due to
network-level disconnect.\n",
GNUNET_i2s (&session->target),
(session->connect_addr != NULL) ?
- GNUNET_a2s (session->connect_addr,
- session->connect_alen) : "*", client);
+ tcp_address_to_string (session->plugin,
+ session->connect_addr,
+ session->connect_alen) : "*",
+ client);
#endif
disconnect_session (session);
}
@@ -1259,6 +1416,7 @@
* @param isDefault do we think this may be our default interface
* @param addr address of the interface
* @param addrlen number of bytes in addr
+ * @return GNUNET_OK to continue iterating
*/
static int
process_interfaces (void *cls,
@@ -1268,28 +1426,41 @@
{
struct Plugin *plugin = cls;
int af;
- struct sockaddr_in *v4;
- struct sockaddr_in6 *v6;
+ struct IPv4TcpAddress t4;
+ struct IPv6TcpAddress t6;
+ void *arg;
+ uint16_t args;
af = addr->sa_family;
if (af == AF_INET)
{
- v4 = (struct sockaddr_in *) addr;
- v4->sin_port = htons (plugin->adv_port);
+ t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+ t4.t_port = htons (plugin->adv_port);
+ arg = &t4;
+ args = sizeof (t4);
}
+ else if (af == AF_INET6)
+ {
+ memcpy (t6.ipv6_addr,
+ ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
+ 16);
+ t6.t6_port = htons (plugin->adv_port);
+ arg = &t6;
+ args = sizeof (t6);
+ }
else
{
- GNUNET_assert (af == AF_INET6);
- v6 = (struct sockaddr_in6 *) addr;
- v6->sin6_port = htons (plugin->adv_port);
+ GNUNET_break (0);
+ return GNUNET_OK;
}
GNUNET_log_from (GNUNET_ERROR_TYPE_INFO |
GNUNET_ERROR_TYPE_BULK,
- "tcp", _("Found address `%s' (%s)\n"),
+ "tcp",
+ _("Found address `%s' (%s)\n"),
GNUNET_a2s (addr, addrlen), name);
plugin->env->notify_address (plugin->env->cls,
"tcp",
- addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL);
+ arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
return GNUNET_OK;
}
@@ -1320,6 +1491,9 @@
/**
* Entry point for the plugin.
+ *
+ * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
+ * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error
*/
void *
libgnunet_plugin_transport_tcp_init (void *cls)
@@ -1377,6 +1551,7 @@
api->disconnect = &tcp_plugin_disconnect;
api->address_pretty_printer = &tcp_plugin_address_pretty_printer;
api->check_address = &tcp_plugin_check_address;
+ api->address_to_string = &tcp_address_to_string;
plugin->service = service;
plugin->server = GNUNET_SERVICE_get_server (service);
plugin->handlers = GNUNET_malloc (sizeof (my_handlers));
Modified: gnunet/src/transport/plugin_transport_template.c
===================================================================
--- gnunet/src/transport/plugin_transport_template.c 2010-05-01 12:17:38 UTC
(rev 11147)
+++ gnunet/src/transport/plugin_transport_template.c 2010-05-02 11:48:52 UTC
(rev 11148)
@@ -248,6 +248,29 @@
/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address. Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure
+ * @param addr binary address
+ * @param addr_len length of the address
+ * @return string representing the same address
+ */
+static const char*
+template_plugin_address_to_string (void *cls,
+ const void *addr,
+ size_t addrlen)
+{
+ GNUNET_break (0);
+ return NULL;
+}
+
+
+
+
+/**
* Entry point for the plugin.
*/
void *
@@ -266,6 +289,7 @@
api->disconnect = &template_plugin_disconnect;
api->address_pretty_printer = &template_plugin_address_pretty_printer;
api->check_address = &template_plugin_address_suggested;
+ api->address_to_string = &template_plugin_address_to_string;
return api;
}
Modified: gnunet/src/transport/plugin_transport_udp.c
===================================================================
--- gnunet/src/transport/plugin_transport_udp.c 2010-05-01 12:17:38 UTC (rev
11147)
+++ gnunet/src/transport/plugin_transport_udp.c 2010-05-02 11:48:52 UTC (rev
11148)
@@ -71,13 +71,64 @@
};
+/**
+ * Network format for IPv4 addresses.
+ */
+struct IPv4UdpAddress
+{
+ /**
+ * IPv4 address, in network byte order.
+ */
+ uint32_t ipv4_addr;
+
+ /**
+ * Port number, in network byte order.
+ */
+ uint16_t u_port;
+
+};
+
+
+/**
+ * Network format for IPv6 addresses.
+ */
+struct IPv6UdpAddress
+{
+ /**
+ * IPv6 address.
+ */
+ unsigned char ipv6_addr[16];
+
+ /**
+ * Port number, in network byte order.
+ */
+ uint16_t u6_port;
+
+};
+
+
+/**
+ *
+ */
struct PrettyPrinterContext
{
+ /**
+ *
+ */
GNUNET_TRANSPORT_AddressStringCallback asc;
+
+ /**
+ * Closure for 'asc'.
+ */
void *asc_cls;
+
+ /**
+ *
+ */
uint16_t port;
};
+
/**
* Encapsulation of all of the state of the plugin.
*/
@@ -134,7 +185,7 @@
/* *********** globals ************* */
/**
- * the socket that we transmit all data with
+ * The socket that we transmit all data with
*/
static struct GNUNET_NETWORK_Handle *udp_sock;
@@ -146,7 +197,8 @@
* @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
*/
void
-udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
+udp_disconnect (void *cls,
+ const struct GNUNET_PeerIdentity *target)
{
/* nothing to do, UDP is stateless */
}
@@ -154,6 +206,8 @@
/**
* Shutdown the server process (stop receiving inbound traffic). Maybe
* restarted later!
+ *
+ * @param cls closure, the 'struct Plugin*'
*/
static int
udp_transport_server_stop (void *cls)
@@ -178,7 +232,7 @@
* Function that can be used by the transport service to transmit
* a message using the plugin.
*
- * @param cls closure
+ * @param cls closure, the 'struct Plugin*'
* @param target who should receive this message (ignored by UDP)
* @param msgbuf one or more GNUNET_MessageHeader(s) strung together
* @param msgbuf_size the size of the msgbuf to send
@@ -217,6 +271,13 @@
struct UDPMessage *message;
int ssize;
ssize_t sent;
+ int af;
+ const void *sb;
+ size_t sbs;
+ struct sockaddr_in a4;
+ struct sockaddr_in6 a6;
+ const struct IPv4UdpAddress *t4;
+ const struct IPv6UdpAddress *t6;
GNUNET_assert (NULL == session);
GNUNET_assert(udp_sock != NULL);
@@ -231,13 +292,45 @@
if (force_address == GNUNET_SYSERR)
return -1; /* never reliable */
+ if (addrlen == sizeof (struct IPv6UdpAddress))
+ {
+ t6 = addr;
+ af = AF_INET6;
+ memset (&a6, 0, sizeof (a6));
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = t6->u6_port;
+ memcpy (a6.sin6_addr.s6_addr,
+ t6->ipv6_addr,
+ 16);
+ sb = &a6;
+ sbs = sizeof (a6);
+ }
+ else if (addrlen == sizeof (struct IPv4UdpAddress))
+ {
+ t4 = addr;
+ af = AF_INET;
+ memset (&a4, 0, sizeof (a4));
+ a4.sin_family = AF_INET;
+ a4.sin_port = t4->u_port;
+ a4.sin_addr.s_addr = t4->ipv4_addr;
+ sb = &a4;
+ sbs = sizeof (a4);
+ }
+ else
+ {
+ GNUNET_break_op (0);
+ return -1;
+ }
+
/* Build the message to be sent */
message = GNUNET_malloc (sizeof (struct UDPMessage) + msgbuf_size);
ssize = sizeof (struct UDPMessage) + msgbuf_size;
#if DEBUG_UDP
- GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
- ("In udp_send, ssize is %d, sending message to %s\n"),
ssize, GNUNET_a2s((const struct sockaddr *)addr, addrlen));
+ GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp",
+ "In udp_send, ssize is %d, sending message to `%s'\n",
+ ssize,
+ GNUNET_a2s(sb, sbs));
#endif
message->header.size = htons (ssize);
message->header.type = htons (0);
@@ -246,8 +339,7 @@
memcpy (&message[1], msgbuf, msgbuf_size);
sent =
GNUNET_NETWORK_socket_sendto (udp_sock, message, ssize,
- addr,
- addrlen);
+ sb, sbs);
if ( (cont != NULL) &&
(sent != -1) )
cont (cont_cls, target, GNUNET_OK);
@@ -259,6 +351,13 @@
/**
* Add the IP of our network interface to the list of
* our external IP addresses.
+ *
+ * @param cls closure (the 'struct Plugin*')
+ * @param name name of the interface (can be NULL for unknown)
+ * @param isDefault is this presumably the default interface
+ * @param addr address of this interface (can be NULL for unknown or
unassigned)
+ * @param addrlen length of the address
+ * @return GNUNET_OK to continue iterating
*/
static int
process_interfaces (void *cls,
@@ -268,29 +367,42 @@
{
struct Plugin *plugin = cls;
int af;
- struct sockaddr_in *v4;
- struct sockaddr_in6 *v6;
+ struct IPv4UdpAddress t4;
+ struct IPv6UdpAddress t6;
+ void *arg;
+ uint16_t args;
af = addr->sa_family;
if (af == AF_INET)
{
- v4 = (struct sockaddr_in *) addr;
- v4->sin_port = htons (plugin->adv_port);
+ t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
+ t4.u_port = htons (plugin->adv_port);
+ arg = &t4;
+ args = sizeof (t4);
}
+ else if (af == AF_INET6)
+ {
+ memcpy (t6.ipv6_addr,
+ ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr,
+ 16);
+ t6.u6_port = htons (plugin->adv_port);
+ arg = &t6;
+ args = sizeof (t6);
+ }
else
{
- GNUNET_assert (af == AF_INET6);
- v6 = (struct sockaddr_in6 *) addr;
- v6->sin6_port = htons (plugin->adv_port);
+ GNUNET_break (0);
+ return GNUNET_OK;
}
GNUNET_log_from (GNUNET_ERROR_TYPE_INFO |
GNUNET_ERROR_TYPE_BULK,
- "udp", _("Found address `%s' (%s)\n"),
- GNUNET_a2s (addr, addrlen), name);
+ "udp",
+ _("Found address `%s' (%s)\n"),
+ GNUNET_a2s (addr, addrlen),
+ name);
plugin->env->notify_address (plugin->env->cls,
"udp",
- addr, addrlen, GNUNET_TIME_UNIT_FOREVER_REL);
-
+ arg, args, GNUNET_TIME_UNIT_FOREVER_REL);
return GNUNET_OK;
}
@@ -346,6 +458,12 @@
int tsize;
char *msgbuf;
const struct GNUNET_MessageHeader *currhdr;
+ struct IPv4UdpAddress t4;
+ struct IPv6UdpAddress t6;
+ const struct sockaddr_in *s4;
+ const struct sockaddr_in6 *s6;
+ const void *ca;
+ size_t calen;
#if DEBUG_UDP
GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
@@ -411,6 +529,31 @@
("offset is %d, tsize is %d (UDPMessage size is %d)\n"),
offset, tsize, sizeof(struct UDPMessage));
#endif
+
+ if (fromlen == sizeof (struct sockaddr_in))
+ {
+ s4 = (const struct sockaddr_in*) &addr;
+ t4.u_port = s4->sin_port;
+ t4.ipv4_addr = s4->sin_addr.s_addr;
+ ca = &t4;
+ calen = sizeof (struct IPv4UdpAddress);
+ }
+ else if (fromlen == sizeof (struct sockaddr_in6))
+ {
+ s6 = (const struct sockaddr_in6*) &addr;
+ t6.u6_port = s6->sin6_port;
+ memcpy (t6.ipv6_addr,
+ s6->sin6_addr.s6_addr,
+ 16);
+ ca = &t6;
+ calen = sizeof (struct IPv6UdpAddress);
+ }
+ else
+ {
+ GNUNET_break (0);
+ ca = NULL;
+ calen = 0;
+ }
while (offset < tsize)
{
currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
@@ -421,7 +564,7 @@
#endif
plugin->env->receive (plugin->env->cls,
sender, currhdr, UDP_DIRECT_DISTANCE,
- NULL, (const char *)&addr, fromlen);
+ NULL, ca, calen);
offset += ntohs(currhdr->size);
#if DEBUG_UDP
GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "udp", _
@@ -446,6 +589,7 @@
/**
* Create a UDP socket. If possible, use IPv6, otherwise
* try IPv4.
+ * @param cls closure, the 'struct Plugin*'
*/
static struct GNUNET_NETWORK_Handle *
udp_transport_server_start (void *cls)
@@ -550,44 +694,31 @@
* @param addrlen length of addr
* @return GNUNET_OK if this is a plausible address for this peer
* and transport, GNUNET_SYSERR if not
- *
- * TODO: perhaps make everything work with sockaddr_storage, it may
- * be a cleaner way to handle addresses in UDP
*/
static int
udp_check_address (void *cls, void *addr, size_t addrlen)
{
struct Plugin *plugin = cls;
- char buf[sizeof (struct sockaddr_in6)];
+ struct IPv4UdpAddress *v4;
+ struct IPv6UdpAddress *v6;
- struct sockaddr_in *v4;
- struct sockaddr_in6 *v6;
-
- if ((addrlen != sizeof (struct sockaddr_in)) &&
- (addrlen != sizeof (struct sockaddr_in6)))
+ if ((addrlen != sizeof (struct IPv4UdpAddress)) &&
+ (addrlen != sizeof (struct IPv6UdpAddress)))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- memcpy (buf, addr, sizeof (struct sockaddr_in6));
- if (addrlen == sizeof (struct sockaddr_in))
+ if (addrlen == sizeof (struct IPv4UdpAddress))
{
- v4 = (struct sockaddr_in *) buf;
- v4->sin_port = htons (check_port (plugin, ntohs (v4->sin_port)));
+ v4 = (struct IPv4UdpAddress *) addr;
+ v4->u_port = htons (check_port (plugin, ntohs (v4->u_port)));
}
else
{
- v6 = (struct sockaddr_in6 *) buf;
- v6->sin6_port = htons (check_port (plugin, ntohs (v6->sin6_port)));
+ v6 = (struct IPv6UdpAddress *) addr;
+ v6->u6_port = htons (check_port (plugin, ntohs (v6->u6_port)));
}
-#if DEBUG_UDP
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
- "tcp",
- "Informing transport service about my address `%s'.\n",
- GNUNET_a2s (addr, addrlen));
-#endif
return GNUNET_OK;
- return GNUNET_OK;
}
@@ -637,13 +768,44 @@
void *asc_cls)
{
struct Plugin *plugin = cls;
- const struct sockaddr_in *v4;
- const struct sockaddr_in6 *v6;
struct PrettyPrinterContext *ppc;
+ const void *sb;
+ struct sockaddr_in a4;
+ struct sockaddr_in6 a6;
+ const struct IPv4UdpAddress *t4;
+ const struct IPv6UdpAddress *t6;
+ int af;
+ size_t sbs;
+ uint16_t port;
- if ((addrlen != sizeof (struct sockaddr_in)) &&
- (addrlen != sizeof (struct sockaddr_in6)))
+ if (addrlen == sizeof (struct IPv6UdpAddress))
{
+ t6 = addr;
+ af = AF_INET6;
+ memset (&a6, 0, sizeof (a6));
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = t6->u6_port;
+ port = ntohs (t6->u6_port);
+ memcpy (a6.sin6_addr.s6_addr,
+ t6->ipv6_addr,
+ 16);
+ sb = &a6;
+ sbs = sizeof (a6);
+ }
+ else if (addrlen == sizeof (struct IPv4UdpAddress))
+ {
+ t4 = addr;
+ af = AF_INET;
+ memset (&a4, 0, sizeof (a4));
+ a4.sin_family = AF_INET;
+ a4.sin_port = t4->u_port;
+ a4.sin_addr.s_addr = t4->ipv4_addr;
+ port = ntohs (t4->u_port);
+ sb = &a4;
+ sbs = sizeof (a4);
+ }
+ else
+ {
/* invalid address */
GNUNET_break_op (0);
asc (asc_cls, NULL);
@@ -652,28 +814,75 @@
ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
ppc->asc = asc;
ppc->asc_cls = asc_cls;
- if (addrlen == sizeof (struct sockaddr_in))
+ ppc->port = port;
+ GNUNET_RESOLVER_hostname_get (plugin->env->sched,
+ plugin->env->cfg,
+ sb,
+ sbs,
+ !numeric, timeout, &append_port, ppc);
+}
+
+
+
+/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address. Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure
+ * @param addr binary address
+ * @param addr_len length of the address
+ * @return string representing the same address
+ */
+static const char*
+udp_address_to_string (void *cls,
+ const void *addr,
+ size_t addrlen)
+{
+ static char buf[INET6_ADDRSTRLEN];
+ const void *sb;
+ struct sockaddr_in a4;
+ struct sockaddr_in6 a6;
+ const struct IPv4UdpAddress *t4;
+ const struct IPv6UdpAddress *t6;
+ int af;
+
+ if (addrlen == sizeof (struct IPv6UdpAddress))
{
- v4 = (const struct sockaddr_in *) addr;
- ppc->port = ntohs (v4->sin_port);
+ t6 = addr;
+ af = AF_INET6;
+ memset (&a6, 0, sizeof (a6));
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = t6->u6_port;
+ memcpy (a6.sin6_addr.s6_addr,
+ t6->ipv6_addr,
+ 16);
+ sb = &a6;
}
- else
+ else if (addrlen == sizeof (struct IPv4UdpAddress))
{
- v6 = (const struct sockaddr_in6 *) addr;
- ppc->port = ntohs (v6->sin6_port);
-
+ t4 = addr;
+ af = AF_INET;
+ memset (&a4, 0, sizeof (a4));
+ a4.sin_family = AF_INET;
+ a4.sin_port = t4->u_port;
+ a4.sin_addr.s_addr = t4->ipv4_addr;
+ sb = &a4;
}
- GNUNET_RESOLVER_hostname_get (plugin->env->sched,
- plugin->env->cfg,
- addr,
- addrlen,
- !numeric, timeout, &append_port, ppc);
+ else
+ return NULL;
+
+ return inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
}
/**
* The exported method. Makes the core api available via a global and
* returns the udp transport API.
+ *
+ * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
+ * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error
*/
void *
libgnunet_plugin_transport_udp_init (void *cls)
@@ -737,7 +946,7 @@
api->disconnect = &udp_disconnect;
api->address_pretty_printer = &udp_plugin_address_pretty_printer;
api->check_address = &udp_check_address;
-
+ api->address_to_string = &udp_address_to_string;
plugin->service = service;
/* FIXME: do the two calls below periodically again and
Modified: gnunet/src/transport/test_plugin_transport_http.c
===================================================================
--- gnunet/src/transport/test_plugin_transport_http.c 2010-05-01 12:17:38 UTC
(rev 11147)
+++ gnunet/src/transport/test_plugin_transport_http.c 2010-05-02 11:48:52 UTC
(rev 11148)
@@ -36,7 +36,7 @@
#include "plugin_transport.h"
#include "transport.h"
-#define VERBOSE GNUNET_YES
+#define VERBOSE GNUNET_NO
/**
* How long until we give up on transmitting the message?
@@ -91,15 +91,17 @@
/**
* Initialize Environment for this plugin
*/
-static void
+static struct GNUNET_TIME_Relative
receive (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_MessageHeader * message,
- uint32_t distance,
- const char *sender_address,
- size_t sender_address_len)
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ uint32_t distance,
+ struct Session *session,
+ const char *sender_address,
+ size_t sender_address_len)
{
/* do nothing */
+ return GNUNET_TIME_UNIT_ZERO;
}
void
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r11148 - gnunet/src/transport,
gnunet <=