struct GNUNET_NAMESTORE_CryptoContainer
{
- struct GNUNET_NAMESTORE_CryptoContainer *next;
- struct GNUNET_NAMESTORE_CryptoContainer *prev;
-
char * filename;
GNUNET_HashCode zone;
static struct GNUNET_NAMESTORE_Client *client_head;
static struct GNUNET_NAMESTORE_Client *client_tail;
-struct GNUNET_NAMESTORE_CryptoContainer *c_head;
-struct GNUNET_NAMESTORE_CryptoContainer *c_tail;
+struct GNUNET_CONTAINER_MultiHashMap *zonekeys;
/**
return GNUNET_OK;
}
+int zone_to_disk_it (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct GNUNET_NAMESTORE_CryptoContainer * c = value;
+
+ if (c->filename != NULL)
+ write_key_to_file(c->filename, c);
+ else
+ {
+ GNUNET_asprintf(&c->filename, "%s/%s.zkey", zonefile_directory, GNUNET_h2s_full (&c->zone));
+ write_key_to_file(c->filename, c);
+ }
+
+ GNUNET_CONTAINER_multihashmap_remove (zonekeys, key, value);;
+ GNUNET_CRYPTO_rsa_key_free(c->privkey);
+ GNUNET_free (c->pubkey);
+ GNUNET_free(c->filename);
+ GNUNET_free (c);
+
+ return GNUNET_OK;
+}
+
+
+struct GNUNET_TIME_Absolute
+get_block_expiration_time (unsigned int rd_count, const struct GNUNET_NAMESTORE_RecordData *rd)
+{
+ int c;
+ struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get_forever();
+ if (NULL == rd)
+ return GNUNET_TIME_absolute_get_zero();
+ for (c = 0; c < rd_count; c++)
+ {
+ if (rd[c].expiration.abs_value < expire.abs_value)
+ expire = rd[c].expiration;
+ }
+ return expire;
+}
/**
* Task run during shutdown.
struct GNUNET_NAMESTORE_ZoneIteration * tmp;
struct GNUNET_NAMESTORE_Client * nc;
struct GNUNET_NAMESTORE_Client * next;
- struct GNUNET_NAMESTORE_CryptoContainer *c;
GNUNET_SERVER_notification_context_destroy (snc);
snc = NULL;
- for (c = c_head; c != NULL; c = c_head)
- {
- if (c->filename != NULL)
- write_key_to_file(c->filename, c);
- else
- {
- GNUNET_asprintf(&c->filename, "%s/%s.zone", zonefile_directory, GNUNET_h2s_full (&c->zone));
- write_key_to_file(c->filename, c);
- }
-
- GNUNET_CONTAINER_DLL_remove(c_head, c_tail, c);
- GNUNET_CRYPTO_rsa_key_free(c->privkey);
- GNUNET_free (c->pubkey);
- GNUNET_free(c->filename);
- GNUNET_free (c);
- }
+ GNUNET_CONTAINER_multihashmap_iterate(zonekeys, &zone_to_disk_it, NULL);
+ GNUNET_CONTAINER_multihashmap_destroy(zonekeys);
for (nc = client_head; nc != NULL; nc = next)
{
next = nc->next;
for (no = nc->op_head; no != NULL; no = tmp)
{
- GNUNET_break (0);
GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
tmp = no->next;
GNUNET_free (no);
GNUNET_SERVER_client_drop(nc->client);
GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc);
GNUNET_free (nc);
+ nc = NULL;
}
struct LookupNameContext *lnc = cls;
struct LookupNameResponseMessage *lnr_msg;
struct GNUNET_NAMESTORE_RecordData *rd_selected = NULL;
+ struct GNUNET_NAMESTORE_CryptoContainer *cc;
+ struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
+ struct GNUNET_TIME_Absolute e;
+ GNUNET_HashCode zone_key_hash;
char *rd_tmp;
char *name_tmp;
size_t rd_ser_len;
size_t name_len = 0;
int copied_elements = 0;
- int contains_signature = 0;
+ int contains_signature = GNUNET_NO;
+ int authoritative = GNUNET_NO;
int c;
if (NULL != name)
char rd_ser[rd_ser_len];
GNUNET_NAMESTORE_records_serialize(copied_elements, rd_selected, rd_ser_len, rd_ser);
- if (rd_selected != rd)
- GNUNET_free (rd_selected);
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u records for name `%s' in zone `%s'\n",
copied_elements, lnc->name, GNUNET_h2s(lnc->zone));
if ((copied_elements == rd_count) && (NULL != signature))
- contains_signature = GNUNET_YES;
+ contains_signature = GNUNET_YES; /* returning all records, so include signature */
else
- contains_signature = GNUNET_NO;
+ contains_signature = GNUNET_NO; /* returning not all records, so do not include signature */
+
+
+ if ((NULL != zone_key) && (copied_elements == rd_count))
+ {
+ GNUNET_CRYPTO_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash);
+ if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &zone_key_hash))
+ {
+ cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &zone_key_hash);
+ e = get_block_expiration_time(rd_count, rd);
+ signature_new = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd, rd_count);
+ GNUNET_assert (signature_new != NULL);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for name `%s' with %u records in zone `%s'\n",name, copied_elements, GNUNET_h2s(&zone_key_hash));
+ authoritative = GNUNET_YES;
+ }
+ else
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am not authoritative for name `%s' in zone `%s'\n",name, GNUNET_h2s(&zone_key_hash));
+ }
r_size = sizeof (struct LookupNameResponseMessage) +
sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) +
lnr_msg->rd_count = htons (copied_elements);
lnr_msg->rd_len = htons (rd_ser_len);
lnr_msg->name_len = htons (name_len);
- lnr_msg->contains_sig = htons (contains_signature);
- lnr_msg->expire = GNUNET_TIME_absolute_hton(expire);
+ lnr_msg->expire = GNUNET_TIME_absolute_hton(get_block_expiration_time(copied_elements, rd_selected));
+
+ if (rd_selected != rd)
+ GNUNET_free (rd_selected);
if (zone_key != NULL)
lnr_msg->public_key = (*zone_key);
else
memset(&lnr_msg->public_key, '\0', sizeof (lnr_msg->public_key));
- if (GNUNET_YES == contains_signature)
+
+ if (GNUNET_YES == authoritative)
+ { /* use new created signature */
+ lnr_msg->contains_sig = htons (GNUNET_YES);
+ GNUNET_assert (signature_new != NULL);
+ lnr_msg->signature = *signature_new;
+ GNUNET_free (signature_new);
+ }
+ else if (GNUNET_YES == contains_signature)
+ {
+ /* use existing signature */
+ lnr_msg->contains_sig = htons (GNUNET_YES);
+ GNUNET_assert (signature != NULL);
lnr_msg->signature = *signature;
+ }
else
+ {
+ /* use no signature */
memset (&lnr_msg->signature, '\0', sizeof (lnr_msg->signature));
+ }
name_tmp = (char *) &lnr_msg[1];
rd_tmp = &name_tmp[name_len];
memcpy (rd_tmp, rd_ser, rd_ser_len);
GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO);
-
GNUNET_free (lnr_msg);
}
const struct GNUNET_CRYPTO_RsaSignature *signature)
{
struct CreateRecordContext * crc = cls;
- struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
struct GNUNET_NAMESTORE_RecordData *rd_new = NULL;
+ struct GNUNET_CRYPTO_RsaSignature dummy_signature;
struct GNUNET_TIME_Absolute block_expiration;
int res;
int exist = GNUNET_SYSERR;
}
if (exist == GNUNET_SYSERR)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "NO existing records for `%s' to update!\n", crc->name);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New record does not exist for name `%s'!\n", crc->name);
if (exist == GNUNET_SYSERR)
{
memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));
rd_count_new = rd_count + 1;
rd_new[rd_count] = *(crc->rd);
- signature_new = GNUNET_NAMESTORE_create_signature (crc->pkey, crc->name, rd_new, rd_count+1);
-
- if (NULL == signature_new)
- {
- GNUNET_break (0);
- res = GNUNET_SYSERR;
- goto end;
- }
}
else if (update == GNUNET_NO)
{
rd_count_new = rd_count;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating expiration from %llu to %llu!\n", rd_new[exist].expiration.abs_value, crc->rd->expiration.abs_value);
rd_new[exist].expiration = crc->rd->expiration;
- signature_new = GNUNET_NAMESTORE_create_signature (crc->pkey, crc->name, rd_new, rd_count_new);
- if (NULL == signature_new)
- {
- GNUNET_break (0);
- res = GNUNET_SYSERR;
- goto end;
- }
}
block_expiration = GNUNET_TIME_absolute_max(crc->expire, expire);
if (block_expiration.abs_value != expire.abs_value)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updated block expiration time\n");
+ memset (&dummy_signature, '\0', sizeof (dummy_signature));
/* Database operation */
GNUNET_assert ((rd_new != NULL) && (rd_count_new > 0));
block_expiration,
crc->name,
rd_count_new, rd_new,
- signature_new);
+ &dummy_signature);
GNUNET_break (GNUNET_OK == res);
if (res == GNUNET_OK)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully put record for `%s' in database \n", crc->name);
end:
GNUNET_free_non_null (rd_new);
- GNUNET_free_non_null (signature_new);
switch (res) {
case GNUNET_SYSERR:
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_CREATE");
struct GNUNET_NAMESTORE_Client *nc;
+ struct GNUNET_NAMESTORE_CryptoContainer *cc;
struct CreateRecordContext crc;
struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
GNUNET_CRYPTO_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &pubkey_hash))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_h2s(&pubkey_hash));
+
+ cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
+ cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
+ cc->pubkey = GNUNET_malloc(sizeof (pub));
+ memcpy (cc->pubkey, &pub, sizeof(pub));
+ cc->zone = pubkey_hash;
+
+ GNUNET_CONTAINER_multihashmap_put(zonekeys, &pubkey_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ }
+
crc.expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire);
crc.res = GNUNET_SYSERR;
crc.pkey = pkey;
if (res != GNUNET_SYSERR)
res = GNUNET_OK;
GNUNET_CRYPTO_rsa_key_free(pkey);
+ pkey = NULL;
/* Send response */
send:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name `%s' now has %u records\n", name, rd_count_new);
- /* Create new signature */
- struct GNUNET_CRYPTO_RsaSignature * new_signature;
- new_signature = GNUNET_NAMESTORE_create_signature (rrc->pkey, name, rd_new, rd_count_new);
+ /* Create dummy signature */
+ struct GNUNET_CRYPTO_RsaSignature dummy_signature;
+ memset (&dummy_signature, '\0', sizeof (dummy_signature));
- if (new_signature == NULL)
- {
- /* Signature failed */
- rrc->op_res = 3;
- return;
- }
/* Put records */
res = GSN_database->put_records(GSN_database->cls,
expire,
name,
rd_count_new, rd_new,
- new_signature);
- GNUNET_free (new_signature);
-
+ &dummy_signature);
if (GNUNET_OK != res)
{
/* Could put records into database */
struct GNUNET_NAMESTORE_Client *nc;
struct RecordRemoveResponseMessage rrr_msg;
struct GNUNET_CRYPTO_RsaPrivateKey *pkey;
+ struct GNUNET_NAMESTORE_CryptoContainer *cc = NULL;
struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub;
GNUNET_HashCode pubkey_hash;
char * pkey_tmp = NULL;
GNUNET_CRYPTO_rsa_key_get_public(pkey, &pub);
GNUNET_CRYPTO_hash (&pub, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &pubkey_hash);
+ if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(zonekeys, &pubkey_hash))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received new private key for zone `%s'\n",GNUNET_h2s(&pubkey_hash));
+ cc = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_CryptoContainer));
+ cc->privkey = GNUNET_CRYPTO_rsa_decode_key((char *) pkey_tmp, key_len);
+ cc->pubkey = GNUNET_malloc(sizeof (pub));
+ memcpy (cc->pubkey, &pub, sizeof(pub));
+ cc->zone = pubkey_hash;
+
+ GNUNET_CONTAINER_multihashmap_put(zonekeys, &pubkey_hash, cc, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
+ }
+
struct GNUNET_NAMESTORE_RecordData rd[rd_count];
res = GNUNET_NAMESTORE_records_deserialize(rd_ser_len, rd_ser, rd_count, rd);
if ((res != GNUNET_OK) || (rd_count != 1))
{
struct GNUNET_NAMESTORE_ZoneIteration *zi = cls;
struct GNUNET_NAMESTORE_Client *nc = zi->client;
- //size_t len;
+ struct GNUNET_NAMESTORE_CryptoContainer * cc;
+ struct GNUNET_CRYPTO_RsaSignature *signature_new = NULL;
+ struct GNUNET_TIME_Absolute e;
+ GNUNET_HashCode zone_key_hash;
+ int authoritative = GNUNET_NO;
if ((zone_key == NULL) && (name == NULL))
{
name_tmp = (char *) &zir_msg[1];
rd_tmp = &name_tmp[name_len];
+ GNUNET_CRYPTO_hash(zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &zone_key_hash);
+ if (GNUNET_CONTAINER_multihashmap_contains(zonekeys, &zone_key_hash))
+ {
+ cc = GNUNET_CONTAINER_multihashmap_get(zonekeys, &zone_key_hash);
+ e = get_block_expiration_time(rd_count, rd);
+ expire = e;
+ signature_new = GNUNET_NAMESTORE_create_signature(cc->privkey, e, name, rd, rd_count);
+ GNUNET_assert (signature_new != NULL);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating signature for `%s' in zone `%s' with %u records and expiration %llu\n", name, GNUNET_h2s(&zone_key_hash), rd_count, e.abs_value);
+ authoritative = GNUNET_YES;
+ }
+
+
zir_msg->gns_header.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE);
zir_msg->gns_header.header.size = htons (msg_size);
zir_msg->gns_header.r_id = htonl(zi->request_id);
zir_msg->name_len = htons (name_len);
zir_msg->rd_count = htons (rd_count);
zir_msg->rd_len = htons (rd_ser_len);
- zir_msg->signature = *signature;
+ if ((GNUNET_YES == authoritative) && (NULL != signature_new))
+ {
+ zir_msg->signature = *signature_new;
+ GNUNET_free (signature_new);
+ }
+ else
+ zir_msg->signature = *signature;
GNUNET_assert (NULL != zone_key);
if (zone_key != NULL)
zir_msg->public_key = *zone_key;
struct ZoneIterationStartMessage * zis_msg = (struct ZoneIterationStartMessage *) message;
struct GNUNET_NAMESTORE_Client *nc;
struct GNUNET_NAMESTORE_ZoneIteration *zi;
- int res;
nc = client_lookup(client);
if (nc == NULL)
GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
- res = GSN_database->iterate_records (GSN_database->cls, zone_tmp , NULL, zi->offset , &zone_iteration_proc, zi);
+ GSN_database->iterate_records (GSN_database->cls, zone_tmp , NULL, zi->offset , &zone_iteration_proc, zi);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
int zonekey_file_it (void *cls, const char *filename)
{
int *counter = cls;
- if ((filename != NULL) && (NULL != strstr(filename, ".zone")))
+ if ((filename != NULL) && (NULL != strstr(filename, ".zkey")))
{
struct GNUNET_CRYPTO_RsaPrivateKey * privkey;
struct GNUNET_NAMESTORE_CryptoContainer *c;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found zonefile for zone `%s'\n", GNUNET_h2s (&c->zone));
- GNUNET_CONTAINER_DLL_insert(c_head, c_tail, c);
+ GNUNET_CONTAINER_multihashmap_put(zonekeys, &c->zone, c, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
(*counter) ++;
}
return GNUNET_OK;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Scanning directory `%s' for zone files\n", zonefile_directory);
+ zonekeys = GNUNET_CONTAINER_multihashmap_create (10);
GNUNET_DISK_directory_scan (zonefile_directory, zonekey_file_it, &counter);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found %u zone files\n", counter);