[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r20287 - in gnunet/src: hello include peerinfo-tool transpo
From: |
gnunet |
Subject: |
[GNUnet-SVN] r20287 - in gnunet/src: hello include peerinfo-tool transport |
Date: |
Mon, 5 Mar 2012 20:56:16 +0100 |
Author: grothoff
Date: 2012-03-05 20:56:16 +0100 (Mon, 05 Mar 2012)
New Revision: 20287
Modified:
gnunet/src/hello/hello.c
gnunet/src/include/gnunet_transport_plugin.h
gnunet/src/peerinfo-tool/Makefile.am
gnunet/src/peerinfo-tool/gnunet-peerinfo.c
gnunet/src/transport/plugin_transport_tcp.c
gnunet/src/transport/transport.h
Log:
-LRN: experimental HELLO URIs
Modified: gnunet/src/hello/hello.c
===================================================================
--- gnunet/src/hello/hello.c 2012-03-05 19:54:31 UTC (rev 20286)
+++ gnunet/src/hello/hello.c 2012-03-05 19:56:16 UTC (rev 20287)
@@ -641,5 +641,46 @@
return ret;
}
+/**
+ * GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER".
+ * The specific structure of "IDENTIFIER" depends on the module and
+ * maybe differenciated into additional subcategories if applicable.
+ * This module only deals with hello identifiers (MODULE = "hello").
+ * <p>
+ *
+ * The concrete URI format is:
+ *
+ * "gnunet://hello/PEER[!YYYYMMDDHHNNSS!<TYPE>!<ADDRESS>]...".
+ * These URIs can be used to add a peer record to peerinfo service.
+ * PEER is the string representation of peer's public key.
+ * YYYYMMDDHHNNSS is the expiration date.
+ * TYPE is a transport type.
+ * ADDRESS is the address, its format depends upon the transport type.
+ * The concrete transport types and corresponding address formats are:
+ *
+ * <ul><li>
+ *
+ * <TCP|UDP>!IPADDRESS
+ * IPVDDRESS is either IPV4 .-delimited address in form of
XXX.XXX.XXX.XXX:PPPPP
+ * or IPV6 :-delimited address, but with '(' and ')' instead of '[' and ']'
(RFC2396 advises against using square brackets in URIs):
+ * (XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX):PPPPP
+ * PPPPP is the port number. May be 0.
+ *
+ * </li><li>
+ *
+ * [add SMTP, HTTP and other addresses here]
+ *
+ * </li></ul>
+ *
+ * The encoding for hexadecimal values is defined in the crypto_hash.c
+ * module in the gnunetutil library and discussed there.
+ *
+ * Examples:
+ *
+ *
gnunet://hello/0430205UC7D56PTQK8NV05776671CNN44FK4TL6D0GQ35OMF8MEN4RNMKA5UF6AL3DQO8B1SC5AQF50SQ2MABIRU4HC8H2HAJKJ59JL1JVRJAK308F9GASRFLMGUBB5TQ5AKR94AS5T3MDG8B9O1EMPRKB0HVCG7T6QPP4CDJ913LAEHVJ2DI1TOBB15Q1JIT5ARBOD12U4SIGRFDV3Q7T66G4TBVSJJ90UQF1BG29TGJJKLGEIMSPHHKO544D6EALQ4F2K0416311JC22GVAD48R616I7VK03K7MP7N0RS2MBV1TE9JV8CK1LSQMR7KCDRTLDA6917UGA67DHTGHERIACCGQ54TGSR48RMSGS9BA5HLMOKASFC1I6V4TT09TUGCU8GNDHQF0JF3H7LPV59UL5I38QID040G000!20120302010059!TCP!192.168.0.1:2086!TCP!64.23.8.174:0
+ *
gnunet://hello/0430205UC7D56PTQK8NV05776671CNN44FK4TL6D0GQ35OMF8MEN4RNMKA5UF6AL3DQO8B1SC5AQF50SQ2MABIRU4HC8H2HAJKJ59JL1JVRJAK308F9GASRFLMGUBB5TQ5AKR94AS5T3MDG8B9O1EMPRKB0HVCG7T6QPP4CDJ913LAEHVJ2DI1TOBB15Q1JIT5ARBOD12U4SIGRFDV3Q7T66G4TBVSJJ90UQF1BG29TGJJKLGEIMSPHHKO544D6EALQ4F2K0416311JC22GVAD48R616I7VK03K7MP7N0RS2MBV1TE9JV8CK1LSQMR7KCDRTLDA6917UGA67DHTGHERIACCGQ54TGSR48RMSGS9BA5HLMOKASFC1I6V4TT09TUGCU8GNDHQF0JF3H7LPV59UL5I38QID040G000!20120302010059!TCP!(2001:db8:85a3:8d3:1319:8a2e:370:7348):2086
+ *
+ * <p>
+ */
/* end of hello.c */
Modified: gnunet/src/include/gnunet_transport_plugin.h
===================================================================
--- gnunet/src/include/gnunet_transport_plugin.h 2012-03-05 19:54:31 UTC
(rev 20286)
+++ gnunet/src/include/gnunet_transport_plugin.h 2012-03-05 19:56:16 UTC
(rev 20287)
@@ -423,7 +423,27 @@
const void *addr,
size_t addrlen);
+/**
+ * Function called to convert a string address to
+ * a binary address.
+ *
+ * @param cls closure ('struct Plugin*')
+ * @param addr string address
+ * @param addrlen length of the address
+ * @param buf location to store a buffer pointer
+ * If the function returns GNUNET_SYSERR, its contents are undefined.
+ * @param max size of the buffer
+ * @param buf_len location to store buffer size.
+ * If the function returns GNUNET_SYSERR, its contents are undefined.
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+typedef int (*GNUNET_TRANSPORT_StringToAddress) (void *cls,
+ const char *addr,
+ uint16_t addrlen,
+ void **buf,
+ size_t *added);
+
/**
* Each plugin is required to return a pointer to a struct of this
* type as the return value from its entry point.
@@ -477,6 +497,12 @@
GNUNET_TRANSPORT_AddressToString address_to_string;
/**
+ * Function that will be called to convert a string address
+ * to binary (numeric conversion only).
+ */
+ GNUNET_TRANSPORT_StringToAddress string_to_address;
+
+ /**
* Function that will be called tell the plugin to create a session
* object
*/
Modified: gnunet/src/peerinfo-tool/Makefile.am
===================================================================
--- gnunet/src/peerinfo-tool/Makefile.am 2012-03-05 19:54:31 UTC (rev
20286)
+++ gnunet/src/peerinfo-tool/Makefile.am 2012-03-05 19:56:16 UTC (rev
20287)
@@ -13,11 +13,14 @@
gnunet-peerinfo
gnunet_peerinfo_SOURCES = \
- gnunet-peerinfo.c
+ gnunet-peerinfo.c \
+ ../transport/gnunet-service-transport_plugins.c
+
gnunet_peerinfo_LDADD = \
$(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
$(top_builddir)/src/transport/libgnunettransport.la \
$(top_builddir)/src/hello/libgnunethello.la \
+ $(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/util/libgnunetutil.la
if HAVE_PYTHON_PEXPECT
Modified: gnunet/src/peerinfo-tool/gnunet-peerinfo.c
===================================================================
--- gnunet/src/peerinfo-tool/gnunet-peerinfo.c 2012-03-05 19:54:31 UTC (rev
20286)
+++ gnunet/src/peerinfo-tool/gnunet-peerinfo.c 2012-03-05 19:56:16 UTC (rev
20287)
@@ -30,6 +30,8 @@
#include "gnunet_peerinfo_service.h"
#include "gnunet_transport_service.h"
#include "gnunet_program_lib.h"
+#include "gnunet_transport_plugin.h"
+#include "../transport/gnunet-service-transport_plugins.h"
static int no_resolve;
@@ -37,8 +39,29 @@
static int get_self;
+static int get_uri;
+
+static char *put_uri;
+
static struct GNUNET_PEERINFO_Handle *peerinfo;
+/**
+ * Configuration handle.
+ */
+const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
+
+/**
+ * Statistics handle.
+ */
+struct GNUNET_STATISTICS_Handle *GST_stats;
+
+/**
+ * Configuration handle.
+ */
+struct GNUNET_PeerIdentity GST_my_identity;
+
+struct GNUNET_MessageHeader *our_hello = NULL;
+
static const struct GNUNET_CONFIGURATION_Handle *cfg;
struct PrintContext
@@ -47,8 +70,20 @@
char **address_list;
unsigned int num_addresses;
uint32_t off;
+ char *uri;
+ size_t uri_len;
};
+/**
+ * Obtain this peers HELLO message.
+ *
+ * @return our HELLO message
+ */
+const struct GNUNET_MessageHeader *
+GST_hello_get ()
+{
+ return (struct GNUNET_MessageHeader *) our_hello;
+}
static void
dump_pc (struct PrintContext *pc)
@@ -150,6 +185,8 @@
if (err_msg != NULL)
FPRINTF (stderr, "%s", _("Error in communication with PEERINFO
service\n"));
GNUNET_PEERINFO_disconnect (peerinfo);
+ GST_plugins_unload ();
+ GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
return;
}
if ((be_quiet) || (NULL == hello))
@@ -169,8 +206,312 @@
GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &print_address, pc);
}
+static int
+compose_uri (void *cls, const struct GNUNET_HELLO_Address *address,
+ struct GNUNET_TIME_Absolute expiration)
+{
+ struct PrintContext *pc = cls;
+ struct GNUNET_TRANSPORT_PluginFunctions *papi;
+ static const char *addr;
+ papi = GST_plugins_find (address->transport_name);
+ if (papi == NULL)
+ {
+ /* Not an error - we might just not have the right plugin. */
+ return GNUNET_OK;
+ }
+
+ addr = papi->address_to_string (papi->cls, address->address,
address->address_length);
+ if (addr != NULL)
+ {
+ ssize_t l = strlen (addr);
+ if (l > 0)
+ {
+ struct tm *t;
+ time_t seconds;
+ int s;
+ seconds = expiration.abs_value / 1000;
+ t = gmtime(&seconds);
+ pc->uri = GNUNET_realloc (pc->uri, pc->uri_len + 1 + 14 + 1 + strlen
(address->transport_name) + 1 + l + 1 /* 0 */);
+ s = sprintf (&pc->uri[pc->uri_len], "!%04u%02u%02u%02u%02u%02u!%s!%s",
+ t->tm_year, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
+ address->transport_name, addr);
+ if (s > 0)
+ pc->uri_len += s;
+ }
+ }
+ return GNUNET_OK;
+}
+
/**
+ * Print information about the peer.
+ */
+static void
+print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_HELLO_Message *hello, const char *err_msg)
+{
+ struct GNUNET_CRYPTO_HashAsciiEncoded enc;
+ struct PrintContext *pc = cls;
+ char *pkey;
+
+ if (peer == NULL)
+ {
+ if (err_msg != NULL)
+ FPRINTF (stderr, "%s", _("Error in communication with PEERINFO
service\n"));
+ GNUNET_PEERINFO_disconnect (peerinfo);
+ GST_plugins_unload ();
+ GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
+ return;
+ }
+ if ((be_quiet) || (NULL == hello))
+ {
+ GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc);
+ printf ("%s\n", (const char *) &enc);
+ if (be_quiet && get_uri != GNUNET_YES)
+ return;
+ }
+ pc->peer = *peer;
+ GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &count_address, pc);
+ GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &compose_uri, pc);
+ printf ("%s\n", pc->uri);
+ GNUNET_free (pc->uri);
+ GNUNET_free (pc);
+}
+
+struct GNUNET_PEERINFO_HelloAddressParsingContext
+{
+ char *tmp;
+ char *pos;
+ size_t tmp_len;
+};
+
+static size_t
+add_addr_to_hello (void *cls, size_t max, void *buffer)
+{
+ struct tm expiration_time;
+ char buf[5];
+ long l;
+ time_t expiration_seconds;
+ struct GNUNET_TIME_Absolute expire;
+
+ struct GNUNET_PEERINFO_HelloAddressParsingContext *ctx = cls;
+ char *exp1, *exp2;
+ struct GNUNET_TRANSPORT_PluginFunctions *papi;
+ void *addr;
+ size_t addr_len;
+
+ /* End of string */
+ if (ctx->pos - ctx->tmp == ctx->tmp_len)
+ return 0;
+
+ /* Parsed past the end of string, OR wrong format */
+ if ((ctx->pos - ctx->tmp > ctx->tmp_len) || ctx->pos[0] != '!')
+ {
+ GNUNET_break (0);
+ return 0;
+ }
+
+ /* Not enough bytes (3 for three '!', 14 for expiration date, and
+ * at least 1 for type and 1 for address (1-byte long address is a joke,
+ * but it is not completely unrealistic. Zero-length address is.
+ */
+ if (ctx->tmp_len - (ctx->pos - ctx->tmp) < 1 /*!*/ * 3 + 14 + /* at least */
2)
+ {
+ GNUNET_break (0);
+ return 0;
+ }
+ /* Go past the first '!', now we're on expiration date */
+ ctx->pos += 1;
+ /* Its length is known, so check for the next '!' right away */
+ if (ctx->pos[14] != '!')
+ {
+ GNUNET_break (0);
+ return 0;
+ }
+
+ memset (&expiration_time, 0, sizeof (struct tm));
+
+ /* This is FAR more strict than strptime(ctx->pos, "%Y%m%d%H%M%S", ...); */
+ /* FIXME: make it a separate function, since expiration is specified to
every address */
+#define GETNDIGITS(n,cond) \
+ strncpy (buf, &ctx->pos[0], n); \
+ buf[n] = '\0'; \
+ errno = 0; \
+ l = strtol (buf, NULL, 10); \
+ if (errno != 0 || cond) \
+ { \
+ GNUNET_break (0); \
+ return 0; \
+ } \
+ ctx->pos += n;
+
+ GETNDIGITS (4, l < 1900)
+ expiration_time.tm_year = l - 1900;
+
+ GETNDIGITS (2, l < 1 || l > 12)
+ expiration_time.tm_mon = l;
+
+ GETNDIGITS (2, l < 1 || l > 31)
+ expiration_time.tm_mday = l;
+
+ GETNDIGITS (2, l < 0 || l > 23)
+ expiration_time.tm_hour = l;
+
+ GETNDIGITS (2, l < 0 || l > 59)
+ expiration_time.tm_min = l;
+
+ /* 60 - with a leap second */
+ GETNDIGITS (2, l < 0 || l > 60)
+ expiration_time.tm_sec = l;
+
+ expiration_time.tm_isdst = -1;
+
+#undef GETNDIGITS
+
+ expiration_seconds = mktime (&expiration_time);
+ if (expiration_seconds == (time_t) -1)
+ {
+ GNUNET_break (0);
+ return 0;
+ }
+ expire.abs_value = expiration_seconds * 1000;
+
+ /* Now we're at '!', advance to the transport type */
+ ctx->pos += 1;
+
+ /* Find the next '!' that separates transport type from
+ * the address
+ */
+ exp1 = strstr (ctx->pos, "!");
+ if (exp1 == NULL)
+ {
+ GNUNET_break (0);
+ return 0;
+ }
+ /* We need it 0-terminated */
+ exp1[0] = '\0';
+ /* Find the '!' that separates address from the next record.
+ * It might not be there, if this is the last record.
+ */
+ exp2 = strstr (&exp1[1], "!");
+ if (exp2 == NULL)
+ exp2 = &ctx->tmp[ctx->tmp_len];
+
+ papi = GST_plugins_find (ctx->pos);
+ if (papi == NULL)
+ {
+ /* Not an error - we might just not have the right plugin.
+ * Skip this part, advance to the next one and recurse.
+ * But only if this is not the end of string.
+ */
+ ctx->pos = exp2 + 1;
+ if (ctx->pos - ctx->tmp >= ctx->tmp_len)
+ return 0;
+ return add_addr_to_hello (cls, max, buffer);
+ }
+
+ if (GNUNET_OK == papi->string_to_address (papi->cls, &exp1[1], exp2 -
&exp1[1], &addr, &addr_len))
+ {
+ struct GNUNET_HELLO_Address address;
+ int ret;
+
+ /* address.peer is unset - not used by add_address() */
+ address.address_length = addr_len;
+ address.address = addr;
+ address.transport_name = ctx->pos;
+ ret = GNUNET_HELLO_add_address (&address, expire, buffer, max);
+ GNUNET_free (addr);
+ ctx->pos = exp2;
+ return ret;
+ }
+ return 0;
+}
+
+void
+parse_hello (const struct GNUNET_CONFIGURATION_Handle *c,
+ const char *put_uri)
+{
+ int r;
+ char *scheme_part = NULL;
+ char *path_part = NULL;
+ char *exc;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
+ int std_result;
+ struct GNUNET_HELLO_Message *hello;
+ struct GNUNET_PEERINFO_HelloAddressParsingContext ctx;
+
+ r = GNUNET_STRINGS_parse_uri (put_uri, &scheme_part, (const char **)
&path_part);
+ if (r == GNUNET_NO)
+ return;
+ if (scheme_part == NULL || strcmp (scheme_part, "gnunet://") != 0)
+ {
+ GNUNET_free_non_null (scheme_part);
+ return;
+ }
+ GNUNET_free (scheme_part);
+
+ if (strncmp (path_part, "hello/", 6) != 0)
+ return;
+
+ path_part = &path_part[6];
+ ctx.tmp = GNUNET_strdup (path_part);
+ ctx.tmp_len = strlen (path_part);
+ exc = strstr (ctx.tmp, "!");
+ if (exc == NULL)
+ exc = ctx.pos + ctx.tmp_len;
+ ctx.pos = exc;
+
+ std_result = GNUNET_STRINGS_string_to_data (ctx.tmp, exc - ctx.tmp,
+ (unsigned char *) &pub, sizeof (pub));
+ if (std_result != GNUNET_OK)
+ {
+ GNUNET_free (ctx.tmp);
+ return;
+ }
+
+ hello = GNUNET_HELLO_create (&pub, add_addr_to_hello, &ctx);
+ GNUNET_free (ctx.tmp);
+
+ /* WARNING: this adds the address from URI WITHOUT verification! */
+ GNUNET_PEERINFO_add_peer (peerinfo, hello);
+}
+
+static struct GNUNET_TIME_Relative
+receive_stub (void *cls, const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message,
+ const struct GNUNET_ATS_Information *ats, uint32_t ats_count,
+ struct Session *session, const char *sender_address,
+ uint16_t sender_address_len)
+{
+ struct GNUNET_TIME_Relative t;
+ t.rel_value = 0;
+ return t;
+}
+
+static void
+address_notification_stub (void *cls, int add_remove,
+ const void *addr, size_t addrlen)
+{
+}
+
+static void
+session_end_stub (void *cls, const struct GNUNET_PeerIdentity *peer,
+ struct Session * session)
+{
+}
+
+static const struct GNUNET_ATS_Information
+address_to_type_stub (void *cls, const struct sockaddr *addr,
+ size_t addrlen)
+{
+ struct GNUNET_ATS_Information t;
+ t.type = 0;
+ t.value = 0;
+ return t;
+}
+
+
+/**
* Main function that will be run by the scheduler.
*
* @param cls closure
@@ -194,14 +535,34 @@
FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]);
return;
}
- if (get_self != GNUNET_YES)
+ if (put_uri != NULL && get_uri == GNUNET_YES)
{
+ FPRINTF (stderr, "%s", _("--put-uri and --get-uri are mutually
exclusive\n"));
+ return;
+ }
+ if (put_uri != NULL || get_uri == GNUNET_YES)
+ {
peerinfo = GNUNET_PEERINFO_connect (cfg);
if (peerinfo == NULL)
{
FPRINTF (stderr, "%s", _("Could not access PEERINFO service.
Exiting.\n"));
return;
}
+ GST_cfg = c;
+ GST_stats = GNUNET_STATISTICS_create ("transport", c);
+ /* FIXME: shouldn't we free GST_stats somewhere? */
+ GST_plugins_load (receive_stub, address_notification_stub,
+ session_end_stub, address_to_type_stub);
+ }
+ if (put_uri != NULL)
+ {
+ parse_hello (c, put_uri);
+ GST_plugins_unload ();
+ GNUNET_STATISTICS_destroy (GST_stats, GNUNET_NO);
+ return;
+ }
+ if (get_self != GNUNET_YES)
+ {
GNUNET_PEERINFO_iterate (peerinfo, NULL,
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS, 5), &print_peer_info,
@@ -233,6 +594,23 @@
printf ("%s\n", (char *) &enc);
else
printf (_("I am peer `%s'.\n"), (const char *) &enc);
+ if (get_uri == GNUNET_YES)
+ {
+ struct PrintContext *pc;
+ char *pkey;
+ ssize_t l, pl;
+ pc = GNUNET_malloc (sizeof (struct PrintContext));
+ pkey = GNUNET_CRYPTO_rsa_public_key_to_string (&pub);
+ pl = strlen ("gnunet://hello/");
+ l = strlen (pkey) + pl;
+ pc->uri = GNUNET_malloc (l + 1);
+ strcpy (pc->uri, "gnunet://hello/");
+ strcpy (&pc->uri[pl], pkey);
+ pc->uri_len = l;
+ GNUNET_PEERINFO_iterate (peerinfo, &pid,
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
+ print_my_uri, pc);
+ }
}
}
@@ -257,6 +635,12 @@
{'s', "self", NULL,
gettext_noop ("output our own identity only"),
0, &GNUNET_GETOPT_set_one, &get_self},
+ {'g', "get-hello", NULL,
+ gettext_noop ("also output HELLO uri(s)"),
+ 0, &GNUNET_GETOPT_set_one, &get_uri},
+ {'p', "put-hello", "HELLO",
+ gettext_noop ("add given HELLO uri to the database"),
+ 1, &GNUNET_GETOPT_set_string, &put_uri},
GNUNET_GETOPT_OPTION_END
};
return (GNUNET_OK ==
Modified: gnunet/src/transport/plugin_transport_tcp.c
===================================================================
--- gnunet/src/transport/plugin_transport_tcp.c 2012-03-05 19:54:31 UTC (rev
20286)
+++ gnunet/src/transport/plugin_transport_tcp.c 2012-03-05 19:56:16 UTC (rev
20287)
@@ -537,7 +537,110 @@
return rbuf;
}
+#define MAX_IPV6_ADDRLEN 47
+int
+tcp_string_to_address_ipv6 (void *cls, const char *addr, uint16_t addrlen,
+ void **buf, size_t *added)
+{
+ char zt_addr[MAX_IPV6_ADDRLEN + 1];
+ int ret;
+ char *port_colon;
+ unsigned int port;
+ struct IPv6TcpAddress *ipv6addr;
+
+ if (addrlen < 6)
+ return GNUNET_SYSERR;
+
+ memset (zt_addr, 0, MAX_IPV6_ADDRLEN + 1);
+ strncpy (zt_addr, addr, addrlen <= MAX_IPV6_ADDRLEN ? addrlen :
MAX_IPV6_ADDRLEN);
+
+ port_colon = strrchr (zt_addr, ':');
+ if (port_colon == NULL)
+ return GNUNET_SYSERR;
+ ret = sscanf (port_colon, ":%u", &port);
+ if (ret != 1 || port > 65535)
+ return GNUNET_SYSERR;
+ port_colon[0] = '\0';
+
+ ipv6addr = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
+ ret = inet_pton (AF_INET6, zt_addr, &ipv6addr->ipv6_addr);
+ if (ret <= 0)
+ {
+ GNUNET_free (ipv6addr);
+ return GNUNET_SYSERR;
+ }
+ ipv6addr->t6_port = port;
+ *buf = ipv6addr;
+ *added = sizeof (struct IPv6TcpAddress);
+ return GNUNET_OK;
+}
+
+#define MAX_IPV4_ADDRLEN 21
+
+int
+tcp_string_to_address_ipv4 (void *cls, const char *addr, uint16_t addrlen,
+ void **buf, size_t *added)
+{
+ unsigned int temps[5];
+ unsigned int port;
+ int cnt;
+ char zt_addr[MAX_IPV4_ADDRLEN + 1];
+ struct IPv4TcpAddress *ipv4addr;
+
+ if (addrlen < 9)
+ return GNUNET_SYSERR;
+
+ memset (zt_addr, 0, MAX_IPV4_ADDRLEN + 1);
+ strncpy (zt_addr, addr, addrlen <= MAX_IPV4_ADDRLEN ? addrlen :
MAX_IPV4_ADDRLEN);
+
+ cnt = sscanf (zt_addr, "%u.%u.%u.%u:%u", &temps[0], &temps[1], &temps[2],
&temps[3], &port);
+ if (cnt != 5)
+ return GNUNET_SYSERR;
+
+ for (cnt = 0; cnt < 4; cnt++)
+ if (temps[cnt] > 0xFF)
+ return GNUNET_SYSERR;
+ if (port > 65535)
+ return GNUNET_SYSERR;
+
+ ipv4addr = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
+ ipv4addr->ipv4_addr =
+ htonl ((temps[0] << 24) + (temps[1] << 16) + (temps[2] << 8) +
+ temps[3]);
+ ipv4addr->t4_port = htonl (port);
+ *buf = ipv4addr;
+ *added = sizeof (struct IPv4TcpAddress);
+ return GNUNET_OK;
+}
+
+/**
+ * Function called to convert a string address to
+ * a binary address.
+ *
+ * @param cls closure ('struct Plugin*')
+ * @param addr string address
+ * @param addrlen length of the address
+ * @param buf location to store the buffer
+ * @param max size of the buffer
+ * @param added location to store the number of bytes in the buffer.
+ * If the function returns GNUNET_SYSERR, its contents are undefined.
+ * @return GNUNET_OK on success, GNUNET_SYSERR on failure
+ */
+int
+tcp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
+ void **buf, size_t *added)
+{
+ if (addrlen < 1)
+ return GNUNET_SYSERR;
+
+ if (addr[0] == '(')
+ return tcp_string_to_address_ipv6 (cls, addr, addrlen, buf, added);
+ else
+ return tcp_string_to_address_ipv4 (cls, addr, addrlen, buf, added);
+}
+
+
struct SessionClientCtx
{
const struct GNUNET_SERVER_Client *client;
@@ -2084,6 +2187,7 @@
api->address_pretty_printer = &tcp_plugin_address_pretty_printer;
api->check_address = &tcp_plugin_check_address;
api->address_to_string = &tcp_address_to_string;
+ api->string_to_address = &tcp_string_to_address;
plugin->service = service;
if (service != NULL)
{
Modified: gnunet/src/transport/transport.h
===================================================================
--- gnunet/src/transport/transport.h 2012-03-05 19:54:31 UTC (rev 20286)
+++ gnunet/src/transport/transport.h 2012-03-05 19:56:16 UTC (rev 20287)
@@ -289,7 +289,7 @@
{
/**
- * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP
+ * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING
*/
struct GNUNET_MessageHeader header;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r20287 - in gnunet/src: hello include peerinfo-tool transport,
gnunet <=