X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fhello%2Fhello.c;h=690a0961a34ffaa344277748415c8fe9a2c3db80;hb=7c1f035ed971e12882cd7a65c7d36883842945b1;hp=d552e4454ad6fa64132e886f202b7ab935847821;hpb=c2d9d1e64c9801122caaa6b429fc67706db5c9d7;p=oweals%2Fgnunet.git diff --git a/src/hello/hello.c b/src/hello/hello.c index d552e4454..690a0961a 100644 --- a/src/hello/hello.c +++ b/src/hello/hello.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - Copyright (C) 2009 Christian Grothoff (and other contributing authors) + Copyright (C) 2009, 2015 GNUnet e.V. GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -14,8 +14,8 @@ You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** @@ -30,42 +30,6 @@ #include "gnunet_util_lib.h" #include "gnunet_transport_plugin.h" -GNUNET_NETWORK_STRUCT_BEGIN - -/** - * A HELLO message is used to exchange information about - * transports with other peers. This struct is always - * followed by the actual network addresses which have - * the format: - * - * 1) transport-name (0-terminated) - * 2) address-length (uint16_t, network byte order; possibly - * unaligned!) - * 3) address expiration (`struct GNUNET_TIME_AbsoluteNBO`); possibly - * unaligned!) - * 4) address (address-length bytes; possibly unaligned!) - */ -struct GNUNET_HELLO_Message -{ - /** - * Type will be #GNUNET_MESSAGE_TYPE_HELLO. - */ - struct GNUNET_MessageHeader header; - - /** - * Use in F2F mode: Do not gossip this HELLO message - */ - uint32_t friend_only GNUNET_PACKED; - - /** - * The public key of the peer. - */ - struct GNUNET_CRYPTO_EddsaPublicKey publicKey; - -}; -GNUNET_NETWORK_STRUCT_END - - /** * Context used for building our own URI. */ @@ -84,7 +48,7 @@ struct GNUNET_HELLO_ComposeUriContext /** - * Context for 'add_address_to_hello'. + * Context for #add_address_to_hello(). */ struct GNUNET_HELLO_ParseUriContext { @@ -108,7 +72,6 @@ struct GNUNET_HELLO_ParseUriContext */ unsigned int counter_added; - /** * Function for finding transport plugins by name. */ @@ -116,21 +79,21 @@ struct GNUNET_HELLO_ParseUriContext }; -/** Return HELLO type +/** + * Return HELLO type * * @param h HELLO Message to test - * @return #GNUNET_YES or #GNUNET_NO + * @return #GNUNET_YES for friend-only or #GNUNET_NO otherwise */ int GNUNET_HELLO_is_friend_only (const struct GNUNET_HELLO_Message *h) { if (GNUNET_YES == ntohl(h->friend_only)) - return GNUNET_YES; + return GNUNET_YES; return GNUNET_NO; } - /** * Copy the given address information into * the given buffer using the format of HELLOs. @@ -144,7 +107,8 @@ GNUNET_HELLO_is_friend_only (const struct GNUNET_HELLO_Message *h) */ size_t GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address, - struct GNUNET_TIME_Absolute expiration, char *target, + struct GNUNET_TIME_Absolute expiration, + char *target, size_t max) { uint16_t alen; @@ -157,12 +121,12 @@ GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address, return 0; exp = GNUNET_TIME_absolute_hton (expiration); alen = htons ((uint16_t) address->address_length); - memcpy (target, address->transport_name, slen); - memcpy (&target[slen], &alen, sizeof (uint16_t)); + GNUNET_memcpy (target, address->transport_name, slen); + GNUNET_memcpy (&target[slen], &alen, sizeof (uint16_t)); slen += sizeof (uint16_t); - memcpy (&target[slen], &exp, sizeof (struct GNUNET_TIME_AbsoluteNBO)); + GNUNET_memcpy (&target[slen], &exp, sizeof (struct GNUNET_TIME_AbsoluteNBO)); slen += sizeof (struct GNUNET_TIME_AbsoluteNBO); - memcpy (&target[slen], address->address, address->address_length); + GNUNET_memcpy (&target[slen], address->address, address->address_length); slen += address->address_length; return slen; } @@ -172,9 +136,9 @@ GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address, * Get the size of an address entry in a HELLO message. * * @param buf pointer to the start of the address entry - * @param max maximum size of the entry (end of buf) + * @param max maximum size of the entry (end of @a buf) * @param ralen set to the address length - * @return size of the entry, or 0 if max is not large enough + * @return size of the entry, or 0 if @a max is not large enough */ static size_t get_hello_address_size (const char *buf, @@ -208,7 +172,7 @@ get_hello_address_size (const char *buf, GNUNET_break_op (0); return 0; } - memcpy (&alen, pos, sizeof (uint16_t)); + GNUNET_memcpy (&alen, pos, sizeof (uint16_t)); alen = ntohs (alen); *ralen = alen; slen += alen + sizeof (uint16_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO); @@ -227,29 +191,38 @@ get_hello_address_size (const char *buf, * expiration time and an iterator that spews the * transport addresses. * + * If friend only is set to #GNUNET_YES we create a FRIEND_HELLO which + * will not be gossiped to other peers. + * + * @param public_key public key to include in the HELLO + * @param addrgen callback to invoke to get addresses + * @param addrgen_cls closure for @a addrgen + * @param friend_only should the returned HELLO be only visible to friends? * @return the hello message */ struct GNUNET_HELLO_Message * -GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *publicKey, +GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, GNUNET_HELLO_GenerateAddressListCallback addrgen, void *addrgen_cls, int friend_only) { - char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1 - 256 - + char buffer[GNUNET_MAX_MESSAGE_SIZE - 1 - 256 - sizeof (struct GNUNET_HELLO_Message)]; size_t max; size_t used; size_t ret; struct GNUNET_HELLO_Message *hello; - GNUNET_assert (NULL != publicKey); - GNUNET_assert ((GNUNET_YES == friend_only) || (GNUNET_NO == friend_only)); - + GNUNET_assert (NULL != public_key); + GNUNET_assert ( (GNUNET_YES == friend_only) || + (GNUNET_NO == friend_only) ); max = sizeof (buffer); used = 0; - if (addrgen != NULL) + if (NULL != addrgen) { - while (GNUNET_SYSERR != (ret = addrgen (addrgen_cls, max, &buffer[used]))) + while (GNUNET_SYSERR != (ret = addrgen (addrgen_cls, + max, + &buffer[used]))) { max -= ret; used += ret; @@ -259,10 +232,10 @@ GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *publicKey, hello->header.type = htons (GNUNET_MESSAGE_TYPE_HELLO); hello->header.size = htons (sizeof (struct GNUNET_HELLO_Message) + used); hello->friend_only = htonl (friend_only); - - memcpy (&hello->publicKey, publicKey, - sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); - memcpy (&hello[1], buffer, used); + hello->publicKey = *public_key; + GNUNET_memcpy (&hello[1], + buffer, + used); return hello; } @@ -280,7 +253,8 @@ GNUNET_HELLO_create (const struct GNUNET_CRYPTO_EddsaPublicKey *publicKey, struct GNUNET_HELLO_Message * GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg, int return_modified, - GNUNET_HELLO_AddressIterator it, void *it_cls) + GNUNET_HELLO_AddressIterator it, + void *it_cls) { struct GNUNET_HELLO_Address address; uint16_t msize; @@ -297,95 +271,176 @@ GNUNET_HELLO_iterate_addresses (const struct GNUNET_HELLO_Message *msg, msize = GNUNET_HELLO_size (msg); if ((msize < sizeof (struct GNUNET_HELLO_Message)) || (ntohs (msg->header.type) != GNUNET_MESSAGE_TYPE_HELLO)) + { + GNUNET_break_op (0); return NULL; + } ret = NULL; if (return_modified) { ret = GNUNET_malloc (msize); - memcpy (ret, msg, msize); + GNUNET_memcpy (ret, + msg, + msize); } inptr = (const char *) &msg[1]; insize = msize - sizeof (struct GNUNET_HELLO_Message); wpos = 0; - woff = (ret != NULL) ? (char *) &ret[1] : NULL; + woff = (NULL != ret) ? (char *) &ret[1] : NULL; address.peer.public_key = msg->publicKey; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "HELLO has %u bytes of address data\n", + (unsigned int) insize); + while (insize > 0) { - esize = get_hello_address_size (inptr, insize, &alen); + esize = get_hello_address_size (inptr, + insize, + &alen); if (0 == esize) { GNUNET_break (0); GNUNET_free_non_null (ret); return NULL; } - memcpy (&expire, + /* need GNUNET_memcpy() due to possibility of misalignment */ + GNUNET_memcpy (&expire, &inptr[esize - alen - sizeof (struct GNUNET_TIME_AbsoluteNBO)], sizeof (struct GNUNET_TIME_AbsoluteNBO)); address.address = &inptr[esize - alen]; address.address_length = alen; address.transport_name = inptr; address.local_info = GNUNET_HELLO_ADDRESS_INFO_NONE; - iret = it (it_cls, &address, GNUNET_TIME_absolute_ntoh (expire)); - if (iret == GNUNET_SYSERR) - { - if (ret != NULL) - ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos); - return ret; - } - if ((iret == GNUNET_OK) && (ret != NULL)) + iret = it (it_cls, + &address, + GNUNET_TIME_absolute_ntoh (expire)); + if (GNUNET_SYSERR == iret) + break; + if ( (GNUNET_OK == iret) && + (NULL != ret) ) { - memcpy (woff, inptr, esize); + /* copy address over */ + GNUNET_memcpy (woff, + inptr, + esize); woff += esize; wpos += esize; } insize -= esize; inptr += esize; } - if (ret != NULL) + if (NULL != ret) ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos); return ret; } +/** + * Closure for #get_match_exp(). + */ struct ExpireContext { + /** + * Address we are looking for. + */ const struct GNUNET_HELLO_Address *address; + + /** + * Set to #GNUNET_YES if we found the @e address. + */ int found; + + /** + * Set to the expiration of the match if @e found is #GNUNET_YES. + */ struct GNUNET_TIME_Absolute expiration; }; +/** + * Store the expiration time of an address that matches the template. + * + * @param cls the `struct ExpireContext` + * @param address address to match against the template + * @param expiration expiration time of @a address, to store in @a cls + * @return #GNUNET_SYSERR if we found a matching address, #GNUNET_OK otherwise + */ static int -get_match_exp (void *cls, const struct GNUNET_HELLO_Address *address, +get_match_exp (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct ExpireContext *ec = cls; - if (0 == GNUNET_HELLO_address_cmp (address, ec->address)) - { - ec->found = GNUNET_YES; - ec->expiration = expiration; - return GNUNET_SYSERR; /* done here */ - } - return GNUNET_OK; + if (0 != GNUNET_HELLO_address_cmp (address, + ec->address)) + return GNUNET_OK; + ec->found = GNUNET_YES; + ec->expiration = expiration; + return GNUNET_SYSERR; /* done here */ } +/** + * Context for a #GNUNET_HELLO_Merge operation. + */ struct MergeContext { + /** + * First HELLO we are merging. + */ const struct GNUNET_HELLO_Message *h1; + + /** + * Second HELLO we are merging. + */ const struct GNUNET_HELLO_Message *h2; + + /** + * Either @e h1 or @e h2, used when copying + * to compare against (so we only copy the + * most recent entry). + */ const struct GNUNET_HELLO_Message *other; + + /** + * Buffer where we copy to. + */ char *buf; + + /** + * Number of bytes allocated in @e buf + */ size_t max; + + /** + * Current (write) offset in @e buf. + */ size_t ret; + + /** + * Should we copy addresses with an identical value + * and expiration time in @e other, or do we only + * copy addresses with strictly later expiration times? + */ int take_equal; }; +/** + * Append the address @a address to the buffer from + * the merge context IF it is more recent than equivalent + * addresses in `other`. + * + * @param cls the `struct MergeContext` + * @param address the HELLO address we might copy + * @param expiration expiration time for @a address + * @return always #GNUNET_OK + */ static int -copy_latest (void *cls, const struct GNUNET_HELLO_Address *address, +copy_latest (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct MergeContext *mc = cls; @@ -393,36 +448,64 @@ copy_latest (void *cls, const struct GNUNET_HELLO_Address *address, 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_us < expiration.abs_value_us) || - ((ec.expiration.abs_value_us == expiration.abs_value_us) && - (mc->take_equal == GNUNET_YES))) + /* check if address exists in other */ + GNUNET_HELLO_iterate_addresses (mc->other, + GNUNET_NO, + &get_match_exp, + &ec); + if ( (GNUNET_NO == ec.found) || + (ec.expiration.abs_value_us < expiration.abs_value_us) || + ( (ec.expiration.abs_value_us == expiration.abs_value_us) && + (GNUNET_YES == mc->take_equal) ) ) { + /* copy address to buffer */ mc->ret += - GNUNET_HELLO_add_address (address, expiration, &mc->buf[mc->ret], + GNUNET_HELLO_add_address (address, + expiration, + &mc->buf[mc->ret], mc->max - mc->ret); } return GNUNET_OK; } +/** + * Function called to build the HELLO during + * #GNUNET_HELLO_merge() by merging addresses from + * two original HELLOs. + * + * @param cls the `struct MergeContext` + * @param max number of bytes we can write at most in @a buf + * @param buf where to copy the addresses + * @return #GNUNET_SYSERR to end iteration, otherwise number of bytes written to @a buf + */ static ssize_t -merge_addr (void *cls, size_t max, void *buf) +merge_addr (void *cls, + size_t max, + void *buf) { struct MergeContext *mc = cls; - if (mc->h1 == NULL) + if (NULL == mc->h1) return GNUNET_SYSERR; /* Stop iteration */ mc->ret = 0; mc->max = max; mc->buf = buf; mc->take_equal = GNUNET_NO; mc->other = mc->h2; - GNUNET_HELLO_iterate_addresses (mc->h1, GNUNET_NO, ©_latest, mc); + /* copy addresses from h1, if strictly larger expiration than h2 */ + GNUNET_HELLO_iterate_addresses (mc->h1, + GNUNET_NO, + ©_latest, + mc); mc->take_equal = GNUNET_YES; mc->other = mc->h1; - GNUNET_HELLO_iterate_addresses (mc->h2, GNUNET_NO, ©_latest, mc); + /* copy addresses from h2, if larger or equal expiration than h1 */ + GNUNET_HELLO_iterate_addresses (mc->h2, + GNUNET_NO, + ©_latest, + mc); + /* set marker to stop iteration */ mc->h1 = NULL; return mc->ret; } @@ -435,7 +518,7 @@ merge_addr (void *cls, size_t max, void *buf) * * @param h1 first HELLO message * @param h2 the second HELLO message - * @return the combined hello message + * @return the combined HELLO message */ struct GNUNET_HELLO_Message * GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1, @@ -449,24 +532,57 @@ GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1, else friend_only = ntohl (h1->friend_only); /* Both HELLO's have the same type */ - return GNUNET_HELLO_create (&h1->publicKey, &merge_addr, &mc, friend_only); + return GNUNET_HELLO_create (&h1->publicKey, + &merge_addr, + &mc, + friend_only); } +/** + * Context used in #GNUNET_HELLO_iterate_new_addresses() to + * figure out which addresses are in fact 'new'. + */ struct DeltaContext { + /** + * We should ignore addresses that expire before this time. + */ struct GNUNET_TIME_Absolute expiration_limit; + /** + * Function to call on addresses that are indeed new. + */ GNUNET_HELLO_AddressIterator it; + /** + * Closure for @e it. + */ void *it_cls; + /** + * HELLO with known addresses, addresses in this HELLO + * we must always ignore. + */ const struct GNUNET_HELLO_Message *old_hello; }; +/** + * Check if the given address is 'new', and if so, call + * the iterator. Compares the existing address against + * addresses in the context's `old_hello` and calls the + * iterator on those that are new (and not expired). + * + * @param cls the `struct DeltaContext` + * @param address an address to check whether it is new + * @param expiration expiration time for @a address + * @return #GNUNET_YES if the address is ignored, otherwise + * whatever the iterator returned. + */ static int -delta_match (void *cls, const struct GNUNET_HELLO_Address *address, +delta_match (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct DeltaContext *dc = cls; @@ -475,35 +591,38 @@ delta_match (void *cls, const struct GNUNET_HELLO_Address *address, ec.address = address; ec.found = GNUNET_NO; - GNUNET_HELLO_iterate_addresses (dc->old_hello, GNUNET_NO, &get_match_exp, + GNUNET_HELLO_iterate_addresses (dc->old_hello, + GNUNET_NO, + &get_match_exp, &ec); - if ((ec.found == GNUNET_YES) && - ((ec.expiration.abs_value_us > expiration.abs_value_us) || - (ec.expiration.abs_value_us >= dc->expiration_limit.abs_value_us))) - return GNUNET_YES; /* skip */ - ret = dc->it (dc->it_cls, address, expiration); + if ( (GNUNET_YES == ec.found) && + ( (ec.expiration.abs_value_us > expiration.abs_value_us) || + (ec.expiration.abs_value_us >= dc->expiration_limit.abs_value_us))) + return GNUNET_YES; /* skip: found and boring */ + ret = dc->it (dc->it_cls, + address, + expiration); return ret; } /** - * Iterate over addresses in "new_hello" that - * are NOT already present in "old_hello". + * Iterate over addresses in @a new_hello that are NOT already present + * in @a old_hello. Note that if the address is present in @a old_hello + * but the expiration time in @a new_hello is more recent, the iterator + * is also called. * * @param new_hello a HELLO message * @param old_hello a HELLO message - * @param expiration_limit ignore addresses in old_hello + * @param expiration_limit ignore addresses in @a old_hello * that expired before the given time stamp * @param it iterator to call on each address - * @param it_cls closure for it + * @param it_cls closure for @a it */ void -GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message - *new_hello, - const struct GNUNET_HELLO_Message - *old_hello, - struct GNUNET_TIME_Absolute - expiration_limit, +GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message *new_hello, + const struct GNUNET_HELLO_Message *old_hello, + struct GNUNET_TIME_Absolute expiration_limit, GNUNET_HELLO_AddressIterator it, void *it_cls) { @@ -513,7 +632,11 @@ GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message dc.it = it; dc.it_cls = it_cls; dc.old_hello = old_hello; - GNUNET_HELLO_iterate_addresses (new_hello, GNUNET_NO, &delta_match, &dc); + GNUNET_assert (NULL == + GNUNET_HELLO_iterate_addresses (new_hello, + GNUNET_NO, + &delta_match, + &dc)); } @@ -534,27 +657,6 @@ GNUNET_HELLO_size (const struct GNUNET_HELLO_Message *hello) } -/** - * Get the public key from a HELLO message. - * - * @param hello the hello message - * @param publicKey where to copy the public key information, can be NULL - * @return #GNUNET_SYSERR if the HELLO was malformed - */ -int -GNUNET_HELLO_get_key (const struct GNUNET_HELLO_Message *hello, - struct GNUNET_CRYPTO_EddsaPublicKey *publicKey) -{ - uint16_t ret = ntohs (hello->header.size); - - if ((ret < sizeof (struct GNUNET_HELLO_Message)) || - (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO)) - return GNUNET_SYSERR; - *publicKey = hello->publicKey; - return GNUNET_OK; -} - - /** * Get the peer identity from a HELLO message. * @@ -597,25 +699,63 @@ GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello) } +/** + * Context used for comparing HELLOs in #GNUNET_HELLO_equals(). + */ struct EqualsContext { + /** + * Addresses that expired before this date are ignored for + * the comparisson. + */ struct GNUNET_TIME_Absolute expiration_limit; + /** + * Earliest expiration time for which we found a match + * with a difference in expiration times. + * At this time, the two HELLOs may start to diverge. + */ struct GNUNET_TIME_Absolute result; - const struct GNUNET_HELLO_Message *h2; + /** + * HELLO message to compare against. (First set to the second + * HELLO, then set to the first HELLO.) + */ + const struct GNUNET_HELLO_Message *ref; + /** + * Address we are currently looking for. + */ const struct GNUNET_HELLO_Address *address; + /** + * Expiration time of @e address. + */ struct GNUNET_TIME_Absolute expiration; + /** + * Did we find the address we were looking for? + */ int found; }; +/** + * Check if the given address matches the address we are currently + * looking for. If so, sets `found` to #GNUNET_YES and, if the + * expiration times for the two addresses differ, updates `result` to + * the minimum of our @a expiration and the existing value + * + * @param cls the `struct EqualsContext` + * @param address address from the reference HELLO + * @param expiration expiration time for @a address + * @return #GNUNET_YES if the address is expired or does not match + * #GNUNET_SYSERR if the address does match. + */ static int -find_other_matching (void *cls, const struct GNUNET_HELLO_Address *address, +find_other_matching (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct EqualsContext *ec = cls; @@ -626,27 +766,45 @@ find_other_matching (void *cls, const struct GNUNET_HELLO_Address *address, { ec->found = GNUNET_YES; if (expiration.abs_value_us < ec->expiration.abs_value_us) - ec->result = GNUNET_TIME_absolute_min (expiration, ec->result); + ec->result = GNUNET_TIME_absolute_min (expiration, + ec->result); return GNUNET_SYSERR; } return GNUNET_YES; } +/** + * Helper function for #GNUNET_HELLO_equals(). Checks + * if the given @a address exists also in the other HELLO; + * if not, the result time is set to zero and the iteration + * is aborted. + * + * @param cls the `struct EqualsContext` + * @param address address to locate + * @param expiration expiration time of the current address + * @return #GNUNET_OK if the address exists or is expired, + * #GNUNET_SYSERR if it was not found + */ static int -find_matching (void *cls, const struct GNUNET_HELLO_Address *address, +find_matching (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct EqualsContext *ec = cls; if (expiration.abs_value_us < ec->expiration_limit.abs_value_us) - return GNUNET_YES; + return GNUNET_OK; /* expired, we don't care */ ec->address = address; ec->expiration = expiration; ec->found = GNUNET_NO; - GNUNET_HELLO_iterate_addresses (ec->h2, GNUNET_NO, &find_other_matching, ec); - if (ec->found == GNUNET_NO) + GNUNET_HELLO_iterate_addresses (ec->ref, + GNUNET_NO, + &find_other_matching, + ec); + if (GNUNET_NO == ec->found) { + /* not found, we differ *now* */ ec->result = GNUNET_TIME_UNIT_ZERO_ABS; return GNUNET_SYSERR; } @@ -657,7 +815,7 @@ find_matching (void *cls, const struct GNUNET_HELLO_Address *address, /** * Test if two HELLO messages contain the same addresses. * If they only differ in expiration time, the lowest - * expiration time larger than 'now' where they differ + * expiration time larger than @a now where they differ * is returned. * * @param h1 first HELLO message @@ -665,9 +823,9 @@ find_matching (void *cls, const struct GNUNET_HELLO_Address *address, * @param now time to use for deciding which addresses have * expired and should not be considered at all * @return absolute time forever if the two HELLOs are - * totally identical; smallest timestamp >= now if + * totally identical; smallest timestamp >= @a now if * they only differ in timestamps; - * zero if the some addresses with expirations >= now + * zero if the some addresses with expirations >= @a now * do not match at all */ struct GNUNET_TIME_Absolute @@ -678,26 +836,42 @@ GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1, struct EqualsContext ec; if (h1->header.type != h2->header.type) - return GNUNET_TIME_UNIT_ZERO_ABS; - + return GNUNET_TIME_UNIT_ZERO_ABS; if (0 != - memcmp (&h1->publicKey, &h2->publicKey, + memcmp (&h1->publicKey, + &h2->publicKey, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey))) return GNUNET_TIME_UNIT_ZERO_ABS; ec.expiration_limit = now; ec.result = GNUNET_TIME_UNIT_FOREVER_ABS; - ec.h2 = h2; - GNUNET_HELLO_iterate_addresses (h1, GNUNET_NO, &find_matching, &ec); + ec.ref = h2; + GNUNET_HELLO_iterate_addresses (h1, + GNUNET_NO, + &find_matching, + &ec); if (ec.result.abs_value_us == GNUNET_TIME_UNIT_ZERO.rel_value_us) return ec.result; - ec.h2 = h1; - GNUNET_HELLO_iterate_addresses (h2, GNUNET_NO, &find_matching, &ec); + ec.ref = h1; + GNUNET_HELLO_iterate_addresses (h2, + GNUNET_NO, + &find_matching, + &ec); return ec.result; } +/** + * Iterator to find the time when the last address will expire. + * Updates the maximum value stored in @a cls. + * + * @param cls where to store the max, a `struct GNUNET_TIME_Absolute` + * @param address an address (ignored) + * @param expiration expiration time for @a address + * @return #GNUNET_OK (always) + */ static int -find_max_expire (void *cls, const struct GNUNET_HELLO_Address *address, +find_max_expire (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct GNUNET_TIME_Absolute *max = cls; @@ -718,11 +892,15 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg) { struct GNUNET_TIME_Absolute ret; - ret.abs_value_us = 0; - GNUNET_HELLO_iterate_addresses (msg, GNUNET_NO, &find_max_expire, &ret); + ret = GNUNET_TIME_UNIT_ZERO_ABS; + GNUNET_HELLO_iterate_addresses (msg, + GNUNET_NO, + &find_max_expire, + &ret); return ret; } + /** * GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER". * The specific structure of "IDENTIFIER" depends on the module and @@ -766,55 +944,19 @@ GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg) */ -/* ************************* Compose HELLO URI ************************** */ - -#if 0 -/** - * 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; -} -#endif - /** * Function that is called on each address of this peer. * Expands the corresponding URI string. * - * @param cls the 'GNUNET_HELLO_GetUriContext' + * @param cls the `struct GNUNET_HELLO_ComposeUriContext` * @param address address to add * @param expiration expiration time for the address - * @return GNUNET_OK (continue iteration). + * @return #GNUNET_OK (continue iteration). */ static int -add_address_to_uri (void *cls, const struct GNUNET_HELLO_Address *address, +add_address_to_uri (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { struct GNUNET_HELLO_ComposeUriContext *ctx = cls; @@ -829,7 +971,7 @@ add_address_to_uri (void *cls, const struct GNUNET_HELLO_Address *address, time_t seconds; papi = ctx->plugins_find (address->transport_name); - if (papi == NULL) + if (NULL == papi) { /* Not an error - we might just not have the right plugin. */ return GNUNET_OK; @@ -841,14 +983,18 @@ add_address_to_uri (void *cls, const struct GNUNET_HELLO_Address *address, address->transport_name); return GNUNET_OK; } - addr = papi->address_to_string (papi->cls, address->address, address->address_length); - - if ( (addr == NULL) || (strlen(addr) == 0) ) + addr = papi->address_to_string (papi->cls, + address->address, + address->address_length); + if ( (NULL == addr) || + (0 == strlen(addr)) ) return GNUNET_OK; addr_dup = GNUNET_strdup (addr); if (NULL != (pos = strstr (addr_dup, "_server"))) - memcpy (pos, client_str, strlen(client_str)); /* Replace all server addresses with client addresses */ + GNUNET_memcpy (pos, + client_str, + strlen (client_str)); /* Replace all server addresses with client addresses */ seconds = expiration.abs_value_us / 1000LL / 1000LL; t = gmtime (&seconds); @@ -857,7 +1003,10 @@ add_address_to_uri (void *cls, const struct GNUNET_HELLO_Address *address, "%s%c%s%c%s%c%s", ctx->uri, GNUNET_HELLO_URI_SEP, - strftime (tbuf, sizeof (tbuf), "%Y%m%d%H%M%S", t) ? tbuf : "0", + strftime (tbuf, + sizeof (tbuf), + "%Y%m%d%H%M%S", + t) ? tbuf : "0", GNUNET_HELLO_URI_SEP, address->transport_name, GNUNET_HELLO_URI_SEP, @@ -881,17 +1030,21 @@ GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello, GNUNET_HELLO_TransportPluginsFind plugins_find) { struct GNUNET_HELLO_ComposeUriContext ctx; - ctx.plugins_find = plugins_find; - - char *pkey = GNUNET_CRYPTO_eddsa_public_key_to_string (&(hello->publicKey)); + char *pkey; - GNUNET_asprintf (&(ctx.uri), + ctx.plugins_find = plugins_find; + pkey = GNUNET_CRYPTO_eddsa_public_key_to_string (&hello->publicKey); + GNUNET_asprintf (&ctx.uri, "%s%s", - (GNUNET_YES == GNUNET_HELLO_is_friend_only (hello)) ? GNUNET_FRIEND_HELLO_URI_PREFIX : GNUNET_HELLO_URI_PREFIX, + (GNUNET_YES == GNUNET_HELLO_is_friend_only (hello)) + ? GNUNET_FRIEND_HELLO_URI_PREFIX + : GNUNET_HELLO_URI_PREFIX, pkey); GNUNET_free (pkey); - - GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &add_address_to_uri, &ctx); + GNUNET_HELLO_iterate_addresses (hello, + GNUNET_NO, + &add_address_to_uri, + &ctx); return ctx.uri; } @@ -903,13 +1056,15 @@ GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello, * We're building a HELLO. Parse the next address from the * parsing context and append it. * - * @param cls the 'struct GNUNET_HELLO_AddressParsingContext' + * @param cls the `struct GNUNET_HELLO_ParseUriContext` * @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, GNUNET_SYSERR on error + * @return number of bytes added to buffer, #GNUNET_SYSERR on error */ static ssize_t -add_address_to_hello (void *cls, size_t max, void *buffer) +add_address_to_hello (void *cls, + size_t max, + void *buffer) { struct GNUNET_HELLO_ParseUriContext *ctx = cls; const char *tname; @@ -926,7 +1081,6 @@ add_address_to_hello (void *cls, size_t max, void *buffer) struct GNUNET_HELLO_Address haddr; ssize_t ret; - if (NULL == ctx->pos) return GNUNET_SYSERR; if (GNUNET_HELLO_URI_SEP != ctx->pos[0]) @@ -937,7 +1091,8 @@ add_address_to_hello (void *cls, size_t max, void *buffer) } ctx->pos++; - if ('0' == ctx->pos[0] && GNUNET_HELLO_URI_SEP == ctx->pos[1]) + if ( ('0' == ctx->pos[0]) && + (GNUNET_HELLO_URI_SEP == ctx->pos[1]) ) { expire = GNUNET_TIME_UNIT_FOREVER_ABS; tname = ctx->pos + 1; @@ -977,7 +1132,8 @@ add_address_to_hello (void *cls, size_t max, void *buffer) return GNUNET_SYSERR; } tname++; - address = strchr (tname, (int) GNUNET_HELLO_URI_SEP); + address = strchr (tname, + (int) GNUNET_HELLO_URI_SEP); if (NULL == address) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -1034,7 +1190,10 @@ add_address_to_hello (void *cls, size_t max, void *buffer) haddr.address_length = addr_len; haddr.address = addr; haddr.transport_name = plugin_name; - ret = GNUNET_HELLO_add_address (&haddr, expire, buffer, max); + ret = GNUNET_HELLO_add_address (&haddr, + expire, + buffer, + max); ctx->counter_added ++; GNUNET_free (addr); GNUNET_free (plugin_name); @@ -1049,7 +1208,7 @@ add_address_to_hello (void *cls, size_t max, void *buffer) * @param pubkey Pointer to struct where public key is parsed * @param hello Pointer to struct where hello message is parsed * @param plugins_find Function to find transport plugins by name - * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors + * @return #GNUNET_OK on success, #GNUNET_SYSERR if the URI was invalid, #GNUNET_NO on other errors */ int GNUNET_HELLO_parse_uri (const char *uri, @@ -1066,18 +1225,18 @@ GNUNET_HELLO_parse_uri (const char *uri, GNUNET_HELLO_URI_PREFIX, strlen (GNUNET_HELLO_URI_PREFIX))) { - pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)]; - friend_only = GNUNET_NO; + pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)]; + friend_only = GNUNET_NO; } else if (0 == strncmp (uri, GNUNET_FRIEND_HELLO_URI_PREFIX, strlen (GNUNET_FRIEND_HELLO_URI_PREFIX))) { - pks = &uri[strlen (GNUNET_FRIEND_HELLO_URI_PREFIX)]; - friend_only = GNUNET_YES; + pks = &uri[strlen (GNUNET_FRIEND_HELLO_URI_PREFIX)]; + friend_only = GNUNET_YES; } else - return GNUNET_SYSERR; + return GNUNET_SYSERR; exc = strchr (pks, GNUNET_HELLO_URI_SEP); if (GNUNET_OK != @@ -1092,11 +1251,15 @@ GNUNET_HELLO_parse_uri (const char *uri, ctx.counter_total = 0; ctx.counter_added = 0; ctx.plugins_find = plugins_find; - *hello = GNUNET_HELLO_create (pubkey, &add_address_to_hello, &ctx, friend_only); + *hello = GNUNET_HELLO_create (pubkey, + &add_address_to_hello, + &ctx, + friend_only); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("HELLO URI contained %u addresses, added %u addresses\n"), - ctx.counter_total, ctx.counter_added); + "HELLO URI contained %u addresses, added %u addresses\n", + ctx.counter_total, + ctx.counter_added); return ctx.ret; }