From: Matthias Wachs Date: Mon, 27 Feb 2012 14:26:17 +0000 (+0000) Subject: - put record X-Git-Tag: initial-import-from-subversion-38251~14609 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=11e0d70c68bdec7df62a1118ce346fc8ec629c4a;p=oweals%2Fgnunet.git - put record --- diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 6f19d96d3..f3211d6a0 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am @@ -76,7 +76,8 @@ test_namestore_api_LDADD = \ EXTRADIST = \ test_namestore_api.conf \ - test_plugin_namestore_sqlite.conf + test_plugin_namestore_sqlite.conf \ + hostkey test_plugin_namestore_sqlite_SOURCES = \ diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index e7c03bf21..1700925de 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c @@ -287,7 +287,6 @@ handle_lookup_name_it (void *cls, 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); @@ -349,6 +348,94 @@ static void handle_lookup_name (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } +static void handle_record_put (void *cls, + struct GNUNET_SERVER_Client * client, + const struct GNUNET_MessageHeader * message) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "NAMESTORE_RECORD_PUT"); + struct GNUNET_NAMESTORE_Client *nc; + struct GNUNET_TIME_Absolute expire; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key; + struct GNUNET_NAMESTORE_RecordData *rd; + struct GNUNET_CRYPTO_RsaSignature *signature; + struct RecordPutResponseMessage rpr_msg; + size_t name_len; + size_t msg_size; + size_t msg_size_exp; + char * name; + uint32_t id = 0; + uint32_t rd_count; + int res = GNUNET_SYSERR; + + if (ntohs (message->size) < sizeof (struct RecordPutMessage)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + nc = client_lookup(client); + if (nc == NULL) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + struct RecordPutMessage * rp_msg = (struct RecordPutMessage *) message; + id = ntohl (rp_msg->op_id); + name_len = ntohs (rp_msg->name_len); + rd_count = ntohl(rp_msg->rd_count); + msg_size = ntohs (message->size); + msg_size_exp = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len + rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData)); + + if (msg_size != msg_size_exp) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Expected message %u size but message size is %u \n", msg_size_exp, msg_size); + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + + if ((name_len == 0) || (name_len > 256)) + { + GNUNET_break_op (0); + GNUNET_SERVER_receive_done (client, GNUNET_OK); + return; + } + + zone_key = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &rp_msg[1]; + name = (char *) &zone_key[1]; + expire = GNUNET_TIME_absolute_ntoh(rp_msg->expire); + signature = (struct GNUNET_CRYPTO_RsaSignature *) &rp_msg->signature; + rd = (struct GNUNET_NAMESTORE_RecordData *) &name[name_len]; + + /* Database operation */ + res = GSN_database->put_records(GSN_database->cls, + zone_key, + expire, + name, + rd_count, rd, + signature); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Putting record for name `%s': %s\n", + name, (res == GNUNET_OK) ? "OK" : "FAIL"); + + /* Send response */ + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "RECORD_PUT_RESPONSE"); + rpr_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE); + rpr_msg.op_id = rp_msg->op_id; + rpr_msg.header.size = htons (sizeof (struct RecordPutResponseMessage)); + if (GNUNET_OK == res) + rpr_msg.op_result = htons (GNUNET_OK); + else + rpr_msg.op_result = htons (GNUNET_NO); + GNUNET_SERVER_notification_context_unicast (snc, nc->client, (const struct GNUNET_MessageHeader *) &rpr_msg, GNUNET_NO); + + GNUNET_SERVER_receive_done (client, GNUNET_OK); +} /** * Process template requests. @@ -370,6 +457,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, GNUNET_MESSAGE_TYPE_NAMESTORE_START, sizeof (struct StartMessage)}, {&handle_lookup_name, NULL, GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME, 0}, + {&handle_record_put, NULL, + GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT, 0}, {NULL, NULL, 0, 0} }; diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index 143f233d4..03b4bb45a 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -31,6 +31,8 @@ */ #define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME 431 #define GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_NAME_RESPONSE 432 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT 433 +#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE 434 GNUNET_NETWORK_STRUCT_BEGIN /** @@ -67,11 +69,10 @@ struct GenericMessage GNUNET_NETWORK_STRUCT_END - -GNUNET_NETWORK_STRUCT_BEGIN /** * Connect to namestore service */ +GNUNET_NETWORK_STRUCT_BEGIN struct LookupNameMessage { /** @@ -96,15 +97,12 @@ struct LookupNameMessage 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] */ - +GNUNET_NETWORK_STRUCT_BEGIN struct LookupNameResponseMessage { /** @@ -126,10 +124,69 @@ struct LookupNameResponseMessage /* Requested record type */ uint32_t rc_count; }; +GNUNET_NETWORK_STRUCT_END + + +/** + * Put a record to the namestore + * Memory layout: + * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData] + */ +GNUNET_NETWORK_STRUCT_BEGIN +struct RecordPutMessage +{ + /** + * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_LOOKUP_RECORD_PUT + */ + struct GNUNET_MessageHeader header; + + /** + * Operation ID in NBO + */ + uint32_t op_id; + + /* Contenct starts here */ + + /* name length */ + uint16_t name_len; + + /* Requested record type */ + uint32_t rd_count; + + struct GNUNET_TIME_AbsoluteNBO expire; + + struct GNUNET_CRYPTO_RsaSignature signature; +}; +GNUNET_NETWORK_STRUCT_END + +/** + * Put a record to the namestore + * Memory layout: + * [struct RecordPutMessage][struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded][char *name][rc_count * struct GNUNET_NAMESTORE_RecordData] + */ +GNUNET_NETWORK_STRUCT_BEGIN +struct RecordPutResponseMessage +{ + /** + * Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE + */ + struct GNUNET_MessageHeader header; + /** + * Operation ID in NBO + */ + uint32_t op_id; + + /* Contenct starts here */ + /** + * name length: GNUNET_NO (0) on error, GNUNET_OK (1) on success + */ + uint16_t op_result; +}; GNUNET_NETWORK_STRUCT_END + /* end of namestore.h */ #endif diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c index 21b24567a..882e5a5de 100644 --- a/src/namestore/namestore_api.c +++ b/src/namestore/namestore_api.c @@ -245,12 +245,51 @@ handle_lookup_name_response (struct GNUNET_NAMESTORE_QueueEntry *qe, { qe->proc (qe->proc_cls, zone_key, expire, name, rd_count, rd, signature); } + /* Operation done, remove */ + GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); + GNUNET_free (qe); +} + + +static void +handle_record_put_response (struct GNUNET_NAMESTORE_QueueEntry *qe, + struct RecordPutResponseMessage* msg, + size_t size) +{ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' \n", + "RECORD_PUT_RESPONSE"); + + struct GNUNET_NAMESTORE_Handle *h = qe->nsh; + int res = GNUNET_OK; + + if (ntohs (msg->op_result) == GNUNET_OK) + { + res = GNUNET_OK; + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, res, _("Namestore added record successfully")); + } + + } + else if (ntohs (msg->op_result) == GNUNET_NO) + { + res = GNUNET_SYSERR; + if (qe->cont != NULL) + { + qe->cont (qe->cont_cls, res, _("Namestore failed to add record")); + } + } + else + { + GNUNET_break_op (0); + return; + } /* Operation done, remove */ GNUNET_CONTAINER_DLL_remove(h->op_head, h->op_tail, qe); - GNUNET_free (qe); + GNUNET_free (qe); } @@ -326,6 +365,14 @@ process_namestore_message (void *cls, const struct GNUNET_MessageHeader *msg) } handle_lookup_name_response (qe, (struct LookupNameResponseMessage *) msg, size); break; + case GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT_RESPONSE: + if (size != sizeof (struct RecordPutResponseMessage)) + { + GNUNET_break_op (0); + break; + } + handle_record_put_response (qe, (struct RecordPutResponseMessage *) msg, size); + break; default: GNUNET_break_op (0); break; @@ -575,7 +622,14 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, { struct GNUNET_NAMESTORE_QueueEntry *qe; struct PendingMessage *pe; + + /* pointer to elements */ + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key_tmp; + struct GNUNET_NAMESTORE_RecordData *rd_tmp; + char * name_tmp; + size_t msg_size = 0; + size_t name_len = strlen(name) + 1; uint32_t id = 0; GNUNET_assert (NULL != h); @@ -588,24 +642,40 @@ GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h, GNUNET_CONTAINER_DLL_insert(h->op_head, h->op_tail, qe); /* set msg_size*/ - pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); + struct RecordPutMessage * msg; + msg_size = sizeof (struct RecordPutMessage) + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + name_len + rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData)); /* create msg here */ + pe = GNUNET_malloc(sizeof (struct PendingMessage) + msg_size); + pe->size = msg_size; + pe->is_init = GNUNET_NO; + msg = (struct RecordPutMessage *) &pe[1]; + zone_key_tmp = (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *) &msg[1]; + name_tmp = (char *) &zone_key_tmp[1]; + rd_tmp = (struct GNUNET_NAMESTORE_RecordData *) &name_tmp[name_len]; + + msg->header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_PUT); + msg->header.size = htons (msg_size); + msg->op_id = htonl (id); + memcpy (zone_key_tmp, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + msg->signature = *signature; + msg->name_len = htons (name_len); + memcpy (name_tmp, name, name_len); + msg->expire = GNUNET_TIME_absolute_hton (expire); + msg->rd_count = htonl(rd_count); + memcpy (rd_tmp, rd, rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData))); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message for name `%s' with size %u\n", "NAMESTORE_RECORD_PUT", name, msg_size); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CALC: %u %u %u %u\n", + sizeof (struct RecordPutMessage), + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + name_len, + rd_count * (sizeof (struct GNUNET_NAMESTORE_RecordData))); GNUNET_CONTAINER_DLL_insert (h->pending_head, h->pending_tail, pe); do_transmit(h); -#if 0 - struct GNUNET_NAMESTORE_SimpleRecord *sr; - sr = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_SimpleRecord)); - sr->name = name; - sr->record_type = record_type; - sr->expiration = expiration; - sr->flags = flags; - sr->data_size = data_size; - sr->data = data; - GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr); -#endif return qe; } diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index ba8f8bca6..c29721643 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c @@ -465,7 +465,7 @@ namestore_sqlite_remove_records (void *cls, * @param rd array of records with data to store * @param signature signature of the record block, NULL if signature is unavailable (i.e. * because the user queried for a particular record type only) - * @return GNUNET_OK on success + * @return GNUNET_OK on success, else GNUNET_SYSERR */ static int namestore_sqlite_put_records (void *cls, diff --git a/src/namestore/test_namestore_api.c b/src/namestore/test_namestore_api.c index 62cfa808a..b907c7139 100644 --- a/src/namestore/test_namestore_api.c +++ b/src/namestore/test_namestore_api.c @@ -34,6 +34,10 @@ static struct GNUNET_NAMESTORE_Handle * nsh; static GNUNET_SCHEDULER_TaskIdentifier endbadly_task; static struct GNUNET_OS_Process *arm; +static struct GNUNET_CRYPTO_RsaPrivateKey * privkey; +static struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pubkey; +static GNUNET_HashCode zone; + static int res; @@ -76,6 +80,10 @@ endbadly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); nsh = NULL; + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + if (NULL != arm) stop_arm(); @@ -92,6 +100,10 @@ end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) endbadly_task = GNUNET_SCHEDULER_NO_TASK; } + if (privkey != NULL) + GNUNET_CRYPTO_rsa_key_free (privkey); + privkey = NULL; + if (nsh != NULL) GNUNET_NAMESTORE_disconnect (nsh, GNUNET_YES); nsh = NULL; @@ -112,19 +124,34 @@ 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); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore lookup result %p `%s' %i %p %p\n", zone_key, name, rd_count, rd, signature); res = 0; GNUNET_SCHEDULER_add_now(&end, NULL); } +void put_cont (void *cls, int32_t success, const char *emsg) +{ + char * name = cls; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Name store added record for `%s': %s\n", name, (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); + + GNUNET_NAMESTORE_lookup_record (nsh, &zone, name, 0, &name_lookup_proc, NULL); +} + static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { endbadly_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,endbadly, NULL); - GNUNET_HashCode zone; - GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &zone); + privkey = GNUNET_CRYPTO_rsa_key_create_from_file("hostkey"); + GNUNET_assert (privkey != NULL); + GNUNET_CRYPTO_rsa_key_get_public(privkey, &pubkey); + + GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &zone); + + + struct GNUNET_CRYPTO_RsaSignature signature; char * name = "dummy.dummy.gnunet"; start_arm (cfgfile); @@ -133,7 +160,9 @@ run (void *cls, char *const *args, const char *cfgfile, nsh = GNUNET_NAMESTORE_connect (cfg); GNUNET_break (NULL != nsh); - GNUNET_NAMESTORE_lookup_record (nsh, &zone, name, 0, &name_lookup_proc, NULL); + GNUNET_NAMESTORE_record_put (nsh, &pubkey, name, + GNUNET_TIME_absolute_get_forever(), + 0, NULL, &signature, put_cont, name); } static int diff --git a/src/namestore/test_namestore_api.conf b/src/namestore/test_namestore_api.conf index 1683d13cf..1b83e8f13 100644 --- a/src/namestore/test_namestore_api.conf +++ b/src/namestore/test_namestore_api.conf @@ -4,7 +4,7 @@ DEFAULTSERVICES = namestore UNIXPATH = /tmp/gnunet-p1-service-arm.sock [namestore] -PREFIX = valgrind --leak-check=full +#PREFIX = valgrind --leak-check=full AUTOSTART = YES UNIXPATH = /tmp/gnunet-service-namestore.sock UNIX_MATCH_UID = YES