From 0cd0e3a5287af73bb81219ebc9548395a8945ce8 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 10 Apr 2018 13:02:28 +0200 Subject: [PATCH] more work on gnunet-zoneimport, some bugfix in flat namestore, misc. style fixes --- src/dns/dnsparser.c | 38 +- src/gns/plugin_gnsrecord_gns.c | 12 +- src/include/gnunet_gnsrecord_plugin.h | 30 +- src/include/gnunet_namestore_plugin.h | 55 +- src/include/gnunet_program_lib.h | 4 +- src/namestore/.gitignore | 1 + src/namestore/Makefile.am | 12 + src/namestore/gnunet-namestore-fcfsd.c | 93 ++- src/namestore/gnunet-namestore.c | 43 +- src/namestore/gnunet-zoneimport.c | 896 ++++++++++++++++++++++ src/namestore/namestore_api_monitor.c | 4 + src/namestore/plugin_namestore_flat.c | 142 ++-- src/namestore/plugin_namestore_postgres.c | 13 +- src/namestore/plugin_namestore_sqlite.c | 14 +- src/namestore/plugin_rest_namestore.c | 58 +- src/util/program.c | 89 ++- 16 files changed, 1309 insertions(+), 195 deletions(-) create mode 100644 src/namestore/gnunet-zoneimport.c diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index ab833f7c5..7e200ee7c 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c @@ -919,9 +919,14 @@ GNUNET_DNSPARSER_builder_add_mx (char *dst, if (*off + sizeof (uint16_t) > dst_len) return GNUNET_NO; mxpref = htons (mx->preference); - GNUNET_memcpy (&dst[*off], &mxpref, sizeof (mxpref)); + GNUNET_memcpy (&dst[*off], + &mxpref, + sizeof (mxpref)); (*off) += sizeof (mxpref); - return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost); + return GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + off, + mx->mxhost); } @@ -1081,21 +1086,36 @@ add_record (char *dst, switch (record->type) { case GNUNET_DNSPARSER_TYPE_MX: - ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx); + ret = GNUNET_DNSPARSER_builder_add_mx (dst, + dst_len, + &pos, + record->data.mx); break; case GNUNET_DNSPARSER_TYPE_CERT: - ret = GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &pos, record->data.cert); + ret = GNUNET_DNSPARSER_builder_add_cert (dst, + dst_len, + &pos, + record->data.cert); break; case GNUNET_DNSPARSER_TYPE_SOA: - ret = GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa); + ret = GNUNET_DNSPARSER_builder_add_soa (dst, + dst_len, + &pos, + record->data.soa); break; case GNUNET_DNSPARSER_TYPE_NS: case GNUNET_DNSPARSER_TYPE_CNAME: case GNUNET_DNSPARSER_TYPE_PTR: - ret = GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &pos, record->data.hostname); + ret = GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &pos, + record->data.hostname); break; case GNUNET_DNSPARSER_TYPE_SRV: - ret = GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv); + ret = GNUNET_DNSPARSER_builder_add_srv (dst, + dst_len, + &pos, + record->data.srv); break; default: if (pos + record->data.raw.data_len > dst_len) @@ -1103,7 +1123,9 @@ add_record (char *dst, ret = GNUNET_NO; break; } - GNUNET_memcpy (&dst[pos], record->data.raw.data, record->data.raw.data_len); + GNUNET_memcpy (&dst[pos], + record->data.raw.data, + record->data.raw.data_len); pos += record->data.raw.data_len; ret = GNUNET_OK; break; diff --git a/src/gns/plugin_gnsrecord_gns.c b/src/gns/plugin_gnsrecord_gns.c index 6adad0f34..07d1a9c04 100644 --- a/src/gns/plugin_gnsrecord_gns.c +++ b/src/gns/plugin_gnsrecord_gns.c @@ -173,7 +173,9 @@ gns_string_to_value (void *cls, case GNUNET_GNSRECORD_TYPE_PKEY: if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (s, strlen (s), &pkey)) + GNUNET_CRYPTO_ecdsa_public_key_from_string (s, + strlen (s), + &pkey)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Unable to parse PKEY record `%s'\n"), @@ -181,7 +183,9 @@ gns_string_to_value (void *cls, return GNUNET_SYSERR; } *data = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPublicKey); - GNUNET_memcpy (*data, &pkey, sizeof (pkey)); + GNUNET_memcpy (*data, + &pkey, + sizeof (pkey)); *data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); return GNUNET_OK; @@ -234,7 +238,9 @@ gns_string_to_value (void *cls, GNUNET_free (cpy); *data_size = off; *data = GNUNET_malloc (off); - GNUNET_memcpy (*data, nsbuf, off); + GNUNET_memcpy (*data, + nsbuf, + off); return GNUNET_OK; } case GNUNET_GNSRECORD_TYPE_VPN: diff --git a/src/include/gnunet_gnsrecord_plugin.h b/src/include/gnunet_gnsrecord_plugin.h index d212c3663..e3e1a98eb 100644 --- a/src/include/gnunet_gnsrecord_plugin.h +++ b/src/include/gnunet_gnsrecord_plugin.h @@ -53,10 +53,11 @@ extern "C" * @param data_size number of bytes in @a data * @return NULL on error, otherwise human-readable representation of the value */ -typedef char * (*GNUNET_GNSRECORD_ValueToStringFunction) (void *cls, - uint32_t type, - const void *data, - size_t data_size); +typedef char * +(*GNUNET_GNSRECORD_ValueToStringFunction) (void *cls, + uint32_t type, + const void *data, + size_t data_size); /** @@ -71,11 +72,12 @@ typedef char * (*GNUNET_GNSRECORD_ValueToStringFunction) (void *cls, * @param data_size set to number of bytes in @a data * @return #GNUNET_OK on success */ -typedef int (*GNUNET_GNSRECORD_StringToValueFunction) (void *cls, - uint32_t type, - const char *s, - void **data, - size_t *data_size); +typedef int +(*GNUNET_GNSRECORD_StringToValueFunction) (void *cls, + uint32_t type, + const char *s, + void **data, + size_t *data_size); /** @@ -86,8 +88,9 @@ typedef int (*GNUNET_GNSRECORD_StringToValueFunction) (void *cls, * @param dns_typename name to convert * @return corresponding number, UINT32_MAX on error */ -typedef uint32_t (*GNUNET_GNSRECORD_TypenameToNumberFunction) (void *cls, - const char *dns_typename); +typedef uint32_t +(*GNUNET_GNSRECORD_TypenameToNumberFunction) (void *cls, + const char *dns_typename); /** @@ -98,8 +101,9 @@ typedef uint32_t (*GNUNET_GNSRECORD_TypenameToNumberFunction) (void *cls, * @param type number of a type to convert * @return corresponding typestring, NULL on error */ -typedef const char * (*GNUNET_GNSRECORD_NumberToTypenameFunction) (void *cls, - uint32_t type); +typedef const char * +(*GNUNET_GNSRECORD_NumberToTypenameFunction) (void *cls, + uint32_t type); /** diff --git a/src/include/gnunet_namestore_plugin.h b/src/include/gnunet_namestore_plugin.h index 3ec0299ba..48965b3b6 100644 --- a/src/include/gnunet_namestore_plugin.h +++ b/src/include/gnunet_namestore_plugin.h @@ -52,11 +52,12 @@ extern "C" * @param rd_count number of entries in @a rd array * @param rd array of records with data to store */ -typedef void (*GNUNET_NAMESTORE_RecordIterator) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd); +typedef void +(*GNUNET_NAMESTORE_RecordIterator) (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *private_key, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd); /** @@ -81,12 +82,13 @@ struct GNUNET_NAMESTORE_PluginFunctions * @param rd array of records with data to store * @return #GNUNET_OK on success, else #GNUNET_SYSERR */ - int (*store_records) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - unsigned int rd_count, - const struct GNUNET_GNSRECORD_Data *rd); - + int + (*store_records) (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const char *label, + unsigned int rd_count, + const struct GNUNET_GNSRECORD_Data *rd); + /** * Lookup records in the datastore for which we are the authority. * @@ -97,11 +99,12 @@ struct GNUNET_NAMESTORE_PluginFunctions * @param iter_cls closure for @a iter * @return #GNUNET_OK on success, else #GNUNET_SYSERR */ - int (*lookup_records) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const char *label, - GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); - + int + (*lookup_records) (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const char *label, + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls); /** @@ -115,10 +118,12 @@ struct GNUNET_NAMESTORE_PluginFunctions * @param iter_cls closure for @a iter * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error */ - int (*iterate_records) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - uint64_t offset, - GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); + int + (*iterate_records) (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + uint64_t offset, + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls); /** @@ -132,10 +137,12 @@ struct GNUNET_NAMESTORE_PluginFunctions * @param iter_cls closure for @a iter * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error */ - int (*zone_to_name) (void *cls, - const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, - const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, - GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls); + int + (*zone_to_name) (void *cls, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, + const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls); }; diff --git a/src/include/gnunet_program_lib.h b/src/include/gnunet_program_lib.h index 526760bdd..65be7ab3d 100644 --- a/src/include/gnunet_program_lib.h +++ b/src/include/gnunet_program_lib.h @@ -84,6 +84,7 @@ GNUNET_PROGRAM_run2 (int argc, void *task_cls, int run_without_scheduler); + /** * Run a standard GNUnet command startup sequence (initialize loggers * and configuration, parse options). @@ -103,7 +104,8 @@ GNUNET_PROGRAM_run (int argc, const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, - GNUNET_PROGRAM_Main task, void *task_cls); + GNUNET_PROGRAM_Main task, + void *task_cls); #if 0 /* keep Emacsens' auto-indent happy */ diff --git a/src/namestore/.gitignore b/src/namestore/.gitignore index 4995a9e36..9a4c615ba 100644 --- a/src/namestore/.gitignore +++ b/src/namestore/.gitignore @@ -19,3 +19,4 @@ test_namestore_api_zone_iteration_stop.nc test_plugin_namestore_postgres test_plugin_namestore_sqlite test_plugin_namestore_flat +gnunet-zoneimport diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am index a848d4b72..cdfed543d 100644 --- a/src/namestore/Makefile.am +++ b/src/namestore/Makefile.am @@ -126,12 +126,24 @@ libexec_PROGRAMS = \ bin_PROGRAMS = \ gnunet-namestore +noinst_PROGRAMS = \ + gnunet-zoneimport + if HAVE_MHD libexec_PROGRAMS += \ gnunet-namestore-fcfsd endif +gnunet_zoneimport_SOURCES = \ + gnunet-zoneimport.c +gnunet_zoneimport_LDADD = \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ + $(top_builddir)/src/dns/libgnunetdnsparser.la \ + $(top_builddir)/src/dns/libgnunetdnsstub.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) + gnunet_namestore_SOURCES = \ gnunet-namestore.c gnunet_namestore_LDADD = \ diff --git a/src/namestore/gnunet-namestore-fcfsd.c b/src/namestore/gnunet-namestore-fcfsd.c index b38761d5a..ddd609918 100644 --- a/src/namestore/gnunet-namestore-fcfsd.c +++ b/src/namestore/gnunet-namestore-fcfsd.c @@ -480,10 +480,16 @@ post_iterator (void *cls, const char *filename, const char *content_type, const char *transfer_encoding, - const char *data, uint64_t off, size_t size) + const char *data, + uint64_t off, + size_t size) { struct Request *request = cls; + (void) kind; + (void) filename; + (void) content_type; + (void) transfer_encoding; if (0 == strcmp ("domain", key)) { if (size + off >= sizeof(request->domain_name)) @@ -578,7 +584,6 @@ zone_to_name_cb (void *cls, struct GNUNET_GNSRECORD_Data r; request->qe = NULL; - if (0 != rd_count) { GNUNET_log (GNUNET_ERROR_TYPE_INFO, @@ -726,8 +731,10 @@ create_response (void *cls, { request = GNUNET_new (struct Request); *ptr = request; - request->pp = MHD_create_post_processor (connection, 1024, - &post_iterator, request); + request->pp = MHD_create_post_processor (connection, + 1024, + &post_iterator, + request); if (NULL == request->pp) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -770,7 +777,8 @@ create_response (void *cls, _("Domain name must not contain `.'\n")); request->phase = RP_FAIL; return fill_s_reply ("Domain name must not contain `.', sorry.", - request, connection); + request, + connection); } if (NULL != strchr (request->domain_name, (int) '+')) { @@ -781,13 +789,14 @@ create_response (void *cls, request, connection); } request->phase = RP_LOOKUP; - request->qe = GNUNET_NAMESTORE_records_lookup (ns, - &fcfs_zone_pkey, - request->domain_name, - &lookup_block_error, - request, - &lookup_block_processor, - request); + request->qe + = GNUNET_NAMESTORE_records_lookup (ns, + &fcfs_zone_pkey, + request->domain_name, + &lookup_block_error, + request, + &lookup_block_processor, + request); break; case RP_LOOKUP: break; @@ -834,6 +843,9 @@ request_completed_callback (void *cls, { struct Request *request = *con_cls; + (void) cls; + (void) connection; + (void) toe; if (NULL == request) return; if (NULL != request->pp) @@ -871,19 +883,34 @@ run_httpd () wes = GNUNET_NETWORK_fdset_create (); wws = GNUNET_NETWORK_fdset_create (); max = -1; - GNUNET_assert (MHD_YES == MHD_get_fdset (httpd, &rs, &ws, &es, &max)); - haveto = MHD_get_timeout (httpd, &timeout); + GNUNET_assert (MHD_YES == + MHD_get_fdset (httpd, + &rs, + &ws, + &es, + &max)); + haveto = MHD_get_timeout (httpd, + &timeout); if (haveto == MHD_YES) tv.rel_value_us = (uint64_t) timeout * 1000LL; else tv = GNUNET_TIME_UNIT_FOREVER_REL; - GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max + 1); - GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1); - GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1); + GNUNET_NETWORK_fdset_copy_native (wrs, + &rs, + max + 1); + GNUNET_NETWORK_fdset_copy_native (wws, + &ws, + max + 1); + GNUNET_NETWORK_fdset_copy_native (wes, + &es, + max + 1); httpd_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH, - tv, wrs, wws, - &do_httpd, NULL); + tv, + wrs, + wws, + &do_httpd, + NULL); GNUNET_NETWORK_fdset_destroy (wrs); GNUNET_NETWORK_fdset_destroy (wws); GNUNET_NETWORK_fdset_destroy (wes); @@ -898,6 +925,7 @@ run_httpd () static void do_httpd (void *cls) { + (void) cls; httpd_task = NULL; MHD_run (httpd); run_httpd (); @@ -912,6 +940,7 @@ do_httpd (void *cls) static void do_shutdown (void *cls) { + (void) cls; if (NULL != httpd_task) { GNUNET_SCHEDULER_cancel (httpd_task); @@ -967,6 +996,9 @@ identity_cb (void *cls, { int options; + (void) cls; + (void) ctx; + (void) name; id_op = NULL; if (NULL == ego) { @@ -1014,9 +1046,14 @@ identity_cb (void *cls, * @param cfg configuration */ static void -run (void *cls, char *const *args, const char *cfgfile, +run (void *cls, + char *const *args, + const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { + (void) cls; + (void) args; + (void) cfgfile; if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, "fcfsd", @@ -1056,21 +1093,27 @@ run (void *cls, char *const *args, const char *cfgfile, * @return 0 ok, 1 on error */ int -main (int argc, char *const *argv) +main (int argc, + char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; - int ret; - if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) + if (GNUNET_OK != + GNUNET_STRINGS_get_utf8_args (argc, argv, + &argc, &argv)) return 2; - GNUNET_log_setup ("fcfsd", "WARNING", NULL); + GNUNET_log_setup ("fcfsd", + "WARNING", + NULL); ret = (GNUNET_OK == - GNUNET_PROGRAM_run (argc, argv, "fcfsd", + GNUNET_PROGRAM_run (argc, + argv, + "gnunet-namestore-fcfsd", _("GNU Name System First Come First Serve name registration service"), options, &run, NULL)) ? 0 : 1; diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index 054417ab5..2eff995e0 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c @@ -203,6 +203,7 @@ static int monitor; static void do_shutdown (void *cls) { + (void) cls; if (NULL != get_default) { GNUNET_IDENTITY_cancel (get_default); @@ -323,6 +324,7 @@ del_continuation (void *cls, int32_t success, const char *emsg) { + (void) cls; del_qe = NULL; if (GNUNET_NO == success) { @@ -348,6 +350,7 @@ del_continuation (void *cls, static void zone_iteration_finished (void *cls) { + (void) cls; list_it = NULL; test_finished (); } @@ -359,6 +362,7 @@ zone_iteration_finished (void *cls) static void zone_iteration_error_cb (void *cls) { + (void) cls; list_it = NULL; fprintf (stderr, "Error iterating over zone\n"); @@ -385,11 +389,11 @@ display_record (void *cls, { const char *typestring; char *s; - unsigned int i; const char *ets; struct GNUNET_TIME_Absolute at; struct GNUNET_TIME_Relative rt; + (void) cls; if ( (NULL != name) && (0 != strcmp (name, rname)) ) { @@ -399,7 +403,7 @@ display_record (void *cls, FPRINTF (stdout, "%s:\n", rname); - for (i=0;i +#include +#include +#include +#include + + +/** + * Record for the request to be stored by GNS. + */ +struct Record +{ + /** + * Kept in a DLL. + */ + struct Record *next; + + /** + * Kept in a DLL. + */ + struct Record *prev; + + /** + * GNS record. + */ + struct GNUNET_GNSRECORD_Data grd; + +}; + + +/** + * Request we should make. + */ +struct Request +{ + /** + * Requests are kept in a DLL. + */ + struct Request *next; + + /** + * Requests are kept in a DLL. + */ + struct Request *prev; + + /** + * Head of records that should be published in GNS for + * this hostname. + */ + struct Record *rec_head; + + /** + * Tail of records that should be published in GNS for + * this hostname. + */ + struct Record *rec_tail; + + /** + * Socket used to make the request, NULL if not active. + */ + struct GNUNET_DNSSTUB_RequestSocket *rs; + + /** + * Raw DNS query. + */ + void *raw; + + /** + * Number of bytes in @e raw. + */ + size_t raw_len; + + /** + * Hostname we are resolving. + */ + char *hostname; + + /** + * Answer we got back and are currently parsing, or NULL + * if not active. + */ + struct GNUNET_DNSPARSER_Packet *p; + + /** + * At what time does the (earliest) of the returned records + * for this name expire? At this point, we need to re-fetch + * the record. + */ + struct GNUNET_TIME_Absolute expires__; + + /** + * When did we last issue this request? + */ + time_t time; + + /** + * How often did we issue this query? (And failed, reset + * to zero once we were successful.) + */ + int issue_num; + + /** + * random 16-bit DNS query identifier. + */ + uint16_t id; +}; + +/** + * Namestore plugin. + */ +static struct GNUNET_NAMESTORE_PluginFunctions *ns; + +/** + * Context for DNS resolution. + */ +static struct GNUNET_DNSSTUB_Context *ctx; + +/** + * The number of queries that are outstanding + */ +static unsigned int pending; + +/** + * Number of lookups we performed overall. + */ +static unsigned int lookups; + +/** + * Number of lookups that failed. + */ +static unsigned int failures; + +/** + * Number of records we found. + */ +static unsigned int records; + +/** + * Head of DLL of all requests to perform, sorted by + * the time we should next do the request (i.e. by expires). + */ +static struct Request *req_head; + +/** + * Tail of DLL of all requests to perform, sorted by + * the time we should next do the request (i.e. by expires). + */ +static struct Request *req_tail; + +/** + * Main task. + */ +static struct GNUNET_SCHEDULER_Task *t; + +/** + * Which DNS server do we use for queries? + */ +static char *dns_server; + +/** + * Name of the database plugin (for loading/unloading). + */ +static char *db_lib_name; + + +/** + * Maximum number of queries pending at the same time. + */ +#define THRESH 20 + +/** + * TIME_THRESH is in usecs. How quickly do we submit fresh queries. + * Used as an additional throttle. + */ +#define TIME_THRESH 10 + +/** + * How often do we retry a query before giving up for good? + */ +#define MAX_RETRIES 5 + + +/** + * Callback for #for_all_records + * + * @param cls closure + * @param rec a DNS record + */ +typedef void +(*RecordProcessor) (void *cls, + const struct GNUNET_DNSPARSER_Record *rec); + + +/** + * Call @a rp for each record in @a p, regardless of + * what response section it is in. + * + * @param p packet from DNS + * @param rp function to call + * @param rp_cls closure for @a rp + */ +static void +for_all_records (const struct GNUNET_DNSPARSER_Packet *p, + RecordProcessor rp, + void *rp_cls) +{ + for (unsigned int i=0;inum_answers;i++) + { + struct GNUNET_DNSPARSER_Record *rs = &p->answers[i]; + + rp (rp_cls, + rs); + } + for (unsigned int i=0;inum_authority_records;i++) + { + struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i]; + + rp (rp_cls, + rs); + } + for (unsigned int i=0;inum_additional_records;i++) + { + struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i]; + + rp (rp_cls, + rs); + } +} + + +/** + * Add record to the GNS record set for @a req. + * + * @param req the request to expand GNS record set for + * @param type type to use + * @param expiration_time when should @a rec expire + * @param data raw data to store + * @param data_len number of bytes in @a data + */ +static void +add_record (struct Request *req, + uint32_t type, + struct GNUNET_TIME_Absolute expiration_time, + const void *data, + size_t data_len) +{ + struct Record *rec; + + rec = GNUNET_malloc (sizeof (struct Record) + data_len); + rec->grd.data = &rec[1]; + rec->grd.expiration_time = expiration_time.abs_value_us; + rec->grd.data_size = data_len; + rec->grd.record_type = type; + rec->grd.flags = GNUNET_GNSRECORD_RF_NONE; + GNUNET_memcpy (&rec[1], + data, + data_len); + GNUNET_CONTAINER_DLL_insert (req->rec_head, + req->rec_tail, + rec); +} + + +/** + * Closure for #check_for_glue. + */ +struct GlueClosure +{ + /** + * Overall request we are processing. + */ + struct Request *req; + + /** + * NS name we are looking for glue for. + */ + const char *ns; + + /** + * Set to #GNUNET_YES if glue was found. + */ + int found; +}; + + +/** + * Try to find glue records for a given NS record. + * + * @param cls a `struct GlueClosure *` + * @param rec record that may contain glue information + */ +static void +check_for_glue (void *cls, + const struct GNUNET_DNSPARSER_Record *rec) +{ + struct GlueClosure *gc = cls; + char dst[65536]; + size_t dst_len; + size_t off; + char ip[INET6_ADDRSTRLEN+1]; + socklen_t ip_size = (socklen_t) sizeof (ip); + + if (0 != strcasecmp (rec->name, + gc->ns)) + return; + dst_len = sizeof (dst); + off = 0; + switch (rec->type) + { + case GNUNET_DNSPARSER_TYPE_A: + if (sizeof (struct in_addr) != rec->data.raw.data_len) + { + GNUNET_break (0); + return; + } + if (NULL == + inet_ntop (AF_INET, + &rec->data.raw.data, + ip, + ip_size)) + { + GNUNET_break (0); + return; + } + if ( (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &off, + gc->req->hostname)) && + (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &off, + ip)) ) + { + add_record (gc->req, + rec->type, + rec->expiration_time, + dst, + off); + gc->found = GNUNET_YES; + } + break; + case GNUNET_DNSPARSER_TYPE_AAAA: + if (sizeof (struct in6_addr) != rec->data.raw.data_len) + { + GNUNET_break (0); + return; + } + if (NULL == + inet_ntop (AF_INET6, + &rec->data.raw.data, + ip, + ip_size)) + { + GNUNET_break (0); + return; + } + if ( (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &off, + gc->req->hostname)) && + (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &off, + ip)) ) + { + add_record (gc->req, + rec->type, + rec->expiration_time, + dst, + off); + gc->found = GNUNET_YES; + } + break; + case GNUNET_DNSPARSER_TYPE_CNAME: + GNUNET_break (0); /* FIXME: implement! */ + break; + default: + /* useless, do nothing */ + break; + } +} + + +/** + * We received @a rec for @a req. Remember the answer. + * + * @param cls a `struct Request` + * @param rec response + */ +static void +process_record (void *cls, + const struct GNUNET_DNSPARSER_Record *rec) +{ + struct Request *req = cls; + char dst[65536]; + size_t dst_len; + size_t off; + + dst_len = sizeof (dst); + off = 0; + records++; + if (0 != strcasecmp (rec->name, + req->hostname)) + return; /* does not match hostname, might be glue, but + not useful for this pass! */ + if (0 == + GNUNET_TIME_absolute_get_remaining (rec->expiration_time).rel_value_us) + return; /* record expired */ + switch (rec->type) + { + case GNUNET_DNSPARSER_TYPE_NS: + { + struct GlueClosure gc; + + /* check for glue */ + gc.req = req; + gc.ns = rec->data.hostname; + gc.found = GNUNET_NO; + for_all_records (req->p, + &check_for_glue, + &gc); + if ( (GNUNET_NO == gc.found) && + (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &off, + req->hostname)) && + (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &off, + rec->data.hostname)) ) + add_record (req, + rec->type, + rec->expiration_time, + dst, + off); + break; + } + case GNUNET_DNSPARSER_TYPE_CNAME: + /* Special logic required, FIXME: support later! */ + fprintf (stdout, + "%s CNAME %s\n", + rec->name, + rec->data.hostname); + break; + case GNUNET_DNSPARSER_TYPE_DNAME: + /* Very special logic required (no support for DNAME + in GNS yet!), FIXME: support later! */ + fprintf (stdout, + "FIMXE: %s DNAME %s\n", + rec->name, + rec->data.hostname); + break; + case GNUNET_DNSPARSER_TYPE_MX: + if (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_mx (dst, + dst_len, + &off, + rec->data.mx)) + add_record (req, + rec->type, + rec->expiration_time, + dst, + off); + break; + case GNUNET_DNSPARSER_TYPE_SOA: + if (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_soa (dst, + dst_len, + &off, + rec->data.soa)) + add_record (req, + rec->type, + rec->expiration_time, + dst, + off); + break; + case GNUNET_DNSPARSER_TYPE_SRV: + if (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_srv (dst, + dst_len, + &off, + rec->data.srv)) + add_record (req, + rec->type, + rec->expiration_time, + dst, + off); + break; + case GNUNET_DNSPARSER_TYPE_PTR: + if (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_name (dst, + dst_len, + &off, + rec->data.hostname)) + add_record (req, + rec->type, + rec->expiration_time, + dst, + off); + break; + case GNUNET_DNSPARSER_TYPE_CERT: + if (GNUNET_OK == + GNUNET_DNSPARSER_builder_add_cert (dst, + dst_len, + &off, + rec->data.cert)) + add_record (req, + rec->type, + rec->expiration_time, + dst, + off); + break; + /* Rest is 'raw' encoded and just needs to be copied IF + the hostname matches the requested name; otherwise we + simply cannot use it. */ + case GNUNET_DNSPARSER_TYPE_A: + case GNUNET_DNSPARSER_TYPE_AAAA: + case GNUNET_DNSPARSER_TYPE_TXT: + default: + add_record (req, + rec->type, + rec->expiration_time, + rec->data.raw.data, + rec->data.raw.data_len); + break; + } +} + + +/** + * Function called with the result of a DNS resolution. + * + * @param cls closure with the `struct Request` + * @param rs socket that received the response + * @param dns dns response, never NULL + * @param dns_len number of bytes in @a dns + */ +static void +process_result (void *cls, + struct GNUNET_DNSSTUB_RequestSocket *rs, + const struct GNUNET_TUN_DnsHeader *dns, + size_t dns_len) +{ + struct Request *req = cls; + struct GNUNET_DNSPARSER_Packet *p; + + (void) rs; + if (NULL == dns) + { + /* stub gave up */ + pending--; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Stub gave up on DNS reply for `%s'\n", + req->hostname); + GNUNET_CONTAINER_DLL_remove (req_head, + req_tail, + req); + if (req->issue_num > MAX_RETRIES) + { + failures++; + GNUNET_free (req->hostname); + GNUNET_free (req->raw); + GNUNET_free (req); + return; + } + GNUNET_CONTAINER_DLL_insert_tail (req_head, + req_tail, + req); + req->rs = NULL; + return; + } + if (req->id != dns->id) + return; + pending--; + GNUNET_DNSSTUB_resolve_cancel (req->rs); + req->rs = NULL; + GNUNET_CONTAINER_DLL_remove (req_head, + req_tail, + req); + p = GNUNET_DNSPARSER_parse ((const char *) dns, + dns_len); + if (NULL == p) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to parse DNS reply for `%s'\n", + req->hostname); + if (req->issue_num > MAX_RETRIES) + { + failures++; + GNUNET_free (req->hostname); + GNUNET_free (req->raw); + GNUNET_free (req); + return; + } + GNUNET_CONTAINER_DLL_insert_tail (req_head, + req_tail, + req); + return; + } + req->p = p; + for_all_records (p, + &process_record, + req); + req->p = NULL; + // FIXME: update database! + GNUNET_DNSPARSER_free_packet (p); + GNUNET_free (req->hostname); + GNUNET_free (req->raw); + GNUNET_free (req); +} + + +/** + * Submit a request to DNS unless we need to slow down because + * we are at the rate limit. + * + * @param req request to submit + * @return #GNUNET_OK if request was submitted + * #GNUNET_NO if request was already submitted + * #GNUNET_SYSERR if we are at the rate limit + */ +static int +submit_req (struct Request *req) +{ + static struct timeval last_request; + struct timeval now; + + if (NULL != req->rs) + return GNUNET_NO; /* already submitted */ + gettimeofday (&now, + NULL); + if ( ( ( (now.tv_sec - last_request.tv_sec) == 0) && + ( (now.tv_usec - last_request.tv_usec) < TIME_THRESH) ) || + (pending >= THRESH) ) + return GNUNET_SYSERR; + GNUNET_assert (NULL == req->rs); + req->rs = GNUNET_DNSSTUB_resolve2 (ctx, + req->raw, + req->raw_len, + &process_result, + req); + GNUNET_assert (NULL != req->rs); + req->issue_num++; + last_request = now; + lookups++; + pending++; + req->time = time (NULL); + return GNUNET_OK; +} + + +/** + * Process as many requests as possible from the queue. + * + * @param cls NULL + */ +static void +process_queue(void *cls) +{ + (void) cls; + t = NULL; + for (struct Request *req = req_head; + NULL != req; + req = req->next) + { + if (GNUNET_SYSERR == submit_req (req)) + break; + } + if (NULL != req_head) + t = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS, + &process_queue, + NULL); + else + GNUNET_SCHEDULER_shutdown (); +} + + +/** + * Clean up and terminate the process. + * + * @param cls NULL + */ +static void +do_shutdown (void *cls) +{ + (void) cls; + if (NULL != t) + { + GNUNET_SCHEDULER_cancel (t); + t = NULL; + } + if (NULL != ns) + { + GNUNET_break (NULL == + GNUNET_PLUGIN_unload (db_lib_name, + ns)); + GNUNET_free (db_lib_name); + db_lib_name = NULL; + } + GNUNET_DNSSTUB_stop (ctx); + ctx = NULL; +} + + +/** + * Add @a hostname to the list of requests to be made. + * + * @param hostname name to resolve + */ +static void +queue (const char *hostname) +{ + struct GNUNET_DNSPARSER_Packet p; + struct GNUNET_DNSPARSER_Query q; + struct Request *req; + char *raw; + size_t raw_size; + + if (GNUNET_OK != + GNUNET_DNSPARSER_check_name (hostname)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Refusing invalid hostname `%s'\n", + hostname); + return; + } + q.name = (char *) hostname; + q.type = GNUNET_DNSPARSER_TYPE_NS; + q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET; + + memset (&p, + 0, + sizeof (p)); + p.num_queries = 1; + p.queries = &q; + p.id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, + UINT16_MAX); + + if (GNUNET_OK != + GNUNET_DNSPARSER_pack (&p, + UINT16_MAX, + &raw, + &raw_size)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to pack query for hostname `%s'\n", + hostname); + return; + } + + req = GNUNET_new (struct Request); + req->hostname = strdup (hostname); + req->raw = raw; + req->raw_len = raw_size; + req->id = p.id; + /* FIXME: import data from namestore! */ + + /* FIXME: insert sorted by record expiration time */ + GNUNET_CONTAINER_DLL_insert_tail (req_head, + req_tail, + req); +} + + +/** + * Process requests from the queue, then if the queue is + * not empty, try again. + * + * @param cls NULL + * @param args remaining command-line arguments + * @param cfgfile name of the configuration file used (for saving, can be NULL!) + * @param cfg configuration + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + char hn[256]; + char *database; + + (void) cls; + (void) args; + (void) cfgfile; + ctx = GNUNET_DNSSTUB_start (dns_server); + if (NULL == ctx) + { + fprintf (stderr, + "Failed to initialize GNUnet DNS STUB\n"); + return; + } + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_value_string (cfg, + "namestore", + "database", + &database)) + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "No database backend configured\n"); + + GNUNET_asprintf (&db_lib_name, + "libgnunet_plugin_namestore_%s", + database); + ns = GNUNET_PLUGIN_load (db_lib_name, + (void *) cfg); + GNUNET_free (database); + while (NULL != + fgets (hn, + sizeof (hn), + stdin)) + { + if (strlen(hn) > 0) + hn[strlen(hn)-1] = '\0'; /* eat newline */ + queue (hn); + } + GNUNET_SCHEDULER_add_shutdown (&do_shutdown, + NULL); + t = GNUNET_SCHEDULER_add_now (&process_queue, + NULL); +} + + +/** + * Call with IP address of resolver to query. + * + * @param argc should be 2 + * @param argv[1] should contain IP address + * @return 0 on success + */ +int +main (int argc, + char *const*argv) +{ + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_mandatory + (GNUNET_GETOPT_option_string ('s', + "server", + "IP", + "which DNS server should be used", + &dns_server)), + GNUNET_GETOPT_OPTION_END + }; + + if (GNUNET_OK != + GNUNET_STRINGS_get_utf8_args (argc, argv, + &argc, &argv)) + return 2; + GNUNET_PROGRAM_run (argc, + argv, + "gnunet-zoneimport", + "import DNS zone into namestore", + options, + &run, + NULL); + GNUNET_free ((void*) argv); + fprintf (stderr, + "Did %u lookups, found %u records, %u lookups failed, %u pending on shutdown\n", + lookups, + records, + failures, + pending); + return 0; +} + +/* end of gnunet-zoneimport.c */ diff --git a/src/namestore/namestore_api_monitor.c b/src/namestore/namestore_api_monitor.c index cd7c7dadb..8e6d39ad7 100644 --- a/src/namestore/namestore_api_monitor.c +++ b/src/namestore/namestore_api_monitor.c @@ -114,6 +114,8 @@ handle_sync (void *cls, { struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls; + (void) cls; + (void) msg; if (NULL != zm->sync_cb) zm->sync_cb (zm->sync_cb_cls); } @@ -138,6 +140,7 @@ check_result (void *cls, const char *name_tmp; const char *rd_ser_tmp; + (void) cls; lrm_len = ntohs (lrm->gns_header.header.size); rd_len = ntohs (lrm->rd_len); rd_count = ntohs (lrm->rd_count); @@ -231,6 +234,7 @@ mq_error_handler (void *cls, { struct GNUNET_NAMESTORE_ZoneMonitor *zm = cls; + (void) error; reconnect (zm); } diff --git a/src/namestore/plugin_namestore_flat.c b/src/namestore/plugin_namestore_flat.c index 923d2696f..024fc34f2 100644 --- a/src/namestore/plugin_namestore_flat.c +++ b/src/namestore/plugin_namestore_flat.c @@ -1,6 +1,6 @@ /* * This file is part of GNUnet - * Copyright (C) 2009-2015 GNUnet e.V. + * Copyright (C) 2009-2015, 2018 GNUnet e.V. * * GNUnet is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published @@ -22,6 +22,7 @@ * @file namestore/plugin_namestore_flat.c * @brief file-based namestore backend * @author Martin Schanzenbach + * @author Christian Grothoff */ #include "platform.h" @@ -76,7 +77,7 @@ struct Plugin /** * PKEY to look for in zone to name */ - struct GNUNET_CRYPTO_EcdsaPublicKey *iter_pkey; + const struct GNUNET_CRYPTO_EcdsaPublicKey *iter_pkey; /** * Iteration result found @@ -147,15 +148,19 @@ database_setup (struct Plugin *plugin) if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "namestore-flat", - "FILENAME", &afsdir)) + "FILENAME", + &afsdir)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, - "namestore-flat", "FILENAME"); + "namestore-flat", + "FILENAME"); return GNUNET_SYSERR; } - if (GNUNET_OK != GNUNET_DISK_file_test (afsdir)) + if (GNUNET_OK != + GNUNET_DISK_file_test (afsdir)) { - if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir)) + if (GNUNET_OK != + GNUNET_DISK_directory_create_for_file (afsdir)) { GNUNET_break (0); GNUNET_free (afsdir); @@ -229,15 +234,19 @@ database_setup (struct Plugin *plugin) if (NULL == label) break; line = strtok (NULL, "\n"); - entry = GNUNET_malloc (sizeof (struct FlatFileEntry)); - if (1 != sscanf (rvalue, "%lu", &entry->rvalue)) + entry = GNUNET_new (struct FlatFileEntry); + if (1 != sscanf (rvalue, + "%lu", + &entry->rvalue)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing entry\n"); GNUNET_free (entry); break; } - if (1 != sscanf (record_count, "%u", &entry->record_count)) + if (1 != sscanf (record_count, + "%u", + &entry->record_count)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing entry\n"); @@ -245,18 +254,22 @@ database_setup (struct Plugin *plugin) break; } entry->label = GNUNET_strdup (label); - record_data_size = GNUNET_STRINGS_base64_decode (record_data_b64, - strlen (record_data_b64), - &record_data); + record_data_size + = GNUNET_STRINGS_base64_decode (record_data_b64, + strlen (record_data_b64), + &record_data); entry->record_data = - GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Data) * entry->record_count); - if (GNUNET_OK != GNUNET_GNSRECORD_records_deserialize (record_data_size, - record_data, - entry->record_count, - entry->record_data)) + GNUNET_new_array (entry->record_count, + struct GNUNET_GNSRECORD_Data); + if (GNUNET_OK != + GNUNET_GNSRECORD_records_deserialize (record_data_size, + record_data, + entry->record_count, + entry->record_data)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Unable to deserialize record %s\n", label); + "Unable to deserialize record %s\n", + label); GNUNET_free (entry->label); GNUNET_free (entry); GNUNET_free (record_data); @@ -268,10 +281,12 @@ database_setup (struct Plugin *plugin) (char**)&entry->private_key); key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); key = GNUNET_malloc (strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); - GNUNET_memcpy (key, label, strlen (label)); + GNUNET_memcpy (key, + label, + strlen (label)); GNUNET_memcpy (key+strlen(label), - entry->private_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + entry->private_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); GNUNET_CRYPTO_hash (key, key_len, &hkey); @@ -296,6 +311,8 @@ database_setup (struct Plugin *plugin) * Store values in hashmap in file and free data * * @param plugin the plugin context + * @param key key in the map + * @param value a `struct FlatFileEntry` */ static int store_and_free_entries (void *cls, @@ -309,6 +326,7 @@ store_and_free_entries (void *cls, char *record_data_b64; size_t data_size; + (void) key; GNUNET_STRINGS_base64_encode ((char*)entry->private_key, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey), &zone_private_key); @@ -316,12 +334,14 @@ store_and_free_entries (void *cls, entry->record_data); { char data[data_size]; - - if (data_size != - GNUNET_GNSRECORD_records_serialize (entry->record_count, - entry->record_data, - data_size, - data)) + ssize_t ret; + + ret = GNUNET_GNSRECORD_records_serialize (entry->record_count, + entry->record_data, + data_size, + data); + if ( (ret < 0) || + (data_size != (size_t) ret) ) { GNUNET_break (0); GNUNET_free (zone_private_key); @@ -363,6 +383,7 @@ static void database_shutdown (struct Plugin *plugin) { struct GNUNET_DISK_FileHandle *fh; + fh = GNUNET_DISK_file_open (plugin->fn, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_TRUNCATE | @@ -409,9 +430,9 @@ namestore_store_records (void *cls, char *key; struct GNUNET_HashCode hkey; struct FlatFileEntry *entry; - int i; - rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); + rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, + UINT64_MAX); key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); key = GNUNET_malloc (key_len); GNUNET_memcpy (key, label, strlen (label)); @@ -426,18 +447,19 @@ namestore_store_records (void *cls, if (0 < rd_count) { - entry = GNUNET_malloc (sizeof (struct FlatFileEntry)); - entry->private_key = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + entry = GNUNET_new (struct FlatFileEntry); + entry->private_key = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey); GNUNET_asprintf (&entry->label, label, strlen (label)); GNUNET_memcpy (entry->private_key, - zone_key, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + zone_key, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); entry->rvalue = rvalue; entry->record_count = rd_count; - entry->record_data = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Data) * rd_count); - for (i = 0; i < rd_count; i++) + entry->record_data = GNUNET_new_array (rd_count, + struct GNUNET_GNSRECORD_Data); + for (unsigned int i = 0; i < rd_count; i++) { entry->record_data[i].expiration_time = rd[i].expiration_time; entry->record_data[i].record_type = rd[i].record_type; @@ -484,21 +506,28 @@ namestore_lookup_records (void *cls, } key_len = strlen (label) + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey); key = GNUNET_malloc (key_len); - GNUNET_memcpy (key, label, strlen (label)); + GNUNET_memcpy (key, + label, + strlen (label)); GNUNET_memcpy (key+strlen(label), - zone, - sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); + zone, + sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)); GNUNET_CRYPTO_hash (key, key_len, &hkey); GNUNET_free (key); - entry = GNUNET_CONTAINER_multihashmap_get (plugin->hm, &hkey); + entry = GNUNET_CONTAINER_multihashmap_get (plugin->hm, + &hkey); if (NULL == entry) return GNUNET_NO; if (NULL != iter) - iter (iter_cls, entry->private_key, entry->label, entry->record_count, entry->record_data); + iter (iter_cls, + entry->private_key, + entry->label, + entry->record_count, + entry->record_data); return GNUNET_YES; } @@ -511,6 +540,7 @@ iterate_zones (void *cls, struct Plugin *plugin = cls; struct FlatFileEntry *entry = value; + (void) key; if ((plugin->target_offset > plugin->offset) || ( (NULL != plugin->iter_zone) && (0 != memcmp (entry->private_key, @@ -528,6 +558,7 @@ iterate_zones (void *cls, return GNUNET_NO; } + /** * Iterate over the results for a particular key and zone in the * datastore. Will return at most one result to the iterator. @@ -543,9 +574,13 @@ static int namestore_iterate_records (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, uint64_t offset, - GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls) { struct Plugin *plugin = cls; + + /* FIXME: maybe use separate closure to better handle + recursive calls? */ plugin->target_offset = offset; plugin->offset = 0; plugin->iter = iter; @@ -558,6 +593,7 @@ namestore_iterate_records (void *cls, return plugin->iter_result_found; } + static int zone_to_name (void *cls, const struct GNUNET_HashCode *key, @@ -565,14 +601,15 @@ zone_to_name (void *cls, { struct Plugin *plugin = cls; struct FlatFileEntry *entry = value; - int i; + (void) key; if (0 != memcmp (entry->private_key, plugin->iter_zone, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))) return GNUNET_YES; - for (i = 0; i < entry->record_count; i++) { + for (unsigned int i = 0; i < entry->record_count; i++) + { if (GNUNET_GNSRECORD_TYPE_PKEY != entry->record_data[i].record_type) continue; if (0 == memcmp (plugin->iter_pkey, @@ -588,10 +625,10 @@ zone_to_name (void *cls, } } - return GNUNET_YES; } + /** * Look for an existing PKEY delegation record for a given public key. * Returns at most one result to the iterator. @@ -607,19 +644,24 @@ static int namestore_zone_to_name (void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone, const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone, - GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls) + GNUNET_NAMESTORE_RecordIterator iter, + void *iter_cls) { struct Plugin *plugin = cls; + /* FIXME: maybe use separate closure to better handle + recursive calls? */ + plugin->iter = iter; + plugin->iter_cls = iter_cls; + plugin->iter_zone = zone; + plugin->iter_pkey = value_zone; + plugin->iter_result_found = GNUNET_NO; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Performing reverse lookup for `%s'\n", GNUNET_GNSRECORD_z2s (value_zone)); - GNUNET_CONTAINER_multihashmap_iterate (plugin->hm, &zone_to_name, plugin); - - return plugin->iter_result_found; } @@ -639,7 +681,9 @@ libgnunet_plugin_namestore_flat_init (void *cls) if (NULL != plugin.cfg) return NULL; /* can only initialize once! */ - memset (&plugin, 0, sizeof (struct Plugin)); + memset (&plugin, + 0, + sizeof (struct Plugin)); plugin.cfg = cfg; if (GNUNET_OK != database_setup (&plugin)) { diff --git a/src/namestore/plugin_namestore_postgres.c b/src/namestore/plugin_namestore_postgres.c index 491cec1cb..de8d76853 100644 --- a/src/namestore/plugin_namestore_postgres.c +++ b/src/namestore/plugin_namestore_postgres.c @@ -217,10 +217,14 @@ namestore_postgres_store_records (void *cls, GNUNET_PQ_query_param_end }; enum GNUNET_DB_QueryStatus res; - - if (data_size != - GNUNET_GNSRECORD_records_serialize (rd_count, rd, - data_size, data)) + ssize_t ret; + + ret = GNUNET_GNSRECORD_records_serialize (rd_count, + rd, + data_size, + data); + if ( (ret < 0) || + (data_size != (size_t) ret) ) { GNUNET_break (0); return GNUNET_SYSERR; @@ -469,7 +473,6 @@ namestore_postgres_zone_to_name (void *cls, pc.iter = iter; pc.iter_cls = iter_cls; pc.zone_key = zone; - res = GNUNET_PQ_eval_prepared_multi_select (plugin->dbh, "zone_to_name", params, diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index 168c52c11..5ad84688c 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c @@ -435,12 +435,14 @@ namestore_sqlite_store_records (void *cls, GNUNET_SQ_query_param_string (label), GNUNET_SQ_query_param_end }; - - if (data_size != - GNUNET_GNSRECORD_records_serialize (rd_count, - rd, - data_size, - data)) + ssize_t ret; + + ret = GNUNET_GNSRECORD_records_serialize (rd_count, + rd, + data_size, + data); + if ( (ret < 0) || + (data_size != (size_t) ret) ) { GNUNET_break (0); return GNUNET_SYSERR; diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c index 954af98d2..4602106da 100644 --- a/src/namestore/plugin_rest_namestore.c +++ b/src/namestore/plugin_rest_namestore.c @@ -248,7 +248,6 @@ cleanup_handle (struct RequestHandle *handle) { struct RecordEntry *record_entry; struct RecordEntry *record_tmp; - int i; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); @@ -276,7 +275,7 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_free (handle->value); if (NULL != handle->rd) { - for (i = 0; i < handle->rd_count; i++) + for (unsigned int i = 0; i < handle->rd_count; i++) { if (NULL != handle->rd[i].data) GNUNET_free ((void*)handle->rd[i].data); @@ -441,22 +440,24 @@ namestore_list_response (void *cls, struct GNUNET_JSONAPI_Resource *json_resource; json_t *result_array; json_t *record_obj; - int i; if (NULL == handle->resp_object) handle->resp_object = GNUNET_JSONAPI_document_new (); if ( (NULL != handle->name) && - (0 != strcmp (handle->name, rname)) ) + (0 != strcmp (handle->name, + rname)) ) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "%s does not match %s\n", rname, handle->name); + "%s does not match %s\n", + rname, + handle->name); GNUNET_NAMESTORE_zone_iterator_next (handle->list_it); return; } result_array = json_array (); - for (i=0; itype) && (GNUNET_GNSRECORD_TYPE_ANY != handle->type) ) continue; - record_obj = gnsrecord_to_json (&(rd[i])); - json_array_append (result_array, record_obj); + record_obj = gnsrecord_to_json (&rd[i]); + json_array_append (result_array, + record_obj); json_decref (record_obj); } @@ -650,21 +652,24 @@ json_to_gnsrecord (const json_t *records_json, size_t rdata_size; const char *typestring; const char *expirationstring; - int i; json_t *type_json; json_t *value_json; json_t *record_json; json_t *exp_json; *rd_count = json_array_size (records_json); - *rd = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Data) * *rd_count); - for (i = 0; i < *rd_count; i++) + *rd = GNUNET_new_array (*rd_count, + struct GNUNET_GNSRECORD_Data); + for (unsigned int i = 0; i < *rd_count; i++) { - memset (&((*rd)[i]), 0, sizeof (struct GNUNET_GNSRECORD_Data)); - record_json = json_array_get (records_json, i); + memset (&(*rd)[i], + 0, + sizeof (struct GNUNET_GNSRECORD_Data)); + record_json = json_array_get (records_json, + i); type_json = json_object_get (record_json, GNUNET_REST_JSONAPI_NAMESTORE_RECORD_TYPE); - if (!json_is_string (type_json)) + if (! json_is_string (type_json)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Type property is no string\n"); @@ -680,20 +685,23 @@ json_to_gnsrecord (const json_t *records_json, } value_json = json_object_get (record_json, GNUNET_REST_JSONAPI_NAMESTORE_VALUE); - if (!json_is_string (value_json)) + if (! json_is_string (value_json)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value property is no string\n"); return GNUNET_SYSERR; } value = GNUNET_strdup (json_string_value (value_json)); - if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value ((*rd)[i].record_type, - value, - &rdata, - &rdata_size)) + if (GNUNET_OK != + GNUNET_GNSRECORD_string_to_value ((*rd)[i].record_type, + value, + &rdata, + &rdata_size)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Value `%s' invalid for record type `%s'\n"), - value, typestring); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Value `%s' invalid for record type `%s'\n"), + value, + typestring); return GNUNET_SYSERR; } (*rd)[i].data = rdata; @@ -706,7 +714,7 @@ json_to_gnsrecord (const json_t *records_json, */ exp_json = json_object_get (record_json, GNUNET_REST_JSONAPI_NAMESTORE_EXPIRATION); - if (!json_is_string (exp_json)) + if (! json_is_string (exp_json)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Expiration property is no string\n"); @@ -732,8 +740,10 @@ json_to_gnsrecord (const json_t *records_json, } else { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Value `%s' invalid for record type `%s'\n"), - value, typestring); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Value `%s' invalid for record type `%s'\n"), + value, + typestring); return GNUNET_SYSERR; } } diff --git a/src/util/program.c b/src/util/program.c index 9e3037b8b..a02bff77c 100644 --- a/src/util/program.c +++ b/src/util/program.c @@ -138,10 +138,13 @@ cmd_sorter (const void *a1, const void *a2) * @return #GNUNET_SYSERR on error, #GNUNET_OK on success */ int -GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, +GNUNET_PROGRAM_run2 (int argc, + char *const *argv, + const char *binaryName, const char *binaryHelp, const struct GNUNET_GETOPT_CommandLineOption *options, - GNUNET_PROGRAM_Main task, void *task_cls, + GNUNET_PROGRAM_Main task, + void *task_cls, int run_without_scheduler) { struct CommandContext cc; @@ -158,7 +161,6 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, unsigned long long skew_variance; long long clock_offset; struct GNUNET_CONFIGURATION_Handle *cfg; - struct GNUNET_GETOPT_CommandLineOption defoptions[] = { GNUNET_GETOPT_option_cfgfile (&cc.cfgfile), GNUNET_GETOPT_option_help (binaryHelp), @@ -177,23 +179,31 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, { char **gargv; unsigned int gargc; - int i; - char *tok; char *cargs; gargv = NULL; gargc = 0; - for (i = 0; i < argc; i++) - GNUNET_array_append (gargv, gargc, GNUNET_strdup (argv[i])); + for (int i = 0; i < argc; i++) + GNUNET_array_append (gargv, + gargc, + GNUNET_strdup (argv[i])); cargs = GNUNET_strdup (gargs); - for (tok = strtok (cargs, " "); NULL != tok; tok = strtok (NULL, " ")) - GNUNET_array_append (gargv, gargc, GNUNET_strdup (tok)); + for (char *tok = strtok (cargs, " "); + NULL != tok; + tok = strtok (NULL, " ")) + GNUNET_array_append (gargv, + gargc, + GNUNET_strdup (tok)); GNUNET_free (cargs); - GNUNET_array_append (gargv, gargc, NULL); + GNUNET_array_append (gargv, + gargc, + NULL); argv = (char *const *) gargv; argc = gargc - 1; } - memset (&cc, 0, sizeof (cc)); + memset (&cc, + 0, + sizeof (cc)); loglev = NULL; cc.task = task; cc.task_cls = task_cls; @@ -204,7 +214,8 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, path = GNUNET_OS_installation_get_path (GNUNET_OS_IPK_LOCALEDIR); if (NULL != path) { - BINDTEXTDOMAIN ("GNUnet", path); + BINDTEXTDOMAIN ("GNUnet", + path); GNUNET_free (path); } textdomain ("GNUnet"); @@ -216,13 +227,17 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, GNUNET_malloc ((cnt + 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption) + sizeof (defoptions)); - GNUNET_memcpy (allopts, defoptions, sizeof (defoptions)); + GNUNET_memcpy (allopts, + defoptions, + sizeof (defoptions)); GNUNET_memcpy (&allopts - [sizeof (defoptions) / - sizeof (struct GNUNET_GETOPT_CommandLineOption)], options, - (cnt + 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption)); + [sizeof (defoptions) / + sizeof (struct GNUNET_GETOPT_CommandLineOption)], options, + (cnt + 1) * sizeof (struct GNUNET_GETOPT_CommandLineOption)); cnt += sizeof (defoptions) / sizeof (struct GNUNET_GETOPT_CommandLineOption); - qsort (allopts, cnt, sizeof (struct GNUNET_GETOPT_CommandLineOption), + qsort (allopts, + cnt, + sizeof (struct GNUNET_GETOPT_CommandLineOption), &cmd_sorter); loglev = NULL; xdg = getenv ("XDG_CONFIG_HOME"); @@ -237,9 +252,15 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, lpfx = GNUNET_strdup (binaryName); if (NULL != (spc = strstr (lpfx, " "))) *spc = '\0'; - ret = GNUNET_GETOPT_run (binaryName, allopts, (unsigned int) argc, argv); + ret = GNUNET_GETOPT_run (binaryName, + allopts, + (unsigned int) argc, + argv); if ((GNUNET_OK > ret) || - (GNUNET_OK != GNUNET_log_setup (lpfx, loglev, logfile))) + (GNUNET_OK != + GNUNET_log_setup (lpfx, + loglev, + logfile))) { GNUNET_free (allopts); GNUNET_free (lpfx); @@ -250,7 +271,9 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, if (GNUNET_YES == GNUNET_DISK_file_test (cc.cfgfile)) { - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, cc.cfgfile)) + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_load (cfg, + cc.cfgfile)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Malformed configuration file `%s', exit ...\n"), @@ -263,11 +286,14 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, } else { - if (0 != strcmp (cc.cfgfile, cfg_fn)) + if (0 != strcmp (cc.cfgfile, + cfg_fn)) GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not access configuration file `%s'\n"), cc.cfgfile); - if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL)) + if (GNUNET_SYSERR == + GNUNET_CONFIGURATION_load (cfg, + NULL)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Malformed configuration, exit ...\n")); @@ -280,11 +306,15 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, GNUNET_free (allopts); GNUNET_free (lpfx); if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (cc.cfg, "testing", "skew_offset", + GNUNET_CONFIGURATION_get_value_number (cc.cfg, + "testing", + "skew_offset", &skew_offset) && (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (cc.cfg, "testing", - "skew_variance", &skew_variance))) + GNUNET_CONFIGURATION_get_value_number (cc.cfg, + "testing", + "skew_variance", + &skew_variance))) { clock_offset = skew_offset - skew_variance; GNUNET_TIME_set_offset (clock_offset); @@ -301,7 +331,8 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, "CONFIG")) { GNUNET_CONFIGURATION_set_value_string (cfg, - "arm", "CONFIG", + "arm", + "CONFIG", cc.cfgfile); } @@ -314,7 +345,10 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, else { GNUNET_RESOLVER_connect (cc.cfg); - cc.task (cc.task_cls, cc.args, cc.cfgfile, cc.cfg); + cc.task (cc.task_cls, + cc.args, + cc.cfgfile, + cc.cfg); } ret = GNUNET_OK; cleanup: @@ -326,6 +360,7 @@ GNUNET_PROGRAM_run2 (int argc, char *const *argv, const char *binaryName, return ret; } + /** * Run a standard GNUnet command startup sequence (initialize loggers * and configuration, parse options). -- 2.25.1