/** * Add the validated peer address to the HELLO. * * @param cls the 'struct ValidationEntry' with the validated address * @param max space in buf * @param buf where to add the address * @return number of bytes written, 0 to signal the * end of the iteration. */ static size_t add_valid_peer_address (void *cls, size_t max, void *buf) { struct ValidationEntry *ve = cls; if (GNUNET_YES == ve->copied) return 0; /* terminate */ ve->copied = GNUNET_YES; return GNUNET_HELLO_add_address (ve->address, ve->valid_until, buf, max); }
/** * Add an address from the 'OwnAddressList' to the buffer. * * @param cls the 'struct GeneratorContext' * @param max maximum number of bytes left * @param buf where to write the address */ static size_t address_generator (void *cls, size_t max, void *buf) { struct GeneratorContext *gc = cls; size_t ret; if (NULL == gc->addr_pos) return 0; ret = GNUNET_HELLO_add_address (gc->addr_pos->address, gc->expiration, buf, max); gc->addr_pos = gc->addr_pos->next; return ret; }
/** * Add the given address with infinit expiration to the buffer. * * @param cls closure * @param address address to add * @param expiration old expiration * @return GNUNET_OK keep iterating */ static int add_to_buf (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct AddContext *ac = cls; size_t ret; ret = GNUNET_HELLO_add_address (address, GNUNET_TIME_UNIT_FOREVER_ABS, ac->buf, ac->max); ac->buf += ret; ac->max -= ret; ac->ret += ret; return GNUNET_OK; }
static ssize_t address_generator (void *cls, size_t max, void *buf) { size_t *agc = cls; ssize_t ret; struct GNUNET_HELLO_Address address; if (0 == *agc) return GNUNET_SYSERR; /* Done */ memset (&address.peer, 0, sizeof(struct GNUNET_PeerIdentity)); address.address = "Address"; address.transport_name = "peerinfotest"; address.address_length = *agc; ret = GNUNET_HELLO_add_address (&address, GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS), buf, max); (*agc)--; return ret; }
static int copy_latest (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct MergeContext *mc = cls; struct ExpireContext ec; ec.address = address; ec.found = GNUNET_NO; GNUNET_HELLO_iterate_addresses (mc->other, GNUNET_NO, &get_match_exp, &ec); if ((ec.found == GNUNET_NO) || (ec.expiration.abs_value < expiration.abs_value) || ((ec.expiration.abs_value == expiration.abs_value) && (mc->take_equal == GNUNET_YES))) { mc->ret += GNUNET_HELLO_add_address (address, expiration, &mc->buf[mc->ret], mc->max - mc->ret); } return GNUNET_OK; }
/** * We're building a HELLO. Parse the next address from the * parsing context and append it. * * @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) { 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) + 1, &addr, &addr_len)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to parse `%s' as an address for plugin `%s'\n"), plugin_address, plugin_name); 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; }