/**
* Our handle to the namestore service
*/
-struct GNUNET_NAMESTORE_Handle *namestore_handle;
+static struct GNUNET_NAMESTORE_Handle *namestore_handle;
/**
* Resolver handle to the dht
*/
-struct GNUNET_DHT_Handle *dht_handle;
+static struct GNUNET_DHT_Handle *dht_handle;
/**
- * Connects resolver to the dht
+ * 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
-connect_to_dht()
+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)
{
- //FIXME
+ 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);
+ return;
+ }
+
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "Trying delegated name %s\n", gph->name);
+ memcpy(gph->new_name, gph->name, strlen(gph->name)+1);
+ 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(struct GNUNET_CRYPTO_ShortHashCode);
+ 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);
+
+}
+
+/**
+ * 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)
+ {
+ memcpy(gph->new_name, name, strlen(gph->name)+1);
+ }
+ else
+ {
+ 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);
+ 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);
+ return;
+ }
+
+ for (i=0; i<num_records; i++)
+ {
+ if ((strcmp(name, "+") == 0) &&
+ (rd[i].record_type == GNUNET_GNS_RECORD_PSEU))
+ {
+ /* found pseu */
+ process_pseu_result(gph, (char*)rd[i].data);
+ return;
+ }
+ }
+ }
+
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "no pseu in dht!\n");
+ process_pseu_result(gph, NULL);
+}
+
+/**
+ * Callback called by namestore for a zone to name
+ * result
+ *
+ * @param cls the closure
+ * @param zone_key the zone we queried
+ * @param expire the expiration time of the name
+ * @param name the name found or NULL
+ * @param rd_len number of records for the name
+ * @param rd the record data (PKEY) for the name
+ * @param signature the signature for the record data
+ */
+static void
+process_zone_to_name_discover(void *cls,
+ const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key,
+ struct GNUNET_TIME_Absolute expire,
+ const char *name,
+ unsigned int rd_len,
+ const struct GNUNET_NAMESTORE_RecordData *rd,
+ const struct GNUNET_CRYPTO_RsaSignature *signature)
+{
+ struct GetPseuAuthorityHandle* gph = (struct GetPseuAuthorityHandle*)cls;
+
+ /* we found a match in our own zone */
+ if (rd_len != 0)
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "name for zone in our root %d\n", strlen(name));
+ GNUNET_free(gph);
+ }
+ else
+ {
+ /**
+ * No name found.
+ * check dht
+ */
+ uint32_t xquery;
+ struct GNUNET_CRYPTO_ShortHashCode name_hash;
+ GNUNET_HashCode lookup_key;
+ struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string;
+ GNUNET_HashCode name_hash_double;
+ GNUNET_HashCode zone_hash_double;
+
+ GNUNET_CRYPTO_short_hash("+", strlen("+"), &name_hash);
+ GNUNET_CRYPTO_short_hash_double (&name_hash, &name_hash_double);
+ GNUNET_CRYPTO_short_hash_double (&gph->new_zone, &zone_hash_double);
+ GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &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,
+ struct GNUNET_CRYPTO_ShortHashCode zone,
+ struct GNUNET_CRYPTO_ShortHashCode 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;
+ 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
+ *
+ * @param nh the namestore handle
+ * @param dh the dht handle
+ * @return GNUNET_OK on success
+ */
+int
+gns_resolver_init(struct GNUNET_NAMESTORE_Handle *nh,
+ struct GNUNET_DHT_Handle *dh)
+{
+ namestore_handle = nh;
+ dht_handle = dh;
+ if ((namestore_handle != NULL) && (dht_handle != NULL))
+ {
+ return GNUNET_OK;
+ }
+ return GNUNET_SYSERR;
+}
+
/**
* Helper function to free resolver handle
if (NULL == rh)
return;
- GNUNET_free_non_null (rh->name);
- GNUNET_free_non_null (rh->authority_name);
-
ac = rh->authority_chain_head;
while (NULL != ac)
{
ac_next = ac->next;
- GNUNET_free_non_null (ac->name);
GNUNET_free(ac);
ac = ac_next;
}
int i;
int rd_size;
- GNUNET_HashCode zone, name_hash;
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "got dht result (size=%d)\n", size);
if (data == NULL)
}
- GNUNET_CRYPTO_hash(name, strlen(name), &name_hash);
- GNUNET_CRYPTO_hash_xor(key, &name_hash, &zone);
-
/**
* FIXME check pubkey against existing key in namestore?
* https://gnunet.org/bugs/view.php?id=2179
resolve_record_dht(struct ResolverHandle *rh)
{
uint32_t xquery;
- GNUNET_HashCode name_hash;
+ struct GNUNET_CRYPTO_ShortHashCode name_hash;
GNUNET_HashCode lookup_key;
+ GNUNET_HashCode name_hash_double;
+ GNUNET_HashCode zone_hash_double;
struct GNUNET_CRYPTO_HashAsciiEncoded lookup_key_string;
struct RecordLookupHandle *rlh = (struct RecordLookupHandle *)rh->proc_cls;
-
- GNUNET_CRYPTO_hash(rh->name, strlen(rh->name), &name_hash);
- GNUNET_CRYPTO_hash_xor(&name_hash, &rh->authority, &lookup_key);
+
+ GNUNET_CRYPTO_short_hash(rh->name, strlen(rh->name), &name_hash);
+ GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double);
+ GNUNET_CRYPTO_short_hash_double(&rh->authority, &zone_hash_double);
+ GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key);
GNUNET_CRYPTO_hash_to_enc (&lookup_key, &lookup_key_string);
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
struct ResolverHandle *rh;
struct RecordLookupHandle *rlh;
struct GNUNET_TIME_Relative remaining_time;
- GNUNET_HashCode zone;
+ struct GNUNET_CRYPTO_ShortHashCode zone;
rh = (struct ResolverHandle *) cls;
rlh = (struct RecordLookupHandle *)rh->proc_cls;
- GNUNET_CRYPTO_hash(key,
+ GNUNET_CRYPTO_short_hash(key,
sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
&zone);
remaining_time = GNUNET_TIME_absolute_get_remaining (expiration);
int i;
for (i=0; i<rd_count;i++)
{
-
+
if (rd[i].record_type != rlh->record_type)
continue;
char* rd_data = (char*) data;
int i;
int rd_size;
- GNUNET_HashCode zone, name_hash;
+ struct GNUNET_CRYPTO_ShortHashCode zone, name_hash;
+ GNUNET_HashCode zone_hash_double, name_hash_double;
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got DHT result\n");
{
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Authority found in DHT\n");
rh->answered = 1;
- memcpy(&rh->authority, rd[i].data, sizeof(GNUNET_HashCode));
+ memcpy(&rh->authority, rd[i].data, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
struct AuthorityChain *auth =
GNUNET_malloc(sizeof(struct AuthorityChain));
auth->zone = rh->authority;
- auth->name = GNUNET_malloc(strlen(rh->authority_name)+1);
memset(auth->name, 0, strlen(rh->authority_name)+1);
strcpy(auth->name, rh->authority_name);
GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head,
rh->authority_chain_tail,
auth);
+
+ /** try to import pkey if private key available */
+ if (rh->priv_key)
+ process_discovered_authority(name, auth->zone,
+ rh->authority_chain_tail->zone,
+ rh->priv_key);
}
}
- GNUNET_CRYPTO_hash(name, strlen(name), &name_hash);
- GNUNET_CRYPTO_hash_xor(key, &name_hash, &zone);
+ GNUNET_CRYPTO_short_hash(name, strlen(name), &name_hash);
+ GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double);
+ GNUNET_CRYPTO_hash_xor(key, &name_hash_double, &zone_hash_double);
+ GNUNET_CRYPTO_short_hash_from_truncation (&zone_hash_double, &zone);
/* Save to namestore */
- if (0 != GNUNET_CRYPTO_hash_cmp(&rh->authority_chain_tail->zone, &zone))
+ if (0 != GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_tail->zone,
+ &zone))
{
GNUNET_NAMESTORE_record_put (namestore_handle,
&nrb->public_key,
resolve_delegation_dht(rh);
return;
}
-
+
/**
- * should never get here unless false dht key/put
- * block plugin should handle this
- **/
- GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "DHT authority lookup error!\n");
- GNUNET_break(0);
+ * No pkey but name exists
+ */
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "DHT authority lookup found no match!\n");
+ rh->proc(rh->proc_cls, rh, 0, NULL);
}
+/**
+ * finish lookup
+ */
+static void
+finish_lookup(struct ResolverHandle *rh,
+ struct RecordLookupHandle* rlh,
+ unsigned int rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd)
+{
+ int i;
+ char* s_value;
+ char new_s_value[256];
+ char new_mx_value[sizeof(struct GNUNET_DNSPARSER_MxRecord)+256];
+ int s_len;
+ struct GNUNET_NAMESTORE_RecordData p_rd[rd_count];
+ char* pos;
+ char* trailer;
+ struct GNUNET_DNSPARSER_MxRecord *mx;
+
+ if (rd_count > 0)
+ memcpy(p_rd, rd, rd_count*sizeof(struct GNUNET_NAMESTORE_RecordData));
+
+ for (i = 0; i < rd_count; i++)
+ {
+
+ if (rd[i].record_type != GNUNET_GNS_RECORD_TYPE_NS &&
+ rd[i].record_type != GNUNET_GNS_RECORD_TYPE_CNAME &&
+ rd[i].record_type != GNUNET_GNS_RECORD_MX)
+ {
+ p_rd[i].data = rd[i].data;
+ continue;
+ }
+
+ /**
+ * for all those records we 'should'
+ * also try to resolve the A/AAAA records (RFC1035)
+ * FIXME
+ */
+ if (rd[i].record_type == GNUNET_GNS_RECORD_MX)
+ {
+ mx = (struct GNUNET_DNSPARSER_MxRecord*)rd[i].data;
+ s_value = (char*)&mx[1];
+ }
+ else
+ {
+ s_value = (char*)rd[i].data;
+ }
+
+ s_len = strlen(s_value)+1;
+
+ if (s_len < 3)
+ {
+ /* no postprocessing */
+ p_rd[i].data = rd[i].data;
+ continue;
+ }
+
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "Postprocessing %s\n", s_value);
+
+ if (0 == strcmp(s_value+s_len-3, ".+"))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "Expanding .+ in %s\n", s_value);
+ if (strcmp(rh->name, "+") == 0)
+ {
+ trailer = rlh->name;
+ }
+ else
+ {
+ trailer = rlh->name+strlen(rh->name)+1;
+ }
+ memset(new_s_value, 0, s_len+strlen(trailer)+strlen(GNUNET_GNS_TLD));
+ strcpy(new_s_value, s_value);
+ pos = new_s_value+s_len-2;
+ strcpy(pos, trailer);
+ pos += strlen(trailer);
+ if (rd[i].record_type == GNUNET_GNS_RECORD_MX)
+ {
+
+ p_rd[i].data_size = sizeof(struct GNUNET_DNSPARSER_MxRecord)
+ +strlen(new_s_value)+1;
+
+ p_rd[i].data = new_mx_value;
+ mx = (struct GNUNET_DNSPARSER_MxRecord*)p_rd[i].data;
+ mx->preference =
+ ((struct GNUNET_DNSPARSER_MxRecord*)rd[i].data)->preference;
+ memcpy((char*)&mx[1], new_s_value, strlen(new_s_value)+1);
+ mx->mxhost = (char*)&mx[1];
+ }
+ else
+ {
+ p_rd[i].data = new_s_value;
+ p_rd[i].data_size = strlen(new_s_value)+1;
+ }
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "Expanded to %s\n", new_s_value);
+ }
+ }
+
+ rlh->proc(rlh->proc_cls, rd_count, p_rd);
+ GNUNET_free(rlh);
+
+}
/**
* Process DHT lookup result for record.
const struct GNUNET_NAMESTORE_RecordData *rd)
{
struct RecordLookupHandle* rlh;
+
rlh = (struct RecordLookupHandle*)cls;
if (rd_count == 0)
{
"No records for %s found in DHT. Aborting\n",
rh->name);
/* give up, cannot resolve */
- rlh->proc(rlh->proc_cls, 0, NULL);
- GNUNET_free(rlh->name);
- GNUNET_free(rlh);
+ finish_lookup(rh, rlh, 0, NULL);
free_resolver_handle(rh);
return;
}
/* results found yay */
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Record resolved from DHT!");
- rlh->proc(rlh->proc_cls, rd_count, rd);
- GNUNET_free(rlh->name);
- GNUNET_free(rlh);
+
+ finish_lookup(rh, rlh, rd_count, rd);
free_resolver_handle(rh);
}
{
/* ns entry expired and not ours. try dht */
if (rh->status & (EXPIRED | !EXISTS) &&
- GNUNET_CRYPTO_hash_cmp(&rh->authority_chain_head->zone,
- &rh->authority_chain_tail->zone))
+ GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+ &rh->authority_chain_tail->zone))
{
rh->proc = &handle_record_dht;
resolve_record_dht(rh);
return;
}
/* give up, cannot resolve */
- rlh->proc(rlh->proc_cls, 0, NULL);
- GNUNET_free(rlh->name);
- GNUNET_free(rlh);
+ finish_lookup(rh, rlh, 0, NULL);
free_resolver_handle(rh);
return;
}
/* results found yay */
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Record resolved from namestore!");
- rlh->proc(rlh->proc_cls, rd_count, rd);
- GNUNET_free(rlh->name);
- GNUNET_free(rlh);
+
+ finish_lookup(rh, rlh, rd_count, rd);
free_resolver_handle(rh);
}
strcpy(dest, (name+len+1));
}
+/**
+ * Checks if name is in tld
+ *
+ * @param name the name to check
+ * @return GNUNET_YES or GNUNET_NO
+ */
+int
+is_tld(const char* name, const char* tld)
+{
+ int offset = 0;
+
+ if (strlen(name) <= strlen(tld))
+ {
+ return GNUNET_NO;
+ }
+
+ offset = strlen(name)-strlen(tld);
+ if (strcmp(name+offset, tld) != 0)
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_INFO,
+ "%s is not in .%s TLD\n", name, tld);
+ return GNUNET_NO;
+ }
+ return GNUNET_YES;
+}
+
/**
* DHT resolution for delegation finished. Processing result.
*
if (strcmp(rh->name, "") == 0)
{
+ if ((rlh->record_type == GNUNET_GNS_RECORD_PKEY))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "Resolved queried PKEY via DHT.\n");
+ finish_lookup(rh, rlh, rd_count, rd);
+ free_resolver_handle(rh);
+ return;
+ }
/* We resolved full name for delegation. resolving record */
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Resolved full name for delegation via DHT. resolving record '' in ns\n");
+ strcpy(rh->name, "+\0");
rh->proc = &handle_record_ns;
resolve_record_ns(rh);
return;
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Cannot fully resolve delegation for %s via DHT!\n",
rh->name);
- rlh->proc(rlh->proc_cls, 0, NULL);
- GNUNET_free(rlh->name);
- GNUNET_free(rlh);
+ finish_lookup(rh, rlh, 0, NULL);
free_resolver_handle(rh);
}
resolve_delegation_dht(struct ResolverHandle *rh)
{
uint32_t xquery;
- GNUNET_HashCode name_hash;
+ struct GNUNET_CRYPTO_ShortHashCode name_hash;
+ GNUNET_HashCode name_hash_double;
+ GNUNET_HashCode zone_hash_double;
GNUNET_HashCode lookup_key;
-
- GNUNET_CRYPTO_hash(rh->authority_name,
+
+ GNUNET_CRYPTO_short_hash(rh->authority_name,
strlen(rh->authority_name),
&name_hash);
- GNUNET_CRYPTO_hash_xor(&name_hash, &rh->authority, &lookup_key);
+ GNUNET_CRYPTO_short_hash_double(&name_hash, &name_hash_double);
+ GNUNET_CRYPTO_short_hash_double(&rh->authority, &zone_hash_double);
+ GNUNET_CRYPTO_hash_xor(&name_hash_double, &zone_hash_double, &lookup_key);
rh->dht_timeout_task = GNUNET_SCHEDULER_add_delayed (DHT_LOOKUP_TIMEOUT,
&dht_authority_lookup_timeout,
if (strcmp(rh->name, "") == 0)
{
+ if ((rlh->record_type == GNUNET_GNS_RECORD_PKEY))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
+ "Resolved queried PKEY in NS.\n");
+ finish_lookup(rh, rlh, rd_count, rd);
+ free_resolver_handle(rh);
+ return;
+ }
/* We resolved full name for delegation. resolving record */
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
- "Resolved full name for delegation. resolving record ''\n");
+ "Resolved full name for delegation. resolving record '+'\n");
+ strcpy(rh->name, "+\0");
rh->proc = &handle_record_ns;
resolve_record_ns(rh);
return;
* or we are authority
**/
if ((rh->status & (EXISTS | !EXPIRED)) ||
- !GNUNET_CRYPTO_hash_cmp(&rh->authority_chain_head->zone,
+ !GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
&rh->authority_chain_tail->zone))
{
if (is_canonical(rh->name))
{
struct ResolverHandle *rh;
struct GNUNET_TIME_Relative remaining_time;
- GNUNET_HashCode zone;
- char* new_name;
+ struct GNUNET_CRYPTO_ShortHashCode zone;
+ char new_name[MAX_DNS_NAME_LENGTH];
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got %d records from authority lookup\n",
rd_count);
rh = (struct ResolverHandle *)cls;
- GNUNET_CRYPTO_hash(key,
+ GNUNET_CRYPTO_short_hash(key,
sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
&zone);
remaining_time = GNUNET_TIME_absolute_get_remaining (expiration);
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Adding %s back to %s\n",
rh->authority_name, rh->name);
- new_name = GNUNET_malloc(strlen(rh->name)
- + strlen(rh->authority_name) + 2);
memset(new_name, 0, strlen(rh->name) + strlen(rh->authority_name) + 2);
strcpy(new_name, rh->name);
strcpy(new_name+strlen(new_name)+1, ".");
strcpy(new_name+strlen(new_name)+2, rh->authority_name);
- GNUNET_free(rh->name);
- rh->name = new_name;
+ strcpy(rh->name, new_name);
}
rh->proc(rh->proc_cls, rh, 0, NULL);
return;
* Resolve rest of query with new authority
*/
GNUNET_assert(rd[i].record_type == GNUNET_GNS_RECORD_PKEY);
- memcpy(&rh->authority, rd[i].data, sizeof(GNUNET_HashCode));
+ memcpy(&rh->authority, rd[i].data, sizeof(struct GNUNET_CRYPTO_ShortHashCode));
struct AuthorityChain *auth = GNUNET_malloc(sizeof(struct AuthorityChain));
auth->zone = rh->authority;
- auth->name = GNUNET_malloc(strlen(rh->authority_name)+1);
memset(auth->name, 0, strlen(rh->authority_name)+1);
strcpy(auth->name, rh->authority_name);
GNUNET_CONTAINER_DLL_insert (rh->authority_chain_head,
* @param cls the closure to pass to proc
*/
void
-gns_resolver_lookup_record(GNUNET_HashCode zone,
+gns_resolver_lookup_record(struct GNUNET_CRYPTO_ShortHashCode zone,
uint32_t record_type,
const char* name,
+ struct GNUNET_CRYPTO_RsaPrivateKey *key,
RecordLookupProcessor proc,
void* cls)
{
struct ResolverHandle *rh;
struct RecordLookupHandle* rlh;
+ char string_hash[MAX_DNS_NAME_LENGTH]; //FIXME name len as soon as shorthash
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Starting resolution for %s (type=%d)!\n",
name, record_type);
+
+ if (is_canonical((char*)name) && (strcmp(GNUNET_GNS_TLD, name) != 0))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s is canonical and not gnunet -> cannot resolve!\n", name);
+ proc(cls, 0, NULL);
+ return;
+ }
+
rlh = GNUNET_malloc(sizeof(struct RecordLookupHandle));
rh = GNUNET_malloc(sizeof (struct ResolverHandle));
rh->authority = zone;
rh->proc_cls = rlh;
- rh->name = GNUNET_malloc(strlen(name)
- - strlen(GNUNET_GNS_TLD));
- memset(rh->name, 0,
- strlen(name)-strlen(GNUNET_GNS_TLD));
- memcpy(rh->name, name,
- strlen(name)-strlen(GNUNET_GNS_TLD) - 1);
- rh->authority_name = GNUNET_malloc(sizeof(char)*MAX_DNS_LABEL_LENGTH);
+ rh->priv_key = key;
+
+ if (strcmp(GNUNET_GNS_TLD, name) == 0)
+ {
+ /**
+ * Only 'gnunet' given
+ */
+ strcpy(rh->name, "\0");
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Checking for TLD...\n");
+ if (is_zkey_tld(name) == GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TLD is zkey\n");
+ /**
+ * This is a zkey tld
+ * build hash and use as initial authority
+ */
+ memset(rh->name, 0,
+ strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY));
+ memcpy(rh->name, name,
+ strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY) - 1);
+ pop_tld(rh->name, string_hash);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "ZKEY is %s!\n", string_hash);
+
+ if (GNUNET_OK != GNUNET_CRYPTO_short_hash_from_string(string_hash,
+ &rh->authority))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Cannot convert ZKEY %s to hash!\n", string_hash);
+ GNUNET_free(rh);
+ GNUNET_free(rlh);
+ proc(cls, 0, NULL);
+ return;
+ }
+
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TLD is gnunet\n");
+ /**
+ * Presumably GNUNET tld
+ */
+ memset(rh->name, 0,
+ strlen(name)-strlen(GNUNET_GNS_TLD));
+ memcpy(rh->name, name,
+ strlen(name)-strlen(GNUNET_GNS_TLD) - 1);
+ }
+ }
+
+ /**
+ * Initialize authority chain
+ */
rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain));
rh->authority_chain_head->prev = NULL;
rh->authority_chain_head->next = NULL;
rh->authority_chain_tail = rh->authority_chain_head;
- rh->authority_chain_head->zone = zone;
-
+ rh->authority_chain_head->zone = rh->authority;
+
+ /**
+ * Copy original query into lookup handle
+ */
rlh->record_type = record_type;
- rlh->name = GNUNET_malloc(strlen(name) + 1);
memset(rlh->name, 0, strlen(name) + 1);
- strcpy(rlh->name, name); //FIXME
+ strcpy(rlh->name, name);
rlh->proc = proc;
rlh->proc_cls = cls;
struct NameShortenHandle* nsh = (struct NameShortenHandle*)rh->proc_cls;
struct AuthorityChain *next_authority;
- char* result;
- char* next_authority_name;
+ char result[MAX_DNS_NAME_LENGTH];
+ char next_authority_name[MAX_DNS_LABEL_LENGTH];
size_t answer_len;
/* we found a match in our own zone */
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"result strlen %d\n", strlen(name));
answer_len = strlen(rh->name) + strlen(name) + strlen(GNUNET_GNS_TLD) + 3;
- result = GNUNET_malloc(answer_len);
memset(result, 0, answer_len);
- strcpy(result, rh->name);
- strcpy(result+strlen(rh->name), ".");
- strcpy(result+strlen(rh->name)+1, name);
- strcpy(result+strlen(rh->name)+strlen(name)+1, ".");
- strcpy(result+strlen(rh->name)+strlen(name)+2, GNUNET_GNS_TLD);
+ if (strlen(rh->name) > 0)
+ {
+ strcpy(result, rh->name);
+ strcpy(result+strlen(rh->name), ".");
+ }
+
+ strcpy(result+strlen(result), name);
+ strcpy(result+strlen(result), ".");
+ strcpy(result+strlen(result), GNUNET_GNS_TLD);
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Sending shorten result %s\n", result);
nsh->proc(nsh->proc_cls, result);
GNUNET_free(nsh);
free_resolver_handle(rh);
- GNUNET_free(result);
}
- else if (GNUNET_CRYPTO_hash_cmp(&rh->authority_chain_head->zone,
- &rh->authority_chain_tail->zone))
+ else if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+ &rh->authority_chain_tail->zone))
{
/* our zone, just append .gnunet */
answer_len = strlen(rh->name) + strlen(GNUNET_GNS_TLD) + 2;
- result = GNUNET_malloc(answer_len);
memset(result, 0, answer_len);
strcpy(result, rh->name);
strcpy(result+strlen(rh->name), ".");
nsh->proc(nsh->proc_cls, result);
GNUNET_free(nsh);
free_resolver_handle(rh);
- GNUNET_free(result);
}
else
{
* continue with next authority
*/
next_authority = rh->authority_chain_head;
- next_authority_name = GNUNET_malloc(strlen(rh->name)+
- strlen(next_authority->name) + 2);
+ // strlen(next_authority->name) + 2);
memset(next_authority_name, 0, strlen(rh->name)+
strlen(next_authority->name) + 2);
strcpy(next_authority_name, rh->name);
strcpy(next_authority_name+strlen(rh->name)+1, ".");
strcpy(next_authority_name+strlen(rh->name)+2, next_authority->name);
- GNUNET_free(rh->name);
- rh->name = next_authority_name;
+ strcpy(rh->name, next_authority_name);
GNUNET_CONTAINER_DLL_remove(rh->authority_chain_head,
rh->authority_chain_tail,
next_authority);
const struct GNUNET_NAMESTORE_RecordData *rd)
{
struct NameShortenHandle *nsh;
- char* result;
+ char result[MAX_DNS_NAME_LENGTH];
size_t answer_len;
nsh = (struct NameShortenHandle *)cls;
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"PKEY resolved as far as possible in ns up to %s!\n", rh->name);
- if (GNUNET_CRYPTO_hash_cmp(&rh->authority_chain_head->zone,
- &rh->authority_chain_tail->zone) == 0)
+ if (GNUNET_CRYPTO_short_hash_cmp(&rh->authority_chain_head->zone,
+ &rh->authority_chain_tail->zone) == 0)
{
/**
* This is our zone append .gnunet unless name is empty
* (it shouldn't be, usually FIXME what happens if we
* shorten to our zone to a "" record??)
- **/
+ */
answer_len = strlen(rh->name) + strlen(GNUNET_GNS_TLD) + 2;
- result = GNUNET_malloc(answer_len);
memset(result, 0, answer_len);
strcpy(result, rh->name);
strcpy(result+strlen(rh->name), ".");
nsh->proc(nsh->proc_cls, result);
GNUNET_free(nsh);
free_resolver_handle(rh);
- GNUNET_free(result);
return;
}
* @param cls closure to pass to proc
*/
void
-gns_resolver_shorten_name(GNUNET_HashCode zone,
+gns_resolver_shorten_name(struct GNUNET_CRYPTO_ShortHashCode zone,
const char* name,
ShortenResultProcessor proc,
void* cls)
{
struct ResolverHandle *rh;
struct NameShortenHandle *nsh;
+ char string_hash[MAX_DNS_NAME_LENGTH]; //FIXME LABEL length when shorthash
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Starting shorten for %s!\n", name);
+ if (is_canonical((char*)name))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%s is canonical. Returning verbatim\n", name);
+ proc(cls, name);
+ return;
+ }
+
nsh = GNUNET_malloc(sizeof (struct NameShortenHandle));
+
+
+ nsh->proc = proc;
+ nsh->proc_cls = cls;
+
rh = GNUNET_malloc(sizeof (struct ResolverHandle));
rh->authority = zone;
- rh->name = GNUNET_malloc(strlen(name)
- - strlen(GNUNET_GNS_TLD));
- memset(rh->name, 0,
- strlen(name)-strlen(GNUNET_GNS_TLD));
- memcpy(rh->name, name,
- strlen(name)-strlen(GNUNET_GNS_TLD)-1);
-
- rh->authority_name = GNUNET_malloc(sizeof(char)*MAX_DNS_LABEL_LENGTH);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Checking for TLD...\n");
+ if (is_zkey_tld(name) == GNUNET_YES)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TLD is zkey\n");
+ /**
+ * This is a zkey tld
+ * build hash and use as initial authority
+ */
+ memset(rh->name, 0,
+ strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY));
+ memcpy(rh->name, name,
+ strlen(name)-strlen(GNUNET_GNS_TLD_ZKEY) - 1);
+ pop_tld(rh->name, string_hash);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "ZKEY is %s!\n", string_hash);
+
+ if (GNUNET_OK != GNUNET_CRYPTO_short_hash_from_string(string_hash,
+ &rh->authority))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Cannot convert ZKEY %s to hash!\n", string_hash);
+ GNUNET_free(rh);
+ GNUNET_free(nsh);
+ proc(cls, name);
+ return;
+ }
+
+ }
+ else
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TLD is gnunet\n");
+ /**
+ * Presumably GNUNET tld
+ */
+ memset(rh->name, 0,
+ strlen(name)-strlen(GNUNET_GNS_TLD));
+ memcpy(rh->name, name,
+ strlen(name)-strlen(GNUNET_GNS_TLD) - 1);
+ }
+
rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain));
rh->authority_chain_tail = rh->authority_chain_head;
rh->authority_chain_head->zone = zone;
rh->proc = &handle_delegation_ns_shorten;
rh->proc_cls = nsh;
-
- nsh->proc = proc;
- nsh->proc_cls = cls;
/* Start delegation resolution in our namestore */
resolve_delegation_ns(rh);
const struct GNUNET_NAMESTORE_RecordData *rd)
{
struct GetNameAuthorityHandle* nah;
- char* result;
+ char result[MAX_DNS_NAME_LENGTH];
size_t answer_len;
nah = (struct GetNameAuthorityHandle*) rh->proc_cls;
answer_len = strlen(nah->name) - strlen(rh->name)
+ strlen(GNUNET_GNS_TLD) + 1;
- result = GNUNET_malloc(answer_len);
memset(result, 0, answer_len);
strcpy(result, nah->name + strlen(rh->name) + 1);
"Got authority result %s\n", result);
nah->proc(nah->proc_cls, result);
- GNUNET_free(nah->name);
GNUNET_free(nah);
free_resolver_handle(rh);
- GNUNET_free(result);
}
else
{
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Unable to resolve authority for remaining %s!\n", rh->name);
nah->proc(nah->proc_cls, "");
- GNUNET_free(nah->name);
GNUNET_free(nah);
free_resolver_handle(rh);
}
* @param cls the closure to pass to the processor
*/
void
-gns_resolver_get_authority(GNUNET_HashCode zone,
+gns_resolver_get_authority(struct GNUNET_CRYPTO_ShortHashCode zone,
const char* name,
GetAuthorityResultProcessor proc,
void* cls)
nah = GNUNET_malloc(sizeof (struct GetNameAuthorityHandle));
rh = GNUNET_malloc(sizeof (struct ResolverHandle));
rh->authority = zone;
+
+ if (strcmp(GNUNET_GNS_TLD, name) == 0)
+ {
+ strcpy(rh->name, "\0");
+ }
+ else
+ {
+ memset(rh->name, 0,
+ strlen(name)-strlen(GNUNET_GNS_TLD));
+ memcpy(rh->name, name,
+ strlen(name)-strlen(GNUNET_GNS_TLD) - 1);
+ }
- rh->name = GNUNET_malloc(strlen(name)
- - strlen(GNUNET_GNS_TLD));
- memset(rh->name, 0,
- strlen(name)-strlen(GNUNET_GNS_TLD));
- memcpy(rh->name, name,
- strlen(name)-strlen(GNUNET_GNS_TLD) - 1);
-
- nah->name = GNUNET_malloc(strlen(name)+1);
memset(nah->name, 0,
strlen(name)+1);
strcpy(nah->name, name);
- rh->authority_name = GNUNET_malloc(MAX_DNS_LABEL_LENGTH);
-
rh->authority_chain_head = GNUNET_malloc(sizeof(struct AuthorityChain));
rh->authority_chain_tail = rh->authority_chain_head;
rh->authority_chain_head->zone = zone;