GNUnet  0.20.0
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 zone nickname.
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:63
#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:78
#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:1272
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:975
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  struct StoreActivity *sa;
1742  struct RecordSet *rs;
1743  enum GNUNET_ErrorCode res;
1744 
1745  key_len = ntohs (rp_msg->key_len);
1746  rp_msg_len = ntohs (rp_msg->gns_header.header.size);
1747  rs_off = sizeof (*rp_msg) + key_len;
1748  rs_len = rp_msg_len - rs_off;
1749  if ((GNUNET_SYSERR ==
1751  key_len,
1752  &zone,
1753  &kb_read)) ||
1754  (kb_read != key_len))
1755  {
1757  "Error reading private key\n");
1758  GNUNET_SERVICE_client_drop (nc->client);
1759  return;
1760  }
1762  "Received NAMESTORE_RECORD_STORE message\n");
1763  rid = ntohl (rp_msg->gns_header.r_id);
1764  rd_set_count = ntohs (rp_msg->rd_set_count);
1765  buf = (const char *) rp_msg + rs_off;
1766  for (int i = 0; i < rd_set_count; i++)
1767  {
1768  rs = (struct RecordSet *) buf;
1769  res = store_record_set (nc, &zone,
1770  rs, &read);
1771  if (GNUNET_EC_NONE != res)
1772  {
1773  send_store_response (nc, res, rid);
1775  return;
1776  }
1777  buf += read;
1778  }
1779  sa = GNUNET_malloc (sizeof(struct StoreActivity) + rs_len);
1781  sa->nc = nc;
1782  sa->rs = (struct RecordSet *) &sa[1];
1783  sa->rd_set_count = rd_set_count;
1784  GNUNET_memcpy (&sa[1], (char *) rp_msg + rs_off, rs_len);
1785  sa->rid = rid;
1786  sa->rd_set_pos = 0;
1787  sa->private_key = zone;
1788  sa->zm_pos = monitor_head;
1789  sa->uncommited = nc->in_transaction;
1791 }
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 1794 of file gnunet-service-namestore.c.

1795 {
1796  struct TxControlResultMessage *txr_msg;
1797  struct GNUNET_MQ_Envelope *env;
1798 
1799  env =
1801  txr_msg->gns_header.r_id = rid;
1802  txr_msg->ec = htonl (ec);
1803  GNUNET_MQ_send (nc->mq, env);
1804 }
#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 1813 of file gnunet-service-namestore.c.

1814 {
1815  struct NamestoreClient *nc = cls;
1816  struct StoreActivity *sa = sa_head;
1817  struct StoreActivity *sn;
1819  char *emsg = NULL;
1820  int blocked = GNUNET_NO;
1821 
1822  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received TX_CONTROL message\n");
1823 
1824  switch (ntohs (tx_msg->control))
1825  {
1827  ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls,
1828  &emsg);
1829  send_tx_response (tx_msg->gns_header.r_id,
1830  (GNUNET_SYSERR == ret) ?
1832  if (GNUNET_SYSERR == ret)
1833  {
1835  "Databse backend error: `%s'", emsg);
1836  GNUNET_free (emsg);
1837  }
1839  nc->in_transaction = GNUNET_YES;
1840  break;
1842  ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls,
1843  &emsg);
1844  send_tx_response (tx_msg->gns_header.r_id,
1845  (GNUNET_SYSERR == ret) ?
1847  nc);
1848  if (GNUNET_SYSERR == ret)
1849  {
1851  "Databse backend error: `%s'", emsg);
1852  GNUNET_free (emsg);
1853  }
1854  if (GNUNET_SYSERR != ret)
1855  {
1856  nc->in_transaction = GNUNET_NO;
1857  while (NULL != sa)
1858  {
1859  if ((nc != sa->nc) ||
1860  (GNUNET_NO == sa->uncommited))
1861  {
1862  sa = sa->next;
1863  continue;
1864  }
1865  sa->uncommited = GNUNET_NO;
1866  sn = sa->next;
1868  blocked = GNUNET_YES;
1869  sa = sn;
1870  }
1871  if (GNUNET_YES != blocked)
1873  }
1874  break;
1876  ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls,
1877  &emsg);
1878  send_tx_response (tx_msg->gns_header.r_id,
1879  (GNUNET_SYSERR == ret) ?
1882  if (GNUNET_SYSERR == ret)
1883  {
1885  "Databse backend error: `%s'", emsg);
1886  GNUNET_free (emsg);
1887  }
1888  if (GNUNET_SYSERR != ret)
1889  {
1890  nc->in_transaction = GNUNET_NO;
1891  while (NULL != sa)
1892  {
1893  if ((nc != sa->nc) ||
1894  (GNUNET_NO == sa->uncommited))
1895  {
1896  sa = sa->next;
1897  continue;
1898  }
1900  "Discarding uncommited StoreActivity\n");
1901  sn = sa->next;
1902  free_store_activity (sa);
1903  sa = sn;
1904  }
1905  }
1906  break;
1907  default:
1909  "Unknown control type %u\n", ntohs (tx_msg->control));
1910  GNUNET_break (0);
1911  }
1912 }
@ 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 1950 of file gnunet-service-namestore.c.

1956 {
1957  struct ZoneToNameCtx *ztn_ctx = cls;
1958  struct GNUNET_MQ_Envelope *env;
1959  struct ZoneToNameResponseMessage *ztnr_msg;
1960  size_t name_len;
1961  size_t key_len;
1962  ssize_t rd_ser_len;
1963  size_t msg_size;
1964  char *name_tmp;
1965  char *rd_tmp;
1966 
1967  GNUNET_assert (0 != seq);
1969  "Found result for zone-to-name lookup: `%s'\n",
1970  name);
1971  ztn_ctx->ec = GNUNET_EC_NONE;
1972  name_len = (NULL == name) ? 0 : strlen (name) + 1;
1974  if (rd_ser_len < 0)
1975  {
1976  GNUNET_break (0);
1977  ztn_ctx->ec = htonl (GNUNET_EC_NAMESTORE_UNKNOWN);
1978  return;
1979  }
1981  msg_size = sizeof(struct ZoneToNameResponseMessage)
1982  + name_len + rd_ser_len + key_len;
1983  if (msg_size >= GNUNET_MAX_MESSAGE_SIZE)
1984  {
1985  GNUNET_break (0);
1987  return;
1988  }
1989  env =
1990  GNUNET_MQ_msg_extra (ztnr_msg,
1991  key_len + name_len + rd_ser_len,
1993  ztnr_msg->gns_header.header.size = htons (msg_size);
1994  ztnr_msg->gns_header.r_id = htonl (ztn_ctx->rid);
1995  ztnr_msg->ec = htonl (ztn_ctx->ec);
1996  ztnr_msg->rd_len = htons (rd_ser_len);
1997  ztnr_msg->rd_count = htons (rd_count);
1998  ztnr_msg->name_len = htons (name_len);
1999  ztnr_msg->key_len = htons (key_len);
2001  &ztnr_msg[1],
2002  key_len);
2003  name_tmp = (char *) &ztnr_msg[1] + key_len;
2004  GNUNET_memcpy (name_tmp, name, name_len);
2005  rd_tmp = &name_tmp[name_len];
2006  GNUNET_assert (
2007  rd_ser_len ==
2008  GNUNET_GNSRECORD_records_serialize (rd_count, rd, rd_ser_len, rd_tmp));
2009  ztn_ctx->ec = GNUNET_EC_NONE;
2010  GNUNET_MQ_send (ztn_ctx->nc->mq, env);
2011 }
@ 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 2028 of file gnunet-service-namestore.c.

2029 {
2031  struct GNUNET_IDENTITY_PublicKey value_zone;
2032  struct NamestoreClient *nc = cls;
2033  struct ZoneToNameCtx ztn_ctx;
2034  struct GNUNET_MQ_Envelope *env;
2035  struct ZoneToNameResponseMessage *ztnr_msg;
2036  size_t key_len;
2037  size_t pkey_len;
2038  size_t kb_read;
2039 
2040  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received ZONE_TO_NAME message\n");
2041  ztn_ctx.rid = ntohl (ztn_msg->gns_header.r_id);
2042  ztn_ctx.nc = nc;
2044  key_len = ntohs (ztn_msg->key_len);
2045  if ((GNUNET_SYSERR ==
2047  key_len,
2048  &zone,
2049  &kb_read)) ||
2050  (kb_read != key_len))
2051  {
2053  "Error parsing private key.\n");
2054  GNUNET_SERVICE_client_drop (nc->client);
2055  GNUNET_break (0);
2056  return;
2057  }
2058  pkey_len = ntohs (ztn_msg->pkey_len);
2059  if ((GNUNET_SYSERR ==
2060  GNUNET_IDENTITY_read_public_key_from_buffer ((char*) &ztn_msg[1]
2061  + key_len,
2062  pkey_len,
2063  &value_zone,
2064  &kb_read)) ||
2065  (kb_read != pkey_len))
2066  {
2068  "Error parsing public key.\n");
2069  GNUNET_SERVICE_client_drop (nc->client);
2070  GNUNET_break (0);
2071  return;
2072  }
2073  if (GNUNET_SYSERR == nc->GSN_database->zone_to_name (nc->GSN_database->cls,
2074  &zone,
2075  &value_zone,
2077  &ztn_ctx))
2078  {
2079  /* internal error, hang up instead of signalling something
2080  that might be wrong */
2081  GNUNET_break (0);
2082  GNUNET_SERVICE_client_drop (nc->client);
2083  return;
2084  }
2085  if (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND == ztn_ctx.ec)
2086  {
2087  /* no result found, send empty response */
2089  "Found no result for zone-to-name lookup.\n");
2090  env = GNUNET_MQ_msg (ztnr_msg,
2092  ztnr_msg->gns_header.r_id = ztn_msg->gns_header.r_id;
2093  ztnr_msg->ec = htonl (GNUNET_EC_NAMESTORE_ZONE_NOT_FOUND);
2094  GNUNET_MQ_send (nc->mq, env);
2095  }
2097 }
@ 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 2134 of file gnunet-service-namestore.c.

2140 {
2141  struct ZoneIterationProcResult *proc = cls;
2142 
2143  GNUNET_assert (0 != seq);
2144  if ((NULL == zone_key) && (NULL == name))
2145  {
2146  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Iteration done\n");
2147  return;
2148  }
2149  if ((NULL == zone_key) || (NULL == name))
2150  {
2151  /* what is this!? should never happen */
2152  GNUNET_break (0);
2153  return;
2154  }
2155  if (0 == proc->limit)
2156  {
2157  /* what is this!? should never happen */
2158  GNUNET_break (0);
2159  return;
2160  }
2161  proc->zi->seq = seq;
2162  if (0 < send_lookup_response_with_filter (proc->zi->nc,
2163  proc->zi->request_id,
2164  zone_key,
2165  name,
2166  rd_count,
2167  rd,
2168  proc->zi->filter))
2169  proc->limit--;
2170  else
2171  proc->run_again = GNUNET_YES;
2172 }
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 2182 of file gnunet-service-namestore.c.

2183 {
2184  struct ZoneIterationProcResult proc;
2185  struct GNUNET_TIME_Absolute start;
2187  struct NamestoreClient *nc = zi->nc;
2188 
2189  memset (&proc, 0, sizeof(proc));
2191  "Asked to return up to %llu records at position %llu\n",
2192  (unsigned long long) limit,
2193  (unsigned long long) zi->seq);
2194  proc.zi = zi;
2195  proc.limit = limit;
2196  proc.run_again = GNUNET_YES;
2198  while (GNUNET_YES == proc.run_again)
2199  {
2200  proc.run_again = GNUNET_NO;
2202  nc->GSN_database->iterate_records (nc->GSN_database->cls,
2203  (GNUNET_YES ==
2204  GNUNET_is_zero (
2205  &zi->zone))
2206  ? NULL
2207  : &zi->zone,
2208  zi->seq,
2209  proc.limit,
2211  &proc));
2212  }
2214  duration = GNUNET_TIME_relative_divide (duration, limit - proc.limit);
2216  "NAMESTORE iteration delay (μs/record)",
2218  GNUNET_NO);
2219  if (0 == proc.limit)
2221  "Returned %llu results, more results available\n",
2222  (unsigned long long) limit);
2223  zi->send_end = (0 != proc.limit);
2224  if (0 == zi->cache_ops)
2226 }
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 2182 of file gnunet-service-namestore.c.

2231 {
2232  uint16_t size;
2233  size_t key_len;
2234 
2235  size = ntohs (zis_msg->gns_header.header.size);
2236  key_len = ntohs (zis_msg->key_len);
2237 
2238  if (size < key_len + sizeof(*zis_msg))
2239  {
2240  GNUNET_break (0);
2241  return GNUNET_SYSERR;
2242  }
2243  return GNUNET_OK;
2244 }
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 2254 of file gnunet-service-namestore.c.

2256 {
2258  struct NamestoreClient *nc = cls;
2259  struct ZoneIteration *zi;
2260  size_t key_len;
2261  size_t kb_read;
2262 
2264  "Received ZONE_ITERATION_START message\n");
2265  key_len = ntohs (zis_msg->key_len);
2266  zi = GNUNET_new (struct ZoneIteration);
2267  if (0 < key_len)
2268  {
2269  if ((GNUNET_SYSERR ==
2271  key_len,
2272  &zone,
2273  &kb_read)) ||
2274  (kb_read != key_len))
2275  {
2276  GNUNET_SERVICE_client_drop (nc->client);
2277  GNUNET_free (zi);
2278  return;
2279  }
2280  zi->zone = zone;
2281  }
2282  zi->request_id = ntohl (zis_msg->gns_header.r_id);
2283  zi->filter = ntohs (zis_msg->filter);
2284  zi->offset = 0;
2285  zi->nc = nc;
2286  GNUNET_CONTAINER_DLL_insert (nc->op_head, nc->op_tail, zi);
2287  run_zone_iteration_round (zi, 1);
2288 }
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 2298 of file gnunet-service-namestore.c.

2300 {
2301  struct NamestoreClient *nc = cls;
2302  struct ZoneIteration *zi;
2303  uint32_t rid;
2304 
2306  "Received ZONE_ITERATION_STOP message\n");
2307  rid = ntohl (zis_msg->gns_header.r_id);
2308  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2309  if (zi->request_id == rid)
2310  break;
2311  if (NULL == zi)
2312  {
2313  GNUNET_break (0);
2314  GNUNET_SERVICE_client_drop (nc->client);
2315  return;
2316  }
2317  GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, zi);
2318  GNUNET_free (zi);
2320 }
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 2330 of file gnunet-service-namestore.c.

2332 {
2333  struct NamestoreClient *nc = cls;
2334  struct ZoneIteration *zi;
2335  uint32_t rid;
2336  uint64_t limit;
2337 
2339  "Received ZONE_ITERATION_NEXT message\n");
2341  "Iteration NEXT messages received",
2342  1,
2343  GNUNET_NO);
2344  rid = ntohl (zis_msg->gns_header.r_id);
2345  limit = GNUNET_ntohll (zis_msg->limit);
2346  for (zi = nc->op_head; NULL != zi; zi = zi->next)
2347  if (zi->request_id == rid)
2348  break;
2349  if (NULL == zi)
2350  {
2351  GNUNET_break (0);
2352  GNUNET_SERVICE_client_drop (nc->client);
2353  return;
2354  }
2355  run_zone_iteration_round (zi, limit);
2356 }
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 2365 of file gnunet-service-namestore.c.

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

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 2407 of file gnunet-service-namestore.c.

2408 {
2409  struct GNUNET_MQ_Envelope *env;
2410  struct GNUNET_MessageHeader *sync;
2412  "Synching zone monitor %p\n", zm);
2413 
2415  GNUNET_MQ_send (zm->nc->mq, env);
2416  /* mark iteration done */
2417  zm->in_first_iteration = GNUNET_NO;
2418  zm->iteration_cnt = 0;
2419  if ((zm->limit > 0) && (zm->sa_waiting))
2420  monitor_unblock (zm);
2421 }
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 2556 of file gnunet-service-namestore.c.

2557 {
2558  struct ZoneMonitor *zm = cls;
2559  struct NamestoreClient *nc = zm->nc;
2560  int ret;
2561 
2562  zm->task = NULL;
2563  GNUNET_assert (0 == zm->iteration_cnt);
2564  if (zm->limit > 16)
2565  zm->iteration_cnt = zm->limit / 2; /* leave half for monitor events */
2566  else
2567  zm->iteration_cnt = zm->limit; /* use it all */
2568  zm->run_again = GNUNET_YES;
2569  while (GNUNET_YES == zm->run_again)
2570  {
2572  "Running iteration\n");
2573  zm->run_again = GNUNET_NO;
2574  ret = nc->GSN_database->iterate_records (nc->GSN_database->cls,
2576  &zm->zone)) ? NULL : &zm->zone,
2577  zm->seq,
2578  zm->iteration_cnt,
2580  zm);
2581  }
2582  if (GNUNET_SYSERR == ret)
2583  {
2584  GNUNET_SERVICE_client_drop (zm->nc->client);
2585  return;
2586  }
2587  if (GNUNET_NO == ret)
2588  {
2590  "Zone empty... syncing\n");
2591  /* empty zone */
2592  monitor_sync (zm);
2593  return;
2594  }
2595 }
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 2444 of file gnunet-service-namestore.c.

2450 {
2451  struct ZoneMonitor *zm = cls;
2452 
2453  GNUNET_assert (0 != seq);
2454  zm->seq = seq;
2455  GNUNET_assert (NULL != name);
2457  "Monitor notifications sent",
2458  1,
2459  GNUNET_NO);
2461  rd_count, rd, zm->filter))
2462  {
2464  "Sent records.\n");
2465  zm->limit--;
2466  zm->iteration_cnt--;
2467  }
2468  else
2469  zm->run_again = GNUNET_YES;
2470  if ((0 == zm->iteration_cnt) && (0 != zm->limit))
2471  {
2472  /* We are done with the current iteration batch, AND the
2473  client would right now accept more, so go again! */
2474  GNUNET_assert (NULL == zm->task);
2476  }
2477 }
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:1299
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 2444 of file gnunet-service-namestore.c.

2482 {
2483  uint16_t size;
2484  size_t key_len;
2485 
2486  size = ntohs (zis_msg->header.size);
2487  key_len = ntohs (zis_msg->key_len);
2488 
2489  if (size < key_len + sizeof(*zis_msg))
2490  {
2491  GNUNET_break (0);
2492  return GNUNET_SYSERR;
2493  }
2494  return GNUNET_OK;
2495 }
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 2505 of file gnunet-service-namestore.c.

2507 {
2509  struct NamestoreClient *nc = cls;
2510  struct ZoneMonitor *zm;
2511  size_t key_len;
2512  size_t kb_read;
2513 
2515  "Received ZONE_MONITOR_START message\n");
2516  zm = GNUNET_new (struct ZoneMonitor);
2517  zm->nc = nc;
2518  key_len = ntohs (zis_msg->key_len);
2519  if (0 < key_len)
2520  {
2521  if ((GNUNET_SYSERR ==
2523  key_len,
2524  &zone,
2525  &kb_read)) ||
2526  (kb_read != key_len))
2527  {
2529  "Error reading private key\n");
2530  GNUNET_SERVICE_client_drop (nc->client);
2531  GNUNET_free (zm);
2532  return;
2533  }
2534  zm->zone = zone;
2535  }
2536  zm->limit = 1;
2537  zm->filter = ntohs (zis_msg->filter);
2538  zm->in_first_iteration = (GNUNET_YES == ntohl (zis_msg->iterate_first));
2543  if (zm->in_first_iteration)
2545  else
2546  monitor_sync (zm);
2547 }
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 2604 of file gnunet-service-namestore.c.

2605 {
2606  struct NamestoreClient *nc = cls;
2607  struct ZoneMonitor *zm;
2608  uint64_t inc;
2609 
2610  inc = GNUNET_ntohll (nm->limit);
2612  "Received ZONE_MONITOR_NEXT message with limit %llu\n",
2613  (unsigned long long) inc);
2614  for (zm = monitor_head; NULL != zm; zm = zm->next)
2615  if (zm->nc == nc)
2616  break;
2617  if (NULL == zm)
2618  {
2619  GNUNET_break (0);
2620  GNUNET_SERVICE_client_drop (nc->client);
2621  return;
2622  }
2624  if (zm->limit + inc < zm->limit)
2625  {
2626  GNUNET_break (0);
2627  GNUNET_SERVICE_client_drop (nc->client);
2628  return;
2629  }
2630  zm->limit += inc;
2631  if ((zm->in_first_iteration) && (zm->limit == inc))
2632  {
2633  /* We are still iterating, and the previous iteration must
2634  have stopped due to the client's limit, so continue it! */
2635  GNUNET_assert (NULL == zm->task);
2637  }
2638  GNUNET_assert (zm->iteration_cnt <= zm->limit);
2639  if ((zm->limit > zm->iteration_cnt) && (zm->sa_waiting))
2640  {
2641  monitor_unblock (zm);
2642  }
2643  else if (GNUNET_YES == zm->sa_waiting)
2644  {
2645  if (NULL != zm->sa_wait_warning)
2646  GNUNET_SCHEDULER_cancel (zm->sa_wait_warning);
2647  zm->sa_waiting_start = GNUNET_TIME_absolute_get ();
2648  zm->sa_wait_warning =
2651  zm);
2652  }
2653 }
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 2663 of file gnunet-service-namestore.c.

2666 {
2667  char *database;
2668  (void) cls;
2669  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n");
2671  "namestore",
2672  "RETURN_ORPHANED");
2673  GSN_cfg = cfg;
2675  statistics = GNUNET_STATISTICS_create ("namestore", cfg);
2676  /* Loading database plugin */
2678  "namestore",
2679  "database",
2680  &database))
2681  {
2682  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No database backend configured\n");
2684  return;
2685  }
2686  GNUNET_asprintf (&db_lib_name, "libgnunet_plugin_namestore_%s", database);
2687  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loading %s\n", db_lib_name);
2689  GNUNET_free (database);
2690  if (NULL == GSN_database)
2691  {
2693  "Could not load database backend `%s'\n",
2694  db_lib_name);
2697  return;
2698  }
2700 }
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:1334
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().