GNUnet  0.19.3
gnunet-service-namestore.c File Reference

namestore for the GNUnet naming system More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_gns_service.h"
#include "gnunet_namestore_service.h"
#include "gnunet_namestore_plugin.h"
#include "gnunet_statistics_service.h"
#include "gnunet_signatures.h"
#include "namestore.h"
Include dependency graph for gnunet-service-namestore.c:

Go to the source code of this file.

Data Structures

struct  ZoneIteration
 A namestore iteration operation. More...
 
struct  NamestoreClient
 A namestore client. More...
 
struct  ZoneMonitor
 A namestore monitor. More...
 
struct  StoreActivity
 Information for an ongoing handle_record_store() operation. More...
 
struct  NickCache
 Entry in list of cached nick resolutions. More...
 
struct  RecordLookupContext
 Closure for lookup_it(). More...
 
struct  LookupExistingRecordsContext
 
struct  ZoneToNameCtx
 Context for record remove operations passed from handle_zone_to_name to handle_zone_to_name_it as closure. More...
 
struct  ZoneIterationProcResult
 Context for record remove operations passed from run_zone_iteration_round to zone_iterate_proc as closure. More...
 

Macros

#define LOG_STRERROR_FILE(kind, syscall, filename)    GNUNET_log_from_strerror_file (kind, "util", syscall, filename)
 
#define MONITOR_STALL_WARN_DELAY   GNUNET_TIME_UNIT_MINUTES
 If a monitor takes more than 1 minute to process an event, print a warning. More...
 
#define NC_SIZE   16
 Size of the cache used by get_nick_record() More...
 

Functions

static void cleanup_task (void *cls)
 Task run during shutdown. More...
 
static void free_store_activity (struct StoreActivity *sa)
 Release memory used by sa. More...
 
static void lookup_nick_it (void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Function called with the records for the GNUNET_GNS_EMPTY_LABEL_AT label in the zone. More...
 
static void cache_nick (const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_GNSRECORD_Data *nick)
 Add entry to the cache for zone and nick. More...
 
static struct GNUNET_GNSRECORD_Dataget_nick_record (const struct GNUNET_IDENTITY_PrivateKey *zone)
 Return the NICK record for the zone (if it exists). More...
 
static void merge_with_nick_records (const struct GNUNET_GNSRECORD_Data *nick_rd, unsigned int rd2_length, const struct GNUNET_GNSRECORD_Data *rd2, unsigned int *rdc_res, struct GNUNET_GNSRECORD_Data **rd_res)
 Merge the nick record nick_rd with the rest of the record set given in rd2. More...
 
static int send_lookup_response_with_filter (struct NamestoreClient *nc, uint32_t request_id, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, enum GNUNET_GNSRECORD_Filter filter)
 Generate a struct LookupNameResponseMessage and send it to the given client using the given notification context. More...
 
static void send_store_response (struct NamestoreClient *nc, enum GNUNET_ErrorCode ec, uint32_t rid)
 Send response to the store request to the client. More...
 
static void zone_iteration_done_client_continue (struct ZoneIteration *zi)
 Function called once we are done with the zone iteration and allow the zone iteration client to send us more messages. More...
 
static void warn_monitor_slow (void *cls)
 Print a warning that one of our monitors is no longer reacting. More...
 
static int continue_store_activity (struct StoreActivity *sa, int call_continue)
 Continue processing the sa. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
 Called whenever a client is disconnected. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 Add a client to our list of active clients. More...
 
static void lookup_it (void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count_nf, const struct GNUNET_GNSRECORD_Data *rd_nf)
 Function called by the namestore plugin when we are trying to lookup a record as part of handle_record_lookup(). More...
 
static int check_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message. More...
 
static void handle_record_lookup (void *cls, const struct LabelLookupMessage *ll_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message. More...
 
static int check_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
 Checks a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message. More...
 
static void get_existing_rd_exp (void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Check if set contains a tombstone, store if necessary. More...
 
static enum GNUNET_ErrorCode store_record_set (struct NamestoreClient *nc, const struct GNUNET_IDENTITY_PrivateKey *private_key, const struct RecordSet *rd_set, ssize_t *len)
 
static void handle_record_store (void *cls, const struct RecordStoreMessage *rp_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message. More...
 
static void send_tx_response (int rid, enum GNUNET_ErrorCode ec, struct NamestoreClient *nc)
 
static void handle_tx_control (void *cls, const struct TxControlMessage *tx_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL message. More...
 
static void handle_zone_to_name_it (void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Zone to name iterator. More...
 
static enum GNUNET_GenericReturnValue check_zone_to_name (void *cls, const struct ZoneToNameMessage *zis_msg)
 
static void handle_zone_to_name (void *cls, const struct ZoneToNameMessage *ztn_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME message. More...
 
static void zone_iterate_proc (void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 Process results for zone iteration from database. More...
 
static void run_zone_iteration_round (struct ZoneIteration *zi, uint64_t limit)
 Perform the next round of the zone iteration. More...
 
static enum GNUNET_GenericReturnValue check_iteration_start (void *cls, const struct ZoneIterationStartMessage *zis_msg)
 
static void handle_iteration_start (void *cls, const struct ZoneIterationStartMessage *zis_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START message. More...
 
static void handle_iteration_stop (void *cls, const struct ZoneIterationStopMessage *zis_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP message. More...
 
static void handle_iteration_next (void *cls, const struct ZoneIterationNextMessage *zis_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT message. More...
 
static void monitor_unblock (struct ZoneMonitor *zm)
 Function called when the monitor is ready for more data, and we should thus unblock PUT operations that were blocked on the monitor not being ready. More...
 
static void monitor_sync (struct ZoneMonitor *zm)
 Send 'sync' message to zone monitor, we're now in sync. More...
 
static void monitor_iteration_next (void *cls)
 Obtain the next datum during the zone monitor's zone initial iteration. More...
 
static void monitor_iterate_cb (void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
 A GNUNET_NAMESTORE_RecordIterator for monitors. More...
 
static enum GNUNET_GenericReturnValue check_monitor_start (void *cls, const struct ZoneMonitorStartMessage *zis_msg)
 
static void handle_monitor_start (void *cls, const struct ZoneMonitorStartMessage *zis_msg)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START message. More...
 
static void handle_monitor_next (void *cls, const struct ZoneMonitorNextMessage *nm)
 Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT message. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
 Process namestore requests. More...
 
 GNUNET_SERVICE_MAIN ("namestore", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_fixed_size(tx_control, GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL, struct TxControlMessage, NULL), GNUNET_MQ_hd_var_size(record_store, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE, struct RecordStoreMessage, NULL), GNUNET_MQ_hd_var_size(record_lookup, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP, struct LabelLookupMessage, NULL), GNUNET_MQ_hd_var_size(zone_to_name, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME, struct ZoneToNameMessage, NULL), GNUNET_MQ_hd_var_size(iteration_start, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START, struct ZoneIterationStartMessage, NULL), GNUNET_MQ_hd_fixed_size(iteration_next, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT, struct ZoneIterationNextMessage, NULL), GNUNET_MQ_hd_fixed_size(iteration_stop, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP, struct ZoneIterationStopMessage, NULL), GNUNET_MQ_hd_var_size(monitor_start, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START, struct ZoneMonitorStartMessage, NULL), GNUNET_MQ_hd_fixed_size(monitor_next, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT, struct ZoneMonitorNextMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static struct NickCache nick_cache [16]
 We cache nick records to reduce DB load. More...
 
static const struct GNUNET_IDENTITY_PrivateKey zero
 Public key of all zeros. More...
 
static const struct GNUNET_CONFIGURATION_HandleGSN_cfg
 Configuration handle. More...
 
static struct GNUNET_STATISTICS_Handlestatistics
 Handle to the statistics service. More...
 
static char * db_lib_name
 Name of the database plugin. More...
 
struct GNUNET_NAMESTORE_PluginFunctionsGSN_database
 Database handle for service. More...
 
static struct ZoneMonitormonitor_head
 First active zone monitor. More...
 
static struct ZoneMonitormonitor_tail
 Last active zone monitor. More...
 
static struct StoreActivitysa_head
 Head of DLL of monitor-blocked store activities. More...
 
static struct StoreActivitysa_tail
 Tail of DLL of monitor-blocked store activities. More...
 
static struct GNUNET_NotificationContextmonitor_nc
 Notification context shared by all monitors. More...
 
static int return_orphaned
 Returned orphaned records? More...
 

Detailed Description

namestore for the GNUnet naming system

Author
Matthias Wachs
Christian Grothoff

Definition in file gnunet-service-namestore.c.

Macro Definition Documentation

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)     GNUNET_log_from_strerror_file (kind, "util", syscall, filename)

Definition at line 36 of file gnunet-service-namestore.c.

◆ MONITOR_STALL_WARN_DELAY

#define MONITOR_STALL_WARN_DELAY   GNUNET_TIME_UNIT_MINUTES

If a monitor takes more than 1 minute to process an event, print a warning.

Definition at line 42 of file gnunet-service-namestore.c.

◆ NC_SIZE

#define NC_SIZE   16

Size of the cache used by get_nick_record()

Definition at line 47 of file gnunet-service-namestore.c.

Function Documentation

◆ cleanup_task()

static void cleanup_task ( void *  cls)
static

Task run during shutdown.

Parameters
clsunused

Definition at line 409 of file gnunet-service-namestore.c.

410 {
411  (void) cls;
412  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n");
413  if (NULL != monitor_nc)
414  {
416  monitor_nc = NULL;
417  }
418  if (NULL != statistics)
419  {
421  statistics = NULL;
422  }
425  db_lib_name = NULL;
426 }
static struct GNUNET_NotificationContext * monitor_nc
Notification context shared by all monitors.
struct GNUNET_NAMESTORE_PluginFunctions * GSN_database
Database handle for service.
static char * db_lib_name
Name of the database plugin.
static struct GNUNET_STATISTICS_Handle * statistics
Handle to the statistics service.
#define GNUNET_log(kind,...)
@ GNUNET_NO
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:138
void * GNUNET_PLUGIN_unload(const char *library_name, void *arg)
Unload plugin (runs the "done" callback and returns whatever "done" returned).
Definition: plugin.c:242
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).

References db_lib_name, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_notification_context_destroy(), GNUNET_PLUGIN_unload(), GNUNET_STATISTICS_destroy(), GSN_database, monitor_nc, and statistics.

Referenced by run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ free_store_activity()

static void free_store_activity ( struct StoreActivity sa)
static

Release memory used by sa.

Parameters
saactivity to free

Definition at line 435 of file gnunet-service-namestore.c.

436 {
438  GNUNET_free (sa);
439 }
static struct StoreActivity * sa_tail
Tail of DLL of monitor-blocked store activities.
static struct StoreActivity * sa_head
Head of DLL of monitor-blocked store activities.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, sa_head, and sa_tail.

Referenced by client_disconnect_cb(), continue_store_activity(), and handle_tx_control().

Here is the caller graph for this function:

◆ lookup_nick_it()

static void lookup_nick_it ( void *  cls,
uint64_t  seq,
const struct GNUNET_IDENTITY_PrivateKey private_key,
const char *  label,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

Function called with the records for the GNUNET_GNS_EMPTY_LABEL_AT label in the zone.

Used to locate the GNUNET_GNSRECORD_TYPE_NICK record, which (if found) is then copied to cls for future use.

Parameters
clsa struct GNUNET_GNSRECORD_Data ** for storing the nick (if found)
seqsequence number of the record, MUST NOT BE ZERO
private_keythe private key of the zone (unused)
labelshould be GNUNET_GNS_EMPTY_LABEL_AT
rd_countnumber of records in rd
rdrecords stored under label in the zone

Definition at line 454 of file gnunet-service-namestore.c.

460 {
461  struct GNUNET_GNSRECORD_Data **res = cls;
462 
463  (void) private_key;
464  GNUNET_assert (0 != seq);
465  if (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT))
466  {
467  GNUNET_break (0);
468  return;
469  }
470  for (unsigned int c = 0; c < rd_count; c++)
471  {
473  {
474  (*res) =
475  GNUNET_malloc (rd[c].data_size + sizeof(struct GNUNET_GNSRECORD_Data));
476  (*res)->data = &(*res)[1];
477  GNUNET_memcpy ((void *) (*res)->data, rd[c].data, rd[c].data_size);
478  (*res)->data_size = rd[c].data_size;
479  (*res)->expiration_time = rd[c].expiration_time;
480  (*res)->flags = rd[c].flags;
481  (*res)->record_type = GNUNET_GNSRECORD_TYPE_NICK;
482  return;
483  }
484  }
485  (*res) = NULL;
486 }
#define GNUNET_GNSRECORD_TYPE_NICK
GNS nick names.
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
static int res
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
#define GNUNET_GNS_EMPTY_LABEL_AT
String we use to indicate an empty label (top-level entry in the zone).
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_malloc(size)
Wrapper around malloc.
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.

References GNUNET_GNSRECORD_Data::data, data_size, GNUNET_GNSRECORD_Data::data_size, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_GNSRECORD_Data::flags, GNUNET_assert, GNUNET_break, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNSRECORD_TYPE_NICK, GNUNET_malloc, GNUNET_memcpy, rd, rd_count, GNUNET_GNSRECORD_Data::record_type, and res.

Referenced by get_nick_record().

Here is the caller graph for this function:

◆ cache_nick()

static void cache_nick ( const struct GNUNET_IDENTITY_PrivateKey zone,
const struct GNUNET_GNSRECORD_Data nick 
)
static

Add entry to the cache for zone and nick.

Parameters
zonezone key to cache under
nicknick entry to cache

Definition at line 496 of file gnunet-service-namestore.c.

498 {
499  struct NickCache *oldest;
500 
501  oldest = NULL;
502  for (unsigned int i = 0; i < NC_SIZE; i++)
503  {
504  struct NickCache *pos = &nick_cache[i];
505 
506  if ((NULL == oldest) ||
507  (oldest->last_used.abs_value_us > pos->last_used.abs_value_us))
508  oldest = pos;
509  if (0 == GNUNET_memcmp (zone, &pos->zone))
510  {
511  oldest = pos;
512  break;
513  }
514  }
515  GNUNET_free (oldest->rd);
516  oldest->zone = *zone;
517  if (NULL != nick)
518  {
519  oldest->rd = GNUNET_malloc (sizeof(*nick) + nick->data_size);
520  *oldest->rd = *nick;
521  oldest->rd->data = &oldest->rd[1];
522  memcpy (&oldest->rd[1], nick->data, nick->data_size);
523  }
524  else
525  {
526  oldest->rd = NULL;
527  }
528  oldest->last_used = GNUNET_TIME_absolute_get ();
529 }
static char * zone
Name of the zone being managed.
#define NC_SIZE
Size of the cache used by get_nick_record()
static struct NickCache nick_cache[16]
We cache nick records to reduce DB load.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:111
uint64_t abs_value_us
The actual value.
Entry in list of cached nick resolutions.
struct GNUNET_GNSRECORD_Data * rd
Cached record data.
struct GNUNET_TIME_Absolute last_used
Timestamp when this cache entry was used last.
struct GNUNET_IDENTITY_PrivateKey zone
Zone the cache entry is for.

References GNUNET_TIME_Absolute::abs_value_us, GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, GNUNET_free, GNUNET_malloc, GNUNET_memcmp, GNUNET_TIME_absolute_get(), NickCache::last_used, NC_SIZE, nick_cache, NickCache::rd, zone, and NickCache::zone.

Referenced by get_nick_record().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_nick_record()

static struct GNUNET_GNSRECORD_Data* get_nick_record ( const struct GNUNET_IDENTITY_PrivateKey zone)
static

Return the NICK record for the zone (if it exists).

Parameters
ncthe namestore client
zoneprivate key for the zone to look for nick
Returns
NULL if no NICK record was found

Definition at line 540 of file gnunet-service-namestore.c.

541 {
543  struct GNUNET_GNSRECORD_Data *nick;
544  int res;
545 
546  /* check cache first */
547  for (unsigned int i = 0; i < NC_SIZE; i++)
548  {
549  struct NickCache *pos = &nick_cache[i];
550  if ((NULL != pos->rd) && (0 == GNUNET_memcmp (zone, &pos->zone)))
551  {
552  if (NULL == pos->rd)
553  return NULL;
554  nick = GNUNET_malloc (sizeof(*nick) + pos->rd->data_size);
555  *nick = *pos->rd;
556  nick->data = &nick[1];
557  memcpy (&nick[1], pos->rd->data, pos->rd->data_size);
559  return nick;
560  }
561  }
562 
563  nick = NULL;
565  zone,
568  &nick);
569  if ((GNUNET_OK != res) || (NULL == nick))
570  {
571 #if ! defined(GNUNET_CULL_LOGGING)
572  static int do_log = GNUNET_LOG_CALL_STATUS;
573 
574  if (0 == do_log)
576  "namestore",
577  __FILE__,
578  __FUNCTION__,
579  __LINE__);
580  if (1 == do_log)
581  {
584  "No nick name set for zone `%s'\n",
586  }
587 #endif
588  /* update cache */
589  cache_nick (zone, NULL);
590  return NULL;
591  }
592 
593  /* update cache */
594  cache_nick (zone, nick);
595  return nick;
596 }
static struct GNUNET_CRYPTO_EddsaPublicKey pub
Definition: gnunet-scrypt.c:47
static void lookup_nick_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Function called with the records for the GNUNET_GNS_EMPTY_LABEL_AT label in the zone.
static void cache_nick(const struct GNUNET_IDENTITY_PrivateKey *zone, const struct GNUNET_GNSRECORD_Data *nick)
Add entry to the cache for zone and nick.
const char * GNUNET_GNSRECORD_z2s(const struct GNUNET_IDENTITY_PublicKey *z)
Convert a zone to a string (for printing debug messages).
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_key_get_public(const struct GNUNET_IDENTITY_PrivateKey *privkey, struct GNUNET_IDENTITY_PublicKey *key)
Retrieves the public key representation of a private key.
Definition: identity_api.c:179
#define GNUNET_LOG_CALL_STATUS
int GNUNET_get_log_call_status(int caller_level, const char *comp, const char *file, const char *function, int line)
Decides whether a particular logging call should or should not be allowed to be made.
@ GNUNET_OK
@ GNUNET_ERROR_TYPE_BULK
An identity key as per LSD0001.
enum GNUNET_GenericReturnValue(* lookup_records)(void *cls, const struct GNUNET_IDENTITY_PrivateKey *zone, const char *label, GNUNET_NAMESTORE_RecordIterator iter, void *iter_cls)
Lookup records in the datastore for which we are the authority.
void * cls
Closure to pass to all plugin functions.

References cache_nick(), GNUNET_NAMESTORE_PluginFunctions::cls, GNUNET_GNSRECORD_Data::data, GNUNET_GNSRECORD_Data::data_size, GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_DEBUG, GNUNET_get_log_call_status(), GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNSRECORD_z2s(), GNUNET_IDENTITY_key_get_public(), GNUNET_log, GNUNET_LOG_CALL_STATUS, GNUNET_malloc, GNUNET_memcmp, GNUNET_OK, GNUNET_TIME_absolute_get(), GSN_database, NickCache::last_used, lookup_nick_it(), GNUNET_NAMESTORE_PluginFunctions::lookup_records, NC_SIZE, nick_cache, pub, NickCache::rd, res, zone, and NickCache::zone.

Referenced by handle_record_lookup(), and send_lookup_response_with_filter().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ merge_with_nick_records()

static void merge_with_nick_records ( const struct GNUNET_GNSRECORD_Data nick_rd,
unsigned int  rd2_length,
const struct GNUNET_GNSRECORD_Data rd2,
unsigned int *  rdc_res,
struct GNUNET_GNSRECORD_Data **  rd_res 
)
static

Merge the nick record nick_rd with the rest of the record set given in rd2.

Store the result in rdc_res and rd_res. The nick_rd's expiration time is set to the maximum expiration time of all of the records in rd2.

Parameters
nick_rdthe nick record to integrate
rd2_lengthlength of the rd2 array
rd2array of records
[out]rdc_reslength of the resulting rd_res array
[out]rd_resset to an array of records, including nick_rd and rd2; all of the variable-size 'data' fields in rd2 are allocated in the same chunk of memory!

Definition at line 615 of file gnunet-service-namestore.c.

620 {
621  uint64_t latest_expiration;
622  size_t req;
623  char *data;
624  size_t data_offset;
625  struct GNUNET_GNSRECORD_Data *target;
626 
627  (*rdc_res) = 1 + rd2_length;
628  if (0 == 1 + rd2_length)
629  {
630  GNUNET_break (0);
631  (*rd_res) = NULL;
632  return;
633  }
634  req = sizeof(struct GNUNET_GNSRECORD_Data) + nick_rd->data_size;
635  for (unsigned int i = 0; i < rd2_length; i++)
636  {
637  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
638 
639  if (req + sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size < req)
640  {
641  GNUNET_break (0);
642  (*rd_res) = NULL;
643  return;
644  }
645  req += sizeof(struct GNUNET_GNSRECORD_Data) + orig->data_size;
646  }
647  target = GNUNET_malloc (req);
648  (*rd_res) = target;
649  data = (char *) &target[1 + rd2_length];
650  data_offset = 0;
651  latest_expiration = 0;
652  for (unsigned int i = 0; i < rd2_length; i++)
653  {
654  const struct GNUNET_GNSRECORD_Data *orig = &rd2[i];
655 
657  {
658  if ((GNUNET_TIME_absolute_get ().abs_value_us + orig->expiration_time) >
659  latest_expiration)
660  latest_expiration = orig->expiration_time;
661  }
662  else if (orig->expiration_time > latest_expiration)
663  latest_expiration = orig->expiration_time;
664  target[i] = *orig;
665  target[i].data = (void *) &data[data_offset];
666  GNUNET_memcpy (&data[data_offset], orig->data, orig->data_size);
667  data_offset += orig->data_size;
668  }
669  /* append nick */
670  target[rd2_length] = *nick_rd;
671  /* Mark as supplemental */
672  target[rd2_length].flags = nick_rd->flags | GNUNET_GNSRECORD_RF_SUPPLEMENTAL;
673  target[rd2_length].expiration_time = latest_expiration;
674  target[rd2_length].data = (void *) &data[data_offset];
675  GNUNET_memcpy (&data[data_offset], nick_rd->data, nick_rd->data_size);
676  data_offset += nick_rd->data_size;
677  GNUNET_assert (req == (sizeof(struct GNUNET_GNSRECORD_Data)) * (*rdc_res)
678  + data_offset);
679 }
uint32_t data
The data value.
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.

References GNUNET_GNSRECORD_Data::data, data, data_size, GNUNET_GNSRECORD_Data::data_size, GNUNET_GNSRECORD_Data::expiration_time, GNUNET_GNSRECORD_Data::flags, GNUNET_assert, GNUNET_break, GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION, GNUNET_GNSRECORD_RF_SUPPLEMENTAL, GNUNET_malloc, GNUNET_memcpy, and GNUNET_TIME_absolute_get().

Referenced by lookup_it(), and send_lookup_response_with_filter().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_lookup_response_with_filter()

static int send_lookup_response_with_filter ( struct NamestoreClient nc,
uint32_t  request_id,
const struct GNUNET_IDENTITY_PrivateKey zone_key,
const char *  name,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd,
enum GNUNET_GNSRECORD_Filter  filter 
)
static

Generate a struct LookupNameResponseMessage and send it to the given client using the given notification context.

Parameters
ncclient to unicast to
request_idrequest ID to use
zone_keyzone key of the zone
namename
rd_countnumber of records in rd
rdarray of records
filterrecord set filter

FIXME if we ever support GNUNET_NAMESTORE_OMIT_PUBLIC, we need to omit adding this public record here

Definition at line 695 of file gnunet-service-namestore.c.

703 {
704  struct GNUNET_MQ_Envelope *env;
705  struct RecordResultMessage *zir_msg;
706  struct GNUNET_GNSRECORD_Data *nick;
707  struct GNUNET_GNSRECORD_Data *res;
708  struct GNUNET_GNSRECORD_Data rd_nf[rd_count];
710  unsigned int res_count;
711  unsigned int rd_nf_count;
712  size_t name_len;
713  size_t key_len;
714  ssize_t rd_ser_len;
715  char *name_tmp;
716  char *rd_ser;
717  char *emsg;
718 
719  nick = get_nick_record (zone_key);
721 
723  rd,
724  rd_count,
725  rd_nf,
726  &rd_nf_count,
727  &block_exp,
728  filter,
729  &emsg))
730  {
731  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
732  GNUNET_free (emsg);
733  GNUNET_assert (0);
734  }
735 
740  if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT)))
741  {
742  nick->flags =
744  merge_with_nick_records (nick, rd_nf_count, rd_nf, &res_count, &res);
745  }
746  else
747  {
748  res_count = rd_nf_count;
749  res = (struct GNUNET_GNSRECORD_Data *) rd_nf;
750  }
751  if (NULL != nick)
752  GNUNET_free (nick);
753 
754  if (0 == res_count)
755  {
756  if (rd_nf != res)
757  GNUNET_free (res);
758  return 0;
759  }
761 
762 
763  name_len = strlen (name) + 1;
764  rd_ser_len = GNUNET_GNSRECORD_records_get_size (res_count, res);
765  if (rd_ser_len < 0)
766  {
767  if (rd_nf != res)
768  GNUNET_free (res);
769  GNUNET_break (0);
770  GNUNET_SERVICE_client_drop (nc->client);
771  return 0;
772  }
773  if (((size_t) rd_ser_len) >= UINT16_MAX - name_len - sizeof(*zir_msg))
774  {
775  if (rd_nf != res)
776  GNUNET_free (res);
777  GNUNET_break (0);
778  GNUNET_SERVICE_client_drop (nc->client);
779  return 0;
780  }
782  env = GNUNET_MQ_msg_extra (zir_msg,
783  name_len + rd_ser_len + key_len,
785  zir_msg->gns_header.r_id = htonl (request_id);
786  zir_msg->name_len = htons (name_len);
787  zir_msg->rd_count = htons (res_count);
788  zir_msg->rd_len = htons ((uint16_t) rd_ser_len);
789  zir_msg->key_len = htons (key_len);
791  &zir_msg[1],
792  key_len);
793  zir_msg->expire = GNUNET_TIME_absolute_hton (block_exp);
794  name_tmp = (char *) &zir_msg[1] + key_len;
795  GNUNET_memcpy (name_tmp, name, name_len);
796  rd_ser = &name_tmp[name_len];
797  GNUNET_assert (
798  rd_ser_len ==
799  GNUNET_GNSRECORD_records_serialize (res_count, res, rd_ser_len, rd_ser));
801  "Sending RECORD_RESULT message with %u records\n",
802  res_count);
804  "Record sets sent to clients",
805  1,
806  GNUNET_NO);
807  GNUNET_MQ_send (nc->mq, env);
808  if (rd_nf != res)
809  GNUNET_free (res);
810  return res_count;
811 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static const struct GNUNET_IDENTITY_PrivateKey * zone_key
Private key of the zone.
static struct GNUNET_PEERINFO_NotifyContext * nc
Iterator context.
static struct GNUNET_CONTAINER_BloomFilter * filter
Bloomfilter to quickly tell if we don't have the content.
static void merge_with_nick_records(const struct GNUNET_GNSRECORD_Data *nick_rd, unsigned int rd2_length, const struct GNUNET_GNSRECORD_Data *rd2, unsigned int *rdc_res, struct GNUNET_GNSRECORD_Data **rd_res)
Merge the nick record nick_rd with the rest of the record set given in rd2.
static struct GNUNET_GNSRECORD_Data * get_nick_record(const struct GNUNET_IDENTITY_PrivateKey *zone)
Return the NICK record for the zone (if it exists).
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be published.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_normalize_record_set(const char *label, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *rd_public, unsigned int *rd_count_public, struct GNUNET_TIME_Absolute *expiry, enum GNUNET_GNSRECORD_Filter filter, char **emsg)
Normalize namestore records: Check for consistency and expirations.
ssize_t GNUNET_IDENTITY_write_private_key_to_buffer(const struct GNUNET_IDENTITY_PrivateKey *key, void *buffer, size_t len)
Writes a GNUNET_IDENTITY_PrivateKey to a compact buffer.
Definition: identity_api.c:933
ssize_t GNUNET_IDENTITY_private_key_get_length(const struct GNUNET_IDENTITY_PrivateKey *key)
Get the compacted length of a GNUNET_IDENTITY_PrivateKey.
Definition: identity_api.c:809
@ GNUNET_ERROR_TYPE_ERROR
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
Definition: gnunet_mq_lib.h:62
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT
Service to client: here is a (plaintext) record you requested.
void GNUNET_SERVICE_client_drop(struct GNUNET_SERVICE_Client *c)
Ask the server to disconnect from the given client.
Definition: service.c:2330
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
const char * name
uint32_t r_id
Request ID in NBO.
Definition: namestore.h:51
struct GNUNET_MQ_Handle * mq
Our connection to the PEERINFO service.
Time for absolute times used by GNUnet, in microseconds.
Record is returned from the namestore (as authority).
Definition: namestore.h:292
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:312
uint16_t name_len
Name length.
Definition: namestore.h:307
uint16_t rd_count
Number of records contained.
Definition: namestore.h:317
struct GNUNET_TIME_AbsoluteNBO expire
Expiration time if the record result (if any).
Definition: namestore.h:302
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT.
Definition: namestore.h:296
uint16_t key_len
Length of the zone key.
Definition: namestore.h:322

References env, RecordResultMessage::expire, filter, GNUNET_GNSRECORD_Data::flags, get_nick_record(), RecordResultMessage::gns_header, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNSRECORD_normalize_record_set(), GNUNET_GNSRECORD_records_get_size(), GNUNET_GNSRECORD_records_serialize(), GNUNET_GNSRECORD_RF_PRIVATE, GNUNET_IDENTITY_private_key_get_length(), GNUNET_IDENTITY_write_private_key_to_buffer(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_OK, GNUNET_SERVICE_client_drop(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_UNIT_ZERO_ABS, RecordResultMessage::key_len, merge_with_nick_records(), GNUNET_PEERINFO_NotifyContext::mq, name, RecordResultMessage::name_len, nc, GNUNET_NAMESTORE_Header::r_id, rd, rd_count, RecordResultMessage::rd_count, RecordResultMessage::rd_len, res, statistics, and zone_key.

Referenced by check_monitor_start(), continue_store_activity(), and zone_iterate_proc().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ send_store_response()

static void send_store_response ( struct NamestoreClient nc,
enum GNUNET_ErrorCode  ec,
uint32_t  rid 
)
static

Send response to the store request to the client.

Parameters
ncclient to talk to
ecstatus of the operation
ridclient's request ID

Definition at line 821 of file gnunet-service-namestore.c.

824 {
825  struct GNUNET_MQ_Envelope *env;
826  struct RecordStoreResponseMessage *rcr_msg;
827 
828  GNUNET_assert (NULL != nc);
830  "Sending RECORD_STORE_RESPONSE message\n");
832  "Store requests completed",
833  1,
834  GNUNET_NO);
835  env = GNUNET_MQ_msg (rcr_msg,
837  rcr_msg->gns_header.r_id = htonl (rid);
838  rcr_msg->ec = htonl (ec);
839  GNUNET_MQ_send (nc->mq, env);
840 }
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:77
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE
Service to client: result of store operation.
Response to a record storage request.
Definition: namestore.h:114
uint32_t ec
GNUNET_ErrorCode.
Definition: namestore.h:123
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE.
Definition: namestore.h:118

References RecordStoreResponseMessage::ec, env, RecordStoreResponseMessage::gns_header, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE_RESPONSE, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, GNUNET_STATISTICS_update(), GNUNET_PEERINFO_NotifyContext::mq, nc, GNUNET_NAMESTORE_Header::r_id, and statistics.

Referenced by continue_store_activity(), and handle_record_store().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ zone_iteration_done_client_continue()

static void zone_iteration_done_client_continue ( struct ZoneIteration zi)
static

Function called once we are done with the zone iteration and allow the zone iteration client to send us more messages.

Parameters
zizone iteration we are processing

Definition at line 850 of file gnunet-service-namestore.c.

851 {
852  struct GNUNET_MQ_Envelope *env;
853  struct GNUNET_NAMESTORE_Header *em;
854 
856  if (! zi->send_end)
857  return;
858  /* send empty response to indicate end of list */
860  em->r_id = htonl (zi->request_id);
861  GNUNET_MQ_send (zi->nc->mq, env);
862 
864  GNUNET_free (zi);
865 }
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END
Service to client: end of list of results.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2249
Generic namestore message with op id.
Definition: namestore.h:41
struct ZoneIteration * op_head
Head of the DLL of Zone iteration operations in progress initiated by this client.
struct GNUNET_MQ_Handle * mq
Message queue for transmission to client.
struct GNUNET_SERVICE_Client * client
The client.
struct ZoneIteration * op_tail
Tail of the DLL of Zone iteration operations in progress initiated by this client.
struct NamestoreClient * nc
Namestore client which intiated this zone iteration.
int send_end
Set to GNUNET_YES if the last iteration exhausted the limit set by the client and we should send the ...
uint32_t request_id
The operation id for the zone iteration in the response for the client.

References NamestoreClient::client, env, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_RESULT_END, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), NamestoreClient::mq, ZoneIteration::nc, NamestoreClient::op_head, NamestoreClient::op_tail, GNUNET_NAMESTORE_Header::r_id, ZoneIteration::request_id, and ZoneIteration::send_end.

Referenced by check_iteration_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ warn_monitor_slow()

static void warn_monitor_slow ( void *  cls)
static

Print a warning that one of our monitors is no longer reacting.

Parameters
clsa struct ZoneMonitor to warn about

Definition at line 876 of file gnunet-service-namestore.c.

877 {
878  struct ZoneMonitor *zm = cls;
879 
881  "No response from monitor since %s\n",
882  GNUNET_STRINGS_absolute_time_to_string (zm->sa_waiting_start));
885  zm);
886 }
static struct GNUNET_NAMESTORE_ZoneMonitor * zm
Monitor handle.
#define MONITOR_STALL_WARN_DELAY
If a monitor takes more than 1 minute to process an event, print a warning.
static void warn_monitor_slow(void *cls)
Print a warning that one of our monitors is no longer reacting.
@ GNUNET_ERROR_TYPE_WARNING
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1241
const char * GNUNET_STRINGS_absolute_time_to_string(struct GNUNET_TIME_Absolute t)
Like asctime, except for GNUnet time.
Definition: strings.c:616
A namestore monitor.

References GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_absolute_time_to_string(), MONITOR_STALL_WARN_DELAY, and zm.

Referenced by continue_store_activity(), handle_monitor_next(), and monitor_unblock().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ continue_store_activity()

static int continue_store_activity ( struct StoreActivity sa,
int  call_continue 
)
static

Continue processing the sa.

Parameters
sastore activity to process

Definition at line 895 of file gnunet-service-namestore.c.

897 {
898  const struct RecordSet *rd_set = sa->rs;
899  unsigned int rd_count;
900  size_t name_len;
901  size_t rd_ser_len;
902  const char *name_tmp;
903  const char *rd_ser;
904  const char *buf;
905  char *conv_name;
906 
907  // If we are in a transaction, do not notify monitors or update
908  // cached. This will be done when we are commiting.
909  if (GNUNET_YES == sa->uncommited)
910  {
912  "Transaction not yet committed, delaying monitor and cache updates\n");
914  if (GNUNET_YES == call_continue)
916  return GNUNET_OK;
917  }
918  buf = (const char *) &sa[1];
919  for (int i = sa->rd_set_pos; i < sa->rd_set_count; i++)
920  {
921  rd_set = (struct RecordSet *) buf;
922  name_len = ntohs (rd_set->name_len);
923  rd_count = ntohs (rd_set->rd_count);
924  rd_ser_len = ntohs (rd_set->rd_len);
925  name_tmp = (const char *) &rd_set[1];
926  rd_ser = &name_tmp[name_len];
927  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
928  GNUNET_assert (NULL != conv_name);
929  {
931 
932  /* We did this before, must succeed again */
933  GNUNET_assert (
934  GNUNET_OK ==
935  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count,
936  rd));
937 
939  "Checking monitors watching for `%s'\n",
940  conv_name);
941  for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos)
942  {
943  if ((0 != GNUNET_memcmp (&sa->private_key, &zm->zone)) &&
944  (0 != GNUNET_memcmp (&zm->zone, &zero)))
945  {
946  sa->zm_pos = zm->next; /* not interesting to this monitor */
947  continue;
948  }
949  if (zm->limit == zm->iteration_cnt)
950  {
951  zm->sa_waiting = GNUNET_YES;
952  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
953  if (NULL != zm->sa_wait_warning)
954  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
955  zm->sa_wait_warning =
958  zm);
960  "Monitor is blocking client for `%s'\n",
961  conv_name);
962  GNUNET_free (conv_name);
963  return GNUNET_NO; /* blocked on zone monitor */
964  }
966  "Notifying monitor about changes under label `%s'\n",
967  conv_name);
969  0,
970  &sa->private_key,
971  conv_name,
972  rd_count,
973  rd,
974  zm->filter))
975  zm->limit--;
976  sa->zm_pos = zm->next;
977  }
978  sa->rd_set_pos++;
979  GNUNET_free (conv_name);
980  }
981  }
982  if (GNUNET_YES == call_continue)
985  free_store_activity (sa);
986  return GNUNET_OK;
987 }
@ GNUNET_EC_NONE
No error (success).
static void free_store_activity(struct StoreActivity *sa)
Release memory used by sa.
static int send_lookup_response_with_filter(struct NamestoreClient *nc, uint32_t request_id, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, enum GNUNET_GNSRECORD_Filter filter)
Generate a struct LookupNameResponseMessage and send it to the given client using the given notificat...
static void send_store_response(struct NamestoreClient *nc, enum GNUNET_ErrorCode ec, uint32_t rid)
Send response to the store request to the client.
static const struct GNUNET_IDENTITY_PrivateKey zero
Public key of all zeros.
static char buf[2048]
char * GNUNET_GNSRECORD_string_normalize(const char *src)
Normalize a UTF-8 string to a GNS name.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
@ GNUNET_YES
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:944
struct GNUNET_IDENTITY_PrivateKey zone
Monitored zone.
enum GNUNET_GNSRECORD_Filter filter
Record set filter for this monitor.
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:64
uint16_t rd_count
Number of records contained.
Definition: namestore.h:69
uint16_t name_len
Name length.
Definition: namestore.h:59
uint32_t rid
The request ID.
const struct RecordSet * rs
Copy of the original record set (as data fields in rd will point into it!).
struct GNUNET_IDENTITY_PrivateKey private_key
The zone private key.
struct NamestoreClient * nc
Which client triggered the store activity?
int uncommited
Wheather or not this store action is already commited.
uint16_t rd_set_pos
The currently processed record.
struct ZoneMonitor * zm_pos
Next zone monitor that still needs to be notified about this PUT.

References buf, NamestoreClient::client, GNUNET_NAMESTORE_ZoneMonitor::filter, free_store_activity(), GNUNET_assert, GNUNET_EC_NONE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_GNSRECORD_records_deserialize(), GNUNET_GNSRECORD_string_normalize(), GNUNET_log, GNUNET_memcmp, GNUNET_NO, GNUNET_NZL, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_SERVICE_client_continue(), GNUNET_TIME_absolute_get(), GNUNET_YES, MONITOR_STALL_WARN_DELAY, RecordSet::name_len, StoreActivity::nc, StoreActivity::private_key, rd, rd_count, RecordSet::rd_count, RecordSet::rd_len, StoreActivity::rd_set_pos, StoreActivity::rid, StoreActivity::rs, send_lookup_response_with_filter(), send_store_response(), StoreActivity::uncommited, warn_monitor_slow(), zero, zm, StoreActivity::zm_pos, and GNUNET_NAMESTORE_ZoneMonitor::zone.

Referenced by client_disconnect_cb(), handle_record_store(), handle_tx_control(), and monitor_unblock().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ client_disconnect_cb()

static void client_disconnect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
void *  app_ctx 
)
static

Called whenever a client is disconnected.

Frees our resources associated with that client.

Parameters
clsclosure
clientidentification of the client
app_ctxthe struct NamestoreClient of client

Definition at line 999 of file gnunet-service-namestore.c.

1002 {
1003  struct NamestoreClient *nc = app_ctx;
1004  struct ZoneIteration *no;
1005  struct StoreActivity *sa = sa_head;
1006  struct StoreActivity *sn;
1007  char *emsg;
1008 
1009  (void) cls;
1010  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p disconnected\n", client);
1011  if (GNUNET_YES == nc->in_transaction)
1012  {
1014  "Client in transaction, rolling back...\n");
1015  if (GNUNET_SYSERR == nc->GSN_database->transaction_rollback (
1016  nc->GSN_database->cls,
1017  &emsg))
1018  {
1020  "Unable to roll back: %s\n", emsg);
1021  GNUNET_free (emsg);
1022  }
1023  else
1024  {
1025  nc->in_transaction = GNUNET_NO;
1026  while (NULL != sa)
1027  {
1028  if ((nc != sa->nc) ||
1029  (GNUNET_NO == sa->uncommited))
1030  {
1031  sa = sa->next;
1032  continue;
1033  }
1034  sn = sa->next;
1035  free_store_activity (sa);
1036  sa = sn;
1037  }
1038  }
1039  }
1040  for (struct ZoneMonitor *zm = monitor_head; NULL != zm; zm = zm->next)
1041  {
1042  if (nc != zm->nc)
1043  continue;
1045  if (NULL != zm->task)
1046  {
1047  GNUNET_SCHEDULER_cancel (zm->task);
1048  zm->task = NULL;
1049  }
1050  if (NULL != zm->sa_wait_warning)
1051  {
1052  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
1053  zm->sa_wait_warning = NULL;
1054  }
1055  for (sa = sa_head; NULL != sa; sa = sn)
1056  {
1057  sn = sa->next;
1058  if (zm == sa->zm_pos)
1059  {
1060  sa->zm_pos = zm->next;
1061  /* this may free sa */
1063  }
1064  }
1065  GNUNET_free (zm);
1066  break;
1067  }
1068  sa = sa_head;
1069  while (NULL != sa)
1070  {
1071  if (nc != sa->nc)
1072  {
1073  sa = sa->next;
1074  continue;
1075  }
1076  sn = sa->next;
1077  free_store_activity (sa);
1078  sa = sn;
1079  }
1080  while (NULL != (no = nc->op_head))
1081  {
1082  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no);
1083  GNUNET_free (no);
1084  }
1085  GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name,
1086  nc->GSN_database));
1087  GNUNET_free (nc->db_lib_name);
1088  GNUNET_free (nc);
1089 }
static int continue_store_activity(struct StoreActivity *sa, int call_continue)
Continue processing the sa.
static struct ZoneMonitor * monitor_head
First active zone monitor.
static struct ZoneMonitor * monitor_tail
Last active zone monitor.
@ GNUNET_SYSERR
A namestore client.
Information for an ongoing handle_record_store() operation.
struct StoreActivity * next
Kept in a DLL.
A namestore iteration operation.

References continue_store_activity(), free_store_activity(), GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NO, GNUNET_PLUGIN_unload(), GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_YES, monitor_head, monitor_tail, nc, StoreActivity::nc, StoreActivity::next, sa_head, StoreActivity::uncommited, zm, and StoreActivity::zm_pos.

Here is the call graph for this function:

◆ client_connect_cb()

static void* client_connect_cb ( void *  cls,
struct GNUNET_SERVICE_Client client,
struct GNUNET_MQ_Handle mq 
)
static

Add a client to our list of active clients.

Parameters
clsNULL
clientclient to add
mqmessage queue for client
Returns
internal namestore client structure for this client

Definition at line 1101 of file gnunet-service-namestore.c.

1104 {
1105  struct NamestoreClient *nc;
1106  char *database;
1107 
1108  (void) cls;
1109  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %p connected\n", client);
1110  nc = GNUNET_new (struct NamestoreClient);
1111  nc->client = client;
1112  nc->mq = mq;
1113  /* Loading database plugin */
1115  "namestore",
1116  "database",
1117  &database))
1118  {
1119  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
1120  GNUNET_free (nc);
1121  return NULL;
1122  }
1123  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading %s\n", db_lib_name);
1124  nc->GSN_database = GNUNET_PLUGIN_load (db_lib_name, (void *) GSN_cfg);
1125  GNUNET_free (database);
1126  if (NULL == nc->GSN_database)
1127  {
1129  "Could not load database backend `%s'\n",
1130  db_lib_name);
1131  GNUNET_free (nc);
1132  return NULL;
1133  }
1134  nc->db_lib_name = GNUNET_strdup (db_lib_name);
1136  return nc;
1137 }
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
static const struct GNUNET_CONFIGURATION_Handle * GSN_cfg
Configuration handle.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
void * GNUNET_PLUGIN_load(const char *library_name, void *arg)
Setup plugin (runs the "init" callback and returns whatever "init" returned).
Definition: plugin.c:198

References NamestoreClient::client, db_lib_name, GNUNET_CONFIGURATION_get_value_string(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_new, GNUNET_OK, GNUNET_PLUGIN_load(), GNUNET_strdup, GSN_cfg, mq, GNUNET_PEERINFO_NotifyContext::mq, and nc.

Here is the call graph for this function:

◆ lookup_it()

static void lookup_it ( void *  cls,
uint64_t  seq,
const struct GNUNET_IDENTITY_PrivateKey private_key,
const char *  label,
unsigned int  rd_count_nf,
const struct GNUNET_GNSRECORD_Data rd_nf 
)
static

Function called by the namestore plugin when we are trying to lookup a record as part of handle_record_lookup().

Merges all results into the context.

Parameters
clsclosure with a struct RecordLookupContext
sequnique serial number of the record, MUST NOT BE ZERO
private_keyprivate key of the zone
labelname that is being mapped (at most 255 characters long)
rd_countnumber of entries in rd array
rdarray of records with data to store

Definition at line 1195 of file gnunet-service-namestore.c.

1201 {
1202  struct RecordLookupContext *rlc = cls;
1203  struct GNUNET_GNSRECORD_Data rd[rd_count_nf];
1204  struct GNUNET_TIME_Absolute block_exp;
1205  unsigned int rd_count = 0;
1206  char *emsg;
1207 
1208  (void) private_key;
1209  GNUNET_assert (0 != seq);
1210  if (0 != strcmp (label, rlc->label))
1211  return;
1212  rlc->found = GNUNET_YES;
1213 
1215  rd_nf,
1216  rd_count_nf,
1217  rd,
1218  &rd_count,
1219  &block_exp,
1220  rlc->filter,
1221  &emsg))
1222  {
1223  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "%s\n", emsg);
1224  GNUNET_free (emsg);
1225  GNUNET_assert (0);
1226  }
1227 
1228  if (0 == rd_count)
1229  {
1230  rlc->rd_ser_len = 0;
1231  rlc->res_rd_count = 0;
1232  rlc->res_rd = NULL;
1233  return;
1234  }
1235  if ((NULL != rlc->nick) && (0 != strcmp (label, GNUNET_GNS_EMPTY_LABEL_AT)))
1236  {
1237  /* Merge */
1238  struct GNUNET_GNSRECORD_Data *rd_res;
1239  unsigned int rdc_res;
1240 
1241  rd_res = NULL;
1242  rdc_res = 0;
1243  rlc->nick->flags = (rlc->nick->flags | GNUNET_GNSRECORD_RF_PRIVATE)
1245  merge_with_nick_records (rlc->nick, rd_count, rd, &rdc_res, &rd_res);
1246  rlc->rd_ser_len = GNUNET_GNSRECORD_records_get_size (rdc_res, rd_res);
1247  if (rlc->rd_ser_len < 0)
1248  {
1249  GNUNET_break (0);
1250  GNUNET_free (rd_res);
1251  rlc->found = GNUNET_NO;
1252  rlc->rd_ser_len = 0;
1253  return;
1254  }
1255  rlc->res_rd_count = rdc_res;
1256  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1257  if (rlc->rd_ser_len != GNUNET_GNSRECORD_records_serialize (rdc_res,
1258  rd_res,
1259  rlc->rd_ser_len,
1260  rlc->res_rd))
1261  {
1262  GNUNET_break (0);
1263  GNUNET_free (rlc->res_rd);
1264  rlc->res_rd = NULL;
1265  rlc->res_rd_count = 0;
1266  rlc->rd_ser_len = 0;
1267  GNUNET_free (rd_res);
1268  rlc->found = GNUNET_NO;
1269  return;
1270  }
1271  GNUNET_free (rd_res);
1272  GNUNET_free (rlc->nick);
1273  rlc->nick = NULL;
1274  }
1275  else
1276  {
1278  if (rlc->rd_ser_len < 0)
1279  {
1280  GNUNET_break (0);
1281  rlc->found = GNUNET_NO;
1282  rlc->rd_ser_len = 0;
1283  return;
1284  }
1285  rlc->res_rd_count = rd_count;
1286  rlc->res_rd = GNUNET_malloc (rlc->rd_ser_len);
1288  rd,
1289  rlc->rd_ser_len,
1290  rlc->res_rd))
1291  {
1292  GNUNET_break (0);
1293  GNUNET_free (rlc->res_rd);
1294  rlc->res_rd = NULL;
1295  rlc->res_rd_count = 0;
1296  rlc->rd_ser_len = 0;
1297  rlc->found = GNUNET_NO;
1298  return;
1299  }
1300  }
1301 }
Closure for lookup_it().
struct GNUNET_GNSRECORD_Data * nick
The nick for the zone.
char * res_rd
The record result.
const char * label
The label to look up.
int found
If a record set was found or not.
unsigned int res_rd_count
The number of found records.
ssize_t rd_ser_len
The length of the serialized records.
enum GNUNET_GNSRECORD_Filter filter
The record filter.

References RecordLookupContext::filter, GNUNET_GNSRECORD_Data::flags, RecordLookupContext::found, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_GNS_EMPTY_LABEL_AT, GNUNET_GNSRECORD_normalize_record_set(), GNUNET_GNSRECORD_records_get_size(), GNUNET_GNSRECORD_records_serialize(), GNUNET_GNSRECORD_RF_PRIVATE, GNUNET_log, GNUNET_malloc, GNUNET_NO, GNUNET_OK, GNUNET_YES, RecordLookupContext::label, merge_with_nick_records(), RecordLookupContext::nick, rd, rd_count, RecordLookupContext::rd_ser_len, RecordLookupContext::res_rd, and RecordLookupContext::res_rd_count.

Referenced by handle_record_lookup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_record_lookup()

static int check_record_lookup ( void *  cls,
const struct LabelLookupMessage ll_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.

Parameters
clsclient sending the message
ll_msgmessage of type struct LabelLookupMessage
Returns
GNUNET_OK if ll_msg is well-formed

Definition at line 1312 of file gnunet-service-namestore.c.

1313 {
1314  uint32_t name_len;
1315  size_t src_size;
1316  size_t key_len;
1317 
1318  (void) cls;
1319  name_len = ntohs (ll_msg->label_len);
1320  key_len = ntohs (ll_msg->key_len);
1321  src_size = ntohs (ll_msg->gns_header.header.size);
1322  if (name_len + key_len != src_size - sizeof(struct LabelLookupMessage))
1323  {
1324  GNUNET_break (0);
1325  return GNUNET_SYSERR;
1326  }
1327  return GNUNET_OK;
1328 }
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_MessageHeader header
header.type will be GNUNET_MESSAGE_TYPE_NAMESTORE_* header.size will be message size
Definition: namestore.h:46
Lookup a label.
Definition: namestore.h:132
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP.
Definition: namestore.h:136
uint16_t key_len
Length of the zone key.
Definition: namestore.h:156
uint16_t label_len
Length of the name.
Definition: namestore.h:141

References LabelLookupMessage::gns_header, GNUNET_break, GNUNET_OK, GNUNET_SYSERR, GNUNET_NAMESTORE_Header::header, LabelLookupMessage::key_len, LabelLookupMessage::label_len, and GNUNET_MessageHeader::size.

◆ handle_record_lookup()

static void handle_record_lookup ( void *  cls,
const struct LabelLookupMessage ll_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP message.

Parameters
clsclient sending the message
ll_msgmessage of type struct LabelLookupMessage

Definition at line 1338 of file gnunet-service-namestore.c.

1339 {
1341  struct NamestoreClient *nc = cls;
1342  struct GNUNET_MQ_Envelope *env;
1343  struct LabelLookupResponseMessage *llr_msg;
1344  struct RecordLookupContext rlc;
1345  const char *name_tmp;
1346  char *res_name;
1347  char *conv_name;
1348  uint32_t name_len;
1349  int res;
1350  size_t key_len;
1351  size_t kb_read;
1352 
1353  key_len = ntohs (ll_msg->key_len);
1354  if ((GNUNET_SYSERR ==
1356  key_len,
1357  &zone,
1358  &kb_read)) ||
1359  (kb_read != key_len))
1360  {
1362  "Error reading private key\n");
1363  GNUNET_SERVICE_client_drop (nc->client);
1364  return;
1365  }
1366  name_tmp = (const char *) &ll_msg[1] + key_len;
1369  "Received NAMESTORE_RECORD_LOOKUP message for name `%s'\n",
1370  name_tmp);
1371 
1372  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1373  if (NULL == conv_name)
1374  {
1376  "Error converting name `%s'\n",
1377  name_tmp);
1378  GNUNET_SERVICE_client_drop (nc->client);
1379  return;
1380  }
1381  name_len = strlen (conv_name) + 1;
1382  rlc.label = conv_name;
1384  "Looking up with filter %u\n", ntohs (ll_msg->filter));
1385  rlc.filter = ntohs (ll_msg->filter);
1386  rlc.found = GNUNET_NO;
1387  rlc.res_rd_count = 0;
1388  rlc.res_rd = NULL;
1389  rlc.rd_ser_len = 0;
1390  rlc.nick = get_nick_record (&zone);
1391  if (GNUNET_YES != ntohs (ll_msg->is_edit_request))
1392  res = nc->GSN_database->lookup_records (nc->GSN_database->cls,
1393  &zone,
1394  conv_name,
1395  &lookup_it,
1396  &rlc);
1397  else
1398  res = nc->GSN_database->edit_records (nc->GSN_database->cls,
1399  &zone,
1400  conv_name,
1401  &lookup_it,
1402  &rlc);
1403 
1404  env =
1405  GNUNET_MQ_msg_extra (llr_msg,
1406  key_len + name_len + rlc.rd_ser_len,
1408  llr_msg->gns_header.r_id = ll_msg->gns_header.r_id;
1409  GNUNET_memcpy (&llr_msg[1], &ll_msg[1], key_len);
1410  llr_msg->key_len = ll_msg->key_len;
1411  llr_msg->name_len = htons (name_len);
1412  llr_msg->rd_count = htons (rlc.res_rd_count);
1413  llr_msg->rd_len = htons (rlc.rd_ser_len);
1414  llr_msg->reserved = htons (0);
1415  res_name = ((char *) &llr_msg[1]) + key_len;
1416  if (GNUNET_YES == rlc.found)
1417  llr_msg->found = htons (GNUNET_YES);
1418  else if (GNUNET_SYSERR == res)
1419  llr_msg->found = htons (GNUNET_SYSERR);
1420  else
1421  llr_msg->found = htons (GNUNET_NO);
1422  GNUNET_memcpy (res_name, conv_name, name_len);
1423  GNUNET_memcpy (&res_name[name_len], rlc.res_rd, rlc.rd_ser_len);
1424  GNUNET_MQ_send (nc->mq, env);
1425  GNUNET_free (rlc.res_rd);
1426  GNUNET_free (conv_name);
1427 }
static void lookup_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count_nf, const struct GNUNET_GNSRECORD_Data *rd_nf)
Function called by the namestore plugin when we are trying to lookup a record as part of handle_recor...
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_read_private_key_from_buffer(const void *buffer, size_t len, struct GNUNET_IDENTITY_PrivateKey *key, size_t *kb_read)
Reads a GNUNET_IDENTITY_PrivateKey from a compact buffer.
Definition: identity_api.c:908
#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE
Service to client: lookup label.
A private key for an identity as per LSD0001.
uint16_t is_edit_request
GNUNET_YES if this lookup corresponds to an edit request.
Definition: namestore.h:146
uint16_t filter
The record filter.
Definition: namestore.h:151
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:183
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE.
Definition: namestore.h:173
uint16_t reserved
Reserved (alignment)
Definition: namestore.h:199
uint16_t key_len
Length of the zone key.
Definition: namestore.h:204
uint16_t rd_count
Number of records contained.
Definition: namestore.h:188
uint16_t name_len
Name length.
Definition: namestore.h:178
int16_t found
Was the label found in the database?? GNUNET_YES or GNUNET_NO.
Definition: namestore.h:194

References env, RecordLookupContext::filter, LabelLookupMessage::filter, RecordLookupContext::found, LabelLookupResponseMessage::found, get_nick_record(), LabelLookupMessage::gns_header, LabelLookupResponseMessage::gns_header, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_GNSRECORD_string_normalize(), GNUNET_IDENTITY_read_private_key_from_buffer(), GNUNET_log, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, GNUNET_YES, LabelLookupMessage::is_edit_request, LabelLookupMessage::key_len, LabelLookupResponseMessage::key_len, RecordLookupContext::label, lookup_it(), GNUNET_PEERINFO_NotifyContext::mq, LabelLookupResponseMessage::name_len, nc, RecordLookupContext::nick, GNUNET_NAMESTORE_Header::r_id, LabelLookupResponseMessage::rd_count, LabelLookupResponseMessage::rd_len, RecordLookupContext::rd_ser_len, res, RecordLookupContext::res_rd, RecordLookupContext::res_rd_count, LabelLookupResponseMessage::reserved, and zone.

Here is the call graph for this function:

◆ check_record_store()

static int check_record_store ( void *  cls,
const struct RecordStoreMessage rp_msg 
)
static

Checks a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.

Parameters
clsclient sending the message
rp_msgmessage of type struct RecordStoreMessage
Returns
GNUNET_OK if rp_msg is well-formed

Definition at line 1439 of file gnunet-service-namestore.c.

1440 {
1441  size_t msg_size;
1442  size_t min_size_exp;
1443  size_t rd_set_count;
1444  size_t key_len;
1445 
1446  (void) cls;
1447  msg_size = ntohs (rp_msg->gns_header.header.size);
1448  rd_set_count = ntohs (rp_msg->rd_set_count);
1449  key_len = ntohs (rp_msg->key_len);
1450 
1451  min_size_exp = sizeof(*rp_msg) + key_len + sizeof (struct RecordSet)
1452  * rd_set_count;
1453  if (msg_size < min_size_exp)
1454  {
1455  GNUNET_break (0);
1456  return GNUNET_SYSERR;
1457  }
1458  return GNUNET_OK;
1459 }
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE.
Definition: namestore.h:91
uint16_t rd_set_count
Number of record sets.
Definition: namestore.h:96
uint16_t key_len
Length of the zone key.
Definition: namestore.h:101

References RecordStoreMessage::gns_header, GNUNET_break, GNUNET_OK, GNUNET_SYSERR, GNUNET_NAMESTORE_Header::header, RecordStoreMessage::key_len, RecordStoreMessage::rd_set_count, and GNUNET_MessageHeader::size.

◆ get_existing_rd_exp()

static void get_existing_rd_exp ( void *  cls,
uint64_t  seq,
const struct GNUNET_IDENTITY_PrivateKey private_key,
const char *  label,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

Check if set contains a tombstone, store if necessary.

Parameters
clsa struct GNUNET_GNSRECORD_Data ** for storing the nick (if found)
seqsequence number of the record, MUST NOT BE ZERO
private_keythe private key of the zone (unused)
labelshould be GNUNET_GNS_EMPTY_LABEL_AT
rd_countnumber of records in rd
rdrecords stored under label in the zone

Definition at line 1489 of file gnunet-service-namestore.c.

1496 {
1497  struct LookupExistingRecordsContext *lctx = cls;
1498  struct GNUNET_GNSRECORD_Data rd_pub[rd_count];
1499  unsigned int rd_pub_count;
1500  char *emsg;
1501 
1502  if ((1 == rd_count) &&
1504  {
1505  /* This record set contains only a tombstone! */
1506  lctx->only_tombstone = GNUNET_YES;
1507  }
1508  if (GNUNET_OK !=
1510  rd,
1511  rd_count,
1512  rd_pub,
1513  &rd_pub_count,
1514  &lctx->exp,
1516  &emsg))
1517  {
1519  "%s\n", emsg);
1520  GNUNET_free (emsg);
1521  }
1522 }
#define GNUNET_GNSRECORD_TYPE_TOMBSTONE
Record type to indicate a previously delete record (PRIVATE only)
@ GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE
Filter private records.
struct GNUNET_TIME_Absolute exp
The expiration of the existing records or tombstone.
int only_tombstone
Whether the existing record set consists only of a tombstone (e.g.

References LookupExistingRecordsContext::exp, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, GNUNET_GNSRECORD_normalize_record_set(), GNUNET_GNSRECORD_TYPE_TOMBSTONE, GNUNET_log, GNUNET_OK, GNUNET_YES, LookupExistingRecordsContext::only_tombstone, rd, rd_count, and GNUNET_GNSRECORD_Data::record_type.

Here is the call graph for this function:

◆ store_record_set()

static enum GNUNET_ErrorCode store_record_set ( struct NamestoreClient nc,
const struct GNUNET_IDENTITY_PrivateKey private_key,
const struct RecordSet rd_set,
ssize_t *  len 
)
static

Definition at line 1489 of file gnunet-service-namestore.c.

1529 {
1530  size_t name_len;
1531  size_t rd_ser_len;
1532  const char *name_tmp;
1533  const char *rd_ser;
1534  char *conv_name;
1535  char *emsg;
1536  unsigned int rd_count;
1537  int res;
1538  enum GNUNET_ErrorCode ec;
1539  struct GNUNET_TIME_Absolute new_block_exp;
1540  struct LookupExistingRecordsContext lctx;
1541  *len = sizeof (struct RecordSet);
1542 
1543  ec = GNUNET_EC_NONE;
1544  lctx.only_tombstone = GNUNET_NO;
1545  lctx.exp = GNUNET_TIME_UNIT_ZERO_ABS;
1546  new_block_exp = GNUNET_TIME_UNIT_ZERO_ABS;
1547  name_len = ntohs (rd_set->name_len);
1548  *len += name_len;
1549  rd_count = ntohs (rd_set->rd_count);
1550  rd_ser_len = ntohs (rd_set->rd_len);
1551  *len += rd_ser_len;
1552  name_tmp = (const char *) &rd_set[1];
1553  rd_ser = &name_tmp[name_len];
1554  {
1556 
1557  /* Extracting and converting private key */
1558  conv_name = GNUNET_GNSRECORD_string_normalize (name_tmp);
1559  if (NULL == conv_name)
1560  {
1562  "Error normalizing name `%s'\n",
1563  name_tmp);
1565  }
1566 
1567  /* Check name for validity */
1568  if (GNUNET_OK != GNUNET_GNSRECORD_label_check (conv_name, &emsg))
1569  {
1571  "Label invalid: `%s'\n",
1572  emsg);
1573  GNUNET_free (emsg);
1574  GNUNET_free (conv_name);
1576  }
1577 
1578  if (GNUNET_OK !=
1579  GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count,
1580  rd))
1581  {
1582  GNUNET_free (conv_name);
1584  }
1585 
1587  "Well-formed store requests received",
1588  1,
1589  GNUNET_NO);
1591  "Creating %u records for name `%s'\n",
1592  (unsigned int) rd_count,
1593  conv_name);
1594  if ((GNUNET_NO == nc->GSN_database->lookup_records (nc->GSN_database->cls,
1595  private_key,
1596  conv_name,
1598  &lctx))
1599  &&
1600  (rd_count == 0))
1601  {
1602  /* This name does not exist, so cannot be removed */
1604  "Name `%s' does not exist, no deletion required\n",
1605  conv_name);
1606  res = GNUNET_NO;
1608  }
1609  else
1610  {
1611  /* remove "NICK" records, unless this is for the
1612  #GNUNET_GNS_EMPTY_LABEL_AT label
1613  We may need one additional record later for tombstone.
1614  FIXME: Since we must normalize the record set (check for
1615  consistency etc) we have to iterate the set twice.
1616  May be inefficient.
1617  We cannot really move the nick caching into GNSRECORD.
1618  */
1619  struct GNUNET_GNSRECORD_Data rd_clean[GNUNET_NZL (rd_count)];
1620  struct GNUNET_GNSRECORD_Data rd_nf[GNUNET_NZL (rd_count) + 1];
1621  unsigned int rd_clean_off;
1622  unsigned int rd_nf_count;
1623  int have_nick;
1624 
1625  rd_clean_off = 0;
1626  have_nick = GNUNET_NO;
1627  for (unsigned int i = 0; i < rd_count; i++)
1628  {
1629  rd_clean[rd_clean_off] = rd[i];
1630 
1631  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) ||
1633  rd_clean_off++;
1634 
1635  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1637  {
1638  // FIXME: In case this is an uncommited transaction,
1639  // we should not do this here. Can we do this in the store activity?
1640  cache_nick (private_key, &rd[i]);
1641  have_nick = GNUNET_YES;
1642  }
1643  }
1644  if (GNUNET_OK !=
1646  rd_clean,
1647  rd_clean_off,
1648  rd_nf,
1649  &rd_nf_count,
1650  &new_block_exp,
1652  &emsg))
1653  {
1654  GNUNET_free (conv_name);
1656  "Error normalizing record set: `%s'\n",
1657  emsg);
1658  GNUNET_free (emsg);
1660  }
1662  "%u/%u records before tombstone\n", rd_nf_count,
1663  rd_clean_off);
1664  /*
1665  * If existing_block_exp is 0, then there was no record set
1666  * and no tombstone.
1667  * Otherwise, if the existing block expiration is after the
1668  * new block expiration would be, we need to add a tombstone
1669  * or update it.
1670  */
1671  if (GNUNET_TIME_absolute_cmp (new_block_exp, <=, lctx.exp))
1672  {
1673  rd_nf[rd_nf_count].record_type = GNUNET_GNSRECORD_TYPE_TOMBSTONE;
1674  rd_nf[rd_nf_count].expiration_time =
1675  lctx.exp.abs_value_us;
1676  rd_nf[rd_nf_count].data = NULL;
1677  rd_nf[rd_nf_count].data_size = 0;
1678  rd_nf[rd_nf_count].flags = GNUNET_GNSRECORD_RF_PRIVATE;
1679  rd_nf_count++;
1680  }
1681  if ((0 == strcmp (GNUNET_GNS_EMPTY_LABEL_AT, conv_name)) &&
1682  (GNUNET_NO == have_nick))
1683  {
1684  /* remove nick record from cache, in case we have one there */
1685  // FIXME: In case this is an uncommited transaction,
1686  // we should not do this here. Can we do this in the store activity?
1687  cache_nick (private_key, NULL);
1688  }
1689  res = nc->GSN_database->store_records (nc->GSN_database->cls,
1690  private_key,
1691  conv_name,
1692  rd_nf_count,
1693  rd_nf);
1694  /* If after a store there is only a TOMBSTONE left, and
1695  * there was >1 record under this label found (the tombstone; indicated
1696  * through res != GNUNET_NO) then we should return "NOT FOUND" == GNUNET_NO
1697  */
1698  if ((GNUNET_SYSERR != res) &&
1699  (0 == rd_count) &&
1700  (1 == rd_nf_count) &&
1702  (GNUNET_YES == lctx.only_tombstone))
1703  {
1705  "Client tried to remove non-existant record\n");
1707  }
1708  }
1709 
1710  if (GNUNET_SYSERR == res)
1711  {
1712  /* store not successful, no need to tell monitors */
1713  GNUNET_free (conv_name);
1715  }
1716  }
1717  GNUNET_free (conv_name);
1718  return ec;
1719 }
GNUNET_ErrorCode
Taler error codes.
@ GNUNET_EC_NAMESTORE_RECORD_DATA_INVALID
Record data invalid.
@ GNUNET_EC_NAMESTORE_LABEL_INVALID
Label invalid or malformed.
@ GNUNET_EC_NAMESTORE_RECORD_NOT_FOUND
Record not found.
@ GNUNET_EC_NAMESTORE_STORE_FAILED
Failed to store the given records.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
static void get_existing_rd_exp(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *private_key, const char *label, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Check if set contains a tombstone, store if necessary.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_label_check(const char *label, char **emsg)
Check label for invalid characters.
@ GNUNET_GNSRECORD_FILTER_NONE
No filter flags set.
#define GNUNET_TIME_absolute_cmp(t1, op, t2)
Compare two absolute times.

Referenced by handle_record_store().

Here is the caller graph for this function:

◆ handle_record_store()

static void handle_record_store ( void *  cls,
const struct RecordStoreMessage rp_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE message.

Parameters
clsclient sending the message
rp_msgmessage of type struct RecordStoreMessage

Definition at line 1728 of file gnunet-service-namestore.c.

1729 {
1731  struct NamestoreClient *nc = cls;
1732  uint32_t rid;
1733  uint16_t rd_set_count;
1734  const char *buf;
1735  ssize_t read;
1736  size_t key_len;
1737  size_t kb_read;
1738  size_t rp_msg_len;
1739  size_t rs_len;
1740  size_t rs_off;
1741  size_t body_len;
1742  struct StoreActivity *sa;
1743  struct RecordSet *rs;
1744  enum GNUNET_ErrorCode res;
1745 
1746  key_len = ntohs (rp_msg->key_len);
1747  rp_msg_len = ntohs (rp_msg->gns_header.header.size);
1748  body_len = rp_msg_len - sizeof (*rp_msg);
1749  rs_off = sizeof (*rp_msg) + key_len;
1750  rs_len = rp_msg_len - rs_off;
1751  if ((GNUNET_SYSERR ==
1753  key_len,
1754  &zone,
1755  &kb_read)) ||
1756  (kb_read != key_len))
1757  {
1759  "Error reading private key\n");
1760  GNUNET_SERVICE_client_drop (nc->client);
1761  return;
1762  }
1764  "Received NAMESTORE_RECORD_STORE message\n");
1765  rid = ntohl (rp_msg->gns_header.r_id);
1766  rd_set_count = ntohs (rp_msg->rd_set_count);
1767  buf = (const char *) rp_msg + rs_off;
1768  for (int i = 0; i < rd_set_count; i++)
1769  {
1770  rs = (struct RecordSet *) buf;
1771  res = store_record_set (nc, &zone,
1772  rs, &read);
1773  if (GNUNET_EC_NONE != res)
1774  {
1775  send_store_response (nc, res, rid);
1777  return;
1778  }
1779  buf += read;
1780  }
1781  sa = GNUNET_malloc (sizeof(struct StoreActivity) + rs_len);
1783  sa->nc = nc;
1784  sa->rs = (struct RecordSet *) &sa[1];
1785  sa->rd_set_count = rd_set_count;
1786  GNUNET_memcpy (&sa[1], (char *) rp_msg + rs_off, rs_len);
1787  sa->rid = rid;
1788  sa->rd_set_pos = 0;
1789  sa->private_key = zone;
1790  sa->zm_pos = monitor_head;
1791  sa->uncommited = nc->in_transaction;
1793 }
static enum GNUNET_ErrorCode store_record_set(struct NamestoreClient *nc, const struct GNUNET_IDENTITY_PrivateKey *private_key, const struct RecordSet *rd_set, ssize_t *len)
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
uint16_t rd_set_count
The number of records in this activity.

References buf, continue_store_activity(), RecordStoreMessage::gns_header, GNUNET_CONTAINER_DLL_insert, GNUNET_EC_NONE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_IDENTITY_read_private_key_from_buffer(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, GNUNET_YES, GNUNET_NAMESTORE_Header::header, RecordStoreMessage::key_len, monitor_head, nc, StoreActivity::nc, StoreActivity::private_key, GNUNET_NAMESTORE_Header::r_id, StoreActivity::rd_set_count, RecordStoreMessage::rd_set_count, StoreActivity::rd_set_pos, res, StoreActivity::rid, StoreActivity::rs, sa_head, sa_tail, send_store_response(), GNUNET_MessageHeader::size, store_record_set(), StoreActivity::uncommited, StoreActivity::zm_pos, and zone.

Here is the call graph for this function:

◆ send_tx_response()

static void send_tx_response ( int  rid,
enum GNUNET_ErrorCode  ec,
struct NamestoreClient nc 
)
static

Definition at line 1796 of file gnunet-service-namestore.c.

1797 {
1798  struct TxControlResultMessage *txr_msg;
1799  struct GNUNET_MQ_Envelope *env;
1800 
1801  env =
1803  txr_msg->gns_header.r_id = rid;
1804  txr_msg->ec = htonl (ec);
1805  GNUNET_MQ_send (nc->mq, env);
1806 }
#define GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT
Return status message for control message.
Result of a transaction control message.
Definition: namestore.h:357
uint32_t ec
Of type GNUNET_ErrorCode.
Definition: namestore.h:366
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT.
Definition: namestore.h:361

References TxControlResultMessage::ec, env, TxControlResultMessage::gns_header, GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_PEERINFO_NotifyContext::mq, nc, and GNUNET_NAMESTORE_Header::r_id.

Referenced by handle_tx_control().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_tx_control()

static void handle_tx_control ( void *  cls,
const struct TxControlMessage tx_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL message.

Parameters
clsclient sending the message
tx_msgmessage of type struct TxControlMessage

Definition at line 1815 of file gnunet-service-namestore.c.

1816 {
1817  struct NamestoreClient *nc = cls;
1818  struct StoreActivity *sa = sa_head;
1819  struct StoreActivity *sn;
1821  char *emsg = NULL;
1822  int blocked = GNUNET_NO;
1823 
1824  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received TX_CONTROL message\n");
1825 
1826  switch (ntohs (tx_msg->control))
1827  {
1829  ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls,
1830  &emsg);
1831  send_tx_response (tx_msg->gns_header.r_id,
1832  (GNUNET_SYSERR == ret) ?
1834  if (GNUNET_SYSERR == ret)
1835  {
1837  "Databse backend error: `%s'", emsg);
1838  GNUNET_free (emsg);
1839  }
1841  nc->in_transaction = GNUNET_YES;
1842  break;
1844  ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls,
1845  &emsg);
1846  send_tx_response (tx_msg->gns_header.r_id,
1847  (GNUNET_SYSERR == ret) ?
1849  nc);
1850  if (GNUNET_SYSERR == ret)
1851  {
1853  "Databse backend error: `%s'", emsg);
1854  GNUNET_free (emsg);
1855  }
1856  if (GNUNET_SYSERR != ret)
1857  {
1858  nc->in_transaction = GNUNET_NO;
1859  while (NULL != sa)
1860  {
1861  if ((nc != sa->nc) ||
1862  (GNUNET_NO == sa->uncommited))
1863  {
1864  sa = sa->next;
1865  continue;
1866  }
1867  sa->uncommited = GNUNET_NO;
1868  sn = sa->next;
1870  blocked = GNUNET_YES;
1871  sa = sn;
1872  }
1873  if (GNUNET_YES != blocked)
1875  }
1876  break;
1878  ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls,
1879  &emsg);
1880  send_tx_response (tx_msg->gns_header.r_id,
1881  (GNUNET_SYSERR == ret) ?
1884  if (GNUNET_SYSERR == ret)
1885  {
1887  "Databse backend error: `%s'", emsg);
1888  GNUNET_free (emsg);
1889  }
1890  if (GNUNET_SYSERR != ret)
1891  {
1892  nc->in_transaction = GNUNET_NO;
1893  while (NULL != sa)
1894  {
1895  if ((nc != sa->nc) ||
1896  (GNUNET_NO == sa->uncommited))
1897  {
1898  sa = sa->next;
1899  continue;
1900  }
1902  "Discarding uncommited StoreActivity\n");
1903  sn = sa->next;
1904  free_store_activity (sa);
1905  sa = sn;
1906  }
1907  }
1908  break;
1909  default:
1911  "Unknown control type %u\n", ntohs (tx_msg->control));
1912  GNUNET_break (0);
1913  }
1914 }
@ GNUNET_EC_NAMESTORE_BACKEND_FAILED
There was an error in the database backend.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static void send_tx_response(int rid, enum GNUNET_ErrorCode ec, struct NamestoreClient *nc)
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_NAMESTORE_TX_COMMIT
@ GNUNET_NAMESTORE_TX_ROLLBACK
@ GNUNET_NAMESTORE_TX_BEGIN
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL.
Definition: namestore.h:339
uint16_t control
The type of control message to send.
Definition: namestore.h:349

References continue_store_activity(), TxControlMessage::control, free_store_activity(), TxControlMessage::gns_header, GNUNET_break, GNUNET_EC_NAMESTORE_BACKEND_FAILED, GNUNET_EC_NONE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_log, GNUNET_NAMESTORE_TX_BEGIN, GNUNET_NAMESTORE_TX_COMMIT, GNUNET_NAMESTORE_TX_ROLLBACK, GNUNET_NO, GNUNET_OK, GNUNET_SERVICE_client_continue(), GNUNET_SYSERR, GNUNET_YES, nc, StoreActivity::nc, StoreActivity::next, GNUNET_NAMESTORE_Header::r_id, ret, sa_head, send_tx_response(), and StoreActivity::uncommited.

Here is the call graph for this function:

◆ handle_zone_to_name_it()

static void handle_zone_to_name_it ( void *  cls,
uint64_t  seq,
const struct GNUNET_IDENTITY_PrivateKey zone_key,
const char *  name,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

Zone to name iterator.

Parameters
clsstruct ZoneToNameCtx *
seqsequence number of the record, MUST NOT BE ZERO
zone_keythe zone key
namename
rd_countnumber of records in rd
rdrecord data

Definition at line 1952 of file gnunet-service-namestore.c.

1958 {
1959  struct ZoneToNameCtx *ztn_ctx = cls;
1960  struct GNUNET_MQ_Envelope *env;
1961  struct ZoneToNameResponseMessage *ztnr_msg;
1962  size_t name_len;
1963  size_t key_len;
1964  ssize_t rd_ser_len;
1965  size_t msg_size;
1966  char *name_tmp;
1967  char *rd_tmp;
1968 
1969  GNUNET_assert (0 != seq);
1971  "Found result for zone-to-name lookup: `%s'\n",
1972  name);
1973  ztn_ctx->ec = GNUNET_EC_NONE;
1974  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1976  if (rd_ser_len < 0)
1977  {
1978  GNUNET_break (0);
1979  ztn_ctx->ec = htonl (GNUNET_EC_NAMESTORE_UNKNOWN);
1980  return;
1981  }
1983  msg_size = sizeof(struct ZoneToNameResponseMessage)
1984  + name_len + rd_ser_len + key_len;
1985  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1986  {
1987  GNUNET_break (0);
1989  return;
1990  }
1991  env =
1992  GNUNET_MQ_msg_extra (ztnr_msg,
1993  key_len + name_len + rd_ser_len,
1995  ztnr_msg->gns_header.header.size = htons (msg_size);
1996  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1997  ztnr_msg->ec = htonl (ztn_ctx->ec);
1998  ztnr_msg->rd_len = htons (rd_ser_len);
1999  ztnr_msg->rd_count = htons (rd_count);
2000  ztnr_msg->name_len = htons (name_len);
2001  ztnr_msg->key_len = htons (key_len);
2003  &ztnr_msg[1],
2004  key_len);
2005  name_tmp = (char *) &ztnr_msg[1] + key_len;
2006  GNUNET_memcpy (name_tmp, name, name_len);
2007  rd_tmp = &name_tmp[name_len];
2008  GNUNET_assert (
2009  rd_ser_len ==
2010  GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
2011  ztn_ctx->ec = GNUNET_EC_NONE;
2012  GNUNET_MQ_send (ztn_ctx->nc->mq, env);
2013 }
@ GNUNET_EC_NAMESTORE_UNKNOWN
Unknown namestore error.
@ GNUNET_EC_NAMESTORE_RECORD_TOO_BIG
Record size exceeds maximum limit.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE
Service to client: result of zone-to-name lookup.
Context for record remove operations passed from handle_zone_to_name to handle_zone_to_name_it as clo...
struct NamestoreClient * nc
Namestore client.
uint32_t rid
Request id (to be used in the response to the client).
enum GNUNET_ErrorCode ec
Set to GNUNET_OK on success, GNUNET_SYSERR on error.
Respone for zone to name lookup.
Definition: namestore.h:246
uint16_t name_len
Length of the name.
Definition: namestore.h:263
int32_t ec
result in NBO: GNUNET_EC_NONE on success, GNUNET_EC_NAMESTORE_NO_RESULTS if there were no results.
Definition: namestore.h:258
uint16_t key_len
Length of the zone key.
Definition: namestore.h:278
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE.
Definition: namestore.h:250
uint16_t rd_count
Number of records contained.
Definition: namestore.h:273
uint16_t rd_len
Length of serialized record data.
Definition: namestore.h:268

Referenced by handle_zone_to_name().

Here is the caller graph for this function:

◆ check_zone_to_name()

◆ handle_zone_to_name()

static void handle_zone_to_name ( void *  cls,
const struct ZoneToNameMessage ztn_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME message.

Parameters
clsclient client sending the message
ztn_msgmessage of type 'struct ZoneToNameMessage'

Definition at line 2030 of file gnunet-service-namestore.c.

2031 {
2033  struct GNUNET_IDENTITY_PublicKey value_zone;
2034  struct NamestoreClient *nc = cls;
2035  struct ZoneToNameCtx ztn_ctx;
2036  struct GNUNET_MQ_Envelope *env;
2037  struct ZoneToNameResponseMessage *ztnr_msg;
2038  size_t key_len;
2039  size_t pkey_len;
2040  size_t kb_read;
2041 
2042  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
2043  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
2044  ztn_ctx.nc = nc;
2046  key_len = ntohs (ztn_msg->key_len);
2047  if ((GNUNET_SYSERR ==
2049  key_len,
2050  &zone,
2051  &kb_read)) ||
2052  (kb_read != key_len))
2053  {
2055  "Error parsing private key.\n");
2056  GNUNET_SERVICE_client_drop (nc->client);
2057  GNUNET_break (0);
2058  return;
2059  }
2060  pkey_len = ntohs (ztn_msg->pkey_len);
2061  if ((GNUNET_SYSERR ==
2062  GNUNET_IDENTITY_read_public_key_from_buffer ((char*) &ztn_msg[1]
2063  + key_len,
2064  pkey_len,
2065  &value_zone,
2066  &kb_read)) ||
2067  (kb_read != pkey_len))
2068  {
2070  "Error parsing public key.\n");
2071  GNUNET_SERVICE_client_drop (nc->client);
2072  GNUNET_break (0);
2073  return;
2074  }
2075  if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
2076  &zone,
2077  &value_zone,
2079  &ztn_ctx))
2080  {
2081  /* internal error, hang up instead of signalling something
2082  that might be wrong */
2083  GNUNET_break (0);
2084  GNUNET_SERVICE_client_drop (nc->client);
2085  return;
2086  }
2087  if (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND == ztn_ctx.ec)
2088  {
2089  /* no result found, send empty response */
2091  "Found no result for zone-to-name lookup.\n");
2092  env = GNUNET_MQ_msg (ztnr_msg,
2094  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
2095  ztnr_msg->ec = htonl (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND);
2096  GNUNET_MQ_send (nc->mq, env);
2097  }
2099 }
@ GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND
Zone not found.
static void handle_zone_to_name_it(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Zone to name iterator.
enum GNUNET_GenericReturnValue GNUNET_IDENTITY_read_public_key_from_buffer(const void *buffer, size_t len, struct GNUNET_IDENTITY_PublicKey *key, size_t *kb_read)
Reads a GNUNET_IDENTITY_PublicKey from a compact buffer.
Definition: identity_api.c:865
uint16_t pkey_len
Length of the public value zone key.
Definition: namestore.h:232
uint16_t key_len
Length of the zone key.
Definition: namestore.h:227
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME.
Definition: namestore.h:222

References ZoneToNameCtx::ec, ZoneToNameResponseMessage::ec, env, ZoneToNameMessage::gns_header, ZoneToNameResponseMessage::gns_header, GNUNET_break, GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND, GNUNET_ERROR_TYPE_DEBUG, GNUNET_IDENTITY_read_private_key_from_buffer(), GNUNET_IDENTITY_read_public_key_from_buffer(), GNUNET_log, GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_TO_NAME_RESPONSE, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, handle_zone_to_name_it(), ZoneToNameMessage::key_len, ZoneToNameResponseMessage::key_len, GNUNET_PEERINFO_NotifyContext::mq, nc, ZoneToNameCtx::nc, ZoneToNameMessage::pkey_len, GNUNET_NAMESTORE_Header::r_id, ZoneToNameCtx::rid, and zone.

Here is the call graph for this function:

◆ zone_iterate_proc()

static void zone_iterate_proc ( void *  cls,
uint64_t  seq,
const struct GNUNET_IDENTITY_PrivateKey zone_key,
const char *  name,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

Process results for zone iteration from database.

Parameters
clsstruct ZoneIterationProcResult
seqsequence number of the record, MUST NOT BE ZERO
zone_keythe zone key
namename
rd_countnumber of records for this name
rdrecord data

Definition at line 2136 of file gnunet-service-namestore.c.

2142 {
2143  struct ZoneIterationProcResult *proc = cls;
2144 
2145  GNUNET_assert (0 != seq);
2146  if ((NULL == zone_key) && (NULL == name))
2147  {
2148  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
2149  return;
2150  }
2151  if ((NULL == zone_key) || (NULL == name))
2152  {
2153  /* what is this!? should never happen */
2154  GNUNET_break (0);
2155  return;
2156  }
2157  if (0 == proc->limit)
2158  {
2159  /* what is this!? should never happen */
2160  GNUNET_break (0);
2161  return;
2162  }
2163  proc->zi->seq = seq;
2164  if (0 < send_lookup_response_with_filter (proc->zi->nc,
2165  proc->zi->request_id,
2166  zone_key,
2167  name,
2168  rd_count,
2169  rd,
2170  proc->zi->filter))
2171  proc->limit--;
2172  else
2173  proc->run_again = GNUNET_YES;
2174 }
Context for record remove operations passed from run_zone_iteration_round to zone_iterate_proc as clo...
struct ZoneIteration * zi
The zone iteration handle.
int run_again
Skip a result and run again unless GNUNET_NO.
uint64_t limit
Number of results left to be returned in this iteration.
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...
enum GNUNET_GNSRECORD_Filter filter
The record set filter.

References ZoneIteration::filter, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_YES, ZoneIterationProcResult::limit, name, ZoneIteration::nc, rd, rd_count, ZoneIteration::request_id, ZoneIterationProcResult::run_again, send_lookup_response_with_filter(), ZoneIteration::seq, ZoneIterationProcResult::zi, and zone_key.

Referenced by check_iteration_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ run_zone_iteration_round()

static void run_zone_iteration_round ( struct ZoneIteration zi,
uint64_t  limit 
)
static

Perform the next round of the zone iteration.

Parameters
zizone iterator to process
limitnumber of results to return in one pass

Definition at line 2184 of file gnunet-service-namestore.c.

2185 {
2186  struct ZoneIterationProcResult proc;
2187  struct GNUNET_TIME_Absolute start;
2189  struct NamestoreClient *nc = zi->nc;
2190 
2191  memset (&proc, 0, sizeof(proc));
2193  "Asked to return up to %llu records at position %llu\n",
2194  (unsigned long long) limit,
2195  (unsigned long long) zi->seq);
2196  proc.zi = zi;
2197  proc.limit = limit;
2198  proc.run_again = GNUNET_YES;
2200  while (GNUNET_YES == proc.run_again)
2201  {
2202  proc.run_again = GNUNET_NO;
2204  nc->GSN_database->iterate_records (nc->GSN_database->cls,
2205  (GNUNET_YES ==
2206  GNUNET_is_zero (
2207  &zi->zone))
2208  ? NULL
2209  : &zi->zone,
2210  zi->seq,
2211  proc.limit,
2213  &proc));
2214  }
2216  duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit);
2218  "NAMESTORE iteration delay (μs/record)",
2220  GNUNET_NO);
2221  if (0 == proc.limit)
2223  "Returned %llu results, more results available\n",
2224  (unsigned long long) limit);
2225  zi->send_end = (0 != proc.limit);
2226  if (0 == zi->cache_ops)
2228 }
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static struct GNUNET_TIME_Relative duration
How long do we run the test?
static void zone_iteration_done_client_continue(struct ZoneIteration *zi)
Function called once we are done with the zone iteration and allow the zone iteration client to send ...
static void zone_iterate_proc(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Process results for zone iteration from database.
#define GNUNET_is_zero(a)
Check that memory in a is all zeros.
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:436
struct GNUNET_TIME_Relative GNUNET_TIME_relative_divide(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Divide relative time by a given factor.
Definition: time.c:550
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
struct GNUNET_IDENTITY_PrivateKey zone
Key of the zone we are iterating over.
unsigned int cache_ops
Number of pending cache operations triggered by this zone iteration which we need to wait for before ...

Referenced by handle_iteration_next(), and handle_iteration_start().

Here is the caller graph for this function:

◆ check_iteration_start()

static enum GNUNET_GenericReturnValue check_iteration_start ( void *  cls,
const struct ZoneIterationStartMessage zis_msg 
)
static

Definition at line 2184 of file gnunet-service-namestore.c.

2233 {
2234  uint16_t size;
2235  size_t key_len;
2236 
2237  size = ntohs (zis_msg->gns_header.header.size);
2238  key_len = ntohs (zis_msg->key_len);
2239 
2240  if (size < key_len + sizeof(*zis_msg))
2241  {
2242  GNUNET_break (0);
2243  return GNUNET_SYSERR;
2244  }
2245  return GNUNET_OK;
2246 }
static unsigned int size
Size of the "table".
Definition: peer.c:68
uint16_t key_len
Length of the zone key.
Definition: namestore.h:448
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START.
Definition: namestore.h:437

References ZoneIteration::cache_ops, duration, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_is_zero, GNUNET_log, GNUNET_NO, GNUNET_STATISTICS_set(), GNUNET_SYSERR, GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_relative_divide(), GNUNET_YES, ZoneIterationProcResult::limit, nc, ZoneIteration::nc, GNUNET_TIME_Relative::rel_value_us, ZoneIterationProcResult::run_again, ZoneIteration::send_end, ZoneIteration::seq, start, statistics, ZoneIterationProcResult::zi, ZoneIteration::zone, zone_iterate_proc(), and zone_iteration_done_client_continue().

Here is the call graph for this function:

◆ handle_iteration_start()

static void handle_iteration_start ( void *  cls,
const struct ZoneIterationStartMessage zis_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_START message.

Parameters
clsthe client sending the message
zis_msgmessage from the client

Definition at line 2256 of file gnunet-service-namestore.c.

2258 {
2260  struct NamestoreClient *nc = cls;
2261  struct ZoneIteration *zi;
2262  size_t key_len;
2263  size_t kb_read;
2264 
2266  "Received ZONE_ITERATION_START message\n");
2267  key_len = ntohs (zis_msg->key_len);
2268  zi = GNUNET_new (struct ZoneIteration);
2269  if (0 < key_len)
2270  {
2271  if ((GNUNET_SYSERR ==
2273  key_len,
2274  &zone,
2275  &kb_read)) ||
2276  (kb_read != key_len))
2277  {
2278  GNUNET_SERVICE_client_drop (nc->client);
2279  GNUNET_free (zi);
2280  return;
2281  }
2282  zi->zone = zone;
2283  }
2284  zi->request_id = ntohl (zis_msg->gns_header.r_id);
2285  zi->filter = ntohs (zis_msg->filter);
2286  zi->offset = 0;
2287  zi->nc = nc;
2288  GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
2289  run_zone_iteration_round (zi, 1);
2290 }
static void run_zone_iteration_round(struct ZoneIteration *zi, uint64_t limit)
Perform the next round of the zone iteration.
uint16_t filter
Record set filter control flags.
Definition: namestore.h:443
uint32_t offset
Offset of the zone iteration used to address next result of the zone iteration in the store.

References ZoneIteration::filter, ZoneIterationStartMessage::filter, ZoneIterationStartMessage::gns_header, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_IDENTITY_read_private_key_from_buffer(), GNUNET_log, GNUNET_new, GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, ZoneIterationStartMessage::key_len, nc, ZoneIteration::nc, ZoneIteration::offset, GNUNET_NAMESTORE_Header::r_id, ZoneIteration::request_id, run_zone_iteration_round(), zone, and ZoneIteration::zone.

Here is the call graph for this function:

◆ handle_iteration_stop()

static void handle_iteration_stop ( void *  cls,
const struct ZoneIterationStopMessage zis_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP message.

Parameters
clsthe client sending the message
zis_msgmessage from the client

Definition at line 2300 of file gnunet-service-namestore.c.

2302 {
2303  struct NamestoreClient *nc = cls;
2304  struct ZoneIteration *zi;
2305  uint32_t rid;
2306 
2308  "Received ZONE_ITERATION_STOP message\n");
2309  rid = ntohl (zis_msg->gns_header.r_id);
2310  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2311  if (zi->request_id == rid)
2312  break;
2313  if (NULL == zi)
2314  {
2315  GNUNET_break (0);
2316  GNUNET_SERVICE_client_drop (nc->client);
2317  return;
2318  }
2319  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
2320  GNUNET_free (zi);
2322 }
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_STOP.
Definition: namestore.h:483
struct ZoneIteration * next
Next element in the DLL.

References ZoneIterationStopMessage::gns_header, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_log, GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), nc, ZoneIteration::next, GNUNET_NAMESTORE_Header::r_id, and ZoneIteration::request_id.

Here is the call graph for this function:

◆ handle_iteration_next()

static void handle_iteration_next ( void *  cls,
const struct ZoneIterationNextMessage zis_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT message.

Parameters
clsthe client sending the message
zis_msgmessage from the client

Definition at line 2332 of file gnunet-service-namestore.c.

2334 {
2335  struct NamestoreClient *nc = cls;
2336  struct ZoneIteration *zi;
2337  uint32_t rid;
2338  uint64_t limit;
2339 
2341  "Received ZONE_ITERATION_NEXT message\n");
2343  "Iteration NEXT messages received",
2344  1,
2345  GNUNET_NO);
2346  rid = ntohl (zis_msg->gns_header.r_id);
2347  limit = GNUNET_ntohll (zis_msg->limit);
2348  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2349  if (zi->request_id == rid)
2350  break;
2351  if (NULL == zi)
2352  {
2353  GNUNET_break (0);
2354  GNUNET_SERVICE_client_drop (nc->client);
2355  return;
2356  }
2357  run_zone_iteration_round (zi, limit);
2358 }
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
struct GNUNET_NAMESTORE_Header gns_header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_ITERATION_NEXT.
Definition: namestore.h:464
uint64_t limit
Number of records to return to the iterator in one shot (before GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_IT...
Definition: namestore.h:471

References ZoneIterationNextMessage::gns_header, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_ntohll(), GNUNET_SERVICE_client_drop(), GNUNET_STATISTICS_update(), ZoneIterationNextMessage::limit, nc, ZoneIteration::next, GNUNET_NAMESTORE_Header::r_id, ZoneIteration::request_id, run_zone_iteration_round(), and statistics.

Here is the call graph for this function:

◆ monitor_unblock()

static void monitor_unblock ( struct ZoneMonitor zm)
static

Function called when the monitor is ready for more data, and we should thus unblock PUT operations that were blocked on the monitor not being ready.

Definition at line 2367 of file gnunet-service-namestore.c.

2368 {
2369  struct StoreActivity *sa = sa_head;
2370 
2372  "Unblocking zone monitor %p\n", zm);
2373  while ((NULL != sa) && (zm->limit > zm->iteration_cnt))
2374  {
2375  struct StoreActivity *sn = sa->next;
2376 
2377  if (sa->zm_pos == zm)
2379  sa = sn;
2380  }
2381  if (zm->limit > zm->iteration_cnt)
2382  {
2383  zm->sa_waiting = GNUNET_NO;
2384  if (NULL != zm->sa_wait_warning)
2385  {
2386  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2387  zm->sa_wait_warning = NULL;
2388  }
2389  }
2390  else if (GNUNET_YES == zm->sa_waiting)
2391  {
2392  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2393  if (NULL != zm->sa_wait_warning)
2394  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2395  zm->sa_wait_warning =
2398  zm);
2399  }
2400 }

References continue_store_activity(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_TIME_absolute_get(), GNUNET_YES, MONITOR_STALL_WARN_DELAY, StoreActivity::next, sa_head, warn_monitor_slow(), zm, and StoreActivity::zm_pos.

Referenced by handle_monitor_next(), and monitor_sync().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ monitor_sync()

static void monitor_sync ( struct ZoneMonitor zm)
static

Send 'sync' message to zone monitor, we're now in sync.

Parameters
zmmonitor that is now in sync

Definition at line 2409 of file gnunet-service-namestore.c.

2410 {
2411  struct GNUNET_MQ_Envelope *env;
2412  struct GNUNET_MessageHeader *sync;
2414  "Synching zone monitor %p\n", zm);
2415 
2417  GNUNET_MQ_send (zm->nc->mq, env);
2418  /* mark iteration done */
2419  zm->in_first_iteration = GNUNET_NO;
2420  zm->iteration_cnt = 0;
2421  if ((zm->limit > 0) && (zm->sa_waiting))
2422  monitor_unblock (zm);
2423 }
static void monitor_unblock(struct ZoneMonitor *zm)
Function called when the monitor is ready for more data, and we should thus unblock PUT operations th...
#define GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC
Service to client: you're now in sync.
Header for all communications.
struct GNUNET_MQ_Handle * mq
Handle to namestore service.

References env, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, monitor_unblock(), GNUNET_NAMESTORE_ZoneMonitor::mq, and zm.

Referenced by handle_monitor_start(), and monitor_iteration_next().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ monitor_iteration_next()

static void monitor_iteration_next ( void *  cls)
static

Obtain the next datum during the zone monitor's zone initial iteration.

Parameters
clszone monitor that does its initial iteration

Definition at line 2558 of file gnunet-service-namestore.c.

2559 {
2560  struct ZoneMonitor *zm = cls;
2561  struct NamestoreClient *nc = zm->nc;
2562  int ret;
2563 
2564  zm->task = NULL;
2565  GNUNET_assert (0 == zm->iteration_cnt);
2566  if (zm->limit > 16)
2567  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2568  else
2569  zm->iteration_cnt = zm->limit; /* use it all */
2570  zm->run_again = GNUNET_YES;
2571  while (GNUNET_YES == zm->run_again)
2572  {
2574  "Running iteration\n");
2575  zm->run_again = GNUNET_NO;
2576  ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
2578  &zm->zone)) ? NULL : &zm->zone,
2579  zm->seq,
2580  zm->iteration_cnt,
2582  zm);
2583  }
2584  if (GNUNET_SYSERR == ret)
2585  {
2586  GNUNET_SERVICE_client_drop (zm->nc->client);
2587  return;
2588  }
2589  if (GNUNET_NO == ret)
2590  {
2592  "Zone empty... syncing\n");
2593  /* empty zone */
2594  monitor_sync (zm);
2595  return;
2596  }
2597 }
static void monitor_sync(struct ZoneMonitor *zm)
Send 'sync' message to zone monitor, we're now in sync.
static void monitor_iterate_cb(void *cls, uint64_t seq, const struct GNUNET_IDENTITY_PrivateKey *zone_key, const char *name, unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
A GNUNET_NAMESTORE_RecordIterator for monitors.

References GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_is_zero, GNUNET_log, GNUNET_NO, GNUNET_SERVICE_client_drop(), GNUNET_SYSERR, GNUNET_YES, monitor_iterate_cb(), monitor_sync(), nc, ret, zm, and GNUNET_NAMESTORE_ZoneMonitor::zone.

Referenced by check_monitor_start(), handle_monitor_next(), and handle_monitor_start().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ monitor_iterate_cb()

static void monitor_iterate_cb ( void *  cls,
uint64_t  seq,
const struct GNUNET_IDENTITY_PrivateKey zone_key,
const char *  name,
unsigned int  rd_count,
const struct GNUNET_GNSRECORD_Data rd 
)
static

A GNUNET_NAMESTORE_RecordIterator for monitors.

Parameters
clsa 'struct ZoneMonitor *' with information about the monitor
seqsequence number of the record, MUST NOT BE ZERO
zone_keyzone key of the zone
namename
rd_countnumber of records in rd
rdarray of records

Definition at line 2446 of file gnunet-service-namestore.c.

2452 {
2453  struct ZoneMonitor *zm = cls;
2454 
2455  GNUNET_assert (0 != seq);
2456  zm->seq = seq;
2457  GNUNET_assert (NULL != name);
2459  "Monitor notifications sent",
2460  1,
2461  GNUNET_NO);
2463  rd_count, rd, zm->filter))
2464  {
2466  "Sent records.\n");
2467  zm->limit--;
2468  zm->iteration_cnt--;
2469  }
2470  else
2471  zm->run_again = GNUNET_YES;
2472  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2473  {
2474  /* We are done with the current iteration batch, AND the
2475  client would right now accept more, so go again! */
2476  GNUNET_assert (NULL == zm->task);
2478  }
2479 }
static void monitor_iteration_next(void *cls)
Obtain the next datum during the zone monitor's zone initial iteration.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1268
uint64_t seq
Last sequence number in the zone iteration used to address next result of the zone iteration in the s...

Referenced by monitor_iteration_next().

Here is the caller graph for this function:

◆ check_monitor_start()

static enum GNUNET_GenericReturnValue check_monitor_start ( void *  cls,
const struct ZoneMonitorStartMessage zis_msg 
)
static

Definition at line 2446 of file gnunet-service-namestore.c.

2484 {
2485  uint16_t size;
2486  size_t key_len;
2487 
2488  size = ntohs (zis_msg->header.size);
2489  key_len = ntohs (zis_msg->key_len);
2490 
2491  if (size < key_len + sizeof(*zis_msg))
2492  {
2493  GNUNET_break (0);
2494  return GNUNET_SYSERR;
2495  }
2496  return GNUNET_OK;
2497 }
uint16_t key_len
Length of the zone key.
Definition: namestore.h:397
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START.
Definition: namestore.h:380

References GNUNET_NAMESTORE_ZoneMonitor::filter, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_now(), GNUNET_STATISTICS_update(), GNUNET_YES, monitor_iteration_next(), name, rd, rd_count, send_lookup_response_with_filter(), ZoneMonitor::seq, statistics, zm, and zone_key.

Here is the call graph for this function:

◆ handle_monitor_start()

static void handle_monitor_start ( void *  cls,
const struct ZoneMonitorStartMessage zis_msg 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_START message.

Parameters
clsthe client sending the message
zis_msgmessage from the client

Definition at line 2507 of file gnunet-service-namestore.c.

2509 {
2511  struct NamestoreClient *nc = cls;
2512  struct ZoneMonitor *zm;
2513  size_t key_len;
2514  size_t kb_read;
2515 
2517  "Received ZONE_MONITOR_START message\n");
2518  zm = GNUNET_new (struct ZoneMonitor);
2519  zm->nc = nc;
2520  key_len = ntohs (zis_msg->key_len);
2521  if (0 < key_len)
2522  {
2523  if ((GNUNET_SYSERR ==
2525  key_len,
2526  &zone,
2527  &kb_read)) ||
2528  (kb_read != key_len))
2529  {
2531  "Error reading private key\n");
2532  GNUNET_SERVICE_client_drop (nc->client);
2533  GNUNET_free (zm);
2534  return;
2535  }
2536  zm->zone = zone;
2537  }
2538  zm->limit = 1;
2539  zm->filter = ntohs (zis_msg->filter);
2540  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2545  if (zm->in_first_iteration)
2547  else
2548  monitor_sync (zm);
2549 }
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:161
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the 'monitor' flag on this client.
Definition: service.c:2413
uint32_t iterate_first
GNUNET_YES to first iterate over all records, GNUNET_NO to only monitor changes.o
Definition: namestore.h:386
uint16_t filter
Record set filter control flags.
Definition: namestore.h:392

References ZoneMonitorStartMessage::filter, GNUNET_NAMESTORE_ZoneMonitor::filter, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_IDENTITY_read_private_key_from_buffer(), GNUNET_log, GNUNET_new, GNUNET_notification_context_add(), GNUNET_SCHEDULER_add_now(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_SERVICE_client_mark_monitor(), GNUNET_SYSERR, GNUNET_YES, ZoneMonitorStartMessage::iterate_first, ZoneMonitorStartMessage::key_len, monitor_head, monitor_iteration_next(), monitor_nc, monitor_sync(), monitor_tail, GNUNET_PEERINFO_NotifyContext::mq, nc, zm, zone, and GNUNET_NAMESTORE_ZoneMonitor::zone.

Here is the call graph for this function:

◆ handle_monitor_next()

static void handle_monitor_next ( void *  cls,
const struct ZoneMonitorNextMessage nm 
)
static

Handles a GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_NEXT message.

Parameters
clsthe client sending the message
nmmessage from the client

Definition at line 2606 of file gnunet-service-namestore.c.

2607 {
2608  struct NamestoreClient *nc = cls;
2609  struct ZoneMonitor *zm;
2610  uint64_t inc;
2611 
2612  inc = GNUNET_ntohll (nm->limit);
2614  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2615  (unsigned long long) inc);
2616  for (zm = monitor_head; NULL != zm; zm = zm->next)
2617  if (zm->nc == nc)
2618  break;
2619  if (NULL == zm)
2620  {
2621  GNUNET_break (0);
2622  GNUNET_SERVICE_client_drop (nc->client);
2623  return;
2624  }
2626  if (zm->limit + inc < zm->limit)
2627  {
2628  GNUNET_break (0);
2629  GNUNET_SERVICE_client_drop (nc->client);
2630  return;
2631  }
2632  zm->limit += inc;
2633  if ((zm->in_first_iteration) && (zm->limit == inc))
2634  {
2635  /* We are still iterating, and the previous iteration must
2636  have stopped due to the client's limit, so continue it! */
2637  GNUNET_assert (NULL == zm->task);
2639  }
2640  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2641  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2642  {
2643  monitor_unblock (zm);
2644  }
2645  else if (GNUNET_YES == zm->sa_waiting)
2646  {
2647  if (NULL != zm->sa_wait_warning)
2648  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2649  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2650  zm->sa_wait_warning =
2653  zm);
2654  }
2655 }
uint64_t limit
Number of records to return to the iterator in one shot (before #GNUNET_MESSAGE_TYPE_NAMESTORE_ZONE_M...
Definition: namestore.h:425
uint64_t limit
Current limit of how many more messages we are allowed to queue to this monitor.

References GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_ntohll(), GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_drop(), GNUNET_TIME_absolute_get(), GNUNET_YES, ZoneMonitor::limit, ZoneMonitorNextMessage::limit, monitor_head, monitor_iteration_next(), MONITOR_STALL_WARN_DELAY, monitor_unblock(), nc, warn_monitor_slow(), and zm.

Here is the call graph for this function:

◆ run()

static void run ( void *  cls,
const struct GNUNET_CONFIGURATION_Handle cfg,
struct GNUNET_SERVICE_Handle service 
)
static

Process namestore requests.

Parameters
clsclosure
cfgconfiguration to use
servicethe initialized service

Definition at line 2665 of file gnunet-service-namestore.c.

2668 {
2669  char *database;
2670  (void) cls;
2671  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2673  "namestore",
2674  "RETURN_ORPHANED");
2675  GSN_cfg = cfg;
2677  statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2678  /* Loading database plugin */
2680  "namestore",
2681  "database",
2682  &database))
2683  {
2684  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2686  return;
2687  }
2688  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2689  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading %s\n", db_lib_name);
2691  GNUNET_free (database);
2692  if (NULL == GSN_database)
2693  {
2695  "Could not load database backend `%s'\n",
2696  db_lib_name);
2699  return;
2700  }
2702 }
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
static int return_orphaned
Returned orphaned records?
static void cleanup_task(void *cls)
Task run during shutdown.
enum GNUNET_GenericReturnValue GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:122
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received,...
Definition: scheduler.c:1303
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.

References cfg, cleanup_task(), db_lib_name, GNUNET_asprintf(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_log, GNUNET_notification_context_create(), GNUNET_OK, GNUNET_PLUGIN_load(), GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_add_shutdown(), GNUNET_STATISTICS_create(), GSN_cfg, GSN_database, monitor_nc, return_orphaned, and statistics.

Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

Variable Documentation

◆ nick_cache

struct NickCache nick_cache[16]
static

We cache nick records to reduce DB load.

Definition at line 1 of file gnunet-service-namestore.c.

Referenced by cache_nick(), and get_nick_record().

◆ zero

◆ GSN_cfg

const struct GNUNET_CONFIGURATION_Handle* GSN_cfg
static

Configuration handle.

Definition at line 355 of file gnunet-service-namestore.c.

Referenced by client_connect_cb(), and run().

◆ statistics

◆ db_lib_name

char* db_lib_name
static

Name of the database plugin.

Definition at line 365 of file gnunet-service-namestore.c.

Referenced by cleanup_task(), client_connect_cb(), and run().

◆ GSN_database

struct GNUNET_NAMESTORE_PluginFunctions* GSN_database

Database handle for service.

Definition at line 370 of file gnunet-service-namestore.c.

Referenced by cleanup_task(), get_nick_record(), and run().

◆ monitor_head

struct ZoneMonitor* monitor_head
static

First active zone monitor.

Definition at line 376 of file gnunet-service-namestore.c.

Referenced by client_disconnect_cb(), handle_monitor_next(), handle_monitor_start(), and handle_record_store().

◆ monitor_tail

struct ZoneMonitor* monitor_tail
static

Last active zone monitor.

Definition at line 381 of file gnunet-service-namestore.c.

Referenced by client_disconnect_cb(), and handle_monitor_start().

◆ sa_head

struct StoreActivity* sa_head
static

Head of DLL of monitor-blocked store activities.

Definition at line 386 of file gnunet-service-namestore.c.

Referenced by client_disconnect_cb(), free_store_activity(), handle_record_store(), handle_tx_control(), and monitor_unblock().

◆ sa_tail

struct StoreActivity* sa_tail
static

Tail of DLL of monitor-blocked store activities.

Definition at line 391 of file gnunet-service-namestore.c.

Referenced by free_store_activity(), and handle_record_store().

◆ monitor_nc

struct GNUNET_NotificationContext* monitor_nc
static

Notification context shared by all monitors.

Definition at line 396 of file gnunet-service-namestore.c.

Referenced by cleanup_task(), handle_monitor_start(), and run().

◆ return_orphaned

int return_orphaned
static

Returned orphaned records?

Definition at line 401 of file gnunet-service-namestore.c.

Referenced by run().