From: Christian Grothoff Date: Sat, 10 Apr 2010 21:05:27 +0000 (+0000) Subject: work on HELLO X-Git-Tag: initial-import-from-subversion-38251~22201 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=8a9ac8c92b1fb30c91c700d42e84749cc8aabb68;p=oweals%2Fgnunet.git work on HELLO --- diff --git a/AUTHORS b/AUTHORS index 6e30bb7a9..1e58d0b51 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,9 +1,10 @@ Primary developers (0.9.x series): Christian Grothoff Heikki Lindholm -Nils Durner +Matthias Wachs Milan Bouchet-Valat Nathan Evans +Nils Durner Code contributions also came from: Adam Warrington [ UPnP ] @@ -76,8 +77,7 @@ new GNU in Net: Nicklas Larsson Maintainers: FreeBSD : Kirill Ponomarew -Debian GNU/Linux: Daniel Baumann and - Arnaud Kyheng +Debian GNU/Linux: Daniel Baumann OS X : Jussi Eloranta diff --git a/TODO b/TODO index 83f25cf3a..868cc5b62 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,12 @@ 0.9.0pre0 [April]: * HOSTLIST: seems to have NO 'tcp' in it, so cannot have any addresses!? [CG] +* FS-acceptance testing [CG] +* Release checks: + - portability + - coverity + - clang + - cppcheck +* ChangeLog update * WWW: - Get IPv6 hooked up [AK, after April 12th] - change DNS [CG, need DNS] @@ -15,8 +22,6 @@ - only connect() sockets that are ready (select()) [Nils] [On W32, we need to select after calling socket before doing connect etc.] -* HELLO: [CG] - - need function to test "equivalency" of HELLOs (or integrate with "merge"?); use in PEERINFO * SETUP: - design & implement new setup tool * TBENCH: [MW] diff --git a/src/hello/hello.c b/src/hello/hello.c index 4ddeebd03..51575ebaf 100644 --- a/src/hello/hello.c +++ b/src/hello/hello.c @@ -510,6 +510,7 @@ GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello, return GNUNET_OK; } + /** * Get the header from a HELLO message, used so other code * can correctly send HELLO messages. @@ -529,4 +530,125 @@ GNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello) return &hello->header; } + +struct EqualsContext +{ + struct GNUNET_TIME_Absolute expiration_limit; + + struct GNUNET_TIME_Absolute result; + + const struct GNUNET_HELLO_Message *h2; + + const char *tname; + + const void *addr; + + struct GNUNET_TIME_Absolute expiration; + + size_t addrlen; + + int found; +}; + + +static int +find_other_matching (void *cls, + const char *tname, + struct GNUNET_TIME_Absolute expiration, + const void *addr, size_t addrlen) +{ + struct EqualsContext *ec = cls; + + if (expiration.value < ec->expiration_limit.value) + return GNUNET_YES; + if ( (addrlen == ec->addrlen) && + (0 == strcmp (tname, + ec->tname)) && + (0 == memcmp (addr, + ec->addr, + addrlen)) ) + { + ec->found = GNUNET_YES; + if (expiration.value < ec->expiration.value) + { + ec->result = GNUNET_TIME_absolute_min (expiration, + ec->result); + } + return GNUNET_SYSERR; + } + return GNUNET_YES; +} + + +static int +find_matching (void *cls, + const char *tname, + struct GNUNET_TIME_Absolute expiration, + const void *addr, size_t addrlen) +{ + struct EqualsContext *ec = cls; + + if (expiration.value < ec->expiration_limit.value) + return GNUNET_YES; + ec->tname = tname; + ec->expiration = expiration; + ec->addr = addr; + ec->addrlen = addrlen; + ec->found = GNUNET_NO; + GNUNET_HELLO_iterate_addresses (ec->h2, + GNUNET_NO, + &find_other_matching, + ec); + if (ec->found == GNUNET_NO) + { + ec->result = GNUNET_TIME_UNIT_ZERO_ABS; + return GNUNET_SYSERR; + } + return GNUNET_OK; +} + +/** + * 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 + * is returned. + * + * @param h1 first HELLO message + * @param h2 the second HELLO message + * @param now time to use for deciding which addresses have + * expired and should not be considered at all + * @return absolute time zero if the two HELLOs are + * totally identical; smallest timestamp >= now if + * they only differ in timestamps; + * forever if the some addresses with expirations >= now + * do not match at all + */ +struct GNUNET_TIME_Absolute +GNUNET_HELLO_equals (const struct + GNUNET_HELLO_Message *h1, + const struct + GNUNET_HELLO_Message *h2, + struct GNUNET_TIME_Absolute now) +{ + struct EqualsContext ec; + + ec.expiration_limit = now; + ec.result = GNUNET_TIME_UNIT_FOREVER_ABS; + ec.h2 = h2; + GNUNET_HELLO_iterate_addresses (h1, + GNUNET_NO, + &find_matching, + &ec); + if (ec.result.value == + GNUNET_TIME_UNIT_ZERO.value) + return ec.result; + ec.h2 = h1; + GNUNET_HELLO_iterate_addresses (h2, + GNUNET_NO, + &find_matching, + &ec); + return ec.result; +} + + /* end of hello.c */ diff --git a/src/include/gnunet_hello_lib.h b/src/include/gnunet_hello_lib.h index 73f84bc43..ca5e29284 100644 --- a/src/include/gnunet_hello_lib.h +++ b/src/include/gnunet_hello_lib.h @@ -120,6 +120,29 @@ struct GNUNET_HELLO_Message *GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h2); +/** + * 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 + * is returned. + * + * @param h1 first HELLO message + * @param h2 the second HELLO message + * @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 + * they only differ in timestamps; + * zero if the some addresses with expirations >= now + * do not match at all + */ +struct GNUNET_TIME_Absolute +GNUNET_HELLO_equals (const struct + GNUNET_HELLO_Message *h1, + const struct + GNUNET_HELLO_Message *h2, + struct GNUNET_TIME_Absolute now); + /** * Iterator callback to go over all addresses. diff --git a/src/peerinfo/gnunet-service-peerinfo.c b/src/peerinfo/gnunet-service-peerinfo.c index 5c3f2dfbf..aa2047c7c 100644 --- a/src/peerinfo/gnunet-service-peerinfo.c +++ b/src/peerinfo/gnunet-service-peerinfo.c @@ -441,6 +441,7 @@ bind_address (const struct GNUNET_PeerIdentity *peer, char *fn; struct HostEntry *host; struct GNUNET_HELLO_Message *mrg; + struct GNUNET_TIME_Absolute delta; add_host_to_known_hosts (peer); host = lookup_host_entry (peer); @@ -453,8 +454,14 @@ bind_address (const struct GNUNET_PeerIdentity *peer, else { mrg = GNUNET_HELLO_merge (host->hello, hello); - /* FIXME: check if old and merged hello are equal, - and if so, bail out early... */ + delta = GNUNET_HELLO_equals (mrg, + host->hello, + GNUNET_TIME_absolute_get ()); + if (delta.value == GNUNET_TIME_UNIT_FOREVER_ABS.value) + { + GNUNET_free (mrg); + return; + } GNUNET_free (host->hello); host->hello = mrg; }