From: Matthias Wachs Date: Fri, 24 Feb 2012 17:05:33 +0000 (+0000) Subject: - lookup API send recv X-Git-Tag: initial-import-from-subversion-38251~14654 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=95c9e40b4153361d1e6e45f99659759a8f0f14de;p=oweals%2Fgnunet.git - lookup API send recv --- diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index 58830b304..e4f7a2b37 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c @@ -93,18 +93,21 @@ cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) struct GNUNET_NAMESTORE_Operation * no; struct GNUNET_NAMESTORE_Client * nc; + struct GNUNET_NAMESTORE_Client * next; - for (nc = client_head; nc != NULL; nc = nc->next) + for (nc = client_head; nc != NULL; nc = next) { + next = nc->next; for (no = nc->op_head; no != NULL; no = no->next) { GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no); GNUNET_free (no); } - } - GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc); - GNUNET_free (nc); + GNUNET_CONTAINER_DLL_remove (client_head, client_tail, nc); + GNUNET_free (nc); + + } GNUNET_SERVER_notification_context_destroy (snc); snc = NULL; @@ -175,15 +178,139 @@ static void handle_start (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } +struct LookupNameContext +{ + struct GNUNET_NAMESTORE_Client *nc; + uint32_t id; + uint32_t record_type; +}; + + +static void +handle_lookup_name_it (void *cls, + const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, + struct GNUNET_TIME_Absolute expire, + const char *name, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd, + const struct GNUNET_CRYPTO_RsaSignature *signature) +{ + /* send response */ + struct LookupNameContext *lnc = cls; + struct LookupNameResponseMessage *lnr_msg; + + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key_tmp; + struct GNUNET_NAMESTORE_RecordData * rd_tmp; + char *name_tmp; + struct GNUNET_CRYPTO_RsaSignature *signature_tmp; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE"); + + size_t r_size = 0; + + size_t name_len = 0; + if (NULL != name) + name_len = strlen(name) + 1; + + int copied_elements = 0; + int contains_signature = 0; + int c; + + /* count records to copy */ + if (rd_count != 0) + { + if (lnc->record_type != 0) + { + /* special record type needed */ + for (c = 0; c < rd_count; c ++) + if (rd[c].record_type == lnc->record_type) + copied_elements++; /* found matching record */ + } + else + copied_elements = rd_count; + } + + if ((copied_elements == rd_count) && (signature != NULL)) + contains_signature = GNUNET_YES; + + r_size = sizeof (struct LookupNameResponseMessage) + + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + + name_len + + copied_elements * sizeof (struct GNUNET_NAMESTORE_RecordData) + + contains_signature * sizeof (struct GNUNET_CRYPTO_RsaSignature); + + lnr_msg = GNUNET_malloc (r_size); + + lnr_msg->header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE); + lnr_msg->header.size = ntohs (r_size); + lnr_msg->op_id = htonl (lnc->id); + lnr_msg->rc_count = htonl (copied_elements); + lnr_msg->name_len = htons (name_len); + lnr_msg->expire = GNUNET_TIME_absolute_hton(expire); + lnr_msg->contains_sig = htons (contains_signature); + + + zone_key_tmp = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &lnr_msg[1]; + name_tmp = (char *) &zone_key_tmp[1]; + rd_tmp = (struct GNUNET_NAMESTORE_RecordData *) &name_tmp[name_len]; + signature_tmp = (struct GNUNET_CRYPTO_RsaSignature *) &rd_tmp[copied_elements]; + + if (zone_key != NULL) + memcpy (zone_key_tmp, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + else + { + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded dummy; + memset (&dummy, '0', sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + memcpy (zone_key_tmp, &dummy, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + } + memcpy (name_tmp, name, name_len); + /* copy records */ + copied_elements = 0; + if (rd_count != 0) + { + if (lnc->record_type != 0) + { + /* special record type needed */ + for (c = 0; c < rd_count; c ++) + if (rd[c].record_type == lnc->record_type) + { + /* found matching record */ + memcpy (&rd_tmp[copied_elements], &rd[c], rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + copied_elements++; + } + } + else + memcpy (rd_tmp, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + } + + if (GNUNET_YES == contains_signature) + memcpy (signature_tmp, signature, sizeof (struct GNUNET_CRYPTO_RsaSignature)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DONE `%s' message\n", "NAMESTORE_LOOKUP_NAME_RESPONSE"); + GNUNET_SERVER_notification_context_unicast (snc, lnc->nc->client, (const struct GNUNET_MessageHeader *) lnr_msg, GNUNET_NO); + + GNUNET_free (lnr_msg); +} + static void handle_lookup_name (void *cls, struct GNUNET_SERVER_Client * client, const struct GNUNET_MessageHeader * message) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_LOOKUP_NAME"); - + struct LookupNameContext lnc; struct GNUNET_NAMESTORE_Client *nc; + GNUNET_HashCode name_hash; + size_t name_len; + char * name; uint32_t id = 0; - size_t r_size = 0; + uint32_t type = 0; + + + if (ntohs (message->size) < sizeof (struct LookupNameMessage)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } nc = client_lookup(client); if (nc == NULL) @@ -195,18 +322,28 @@ static void handle_lookup_name (void *cls, struct LookupNameMessage * ln_msg = (struct LookupNameMessage *) message; id = ntohl (ln_msg->op_id); + name_len = ntohl (ln_msg->name_len); + type = ntohl (ln_msg->record_type); - /* do the actual lookup */ + if ((name_len == 0) || (name_len > 256)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } - /* send response */ - struct LookupNameResponseMessage lnr_msg; - r_size = sizeof (struct LookupNameResponseMessage); + name = GNUNET_malloc (name_len); + memcpy (name, &ln_msg[1], name_len); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking up record for name `%s'\n", name); + GNUNET_CRYPTO_hash(name, name_len-1, &name_hash); + GNUNET_free (name); - lnr_msg.header.type = ntohs (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE); - lnr_msg.header.size = ntohs (r_size); - lnr_msg.op_id = htonl (id); + /* do the actual lookup */ + lnc.id = id; + lnc.nc = nc; + lnc.record_type = type; + GSN_database->iterate_records(GSN_database->cls, &ln_msg->zone, &ln_msg->zone, 0, &handle_lookup_name_it, &lnc); - GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &lnr_msg, GNUNET_NO); GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -230,7 +367,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, {&handle_start, NULL, GNUNET_MESSAGE_TYPE_NAMESTORE_START, sizeof (struct StartMessage)}, {&handle_lookup_name, NULL, - GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, sizeof (struct LookupNameMessage)}, + GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, 0}, {NULL, NULL, 0, 0} }; diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index 27d36d78b..143f233d4 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -66,6 +66,8 @@ struct GenericMessage }; GNUNET_NETWORK_STRUCT_END + + GNUNET_NETWORK_STRUCT_BEGIN /** * Connect to namestore service @@ -81,11 +83,28 @@ struct LookupNameMessage * Operation ID in NBO */ uint32_t op_id; + + /* The zone */ + GNUNET_HashCode zone; + + /* Requested record type */ + uint32_t record_type; + + /* Requested record type */ + uint32_t name_len; }; GNUNET_NETWORK_STRUCT_END + + GNUNET_NETWORK_STRUCT_BEGIN +/** + * Lookup response + * Memory layout: + * [struct LookupNameResponseMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData][struct GNUNET_CRYPTO_RsaSignature] + */ + struct LookupNameResponseMessage { /** @@ -97,6 +116,15 @@ struct LookupNameResponseMessage * Operation ID in NBO */ uint32_t op_id; + + struct GNUNET_TIME_AbsoluteNBO expire; + + uint16_t name_len; + + uint16_t contains_sig; + + /* Requested record type */ + uint32_t rc_count; }; diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index 0e269f4aa..811c0b2d0 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -196,23 +196,59 @@ handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe, "LOOKUP_NAME_RESPONSE"); struct GNUNET_NAMESTORE_Handle *nsh = qe->nsh; - - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key = NULL; - struct GNUNET_TIME_Absolute expire = GNUNET_TIME_absolute_get_forever(); - const char *name = ""; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; + char *name; + struct GNUNET_NAMESTORE_RecordData *rd = NULL; + struct GNUNET_CRYPTO_RsaSignature *signature = NULL; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded dummy; + struct GNUNET_TIME_Absolute expire; unsigned int rd_count = 0; - const struct GNUNET_NAMESTORE_RecordData *rd = NULL; - const struct GNUNET_CRYPTO_RsaSignature *signature = NULL; + size_t msg_len = 0; + size_t name_len = 0; + int contains_sig = GNUNET_NO; + + rd_count = ntohl (msg->rc_count); + msg_len = ntohs (msg->header.size); + name_len = ntohs (msg->name_len); + contains_sig = ntohs (msg->contains_sig); + expire = GNUNET_TIME_absolute_ntoh(msg->expire); + + if (msg_len != sizeof (struct LookupNameResponseMessage) + + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + + name_len + + rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData) + + contains_sig * sizeof (struct GNUNET_CRYPTO_RsaSignature)) + { + GNUNET_break_op (0); + return; + } + + zone_key = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &msg[1]; + name = (char *) &zone_key[1]; + rd = (struct GNUNET_NAMESTORE_RecordData *) &name[name_len]; - /* TODO: extract real values */ + /* reset values if values not contained */ + if (contains_sig == GNUNET_NO) + signature = NULL; + else + signature = (struct GNUNET_CRYPTO_RsaSignature *) &rd[rd_count]; + if (rd_count == 0) + rd = NULL; + if (name_len == 0) + name = NULL; - /* Lookup complete, remove queue entry */ - GNUNET_CONTAINER_DLL_remove (nsh->op_head, nsh->op_tail, qe); + memset (&dummy, '0', sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + if (0 == memcmp (zone_key, &dummy, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) + zone_key = NULL; - /* Notify */ if (qe->proc != NULL) + { qe->proc (qe->proc_cls, zone_key, expire, name, rd_count, rd, signature); + } + + /* Operation done, remove */ + GNUNET_CONTAINER_DLL_remove(nsh->op_head, nsh->op_tail, qe); GNUNET_free (qe); } @@ -283,6 +319,11 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) /* handle different message type */ switch (type) { case GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE: + if (size < sizeof (struct LookupNameResponseMessage)) + { + GNUNET_break_op (0); + break; + } handle_lookup_name_response (qe, (struct LookupNameResponseMessage *) msg, size); break; default: @@ -724,9 +765,20 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, struct GNUNET_NAMESTORE_QueueEntry *qe; struct PendingMessage *pe; size_t msg_size = 0; + size_t name_len = 0; uint32_t id = 0; GNUNET_assert (NULL != h); + GNUNET_assert (NULL != zone); + GNUNET_assert (NULL != name); + + name_len = strlen (name) + 1; + if ((name_len == 0) || (name_len > 256)) + { + GNUNET_break (0); + return NULL; + } + id = get_op_id(h); qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry)); qe->nsh = h; @@ -736,7 +788,7 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, GNUNET_CONTAINER_DLL_insert(h->op_head, h->op_tail, qe); /* set msg_size*/ - msg_size = sizeof (struct LookupNameMessage); + msg_size = sizeof (struct LookupNameMessage) + name_len; pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); /* create msg here */ @@ -747,6 +799,12 @@ GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME); msg->header.size = htons (msg_size); msg->op_id = htonl (id); + msg->record_type = htonl (record_type); + msg->zone = *zone; + msg->name_len = htonl (name_len); + memcpy (&msg[1], name, name_len); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s'\n", "NAMESTORE_LOOKUP_NAME", name); /* transmit message */ GNUNET_CONTAINER_DLL_insert (h->pending_head, h->pending_tail, pe); diff --git a/src/namestore/test_namestore_api.c b/src/namestore/test_namestore_api.c index 335bbbfba..a72530d13 100644 --- a/src/namestore/test_namestore_api.c +++ b/src/namestore/test_namestore_api.c @@ -27,7 +27,7 @@ #define VERBOSE GNUNET_EXTRA_LOGGING -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) static struct GNUNET_NAMESTORE_Handle * nsh; @@ -112,6 +112,7 @@ void name_lookup_proc (void *cls, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature) { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "name_lookup_proc %p `%s' %i %p %p\n", zone_key, name, rd_count, rd, signature); res = 0; GNUNET_SCHEDULER_add_now(&end, NULL); } @@ -122,13 +123,17 @@ run (void *cls, char *const *args, const char *cfgfile, { endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); + GNUNET_HashCode zone; + GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &zone); + char * name = "dummy.dummy.gnunet"; + start_arm (cfgfile); GNUNET_assert (arm != NULL); nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_break (NULL != nsh); - GNUNET_NAMESTORE_lookup_record (nsh, NULL, NULL, 0, &name_lookup_proc, NULL); + GNUNET_NAMESTORE_lookup_record (nsh, &zone, name, 0, &name_lookup_proc, NULL); } static int diff --git a/src/namestore/test_namestore_api.conf b/src/namestore/test_namestore_api.conf index be93cb962..1683d13cf 100644 --- a/src/namestore/test_namestore_api.conf +++ b/src/namestore/test_namestore_api.conf @@ -4,6 +4,7 @@ DEFAULTSERVICES = namestore UNIXPATH = /tmp/gnunet-p1-service-arm.sock [namestore] +PREFIX = valgrind --leak-check=full AUTOSTART = YES UNIXPATH = /tmp/gnunet-service-namestore.sock UNIX_MATCH_UID = YES