X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fgns%2Fgnunet-service-gns.c;h=c376ddfcc390478ec44771d7fa67e33c0cca23a0;hb=620bdac536dff4b17317d9d20b8a6840836d6490;hp=5ad0bcf76820c8bc173069a3723ea0a4396db453;hpb=55798b50feda4db5255e991e66ef5c78fadf008a;p=oweals%2Fgnunet.git diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 5ad0bcf76..c376ddfcc 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors) + Copyright (C) 2011-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 @@ -14,126 +14,125 @@ 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. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ - /** - * * @file gns/gnunet-service-gns.c - * @brief GNUnet GNS service + * @brief GNU Name System (main service) * @author Martin Schanzenbach + * @author Christian Grothoff */ #include "platform.h" #include "gnunet_util_lib.h" -#include "gnunet_transport_service.h" #include "gnunet_dns_service.h" #include "gnunet_dnsparser_lib.h" #include "gnunet_dht_service.h" -#include "gnunet_namestore_service.h" +#include "gnunet_namecache_service.h" +#include "gnunet_gnsrecord_lib.h" #include "gnunet_gns_service.h" #include "gnunet_statistics_service.h" -#include "block_gns.h" #include "gns.h" -#include "gns_common.h" #include "gnunet-service-gns_resolver.h" #include "gnunet-service-gns_interceptor.h" #include "gnunet_protocols.h" -#define INITIAL_ZONE_ITERATION_INTERVAL GNUNET_TIME_UNIT_MILLISECONDS -#define MINIMUM_ZONE_ITERATION_INTERVAL GNUNET_TIME_UNIT_SECONDS -#define DEFAULT_RECORD_PUT_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) -#define LATE_ITERATION_SPEEDUP_FACTOR 2 +/** + * GnsClient prototype + */ +struct GnsClient; /** - * Handle to a shorten operation from api + * Handle to a lookup operation from client via API. */ -struct ClientShortenHandle +struct ClientLookupHandle { - /* DLL */ - struct ClientShortenHandle *next; - - /* DLL */ - struct ClientShortenHandle *prev; - - /* the requesting client that */ - struct GNUNET_SERVER_Client *client; - - /* request id */ - uint64_t unique_id; - - /* request type */ - enum GNUNET_GNS_RecordType type; + /** + * We keep these in a DLL. + */ + struct ClientLookupHandle *next; - /* name to shorten */ - char name[MAX_DNS_NAME_LENGTH]; + /** + * We keep these in a DLL. + */ + struct ClientLookupHandle *prev; - /* name of private zone (relative to root) */ - char private_zone_id[MAX_DNS_NAME_LENGTH]; - - /* name of shorten zone (relative to root) */ - char shorten_zone_id[MAX_DNS_NAME_LENGTH]; - - /* root zone */ - struct GNUNET_CRYPTO_ShortHashCode root_zone; + /** + * Client handle + */ + struct GnsClient *gc; - /* private zone */ - struct GNUNET_CRYPTO_ShortHashCode private_zone; - - /* shorten zone */ - struct GNUNET_CRYPTO_ShortHashCode shorten_zone; + /** + * Active handle for the lookup. + */ + struct GNS_ResolverHandle *lookup; - /* Namestore lookup task */ - struct GNUNET_NAMESTORE_QueueEntry *namestore_task; + /** + * request id + */ + uint32_t request_id; }; /** - * Handle to a get auhtority operation from api + * Information we track per connected client. */ -struct ClientGetAuthHandle +struct GnsClient { - /* the requesting client that */ - struct GNUNET_SERVER_Client *client; + /** + * The client + */ + struct GNUNET_SERVICE_Client *client; - /* request id */ - uint64_t unique_id; + /** + * The MQ + */ + struct GNUNET_MQ_Handle *mq; - /* name to lookup authority */ - char *name; + /** + * Head of the DLL. + */ + struct ClientLookupHandle *clh_head; + /** + * Tail of the DLL. + */ + struct ClientLookupHandle *clh_tail; }; /** - * Handle to a lookup operation from api + * Representation of a TLD, mapping the respective TLD string + * (i.e. ".gnu") to the respective public key of the zone. */ -struct ClientLookupHandle +struct GNS_TopLevelDomain { - /* the requesting client that */ - struct GNUNET_SERVER_Client *client; - - /* The zone we look up in */ - struct GNUNET_CRYPTO_ShortHashCode zone; - - /* Do we only want to lookup from local cache? */ - int only_cached; + /** + * Kept in a DLL, as there are unlikely enough of these to + * warrant a hash map. + */ + struct GNS_TopLevelDomain *next; - /* request id */ - uint64_t unique_id; + /** + * Kept in a DLL, as there are unlikely enough of these to + * warrant a hash map. + */ + struct GNS_TopLevelDomain *prev; - /* request type */ - enum GNUNET_GNS_RecordType type; + /** + * Public key associated with the @a tld. + */ + struct GNUNET_CRYPTO_EcdsaPublicKey pkey; - /* optional zone private key used for shorten */ - struct GNUNET_CRYPTO_RsaPrivateKey *shorten_key; + /** + * Top-level domain as a string, including leading ".". + */ + char *tld; - /* the name to look up */ - char *name; }; @@ -143,1195 +142,458 @@ struct ClientLookupHandle static struct GNUNET_DHT_Handle *dht_handle; /** - * Our zone's private key - */ -static struct GNUNET_CRYPTO_RsaPrivateKey *zone_key; - -/** - * Our handle to the namestore service - * FIXME maybe need a second handle for iteration - */ -static struct GNUNET_NAMESTORE_Handle *namestore_handle; - -/** - * Handle to iterate over our authoritative zone in namestore + * Our handle to the namecache service */ -static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; +static struct GNUNET_NAMECACHE_Handle *namecache_handle; /** - * Our notification context. + * #GNUNET_YES if ipv6 is supported */ -static struct GNUNET_SERVER_NotificationContext *nc; +static int v6_enabled; /** - * Our zone hash + * #GNUNET_YES if ipv4 is supported */ -static struct GNUNET_CRYPTO_ShortHashCode zone_hash; +static int v4_enabled; /** - * Useful for zone update for DHT put + * Handle to the statistics service */ -static unsigned long long num_public_records; +static struct GNUNET_STATISTICS_Handle *statistics; /** - * Last seen record count + * Head of DLL of TLDs we map to GNS zones. */ -static unsigned long long last_num_public_records; +static struct GNS_TopLevelDomain *tld_head; /** - * FIXME! + * Tail of DLL of TLDs we map to GNS zones. */ -static struct GNUNET_TIME_Relative zone_iteration_interval; - -/* dht update interval FIXME define? */ -static struct GNUNET_TIME_Relative record_put_interval; - -/* zone update task */ -static GNUNET_SCHEDULER_TaskIdentifier zone_update_taskid; - -/* automatic pkey import for name shortening */ -static int auto_import_pkey; - -/* first zone iteration is specia */ -static int first_zone_iteration; - -/* lookup timeout */ -static struct GNUNET_TIME_Relative default_lookup_timeout; - -/* ipv6 support */ -static int v6_enabled; - -/* ipv4 support */ -static int v4_enabled; - -/* Shorten DLL for cancelling NS requests */ -static struct ClientShortenHandle *csh_head; - -/* Shorten DLL for cancelling NS requests */ -static struct ClientShortenHandle *csh_tail; - -/* Statistics handle */ -static struct GNUNET_STATISTICS_Handle *statistics; +static struct GNS_TopLevelDomain *tld_tail; /** - * Task run during shutdown. + * Find GNS zone belonging to TLD @a tld. * - * @param cls unused - * @param tc unused + * @param tld_str top-level domain to look up + * @param[out] pkey public key to set + * @return #GNUNET_YES if @a tld was found #GNUNET_NO if not */ -static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +int +GNS_find_tld (const char *tld_str, + struct GNUNET_CRYPTO_EcdsaPublicKey *pkey) { - struct ClientShortenHandle *csh_tmp; - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Shutting down!"); - while (NULL != (csh_tmp = csh_head)) - { - GNUNET_CONTAINER_DLL_remove (csh_head, csh_tail, csh_tmp); - GNUNET_free(csh_tmp); + if ('\0' == *tld_str) + return GNUNET_NO; + for (struct GNS_TopLevelDomain *tld = tld_head; + NULL != tld; + tld = tld->next) + { + if (0 == strcasecmp (tld_str, + tld->tld)) + { + *pkey = tld->pkey; + return GNUNET_YES; + } } - GNUNET_SERVER_notification_context_destroy (nc); - gns_interceptor_stop (); - gns_resolver_cleanup (); - if (NULL != statistics) - GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); - if (zone_update_taskid != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (zone_update_taskid); - if (NULL != namestore_iter) - GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter); - GNUNET_NAMESTORE_disconnect(namestore_handle); - GNUNET_DHT_disconnect(dht_handle); + if (GNUNET_OK == + GNUNET_GNSRECORD_zkey_to_pkey (tld_str + 1, + pkey)) + return GNUNET_YES; /* TLD string *was* the public key */ + return GNUNET_NO; } /** - * Method called periodically that triggers iteration over authoritative records + * Obtain the TLD of the given @a name. * - * @param cls closure - * @param tc task context + * @param name a name + * @return the part of @a name after the last ".", + * or @a name if @a name does not contain a "." */ -static void -update_zone_dht_next (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +const char * +GNS_get_tld (const char *name) { - zone_update_taskid = GNUNET_SCHEDULER_NO_TASK; - GNUNET_NAMESTORE_zone_iterator_next (namestore_iter); -} - + const char *tld; -/** - * Continuation for DHT put - * - * @param cls closure - * @param success GNUNET_OK if the PUT was transmitted, - * GNUNET_NO on timeout, - * GNUNET_SYSERR on disconnect from service - * after the PUT message was transmitted - * (so we don't know if it was received or not) - */ -static void -record_dht_put(void *cls, int success) -{ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "put request transmitted\n"); + tld = strrchr (name, + (unsigned char) '.'); + if (NULL == tld) + tld = name; + else + tld++; /* skip the '.' */ + return tld; } -/* prototype */ -static void -update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); - - /** - * Function used to put all records successively into the DHT. + * Task run during shutdown. * - * @param cls the closure (NULL) - * @param key the public key of the authority (ours) - * @param expiration lifetime of the namestore entry - * @param name the name of the records - * @param rd_count the number of records in data - * @param rd the record data - * @param signature the signature for the record data + * @param cls unused, NULL */ static void -put_gns_record(void *cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) -{ - struct GNSNameRecordBlock *nrb; - struct GNUNET_CRYPTO_ShortHashCode zhash; - struct GNUNET_HashCode dht_key; - uint32_t rd_payload_length; - char* nrb_data = NULL; - size_t namelen; - struct GNUNET_TIME_Relative next_put_interval; - - if (NULL == name) - { - /* we're done */ - namestore_iter = NULL; - last_num_public_records = num_public_records; - first_zone_iteration = GNUNET_NO; - if (0 == num_public_records) - { - /** - * If no records are known (startup) or none present - * we can safely set the interval to the value for a single - * record - */ - zone_iteration_interval = GNUNET_TIME_relative_divide (record_put_interval, - 1); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, - "No records in db.\n"); - } - else - { - zone_iteration_interval = GNUNET_TIME_relative_divide (record_put_interval, - num_public_records); - } - zone_iteration_interval = GNUNET_TIME_relative_max (MINIMUM_ZONE_ITERATION_INTERVAL, - zone_iteration_interval); +shutdown_task (void *cls) +{ + struct GNS_TopLevelDomain *tld; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Zone iteration finished. Adjusted zone iteration interval to %s\n", - GNUNET_STRINGS_relative_time_to_string (zone_iteration_interval, GNUNET_YES)); - GNUNET_STATISTICS_set (statistics, - "Current zone iteration interval (in ms)", - zone_iteration_interval.rel_value, - GNUNET_NO); - GNUNET_STATISTICS_update (statistics, - "Number of zone iterations", 1, GNUNET_NO); - GNUNET_STATISTICS_set (statistics, - "Number of public records in DHT", - last_num_public_records, - GNUNET_NO); - if (0 == num_public_records) - zone_update_taskid = GNUNET_SCHEDULER_add_delayed (zone_iteration_interval, - &update_zone_dht_start, - NULL); - else - zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_start, NULL); - return; - } - - namelen = strlen (name) + 1; - if (0 == rd_count) + (void) cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Shutting down!\n"); + GNS_interceptor_done (); + GNS_resolver_done (); + if (NULL != statistics) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No records for name `%s'! Skipping.\n", - name); - zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_next, - NULL); - return; + GNUNET_STATISTICS_destroy (statistics, + GNUNET_NO); + statistics = NULL; } - if (NULL == signature) + if (NULL != namecache_handle) { - GNUNET_break (0); - zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_next, - NULL); - return; + GNUNET_NAMECACHE_disconnect (namecache_handle); + namecache_handle = NULL; } - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Putting records for `%s' into the DHT\n", name); - rd_payload_length = GNUNET_NAMESTORE_records_get_size (rd_count, rd); - nrb = GNUNET_malloc (rd_payload_length + namelen - + sizeof (struct GNSNameRecordBlock)); - nrb->signature = *signature; - nrb->public_key = *key; - nrb->rd_count = htonl (rd_count); - memcpy (&nrb[1], name, namelen); - nrb_data = (char *) &nrb[1]; - nrb_data += namelen; - rd_payload_length += sizeof(struct GNSNameRecordBlock) + namelen; - GNUNET_CRYPTO_short_hash (key, - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &zhash); - if (-1 == GNUNET_NAMESTORE_records_serialize (rd_count, - rd, - rd_payload_length, - nrb_data)) + if (NULL != dht_handle) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Records for name `%s' in zone %s too large to fit into DHT"), - name, - GNUNET_short_h2s (&zhash)); - GNUNET_free(nrb); - zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_next, - NULL); - return; + GNUNET_DHT_disconnect (dht_handle); + dht_handle = NULL; } - - GNUNET_GNS_get_key_for_record (name, &zhash, &dht_key); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "putting %u records from zone %s for `%s' under key: %s with size %u and timeout %s\n", - rd_count, - GNUNET_short_h2s (&zhash), - name, - GNUNET_h2s (&dht_key), - (unsigned int) rd_payload_length, - GNUNET_STRINGS_relative_time_to_string (DHT_OPERATION_TIMEOUT, GNUNET_YES)); - - GNUNET_STATISTICS_update (statistics, - "Record bytes put into DHT", rd_payload_length, GNUNET_NO); - - (void) GNUNET_DHT_put (dht_handle, &dht_key, - DHT_GNS_REPLICATION_LEVEL, - GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - GNUNET_BLOCK_TYPE_GNS_NAMERECORD, - rd_payload_length, - (char*)nrb, - expiration, - DHT_OPERATION_TIMEOUT, - &record_dht_put, - NULL); - GNUNET_free (nrb); - - num_public_records++; - if ( (num_public_records > last_num_public_records) - && (GNUNET_NO == first_zone_iteration) ) + while (NULL != (tld = tld_head)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Last record count was lower than current record count. Reducing interval.\n"); - zone_iteration_interval = GNUNET_TIME_relative_divide (record_put_interval, - num_public_records); - next_put_interval = GNUNET_TIME_relative_divide (zone_iteration_interval, - LATE_ITERATION_SPEEDUP_FACTOR); + GNUNET_CONTAINER_DLL_remove (tld_head, + tld_tail, + tld); + GNUNET_free (tld->tld); + GNUNET_free (tld); } - else - next_put_interval = zone_iteration_interval; - - GNUNET_STATISTICS_set (statistics, - "Current zone iteration interval (ms)", - next_put_interval.rel_value, - GNUNET_NO); - zone_update_taskid = GNUNET_SCHEDULER_add_delayed (next_put_interval, - &update_zone_dht_next, - NULL); } /** - * Periodically iterate over our zone and store everything in dht + * Called whenever a client is disconnected. * - * @param cls NULL - * @param tc task context - */ -static void -update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - zone_update_taskid = GNUNET_SCHEDULER_NO_TASK; - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Scheduling DHT zone update!\n"); - /* start counting again */ - num_public_records = 0; - namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle, - NULL, /* All zones */ - GNUNET_NAMESTORE_RF_AUTHORITY, - GNUNET_NAMESTORE_RF_PRIVATE, - &put_gns_record, - NULL); -} - - -/* END DHT ZONE PROPAGATION */ - - -/** - * Send shorten response back to client - * - * @param cls the closure containing a client shorten handle - * @param name the shortened name result or NULL if cannot be shortened + * @param cls closure + * @param client identification of the client + * @param app_ctx @a client */ static void -send_shorten_response (void* cls, const char* name) +client_disconnect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + void *app_ctx) { - struct ClientShortenHandle *csh = cls; - struct GNUNET_GNS_ClientShortenResultMessage *rmsg; - size_t name_len; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n", - "SHORTEN_RESULT", name); - if (NULL == name) - name_len = 0; - else - name_len = strlen (name) + 1; - GNUNET_STATISTICS_update (statistics, - "Name shorten results", 1, GNUNET_NO); - - rmsg = GNUNET_malloc (sizeof (struct GNUNET_GNS_ClientShortenResultMessage) + - name_len); - - rmsg->id = csh->unique_id; - rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_SHORTEN_RESULT); - rmsg->header.size = - htons(sizeof(struct GNUNET_GNS_ClientShortenResultMessage) + - name_len); - memcpy (&rmsg[1], name, name_len); - GNUNET_SERVER_notification_context_unicast (nc, csh->client, - &rmsg->header, - GNUNET_NO); - if (NULL != csh->namestore_task) - GNUNET_NAMESTORE_cancel (csh->namestore_task); - GNUNET_free (rmsg); - GNUNET_free (csh); -} - + struct ClientLookupHandle *clh; + struct GnsClient *gc = app_ctx; -/** - * Lookup the zone infos and shorten name - * - * @param cls the client shorten handle - * @param key key of the zone - * @param expiration expiration of record - * @param name name found or null if no result - * @param rd_count number of records found - * @param rd record data - * @param signature - * - */ -static void -process_shorten_in_private_zone_lookup (void *cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) -{ - struct ClientShortenHandle *csh = cls; - struct GNUNET_CRYPTO_ShortHashCode *szone = &csh->shorten_zone; - struct GNUNET_CRYPTO_ShortHashCode *pzone = &csh->private_zone; - - csh->namestore_task = NULL; - if (0 == strcmp (csh->private_zone_id, "")) - pzone = NULL; - - if (rd_count == 0) + (void) cls; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Client %p disconnected\n", + client); + while (NULL != (clh = gc->clh_head)) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No shorten zone in private zone!\n"); - strcpy (csh->shorten_zone_id, ""); - szone = NULL; + if (NULL != clh->lookup) + GNS_resolver_lookup_cancel (clh->lookup); + GNUNET_CONTAINER_DLL_remove (gc->clh_head, + gc->clh_tail, + clh); + GNUNET_free (clh); } - else - { - GNUNET_assert (rd_count == 1); - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Shorten zone %s found in private zone %s\n", - name, csh->private_zone_id); - - sprintf (csh->shorten_zone_id, "%s.%s", name, csh->private_zone_id); - } - - GNUNET_CONTAINER_DLL_remove (csh_head, csh_tail, csh); - - gns_resolver_shorten_name (&csh->root_zone, - pzone, - szone, - csh->name, - csh->private_zone_id, - csh->shorten_zone_id, - &send_shorten_response, csh); + GNUNET_free (gc); } /** - * Lookup the zone infos and shorten name - * - * @param cls the shorten handle - * @param key key of the zone - * @param expiration expiration of record - * @param name name found or null if no result - * @param rd_count number of records found - * @param rd record data - * @param signature + * Add a client to our list of active clients. * + * @param cls NULL + * @param client client to add + * @param mq message queue for @a client + * @return internal namestore client structure for this client */ -static void -process_shorten_in_root_zone_lookup (void *cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) +static void * +client_connect_cb (void *cls, + struct GNUNET_SERVICE_Client *client, + struct GNUNET_MQ_Handle *mq) { - struct ClientShortenHandle *csh = cls; - struct GNUNET_CRYPTO_ShortHashCode *szone = &csh->shorten_zone; - struct GNUNET_CRYPTO_ShortHashCode *pzone = &csh->private_zone; - - csh->namestore_task = NULL; - if (0 == strcmp (csh->private_zone_id, "")) - pzone = NULL; - - if (rd_count == 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No shorten zone in zone and no private zone!\n"); - - strcpy (csh->shorten_zone_id, ""); - - GNUNET_CONTAINER_DLL_remove (csh_head, csh_tail, csh); - szone = NULL; - - gns_resolver_shorten_name (&csh->root_zone, - pzone, - szone, - csh->name, - csh->private_zone_id, - csh->shorten_zone_id, - &send_shorten_response, csh); - return; - } - - GNUNET_assert (rd_count == 1); + struct GnsClient *gc; + (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Private zone %s found in root zone\n", name); - - strcpy (csh->private_zone_id, name); - - csh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, - pzone, - szone, - &process_shorten_in_private_zone_lookup, - csh); + "Client %p connected\n", + client); + gc = GNUNET_new (struct GnsClient); + gc->client = client; + gc->mq = mq; + return gc; } /** - * Lookup the zone infos and shorten name - * - * @param cls the shorten handle - * @param key key of the zone - * @param expiration expiration of record - * @param name name found or null if no result - * @param rd_count number of records found - * @param rd record data - * @param signature + * Reply to client with the result from our lookup. * + * @param cls the closure (our client lookup handle) + * @param rd_count the number of records in @a rd + * @param rd the record data */ static void -process_private_in_root_zone_lookup (void *cls, - const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key, - struct GNUNET_TIME_Absolute expiration, - const char *name, - unsigned int rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd, - const struct GNUNET_CRYPTO_RsaSignature *signature) +send_lookup_response (void* cls, + uint32_t rd_count, + const struct GNUNET_GNSRECORD_Data *rd) { - struct ClientShortenHandle *csh = cls; - csh->namestore_task = NULL; - - if (rd_count == 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No private zone in root zone\n"); - - strcpy (csh->private_zone_id, ""); - - csh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, - &csh->root_zone, - &csh->shorten_zone, - &process_shorten_in_root_zone_lookup, - csh); - return; - } - - GNUNET_assert (rd_count == 1); + struct ClientLookupHandle *clh = cls; + struct GNUNET_MQ_Envelope *env; + struct LookupResultMessage *rmsg; + size_t len; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Private zone %s found in root zone\n", name); - - strcpy (csh->private_zone_id, name); - - csh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, - &csh->private_zone, - &csh->shorten_zone, - &process_shorten_in_private_zone_lookup, - csh); -} - - -/** - * Lookup the zone infos and shorten name - * - * @param csh the shorten handle - * - */ -static void -start_shorten_name (struct ClientShortenHandle *csh) -{ - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Looking for private zone name in root zone\n"); - - csh->namestore_task = GNUNET_NAMESTORE_zone_to_name (namestore_handle, - &csh->root_zone, - &csh->private_zone, - &process_private_in_root_zone_lookup, - csh); + "Sending LOOKUP_RESULT message with %u results\n", + (unsigned int) rd_count); + + len = GNUNET_GNSRECORD_records_get_size (rd_count, rd); + env = GNUNET_MQ_msg_extra (rmsg, + len, + GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT); + rmsg->id = clh->request_id; + rmsg->rd_count = htonl (rd_count); + GNUNET_GNSRECORD_records_serialize (rd_count, rd, len, + (char*) &rmsg[1]); + GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq(clh->gc->client), + env); + GNUNET_CONTAINER_DLL_remove (clh->gc->clh_head, + clh->gc->clh_tail, + clh); + GNUNET_free (clh); + GNUNET_STATISTICS_update (statistics, + "Completed lookups", 1, + GNUNET_NO); + GNUNET_STATISTICS_update (statistics, + "Records resolved", + rd_count, + GNUNET_NO); } /** - * Handle a shorten message from the api + * Checks a #GNUNET_MESSAGE_TYPE_GNS_LOOKUP message * - * @param cls the closure (unused) - * @param client the client - * @param message the message + * @param cls client sending the message + * @param l_msg message of type `struct LookupMessage` + * @return #GNUNET_OK if @a l_msg is well-formed */ -static void -handle_shorten (void *cls, - struct GNUNET_SERVER_Client * client, - const struct GNUNET_MessageHeader * message) +static int +check_lookup (void *cls, + const struct LookupMessage *l_msg) { - uint16_t msg_size; - const struct GNUNET_GNS_ClientShortenMessage *sh_msg; - struct ClientShortenHandle *csh; - const char *utf_in; - char name[MAX_DNS_NAME_LENGTH]; - char* nameptr = name; + size_t msg_size; + const char* name; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "SHORTEN"); - msg_size = ntohs (message->size); - if (msg_size < sizeof (struct GNUNET_GNS_ClientShortenMessage)) + (void) cls; + msg_size = ntohs (l_msg->header.size); + if (msg_size < sizeof (struct LookupMessage)) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; + return GNUNET_SYSERR; } - sh_msg = (const struct GNUNET_GNS_ClientShortenMessage *) message; - utf_in = (const char *) &sh_msg[1]; - if ('\0' != utf_in[msg_size - sizeof (struct GNUNET_GNS_ClientShortenMessage) - 1]) + name = (const char *) &l_msg[1]; + if ( ('\0' != name[msg_size - sizeof (struct LookupMessage) - 1]) || + (strlen (name) > GNUNET_DNSPARSER_MAX_NAME_LENGTH) ) { GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - csh = GNUNET_malloc (sizeof (struct ClientShortenHandle)); - csh->client = client; - csh->unique_id = sh_msg->id; - GNUNET_CONTAINER_DLL_insert (csh_head, csh_tail, csh); - GNUNET_STRINGS_utf8_tolower (utf_in, &nameptr); - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "SHORTEN: Converted `%s' to `%s'\n", - utf_in, - nameptr); - GNUNET_SERVER_notification_context_add (nc, client); - if (strlen (name) < strlen (GNUNET_GNS_TLD)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "SHORTEN: %s is too short\n", name); - GNUNET_CONTAINER_DLL_remove (csh_head, csh_tail, csh); - send_shorten_response(csh, name); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - return; - } - if (strlen (name) > MAX_DNS_NAME_LENGTH) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "SHORTEN: %s is too long\n", name); - GNUNET_CONTAINER_DLL_remove (csh_head, csh_tail, csh); - send_shorten_response(csh, name); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - return; - } - if ( (! is_gnunet_tld (name)) && - (! is_zkey_tld (name)) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "%s is not our domain. Returning\n", name); - GNUNET_CONTAINER_DLL_remove (csh_head, csh_tail, csh); - send_shorten_response (csh, name); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - return; + return GNUNET_SYSERR; } - csh->shorten_zone = sh_msg->shorten_zone; - csh->private_zone = sh_msg->private_zone; - strcpy (csh->name, name); - if (1 == ntohl(sh_msg->use_default_zone)) - csh->root_zone = zone_hash; //Default zone - else - csh->root_zone = sh_msg->zone; - start_shorten_name (csh); - GNUNET_STATISTICS_update (statistics, - "Name shorten attempts", 1, GNUNET_NO); - GNUNET_SERVER_receive_done (client, GNUNET_OK); -} - - -/** - * Send get authority response back to client - * - * @param cls the closure containing a client get auth handle - * @param name the shortened name result or NULL if cannot be shortened - */ -static void -send_get_auth_response(void *cls, const char* name) -{ - struct ClientGetAuthHandle *cah = cls; - struct GNUNET_GNS_ClientGetAuthResultMessage *rmsg; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %s\n", - "GET_AUTH_RESULT", name); - if (name != NULL) - { - GNUNET_STATISTICS_update (statistics, - "Authorities resolved", 1, GNUNET_NO); - } - if (name == NULL) - name = ""; - - rmsg = GNUNET_malloc(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage) - + strlen(name) + 1); - - rmsg->id = cah->unique_id; - rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_GET_AUTH_RESULT); - rmsg->header.size = - htons(sizeof(struct GNUNET_GNS_ClientGetAuthResultMessage) + - strlen(name) + 1); - strcpy ((char*)&rmsg[1], name); - - GNUNET_SERVER_notification_context_unicast (nc, cah->client, - &rmsg->header, - GNUNET_NO); - GNUNET_SERVER_receive_done (cah->client, GNUNET_OK); - - GNUNET_free(rmsg); - GNUNET_free_non_null(cah->name); - GNUNET_free(cah); + return GNUNET_OK; } /** - * Handle a get authority message from the api + * Handle lookup requests from client * * @param cls the closure * @param client the client * @param message the message */ -static void -handle_get_authority (void *cls, - struct GNUNET_SERVER_Client * client, - const struct GNUNET_MessageHeader * message) +static void +handle_lookup (void *cls, + const struct LookupMessage *sh_msg) { - uint16_t msg_size; - const struct GNUNET_GNS_ClientGetAuthMessage *sh_msg; - struct ClientGetAuthHandle *cah; + struct GnsClient *gc = cls; + char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 1]; + struct ClientLookupHandle *clh; + char *nameptr = name; const char *utf_in; - char name[MAX_DNS_NAME_LENGTH]; - char* nameptr = name; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "GET_AUTH"); - msg_size = ntohs(message->size); - if (msg_size < sizeof (struct GNUNET_GNS_ClientGetAuthMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_OK); - return; - } - GNUNET_SERVER_notification_context_add (nc, client); - sh_msg = (const struct GNUNET_GNS_ClientGetAuthMessage *) message; + GNUNET_SERVICE_client_continue (gc->client); utf_in = (const char *) &sh_msg[1]; - if ('\0' != utf_in[msg_size - sizeof (struct GNUNET_GNS_ClientGetAuthMessage) - 1]) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - GNUNET_STRINGS_utf8_tolower(utf_in, &nameptr); - cah = GNUNET_malloc(sizeof(struct ClientGetAuthHandle)); - cah->client = client; - cah->unique_id = sh_msg->id; - if (strlen (name) < strlen(GNUNET_GNS_TLD)) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GET_AUTH: `%s' is too short. Returning\n", name); - cah->name = NULL; - send_get_auth_response(cah, name); - return; - } - if (strlen (name) > MAX_DNS_NAME_LENGTH) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "GET_AUTH: `%s' is too long", name); - cah->name = NULL; - send_get_auth_response(cah, name); - return; - } - if (0 != strcmp (name + strlen (name) - strlen(GNUNET_GNS_TLD), - GNUNET_GNS_TLD)) + GNUNET_STRINGS_utf8_tolower (utf_in, + nameptr); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received LOOKUP `%s' message\n", + name); + + clh = GNUNET_new (struct ClientLookupHandle); + GNUNET_CONTAINER_DLL_insert (gc->clh_head, + gc->clh_tail, + clh); + clh->gc = gc; + clh->request_id = sh_msg->id; + if ( (GNUNET_DNSPARSER_TYPE_A == ntohl (sh_msg->type)) && + (GNUNET_OK != v4_enabled) ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GET_AUTH: %s is not our domain. Returning\n", name); - cah->name = NULL; - send_get_auth_response(cah, name); + "LOOKUP: Query for A record but AF_INET not supported!"); + send_lookup_response (clh, + 0, + NULL); return; } - - if (0 == strcmp(name, GNUNET_GNS_TLD)) + if ( (GNUNET_DNSPARSER_TYPE_AAAA == ntohl (sh_msg->type)) && + (GNUNET_OK != v6_enabled) ) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "GET_AUTH: %s is us. Returning\n", name); - cah->name = NULL; - send_get_auth_response(cah, name); + "LOOKUP: Query for AAAA record but AF_INET6 not supported!"); + send_lookup_response (clh, + 0, + NULL); return; - } - cah->name = GNUNET_malloc(strlen (name) - - strlen (GNUNET_GNS_TLD) + 1); - memset (cah->name, 0, - strlen (name) - strlen (GNUNET_GNS_TLD) + 1); - memcpy (cah->name, name, - strlen (name) - strlen(GNUNET_GNS_TLD)); - - /* Start delegation resolution in our namestore */ - gns_resolver_get_authority(zone_hash, zone_hash, name, &send_get_auth_response, cah); - + } + clh->lookup = GNS_resolver_lookup (&sh_msg->zone, + ntohl (sh_msg->type), + name, + (enum GNUNET_GNS_LocalOptions) ntohs (sh_msg->options), + &send_lookup_response, clh); GNUNET_STATISTICS_update (statistics, - "Authority lookup attempts", 1, GNUNET_NO); + "Lookup attempts", + 1, GNUNET_NO); } - /** - * Reply to client with the result from our lookup. + * Reads the configuration and populates TLDs * - * @param cls the closure (our client lookup handle) - * @param rd_count the number of records - * @param rd the record data + * @param cls unused + * @param section name of section in config, always "gns" + * @param option name of the option, TLDs start with "." + * @param value value for the option, public key for TLDs */ static void -send_lookup_response(void* cls, - uint32_t rd_count, - const struct GNUNET_NAMESTORE_RecordData *rd) +read_service_conf (void *cls, + const char *section, + const char *option, + const char *value) { - struct ClientLookupHandle* clh = (struct ClientLookupHandle*)cls; - struct GNUNET_GNS_ClientLookupResultMessage *rmsg; - size_t len; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %d results\n", - "LOOKUP_RESULT", rd_count); - - len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); - rmsg = GNUNET_malloc(len+sizeof(struct GNUNET_GNS_ClientLookupResultMessage)); - - rmsg->id = clh->unique_id; - rmsg->rd_count = htonl(rd_count); - rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT); - rmsg->header.size = - htons(len+sizeof(struct GNUNET_GNS_ClientLookupResultMessage)); - - GNUNET_NAMESTORE_records_serialize (rd_count, rd, len, (char*)&rmsg[1]); - - GNUNET_SERVER_notification_context_unicast (nc, clh->client, - (const struct GNUNET_MessageHeader *) rmsg, - GNUNET_NO); - GNUNET_SERVER_receive_done (clh->client, GNUNET_OK); - - GNUNET_free(rmsg); - GNUNET_free(clh->name); - - if (NULL != clh->shorten_key) - GNUNET_CRYPTO_rsa_key_free (clh->shorten_key); - - GNUNET_free(clh); - - GNUNET_STATISTICS_update (statistics, - "Completed lookups", 1, GNUNET_NO); - - if (rd != NULL) - { - GNUNET_STATISTICS_update (statistics, - "Records resolved", rd_count, GNUNET_NO); - } + struct GNUNET_CRYPTO_EcdsaPublicKey pk; + struct GNS_TopLevelDomain *tld; -} - - -/** - * Handle lookup requests from client - * - * @param cls the closure - * @param client the client - * @param message the message - */ -static void -handle_lookup(void *cls, - struct GNUNET_SERVER_Client * client, - const struct GNUNET_MessageHeader * message) -{ - uint16_t msg_size; - const struct GNUNET_GNS_ClientLookupMessage *sh_msg; - size_t namelen; - char name[MAX_DNS_NAME_LENGTH]; - struct ClientLookupHandle *clh; - char* nameptr = name; - const char *utf_in; - int only_cached; - struct GNUNET_CRYPTO_RsaPrivateKey *key; - struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *pkey; - char* tmp_pkey; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n", "LOOKUP"); - msg_size = ntohs(message->size); - if (msg_size < sizeof (struct GNUNET_GNS_ClientLookupMessage)) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_OK); + (void) cls; + (void) section; + if (option[0] != '.') return; - } - sh_msg = (const struct GNUNET_GNS_ClientLookupMessage *) message; - GNUNET_SERVER_notification_context_add (nc, client); - if (GNUNET_YES == ntohl (sh_msg->have_key)) - { - pkey = (struct GNUNET_CRYPTO_RsaPrivateKeyBinaryEncoded *)&sh_msg[1]; - tmp_pkey = (char*)&sh_msg[1]; - key = GNUNET_CRYPTO_rsa_decode_key (tmp_pkey, ntohs(pkey->len)); - GNUNET_STRINGS_utf8_tolower(&tmp_pkey[ntohs(pkey->len)], &nameptr); - } - else - { - key = NULL; - utf_in = (const char *) &sh_msg[1]; - if ('\0' != utf_in[msg_size - sizeof (struct GNUNET_GNS_ClientLookupMessage) - 1]) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - GNUNET_STRINGS_utf8_tolower(utf_in, &nameptr); - } - namelen = strlen (name)+1; - clh = GNUNET_malloc (sizeof (struct ClientLookupHandle)); - memset (clh, 0, sizeof (struct ClientLookupHandle)); - clh->client = client; - clh->name = GNUNET_malloc(namelen); - strcpy(clh->name, name); - clh->unique_id = sh_msg->id; - clh->type = ntohl(sh_msg->type); - clh->shorten_key = key; - - only_cached = ntohl(sh_msg->only_cached); - - if (strlen (name) > MAX_DNS_NAME_LENGTH) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "LOOKUP: %s is too long", name); - clh->name = NULL; - send_lookup_response(clh, 0, NULL); - return; - } - - if ((clh->type == GNUNET_GNS_RECORD_A) && - (GNUNET_OK != v4_enabled)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "LOOKUP: Query for A record but AF_INET not supported!"); - clh->name = NULL; - send_lookup_response(clh, 0, NULL); + if (GNUNET_OK != + GNUNET_STRINGS_string_to_data (value, + strlen (value), + &pk, + sizeof (pk))) + { + GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, + section, + option, + _("Properly base32-encoded public key required")); return; } - - if ((clh->type == GNUNET_GNS_RECORD_AAAA) && - (GNUNET_OK != v6_enabled)) - { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "LOOKUP: Query for AAAA record but AF_INET6 not supported!"); - clh->name = NULL; - send_lookup_response(clh, 0, NULL); - return; - } - - if (1 == ntohl(sh_msg->use_default_zone)) - clh->zone = zone_hash; //Default zone - else - clh->zone = sh_msg->zone; - - if (GNUNET_YES == auto_import_pkey) - { - gns_resolver_lookup_record (clh->zone, clh->zone, clh->type, clh->name, - clh->shorten_key, - default_lookup_timeout, - clh->only_cached, - &send_lookup_response, clh); - } - else - { - gns_resolver_lookup_record (clh->zone, clh->zone, clh->type, name, - NULL, - default_lookup_timeout, - only_cached, - &send_lookup_response, clh); - } - - GNUNET_STATISTICS_update (statistics, - "Record lookup attempts", 1, GNUNET_NO); -} - - -/** - * Test if the given AF is supported by this system. - * - * @param af to test - * @return GNUNET_OK if the AF is supported - */ -static int -test_af (int af) -{ - int s; - - s = socket (af, SOCK_STREAM, 0); - if (-1 == s) - { - if (EAFNOSUPPORT == errno) - return GNUNET_NO; - fprintf (stderr, "Failed to create test socket: %s\n", STRERROR (errno)); - return GNUNET_SYSERR; - } -#if WINDOWS - closesocket (s); -#else - close (s); -#endif - return GNUNET_OK; + tld = GNUNET_new (struct GNS_TopLevelDomain); + tld->tld = GNUNET_strdup (&option[1]); + tld->pkey = pk; + GNUNET_CONTAINER_DLL_insert (tld_head, + tld_tail, + tld); } /** * Process GNS requests. * - * @param cls closure) + * @param cls closure * @param server the initialized server * @param c configuration to use */ static void -run (void *cls, struct GNUNET_SERVER_Handle *server, - const struct GNUNET_CONFIGURATION_Handle *c) +run (void *cls, + const struct GNUNET_CONFIGURATION_Handle *c, + struct GNUNET_SERVICE_Handle *service) { - char* keyfile; - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; - unsigned long long max_parallel_bg_queries = 0; - unsigned long long default_lookup_timeout_secs = 0; - int ignore_pending = GNUNET_NO; - - static const struct GNUNET_SERVER_MessageHandler handlers[] = { - {&handle_shorten, NULL, GNUNET_MESSAGE_TYPE_GNS_SHORTEN, 0}, - {&handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0}, - {&handle_get_authority, NULL, GNUNET_MESSAGE_TYPE_GNS_GET_AUTH, 0} - }; - - v6_enabled = test_af (AF_INET6); - v4_enabled = test_af (AF_INET); - - if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (c, "gns", - "ZONEKEY", &keyfile)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "No private key for root zone specified!\n"); - GNUNET_SCHEDULER_shutdown (); - return; - } - - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, - "Using keyfile %s for root zone.\n", keyfile); + unsigned long long max_parallel_bg_queries = 16; - zone_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile); - GNUNET_CRYPTO_rsa_key_get_public (zone_key, &pkey); - - GNUNET_CRYPTO_short_hash(&pkey, - sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &zone_hash); - GNUNET_free(keyfile); - namestore_handle = GNUNET_NAMESTORE_connect (c); - if (NULL == namestore_handle) + GNUNET_CONFIGURATION_iterate_section_values (c, + "gns", + &read_service_conf, + NULL); + v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); + v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); + namecache_handle = GNUNET_NAMECACHE_connect (c); + if (NULL == namecache_handle) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to connect to the namestore!\n")); + _("Failed to connect to the namecache!\n")); GNUNET_SCHEDULER_shutdown (); return; } - - auto_import_pkey = GNUNET_NO; - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (c, "gns", - "AUTO_IMPORT_PKEY")) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Automatic PKEY import is enabled.\n"); - auto_import_pkey = GNUNET_YES; - - } - - zone_iteration_interval = INITIAL_ZONE_ITERATION_INTERVAL; - - record_put_interval = DEFAULT_RECORD_PUT_INTERVAL; - - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_time (c, "gns", - "RECORD_PUT_INTERVAL", - &record_put_interval)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Record put interval: %s\n", - GNUNET_STRINGS_relative_time_to_string (record_put_interval, GNUNET_YES)); - } - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number (c, "gns", - "MAX_PARALLEL_BACKGROUND_QUERIES", - &max_parallel_bg_queries)) + GNUNET_CONFIGURATION_get_value_number (c, + "gns", + "MAX_PARALLEL_BACKGROUND_QUERIES", + &max_parallel_bg_queries)) { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Number of allowed parallel background queries: %llu\n", - max_parallel_bg_queries); - } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (c, "gns", - "AUTO_IMPORT_CONFIRMATION_REQ")) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Auto import requires user confirmation\n"); - ignore_pending = GNUNET_YES; - } - - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_number(c, "gns", - "DEFAULT_LOOKUP_TIMEOUT", - &default_lookup_timeout_secs)) - { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Default lookup timeout: %llus\n", default_lookup_timeout_secs); - default_lookup_timeout = GNUNET_TIME_relative_multiply( - GNUNET_TIME_UNIT_SECONDS, - default_lookup_timeout_secs); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Number of allowed parallel background queries: %llu\n", + max_parallel_bg_queries); } - - /** - * handle to the dht - */ - dht_handle = GNUNET_DHT_connect(c, - //max_parallel_bg_queries); //FIXME get ht_len from cfg - 1024); - + dht_handle = GNUNET_DHT_connect (c, + (unsigned int) max_parallel_bg_queries); if (NULL == dht_handle) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to DHT!\n"); - } - - if (gns_resolver_init(namestore_handle, dht_handle, zone_hash, c, - max_parallel_bg_queries, - ignore_pending) - == GNUNET_SYSERR) - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - "Unable to initialize resolver!\n"); - GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not connect to DHT!\n")); + GNUNET_SCHEDULER_add_now (&shutdown_task, + NULL); return; } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_yesno (c, "gns", "HIJACK_DNS")) + GNS_resolver_init (namecache_handle, + dht_handle, + c, + max_parallel_bg_queries); + if ( (GNUNET_YES == + GNUNET_CONFIGURATION_get_value_yesno (c, + "gns", + "INTERCEPT_DNS")) && + (GNUNET_SYSERR == + GNS_interceptor_init (c)) ) { - GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "DNS hijacking enabled... connecting to service.\n"); - - if (gns_interceptor_init(zone_hash, zone_key, c) == GNUNET_SYSERR) - { - GNUNET_log(GNUNET_ERROR_TYPE_ERROR, - "Failed to enable the dns interceptor!\n"); - } + GNUNET_break (0); + GNUNET_SCHEDULER_add_now (&shutdown_task, + NULL); + return; } - - /** - * Schedule periodic put - * for our records - * We have roughly an hour for all records; - */ - first_zone_iteration = GNUNET_YES; - zone_update_taskid = GNUNET_SCHEDULER_add_now (&update_zone_dht_start, NULL); - - GNUNET_SERVER_add_handlers (server, handlers); - - //FIXME - //GNUNET_SERVER_disconnect_notify (server, - // &client_disconnect_notification, - // NULL); - - statistics = GNUNET_STATISTICS_create ("gns", c); - - nc = GNUNET_SERVER_notification_context_create (server, 1); - - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, - NULL); + statistics = GNUNET_STATISTICS_create ("gns", + c); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, + NULL); } /** - * The main function for the GNS service. - * - * @param argc number of arguments from the command line - * @param argv command line arguments - * @return 0 ok, 1 on error + * Define "main" method using service macro. */ -int -main (int argc, char *const *argv) -{ - int ret; +GNUNET_SERVICE_MAIN +("gns", + GNUNET_SERVICE_OPTION_NONE, + &run, + &client_connect_cb, + &client_disconnect_cb, + NULL, + GNUNET_MQ_hd_var_size (lookup, + GNUNET_MESSAGE_TYPE_GNS_LOOKUP, + struct LookupMessage, + NULL), + GNUNET_MQ_handler_end()); - ret = - (GNUNET_OK == - GNUNET_SERVICE_run (argc, argv, "gns", GNUNET_SERVICE_OPTION_NONE, &run, - NULL)) ? 0 : 1; - return ret; -} /* end of gnunet-service-gns.c */