X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fpeerinfo-tool%2Fgnunet-peerinfo.c;h=0cb434d8913ff16be8f516ff120fc9d99df2b0e9;hb=82e8f0e1cd800fe8de0251aa06463af88435637f;hp=8bb7392d94754eabcc6caddecc742e1ce7793327;hpb=78ef40f28e08ef786292429a4257fb82cf244635;p=oweals%2Fgnunet.git diff --git a/src/peerinfo-tool/gnunet-peerinfo.c b/src/peerinfo-tool/gnunet-peerinfo.c index 8bb7392d9..0cb434d89 100644 --- a/src/peerinfo-tool/gnunet-peerinfo.c +++ b/src/peerinfo-tool/gnunet-peerinfo.c @@ -27,17 +27,12 @@ #include "gnunet_crypto_lib.h" #include "gnunet_configuration_lib.h" #include "gnunet_getopt_lib.h" -#include "gnunet_peerinfo_service.h" -#include "gnunet_transport_service.h" #include "gnunet_program_lib.h" -#include "gnunet_transport_plugin.h" +#include "gnunet_hello_lib.h" +#include "gnunet_transport_service.h" +#include "gnunet_peerinfo_service.h" #include "gnunet-peerinfo_plugins.h" -/** - * Prefix that every HELLO URI must start with. - */ -#define HELLO_URI_PREFIX "gnunet://hello/" - /** * How long until we time out during peerinfo iterations? */ @@ -114,37 +109,6 @@ struct PrintContext }; -/** - * Context used for building our own URI. - */ -struct GetUriContext -{ - /** - * Final URI. - */ - char *uri; - -}; - - -/** - * Context for 'add_address_to_hello'. - */ -struct GNUNET_PEERINFO_HelloAddressParsingContext -{ - /** - * Position in the URI with the next address to parse. - */ - const char *pos; - - /** - * Set to GNUNET_SYSERR to indicate parse errors. - */ - int ret; - -}; - - /** * Option '-n' */ @@ -203,7 +167,7 @@ static struct GNUNET_PeerIdentity my_peer_identity; /** * My public key. */ -static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded my_public_key; +static struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded my_public_key; /** * Head of list of print contexts. @@ -215,6 +179,11 @@ static struct PrintContext *pc_head; */ static struct PrintContext *pc_tail; +/** + * Handle to current 'GNUNET_PEERINFO_add_peer' operation. + */ +static struct GNUNET_PEERINFO_AddContext *ac; + /** * Main state machine that goes over all options and @@ -228,42 +197,6 @@ state_machine (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - -/** - * Replace all characters in the input 'in' according - * to the mapping. The mapping says to map each character - * in 'oldchars' to the corresponding character (by offset) - * in 'newchars'. - * - * @param in input string to remap - * @param oldchars characters to replace - * @param newchars replacement characters, must have same length as 'oldchars' - * @return copy of string with replacement applied. - */ -static char * -map_characters (const char *in, - const char *oldchars, - const char *newchars) -{ - char *ret; - const char *off; - size_t i; - - GNUNET_assert (strlen (oldchars) == strlen (newchars)); - ret = GNUNET_strdup (in); - i = 0; - while (ret[i] != '\0') - { - off = strchr (oldchars, ret[i]); - if (NULL != off) - ret[i] = newchars[off - oldchars]; - i++; - } - return ret; -} - - - /* ********************* 'get_info' ******************* */ /** @@ -389,10 +322,10 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, struct GNUNET_CRYPTO_HashAsciiEncoded enc; struct PrintContext *pc; - if (peer == NULL) + if (NULL == peer) { pic = NULL; /* end of iteration */ - if (err_msg != NULL) + if (NULL != err_msg) { FPRINTF (stderr, _("Error in communication with PEERINFO service: %s\n"), @@ -432,65 +365,6 @@ print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer, /* ************************* GET URI ************************** */ -/** - * Function that is called on each address of this peer. - * Expands the corresponding URI string. - * - * @param cls the 'GetUriContext' - * @param address address to add - * @param expiration expiration time for the address - * @return GNUNET_OK (continue iteration). - */ -static int -compose_uri (void *cls, const struct GNUNET_HELLO_Address *address, - struct GNUNET_TIME_Absolute expiration) -{ - struct GetUriContext *guc = cls; - struct GNUNET_TRANSPORT_PluginFunctions *papi; - const char *addr; - char *uri_addr; - char *ret; - char tbuf[16]; - struct tm *t; - time_t seconds; - - papi = GPI_plugins_find (address->transport_name); - if (papi == NULL) - { - /* Not an error - we might just not have the right plugin. */ - return GNUNET_OK; - } - if (NULL == papi->address_to_string) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "URI conversion not implemented for plugin `%s'\n", - address->transport_name); - return GNUNET_OK; - } - addr = papi->address_to_string (papi->cls, address->address, address->address_length); - if ( (addr == NULL) || (strlen(addr) == 0) ) - return GNUNET_OK; - /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved - characters in URIs */ - uri_addr = map_characters (addr, "[]", "()"); - seconds = expiration.abs_value / 1000; - t = gmtime (&seconds); - GNUNET_assert (0 != strftime (tbuf, sizeof (tbuf), - "%Y%m%d%H%M%S", - t)); - GNUNET_asprintf (&ret, - "%s!%s!%s!%s", - guc->uri, - tbuf, - address->transport_name, - uri_addr); - GNUNET_free (uri_addr); - GNUNET_free (guc->uri); - guc->uri = ret; - return GNUNET_OK; -} - - /** * Print URI of the peer. * @@ -504,8 +378,6 @@ print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg) { - struct GetUriContext *guc = cls; - if (peer == NULL) { pic = NULL; @@ -513,14 +385,18 @@ print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer, FPRINTF (stderr, _("Error in communication with PEERINFO service: %s\n"), err_msg); - GNUNET_free_non_null (guc->uri); - GNUNET_free (guc); tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); return; - } - if (NULL != hello) - GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &compose_uri, guc); - printf ("%s\n", (const char *) guc->uri); + } + + if (NULL == hello) + return; + + char *uri = GNUNET_HELLO_compose_uri(hello, &GPI_plugins_find); + if (NULL != uri) { + printf ("%s\n", (const char *) uri); + GNUNET_free (uri); + } } @@ -528,138 +404,21 @@ print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer, /** - * We're building a HELLO. Parse the next address from the - * parsing context and append it. + * Continuation called from 'GNUNET_PEERINFO_add_peer' * - * @param cls the 'struct GNUNET_PEERINFO_HelloAddressParsingContext' - * @param max number of bytes available for HELLO construction - * @param buffer where to copy the next address (in binary format) - * @return number of bytes added to buffer - */ -static size_t -add_address_to_hello (void *cls, size_t max, void *buffer) + * @param cls closure, NULL + * @param emsg error message, NULL on success + */ +static void +add_continuation (void *cls, + const char *emsg) { - struct GNUNET_PEERINFO_HelloAddressParsingContext *ctx = cls; - const char *tname; - const char *address; - char *uri_address; - char *plugin_address; - const char *end; - char *plugin_name; - struct tm expiration_time; - time_t expiration_seconds; - struct GNUNET_TIME_Absolute expire; - struct GNUNET_TRANSPORT_PluginFunctions *papi; - void *addr; - size_t addr_len; - struct GNUNET_HELLO_Address haddr; - size_t ret; - - if (NULL == ctx->pos) - return 0; - if ('!' != ctx->pos[0]) - { - ctx->ret = GNUNET_SYSERR; - GNUNET_break (0); - return 0; - } - ctx->pos++; - memset (&expiration_time, 0, sizeof (expiration_time)); - tname = strptime (ctx->pos, - "%Y%m%d%H%M%S", - &expiration_time); - - if (NULL == tname) - { - ctx->ret = GNUNET_SYSERR; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to parse HELLO message: missing expiration time\n")); - GNUNET_break (0); - return 0; - } - expiration_seconds = mktime (&expiration_time); - if (expiration_seconds == (time_t) -1) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to parse HELLO message: invalid expiration time\n")); - ctx->ret = GNUNET_SYSERR; - GNUNET_break (0); - return 0; - } - expire.abs_value = expiration_seconds * 1000; - if ('!' != tname[0]) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to parse HELLO message: malformed\n")); - ctx->ret = GNUNET_SYSERR; - GNUNET_break (0); - return 0; - } - tname++; - address = strchr (tname, (int) '!'); - if (NULL == address) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to parse HELLO message: missing transport plugin\n")); - ctx->ret = GNUNET_SYSERR; - GNUNET_break (0); - return 0; - } - address++; - end = strchr (address, (int) '!'); - ctx->pos = end; - plugin_name = GNUNET_strndup (tname, address - (tname+1)); - papi = GPI_plugins_find (plugin_name); - if (NULL == papi) - { - /* 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. - */ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Plugin `%s' not found\n"), - plugin_name); - GNUNET_free (plugin_name); - GNUNET_break (0); - return 0; - } - if (NULL == papi->string_to_address) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Plugin `%s' does not support URIs yet\n"), - plugin_name); - GNUNET_free (plugin_name); - GNUNET_break (0); - return 0; - } - uri_address = GNUNET_strndup (address, end - address); - /* For URIs we use '(' and ')' instead of '[' and ']' as brackets are reserved - characters in URIs; need to convert back to '[]' for the plugin */ - plugin_address = map_characters (uri_address, "()", "[]"); - GNUNET_free (uri_address); - if (GNUNET_OK != - papi->string_to_address (papi->cls, - plugin_address, - strlen (plugin_address), - &addr, - &addr_len)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to parse `%s'\n"), - plugin_address); - GNUNET_free (plugin_name); - GNUNET_free (plugin_address); - return 0; - } - GNUNET_free (plugin_address); - /* address.peer is unset - not used by add_address() */ - haddr.address_length = addr_len; - haddr.address = addr; - haddr.transport_name = plugin_name; - ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max); - GNUNET_free (addr); - GNUNET_free (plugin_name); - return ret; + ac = NULL; + if (NULL != emsg) + fprintf (stderr, + _("Failure adding HELLO: %s\n"), + emsg); + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); } @@ -673,41 +432,23 @@ add_address_to_hello (void *cls, size_t max, void *buffer) static int parse_hello_uri (const char *put_uri) { - const char *pks; - const char *exc; - struct GNUNET_HELLO_Message *hello; - struct GNUNET_PEERINFO_HelloAddressParsingContext ctx; - - if (0 != strncmp (put_uri, - HELLO_URI_PREFIX, - strlen (HELLO_URI_PREFIX))) - return GNUNET_SYSERR; - pks = &put_uri[strlen (HELLO_URI_PREFIX)]; - exc = strstr (pks, "!"); - - if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pks, - (NULL == exc) ? strlen (pks) : (exc - pks), - (unsigned char *) &my_public_key, - sizeof (my_public_key))) - return GNUNET_SYSERR; - ctx.pos = exc; - ctx.ret = GNUNET_OK; - hello = GNUNET_HELLO_create (&my_public_key, &add_address_to_hello, &ctx); - - if (NULL != hello) - { + struct GNUNET_HELLO_Message *hello = NULL; + + int ret = GNUNET_HELLO_parse_uri(put_uri, &my_public_key, &hello, &GPI_plugins_find); + + if (NULL != hello) { /* WARNING: this adds the address from URI WITHOUT verification! */ - if (GNUNET_OK == ctx.ret) - GNUNET_PEERINFO_add_peer (peerinfo, hello); + if (GNUNET_OK == ret) + ac = GNUNET_PEERINFO_add_peer (peerinfo, hello, &add_continuation, NULL); + else + tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL); GNUNET_free (hello); } /* wait 1s to give peerinfo operation a chance to succeed */ /* FIXME: current peerinfo API sucks to require this; not to mention that we get no feedback to determine if the operation actually succeeded */ - tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, - &state_machine, NULL); - return ctx.ret; + return ret; } @@ -729,6 +470,11 @@ shutdown_task (void *cls, struct AddressRecord *ar; unsigned int i; + if (NULL != ac) + { + GNUNET_PEERINFO_add_peer_cancel (ac); + ac = NULL; + } if (GNUNET_SCHEDULER_NO_TASK != tt) { GNUNET_SCHEDULER_cancel (tt); @@ -778,17 +524,25 @@ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - struct GNUNET_CRYPTO_RsaPrivateKey *priv; + struct GNUNET_CRYPTO_EccPrivateKey *priv; char *fn; cfg = c; - if (args[0] != NULL) + if ( (NULL != args[0]) && + (NULL == put_uri) && + (args[0] == strcasestr (args[0], "gnunet://hello/")) ) + { + put_uri = GNUNET_strdup (args[0]); + args++; + } + if (NULL != args[0]) { - FPRINTF (stderr, _("Invalid command line argument `%s'\n"), args[0]); + FPRINTF (stderr, + _("Invalid command line argument `%s'\n"), + args[0]); return; } - peerinfo = GNUNET_PEERINFO_connect (cfg); - if (peerinfo == NULL) + if (NULL == (peerinfo = GNUNET_PEERINFO_connect (cfg))) { FPRINTF (stderr, "%s", _("Could not access PEERINFO service. Exiting.\n")); return; @@ -797,23 +551,22 @@ run (void *cls, char *const *args, const char *cfgfile, { /* load private key */ if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_filename (cfg, "GNUNETD", "HOSTKEY", + GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &fn)) { FPRINTF (stderr, _("Could not find option `%s:%s' in configuration.\n"), "GNUNETD", "HOSTKEYFILE"); return; } - - if (NULL == (priv = GNUNET_CRYPTO_rsa_key_create_from_file (fn))) + if (NULL == (priv = GNUNET_CRYPTO_ecc_key_create_from_file (fn))) { FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), fn); GNUNET_free (fn); return; } GNUNET_free (fn); - GNUNET_CRYPTO_rsa_key_get_public (priv, &my_public_key); - GNUNET_CRYPTO_rsa_key_free (priv); + GNUNET_CRYPTO_ecc_key_get_public (priv, &my_public_key); + GNUNET_CRYPTO_ecc_key_free (priv); GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key), &my_peer_identity.hashPubKey); } @@ -841,9 +594,12 @@ state_machine (void *cls, { GPI_plugins_load (cfg); if (GNUNET_SYSERR == parse_hello_uri (put_uri)) + { fprintf (stderr, _("Invalid URI `%s'\n"), - put_uri); + put_uri); + GNUNET_SCHEDULER_shutdown (); + } GNUNET_free (put_uri); put_uri = NULL; return; @@ -870,20 +626,9 @@ state_machine (void *cls, } if (GNUNET_YES == get_uri) { - struct GetUriContext *guc; - char *pkey; - - guc = GNUNET_malloc (sizeof (struct GetUriContext)); - pkey = GNUNET_CRYPTO_rsa_public_key_to_string (&my_public_key); - GNUNET_asprintf (&guc->uri, - "%s%s", - HELLO_URI_PREFIX, - pkey); - GNUNET_free (pkey); GPI_plugins_load (cfg); pic = GNUNET_PEERINFO_iterate (peerinfo, &my_peer_identity, - TIMEOUT, - &print_my_uri, guc); + TIMEOUT, &print_my_uri, NULL); get_uri = GNUNET_NO; return; } @@ -922,10 +667,17 @@ main (int argc, char *const *argv) 1, &GNUNET_GETOPT_set_string, &put_uri}, GNUNET_GETOPT_OPTION_END }; - return (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "gnunet-peerinfo", - gettext_noop ("Print information about peers."), - options, &run, NULL)) ? 0 : 1; + int ret; + + if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + return 2; + + ret = (GNUNET_OK == + GNUNET_PROGRAM_run (argc, argv, "gnunet-peerinfo", + gettext_noop ("Print information about peers."), + options, &run, NULL)) ? 0 : 1; + GNUNET_free ((void*) argv); + return ret; } /* end of gnunet-peerinfo.c */