From 00da095d9d83afea982baa79b8075a35d41be834 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Fri, 16 Mar 2012 14:32:07 +0000 Subject: [PATCH] -pseu caching + test --- src/gns/Makefile.am | 18 +- src/gns/gnunet-service-gns.c | 3 +- src/gns/gnunet-service-gns_interceptor.c | 21 +- src/gns/gnunet-service-gns_interceptor.h | 1 + src/gns/gnunet-service-gns_resolver.c | 338 ++++++++++++- src/gns/gnunet-service-gns_resolver.h | 33 ++ src/gns/plugin_block_gns.c | 4 +- src/gns/test_gns_pseu_shorten.c | 610 +++++++++++++++++++++++ 8 files changed, 1011 insertions(+), 17 deletions(-) create mode 100644 src/gns/test_gns_pseu_shorten.c diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am index 61bf54f80..d31d5c4b1 100644 --- a/src/gns/Makefile.am +++ b/src/gns/Makefile.am @@ -35,7 +35,8 @@ check_PROGRAMS = \ test_gns_simple_get_authority \ test_gns_simple_lookup \ test_gns_simple_delegated_lookup \ - test_gns_dht_delegated_lookup + test_gns_dht_delegated_lookup \ + test_gns_pseu_shorten # test_gns_simple_lookup @@ -125,6 +126,21 @@ test_gns_simple_get_authority_DEPENDENCIES = \ $(top_builddir)/src/testing/libgnunettesting.la +test_gns_pseu_shorten_SOURCES = \ + test_gns_pseu_shorten.c +test_gns_pseu_shorten_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la +test_gns_pseu_shorten_DEPENDENCIES = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la \ + $(top_builddir)/src/dht/libgnunetdht.la \ + $(top_builddir)/src/gns/libgnunetgns.la \ + $(top_builddir)/src/testing/libgnunettesting.la + gnunet_gns_SOURCES = \ gnunet-gns.c gnunet_gns_LDADD = \ diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 182655005..9332eba93 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c @@ -713,6 +713,7 @@ handle_lookup(void *cls, clh->type = ntohl(sh_msg->type); gns_resolver_lookup_record(zone_hash, clh->type, name, + zone_key, &send_lookup_response, clh); } @@ -799,7 +800,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_log(GNUNET_ERROR_TYPE_INFO, "DNS hijacking enabled... connecting to service.\n"); - if (gns_interceptor_init(zone_hash, c) == GNUNET_SYSERR) + if (gns_interceptor_init(zone_hash, zone_key, c) == GNUNET_SYSERR) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to enable the dns interceptor!\n"); diff --git a/src/gns/gnunet-service-gns_interceptor.c b/src/gns/gnunet-service-gns_interceptor.c index 069975fc9..25cad7ead 100644 --- a/src/gns/gnunet-service-gns_interceptor.c +++ b/src/gns/gnunet-service-gns_interceptor.c @@ -54,13 +54,18 @@ struct InterceptLookupHandle /** * Our handle to the DNS handler library */ -struct GNUNET_DNS_Handle *dns_handle; +static struct GNUNET_DNS_Handle *dns_handle; /** * The root zone for this interceptor */ static GNUNET_HashCode our_zone; +/** + * Our priv key + */ +static struct GNUNET_CRYPTO_RsaPrivateKey *our_key; + /** * Reply to dns request with the result from our lookup. * @@ -203,7 +208,9 @@ start_resolution_for_dns(struct GNUNET_DNS_RequestHandle *request, ilh->request_handle = request; /* Start resolution in our zone */ - gns_resolver_lookup_record(our_zone, q->type, q->name, &reply_to_dns, ilh); + gns_resolver_lookup_record(our_zone, q->type, q->name, + our_key, + &reply_to_dns, ilh); } @@ -300,14 +307,24 @@ handle_dns_request(void *cls, } +/** + * Initialized the interceptor + * + * @param zone the zone to work in + * @param the prov key of the zone (can be null, needed for caching) + * @param c the configuration + * @return GNUNET_OK on success + */ int gns_interceptor_init(GNUNET_HashCode zone, + struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_CONFIGURATION_Handle *c) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, "DNS hijacking enabled... connecting to service.\n"); our_zone = zone; + our_key = key; /** * Do gnunet dns init here */ diff --git a/src/gns/gnunet-service-gns_interceptor.h b/src/gns/gnunet-service-gns_interceptor.h index 03b91856e..855b034b1 100644 --- a/src/gns/gnunet-service-gns_interceptor.h +++ b/src/gns/gnunet-service-gns_interceptor.h @@ -10,6 +10,7 @@ */ int gns_interceptor_init(GNUNET_HashCode zone, + struct GNUNET_CRYPTO_RsaPrivateKey *key, const struct GNUNET_CONFIGURATION_Handle *c); void diff --git a/src/gns/gnunet-service-gns_resolver.c b/src/gns/gnunet-service-gns_resolver.c index 0b11e980f..41c2c0de0 100644 --- a/src/gns/gnunet-service-gns_resolver.c +++ b/src/gns/gnunet-service-gns_resolver.c @@ -54,6 +54,324 @@ static struct GNUNET_NAMESTORE_Handle *namestore_handle; */ static struct GNUNET_DHT_Handle *dht_handle; +/** + * Namestore calls this function if we have record for this name. + * (or with rd_count=0 to indicate no matches) + * + * @param cls the pending query + * @param key the key of the zone we did the lookup + * @param expiration expiration date of the namestore entry + * @param name the name for which we need an authority + * @param rd_count the number of records with 'name' + * @param rd the record data + * @param signature the signature of the authority for the record data + */ +static void +process_pseu_lookup_ns(void* cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, + struct GNUNET_TIME_Absolute expiration, + const char *name, unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; + struct GNUNET_NAMESTORE_RecordData new_pkey; + + if (rd_count > 0) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Name %s already taken in NS!\n", name); + if (0 == strcmp(gph->name, name)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Intelligent replacement not implemented\n", name); + GNUNET_free(gph->new_name); + GNUNET_free(gph->name); + GNUNET_free(gph); + return; + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Trying delegated name %s\n", gph->name); + gph->new_name = gph->name; + GNUNET_NAMESTORE_lookup_record(namestore_handle, + &gph->zone, + gph->new_name, + GNUNET_GNS_RECORD_PSEU, + &process_pseu_lookup_ns, + gph); + return; + } + + /** name is free */ + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Name %s not taken in NS! Adding\n", gph->new_name); + + new_pkey.expiration = GNUNET_TIME_absolute_get_forever (); + new_pkey.data_size = sizeof(GNUNET_HashCode); + new_pkey.data = &gph->new_zone; + new_pkey.record_type = GNUNET_GNS_RECORD_PKEY; + GNUNET_NAMESTORE_record_create (namestore_handle, + gph->key, + gph->new_name, + &new_pkey, + NULL, //cont + NULL); //cls + GNUNET_free(gph->new_name); + GNUNET_free(gph->name); + GNUNET_free(gph); + +} + +/** + * process result of a dht pseu lookup + * + * @param gph the handle + * @param name the pseu result or NULL + */ +static void +process_pseu_result(struct GetPseuAuthorityHandle* gph, char* name) +{ + if (NULL == name) + { + gph->new_name = GNUNET_malloc(strlen(gph->name)+1); + memcpy(gph->new_name, name, strlen(gph->name)+1); + } + else + { + gph->new_name = GNUNET_malloc(strlen(name)+1); + memcpy(gph->new_name, name, strlen(name)+1); + } + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "Checking %s for collision in NS\n", gph->new_name); + + /** + * Check for collision + */ + GNUNET_NAMESTORE_lookup_record(namestore_handle, + &gph->zone, + gph->new_name, + GNUNET_GNS_RECORD_PSEU, + &process_pseu_lookup_ns, + gph); +} + +/** + * Handle timeout for dht request + * + * @param cls the request handle as closure + * @param tc the task context + */ +static void +handle_auth_discovery_timeout(void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "dht lookup for query PSEU timed out.\n"); + GNUNET_DHT_get_stop (gph->get_handle); + process_pseu_result(gph, NULL); +} + +/** + * Function called when we find a PSEU entry in the DHT + * + * @param cls the request handle + * @param exp lifetime + * @param key the key the record was stored under + * @param get_path get path + * @param get_path_length get path length + * @param put_path put path + * @param put_path_length put path length + * @param type the block type + * @param size the size of the record + * @param data the record data + */ +static void +process_auth_discovery_dht_result(void* cls, + struct GNUNET_TIME_Absolute exp, + const GNUNET_HashCode * key, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, + enum GNUNET_BLOCK_Type type, + size_t size, const void *data) +{ + struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls; + struct GNSNameRecordBlock *nrb; + char* rd_data = (char*)data; + char* name; + int num_records; + size_t rd_size; + int i; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "got dht result (size=%d)\n", size); + + if (data == NULL) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "got dht result null!\n", size); + GNUNET_break(0); + GNUNET_free(gph->new_name); + GNUNET_free(gph->name); + GNUNET_free(gph); + return; + } + + nrb = (struct GNSNameRecordBlock*)data; + + /* stop lookup and timeout task */ + GNUNET_DHT_get_stop (gph->get_handle); + GNUNET_SCHEDULER_cancel(gph->dht_timeout); + + gph->get_handle = NULL; + + nrb = (struct GNSNameRecordBlock*)data; + + name = (char*)&nrb[1]; + num_records = ntohl(nrb->rd_count); + { + struct GNUNET_NAMESTORE_RecordData rd[num_records]; + + rd_data += strlen(name) + 1 + sizeof(struct GNSNameRecordBlock); + rd_size = size - strlen(name) - 1 - sizeof(struct GNSNameRecordBlock); + + if (GNUNET_SYSERR == GNUNET_NAMESTORE_records_deserialize (rd_size, + rd_data, + num_records, + rd)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error deserializing data!\n"); + GNUNET_break(0); + GNUNET_free(gph->new_name); + GNUNET_free(gph->name); + GNUNET_free(gph); + return; + } + + for (i=0; inew_name); + GNUNET_free(gph->name); + GNUNET_free(gph); + } + else + { + /** + * No name found. + * check dht + */ + uint32_t xquery; + GNUNET_HashCode name_hash; + GNUNET_HashCode lookup_key; + struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string; + + GNUNET_CRYPTO_hash("+", strlen("+"), &name_hash); + GNUNET_CRYPTO_hash_xor(&name_hash, &gph->new_zone, &lookup_key); + GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, + "starting dht lookup for %s with key: %s\n", + "+", (char*)&lookup_key_string); + + gph->dht_timeout = GNUNET_SCHEDULER_add_delayed(DHT_LOOKUP_TIMEOUT, + &handle_auth_discovery_timeout, gph); + + xquery = htonl(GNUNET_GNS_RECORD_PSEU); + + gph->get_handle = GNUNET_DHT_get_start(dht_handle, + DHT_OPERATION_TIMEOUT, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + &lookup_key, + DHT_GNS_REPLICATION_LEVEL, + GNUNET_DHT_RO_NONE, + &xquery, + sizeof(xquery), + &process_auth_discovery_dht_result, + gph); + + } +} + + +/** + * Callback for new authories + * + * @param name the name given by delegation + * @param zone the authority + * @param the private key of our authority + */ +static void process_discovered_authority(char* name, GNUNET_HashCode zone, + GNUNET_HashCode our_zone, + struct GNUNET_CRYPTO_RsaPrivateKey *key) +{ + struct GetPseuAuthorityHandle *gph; + size_t namelen; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New authority %s discovered\n", + name); + + gph = GNUNET_malloc(sizeof(struct GetPseuAuthorityHandle)); + namelen = strlen(name) + 1; + gph->name = GNUNET_malloc(namelen); + memcpy(gph->name, name, namelen); + + gph->new_zone = zone; + gph->zone = our_zone; + gph->key = key; + + GNUNET_NAMESTORE_zone_to_name (namestore_handle, + &our_zone, + &gph->new_zone, + &process_zone_to_name_discover, + gph); + +} + /** * Initialize the resolver * @@ -74,18 +392,6 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, return GNUNET_SYSERR; } -/** - * Set the callback to call when we discover a - * new authority via the DHT - * - * @param adb the callback to set - * -void -gns_resolver_set_auth_discovered_cb(AuthorityDiscoveredProcessor adb) -{ - auth_discovered = adb; -} -*/ /** * Helper function to free resolver handle @@ -584,6 +890,12 @@ process_delegation_result_dht(void* cls, GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head, rh->authority_chain_tail, auth); + + /** call process new authority */ + if (rh->priv_key) + process_discovered_authority(name, auth->zone, + rh->authority_chain_tail->zone, + rh->priv_key); } } @@ -1107,6 +1419,7 @@ void gns_resolver_lookup_record(GNUNET_HashCode zone, uint32_t record_type, const char* name, + struct GNUNET_CRYPTO_RsaPrivateKey *key, RecordLookupProcessor proc, void* cls) { @@ -1131,6 +1444,7 @@ gns_resolver_lookup_record(GNUNET_HashCode zone, rh->authority = zone; rh->proc_cls = rlh; + rh->priv_key = key; if (strcmp(GNUNET_GNS_TLD, name) == 0) { diff --git a/src/gns/gnunet-service-gns_resolver.h b/src/gns/gnunet-service-gns_resolver.h index 79e916015..a7f86a2d7 100644 --- a/src/gns/gnunet-service-gns_resolver.h +++ b/src/gns/gnunet-service-gns_resolver.h @@ -32,6 +32,7 @@ struct AuthorityChain /* handle to a resolution process */ struct ResolverHandle; + /** * processor for a resultion result * @@ -131,6 +132,8 @@ struct ResolverHandle /* status of the resolution result */ enum ResolutionStatus status; + struct GNUNET_CRYPTO_RsaPrivateKey *priv_key; + }; @@ -186,6 +189,33 @@ struct GetNameAuthorityHandle }; +/** + * Handle to a pseu lookup + */ +struct GetPseuAuthorityHandle +{ + /* the name given from delegation */ + char* name; + + /* name to store the pseu under */ + char* new_name; + + /* the zone of discovered authority */ + GNUNET_HashCode new_zone; + + /* the zone of our authority */ + GNUNET_HashCode zone; + + /* the private key of the zone to store the pseu in */ + struct GNUNET_CRYPTO_RsaPrivateKey *key; + + /* a handle for dht lookups. should be NULL if no lookups are in progress */ + struct GNUNET_DHT_GetHandle *get_handle; + + /* timeout task for dht lookups */ + GNUNET_SCHEDULER_TaskIdentifier dht_timeout; +}; + /** * Initialize the resolver * @@ -203,6 +233,8 @@ gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh, * * @param zone the root zone * @param record_type the record type to look up + * @param name the name to look up + * @param key optional private key for authority caching * @param proc the processor to call * @param cls the closure to pass to proc */ @@ -210,6 +242,7 @@ void gns_resolver_lookup_record(GNUNET_HashCode zone, uint32_t record_type, const char* name, + struct GNUNET_CRYPTO_RsaPrivateKey *key, RecordLookupProcessor proc, void* cls); diff --git a/src/gns/plugin_block_gns.c b/src/gns/plugin_block_gns.c index 46db6a22a..19495f243 100644 --- a/src/gns/plugin_block_gns.c +++ b/src/gns/plugin_block_gns.c @@ -74,6 +74,8 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, int rd_len; uint32_t record_xquery; unsigned int record_match; + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "RB SIZE %d\n", reply_block_size); if (type != GNUNET_BLOCK_TYPE_GNS_NAMERECORD) return GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED; @@ -166,7 +168,7 @@ block_plugin_gns_evaluate (void *cls, enum GNUNET_BLOCK_Type type, rd, &nrb->signature)) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Signature invalid\n"); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Signature invalid for name %s\n"); return GNUNET_BLOCK_EVALUATION_RESULT_INVALID; } } diff --git a/src/gns/test_gns_pseu_shorten.c b/src/gns/test_gns_pseu_shorten.c new file mode 100644 index 000000000..a7f01de2c --- /dev/null +++ b/src/gns/test_gns_pseu_shorten.c @@ -0,0 +1,610 @@ +/* + This file is part of GNUnet. + (C) 2009 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + 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. +*/ +/** + * @file gns/test_gns_pseu_shorten.c + * @brief base testcase for testing on the fly pseu import and shorten + * + */ +#include "platform.h" +#include "gnunet_testing_lib.h" +#include "gnunet_core_service.h" +#include "block_gns.h" +#include "gnunet_signatures.h" +#include "gnunet_namestore_service.h" +#include "../namestore/namestore.h" +#include "gnunet_dnsparser_lib.h" +#include "gnunet_dht_service.h" +#include "gnunet_gns_service.h" + +/* DEFINES */ +#define VERBOSE GNUNET_YES + +/* Timeout for entire testcase */ +#define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5) + +/* If number of peers not in config file, use this number */ +#define DEFAULT_NUM_PEERS 2 + +/* test records to resolve */ +#define TEST_DOMAIN "www.alice.bob.gnunet" +#define TEST_IP "127.0.0.1" +#define TEST_RECORD_NAME "www" + +#define TEST_AUTHORITY_BOB "bob" +#define TEST_AUTHORITY_ALICE "alice" +#define TEST_PSEU_ALICE "carol" +#define TEST_EXPECTED_RESULT "www.carol.gnunet" + +#define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) + +/* Globals */ + +/** + * Directory to store temp data in, defined in config file + */ +static char *test_directory; + +struct GNUNET_TESTING_Daemon *d1; + + +/* Task handle to use to schedule test failure */ +GNUNET_SCHEDULER_TaskIdentifier die_task; + +/* Global return value (0 for success, anything else for failure) */ +static int ok; + +static struct GNUNET_NAMESTORE_Handle *namestore_handle; + +static struct GNUNET_GNS_Handle *gns_handle; + +static struct GNUNET_DHT_Handle *dht_handle; + +const struct GNUNET_CONFIGURATION_Handle *cfg; + +struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded alice_pkey; +struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded bob_pkey; +struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded our_pkey; +struct GNUNET_CRYPTO_RsaPrivateKey *alice_key; +struct GNUNET_CRYPTO_RsaPrivateKey *bob_key; +struct GNUNET_CRYPTO_RsaPrivateKey *our_key; +GNUNET_HashCode alice_hash; +GNUNET_HashCode bob_hash; + +/** + * Check whether peers successfully shut down. + */ +void +shutdown_callback (void *cls, const char *emsg) +{ + if (emsg != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error on shutdown! ret=%d\n", ok); + if (ok == 0) + ok = 2; + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "done(ret=%d)!\n", ok); +} + +/** + * Called when gns shorten finishes + */ +static void +process_shorten_result(void* cls, const char* sname) +{ + GNUNET_GNS_disconnect(gns_handle); + ok = 0; + + if (sname == NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "shorten test failed!\n"); + ok = 1; + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "%s shortened to %s\n", (char*)cls, sname); + if (0 != strcmp(sname, TEST_EXPECTED_RESULT)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "shorten test failed! (wanted: %s got: %s\n", + (char*)cls, sname); + ok = 1; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shorten test succeeded!\n"); + } + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Shutting down peer1!\n"); + GNUNET_TESTING_daemon_stop (d1, TIMEOUT, &shutdown_callback, NULL, + GNUNET_YES, GNUNET_NO); +} + +static void +do_shorten(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_GNS_shorten(gns_handle, TEST_DOMAIN, &process_shorten_result, +TEST_DOMAIN); +} + +static void +on_lookup_result(void *cls, uint32_t rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + struct in_addr a; + int i; + char* addr; + + if (rd_count == 0) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Lookup failed, rp_filtering?\n"); + ok = 2; + } + else + { + ok = 1; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls); + for (i=0; isignature = *sig; + nrb->public_key = alice_pkey; + nrb->rd_count = htonl(1); + memset(&nrb[1], 0, strlen("+") + 1); + strcpy((char*)&nrb[1], "+"); + nrb_data = (char*)&nrb[1]; + nrb_data += strlen("+") + 1; + + if (-1 == GNUNET_NAMESTORE_records_serialize (1, + &rd, + rd_payload_length, + nrb_data)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Record serialization failed!\n"); + ok = 3; + GNUNET_DHT_disconnect(dht_handle); + + + GNUNET_CRYPTO_rsa_key_free(our_key); + GNUNET_CRYPTO_rsa_key_free(bob_key); + GNUNET_CRYPTO_rsa_key_free(alice_key); + GNUNET_free(sig); + GNUNET_free (nrb); + return; + } + GNUNET_CRYPTO_hash("+", strlen("+"), &name_hash); + GNUNET_CRYPTO_hash(&alice_pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone_hash); + GNUNET_CRYPTO_hash_xor(&zone_hash, &name_hash, &xor_hash); + + rd_payload_length += sizeof(struct GNSNameRecordBlock) + + strlen("+") + 1; + + GNUNET_DHT_put (dht_handle, &xor_hash, + 0, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + rd.expiration, + DHT_OPERATION_TIMEOUT, + &commence_testing, + NULL); + + GNUNET_free(sig); + GNUNET_free (nrb); +} + +static void +put_www_dht(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct GNSNameRecordBlock *nrb; + GNUNET_HashCode name_hash; + GNUNET_HashCode xor_hash; + GNUNET_HashCode zone_hash; + uint32_t rd_payload_length; + char* nrb_data = NULL; + struct GNUNET_CRYPTO_RsaSignature *sig; + struct GNUNET_NAMESTORE_RecordData rd; + char* ip = TEST_IP; + struct in_addr *web = GNUNET_malloc(sizeof(struct in_addr)); + + rd.expiration = GNUNET_TIME_absolute_get_forever (); + GNUNET_assert(1 == inet_pton (AF_INET, ip, web)); + rd.data_size = sizeof(struct in_addr); + rd.data = web; + rd.record_type = GNUNET_DNSPARSER_TYPE_A; + + sig = GNUNET_NAMESTORE_create_signature(alice_key, + GNUNET_TIME_absolute_get_forever(), + TEST_RECORD_NAME, + &rd, 1); + rd_payload_length = GNUNET_NAMESTORE_records_get_size (1, &rd); + nrb = GNUNET_malloc(rd_payload_length + strlen(TEST_RECORD_NAME) + 1 + + sizeof(struct GNSNameRecordBlock)); + nrb->signature = *sig; + nrb->public_key = alice_pkey; + nrb->rd_count = htonl(1); + memset(&nrb[1], 0, strlen(TEST_RECORD_NAME) + 1); + strcpy((char*)&nrb[1], TEST_RECORD_NAME); + nrb_data = (char*)&nrb[1]; + nrb_data += strlen(TEST_RECORD_NAME) + 1; + + if (-1 == GNUNET_NAMESTORE_records_serialize (1, + &rd, + rd_payload_length, + nrb_data)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Record serialization failed!\n"); + ok = 3; + GNUNET_DHT_disconnect(dht_handle); + + GNUNET_CRYPTO_rsa_key_free(our_key); + GNUNET_CRYPTO_rsa_key_free(bob_key); + GNUNET_CRYPTO_rsa_key_free(alice_key); + GNUNET_free(web); + GNUNET_free (nrb); + return; + } + GNUNET_CRYPTO_hash(TEST_RECORD_NAME, strlen(TEST_RECORD_NAME), &name_hash); + GNUNET_CRYPTO_hash(&alice_pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone_hash); + GNUNET_CRYPTO_hash_xor(&zone_hash, &name_hash, &xor_hash); + + rd_payload_length += sizeof(struct GNSNameRecordBlock) + + strlen(TEST_RECORD_NAME) + 1; + + GNUNET_DHT_put (dht_handle, &xor_hash, + 0, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + rd.expiration, + DHT_OPERATION_TIMEOUT, + &put_pseu_dht, + NULL); + + GNUNET_free(web); + GNUNET_free (nrb); +} + + +static void +put_pkey_dht(void *cls, int32_t success, const char *emsg) +{ + struct GNSNameRecordBlock *nrb; + GNUNET_HashCode name_hash; + GNUNET_HashCode xor_hash; + GNUNET_HashCode zone_hash; + uint32_t rd_payload_length; + char* nrb_data = NULL; + struct GNUNET_CRYPTO_RsaSignature *sig; + struct GNUNET_NAMESTORE_RecordData rd; + + rd.expiration = GNUNET_TIME_absolute_get_forever (); + rd.data_size = sizeof(GNUNET_HashCode); + rd.data = &alice_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + sig = GNUNET_NAMESTORE_create_signature(bob_key, + GNUNET_TIME_absolute_get_forever(), + TEST_AUTHORITY_ALICE, + &rd, + 1); + + rd_payload_length = GNUNET_NAMESTORE_records_get_size (1, &rd); + nrb = GNUNET_malloc(rd_payload_length + strlen(TEST_AUTHORITY_ALICE) + 1 + + sizeof(struct GNSNameRecordBlock)); + nrb->signature = *sig; + nrb->public_key = bob_pkey; + nrb->rd_count = htonl(1); + memset(&nrb[1], 0, strlen(TEST_AUTHORITY_ALICE) + 1); + strcpy((char*)&nrb[1], TEST_AUTHORITY_ALICE); + nrb_data = (char*)&nrb[1]; + nrb_data += strlen(TEST_AUTHORITY_ALICE) + 1; + + if (-1 == GNUNET_NAMESTORE_records_serialize (1, + &rd, + rd_payload_length, + nrb_data)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Record serialization failed!\n"); + ok = 3; + + GNUNET_CRYPTO_rsa_key_free(our_key); + GNUNET_CRYPTO_rsa_key_free(bob_key); + GNUNET_CRYPTO_rsa_key_free(alice_key); + GNUNET_free(sig); + GNUNET_free (nrb); + return; + } + + + GNUNET_CRYPTO_hash(TEST_AUTHORITY_ALICE, + strlen(TEST_AUTHORITY_ALICE), &name_hash); + GNUNET_CRYPTO_hash(&bob_pkey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &zone_hash); + GNUNET_CRYPTO_hash_xor(&zone_hash, &name_hash, &xor_hash); + + rd_payload_length += sizeof(struct GNSNameRecordBlock) + + strlen(TEST_AUTHORITY_ALICE) + 1; + GNUNET_DHT_put (dht_handle, &xor_hash, + 0, + GNUNET_DHT_RO_NONE, + GNUNET_BLOCK_TYPE_GNS_NAMERECORD, + rd_payload_length, + (char*)nrb, + rd.expiration, + DHT_OPERATION_TIMEOUT, + &put_www_dht, + NULL); + GNUNET_NAMESTORE_disconnect(namestore_handle, GNUNET_NO); + GNUNET_free (nrb); +} + +static void +do_lookup(void *cls, const struct GNUNET_PeerIdentity *id, + const struct GNUNET_CONFIGURATION_Handle *cfg, + struct GNUNET_TESTING_Daemon *d, const char *emsg) +{ + + + char* our_keyfile; + + + GNUNET_SCHEDULER_cancel (die_task); + + /* put records into namestore */ + namestore_handle = GNUNET_NAMESTORE_connect(cfg); + if (NULL == namestore_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to namestore\n"); + ok = -1; + return; + } + + /* dht */ + dht_handle = GNUNET_DHT_connect(cfg, 1); + if (NULL == dht_handle) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to connect to dht\n"); + ok = -1; + return; + } + + if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns", + "ZONEKEY", + &our_keyfile)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to get key from cfg\n"); + ok = -1; + return; + } + + our_key = GNUNET_CRYPTO_rsa_key_create_from_file (our_keyfile); + bob_key = GNUNET_CRYPTO_rsa_key_create (); + alice_key = GNUNET_CRYPTO_rsa_key_create (); + + GNUNET_free(our_keyfile); + + GNUNET_CRYPTO_rsa_key_get_public (our_key, &our_pkey); + GNUNET_CRYPTO_rsa_key_get_public (bob_key, &bob_pkey); + GNUNET_CRYPTO_rsa_key_get_public (alice_key, &alice_pkey); + GNUNET_CRYPTO_hash(&bob_pkey, sizeof(bob_pkey), &bob_hash); + GNUNET_CRYPTO_hash(&alice_pkey, sizeof(alice_pkey), &alice_hash); + + struct GNUNET_NAMESTORE_RecordData rd; + rd.expiration = GNUNET_TIME_absolute_get_forever (); + rd.data_size = sizeof(GNUNET_HashCode); + rd.data = &bob_hash; + rd.record_type = GNUNET_GNS_RECORD_PKEY; + + GNUNET_NAMESTORE_record_create (namestore_handle, + our_key, + TEST_AUTHORITY_BOB, + &rd, + &put_pkey_dht, + NULL); + + +} + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *c) +{ + cfg = c; + /* Get path from configuration file */ + if (GNUNET_YES != + GNUNET_CONFIGURATION_get_value_string (cfg, "paths", "servicehome", + &test_directory)) + { + ok = 404; + return; + } + + + /* Set up a task to end testing if peer start fails */ + die_task = + GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, + "didn't start all daemons in reasonable amount of time!!!"); + + /* Start alice */ + d1 = GNUNET_TESTING_daemon_start(cfg, TIMEOUT, GNUNET_NO, NULL, NULL, 0, + NULL, NULL, NULL, &do_lookup, NULL); +} + +static int +check () +{ + int ret; + + /* Arguments for GNUNET_PROGRAM_run */ + char *const argv[] = { "test-gns-dht-delegated-lookup", /* Name to give running binary */ + "-c", + "test_gns_simple_lookup.conf", /* Config file to use */ +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + /* Run the run function as a new program */ + ret = + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, + "test-gns-dht-delegated-lookup", "nohelp", options, &run, + &ok); + if (ret != GNUNET_OK) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "`test-gns-dht-delegated-lookup': Failed with error code %d\n", ret); + } + return ok; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + GNUNET_log_setup ("test-gns-simple-lookup", +#if VERBOSE + "DEBUG", +#else + "WARNING", +#endif + NULL); + ret = check (); + /** + * Need to remove base directory, subdirectories taken care + * of by the testing framework. + */ + return ret; +} + +/* end of test_gns_twopeer.c */ -- 2.25.1