From efdbca9f6d63d177280669211448683aa033d92b Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Tue, 28 Feb 2012 15:33:38 +0000 Subject: [PATCH] - record serialization + test --- src/namestore/Makefile.am | 18 +- src/namestore/gnunet-service-namestore.c | 74 ++++++-- src/namestore/hostkey | Bin 0 -> 913 bytes src/namestore/namestore.h | 36 ++++ src/namestore/namestore_common.c | 159 ++++++++++++++++++ .../test_namestore_record_serialization.c | 157 +++++++++++++++++ 6 files changed, 430 insertions(+), 14 deletions(-) create mode 100644 src/namestore/hostkey create mode 100644 src/namestore/namestore_common.c create mode 100644 src/namestore/test_namestore_record_serialization.c diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index 622c445d9..2e9a99d5f 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am @@ -26,7 +26,9 @@ check_PROGRAMS = \ $(SQLITE_TESTS) if HAVE_EXPERIMENTAL -check_PROGRAMS += test_namestore_api test_namestore_api_zone_iteration +check_PROGRAMS += test_namestore_api \ +test_namestore_api_zone_iteration \ +test_namestore_record_serialization endif lib_LTLIBRARIES = \ @@ -46,7 +48,8 @@ bin_PROGRAMS = \ gnunet-service-namestore gnunet_service_namestore_SOURCES = \ - gnunet-service-namestore.c + gnunet-service-namestore.c \ + namestore_common.c gnunet_service_namestore_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/util/libgnunetutil.la \ @@ -80,10 +83,17 @@ test_namestore_api_zone_iteration_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(top_builddir)/src/namestore/libgnunetnamestore.la +test_namestore_record_serialization_SOURCES = \ + test_namestore_record_serialization.c \ + namestore_common.c +test_namestore_record_serialization_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/namestore/libgnunetnamestore.la + EXTRA_DIST = \ test_namestore_api.conf \ - test_plugin_namestore_sqlite.conf -# hostkey + 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 747726fd0..8f969371b 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c @@ -192,6 +192,8 @@ struct LookupNameContext }; + + static void handle_lookup_name_it (void *cls, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, @@ -578,6 +580,22 @@ static void handle_record_remove (void *cls, GNUNET_SERVER_receive_done (client, GNUNET_OK); } +struct ZoneIterationProcResult +{ + int have_zone_key; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded zone_key; + + int have_signature; + struct GNUNET_CRYPTO_RsaSignature signature; + struct GNUNET_TIME_Absolute expire; + + int have_name; + char name[256]; + + unsigned int rd_count; + char *rd_ser; +}; + void zone_iteration_proc (void *cls, const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, @@ -587,15 +605,40 @@ void zone_iteration_proc (void *cls, const struct GNUNET_NAMESTORE_RecordData *rd, const struct GNUNET_CRYPTO_RsaSignature *signature) { - struct ZoneIterationResponseMessage zir_msg; - struct GNUNET_NAMESTORE_ZoneIteration * zi = cls; + struct ZoneIterationProcResult *zipr = cls; + size_t len; + if (zone_key != NULL) + { + zipr->zone_key = *zone_key; + zipr->have_zone_key = GNUNET_YES; + } + else + zipr->have_zone_key = GNUNET_NO; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_ITERATION_RESPONSE"); - zir_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE); - zir_msg.op_id = htonl(zi->op_id); - zir_msg.header.size = htons (sizeof (struct ZoneIterationResponseMessage)); + zipr->expire = expire; - GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO); + if (name != NULL) + { + memcpy (zipr->name, name, strlen(name) + 1); + zipr->have_name = GNUNET_YES; + } + else + zipr->have_name = GNUNET_NO; + + zipr->rd_count = rd_count; + + if (signature != NULL) + { + zipr->signature = *signature; + zipr->have_signature = GNUNET_YES; + } + else + zipr->have_signature = GNUNET_NO; + + if ((rd_count > 0) && (rd != NULL)) + { + len = GNUNET_NAMESTORE_records_serialize (&zipr->rd_ser, rd_count, rd); + } } static void handle_iteration_start (void *cls, @@ -607,6 +650,8 @@ static void handle_iteration_start (void *cls, struct ZoneIterationStartMessage * zis_msg = (struct ZoneIterationStartMessage *) message; struct GNUNET_NAMESTORE_Client *nc; struct GNUNET_NAMESTORE_ZoneIteration *zi; + struct ZoneIterationResponseMessage zir_msg; + struct ZoneIterationProcResult zipr; int res; nc = client_lookup(client); @@ -625,8 +670,16 @@ static void handle_iteration_start (void *cls, GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi); - res = GSN_database->iterate_records (GSN_database->cls, &zis_msg->zone, NULL, zi->offset , &zone_iteration_proc, zi); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "iterate_records: %i\n", res); + res = GSN_database->iterate_records (GSN_database->cls, &zis_msg->zone, NULL, zi->offset , &zone_iteration_proc, &zipr); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message\n", "ZONE_ITERATION_RESPONSE"); + zir_msg.header.type = htons (GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_RESPONSE); + zir_msg.op_id = htonl(zi->op_id); + zir_msg.header.size = htons (sizeof (struct ZoneIterationResponseMessage)); + + GNUNET_SERVER_notification_context_unicast (snc, zi->client->client, (const struct GNUNET_MessageHeader *) &zir_msg, GNUNET_NO); + + GNUNET_SERVER_receive_done (client, GNUNET_OK); } @@ -679,6 +732,7 @@ static void handle_iteration_next (void *cls, struct GNUNET_NAMESTORE_ZoneIteration *zi; struct ZoneIterationStopMessage * zis_msg = (struct ZoneIterationStopMessage *) message; uint32_t id; + int res; nc = client_lookup(client); if (nc == NULL) @@ -702,7 +756,7 @@ static void handle_iteration_next (void *cls, } zi->offset++; - res = GSN_database->iterate_records (GSN_database->cls, &zis_msg->zone, NULL, zi->offset , &zone_iteration_proc, zi); + res = GSN_database->iterate_records (GSN_database->cls, &zi->zone, NULL, zi->offset , &zone_iteration_proc, zi); } diff --git a/src/namestore/hostkey b/src/namestore/hostkey new file mode 100644 index 0000000000000000000000000000000000000000..eac1d1e2fb312c41e59f0b950885a08ea4df2acc GIT binary patch literal 913 zcmV;C18)2SkpTbz0s#L2fB=910002Zco5MMf{mF!b&kaI2=mGEwZL67@bz%6F0i4R zRWM|)Apa8^@YEP~;2!aDg7n1{Mfgz{@;#P|-WhxSg6U^W-p95mBdYz3AtAV@1@0J^ z8=cG)f79E}!bB2vQMb(x8}u{8=N|U7%GZ`a_(2-55xNcgrTF_S#vI9b!UNir^Ui2J{N z^-iZE@3YE~X!CMa`n4M?V@cH4{xbHZGk9F#2^EHvAg_-EFj3wzkHG_@tot5PsCZO` zNl=$+k$9b3ezlSMm|Hl>z7>%H0k!R~d?BZ~vJ{Nfpp4LZ0G>QG zSAo-7z4^~jzo?)CU6W}3Oey%yV?B7TV5A*5<8=H9l0|@tz2l!`WVtmqb^so`@A{E9^qzY<&Tas8h*=?+3xMB^l_0m9$=P;!VWTRw6+zM2Zo@32w zk_^VdV+VDUAv@wN4chjB=9T%W?b!-$_!taDk?&g+k?|1`i*7mkGwv{J&j~?r7t^W% z6bHb4i$|fwsVP4-FE&K}39;}kE$4OriR4reM0&4GlLMLO^#hbDn-X{uRtwoY3SNx} z^jDxLq0XsRP*IajE6hTRDbRceV7|8WcTD-7Gi<}ZAuALP%O_{Wz?Oy9 zFhxiQ@T+zQxT^2Dyoio5RDMB^=`vnvMgdvYn; z$_?v+az@V+zZ^V}9`EkI0dURZRJ-lwBOl%#$)#&SHR|xs7qjx#q=KAy!NKB-k&|LB nd$c)y4vhLlcrzEPL#lQPpZ$ALkA#n|>sH#pTYhyMImlj5Jc7J# literal 0 HcmV?d00001 diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h index 04eaa61fc..5b6a24ca6 100644 --- a/src/namestore/namestore.h +++ b/src/namestore/namestore.h @@ -43,6 +43,42 @@ #define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT 441 #define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP 442 +size_t +GNUNET_NAMESTORE_records_serialize (char ** dest, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd); + +int +GNUNET_NAMESTORE_records_deserialize ( struct GNUNET_NAMESTORE_RecordData **dest, char *src, size_t len); + +/** + * A GNS record serialized for network transmission. + * layout is [struct GNUNET_NAMESTORE_NetworkRecord][char[data_size] data] + */ +struct GNUNET_NAMESTORE_NetworkRecord +{ + /** + * Expiration time for the DNS record. + */ + struct GNUNET_TIME_AbsoluteNBO expiration; + + /** + * Number of bytes in 'data'. + */ + uint32_t data_size; + + /** + * Type of the GNS/DNS record. + */ + uint32_t record_type; + + /** + * Flags for the record. + */ + uint32_t flags; +}; + + GNUNET_NETWORK_STRUCT_BEGIN /** diff --git a/src/namestore/namestore_common.c b/src/namestore/namestore_common.c new file mode 100644 index 000000000..37f0eab0b --- /dev/null +++ b/src/namestore/namestore_common.c @@ -0,0 +1,159 @@ +/* + This file is part of GNUnet. + (C) 2009, 2010 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 namestore/namestore_common.c + * @brief API to access the NAMESTORE service + * @author Martin Schanzenbach + * @author Matthias Wachs + */ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_constants.h" +#include "gnunet_arm_service.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" +#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING + +#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) +/** + * Serialize an array of GNUNET_NAMESTORE_RecordData *rd to transmit over the + * network + * + * @param dest where to write the serialized data + * @param rd_count number of elements in array + * @param rd array + * + * @return number of bytes written to destination dest + */ +size_t +GNUNET_NAMESTORE_records_serialize (char ** dest, + unsigned int rd_count, + const struct GNUNET_NAMESTORE_RecordData *rd) +{ + //size_t len = 0; + struct GNUNET_NAMESTORE_NetworkRecord * nr; + char * d = (*dest); + int c = 0; + int offset; + + + size_t total_len = rd_count * sizeof (struct GNUNET_NAMESTORE_NetworkRecord); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Struct size: %u\n", total_len); + + /* figure out total len required */ + for (c = 0; c < rd_count; c ++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data size record[%i] : %u\n", c, rd[c].data_size); + total_len += rd[c].data_size; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serializing %i records with total length of %llu\n", rd_count, total_len); + + (*dest) = GNUNET_malloc (total_len); + d = (*dest); + + /* copy records */ + offset = 0; + + for (c = 0; c < rd_count; c ++) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized record [%i]: data_size %i\n", c,rd[c].data_size); + + nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &d[offset]; + nr->data_size = htonl (rd[c].data_size); + nr->flags = htonl (rd[c].flags); + nr->record_type = htonl (rd[c].record_type); + nr->expiration = GNUNET_TIME_absolute_hton(rd[c].expiration); + + /*put data here */ + offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); + memcpy (&d[offset], rd[c].data, rd[c].data_size); + offset += rd[c].data_size; + } + + GNUNET_assert (offset == total_len); + return total_len; +} + + +/** + * Deserialize an array of GNUNET_NAMESTORE_RecordData *rd after transmission + * over the network + * + * @param source where to read the data to deserialize + * @param rd_count number of elements in array + * @param rd array + * + * @return number of elements deserialized + */ +int +GNUNET_NAMESTORE_records_deserialize ( struct GNUNET_NAMESTORE_RecordData **dest, char *src, size_t len) +{ + struct GNUNET_NAMESTORE_NetworkRecord * nr; + struct GNUNET_NAMESTORE_RecordData *d = (*dest); + int elements; + size_t offset; + uint32_t data_size; + int c; + + offset = 0; + elements = 0; + while (offset < len) + { + nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset]; + offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); + + data_size = ntohl (nr->data_size); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Datasize record[%i]: %u\n", elements, data_size); + offset += data_size; + elements ++; + } + + GNUNET_assert (len == offset); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserializing %i records with total length of %u\n", elements, len); + + (*dest) = GNUNET_malloc (elements * sizeof (struct GNUNET_NAMESTORE_RecordData)); + d = (*dest); + + offset = 0; + for (c = 0; c < elements; c++) + { + nr = (struct GNUNET_NAMESTORE_NetworkRecord *) &src[offset]; + d[c].expiration = GNUNET_TIME_absolute_ntoh(nr->expiration); + d[c].record_type = ntohl (nr->record_type); + d[c].flags = ntohl (nr->flags); + d[c].data_size = ntohl (nr->data_size); + d[c].data = GNUNET_malloc (d[c].data_size); + GNUNET_assert (d[c].data != NULL); + + offset += sizeof (struct GNUNET_NAMESTORE_NetworkRecord); + memcpy((char *) d[c].data, &src[offset], d[c].data_size); + + offset += d[c].data_size; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserialized record[%i] /w data_size %i\n", c, d[c].data_size); + } + GNUNET_assert(offset == len); + + return elements; +} + +/* end of namestore_api.c */ diff --git a/src/namestore/test_namestore_record_serialization.c b/src/namestore/test_namestore_record_serialization.c new file mode 100644 index 000000000..5ea345bef --- /dev/null +++ b/src/namestore/test_namestore_record_serialization.c @@ -0,0 +1,157 @@ +/* + 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 namestore/test_namestore_record_serialization.c + * @brief testcase for test_namestore_record_serialization.c + */ +#include "platform.h" +#include "gnunet_common.h" +#include "gnunet_namestore_service.h" +#include "namestore.h" + +#define VERBOSE GNUNET_NO + +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10) + +static int res; + +static void +run (void *cls, char *const *args, const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char * dest = NULL; + size_t len; + int c; + int elem = 0; + + int rd_count = 3; + size_t data_len; + struct GNUNET_NAMESTORE_RecordData src[rd_count]; + struct GNUNET_NAMESTORE_RecordData *dst = NULL; + + memset(src, '\0', rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); + + data_len = 0; + for (c = 0; c < rd_count; c++) + { + src[c].record_type = c+1; + src[c].data_size = data_len; + src[c].data = GNUNET_malloc (data_len); + + /* Setting data to data_len * record_type */ + memset ((char *) src[c].data, 'a', data_len); + data_len += 10; + } + res = 0; + + len = GNUNET_NAMESTORE_records_serialize (&dest, rd_count, src); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized data len: %u\n",len); + + GNUNET_assert (dest != NULL); + + elem = GNUNET_NAMESTORE_records_deserialize(&dst, dest, len); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Deserialized elements: %u\n",elem); + + GNUNET_assert (elem == rd_count); + GNUNET_assert (dst != NULL); + + for (c = 0; c < elem; c++) + { + if (src[c].data_size != dst[c].data_size) + { + GNUNET_break (0); + res = 1; + } + if (GNUNET_TIME_absolute_get_difference(src[c].expiration, dst[c].expiration).rel_value != GNUNET_TIME_relative_get_zero().rel_value) + { + GNUNET_break (0); + res = 1; + } + if (src[c].flags != dst[c].flags) + { + GNUNET_break (0); + res = 1; + } + if (src[c].record_type != dst[c].record_type) + { + GNUNET_break (0); + res = 1; + } + + size_t data_size = src[c].data_size; + char data[data_size]; + memset (data, 'a', data_size); + if (0 != memcmp (data, dst[c].data, data_size)) + { + GNUNET_break (0); + res = 1; + } + if (0 != memcmp (data, src[c].data, data_size)) + { + GNUNET_break (0); + res = 1; + } + if (0 != memcmp (src[c].data, dst[c].data, src[c].data_size)) + { + GNUNET_break (0); + res = 1; + } + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c); + /* clean up */ + GNUNET_free((char *) dst[c].data); + GNUNET_free((char *) src[c].data); + } + GNUNET_free (dest); + GNUNET_free (dst); +} + +static int +check () +{ + static char *const argv[] = { "test_namestore_record_serialization", + "-c", + "test_namestore_api.conf", +#if VERBOSE + "-L", "DEBUG", +#endif + NULL + }; + static struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_OPTION_END + }; + + res = 1; + GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1, argv, "test_namestore_record_serialization", + "nohelp", options, &run, &res); + return res; +} + +int +main (int argc, char *argv[]) +{ + int ret; + + ret = check (); + + return ret; +} + +/* end of test_namestore_record_serialization.c */ -- 2.25.1