From: Christian Grothoff Date: Mon, 5 Mar 2012 19:56:16 +0000 (+0000) Subject: -LRN: experimental HELLO URIs X-Git-Tag: initial-import-from-subversion-38251~14420 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=b1780f05127f1c84c442f12fe84ae8e712032164;p=oweals%2Fgnunet.git -LRN: experimental HELLO URIs --- diff --git a/src/hello/hello.c b/src/hello/hello.c index 7aa974008..6529c9333 100644 --- a/src/hello/hello.c +++ b/src/hello/hello.c @@ -641,5 +641,46 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg) 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"). + *

+ * + * The concrete URI format is: + * + * "gnunet://hello/PEER[!YYYYMMDDHHNNSS!!

]...". + * 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: + * + * + * + * 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 + * + *

+ */ /* end of hello.c */ diff --git a/src/include/gnunet_transport_plugin.h b/src/include/gnunet_transport_plugin.h index 9b39a4190..194d4d214 100644 --- a/src/include/gnunet_transport_plugin.h +++ b/src/include/gnunet_transport_plugin.h @@ -423,6 +423,26 @@ typedef const char *(*GNUNET_TRANSPORT_AddressToString) (void *cls, 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 @@ -476,6 +496,12 @@ struct GNUNET_TRANSPORT_PluginFunctions */ 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 diff --git a/src/peerinfo-tool/Makefile.am b/src/peerinfo-tool/Makefile.am index 8c5fd8fbb..7270bfb51 100644 --- a/src/peerinfo-tool/Makefile.am +++ b/src/peerinfo-tool/Makefile.am @@ -13,11 +13,14 @@ bin_PROGRAMS = \ 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 diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c index 21c996661..1e93a5ee8 100644 --- a/src/peerinfo-tool/gnunet-peerinfo.c +++ b/src/peerinfo-tool/gnunet-peerinfo.c @@ -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 be_quiet; 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 @@ struct PrintContext 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 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, 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,6 +206,310 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, 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. @@ -194,7 +535,12 @@ run (void *cls, char *const *args, const char *cfgfile, 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) @@ -202,6 +548,21 @@ run (void *cls, char *const *args, const char *cfgfile, 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 @@ run (void *cls, char *const *args, const char *cfgfile, 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 @@ main (int argc, char *const *argv) {'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 == diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 52efd4d4e..628a0ff42 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -537,6 +537,109 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen) 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 { @@ -2084,6 +2187,7 @@ libgnunet_plugin_transport_tcp_init (void *cls) 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) { diff --git a/src/transport/transport.h b/src/transport/transport.h index ff6818813..027720271 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -289,7 +289,7 @@ struct AddressLookupMessage { /** - * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP + * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING */ struct GNUNET_MessageHeader header;