GNUnet  0.10.x
Data Structures | Macros | Enumerations | Functions | Variables
gnunet-service-transport_validation.c File Reference

address validation subsystem More...

#include "platform.h"
#include "gnunet-service-transport_ats.h"
#include "gnunet-service-transport_hello.h"
#include "gnunet-service-transport_neighbours.h"
#include "gnunet-service-transport_plugins.h"
#include "gnunet-service-transport_validation.h"
#include "gnunet-service-transport.h"
#include "gnunet_hello_lib.h"
#include "gnunet_ats_service.h"
#include "gnunet_peerinfo_service.h"
#include "gnunet_signatures.h"
Include dependency graph for gnunet-service-transport_validation.c:

Go to the source code of this file.

Data Structures

struct  TransportPingMessage
 Message used to ask a peer to validate receipt (to check an address from a HELLO). More...
 
struct  TransportPongMessage
 Message used to validate a HELLO. More...
 
struct  ValidationEntry
 Information about an address under validation. More...
 
struct  ValidationEntryMatchContext
 Context for the validation entry match function. More...
 
struct  IteratorContext
 Closure for the neighbours_iterate() function. More...
 

Macros

#define PONG_SIGNATURE_LIFETIME   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1)
 How long is a PONG signature valid? We'll recycle a signature until 1/4 of this time is remaining. More...
 
#define HELLO_ADDRESS_EXPIRATION   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)
 After how long do we expire an address in a HELLO that we just validated? This value is also used for our own addresses when we create a HELLO. More...
 
#define UNVALIDATED_PING_KEEPALIVE   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
 How often do we allow PINGing an address that we have not yet validated? This also determines how long we track an address that we cannot validate (because after this time we can destroy the validation record). More...
 
#define VALIDATED_PING_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
 How often do we PING an address that we have successfully validated in the past but are not actively using? Should be (significantly) smaller than HELLO_ADDRESS_EXPIRATION. More...
 
#define CONNECTED_PING_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)
 How often do we PING an address that we are currently using? More...
 
#define ACCEPTABLE_PING_DELAY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)
 How much delay is acceptable for sending the PING or PONG? More...
 
#define VALIDATION_MAP_SIZE   256
 Size of the validation map hashmap. More...
 
#define PING_PRIORITY   2
 Priority to use for PINGs. More...
 
#define PONG_PRIORITY   4
 Priority to use for PONGs. More...
 

Enumerations

enum  GNUNET_TRANSPORT_ValidationState {
  GNUNET_TRANSPORT_VS_NONE, GNUNET_TRANSPORT_VS_NEW, GNUNET_TRANSPORT_VS_UPDATE, GNUNET_TRANSPORT_VS_TIMEOUT,
  GNUNET_TRANSPORT_VS_REMOVE
}
 Current state of a validation process. More...
 

Functions

static void publish_ve_stat_update ()
 Provide an update on the validation_map map size to statistics. More...
 
static int validation_entry_match (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Iterate over validation entries until a matching one is found. More...
 
static void validation_entry_changed (struct ValidationEntry *ve, enum GNUNET_TRANSPORT_ValidationState state)
 A validation entry changed. More...
 
static int cleanup_validation_entry (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Iterate over validation entries and free them. More...
 
static void timeout_hello_validation (void *cls)
 Address validation cleanup task. More...
 
static void transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_HELLO_Address *address_null, struct GNUNET_ATS_Session *session_null, int result)
 Function called with the result from blacklisting. More...
 
static void revalidate_address (void *cls)
 Do address validation again to keep address valid. More...
 
static struct ValidationEntryfind_validation_entry (const struct GNUNET_HELLO_Address *address)
 Find a ValidationEntry entry for the given neighbour that matches the given address and transport. More...
 
static int add_valid_address (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Iterator which adds the given address to the set of validated addresses. More...
 
static void process_peerinfo_hello (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg)
 Function called for any HELLO known to PEERINFO. More...
 
void GST_validation_start (unsigned int max_fds)
 Start the validation subsystem. More...
 
void GST_validation_stop ()
 Stop the validation subsystem. More...
 
static void multicast_pong (void *cls, struct GNUNET_TIME_Absolute valid_until, struct GNUNET_TIME_Absolute validation_block, const struct GNUNET_HELLO_Address *address)
 Send the given PONG to the given address. More...
 
int GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *hdr, const struct GNUNET_HELLO_Address *sender_address, struct GNUNET_ATS_Session *session)
 We've received a PING. More...
 
void GST_validation_handle_address (const struct GNUNET_HELLO_Address *address)
 Validate an individual address. More...
 
static int validate_address_iterator (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Iterator callback to go over all addresses and try to validate them (unless blocked or already validated). More...
 
static ssize_t add_valid_peer_address (void *cls, size_t max, void *buf)
 Add the validated peer address to the HELLO. More...
 
int GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *hdr)
 We've received a PONG. More...
 
int GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello)
 We've received a HELLO, check which addresses are new and trigger validation. More...
 
static int iterate_addresses (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Call the callback in the closure for each validation entry. More...
 
void GST_validation_get_addresses (const struct GNUNET_PeerIdentity *target, GST_ValidationAddressCallback cb, void *cb_cls)
 Call the given function for each address for the given target. More...
 
void GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, int in_use)
 Update if we are using an address for a connection actively right now. More...
 

Variables

static struct GNUNET_CONTAINER_MultiPeerMapvalidation_map
 Map of PeerIdentities to 'struct ValidationEntry*'s (addresses of the given peer that we are currently validating, have validated or are blocked from re-validation for a while). More...
 
static struct GNUNET_PEERINFO_NotifyContextpnc
 Context for peerinfo iteration. More...
 
static struct GNUNET_TIME_Relative validation_delay
 Minimum delay between to validations. More...
 
static unsigned int validations_running
 Number of validations running; any PING that was not yet matched by a PONG and for which we have not yet hit the timeout is considered a running 'validation'. More...
 
static unsigned int validations_fast_start_threshold
 Validition fast start threshold. More...
 
static struct GNUNET_TIME_Absolute validation_next
 When is next validation allowed. More...
 

Detailed Description

address validation subsystem

Author
Christian Grothoff

Definition in file gnunet-service-transport_validation.c.

Macro Definition Documentation

◆ PONG_SIGNATURE_LIFETIME

#define PONG_SIGNATURE_LIFETIME   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1)

How long is a PONG signature valid? We'll recycle a signature until 1/4 of this time is remaining.

PONGs should expire so that if our external addresses change an adversary cannot replay them indefinitely. OTOH, we don't want to spend too much time generating PONG signatures, so they must have some lifetime to reduce our CPU usage.

Definition at line 93 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_handle_ping().

◆ HELLO_ADDRESS_EXPIRATION

#define HELLO_ADDRESS_EXPIRATION   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 12)

After how long do we expire an address in a HELLO that we just validated? This value is also used for our own addresses when we create a HELLO.

Definition at line 100 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_handle_pong().

◆ UNVALIDATED_PING_KEEPALIVE

#define UNVALIDATED_PING_KEEPALIVE   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)

How often do we allow PINGing an address that we have not yet validated? This also determines how long we track an address that we cannot validate (because after this time we can destroy the validation record).

Definition at line 108 of file gnunet-service-transport_validation.c.

Referenced by find_validation_entry(), and revalidate_address().

◆ VALIDATED_PING_FREQUENCY

#define VALIDATED_PING_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)

How often do we PING an address that we have successfully validated in the past but are not actively using? Should be (significantly) smaller than HELLO_ADDRESS_EXPIRATION.

Definition at line 115 of file gnunet-service-transport_validation.c.

Referenced by revalidate_address().

◆ CONNECTED_PING_FREQUENCY

#define CONNECTED_PING_FREQUENCY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2)

How often do we PING an address that we are currently using?

Definition at line 120 of file gnunet-service-transport_validation.c.

Referenced by revalidate_address().

◆ ACCEPTABLE_PING_DELAY

#define ACCEPTABLE_PING_DELAY   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1)

How much delay is acceptable for sending the PING or PONG?

Definition at line 125 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_handle_ping(), multicast_pong(), and transmit_ping_if_allowed().

◆ VALIDATION_MAP_SIZE

#define VALIDATION_MAP_SIZE   256

Size of the validation map hashmap.

Definition at line 130 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_start().

◆ PING_PRIORITY

#define PING_PRIORITY   2

Priority to use for PINGs.

Definition at line 135 of file gnunet-service-transport_validation.c.

Referenced by transmit_ping_if_allowed().

◆ PONG_PRIORITY

#define PONG_PRIORITY   4

Priority to use for PONGs.

Definition at line 140 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_handle_ping(), and multicast_pong().

Enumeration Type Documentation

◆ GNUNET_TRANSPORT_ValidationState

Current state of a validation process.

FIXME: what state is used to indicate that a validation was successful? If that is clarified/determined, "UGH" in ~gnunetpeerinfogtk.c:1103 should be resolved.

Enumerator
GNUNET_TRANSPORT_VS_NONE 

Undefined state.

Used for final callback indicating operation done

GNUNET_TRANSPORT_VS_NEW 

Fresh validation entry.

Entry was just created, no validation process was executed

GNUNET_TRANSPORT_VS_UPDATE 

Updated validation entry.

This is an update for an existing validation entry

GNUNET_TRANSPORT_VS_TIMEOUT 

Timeout for validation entry.

A timeout occured during the validation process

GNUNET_TRANSPORT_VS_REMOVE 

Validation entry is removed.

The validation entry is getting removed due to a failed validation

Definition at line 45 of file gnunet-service-transport_validation.c.

Function Documentation

◆ publish_ve_stat_update()

static void publish_ve_stat_update ( )
static

Provide an update on the validation_map map size to statistics.

This function should be called whenever the validation_map is changed.

Definition at line 385 of file gnunet-service-transport_validation.c.

References gettext_noop, GNUNET_CONTAINER_multipeermap_size(), GNUNET_NO, GNUNET_STATISTICS_set(), and GST_stats.

Referenced by cleanup_validation_entry(), and find_validation_entry().

386 {
388  gettext_noop ("# Addresses in validation map"),
390  GNUNET_NO);
391 }
#define GNUNET_NO
Definition: gnunet_common.h:81
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
static struct GNUNET_CONTAINER_MultiPeerMap * validation_map
Map of PeerIdentities to 'struct ValidationEntry*'s (addresses of the given peer that we are currentl...
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
unsigned int GNUNET_CONTAINER_multipeermap_size(const struct GNUNET_CONTAINER_MultiPeerMap *map)
Get the number of key-value pairs in the map.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validation_entry_match()

static int validation_entry_match ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Iterate over validation entries until a matching one is found.

Parameters
clsthe struct ValidationEntryMatchContext *
keypeer identity (unused)
valuea struct ValidationEntry * to match
Returns
GNUNET_YES if the entry does not match, GNUNET_NO if the entry does match

Definition at line 404 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, ValidationEntryMatchContext::address, GNUNET_HELLO_address_cmp(), GNUNET_NO, GNUNET_YES, value, and ValidationEntryMatchContext::ve.

Referenced by find_validation_entry().

407 {
408  struct ValidationEntryMatchContext *vemc = cls;
409  struct ValidationEntry *ve = value;
410 
411  if (0 == GNUNET_HELLO_address_cmp (ve->address,
412  vemc->address))
413  {
414  vemc->ve = ve;
415  return GNUNET_NO;
416  }
417  return GNUNET_YES;
418 }
Information about an address under validation.
const struct GNUNET_HELLO_Address * address
Address we're interested in.
#define GNUNET_NO
Definition: gnunet_common.h:81
int GNUNET_HELLO_address_cmp(const struct GNUNET_HELLO_Address *a1, const struct GNUNET_HELLO_Address *a2)
Compare two addresses.
Definition: address.c:130
static char * value
Value of the record to add/remove.
Context for the validation entry match function.
struct ValidationEntry * ve
Where to store the result?
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_HELLO_Address * address
The address.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validation_entry_changed()

static void validation_entry_changed ( struct ValidationEntry ve,
enum GNUNET_TRANSPORT_ValidationState  state 
)
static

A validation entry changed.

Update the state and notify monitors.

Parameters
vevalidation entry that changed
statenew state

Definition at line 429 of file gnunet-service-transport_validation.c.

References state, and ValidationEntry::state.

Referenced by add_valid_address(), cleanup_validation_entry(), find_validation_entry(), GST_validation_handle_pong(), and transmit_ping_if_allowed().

431 {
432  ve->state = state;
433 }
enum State state
current state of profiling
enum GNUNET_TRANSPORT_ValidationState state
Current state of this validation entry.
Here is the caller graph for this function:

◆ cleanup_validation_entry()

static int cleanup_validation_entry ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Iterate over validation entries and free them.

Parameters
cls(unused)
keypeer identity (unused)
valuea struct ValidationEntry * to clean up
Returns
GNUNET_YES (continue to iterate)

Definition at line 445 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, ValidationEntry::bc, ValidationEntry::expecting_pong, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_CONTAINER_multipeermap_remove(), GNUNET_free, GNUNET_HELLO_address_free, GNUNET_NO, GNUNET_OK, GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_set(), GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_REMOVE, GNUNET_YES, GST_ats_expire_address(), GST_ats_is_known_no_session(), GST_blacklist_test_cancel(), GST_stats, ValidationEntry::known_to_ats, ValidationEntry::next_validation, GNUNET_HELLO_Address::peer, publish_ve_stat_update(), ValidationEntry::revalidation_task, ValidationEntry::timeout_task, ValidationEntry::valid_until, validation_entry_changed(), validations_running, and value.

Referenced by GST_validation_stop(), timeout_hello_validation(), and transmit_ping_if_allowed().

448 {
449  struct ValidationEntry *ve = value;
450 
453 
454  /* Notify about deleted entry */
457 
458  if (NULL != ve->bc)
459  {
461  ve->bc = NULL;
462  }
465  &ve->address->peer,
466  ve));
468  if (GNUNET_YES == ve->known_to_ats)
469  {
473  ve->known_to_ats = GNUNET_NO;
474  }
476  if (NULL != ve->timeout_task)
477  {
479  ve->timeout_task = NULL;
480  }
481  if (NULL != ve->revalidation_task)
482  {
484  ve->revalidation_task = NULL;
485  }
486  if ( (GNUNET_YES == ve->expecting_pong) &&
487  (validations_running > 0) )
488  {
491  gettext_noop ("# validations running"),
493  GNUNET_NO);
494  }
495  GNUNET_free (ve);
496  return GNUNET_OK;
497 }
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct GNUNET_TIME_Absolute valid_until
Until when is this address valid? ZERO if it is not currently considered valid.
int expecting_pong
Are we expecting a PONG message for this validation entry?
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Information about an address under validation.
int known_to_ats
Is this address known to ATS as valid right now?
int GNUNET_CONTAINER_multipeermap_remove(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, const void *value)
Remove the given key-value pair from the map.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static void publish_ve_stat_update()
Provide an update on the validation_map map size to statistics.
static void validation_entry_changed(struct ValidationEntry *ve, enum GNUNET_TRANSPORT_ValidationState state)
A validation entry changed.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SCHEDULER_Task * revalidation_task
ID of task that will trigger address revalidation.
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
static char * value
Value of the record to add/remove.
static unsigned int validations_running
Number of validations running; any PING that was not yet matched by a PONG and for which we have not ...
void GST_ats_expire_address(const struct GNUNET_HELLO_Address *address)
Notify ATS that the address has expired and thus cannot be used any longer.
struct GNUNET_SCHEDULER_Task * timeout_task
ID of task that will clean up this entry if nothing happens.
static struct GNUNET_CONTAINER_MultiPeerMap * validation_map
Map of PeerIdentities to 'struct ValidationEntry*'s (addresses of the given peer that we are currentl...
void GNUNET_STATISTICS_set(struct GNUNET_STATISTICS_Handle *handle, const char *name, uint64_t value, int make_persistent)
Set statistic value for the peer.
int GST_ats_is_known_no_session(const struct GNUNET_HELLO_Address *address)
Test if ATS knows about this address.
void GST_blacklist_test_cancel(struct GST_BlacklistCheck *bc)
Cancel a blacklist check.
struct GNUNET_PeerIdentity peer
For which peer is this an address?
struct GNUNET_TIME_Absolute next_validation
At what time do we send the next validation request (PING)?
struct GST_BlacklistCheck * bc
Handle to the blacklist check (if we're currently in it).
#define GNUNET_YES
Definition: gnunet_common.h:80
#define GNUNET_HELLO_address_free(addr)
Free an address.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_HELLO_Address * address
The address.
#define gettext_noop(String)
Definition: gettext.h:69
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timeout_hello_validation()

static void timeout_hello_validation ( void *  cls)
static

Address validation cleanup task.

Assesses if the record is no longer valid and then possibly triggers its removal.

Parameters
clsthe struct ValidationEntry

Definition at line 507 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, cleanup_validation_entry(), gettext_noop, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_max(), GST_stats, GNUNET_HELLO_Address::peer, GNUNET_TIME_Relative::rel_value_us, ValidationEntry::revalidation_block, ValidationEntry::timeout_task, and ValidationEntry::valid_until.

Referenced by find_validation_entry().

508 {
509  struct ValidationEntry *ve = cls;
510  struct GNUNET_TIME_Absolute max;
511  struct GNUNET_TIME_Relative left;
512 
513  ve->timeout_task = NULL;
514  /* For valid addresses, we want to wait until the expire;
515  for addresses under PING validation, we want to wait
516  until we give up on the PING */
518  ve->revalidation_block);
520  if (left.rel_value_us > 0)
521  {
522  /* We should wait a bit longer. This happens when
523  address lifetimes are extended due to successful
524  validations. */
525  ve->timeout_task =
528  ve);
529  return;
530  }
532  gettext_noop ("# address records discarded (timeout)"),
533  1,
534  GNUNET_NO);
536  &ve->address->peer,
537  ve);
538 }
struct GNUNET_TIME_Absolute revalidation_block
How long until we can try to validate this address again? FOREVER if the address is for an unsupporte...
struct GNUNET_TIME_Absolute valid_until
Until when is this address valid? ZERO if it is not currently considered valid.
static void timeout_hello_validation(void *cls)
Address validation cleanup task.
Information about an address under validation.
#define GNUNET_NO
Definition: gnunet_common.h:81
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int cleanup_validation_entry(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterate over validation entries and free them.
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:1246
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:317
struct GNUNET_SCHEDULER_Task * timeout_task
ID of task that will clean up this entry if nothing happens.
struct GNUNET_PeerIdentity peer
For which peer is this an address?
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Time for absolute times used by GNUnet, in microseconds.
struct GNUNET_HELLO_Address * address
The address.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ transmit_ping_if_allowed()

static void transmit_ping_if_allowed ( void *  cls,
const struct GNUNET_PeerIdentity pid,
const struct GNUNET_HELLO_Address address_null,
struct GNUNET_ATS_Session session_null,
int  result 
)
static

Function called with the result from blacklisting.

Send a PING to the other peer if a communication is allowed.

Parameters
clsour struct ValidationEntry
pididentity of the other peer
address_nulladdress associated with the request, always NULL
session_nullsession associated with the request, always NULL
resultGNUNET_OK if the connection is allowed, GNUNET_NO if not, GNUNET_SYSERR if operation was aborted

Definition at line 554 of file gnunet-service-transport_validation.c.

References ACCEPTABLE_PING_DELAY, ValidationEntry::address, ValidationEntry::bc, TransportPingMessage::challenge, cleanup_validation_entry(), GNUNET_TRANSPORT_PluginFunctions::cls, GNUNET_TRANSPORT_PluginFunctions::get_network, GNUNET_TRANSPORT_PluginFunctions::get_session, gettext_noop, GNUNET_ALIGN, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_TRANSPORT_PING, GNUNET_NO, GNUNET_NT_UNSPECIFIED, GNUNET_OK, GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_max(), GNUNET_TIME_relative_to_absolute(), GNUNET_TRANSPORT_VS_UPDATE, GNUNET_YES, GST_hello_get(), GST_neighbours_notify_data_sent(), GST_plugins_a2s(), GST_plugins_find(), GST_stats, TransportPingMessage::header, pid, PING_PRIORITY, ret, GNUNET_TRANSPORT_PluginFunctions::send, GNUNET_MessageHeader::size, TransportPingMessage::target, GNUNET_HELLO_Address::transport_name, GNUNET_MessageHeader::type, validation_delay, validation_entry_changed(), validation_next, and validations_running.

Referenced by revalidate_address().

559 {
560  struct ValidationEntry *ve = cls;
561  struct TransportPingMessage ping;
563  struct GNUNET_TIME_Absolute next;
564  const struct GNUNET_MessageHeader *hello;
565  ssize_t ret;
566  size_t tsize;
567  size_t slen;
568  uint16_t hsize;
569  struct GNUNET_ATS_Session *session;
570 
571  ve->bc = NULL;
572  if (GNUNET_OK != result)
573  {
575  "Blacklist denies sending PING to `%s' `%s' `%s'\n",
576  GNUNET_i2s (pid),
577  GST_plugins_a2s (ve->address),
578  ve->address->transport_name);
580  gettext_noop ("# address records discarded (blacklist)"),
581  1,
582  GNUNET_NO);
584  pid,
585  ve);
586  return;
587  }
588  hello = GST_hello_get ();
589  GNUNET_assert (NULL != hello);
590  slen = strlen (ve->address->transport_name) + 1;
591  hsize = ntohs (hello->size);
592  tsize = sizeof (struct TransportPingMessage) +
593  ve->address->address_length + slen + hsize;
594 
595  ping.header.size =
596  htons (sizeof (struct TransportPingMessage) +
597  ve->address->address_length + slen);
598  ping.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
599  ping.challenge = htonl (ve->challenge);
600  ping.target = *pid;
601 
602  if (tsize >= GNUNET_MAX_MESSAGE_SIZE)
603  {
604  GNUNET_break (0);
605  hsize = 0;
606  tsize =
607  sizeof (struct TransportPingMessage) + ve->address->address_length +
608  slen + hsize;
609  }
610  {
611  char message_buf[tsize] GNUNET_ALIGN;
612 
613  GNUNET_memcpy (message_buf,
614  hello,
615  hsize);
616  GNUNET_memcpy (&message_buf[hsize],
617  &ping,
618  sizeof (struct TransportPingMessage));
619  GNUNET_memcpy (&message_buf[sizeof (struct TransportPingMessage) + hsize],
620  ve->address->transport_name,
621  slen);
622  GNUNET_memcpy (&message_buf[sizeof (struct TransportPingMessage) + slen + hsize],
623  ve->address->address,
624  ve->address->address_length);
626  GNUNET_assert (NULL != papi);
627  session = papi->get_session (papi->cls,
628  ve->address);
629  if (NULL == session)
630  {
631  /* Could not get a valid session */
633  "Failed to get session to send PING to `%s' at `%s'\n",
634  GNUNET_i2s (pid),
635  GST_plugins_a2s (ve->address));
636  return;
637  }
638 
639  ret = papi->send (papi->cls, session,
640  message_buf, tsize,
643  NULL, NULL);
644  if (-1 == ret)
645  {
647  "Failed to send PING to `%s' at `%s'\n",
648  GNUNET_i2s (pid),
649  GST_plugins_a2s (ve->address));
650  return;
651  }
653  "Transmitted plain PING to `%s' `%s' `%s'\n",
654  GNUNET_i2s (pid),
655  GST_plugins_a2s (ve->address),
656  ve->address->transport_name);
657  ve->network = papi->get_network (papi->cls,
658  session);
661  session,
662  tsize);
668  gettext_noop ("# PINGs for address validation sent"),
669  1,
670  GNUNET_NO);
674  "Validation started, %u validation processes running\n",
677  gettext_noop ("# validations running"),
679  GNUNET_NO);
680  /* Notify about PING sent */
683 
684  }
685 }
size_t address_length
Number of bytes in address.
static void ping(void *cls)
Send a ping to destination.
GNUNET_TRANSPORT_CreateSession get_session
Function that will be called tell the plugin to create a session object.
int expecting_pong
Are we expecting a PONG message for this validation entry?
const void * address
Binary representation of the address (plugin-specific).
#define GNUNET_MESSAGE_TYPE_TRANSPORT_PING
Transport PING message.
GNUNET_TRANSPORT_TransmitFunction send
Function that the transport service will use to transmit data to another peer.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static struct GNUNET_TIME_Absolute validation_next
When is next validation allowed.
Information about an address under validation.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
uint32_t challenge
Challenge number we used.
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int ret
Final status code.
Definition: gnunet-arm.c:89
static void validation_entry_changed(struct ValidationEntry *ve, enum GNUNET_TRANSPORT_ValidationState state)
A validation entry changed.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static int cleanup_validation_entry(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterate over validation entries and free them.
Message used to ask a peer to validate receipt (to check an address from a HELLO).
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
void * cls
Closure for all of the callbacks.
#define GNUNET_memcpy(dst, src, n)
#define ACCEPTABLE_PING_DELAY
How much delay is acceptable for sending the PING or PONG?
static unsigned int validations_running
Number of validations running; any PING that was not yet matched by a PONG and for which we have not ...
Information about ongoing sessions of the transport client.
GNUNET_TRANSPORT_GetNetworkType get_network
Function to obtain the network type for a session.
void GST_neighbours_notify_data_sent(const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, size_t size)
Track information about data we transmitted using the given address and session (used to notify ATS a...
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:317
const char * transport_name
Name of the transport plugin enabling the communication using this address.
static int result
Global testing status.
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
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_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static struct GNUNET_TIME_Relative validation_delay
Minimum delay between to validations.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
const struct GNUNET_MessageHeader * GST_hello_get()
Obtain this peers HELLO message.
#define PING_PRIORITY
Priority to use for PINGs.
struct GST_BlacklistCheck * bc
Handle to the blacklist check (if we're currently in it).
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to 'struct's...
#define GNUNET_log(kind,...)
enum GNUNET_NetworkType network
Which network type does our address belong to?
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
struct GNUNET_TIME_Absolute send_time
At what time did we send the latest validation request (PING)?
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_HELLO_Address * address
The address.
#define gettext_noop(String)
Definition: gettext.h:69
Category of last resort.
Definition: gnunet_nt_lib.h:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ revalidate_address()

static void revalidate_address ( void *  cls)
static

Do address validation again to keep address valid.

Parameters
clsthe struct ValidationEntry

Definition at line 694 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, ValidationEntry::bc, CONNECTED_PING_FREQUENCY, gettext_noop, GNUNET_CRYPTO_QUALITY_WEAK, GNUNET_CRYPTO_random_u32(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_STATISTICS_update(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_relative_add(), GNUNET_TIME_relative_min(), GNUNET_TIME_relative_multiply(), GNUNET_TIME_relative_to_absolute(), GNUNET_TIME_UNIT_MICROSECONDS, GNUNET_YES, GST_blacklist_test_allowed(), GST_blacklist_test_cancel(), GST_plugins_a2s(), GST_stats, ValidationEntry::in_use, ValidationEntry::next_validation, GNUNET_HELLO_Address::peer, GNUNET_TIME_Relative::rel_value_us, ValidationEntry::revalidation_block, ValidationEntry::revalidation_task, transmit_ping_if_allowed(), GNUNET_HELLO_Address::transport_name, UNVALIDATED_PING_KEEPALIVE, ValidationEntry::valid_until, VALIDATED_PING_FREQUENCY, validation_next, validations_fast_start_threshold, and validations_running.

Referenced by add_valid_address(), GST_validation_handle_address(), and GST_validation_set_address_use().

695 {
696  struct ValidationEntry *ve = cls;
697  struct GNUNET_TIME_Relative canonical_delay;
699  struct GNUNET_TIME_Relative blocked_for;
700  struct GST_BlacklistCheck *bc;
701  uint32_t rdelay;
702 
703  ve->revalidation_task = NULL;
705  /* Considering current connectivity situation, what is the maximum
706  block period permitted? */
707  if (GNUNET_YES == ve->in_use)
708  canonical_delay = CONNECTED_PING_FREQUENCY;
710  canonical_delay = VALIDATED_PING_FREQUENCY;
711  else
712  canonical_delay = UNVALIDATED_PING_KEEPALIVE;
713  /* Use delay that is MIN of original delay and possibly adjusted
714  new maximum delay (which may be lower); the real delay
715  is originally randomized between "canonical_delay" and "2 * canonical_delay",
716  so continue to permit that window for the operation. */
718  GNUNET_TIME_relative_multiply (canonical_delay,
719  2));
721  if (delay.rel_value_us > 0)
722  {
723  /* should wait a bit longer */
725  "Waiting for %s longer before (re)validating address `%s'\n",
727  GNUNET_YES),
728  GST_plugins_a2s (ve->address));
729  ve->revalidation_task =
731  &revalidate_address, ve);
733  return;
734  }
735  /* check if globally we have too many active validations at a
736  too high rate, if so, delay ours */
739  (blocked_for.rel_value_us > 0) )
740  {
741  /* Validations are blocked, have to wait for blocked_for time */
743  "Validations blocked for another %s, delaying validating address `%s'\n",
745  GNUNET_YES),
746  GST_plugins_a2s (ve->address));
748  gettext_noop ("# validations delayed by global throttle"),
749  1,
750  GNUNET_NO);
751  ve->revalidation_task =
752  GNUNET_SCHEDULER_add_delayed (blocked_for,
754  ve);
756  return;
757  }
758 
759  /* We are good to go; remember to not go again for `canonical_delay` time;
760  add up to `canonical_delay` to randomize start time */
762  /* schedule next PINGing with some extra random delay to avoid synchronous re-validations */
763  rdelay =
765  canonical_delay.rel_value_us);
766 
767  delay = GNUNET_TIME_relative_add (canonical_delay,
770  rdelay));
771 
773  "Validating now, next scheduled for %s, now validating address `%s'\n",
775  GNUNET_YES),
776  GST_plugins_a2s (ve->address));
777  ve->revalidation_task =
780  ve);
782 
783  /* start PINGing by checking blacklist */
785  gettext_noop ("# address revalidations started"), 1,
786  GNUNET_NO);
787  if (NULL != ve->bc)
788  {
790  ve->bc = NULL;
791  }
793  ve->address->transport_name,
795  ve,
796  NULL,
797  NULL);
798  if (NULL != bc)
799  {
800  /* If transmit_ping_if_allowed was already called it may have freed ve,
801  * so only set ve->bc if it has not been called.
802  */
803  ve->bc = bc;
804  }
805 }
#define CONNECTED_PING_FREQUENCY
How often do we PING an address that we are currently using?
struct GNUNET_TIME_Absolute revalidation_block
How long until we can try to validate this address again? FOREVER if the address is for an unsupporte...
uint64_t rel_value_us
The actual value.
Context we use when performing a blacklist check.
struct GNUNET_TIME_Absolute valid_until
Until when is this address valid? ZERO if it is not currently considered valid.
struct GST_BlacklistCheck * GST_blacklist_test_allowed(const struct GNUNET_PeerIdentity *peer, const char *transport_name, GST_BlacklistTestContinuation cont, void *cont_cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session)
Test if a peer/transport combination is blacklisted.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
int in_use
Are we currently using this address for a connection?
static struct GNUNET_TIME_Absolute validation_next
When is next validation allowed.
Information about an address under validation.
#define UNVALIDATED_PING_KEEPALIVE
How often do we allow PINGing an address that we have not yet validated? This also determines how lon...
#define GNUNET_NO
Definition: gnunet_common.h:81
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
struct GNUNET_SCHEDULER_Task * revalidation_task
ID of task that will trigger address revalidation.
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:1246
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
static unsigned int validations_running
Number of validations running; any PING that was not yet matched by a PONG and for which we have not ...
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:727
const char * transport_name
Name of the transport plugin enabling the communication using this address.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_multiply(struct GNUNET_TIME_Relative rel, unsigned long long factor)
Multiply relative time by a given factor.
Definition: time.c:439
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_min(struct GNUNET_TIME_Relative t1, struct GNUNET_TIME_Relative t2)
Return the minimum of two relative time values.
Definition: time.c:271
void GST_blacklist_test_cancel(struct GST_BlacklistCheck *bc)
Cancel a blacklist check.
#define VALIDATED_PING_FREQUENCY
How often do we PING an address that we have successfully validated in the past but are not actively ...
static struct GNUNET_TIME_Relative delay
When should dkg communication start?
struct GNUNET_PeerIdentity peer
For which peer is this an address?
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:576
struct GNUNET_TIME_Absolute next_validation
At what time do we send the next validation request (PING)?
struct GST_BlacklistCheck * bc
Handle to the blacklist check (if we're currently in it).
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
static void revalidate_address(void *cls)
Do address validation again to keep address valid.
#define GNUNET_YES
Definition: gnunet_common.h:80
static void transmit_ping_if_allowed(void *cls, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_HELLO_Address *address_null, struct GNUNET_ATS_Session *session_null, int result)
Function called with the result from blacklisting.
static unsigned int validations_fast_start_threshold
Validition fast start threshold.
#define GNUNET_TIME_UNIT_MICROSECONDS
One microsecond, our basic time unit.
No good quality of the operation is needed (i.e., random numbers can be pseudo-random).
struct GNUNET_HELLO_Address * address
The address.
Time for relative time used by GNUnet, in microseconds.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_validation_entry()

static struct ValidationEntry* find_validation_entry ( const struct GNUNET_HELLO_Address address)
static

Find a ValidationEntry entry for the given neighbour that matches the given address and transport.

If none exists, create one (but without starting any validation).

Parameters
addressaddress to find
Returns
validation entry matching the given specifications, NULL if we don't have an existing entry and no public key was given

Definition at line 818 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, address, ValidationEntryMatchContext::address, ValidationEntry::challenge, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE, GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_CRYPTO_QUALITY_NONCE, GNUNET_CRYPTO_random_u32(), GNUNET_HELLO_address_copy(), GNUNET_new, GNUNET_NO, GNUNET_SCHEDULER_add_delayed(), GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NEW, GST_ats_is_known_no_session(), ValidationEntry::in_use, ValidationEntry::latency, GNUNET_HELLO_Address::peer, ValidationEntry::pong_sig_cache, ValidationEntry::pong_sig_valid_until, publish_ve_stat_update(), timeout_hello_validation(), ValidationEntry::timeout_task, UNVALIDATED_PING_KEEPALIVE, validation_entry_changed(), validation_entry_match(), and ValidationEntryMatchContext::ve.

Referenced by add_valid_address(), GST_validation_handle_address(), GST_validation_handle_pong(), and GST_validation_set_address_use().

819 {
820  struct ValidationEntryMatchContext vemc;
821  struct ValidationEntry *ve;
822 
823  vemc.ve = NULL;
824  vemc.address = address;
826  &address->peer,
827  &validation_entry_match, &vemc);
828  if (NULL != (ve = vemc.ve))
829  return ve;
831  GST_ats_is_known_no_session (address));
832  ve = GNUNET_new (struct ValidationEntry);
833  ve->in_use = GNUNET_SYSERR; /* not defined */
834  ve->address = GNUNET_HELLO_address_copy (address);
836  memset (&ve->pong_sig_cache,
837  '\0',
838  sizeof (struct GNUNET_CRYPTO_EddsaSignature));
840  ve->challenge =
842  ve->timeout_task =
845  ve);
847  &address->peer,
848  ve,
853  return ve;
854 }
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
static int validation_entry_match(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterate over validation entries until a matching one is found.
uint32_t GNUNET_CRYPTO_random_u32(enum GNUNET_CRYPTO_Quality mode, uint32_t i)
Produce a random value.
static void timeout_hello_validation(void *cls)
Address validation cleanup task.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
int in_use
Are we currently using this address for a connection?
Information about an address under validation.
#define UNVALIDATED_PING_KEEPALIVE
How often do we allow PINGing an address that we have not yet validated? This also determines how lon...
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_new(type)
Allocate a struct or union of the given type.
uint32_t challenge
Challenge number we used.
static void publish_ve_stat_update()
Provide an update on the validation_map map size to statistics.
static void validation_entry_changed(struct ValidationEntry *ve, enum GNUNET_TRANSPORT_ValidationState state)
A validation entry changed.
struct GNUNET_TIME_Relative latency
Last observed latency for this address (round-trip), delay between last PING sent and PONG received; ...
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:1246
Context for the validation entry match function.
Randomness for IVs etc.
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_SCHEDULER_Task * timeout_task
ID of task that will clean up this entry if nothing happens.
static struct GNUNET_CONTAINER_MultiPeerMap * validation_map
Map of PeerIdentities to 'struct ValidationEntry*'s (addresses of the given peer that we are currentl...
int GST_ats_is_known_no_session(const struct GNUNET_HELLO_Address *address)
Test if ATS knows about this address.
struct GNUNET_CRYPTO_EddsaSignature pong_sig_cache
Cached PONG signature.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
struct GNUNET_PeerIdentity peer
For which peer is this an address?
an ECC signature using EdDSA.
Allow multiple values with the same key.
int GNUNET_CONTAINER_multipeermap_put(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, void *value, enum GNUNET_CONTAINER_MultiHashMapOption opt)
Store a key-value pair in the map.
struct GNUNET_HELLO_Address * GNUNET_HELLO_address_copy(const struct GNUNET_HELLO_Address *address)
Copy an address struct.
Definition: address.c:109
struct GNUNET_TIME_Absolute pong_sig_valid_until
Until when is the cached PONG signature valid? ZERO if it is not currently considered valid...
static char * address
GNS address for this phone.
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
struct GNUNET_HELLO_Address * address
The address.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_valid_address()

static int add_valid_address ( void *  cls,
const struct GNUNET_HELLO_Address address,
struct GNUNET_TIME_Absolute  expiration 
)
static

Iterator which adds the given address to the set of validated addresses.

Parameters
clsoriginal HELLO message
addressthe address
expirationexpiration time
Returns
GNUNET_OK (keep the address), could return GNUNET_NO (delete address, but this is ignored); GNUNET_SYSERR would abort iteration (but we always iterate all)

Definition at line 869 of file gnunet-service-transport_validation.c.

References GNUNET_HELLO_Address::address, ValidationEntry::address, GNUNET_HELLO_Address::address_length, GNUNET_TRANSPORT_PluginFunctions::address_to_string, GNUNET_TRANSPORT_PluginFunctions::cls, GNUNET_ATS_Properties::delay, find_validation_entry(), GNUNET_TRANSPORT_PluginFunctions::get_network_for_address, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_HELLO_get_id(), GNUNET_i2s(), GNUNET_log, GNUNET_NT_UNSPECIFIED, GNUNET_OK, GNUNET_SCHEDULER_add_now(), GNUNET_TIME_absolute_get(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_max(), GNUNET_TIME_relative_divide(), GNUNET_TRANSPORT_VS_UPDATE, GNUNET_YES, GST_ats_add_address(), GST_ats_is_known_no_session(), GST_plugins_a2s(), GST_plugins_find(), ValidationEntry::known_to_ats, ValidationEntry::latency, ValidationEntry::network, ValidationEntry::next_validation, revalidate_address(), ValidationEntry::revalidation_task, GNUNET_ATS_Properties::scope, GNUNET_HELLO_Address::transport_name, ValidationEntry::valid_until, and validation_entry_changed().

Referenced by process_peerinfo_hello().

872 {
873  const struct GNUNET_HELLO_Message *hello = cls;
874  struct ValidationEntry *ve;
875  struct GNUNET_PeerIdentity pid;
876  struct GNUNET_ATS_Properties prop;
878 
879  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
880  return GNUNET_OK; /* expired */
881  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
882  {
883  GNUNET_break (0);
884  return GNUNET_OK; /* invalid HELLO !? */
885  }
886  if (NULL == (papi = GST_plugins_find (address->transport_name)))
887  {
888  /* might have been valid in the past, but we don't have that
889  plugin loaded right now */
890  return GNUNET_OK;
891  }
892  if (NULL ==
893  papi->address_to_string (papi->cls,
894  address->address,
895  address->address_length))
896  {
897  /* Why do we try to add an ill-formed address? */
898  GNUNET_break (0);
900  "Address with %u bytes for plugin %s and peer %s is malformed\n",
901  (unsigned int) address->address_length,
902  address->transport_name,
903  GNUNET_i2s (&pid));
904  return GNUNET_OK;
905  }
906 
907  ve = find_validation_entry (address);
908  ve->network = papi->get_network_for_address (papi->cls,
909  address);
912  expiration);
913  if (NULL == ve->revalidation_task)
914  {
916  "Starting revalidations for valid address `%s'\n",
917  GST_plugins_a2s (ve->address));
920  }
923  memset (&prop, 0, sizeof (prop));
924  prop.scope = ve->network;
925  prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2);
926  if (GNUNET_YES != ve->known_to_ats)
927  {
928  ve->known_to_ats = GNUNET_YES;
929  GST_ats_add_address (address, &prop);
932  }
933  return GNUNET_OK;
934 }
size_t address_length
Number of bytes in address.
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:668
A HELLO message is used to exchange information about transports with other peers.
GNUNET_TRANSPORT_AddressToString address_to_string
Function that will be called to convert a binary address to a string (numeric conversion only)...
struct GNUNET_TIME_Absolute valid_until
Until when is this address valid? ZERO if it is not currently considered valid.
const void * address
Binary representation of the address (plugin-specific).
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Information about an address under validation.
void GST_ats_add_address(const struct GNUNET_HELLO_Address *address, const struct GNUNET_ATS_Properties *prop)
Notify ATS about the new address including the network this address is located in.
int known_to_ats
Is this address known to ATS as valid right now?
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
static struct ValidationEntry * find_validation_entry(const struct GNUNET_HELLO_Address *address)
Find a ValidationEntry entry for the given neighbour that matches the given address and transport...
static void validation_entry_changed(struct ValidationEntry *ve, enum GNUNET_TRANSPORT_ValidationState state)
A validation entry changed.
ATS performance characteristics for an address.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_TIME_Relative latency
Last observed latency for this address (round-trip), delay between last PING sent and PONG received; ...
struct GNUNET_SCHEDULER_Task * revalidation_task
ID of task that will trigger address revalidation.
void * cls
Closure for all of the callbacks.
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:1273
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:317
const char * transport_name
Name of the transport plugin enabling the communication using this address.
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
int GST_ats_is_known_no_session(const struct GNUNET_HELLO_Address *address)
Test if ATS knows about this address.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
The identity of the host (wraps the signing key of the peer).
struct GNUNET_TIME_Absolute next_validation
At what time do we send the next validation request (PING)?
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
enum GNUNET_NetworkType network
Which network type does our address belong to?
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:525
static void revalidate_address(void *cls)
Do address validation again to keep address valid.
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_HELLO_Address * address
The address.
GNUNET_TRANSPORT_GetNetworkTypeForAddress get_network_for_address
Function to obtain the network type for an address.
Category of last resort.
Definition: gnunet_nt_lib.h:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_peerinfo_hello()

static void process_peerinfo_hello ( void *  cls,
const struct GNUNET_PeerIdentity peer,
const struct GNUNET_HELLO_Message hello,
const char *  err_msg 
)
static

Function called for any HELLO known to PEERINFO.

Parameters
clsunused (NULL)
peerid of the peer, NULL for last call (during iteration, as we are monitoring, this should never happen)
hellohello message for the peer (can be NULL)
err_msgerror message

Definition at line 947 of file gnunet-service-transport_validation.c.

References add_valid_address(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_iterate_addresses(), GNUNET_i2s(), GNUNET_log, GNUNET_NO, and GST_my_identity.

Referenced by GST_validation_start().

951 {
952  GNUNET_assert (NULL != peer);
953  if (NULL == hello)
954  return;
955  if (0 == memcmp (&GST_my_identity,
956  peer,
957  sizeof (struct GNUNET_PeerIdentity)))
958  {
959  /* Peerinfo returned own identity, skip validation */
960  return;
961  }
963  "Handling HELLO for peer `%s'\n",
964  GNUNET_i2s (peer));
965  GNUNET_assert (NULL ==
968  (void *) hello));
969 }
static struct GNUNET_PeerIdentity GST_my_identity
Our public key.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
struct GNUNET_HELLO_Message * GNUNET_HELLO_iterate_addresses(const struct GNUNET_HELLO_Message *msg, int return_modified, GNUNET_HELLO_AddressIterator it, void *it_cls)
Iterate over all of the addresses in the HELLO.
Definition: hello.c:254
static int add_valid_address(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Iterator which adds the given address to the set of validated addresses.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GST_validation_start()

void GST_validation_start ( unsigned int  max_fds)

Start the validation subsystem.

Parameters
max_fdsmaximum number of fds to use

Initialization for validation throttling

We have a maximum number max_fds of connections we can use for validation We monitor the number of validations in parallel and start to throttle it when doing to many validations in parallel: if (running validations < (max_fds / 2))

  • "fast start": run validation immediately
  • have delay of (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us) / (max_fds / 2) (300 sec / ~150 == ~2 sec.) between two validations

Definition at line 978 of file gnunet-service-transport_validation.c.

References gettext_noop, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, GNUNET_CONTAINER_multipeermap_create(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_NO, GNUNET_PEERINFO_notify(), GNUNET_STATISTICS_set(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_YES, GST_cfg, GST_stats, process_peerinfo_hello(), GNUNET_TIME_Relative::rel_value_us, validation_delay, VALIDATION_MAP_SIZE, validation_next, validations_fast_start_threshold, and validations_running.

Referenced by run().

979 {
994  validations_fast_start_threshold = (max_fds / 2);
997  gettext_noop ("# validations running"),
999  GNUNET_NO);
1001  "Validation uses a fast start threshold of %u connections and a delay of %s\n",
1004  GNUNET_YES));
1006  GNUNET_NO);
1008  &process_peerinfo_hello, NULL);
1009 }
uint64_t rel_value_us
The actual value.
static struct GNUNET_TIME_Absolute validation_next
When is next validation allowed.
#define GNUNET_NO
Definition: gnunet_common.h:81
struct GNUNET_CONTAINER_MultiPeerMap * GNUNET_CONTAINER_multipeermap_create(unsigned int len, int do_not_copy_keys)
Create a multi peer map (hash map for public keys of peers).
struct GNUNET_PEERINFO_NotifyContext * GNUNET_PEERINFO_notify(const struct GNUNET_CONFIGURATION_Handle *cfg, int include_friend_only, GNUNET_PEERINFO_Processor callback, void *callback_cls)
Call a method whenever our known information about peers changes.
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
static unsigned int validations_running
Number of validations running; any PING that was not yet matched by a PONG and for which we have not ...
#define VALIDATION_MAP_SIZE
Size of the validation map hashmap.
static void process_peerinfo_hello(void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello, const char *err_msg)
Function called for any HELLO known to PEERINFO.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:727
static struct GNUNET_CONTAINER_MultiPeerMap * validation_map
Map of PeerIdentities to &#39;struct ValidationEntry*&#39;s (addresses of the given peer that we are currentl...
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_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static struct GNUNET_TIME_Relative validation_delay
Minimum delay between to validations.
#define GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
After how long do we consider a connection to a peer dead if we don&#39;t receive messages from the peer...
static struct GNUNET_PEERINFO_NotifyContext * pnc
Context for peerinfo iteration.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
static const struct GNUNET_CONFIGURATION_Handle * GST_cfg
Configuration handle.
static unsigned int validations_fast_start_threshold
Validition fast start threshold.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GST_validation_stop()

void GST_validation_stop ( void  )

Stop the validation subsystem.

Definition at line 1016 of file gnunet-service-transport_validation.c.

References cleanup_validation_entry(), GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), and GNUNET_PEERINFO_notify_cancel().

Referenced by shutdown_task().

1017 {
1020  NULL);
1022  validation_map = NULL;
1024 }
void GNUNET_PEERINFO_notify_cancel(struct GNUNET_PEERINFO_NotifyContext *nc)
Stop notifying about changes.
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
static int cleanup_validation_entry(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Iterate over validation entries and free them.
static struct GNUNET_CONTAINER_MultiPeerMap * validation_map
Map of PeerIdentities to &#39;struct ValidationEntry*&#39;s (addresses of the given peer that we are currentl...
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
static struct GNUNET_PEERINFO_NotifyContext * pnc
Context for peerinfo iteration.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ multicast_pong()

static void multicast_pong ( void *  cls,
struct GNUNET_TIME_Absolute  valid_until,
struct GNUNET_TIME_Absolute  validation_block,
const struct GNUNET_HELLO_Address address 
)
static

Send the given PONG to the given address.

Parameters
clsthe PONG message
valid_untilis ZERO if we never validated the address, otherwise a time up to when we consider it (or was) valid
validation_blockis FOREVER if the address is for an unsupported plugin (from PEERINFO) is ZERO if the address is considered valid (no validation needed) otherwise a time in the future if we're currently denying re-validation
addresstarget address

Definition at line 1039 of file gnunet-service-transport_validation.c.

References ACCEPTABLE_PING_DELAY, GNUNET_TRANSPORT_PluginFunctions::cls, GNUNET_TRANSPORT_PluginFunctions::get_session, GNUNET_assert, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GST_ats_new_session(), GST_neighbours_notify_data_sent(), GST_plugins_find(), pong(), PONG_PRIORITY, GNUNET_TRANSPORT_PluginFunctions::send, and GNUNET_HELLO_Address::transport_name.

Referenced by GST_validation_handle_ping().

1043 {
1044  struct TransportPongMessage *pong = cls;
1045  struct GNUNET_TRANSPORT_PluginFunctions *papi;
1046  struct GNUNET_ATS_Session *session;
1047 
1048  papi = GST_plugins_find (address->transport_name);
1049  if (NULL == papi)
1050  {
1052  "Plugin %s not supported, cannot send PONG\n",
1053  address->transport_name);
1054  return;
1055  }
1056  GNUNET_assert (NULL != papi->send);
1057  GNUNET_assert (NULL != papi->get_session);
1058  session = papi->get_session(papi->cls, address);
1059  if (NULL == session)
1060  {
1061  GNUNET_break (0);
1062  return;
1063  }
1064  GST_ats_new_session (address, session);
1065  papi->send (papi->cls, session,
1066  (const char *) pong,
1067  ntohs (pong->header.size),
1068  PONG_PRIORITY,
1070  NULL, NULL);
1072  session,
1073  pong->header.size);
1074 }
GNUNET_TRANSPORT_CreateSession get_session
Function that will be called tell the plugin to create a session object.
GNUNET_TRANSPORT_TransmitFunction send
Function that the transport service will use to transmit data to another peer.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
#define PONG_PRIORITY
Priority to use for PONGs.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
void * cls
Closure for all of the callbacks.
#define ACCEPTABLE_PING_DELAY
How much delay is acceptable for sending the PING or PONG?
Information about ongoing sessions of the transport client.
Message used to validate a HELLO.
void GST_neighbours_notify_data_sent(const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, size_t size)
Track information about data we transmitted using the given address and session (used to notify ATS a...
const char * transport_name
Name of the transport plugin enabling the communication using this address.
struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
static void pong(struct GNUNET_CADET_Channel *channel, const struct CadetPingMessage *ping)
Reply with a pong to origin.
#define GNUNET_log(kind,...)
void GST_ats_new_session(const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session)
Notify ATS about a new session now existing for the given address.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GST_validation_handle_ping()

int GST_validation_handle_ping ( const struct GNUNET_PeerIdentity sender,
const struct GNUNET_MessageHeader hdr,
const struct GNUNET_HELLO_Address sender_address,
struct GNUNET_ATS_Session session 
)

We've received a PING.

If appropriate, generate a PONG.

Parameters
senderpeer sending the PING
hdrthe PING
sender_addressthe sender address as we got it
sessionsession we got the PING from
Returns
GNUNET_OK if the message was fine, GNUNET_SYSERR on serious error

Definition at line 1087 of file gnunet-service-transport_validation.c.

References _, ACCEPTABLE_PING_DELAY, GNUNET_HELLO_Address::address, GNUNET_HELLO_Address::address_length, TransportPongMessage::addrlen, TransportPingMessage::challenge, TransportPongMessage::challenge, GNUNET_TRANSPORT_PluginFunctions::check_address, GNUNET_TRANSPORT_PluginFunctions::cls, TransportPongMessage::expiration, GNUNET_TRANSPORT_PluginFunctions::get_session, gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_eddsa_sign(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_HELLO_ADDRESS_INFO_NONE, GNUNET_i2s(), GNUNET_i2s_full(), GNUNET_log, GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_TRANSPORT_PONG, GNUNET_NO, GNUNET_OK, GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN, GNUNET_snprintf(), GNUNET_STATISTICS_update(), GNUNET_strdup, GNUNET_SYSERR, GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_hton(), GNUNET_TIME_relative_to_absolute(), GNUNET_YES, GST_hello_test_address(), GST_my_identity, GST_my_private_key, GST_neighbours_notify_data_sent(), GST_plugins_a2s(), GST_plugins_find(), GST_stats, GST_validation_get_addresses(), TransportPongMessage::header, GNUNET_HELLO_Address::local_info, multicast_pong(), GNUNET_HELLO_Address::peer, ping(), plugin_name, pong(), PONG_PRIORITY, PONG_SIGNATURE_LIFETIME, GNUNET_CRYPTO_EccSignaturePurpose::purpose, TransportPongMessage::purpose, GNUNET_TIME_Relative::rel_value_us, ret, GNUNET_TRANSPORT_PluginFunctions::send, TransportPongMessage::signature, GNUNET_CRYPTO_EccSignaturePurpose::size, GNUNET_MessageHeader::size, TransportPingMessage::target, GNUNET_HELLO_Address::transport_name, and GNUNET_MessageHeader::type.

Referenced by GST_receive_callback().

1091 {
1092  const struct TransportPingMessage *ping;
1093  struct TransportPongMessage *pong;
1094  struct GNUNET_TRANSPORT_PluginFunctions *papi;
1095  struct GNUNET_CRYPTO_EddsaSignature *sig_cache;
1096  struct GNUNET_TIME_Absolute *sig_cache_exp;
1097  const char *addr;
1098  const char *addrend;
1099  char *plugin_name;
1100  char *pos;
1101  size_t len_address;
1102  size_t len_plugin;
1103  ssize_t ret;
1105 
1106  if (0 ==
1107  memcmp (&GST_my_identity,
1108  sender,
1109  sizeof (struct GNUNET_PeerIdentity)))
1110  return GNUNET_OK; /* our own, ignore! */
1111  if (ntohs (hdr->size) < sizeof (struct TransportPingMessage))
1112  {
1113  GNUNET_break_op (0);
1114  return GNUNET_SYSERR;
1115  }
1116  ping = (const struct TransportPingMessage *) hdr;
1117  if (0 !=
1118  memcmp (&ping->target,
1119  &GST_my_identity,
1120  sizeof (struct GNUNET_PeerIdentity)))
1121  {
1123  gettext_noop
1124  ("# PING message for different peer received"), 1,
1125  GNUNET_NO);
1126  return GNUNET_SYSERR;
1127  }
1129  gettext_noop ("# PING messages received"), 1,
1130  GNUNET_NO);
1131  addr = (const char *) &ping[1];
1132  len_address = ntohs (hdr->size) - sizeof (struct TransportPingMessage);
1133  /* peer wants to confirm that this is one of our addresses, this is what is
1134  * used for address validation */
1135 
1136  sig_cache = NULL;
1137  sig_cache_exp = NULL;
1138  papi = NULL;
1139  if (len_address > 0)
1140  {
1141  addrend = memchr (addr, '\0', len_address);
1142  if (NULL == addrend)
1143  {
1144  GNUNET_break_op (0);
1145  return GNUNET_SYSERR;
1146  }
1147  addrend++;
1148  len_plugin = strlen (addr) + 1;
1149  len_address -= len_plugin;
1151  address.address = addrend;
1152  address.address_length = len_address;
1153  address.transport_name = addr;
1154  address.peer = GST_my_identity;
1155 
1156  if (NULL == address.transport_name)
1157  {
1158  GNUNET_break (0);
1159  }
1160 
1161  if (0 != strstr (address.transport_name, "_client"))
1162  {
1163  plugin_name = GNUNET_strdup (address.transport_name);
1164  pos = strstr (plugin_name, "_client");
1165  GNUNET_assert (NULL != pos);
1166  GNUNET_snprintf (pos, strlen ("_server") + 1, "%s", "_server");
1167  }
1168  else
1169  plugin_name = GNUNET_strdup (address.transport_name);
1170 
1171  if (NULL == (papi = GST_plugins_find (plugin_name)))
1172  {
1173  /* we don't have the plugin for this address */
1175  _("Plugin `%s' not available, cannot confirm having this address\n"),
1176  plugin_name);
1177  GNUNET_free (plugin_name);
1178  return GNUNET_SYSERR;
1179  }
1180  GNUNET_free (plugin_name);
1181  if (GNUNET_OK !=
1182  papi->check_address (papi->cls,
1183  addrend,
1184  len_address))
1185  {
1187  gettext_noop
1188  ("# failed address checks during validation"), 1,
1189  GNUNET_NO);
1191  _("Address `%s' is not one of my addresses, not confirming PING\n"),
1193  return GNUNET_SYSERR;
1194  }
1195  else
1196  {
1198  gettext_noop
1199  ("# successful address checks during validation"), 1,
1200  GNUNET_NO);
1202  "Address `%s' is one of my addresses, confirming PING\n",
1204  }
1205 
1206  if (GNUNET_YES !=
1208  &sig_cache,
1209  &sig_cache_exp))
1210  {
1212  _("Not confirming PING from peer `%s' with address `%s' since I cannot confirm having this address.\n"),
1213  GNUNET_i2s (sender),
1215  return GNUNET_SYSERR;
1216  }
1217  }
1218  else
1219  {
1220  addrend = NULL; /* make gcc happy */
1221  len_plugin = 0;
1222  static struct GNUNET_CRYPTO_EddsaSignature no_address_signature;
1223  static struct GNUNET_TIME_Absolute no_address_signature_expiration;
1224 
1225  sig_cache = &no_address_signature;
1226  sig_cache_exp = &no_address_signature_expiration;
1227  }
1228 
1230  "I am `%s', sending PONG to peer `%s'\n",
1232  GNUNET_i2s (sender));
1233 
1234  /* message with structure:
1235  * [TransportPongMessage][Transport name][Address] */
1236 
1237  pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + len_address + len_plugin);
1238  pong->header.size =
1239  htons (sizeof (struct TransportPongMessage) + len_address + len_plugin);
1241  pong->purpose.size =
1242  htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
1243  sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) +
1244  len_address + len_plugin);
1246  GNUNET_memcpy (&pong->challenge, &ping->challenge, sizeof (ping->challenge));
1247  pong->addrlen = htonl (len_address + len_plugin);
1248  GNUNET_memcpy (&pong[1], addr, len_plugin); /* Copy transport plugin */
1249  if (len_address > 0)
1250  {
1251  GNUNET_assert (NULL != addrend);
1252  GNUNET_memcpy (&((char *) &pong[1])[len_plugin], addrend, len_address);
1253  }
1254  if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value_us <
1255  PONG_SIGNATURE_LIFETIME.rel_value_us / 4)
1256  {
1257  /* create / update cached sig */
1259  "Creating PONG signature to indicate ownership.\n");
1261  pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp);
1262  if (GNUNET_OK !=
1264  sig_cache))
1265  {
1267  _("Failed to create PONG signature for peer `%s'\n"), GNUNET_i2s (sender));
1268  }
1269  }
1270  else
1271  {
1272  pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp);
1273  }
1274  pong->signature = *sig_cache;
1275 
1276  GNUNET_assert (NULL != sender_address);
1277 
1278  /* first see if the session we got this PING from can be used to transmit
1279  * a response reliably */
1280  if (NULL == papi)
1281  {
1282  ret = -1;
1283  }
1284  else
1285  {
1286  GNUNET_assert (NULL != papi->send);
1287  GNUNET_assert (NULL != papi->get_session);
1288  if (NULL == session)
1289  {
1290  session = papi->get_session (papi->cls, sender_address);
1291  }
1292  if (NULL == session)
1293  {
1294  GNUNET_break (0);
1295  ret = -1;
1296  }
1297  else
1298  {
1299  ret = papi->send (papi->cls, session,
1300  (const char *) pong,
1301  ntohs (pong->header.size),
1303  NULL, NULL);
1304  if (-1 != ret)
1305  GST_neighbours_notify_data_sent (sender_address,
1306  session,
1307  pong->header.size);
1308  }
1309  }
1310  if (-1 != ret)
1311  {
1313  "Transmitted PONG to `%s' via reliable mechanism\n",
1314  GNUNET_i2s (sender));
1315  /* done! */
1317  gettext_noop
1318  ("# PONGs unicast via reliable transport"), 1,
1319  GNUNET_NO);
1320  GNUNET_free (pong);
1321  return GNUNET_OK;
1322  }
1323 
1324  /* no reliable method found, try transmission via all known addresses */
1326  gettext_noop
1327  ("# PONGs multicast to all available addresses"), 1,
1328  GNUNET_NO);
1330  &multicast_pong, pong);
1331  GNUNET_free (pong);
1332  return GNUNET_OK;
1333 }
static struct GNUNET_PeerIdentity GST_my_identity
Our public key.
static void ping(void *cls)
Send a ping to destination.
GNUNET_TRANSPORT_CreateSession get_session
Function that will be called tell the plugin to create a session object.
uint64_t rel_value_us
The actual value.
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
int GNUNET_snprintf(char *buf, size_t size, const char *format,...)
Like snprintf, just aborts if the buffer is of insufficient size.
GNUNET_TRANSPORT_TransmitFunction send
Function that the transport service will use to transmit data to another peer.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_PONG.
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
void GST_validation_get_addresses(const struct GNUNET_PeerIdentity *target, GST_ValidationAddressCallback cb, void *cb_cls)
Call the given function for each address for the given target.
struct GNUNET_CRYPTO_EddsaSignature signature
Signature.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
int GNUNET_CRYPTO_eddsa_sign(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition: crypto_ecc.c:989
#define GNUNET_NO
Definition: gnunet_common.h:81
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define PONG_PRIORITY
Priority to use for PONGs.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
static int ret
Final status code.
Definition: gnunet-arm.c:89
uint32_t addrlen
Size of address appended to this message (part of what is being signed, hence not redundant)...
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
int GST_hello_test_address(const struct GNUNET_HELLO_Address *address, struct GNUNET_CRYPTO_EddsaSignature **sig, struct GNUNET_TIME_Absolute **sig_expiration)
Test if a particular address is one of ours.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static void multicast_pong(void *cls, struct GNUNET_TIME_Absolute valid_until, struct GNUNET_TIME_Absolute validation_block, const struct GNUNET_HELLO_Address *address)
Send the given PONG to the given address.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
Message used to ask a peer to validate receipt (to check an address from a HELLO).
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
void * cls
Closure for all of the callbacks.
#define GNUNET_memcpy(dst, src, n)
#define ACCEPTABLE_PING_DELAY
How much delay is acceptable for sending the PING or PONG?
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Message used to validate a HELLO.
void GST_neighbours_notify_data_sent(const struct GNUNET_HELLO_Address *address, struct GNUNET_ATS_Session *session, size_t size)
Track information about data we transmitted using the given address and session (used to notify ATS a...
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
static char * plugin_name
Solver plugin name as string.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
uint32_t challenge
Challenge code from PING (showing freshness).
static void pong(struct GNUNET_CADET_Channel *channel, const struct CadetPingMessage *ping)
Reply with a pong to origin.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN to confirm that this is a plausible address for the signi...
#define PONG_SIGNATURE_LIFETIME
How long is a PONG signature valid? We&#39;ll recycle a signature until 1/4 of this time is remaining...
an ECC signature using EdDSA.
#define GNUNET_MESSAGE_TYPE_TRANSPORT_PONG
Transport PONG message.
static struct GNUNET_CRYPTO_EddsaPrivateKey * GST_my_private_key
Our private key.
The identity of the host (wraps the signing key of the peer).
No additional information.
#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN
Signature for confirming that this peer uses a particular address.
An address for communicating with a peer.
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
GNUNET_TRANSPORT_CheckAddress check_address
Function that will be called to check if a binary address for this plugin is well-formed and correspo...
uint32_t challenge
Challenge code (to ensure fresh reply).
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
static char * address
GNS address for this phone.
struct GNUNET_PeerIdentity target
Who is the intended recipient?
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_malloc(size)
Wrapper around malloc.
struct GNUNET_TIME_AbsoluteNBO expiration
When does this signature expire?
#define GNUNET_free(ptr)
Wrapper around free.
#define gettext_noop(String)
Definition: gettext.h:69
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GST_validation_handle_address()

void GST_validation_handle_address ( const struct GNUNET_HELLO_Address address)

Validate an individual address.

Parameters
addressaddress we should try to validate

Definition at line 1342 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, find_validation_entry(), GNUNET_ERROR_TYPE_INFO, GNUNET_i2s(), GNUNET_log, GNUNET_SCHEDULER_add_now(), GST_plugins_a2s(), GST_plugins_find(), GNUNET_HELLO_Address::peer, revalidate_address(), ValidationEntry::revalidation_task, and GNUNET_HELLO_Address::transport_name.

Referenced by plugin_env_session_start_bl_check_cont(), and validate_address_iterator().

1343 {
1344  struct GNUNET_TRANSPORT_PluginFunctions *papi;
1345  struct ValidationEntry *ve;
1346 
1347  papi = GST_plugins_find (address->transport_name);
1348  if (NULL == papi)
1349  {
1350  /* This plugin is currently unvailable ... ignore */
1352  "No plugin available for %s\n",
1353  address->transport_name);
1354  return;
1355  }
1356  ve = find_validation_entry (address);
1357  if (NULL == ve->revalidation_task)
1358  {
1360  "Validation process started for fresh address `%s' of %s\n",
1361  GST_plugins_a2s (ve->address),
1362  GNUNET_i2s (&ve->address->peer));
1364  }
1365  else
1366  {
1368  "Validation already running for address `%s' of %s\n",
1369  GST_plugins_a2s (ve->address),
1370  GNUNET_i2s (&ve->address->peer));
1371  }
1372 }
Information about an address under validation.
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
static struct ValidationEntry * find_validation_entry(const struct GNUNET_HELLO_Address *address)
Find a ValidationEntry entry for the given neighbour that matches the given address and transport...
struct GNUNET_SCHEDULER_Task * revalidation_task
ID of task that will trigger address revalidation.
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:1273
const char * transport_name
Name of the transport plugin enabling the communication using this address.
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
struct GNUNET_PeerIdentity peer
For which peer is this an address?
#define GNUNET_log(kind,...)
static void revalidate_address(void *cls)
Do address validation again to keep address valid.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_HELLO_Address * address
The address.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate_address_iterator()

static int validate_address_iterator ( void *  cls,
const struct GNUNET_HELLO_Address address,
struct GNUNET_TIME_Absolute  expiration 
)
static

Iterator callback to go over all addresses and try to validate them (unless blocked or already validated).

Parameters
clsNULL
addressthe address
expirationexpiration time
Returns
GNUNET_OK (keep the address)

Definition at line 1385 of file gnunet-service-transport_validation.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_OK, GNUNET_TIME_absolute_get_remaining(), and GST_validation_handle_address().

Referenced by GST_validation_handle_hello().

1388 {
1389  if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us)
1390  {
1392  "Skipping expired address from HELLO\n");
1393  return GNUNET_OK; /* expired */
1394  }
1396  return GNUNET_OK;
1397 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
void GST_validation_handle_address(const struct GNUNET_HELLO_Address *address)
Validate an individual address.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_valid_peer_address()

static ssize_t add_valid_peer_address ( void *  cls,
size_t  max,
void *  buf 
)
static

Add the validated peer address to the HELLO.

Parameters
clsthe struct ValidationEntry * with the validated address
maxspace in buf
bufwhere to add the address
Returns
number of bytes written, GNUNET_SYSERR to signal the end of the iteration.

Definition at line 1410 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, ValidationEntry::copied, GNUNET_HELLO_add_address(), GNUNET_SYSERR, GNUNET_YES, and ValidationEntry::valid_until.

Referenced by GST_validation_handle_pong().

1413 {
1414  struct ValidationEntry *ve = cls;
1415 
1416  if (GNUNET_YES == ve->copied)
1417  return GNUNET_SYSERR; /* Done */
1418  ve->copied = GNUNET_YES;
1419  return GNUNET_HELLO_add_address (ve->address,
1420  ve->valid_until,
1421  buf,
1422  max);
1423 }
struct GNUNET_TIME_Absolute valid_until
Until when is this address valid? ZERO if it is not currently considered valid.
int copied
When passing the address in add_valid_peer_address(), did we copy the address to the HELLO yet...
Information about an address under validation.
static char buf[2048]
size_t GNUNET_HELLO_add_address(const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration, char *target, size_t max)
Copy the given address information into the given buffer using the format of HELLOs.
Definition: hello.c:109
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_HELLO_Address * address
The address.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GST_validation_handle_pong()

int GST_validation_handle_pong ( const struct GNUNET_PeerIdentity sender,
const struct GNUNET_MessageHeader hdr 
)

We've received a PONG.

Check if it matches a pending PING and mark the respective address as confirmed.

Parameters
senderpeer sending the PONG
hdrthe PONG
Returns
GNUNET_OK if the message was fine, GNUNET_SYSERR on serious error

Definition at line 1435 of file gnunet-service-transport_validation.c.

References add_valid_peer_address(), GNUNET_HELLO_Address::address, ValidationEntry::address, GNUNET_HELLO_Address::address_length, TransportPongMessage::addrlen, ValidationEntry::copied, GNUNET_ATS_Properties::delay, ValidationEntry::expecting_pong, TransportPongMessage::expiration, find_validation_entry(), gettext_noop, GNUNET_assert, GNUNET_break, GNUNET_break_op, GNUNET_CRYPTO_eddsa_verify(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_HELLO_ADDRESS_INFO_NONE, GNUNET_HELLO_create(), GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_NT_UNSPECIFIED, GNUNET_OK, GNUNET_PEERINFO_add_peer(), GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN, GNUNET_STATISTICS_set(), GNUNET_STATISTICS_update(), GNUNET_SYSERR, GNUNET_TIME_absolute_get_duration(), GNUNET_TIME_absolute_get_remaining(), GNUNET_TIME_absolute_ntoh(), GNUNET_TIME_relative_divide(), GNUNET_TIME_relative_to_absolute(), GNUNET_TRANSPORT_VS_UPDATE, GNUNET_YES, GST_ats_add_address(), GST_ats_is_known_no_session(), GST_ats_update_delay(), GST_my_identity, GST_peerinfo, GST_plugins_a2s(), GST_plugins_find(), GST_stats, HELLO_ADDRESS_EXPIRATION, ValidationEntry::known_to_ats, ValidationEntry::latency, GNUNET_HELLO_Address::local_info, ValidationEntry::network, GNUNET_HELLO_Address::peer, pong(), ValidationEntry::pong_sig_cache, ValidationEntry::pong_sig_valid_until, GNUNET_PeerIdentity::public_key, TransportPongMessage::purpose, GNUNET_TIME_Relative::rel_value_us, GNUNET_ATS_Properties::scope, ValidationEntry::send_time, TransportPongMessage::signature, size, GNUNET_MessageHeader::size, GNUNET_HELLO_Address::transport_name, ValidationEntry::valid_until, validation_entry_changed(), and validations_running.

Referenced by GST_receive_callback().

1437 {
1438  const struct TransportPongMessage *pong;
1439  struct ValidationEntry *ve;
1440  const char *tname;
1441  const char *addr;
1442  size_t addrlen;
1443  size_t slen;
1444  size_t size;
1445  struct GNUNET_HELLO_Message *hello;
1447  int sig_res;
1448  int do_verify;
1449 
1450  if (0 ==
1451  memcmp (&GST_my_identity,
1452  sender,
1453  sizeof (struct GNUNET_PeerIdentity)))
1454  return GNUNET_OK; /* our own, ignore! */
1455 
1456  if (ntohs (hdr->size) < sizeof (struct TransportPongMessage))
1457  {
1458  GNUNET_break_op (0);
1459  return GNUNET_SYSERR;
1460  }
1462  gettext_noop ("# PONG messages received"), 1,
1463  GNUNET_NO);
1464 
1465  /* message with structure:
1466  * [TransportPongMessage][Transport name][Address] */
1467 
1468  pong = (const struct TransportPongMessage *) hdr;
1469  tname = (const char *) &pong[1];
1470  size = ntohs (hdr->size) - sizeof (struct TransportPongMessage);
1471  addr = memchr (tname, '\0', size);
1472  if (NULL == addr)
1473  {
1474  GNUNET_break_op (0);
1475  return GNUNET_SYSERR;
1476  }
1477  addr++;
1478  slen = strlen (tname) + 1;
1479  addrlen = size - slen;
1480 
1481  if (NULL == GST_plugins_find (tname))
1482  {
1483  /* we got the PONG, but the transport plugin specified in it
1484  is not supported by this peer, so this cannot be a good
1485  PONG for us. */
1486  GNUNET_break_op (0);
1487  return GNUNET_OK;
1488  }
1489 
1490  address.peer = *sender;
1491  address.address = addr;
1492  address.address_length = addrlen;
1493  address.transport_name = tname;
1496  if ((NULL == ve) || (GNUNET_NO == ve->expecting_pong))
1497  {
1499  gettext_noop
1500  ("# PONGs dropped, no matching pending validation"),
1501  1, GNUNET_NO);
1502  return GNUNET_OK;
1503  }
1504  /* now check that PONG is well-formed */
1505  if (0 != memcmp (&ve->address->peer,
1506  sender,
1507  sizeof (struct GNUNET_PeerIdentity)))
1508  {
1509  GNUNET_break_op (0);
1510  return GNUNET_SYSERR;
1511  }
1512  if (0 ==
1515  {
1517  gettext_noop
1518  ("# PONGs dropped, signature expired"), 1,
1519  GNUNET_NO);
1520  return GNUNET_SYSERR;
1521  }
1522 
1523  sig_res = GNUNET_SYSERR;
1524  do_verify = GNUNET_YES;
1526  {
1527  /* We have a cached and valid signature for this peer,
1528  * try to compare instead of verify */
1529  if (0 == memcmp (&ve->pong_sig_cache,
1530  &pong->signature,
1531  sizeof (struct GNUNET_CRYPTO_EddsaSignature)))
1532  {
1533  /* signatures are identical, we can skip verification */
1534  sig_res = GNUNET_OK;
1535  do_verify = GNUNET_NO;
1536  }
1537  else
1538  {
1539  sig_res = GNUNET_SYSERR;
1540  /* signatures do not match, we have to verify */
1541  }
1542  }
1543 
1544  if (GNUNET_YES == do_verify)
1545  {
1546  /* Do expensive verification */
1548  &pong->purpose,
1549  &pong->signature,
1550  &ve->address->peer.public_key);
1551  if (sig_res == GNUNET_SYSERR)
1552  {
1553  GNUNET_break_op (0);
1555  "Failed to verify: invalid signature on address `%s':%s from peer `%s'\n",
1556  tname,
1557  GST_plugins_a2s (ve->address),
1558  GNUNET_i2s (sender));
1559  }
1560  }
1561  if (sig_res == GNUNET_SYSERR)
1562  {
1563  GNUNET_break_op (0);
1564  return GNUNET_SYSERR;
1565  }
1566 
1568  "Validation process successful for peer `%s' with plugin `%s' address `%s'\n",
1569  GNUNET_i2s (sender),
1570  tname,
1571  GST_plugins_a2s (ve->address));
1573  gettext_noop ("# validations succeeded"),
1574  1,
1575  GNUNET_NO);
1576  /* validity achieved, remember it! */
1577  ve->expecting_pong = GNUNET_NO;
1579  ve->pong_sig_cache = pong->signature;
1582  {
1583  if (GNUNET_YES == ve->known_to_ats)
1584  {
1589  }
1590  else
1591  {
1592  struct GNUNET_ATS_Properties prop;
1593 
1594  memset (&prop, 0, sizeof (prop));
1596  prop.scope = ve->network;
1597  prop.delay = GNUNET_TIME_relative_divide (ve->latency, 2);
1600  ve->known_to_ats = GNUNET_YES;
1601  GST_ats_add_address (ve->address, &prop);
1604  }
1605  }
1606  if (validations_running > 0)
1607  {
1610  gettext_noop ("# validations running"),
1612  GNUNET_NO);
1614  "Validation finished, %u validation processes running\n",
1616  }
1617  else
1618  {
1619  GNUNET_break (0);
1620  }
1621 
1622  /* Notify about new validity */
1625 
1626  /* build HELLO to store in PEERINFO */
1628  gettext_noop ("# HELLOs given to peerinfo"),
1629  1,
1630  GNUNET_NO);
1631  ve->copied = GNUNET_NO;
1632  hello = GNUNET_HELLO_create (&ve->address->peer.public_key,
1634  ve,
1635  GNUNET_NO);
1636  GNUNET_break (NULL !=
1638  hello,
1639  NULL,
1640  NULL));
1641  GNUNET_free (hello);
1642  return GNUNET_OK;
1643 }
static struct GNUNET_PeerIdentity GST_my_identity
Our public key.
A HELLO message is used to exchange information about transports with other peers.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
uint64_t rel_value_us
The actual value.
struct GNUNET_TIME_Absolute valid_until
Until when is this address valid? ZERO if it is not currently considered valid.
int expecting_pong
Are we expecting a PONG message for this validation entry?
struct GNUNET_HELLO_Message * GNUNET_HELLO_create(const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, GNUNET_HELLO_GenerateAddressListCallback addrgen, void *addrgen_cls, int friend_only)
Construct a HELLO message given the public key, expiration time and an iterator that spews the transp...
Definition: hello.c:204
int copied
When passing the address in add_valid_peer_address(), did we copy the address to the HELLO yet...
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition: time.c:245
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CRYPTO_EddsaSignature signature
Signature.
Information about an address under validation.
void GST_ats_add_address(const struct GNUNET_HELLO_Address *address, const struct GNUNET_ATS_Properties *prop)
Notify ATS about the new address including the network this address is located in.
int known_to_ats
Is this address known to ATS as valid right now?
static ssize_t add_valid_peer_address(void *cls, size_t max, void *buf)
Add the validated peer address to the HELLO.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
void GNUNET_STATISTICS_update(struct GNUNET_STATISTICS_Handle *handle, const char *name, int64_t delta, int make_persistent)
Set statistic value for the peer.
uint32_t addrlen
Size of address appended to this message (part of what is being signed, hence not redundant)...
static struct ValidationEntry * find_validation_entry(const struct GNUNET_HELLO_Address *address)
Find a ValidationEntry entry for the given neighbour that matches the given address and transport...
static void validation_entry_changed(struct ValidationEntry *ve, enum GNUNET_TRANSPORT_ValidationState state)
A validation entry changed.
ATS performance characteristics for an address.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_TIME_Relative latency
Last observed latency for this address (round-trip), delay between last PING sent and PONG received; ...
static struct GNUNET_STATISTICS_Handle * GST_stats
Statistics handle.
int GNUNET_CRYPTO_eddsa_verify(uint32_t purpose, const struct GNUNET_CRYPTO_EccSignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition: crypto_ecc.c:1116
static unsigned int validations_running
Number of validations running; any PING that was not yet matched by a PONG and for which we have not ...
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
Message used to validate a HELLO.
const char * GST_plugins_a2s(const struct GNUNET_HELLO_Address *address)
Convert a given address to a human-readable format.
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_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
struct GNUNET_MQ_Envelope * GNUNET_PEERINFO_add_peer(struct GNUNET_PEERINFO_Handle *h, const struct GNUNET_HELLO_Message *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
Add a host to the persistent list.
Definition: peerinfo_api.c:557
int GST_ats_is_known_no_session(const struct GNUNET_HELLO_Address *address)
Test if ATS knows about this address.
struct GNUNET_CRYPTO_EddsaSignature pong_sig_cache
Cached PONG signature.
static void pong(struct GNUNET_CADET_Channel *channel, const struct CadetPingMessage *ping)
Reply with a pong to origin.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN to confirm that this is a plausible address for the signi...
struct GNUNET_PeerIdentity peer
For which peer is this an address?
an ECC signature using EdDSA.
#define HELLO_ADDRESS_EXPIRATION
After how long do we expire an address in a HELLO that we just validated? This value is also used for...
The identity of the host (wraps the signing key of the peer).
No additional information.
struct GNUNET_PEERINFO_Handle * GST_peerinfo
Handle to peerinfo service.
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:373
#define GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN
Signature for confirming that this peer uses a particular address.
An address for communicating with a peer.
void GST_ats_update_delay(const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Relative delay)
Notify ATS about delay changes to properties of an address.
struct GNUNET_TIME_Absolute pong_sig_valid_until
Until when is the cached PONG signature valid? ZERO if it is not currently considered valid...
#define GNUNET_log(kind,...)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_remaining(struct GNUNET_TIME_Absolute future)
Given a timestamp in the future, how much time remains until then?
Definition: time.c:331
enum GNUNET_NetworkType network
Which network type does our address belong to?
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:525
#define GNUNET_YES
Definition: gnunet_common.h:80
struct GNUNET_TIME_Absolute send_time
At what time did we send the latest validation request (PING)?
static char * address
GNS address for this phone.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_TIME_AbsoluteNBO expiration
When does this signature expire?
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_HELLO_Address * address
The address.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
#define gettext_noop(String)
Definition: gettext.h:69
Category of last resort.
Definition: gnunet_nt_lib.h:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GST_validation_handle_hello()

int GST_validation_handle_hello ( const struct GNUNET_MessageHeader hello)

We've received a HELLO, check which addresses are new and trigger validation.

Parameters
hellothe HELLO we received
Returns
GNUNET_OK if the message was fine, GNUNET_SYSERR on serious error

Definition at line 1654 of file gnunet-service-transport_validation.c.

References GNUNET_assert, GNUNET_break_op, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_get_id(), GNUNET_HELLO_is_friend_only(), GNUNET_HELLO_iterate_addresses(), GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, GST_my_identity, GNUNET_MessageHeader::size, and validate_address_iterator().

Referenced by GST_receive_callback(), and handle_client_hello().

1655 {
1656  const struct GNUNET_HELLO_Message *hm =
1657  (const struct GNUNET_HELLO_Message *) hello;
1658  struct GNUNET_PeerIdentity pid;
1659  int friend;
1660 
1661  friend = GNUNET_HELLO_is_friend_only (hm);
1662  if ( ( (GNUNET_YES != friend) &&
1663  (GNUNET_NO != friend) ) ||
1664  (GNUNET_OK != GNUNET_HELLO_get_id (hm, &pid)) )
1665  {
1666  /* malformed HELLO */
1667  GNUNET_break_op (0);
1668  return GNUNET_SYSERR;
1669  }
1670  if (0 ==
1671  memcmp (&GST_my_identity,
1672  &pid,
1673  sizeof (struct GNUNET_PeerIdentity)))
1674  {
1675  /* got our own HELLO, how boring */
1677  "Validation received our own HELLO (%s), ignoring\n",
1678  GNUNET_i2s (&pid));
1679  return GNUNET_OK;
1680  }
1682  "Validation received HELLO message for peer `%s' with size %u, checking for new addresses\n",
1683  GNUNET_i2s (&pid),
1684  ntohs (hello->size));
1685  GNUNET_assert (NULL ==
1687  GNUNET_NO,
1689  NULL));
1690  return GNUNET_OK;
1691 }
static struct GNUNET_PeerIdentity GST_my_identity
Our public key.
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:668
A HELLO message is used to exchange information about transports with other peers.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_HELLO_Message * GNUNET_HELLO_iterate_addresses(const struct GNUNET_HELLO_Message *msg, int return_modified, GNUNET_HELLO_AddressIterator it, void *it_cls)
Iterate over all of the addresses in the HELLO.
Definition: hello.c:254
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:89
static int validate_address_iterator(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Iterator callback to go over all addresses and try to validate them (unless blocked or already valida...
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
Here is the call graph for this function:
Here is the caller graph for this function:

◆ iterate_addresses()

static int iterate_addresses ( void *  cls,
const struct GNUNET_PeerIdentity key,
void *  value 
)
static

Call the callback in the closure for each validation entry.

Parameters
clsthe struct IteratorContext
keythe peer's identity
valuethe struct ValidationEntry
Returns
GNUNET_OK (continue to iterate)

Definition at line 1721 of file gnunet-service-transport_validation.c.

References ValidationEntry::address, IteratorContext::cb, IteratorContext::cb_cls, GNUNET_OK, ValidationEntry::revalidation_block, ValidationEntry::valid_until, and value.

Referenced by GST_validation_get_addresses().

1724 {
1725  struct IteratorContext *ic = cls;
1726  struct ValidationEntry *ve = value;
1727 
1728  ic->cb (ic->cb_cls,
1729  ve->valid_until,
1730  ve->revalidation_block,
1731  ve->address);
1732  return GNUNET_OK;
1733 }
struct GNUNET_TIME_Absolute revalidation_block
How long until we can try to validate this address again? FOREVER if the address is for an unsupporte...
struct GNUNET_TIME_Absolute valid_until
Until when is this address valid? ZERO if it is not currently considered valid.
Information about an address under validation.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
Closure for the neighbours_iterate() function.
static char * value
Value of the record to add/remove.
GST_NeighbourIterator cb
Function to call on each connected neighbour.
struct GNUNET_HELLO_Address * address
The address.
Here is the caller graph for this function:

◆ GST_validation_get_addresses()

void GST_validation_get_addresses ( const struct GNUNET_PeerIdentity target,
GST_ValidationAddressCallback  cb,
void *  cb_cls 
)

Call the given function for each address for the given target.

Can either give a snapshot (synchronous API) or be continuous.

Parameters
targetpeer information is requested for
cbfunction to call; will not be called after this function returns
cb_clsclosure for cb

Definition at line 1745 of file gnunet-service-transport_validation.c.

References IteratorContext::cb, IteratorContext::cb_cls, GNUNET_CONTAINER_multipeermap_get_multiple(), and iterate_addresses().

Referenced by GST_validation_handle_ping().

1748 {
1749  struct IteratorContext ic;
1750 
1751  ic.cb = cb;
1752  ic.cb_cls = cb_cls;
1754  target,
1755  &iterate_addresses, &ic);
1756 }
static int iterate_addresses(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Call the callback in the closure for each validation entry.
Closure for the neighbours_iterate() function.
static struct GNUNET_CONTAINER_MultiPeerMap * validation_map
Map of PeerIdentities to &#39;struct ValidationEntry*&#39;s (addresses of the given peer that we are currentl...
GST_NeighbourIterator cb
Function to call on each connected neighbour.
int GNUNET_CONTAINER_multipeermap_get_multiple(struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map that match a particular key.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GST_validation_set_address_use()

void GST_validation_set_address_use ( const struct GNUNET_HELLO_Address address,
int  in_use 
)

Update if we are using an address for a connection actively right now.

Based on this, the validation module will measure latency for the address more or less often.

Parameters
addressthe address that we are now using (or not)
in_useGNUNET_YES if we are now using the address for a connection, GNUNET_NO if we are no longer using the address for a connection

Definition at line 1769 of file gnunet-service-transport_validation.c.

References find_validation_entry(), GNUNET_break, GNUNET_HELLO_address_check_option(), GNUNET_HELLO_ADDRESS_INFO_INBOUND, GNUNET_SCHEDULER_add_now(), GNUNET_SCHEDULER_cancel(), GNUNET_YES, GST_plugins_find(), ValidationEntry::in_use, revalidate_address(), ValidationEntry::revalidation_task, and GNUNET_HELLO_Address::transport_name.

Referenced by free_address(), and set_primary_address().

1771 {
1772  struct ValidationEntry *ve;
1773 
1774  if (GNUNET_HELLO_address_check_option (address,
1776  return; /* ignore inbound for validation */
1777  if (NULL == GST_plugins_find (address->transport_name))
1778  {
1779  /* How can we use an address for which we don't have the plugin? */
1780  GNUNET_break (0);
1781  return;
1782  }
1783  ve = find_validation_entry (address);
1784  if (NULL == ve)
1785  {
1786  GNUNET_break (0);
1787  return;
1788  }
1789  if (in_use == ve->in_use)
1790  return;
1791  ve->in_use = in_use;
1792  if (GNUNET_YES == in_use)
1793  {
1794  /* from now on, higher frequeny, so reschedule now */
1795  if (NULL != ve->revalidation_task)
1798  ve);
1799  }
1800 }
int in_use
Are we currently using this address for a connection?
Information about an address under validation.
static struct ValidationEntry * find_validation_entry(const struct GNUNET_HELLO_Address *address)
Find a ValidationEntry entry for the given neighbour that matches the given address and transport...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct GNUNET_SCHEDULER_Task * revalidation_task
ID of task that will trigger address revalidation.
int GNUNET_HELLO_address_check_option(const struct GNUNET_HELLO_Address *address, enum GNUNET_HELLO_AddressInfo option)
Check if an address has a local option set.
Definition: address.c:39
This is an inbound address and cannot be used to initiate an outbound connection to another peer...
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:1273
const char * transport_name
Name of the transport plugin enabling the communication using this address.
struct GNUNET_TRANSPORT_PluginFunctions * GST_plugins_find(const char *name)
Obtain the plugin API based on a plugin name.
static void revalidate_address(void *cls)
Do address validation again to keep address valid.
#define GNUNET_YES
Definition: gnunet_common.h:80
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:965
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ validation_map

struct GNUNET_CONTAINER_MultiPeerMap* validation_map
static

Map of PeerIdentities to 'struct ValidationEntry*'s (addresses of the given peer that we are currently validating, have validated or are blocked from re-validation for a while).

Definition at line 331 of file gnunet-service-transport_validation.c.

◆ pnc

struct GNUNET_PEERINFO_NotifyContext* pnc
static

Context for peerinfo iteration.

Definition at line 336 of file gnunet-service-transport_validation.c.

◆ validation_delay

struct GNUNET_TIME_Relative validation_delay
static

Minimum delay between to validations.

Definition at line 341 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_start(), and transmit_ping_if_allowed().

◆ validations_running

unsigned int validations_running
static

Number of validations running; any PING that was not yet matched by a PONG and for which we have not yet hit the timeout is considered a running 'validation'.

Definition at line 348 of file gnunet-service-transport_validation.c.

Referenced by cleanup_validation_entry(), GST_validation_handle_pong(), GST_validation_start(), revalidate_address(), and transmit_ping_if_allowed().

◆ validations_fast_start_threshold

unsigned int validations_fast_start_threshold
static

Validition fast start threshold.

Definition at line 353 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_start(), and revalidate_address().

◆ validation_next

struct GNUNET_TIME_Absolute validation_next
static

When is next validation allowed.

Definition at line 358 of file gnunet-service-transport_validation.c.

Referenced by GST_validation_start(), revalidate_address(), and transmit_ping_if_allowed().