GNUnet  0.11.x
Data Structures | Macros | Functions | Variables
gnunet-service-peerinfo.c File Reference

maintains list of known peers More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_hello_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_statistics_service.h"
#include "peerinfo.h"
Include dependency graph for gnunet-service-peerinfo.c:

Go to the source code of this file.

Data Structures

struct  HostEntry
 In-memory cache of known hosts. More...
 
struct  ReadHostFileContext
 Result of reading a file. More...
 
struct  DirScanContext
 Closure for hosts_directory_scan_callback(). More...
 
struct  TransmitContext
 Closure for add_to_tc() More...
 

Macros

#define DATA_HOST_FREQ   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)
 How often do we scan the HOST_DIR for new entries? More...
 
#define DATA_HOST_CLEAN_FREQ   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60)
 How often do we discard old entries in data/hosts/? More...
 

Functions

static struct InfoMessagemake_info_message (const struct HostEntry *he, int include_friend_only)
 Notify all clients in the notify list about the given host entry changing. More...
 
static int discard_expired (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Address iterator that causes expired entries to be discarded. More...
 
static int count_addresses (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Address iterator that counts the remaining addresses. More...
 
static char * get_host_filename (const struct GNUNET_PeerIdentity *id)
 Get the filename under which we would store the GNUNET_HELLO_Message for the given host and protocol. More...
 
static void notify_all (struct HostEntry *entry)
 Broadcast information about the given entry to all clients that care. More...
 
static void update_hello (const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello)
 Bind a host address (hello) to a hostId. More...
 
static void read_host_file (const char *fn, int unlink_garbage, struct ReadHostFileContext *r)
 Try to read the HELLOs in the given filename and discard expired addresses. More...
 
static struct HostEntryadd_host_to_known_hosts (const struct GNUNET_PeerIdentity *identity)
 Add a host to the list and notify clients about this event. More...
 
static void remove_garbage (const char *fullname)
 Remove a file that should not be there. More...
 
static int hosts_directory_scan_callback (void *cls, const char *fullname)
 Function that is called on each HELLO file in a particular directory. More...
 
static void cron_scan_directory_data_hosts (void *cls)
 Call this method periodically to scan data/hosts for new hosts. More...
 
static struct GNUNET_HELLO_Messageupdate_friend_hello (const struct GNUNET_HELLO_Message *hello, const struct GNUNET_HELLO_Message *friend_hello)
 Update the HELLO of a friend by merging the addresses. More...
 
static int add_to_tc (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Do transmit info about peer to given host. More...
 
static int discard_hosts_helper (void *cls, const char *fn)
 delete expired HELLO entries in directory More...
 
static void cron_clean_data_hosts (void *cls)
 Call this method periodically to scan peerinfo/ for ancient HELLOs to expire. More...
 
static int check_hello (void *cls, const struct GNUNET_HELLO_Message *hello)
 Check HELLO-message. More...
 
static void handle_hello (void *cls, const struct GNUNET_HELLO_Message *hello)
 Handle HELLO-message. More...
 
static void handle_get (void *cls, const struct ListPeerMessage *lpm)
 Handle GET-message. More...
 
static void handle_get_all (void *cls, const struct ListAllPeersMessage *lapm)
 Handle GET-ALL-message. More...
 
static void handle_notify (void *cls, const struct NotifyMessage *nm)
 Handle NOTIFY-message. More...
 
static void * client_connect_cb (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq)
 Client connect callback. More...
 
static void client_disconnect_cb (void *cls, struct GNUNET_SERVICE_Client *client, void *app_ctx)
 Client disconnect callback. More...
 
static int free_host_entry (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
 Release memory taken by a host entry. More...
 
static void shutdown_task (void *cls)
 Clean up our state. More...
 
static void run (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_SERVICE_Handle *service)
 Start up peerinfo service. More...
 
 GNUNET_SERVICE_MAIN ("peerinfo", GNUNET_SERVICE_OPTION_NONE, &run, &client_connect_cb, &client_disconnect_cb, NULL, GNUNET_MQ_hd_var_size(hello, GNUNET_MESSAGE_TYPE_HELLO, struct GNUNET_HELLO_Message, NULL), GNUNET_MQ_hd_fixed_size(get, GNUNET_MESSAGE_TYPE_PEERINFO_GET, struct ListPeerMessage, NULL), GNUNET_MQ_hd_fixed_size(get_all, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, struct ListAllPeersMessage, NULL), GNUNET_MQ_hd_fixed_size(notify, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY, struct NotifyMessage, NULL), GNUNET_MQ_handler_end())
 Define "main" method using service macro. More...
 

Variables

static struct GNUNET_CONTAINER_MultiPeerMaphostmap
 The in-memory list of known hosts, mapping of host IDs to 'struct HostEntry*' values. More...
 
static struct GNUNET_NotificationContextnotify_list
 Clients to immediately notify about all changes. More...
 
static struct GNUNET_NotificationContextnotify_friend_only_list
 Clients to immediately notify about all changes, even for friend-only HELLOs. More...
 
static char * networkIdDirectory
 Directory where the hellos are stored in (peerinfo/) More...
 
static struct GNUNET_STATISTICS_Handlestats
 Handle for reporting statistics. More...
 
static struct GNUNET_SCHEDULER_Taskcron_clean
 Handle for task to run cron_clean_data_hosts() More...
 
static struct GNUNET_SCHEDULER_Taskcron_scan
 Handle for task to run cron_scan_directory_data_hosts() More...
 

Detailed Description

maintains list of known peers

Code to maintain the list of currently known hosts (in memory structure of data/hosts/).

Author
Christian Grothoff

Definition in file gnunet-service-peerinfo.c.

Macro Definition Documentation

◆ DATA_HOST_FREQ

#define DATA_HOST_FREQ   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 15)

How often do we scan the HOST_DIR for new entries?

Definition at line 41 of file gnunet-service-peerinfo.c.

Referenced by cron_scan_directory_data_hosts().

◆ DATA_HOST_CLEAN_FREQ

#define DATA_HOST_CLEAN_FREQ   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 60)

How often do we discard old entries in data/hosts/?

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

Referenced by cron_clean_data_hosts().

Function Documentation

◆ make_info_message()

static struct InfoMessage* make_info_message ( const struct HostEntry he,
int  include_friend_only 
)
static

Notify all clients in the notify list about the given host entry changing.

Parameters
heentry of the host for which we generate a notification
include_friend_onlycreate public of friend-only message
Returns
generated notification message

Definition at line 137 of file gnunet-service-peerinfo.c.

References HostEntry::friend_only_hello, GNUNET_HELLO_size(), GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_PEERINFO_INFO, GNUNET_YES, InfoMessage::header, HostEntry::hello, HostEntry::identity, InfoMessage::peer, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by notify_all().

138 {
139  struct InfoMessage *im;
140  struct GNUNET_HELLO_Message *src;
141  size_t hs;
142 
144  src = he->friend_only_hello;
145  else
146  src = he->hello;
147  hs = (NULL == src) ? 0 : GNUNET_HELLO_size (src);
148  im = GNUNET_malloc (sizeof(struct InfoMessage) + hs);
149  im->header.size = htons (hs + sizeof(struct InfoMessage));
151  im->peer = he->identity;
152  GNUNET_memcpy (&im[1], src, hs);
153  return im;
154 }
A HELLO message is used to exchange information about transports with other peers.
Message used to inform the client about a particular peer; this message is optionally followed by a H...
Definition: peerinfo.h:102
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int include_friend_only
Option '-f'.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
struct GNUNET_PeerIdentity peer
About which peer are we talking here?
Definition: peerinfo.h:117
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_PEERINFO_INFO.
Definition: peerinfo.h:107
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO
Information about one of the peers.
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_HELLO_Message * hello
Hello for the peer (can be NULL)
struct GNUNET_PeerIdentity identity
Identity of the peer.
struct GNUNET_HELLO_Message * friend_only_hello
Friend only hello for the peer (can be NULL)
#define GNUNET_malloc(size)
Wrapper around malloc.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ discard_expired()

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

Address iterator that causes expired entries to be discarded.

Parameters
clspointer to the current time
addressthe address
expirationexpiration time for the address
Returns
GNUNET_NO if expiration smaller than the current time

Definition at line 166 of file gnunet-service-peerinfo.c.

References _, GNUNET_TIME_Absolute::abs_value_us, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_NO, GNUNET_OK, and GNUNET_HELLO_Address::transport_name.

Referenced by discard_hosts_helper(), and read_host_file().

169 {
170  const struct GNUNET_TIME_Absolute *now = cls;
171 
172  if (now->abs_value_us > expiration.abs_value_us)
173  {
175  _ ("Removing expired address of transport `%s'\n"),
176  address->transport_name);
177  return GNUNET_NO;
178  }
179  return GNUNET_OK;
180 }
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
uint64_t abs_value_us
The actual value.
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
const char * transport_name
Name of the transport plugin enabling the communication using this address.
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
Here is the caller graph for this function:

◆ count_addresses()

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

Address iterator that counts the remaining addresses.

Parameters
clspointer to the counter
addressthe address
expirationexpiration time for the address
Returns
GNUNET_OK (always)

Definition at line 192 of file gnunet-service-peerinfo.c.

References GNUNET_OK.

Referenced by discard_hosts_helper(), distribute_bandwidth(), read_host_file(), and update_hello().

195 {
196  unsigned int *cnt = cls;
197 
198  (void) address;
199  (void) expiration;
200  (*cnt)++;
201  return GNUNET_OK;
202 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Here is the caller graph for this function:

◆ get_host_filename()

static char* get_host_filename ( const struct GNUNET_PeerIdentity id)
static

Get the filename under which we would store the GNUNET_HELLO_Message for the given host and protocol.

Parameters
idpeer for which we need the filename for the HELLO
Returns
filename of the form DIRECTORY/HOSTID

Definition at line 213 of file gnunet-service-peerinfo.c.

References DIR_SEPARATOR_STR, fn, GNUNET_asprintf(), GNUNET_i2s_full(), and networkIdDirectory.

Referenced by add_host_to_known_hosts(), and update_hello().

214 {
215  char *fn;
216 
217  if (NULL == networkIdDirectory)
218  return NULL;
219  GNUNET_asprintf (&fn,
220  "%s%s%s",
223  GNUNET_i2s_full (id));
224  return fn;
225 }
const char * GNUNET_i2s_full(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
static char * fn
Filename of the unique file.
#define DIR_SEPARATOR_STR
Definition: platform.h:168
static char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ notify_all()

static void notify_all ( struct HostEntry entry)
static

Broadcast information about the given entry to all clients that care.

Parameters
entryentry to broadcast about

Definition at line 235 of file gnunet-service-peerinfo.c.

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_i2s(), GNUNET_log, GNUNET_NO, GNUNET_notification_context_broadcast(), GNUNET_YES, InfoMessage::header, HostEntry::hello, HostEntry::identity, make_info_message(), peer, and update_hello().

Referenced by add_host_to_known_hosts(), and update_hello().

236 {
237  struct InfoMessage *msg_pub;
238  struct InfoMessage *msg_friend;
239 
241  "Notifying all clients about peer `%s'\n",
242  GNUNET_i2s (&entry->identity));
243  msg_pub = make_info_message (entry, GNUNET_NO);
245  &msg_pub->header,
246  GNUNET_NO);
247  GNUNET_free (msg_pub);
248  msg_friend = make_info_message (entry, GNUNET_YES);
250  &msg_friend->header,
251  GNUNET_NO);
252  GNUNET_free (msg_friend);
253 }
static struct InfoMessage * make_info_message(const struct HostEntry *he, int include_friend_only)
Notify all clients in the notify list about the given host entry changing.
static struct GNUNET_NotificationContext * notify_friend_only_list
Clients to immediately notify about all changes, even for friend-only HELLOs.
Message used to inform the client about a particular peer; this message is optionally followed by a H...
Definition: peerinfo.h:102
#define GNUNET_NO
Definition: gnunet_common.h:78
static struct GNUNET_NotificationContext * notify_list
Clients to immediately notify about all changes.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_PEERINFO_INFO.
Definition: peerinfo.h:107
void GNUNET_notification_context_broadcast(struct GNUNET_NotificationContext *nc, const struct GNUNET_MessageHeader *msg, int can_drop)
Send a message to all subscribers of this context.
Definition: nc.c:189
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_PeerIdentity identity
Identity of the peer.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_hello()

static void update_hello ( const struct GNUNET_PeerIdentity peer,
const struct GNUNET_HELLO_Message hello 
)
static

Bind a host address (hello) to a hostId.

Parameters
peerthe peer for which this is a hello
hellothe verified (!) hello message

Definition at line 683 of file gnunet-service-peerinfo.c.

References GNUNET_TIME_Absolute::abs_value_us, count_addresses(), fn, HostEntry::friend_only_hello, get_host_filename(), GNUNET_assert, GNUNET_CONTAINER_multipeermap_get(), GNUNET_DISK_directory_create_for_file(), GNUNET_DISK_fn_write(), GNUNET_DISK_PERM_GROUP_READ, GNUNET_DISK_PERM_OTHER_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_free_non_null, GNUNET_HELLO_equals(), GNUNET_HELLO_is_friend_only(), GNUNET_HELLO_iterate_addresses(), GNUNET_HELLO_merge(), GNUNET_HELLO_size(), GNUNET_i2s(), GNUNET_log, GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_FOREVER_ABS, GNUNET_YES, HostEntry::hello, notify_all(), size, and update_friend_hello().

Referenced by add_host_to_known_hosts(), handle_hello(), hosts_directory_scan_callback(), and notify_all().

685 {
686  char *fn;
687  struct HostEntry *host;
688  struct GNUNET_HELLO_Message *mrg;
689  struct GNUNET_HELLO_Message **dest;
691  unsigned int cnt;
692  unsigned int size;
693  int friend_hello_type;
694  int store_hello;
695  int store_friend_hello;
696  unsigned int pos;
697  char *buffer;
698 
700  GNUNET_assert (NULL != host);
701 
702  friend_hello_type = GNUNET_HELLO_is_friend_only (hello);
704  "Updating %s HELLO for `%s'\n",
705  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
706  GNUNET_i2s (peer));
707 
708  dest = NULL;
709  if (GNUNET_YES == friend_hello_type)
710  {
711  dest = &host->friend_only_hello;
712  }
713  else
714  {
715  dest = &host->hello;
716  }
717 
718  if (NULL == (*dest))
719  {
720  (*dest) = GNUNET_malloc (GNUNET_HELLO_size (hello));
721  GNUNET_memcpy ((*dest), hello, GNUNET_HELLO_size (hello));
722  }
723  else
724  {
725  mrg = GNUNET_HELLO_merge ((*dest), hello);
727  if (delta.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
728  {
729  /* no differences, just ignore the update */
731  "No change in %s HELLO for `%s'\n",
732  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
733  GNUNET_i2s (peer));
734  GNUNET_free (mrg);
735  return;
736  }
737  GNUNET_free ((*dest));
738  (*dest) = mrg;
739  }
740 
741  if ((NULL != (host->hello)) && (GNUNET_NO == friend_hello_type))
742  {
743  /* Update friend only hello */
744  mrg = update_friend_hello (host->hello, host->friend_only_hello);
745  if (NULL != host->friend_only_hello)
747  host->friend_only_hello = mrg;
748  }
749 
750  if (NULL != host->hello)
752  if (NULL != host->friend_only_hello)
753  GNUNET_assert (
755 
756  fn = get_host_filename (peer);
757  if ((NULL != fn) && (GNUNET_OK == GNUNET_DISK_directory_create_for_file (fn)))
758  {
759  store_hello = GNUNET_NO;
760  size = 0;
761  cnt = 0;
762  if (NULL != host->hello)
764  GNUNET_NO,
766  &cnt);
767  if (cnt > 0)
768  {
769  store_hello = GNUNET_YES;
770  size += GNUNET_HELLO_size (host->hello);
771  }
772  cnt = 0;
773  if (NULL != host->friend_only_hello)
775  GNUNET_NO,
777  &cnt);
778  store_friend_hello = GNUNET_NO;
779  if (0 < cnt)
780  {
781  store_friend_hello = GNUNET_YES;
782  size += GNUNET_HELLO_size (host->friend_only_hello);
783  }
784 
785  if ((GNUNET_NO == store_hello) && (GNUNET_NO == store_friend_hello))
786  {
787  /* no valid addresses, don't put HELLO on disk; in fact,
788  if one exists on disk, remove it */
789  (void) unlink (fn);
790  }
791  else
792  {
793  buffer = GNUNET_malloc (size);
794  pos = 0;
795 
796  if (GNUNET_YES == store_hello)
797  {
798  GNUNET_memcpy (buffer, host->hello, GNUNET_HELLO_size (host->hello));
799  pos += GNUNET_HELLO_size (host->hello);
800  }
801  if (GNUNET_YES == store_friend_hello)
802  {
803  GNUNET_memcpy (&buffer[pos],
804  host->friend_only_hello,
806  pos += GNUNET_HELLO_size (host->friend_only_hello);
807  }
808  GNUNET_assert (pos == size);
809 
811  buffer,
812  size,
818  else
820  "Stored %s %s HELLO in %s with total size %u\n",
821  (GNUNET_YES == store_friend_hello) ? "friend-only" : "",
822  (GNUNET_YES == store_hello) ? "public" : "",
823  fn,
824  size);
825  GNUNET_free (buffer);
826  }
827  }
829  notify_all (host);
830 }
static int count_addresses(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that counts the remaining addresses.
A HELLO message is used to exchange information about transports with other peers.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
struct GNUNET_HELLO_Message * GNUNET_HELLO_merge(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2)
Construct a HELLO message by merging the addresses in two existing HELLOs (which must be for the same...
Definition: hello.c:524
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_TIME_Absolute GNUNET_HELLO_equals(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2, struct GNUNET_TIME_Absolute now)
Test if two HELLO messages contain the same addresses.
Definition: hello.c:834
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:684
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static char * get_host_filename(const struct GNUNET_PeerIdentity *id)
Get the filename under which we would store the GNUNET_HELLO_Message for the given host and protocol...
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static struct GNUNET_HELLO_Message * update_friend_hello(const struct GNUNET_HELLO_Message *hello, const struct GNUNET_HELLO_Message *friend_hello)
Update the HELLO of a friend by merging the addresses.
ssize_t GNUNET_DISK_fn_write(const char *fn, const void *buffer, size_t n, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file.
Definition: disk.c:880
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
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_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:89
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
Everybody can read.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
#define GNUNET_log(kind,...)
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
static void notify_all(struct HostEntry *entry)
Broadcast information about the given entry to all clients that care.
In-memory cache of known hosts.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_HELLO_Message * hello
Hello for the peer (can be NULL)
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_HELLO_Message * friend_only_hello
Friend only hello for the peer (can be NULL)
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_host_file()

static void read_host_file ( const char *  fn,
int  unlink_garbage,
struct ReadHostFileContext r 
)
static

Try to read the HELLOs in the given filename and discard expired addresses.

Removes the file if one the HELLO is malformed. If all addresses are expired, the HELLO is also removed (but the HELLO with the public key is still returned if it was found and valid). The file can contain multiple HELLO messages.

Parameters
fnname of the file
unlink_garbageif GNUNET_YES, try to remove useless files
rReadHostFileContext to store the resutl

Definition at line 279 of file gnunet-service-peerinfo.c.

References _, count_addresses(), discard_expired(), ReadHostFileContext::friend_only_hello, GNUNET_ALIGN, GNUNET_break, GNUNET_DISK_file_test(), GNUNET_DISK_fn_read(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_HELLO_is_friend_only(), GNUNET_HELLO_iterate_addresses(), GNUNET_HELLO_size(), GNUNET_log, GNUNET_log_strerror_file, GNUNET_MAX_MESSAGE_SIZE, GNUNET_NO, GNUNET_TIME_absolute_get(), GNUNET_YES, HostEntry::hello, and ReadHostFileContext::hello.

Referenced by add_host_to_known_hosts(), and hosts_directory_scan_callback().

282 {
283  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
284  ssize_t size_total;
285  struct GNUNET_TIME_Absolute now;
286  unsigned int left;
287  const struct GNUNET_HELLO_Message *hello;
288  struct GNUNET_HELLO_Message *hello_clean;
289  size_t read_pos;
290  uint16_t size_hello;
291 
292  r->friend_only_hello = NULL;
293  r->hello = NULL;
294 
296  return;
297  size_total = GNUNET_DISK_fn_read (fn, buffer, sizeof(buffer));
299  "Read %d bytes from `%s'\n",
300  (int) size_total,
301  fn);
302  if ((size_total < 0) ||
303  (((size_t) size_total) < sizeof(struct GNUNET_MessageHeader)))
304  {
306  _ ("Failed to parse HELLO in file `%s': %s\n"),
307  fn,
308  "File has invalid size");
309  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)) &&
310  (ENOENT != errno))
312  return;
313  }
314 
315  read_pos = 0;
316  while (read_pos < (size_t) size_total)
317  {
318  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
319  size_hello = GNUNET_HELLO_size (hello);
320  if ((0 == size_hello) || (((size_t) size_total) - read_pos < size_hello))
321  {
323  _ ("Failed to parse HELLO in file `%s'\n"),
324  fn);
325  if (0 == read_pos)
326  {
327  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)) &&
328  (ENOENT != errno))
330  }
331  else
332  {
333  if ((GNUNET_YES == unlink_garbage) && (0 != truncate (fn, read_pos)) &&
334  (ENOENT != errno))
336  }
337  return;
338  }
339 
340  now = GNUNET_TIME_absolute_get ();
341  hello_clean = GNUNET_HELLO_iterate_addresses (hello,
342  GNUNET_YES,
344  &now);
345  if (NULL == hello_clean)
346  {
348  _ ("Failed to parse HELLO in file `%s'\n"),
349  fn);
350  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)) &&
351  (ENOENT != errno))
353  return;
354  }
355  left = 0;
356  (void) GNUNET_HELLO_iterate_addresses (hello_clean,
357  GNUNET_NO,
359  &left);
360 
361  if (0 == left)
362  {
363  GNUNET_free (hello_clean);
364  break;
365  }
366 
367  if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello_clean))
368  {
369  if (NULL == r->hello)
370  r->hello = hello_clean;
371  else
372  {
373  GNUNET_break (0);
374  GNUNET_free (r->hello);
375  r->hello = hello_clean;
376  }
377  }
378  else
379  {
380  if (NULL == r->friend_only_hello)
381  r->friend_only_hello = hello_clean;
382  else
383  {
384  GNUNET_break (0);
386  r->friend_only_hello = hello_clean;
387  }
388  }
389  read_pos += size_hello;
390  }
391 
392  if (0 == left)
393  {
394  /* no addresses left, remove from disk */
395  if ((GNUNET_YES == unlink_garbage) && (0 != unlink (fn)))
397  }
399  "Found `%s' and `%s' HELLO message in file\n",
400  (NULL != r->hello) ? "public" : "NON-public",
401  (NULL != r->friend_only_hello) ? "friend only"
402  : "NO friend only");
403 }
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:544
struct GNUNET_HELLO_Message * hello
Hello for the peer (can be NULL)
static int count_addresses(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that counts the remaining addresses.
A HELLO message is used to exchange information about transports with other peers.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:89
struct GNUNET_HELLO_Message * friend_only_hello
Friend only hello for the peer (can be NULL)
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
#define GNUNET_log(kind,...)
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int discard_expired(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that causes expired entries to be discarded.
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:794
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_host_to_known_hosts()

static struct HostEntry* add_host_to_known_hosts ( const struct GNUNET_PeerIdentity identity)
static

Add a host to the list and notify clients about this event.

Parameters
identitythe identity of the host
Returns
the HostEntry

Definition at line 413 of file gnunet-service-peerinfo.c.

References fn, ReadHostFileContext::friend_only_hello, get_host_filename(), gettext_noop, GNUNET_assert, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY, GNUNET_CONTAINER_multipeermap_get(), GNUNET_CONTAINER_multipeermap_put(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_free_non_null, GNUNET_i2s(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OK, GNUNET_STATISTICS_update(), GNUNET_YES, ReadHostFileContext::hello, HostEntry::identity, notify_all(), read_host_file(), and update_hello().

Referenced by handle_hello(), and hosts_directory_scan_callback().

414 {
415  struct HostEntry *entry;
416  struct ReadHostFileContext r;
417  char *fn;
418 
419  entry = GNUNET_CONTAINER_multipeermap_get (hostmap, identity);
420  if (NULL == entry)
421  {
423  "Adding new peer `%s'\n",
424  GNUNET_i2s (identity));
426  gettext_noop ("# peers known"),
427  1,
428  GNUNET_NO);
429  entry = GNUNET_new (struct HostEntry);
430  entry->identity = *identity;
433  hostmap,
434  &entry->identity,
435  entry,
437  notify_all (entry);
438  fn = get_host_filename (identity);
439  if (NULL != fn)
440  {
441  read_host_file (fn, GNUNET_YES, &r);
442  if (NULL != r.hello)
443  update_hello (identity, r.hello);
444  if (NULL != r.friend_only_hello)
445  update_hello (identity, r.friend_only_hello);
446  GNUNET_free_non_null (r.hello);
447  GNUNET_free_non_null (r.friend_only_hello);
448  GNUNET_free (fn);
449  }
450  }
451  return entry;
452 }
static void update_hello(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello)
Bind a host address (hello) to a hostId.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
static char * get_host_filename(const struct GNUNET_PeerIdentity *id)
Get the filename under which we would store the GNUNET_HELLO_Message for the given host and protocol...
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
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 char * fn
Filename of the unique file.
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
There must only be one value per key; storing a value should fail if a value under the same key alrea...
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
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.
Result of reading a file.
void * GNUNET_CONTAINER_multipeermap_get(const struct GNUNET_CONTAINER_MultiPeerMap *map, const struct GNUNET_PeerIdentity *key)
Given a key find a value in the map matching the key.
#define GNUNET_log(kind,...)
static void notify_all(struct HostEntry *entry)
Broadcast information about the given entry to all clients that care.
In-memory cache of known hosts.
#define GNUNET_YES
Definition: gnunet_common.h:77
static void read_host_file(const char *fn, int unlink_garbage, struct ReadHostFileContext *r)
Try to read the HELLOs in the given filename and discard expired addresses.
struct GNUNET_PeerIdentity identity
Identity of the peer.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#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:

◆ remove_garbage()

static void remove_garbage ( const char *  fullname)
static

Remove a file that should not be there.

LOG success or failure.

Parameters
fullnamename of the file to remove

Definition at line 462 of file gnunet-service-peerinfo.c.

References _, GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_log_strerror_file, and networkIdDirectory.

Referenced by hosts_directory_scan_callback().

463 {
464  if (0 == unlink (fullname))
465  GNUNET_log (
467  _ (
468  "File `%s' in directory `%s' does not match naming convention. Removed.\n"),
469  fullname,
471  else
473  "unlink",
474  fullname);
475 }
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
#define GNUNET_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
#define GNUNET_log(kind,...)
Here is the caller graph for this function:

◆ hosts_directory_scan_callback()

static int hosts_directory_scan_callback ( void *  cls,
const char *  fullname 
)
static

Function that is called on each HELLO file in a particular directory.

Try to parse the file and add the HELLO to our list.

Parameters
clspointer to 'unsigned int' to increment for each file, or NULL if the file is from a read-only, read-once resource directory
fullnamename of the file to parse
Returns
GNUNET_OK (continue iteration)

Definition at line 508 of file gnunet-service-peerinfo.c.

References add_host_to_known_hosts(), DIR_SEPARATOR, filename, ReadHostFileContext::friend_only_hello, GNUNET_break, GNUNET_CRYPTO_eddsa_public_key_from_string(), GNUNET_DISK_file_test(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_get_id(), GNUNET_i2s(), GNUNET_log, GNUNET_memcmp, GNUNET_OK, GNUNET_YES, ReadHostFileContext::hello, DirScanContext::matched, GNUNET_PeerIdentity::public_key, read_host_file(), DirScanContext::remove_files, remove_garbage(), and update_hello().

Referenced by cron_scan_directory_data_hosts(), and run().

509 {
510  struct DirScanContext *dsc = cls;
512  struct ReadHostFileContext r;
513  const char *filename;
514  struct GNUNET_PeerIdentity id_public;
515  struct GNUNET_PeerIdentity id_friend;
516  struct GNUNET_PeerIdentity id;
517 
518  if (GNUNET_YES != GNUNET_DISK_file_test (fullname))
519  return GNUNET_OK; /* ignore non-files */
520 
521  filename = strrchr (fullname, DIR_SEPARATOR);
522  if ((NULL == filename) || (1 > strlen (filename)))
523  filename = fullname;
524  else
525  filename++;
526 
527  read_host_file (fullname, dsc->remove_files, &r);
528  if ((NULL == r.hello) && (NULL == r.friend_only_hello))
529  return GNUNET_OK;
530  if (NULL != r.friend_only_hello)
531  {
532  if (GNUNET_OK != GNUNET_HELLO_get_id (r.friend_only_hello, &id_friend))
533  {
534  if (GNUNET_YES == dsc->remove_files)
535  remove_garbage (fullname);
536  return GNUNET_OK;
537  }
538  id = id_friend;
539  }
540  if (NULL != r.hello)
541  {
542  if (GNUNET_OK != GNUNET_HELLO_get_id (r.hello, &id_public))
543  {
544  if (GNUNET_YES == dsc->remove_files)
545  remove_garbage (fullname);
546  return GNUNET_OK;
547  }
548  id = id_public;
549  }
550 
551  if ((NULL != r.hello) && (NULL != r.friend_only_hello) &&
552  (0 != GNUNET_memcmp (&id_friend, &id_public)))
553  {
554  /* HELLOs are not for the same peer */
555  GNUNET_break (0);
556  if (GNUNET_YES == dsc->remove_files)
557  remove_garbage (fullname);
558  return GNUNET_OK;
559  }
560  if (GNUNET_OK ==
562  strlen (filename),
563  &identity.public_key))
564  {
565  if (0 != GNUNET_memcmp (&id, &identity))
566  {
567  /* HELLOs are not for the same peer */
568  GNUNET_break (0);
569  if (GNUNET_YES == dsc->remove_files)
570  remove_garbage (fullname);
571  return GNUNET_OK;
572  }
573  }
574 
575  /* ok, found something valid, remember HELLO */
577  if (NULL != r.hello)
578  {
580  "Updating peer `%s' public HELLO \n",
581  GNUNET_i2s (&id));
582  update_hello (&id, r.hello);
583  GNUNET_free (r.hello);
584  }
585  if (NULL != r.friend_only_hello)
586  {
588  "Updating peer `%s' friend only HELLO \n",
589  GNUNET_i2s (&id));
590  update_hello (&id, r.friend_only_hello);
591  GNUNET_free (r.friend_only_hello);
592  }
593  dsc->matched++;
594  return GNUNET_OK;
595 }
static void remove_garbage(const char *fullname)
Remove a file that should not be there.
int GNUNET_DISK_file_test(const char *fil)
Check that fil corresponds to a filename (of a file that exists and that is not a directory)...
Definition: disk.c:544
int remove_files
GNUNET_YES if we should remove files that are broken, GNUNET_NO if the directory we are iterating ove...
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:671
static void update_hello(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello)
Bind a host address (hello) to a hostId.
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
unsigned int matched
Counter for the number of (valid) entries found, incremented by one for each match.
static struct HostEntry * add_host_to_known_hosts(const struct GNUNET_PeerIdentity *identity)
Add a host to the list and notify clients about this event.
static char * filename
Closure for hosts_directory_scan_callback().
#define DIR_SEPARATOR
Definition: platform.h:167
static struct GNUNET_IDENTITY_Handle * identity
Which namespace do we publish to? NULL if we do not publish to a namespace.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
int GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition: crypto_ecc.c:499
The identity of the host (wraps the signing key of the peer).
Result of reading a file.
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
static void read_host_file(const char *fn, int unlink_garbage, struct ReadHostFileContext *r)
Try to read the HELLOs in the given filename and discard expired addresses.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cron_scan_directory_data_hosts()

static void cron_scan_directory_data_hosts ( void *  cls)
static

Call this method periodically to scan data/hosts for new hosts.

Parameters
clsunused

Definition at line 604 of file gnunet-service-peerinfo.c.

References _, DATA_HOST_FREQ, GNUNET_DISK_directory_create(), GNUNET_DISK_directory_scan(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_INFO, GNUNET_ERROR_TYPE_WARNING, GNUNET_log, GNUNET_SCHEDULER_add_delayed_with_priority(), GNUNET_SCHEDULER_PRIORITY_IDLE, GNUNET_SYSERR, GNUNET_YES, hosts_directory_scan_callback(), DirScanContext::matched, networkIdDirectory, and DirScanContext::remove_files.

Referenced by run().

605 {
606  static unsigned int retries;
607  struct DirScanContext dsc;
608 
609  (void) cls;
610  cron_scan = NULL;
612  {
613  cron_scan =
616  &
618  NULL);
619  return;
620  }
621  dsc.matched = 0;
622  dsc.remove_files = GNUNET_YES;
624  _ ("Scanning directory `%s'\n"),
628  &dsc);
629  if ((0 == dsc.matched) && (0 == (++retries & 31)))
631  _ ("Still no peers found in `%s'!\n"),
633  cron_scan =
637  NULL);
638 }
static struct GNUNET_SCHEDULER_Task * cron_scan
Handle for task to run cron_scan_directory_data_hosts()
static void cron_scan_directory_data_hosts(void *cls)
Call this method periodically to scan data/hosts for new hosts.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed_with_priority(struct GNUNET_TIME_Relative delay, enum GNUNET_SCHEDULER_Priority priority, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1183
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:589
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:912
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
Closure for hosts_directory_scan_callback().
Run when otherwise idle.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
#define DATA_HOST_FREQ
How often do we scan the HOST_DIR for new entries?
static char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:77
static int hosts_directory_scan_callback(void *cls, const char *fullname)
Function that is called on each HELLO file in a particular directory.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_friend_hello()

static struct GNUNET_HELLO_Message* update_friend_hello ( const struct GNUNET_HELLO_Message hello,
const struct GNUNET_HELLO_Message friend_hello 
)
static

Update the HELLO of a friend by merging the addresses.

Parameters
hellooriginal hello
friend_hellohello with additional addresses
Returns
merged HELLO

Definition at line 649 of file gnunet-service-peerinfo.c.

References GNUNET_assert, GNUNET_break, GNUNET_free, GNUNET_HELLO_create(), GNUNET_HELLO_get_id(), GNUNET_HELLO_is_friend_only(), GNUNET_HELLO_merge(), GNUNET_OK, GNUNET_YES, GNUNET_PeerIdentity::public_key, and res.

Referenced by update_hello().

651 {
652  struct GNUNET_HELLO_Message *res;
653  struct GNUNET_HELLO_Message *tmp;
654  struct GNUNET_PeerIdentity pid;
655 
656  if (NULL != friend_hello)
657  {
658  res = GNUNET_HELLO_merge (hello, friend_hello);
660  return res;
661  }
662 
663  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
664  {
665  GNUNET_break (0);
666  return NULL;
667  }
668  tmp = GNUNET_HELLO_create (&pid.public_key, NULL, NULL, GNUNET_YES);
669  res = GNUNET_HELLO_merge (hello, tmp);
670  GNUNET_free (tmp);
672  return res;
673 }
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:671
A HELLO message is used to exchange information about transports with other peers.
struct GNUNET_HELLO_Message * GNUNET_HELLO_merge(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2)
Construct a HELLO message by merging the addresses in two existing HELLOs (which must be for the same...
Definition: hello.c:524
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
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static int res
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:89
The identity of the host (wraps the signing key of the peer).
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Here is the call graph for this function:
Here is the caller graph for this function:

◆ add_to_tc()

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

Do transmit info about peer to given host.

Parameters
clsNULL to hit all hosts, otherwise specifies a particular target
keyhostID
valueinformation to transmit
Returns
GNUNET_YES (continue to iterate)

Definition at line 859 of file gnunet-service-peerinfo.c.

References TransmitContext::client, env, TransmitContext::friend_only, HostEntry::friend_only_hello, GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_size(), GNUNET_i2s(), GNUNET_log, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_PEERINFO_INFO, GNUNET_MQ_msg, GNUNET_MQ_msg_extra, GNUNET_MQ_send(), GNUNET_NO, GNUNET_SERVICE_client_get_mq(), GNUNET_YES, HostEntry::hello, HostEntry::identity, InfoMessage::peer, tc, and value.

Referenced by handle_get(), handle_get_all(), and handle_notify().

860 {
861  struct TransmitContext *tc = cls;
862  struct HostEntry *pos = value;
863  struct InfoMessage *im;
864  uint16_t hs;
865  struct GNUNET_MQ_Envelope *env;
866 
867  hs = 0;
868 
869  if ((NULL != pos->hello) && (GNUNET_NO == tc->friend_only))
870  {
871  /* Copy public HELLO */
872  hs = GNUNET_HELLO_size (pos->hello);
873  GNUNET_assert (hs < GNUNET_MAX_MESSAGE_SIZE - sizeof(struct InfoMessage));
875  GNUNET_memcpy (&im[1], pos->hello, hs);
877  "Sending public HELLO with size %u for peer `%s'\n",
878  hs,
879  GNUNET_i2s (key));
880  }
881  else if ((NULL != pos->friend_only_hello) && (GNUNET_YES == tc->friend_only))
882  {
883  /* Copy friend only HELLO */
885  GNUNET_assert (hs < GNUNET_MAX_MESSAGE_SIZE - sizeof(struct InfoMessage));
887  GNUNET_memcpy (&im[1], pos->friend_only_hello, hs);
889  "Sending friend-only HELLO with size %u for peer `%s'\n",
890  hs,
891  GNUNET_i2s (key));
892  }
893  else
894  {
897  "Adding no HELLO for peer `%s'\n",
898  GNUNET_i2s (key));
899  }
900  im->peer = pos->identity;
902  return GNUNET_YES;
903 }
Closure for add_to_tc()
struct GNUNET_SERVICE_Client * client
Client to transmit to.
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Message used to inform the client about a particular peer; this message is optionally followed by a H...
Definition: peerinfo.h:102
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:418
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:78
int friend_only
Include friend only HELLOs GNUNET_YES or GNUNET_NO.
struct GNUNET_PeerIdentity peer
About which peer are we talking here?
Definition: peerinfo.h:117
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct...
Definition: gnunet_mq_lib.h:52
static char * value
Value of the record to add/remove.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO
Information about one of the peers.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
#define GNUNET_log(kind,...)
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
In-memory cache of known hosts.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
struct GNUNET_HELLO_Message * hello
Hello for the peer (can be NULL)
struct GNUNET_PeerIdentity identity
Identity of the peer.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
struct GNUNET_HELLO_Message * friend_only_hello
Friend only hello for the peer (can be NULL)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ discard_hosts_helper()

static int discard_hosts_helper ( void *  cls,
const char *  fn 
)
static

delete expired HELLO entries in directory

Parameters
clspointer to current time (struct GNUNET_TIME_Absolute *)
fnfilename to test to see if the HELLO expired
Returns
GNUNET_OK (continue iteration)

Definition at line 914 of file gnunet-service-peerinfo.c.

References count_addresses(), discard_expired(), GNUNET_ALIGN, GNUNET_DISK_file_size(), GNUNET_DISK_fn_read(), GNUNET_DISK_fn_write(), GNUNET_DISK_PERM_GROUP_READ, GNUNET_DISK_PERM_OTHER_READ, GNUNET_DISK_PERM_USER_READ, GNUNET_DISK_PERM_USER_WRITE, GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_WARNING, GNUNET_free, GNUNET_free_non_null, GNUNET_HELLO_iterate_addresses(), GNUNET_HELLO_size(), GNUNET_log_strerror_file, GNUNET_malloc, GNUNET_MAX_MESSAGE_SIZE, GNUNET_memcpy, GNUNET_NO, GNUNET_OK, GNUNET_YES, and HostEntry::hello.

Referenced by cron_clean_data_hosts().

915 {
916  struct GNUNET_TIME_Absolute *now = cls;
917  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
918  const struct GNUNET_HELLO_Message *hello;
919  struct GNUNET_HELLO_Message *new_hello;
920  int read_size;
921  unsigned int cur_hello_size;
922  unsigned int new_hello_size;
923  int read_pos;
924  int write_pos;
925  unsigned int cnt;
926  char *writebuffer;
927  uint64_t fsize;
928 
930  {
933  "fstat",
934  fn);
935  return GNUNET_OK;
936  }
937  read_size = GNUNET_DISK_fn_read (fn, buffer, sizeof(buffer));
938 
939  if ((read_size < (int) sizeof(struct GNUNET_MessageHeader)) ||
940  (fsize > GNUNET_MAX_MESSAGE_SIZE))
941  {
942  if (0 != unlink (fn))
945  "unlink",
946  fn);
947  return GNUNET_OK;
948  }
949 
950  writebuffer = GNUNET_malloc (read_size);
951  read_pos = 0;
952  write_pos = 0;
953  while (read_pos < read_size)
954  {
955  /* Check each HELLO */
956  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
957  cur_hello_size = GNUNET_HELLO_size (hello);
958  if (0 == cur_hello_size)
959  {
960  /* Invalid data, discard */
961  if (0 != unlink (fn))
964  "unlink",
965  fn);
966  GNUNET_free (writebuffer);
967  return GNUNET_OK;
968  }
969  new_hello =
971  cnt = 0;
972  if (NULL != new_hello)
973  (void) GNUNET_HELLO_iterate_addresses (hello,
974  GNUNET_NO,
976  &cnt);
977  if ((NULL != new_hello) && (0 < cnt))
978  {
979  /* Store new HELLO to write it when done */
980  new_hello_size = GNUNET_HELLO_size (new_hello);
981  GNUNET_memcpy (&writebuffer[write_pos], new_hello, new_hello_size);
982  write_pos += new_hello_size;
983  }
984  read_pos += cur_hello_size;
985  GNUNET_free_non_null (new_hello);
986  }
987 
988  if (0 < write_pos)
989  {
991  writebuffer,
992  write_pos,
997  }
998  else if (0 != unlink (fn))
1001  "unlink",
1002  fn);
1003 
1004  GNUNET_free (writebuffer);
1005  return GNUNET_OK;
1006 }
static int count_addresses(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that counts the remaining addresses.
A HELLO message is used to exchange information about transports with other peers.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
ssize_t GNUNET_DISK_fn_write(const char *fn, const void *buffer, size_t n, enum GNUNET_DISK_AccessPermissions mode)
Write a buffer to a file.
Definition: disk.c:880
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_log_strerror_file(level, cmd, filename)
Log an error message at log-level &#39;level&#39; that indicates a failure of the command &#39;cmd&#39; with the mess...
static char * fn
Filename of the unique file.
int GNUNET_DISK_file_size(const char *filename, uint64_t *size, int include_symbolic_links, int single_file_mode)
Get the size of the file (or directory) of the given file (in bytes).
Definition: disk.c:257
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
Everybody can read.
#define GNUNET_ALIGN
gcc-ism to force alignment; we use this to align char-arrays that may then be cast to &#39;struct&#39;s...
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int discard_expired(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Address iterator that causes expired entries to be discarded.
#define GNUNET_malloc(size)
Wrapper around malloc.
ssize_t GNUNET_DISK_fn_read(const char *fn, void *result, size_t len)
Read the contents of a binary file into a buffer.
Definition: disk.c:794
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ cron_clean_data_hosts()

static void cron_clean_data_hosts ( void *  cls)
static

Call this method periodically to scan peerinfo/ for ancient HELLOs to expire.

Parameters
clsunused

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

References _, DATA_HOST_CLEAN_FREQ, discard_hosts_helper(), GNUNET_DISK_directory_scan(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_INFO, GNUNET_log, GNUNET_SCHEDULER_add_delayed(), GNUNET_TIME_absolute_get(), and networkIdDirectory.

Referenced by run().

1017 {
1018  struct GNUNET_TIME_Absolute now;
1019 
1020  (void) cls;
1021  cron_clean = NULL;
1022  now = GNUNET_TIME_absolute_get ();
1024  _ ("Cleaning up directory `%s'\n"),
1029  NULL);
1030 }
static void cron_clean_data_hosts(void *cls)
Call this method periodically to scan peerinfo/ for ancient HELLOs to expire.
#define DATA_HOST_CLEAN_FREQ
How often do we discard old entries in data/hosts/?
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:912
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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:1253
static int discard_hosts_helper(void *cls, const char *fn)
delete expired HELLO entries in directory
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
static char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
#define GNUNET_log(kind,...)
Time for absolute times used by GNUnet, in microseconds.
static struct GNUNET_SCHEDULER_Task * cron_clean
Handle for task to run cron_clean_data_hosts()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_hello()

static int check_hello ( void *  cls,
const struct GNUNET_HELLO_Message hello 
)
static

Check HELLO-message.

Parameters
clsidentification of the client
hellothe actual message
Returns
GNUNET_OK if hello is well-formed

Definition at line 1041 of file gnunet-service-peerinfo.c.

References GNUNET_break, GNUNET_HELLO_get_id(), GNUNET_OK, and GNUNET_SYSERR.

1042 {
1043  struct GNUNET_PeerIdentity pid;
1044 
1045  (void) cls;
1046  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
1047  {
1048  GNUNET_break (0);
1049  return GNUNET_SYSERR;
1050  }
1051  return GNUNET_OK;
1052 }
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:671
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
The identity of the host (wraps the signing key of the peer).
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
Here is the call graph for this function:

◆ handle_hello()

static void handle_hello ( void *  cls,
const struct GNUNET_HELLO_Message hello 
)
static

Handle HELLO-message.

Parameters
clsidentification of the client
hellothe actual message

Definition at line 1062 of file gnunet-service-peerinfo.c.

References add_host_to_known_hosts(), GNUNET_assert, GNUNET_ERROR_TYPE_DEBUG, GNUNET_HELLO_get_id(), GNUNET_i2s(), GNUNET_log, GNUNET_OK, GNUNET_SERVICE_client_continue(), and update_hello().

1063 {
1064  struct GNUNET_SERVICE_Client *client = cls;
1065  struct GNUNET_PeerIdentity pid;
1066 
1069  "HELLO message received for peer `%s'\n",
1070  GNUNET_i2s (&pid));
1072  update_hello (&pid, hello);
1074 }
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:671
static void update_hello(const struct GNUNET_PeerIdentity *peer, const struct GNUNET_HELLO_Message *hello)
Bind a host address (hello) to a hostId.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
Handle to a client that is connected to a service.
Definition: service.c:250
static struct HostEntry * add_host_to_known_hosts(const struct GNUNET_PeerIdentity *identity)
Add a host to the list and notify clients about this event.
The identity of the host (wraps the signing key of the peer).
#define GNUNET_log(kind,...)
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).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
Here is the call graph for this function:

◆ handle_get()

static void handle_get ( void *  cls,
const struct ListPeerMessage lpm 
)
static

Handle GET-message.

Parameters
clsidentification of the client
lpmthe actual message

Definition at line 1084 of file gnunet-service-peerinfo.c.

References add_to_tc(), TransmitContext::client, env, TransmitContext::friend_only, GNUNET_CONTAINER_multipeermap_get_multiple(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_log, GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_get_mq(), ListPeerMessage::include_friend_only, msg, and ListPeerMessage::peer.

1085 {
1086  struct GNUNET_SERVICE_Client *client = cls;
1087  struct TransmitContext tcx;
1088  struct GNUNET_MessageHeader *msg;
1089  struct GNUNET_MQ_Envelope *env;
1090 
1092  "GET message received for peer `%s'\n",
1093  GNUNET_i2s (&lpm->peer));
1094  tcx.friend_only = ntohl (lpm->include_friend_only);
1095  tcx.client = client;
1097  &lpm->peer,
1098  &add_to_tc,
1099  &tcx);
1103 }
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:51
Closure for add_to_tc()
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_PeerIdentity peer
Restrict to peers with this identity (optional field, check header.size!).
Definition: peerinfo.h:57
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
Handle to a client that is connected to a service.
Definition: service.c:250
static int add_to_tc(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Do transmit info about peer to given host.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
#define GNUNET_log(kind,...)
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END
End of information about other peers.
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
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:

◆ handle_get_all()

static void handle_get_all ( void *  cls,
const struct ListAllPeersMessage lapm 
)
static

Handle GET-ALL-message.

Parameters
clsidentification of the client
lapmthe actual message

Definition at line 1113 of file gnunet-service-peerinfo.c.

References add_to_tc(), TransmitContext::client, env, TransmitContext::friend_only, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_get_mq(), ListAllPeersMessage::include_friend_only, and msg.

1114 {
1115  struct GNUNET_SERVICE_Client *client = cls;
1116  struct TransmitContext tcx;
1117  struct GNUNET_MQ_Envelope *env;
1118  struct GNUNET_MessageHeader *msg;
1119 
1120  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GET_ALL message received\n");
1121  tcx.friend_only = ntohl (lapm->include_friend_only);
1122  tcx.client = client;
1127 }
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:74
Closure for add_to_tc()
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
Handle to a client that is connected to a service.
Definition: service.c:250
static int add_to_tc(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Do transmit info about peer to given host.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
#define GNUNET_log(kind,...)
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END
End of information about other peers.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
Here is the call graph for this function:

◆ handle_notify()

static void handle_notify ( void *  cls,
const struct NotifyMessage nm 
)
static

Handle NOTIFY-message.

Parameters
clsidentification of the client
nmthe actual message

Definition at line 1137 of file gnunet-service-peerinfo.c.

References add_to_tc(), TransmitContext::client, env, TransmitContext::friend_only, GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_notification_context_add(), GNUNET_SERVICE_client_continue(), GNUNET_SERVICE_client_get_mq(), GNUNET_SERVICE_client_mark_monitor(), NotifyMessage::include_friend_only, mq, and msg.

1138 {
1139  struct GNUNET_SERVICE_Client *client = cls;
1140  struct GNUNET_MQ_Handle *mq;
1141  struct TransmitContext tcx;
1142  struct GNUNET_MQ_Envelope *env;
1143  struct GNUNET_MessageHeader *msg;
1144 
1145  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "NOTIFY message received\n");
1146  mq = GNUNET_SERVICE_client_get_mq (client);
1148  if (ntohl (nm->include_friend_only))
1150  else
1152  tcx.friend_only = ntohl (nm->include_friend_only);
1153  tcx.client = client;
1158 }
Closure for add_to_tc()
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:91
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2437
static struct GNUNET_NotificationContext * notify_friend_only_list
Clients to immediately notify about all changes, even for friend-only HELLOs.
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
void GNUNET_notification_context_add(struct GNUNET_NotificationContext *nc, struct GNUNET_MQ_Handle *mq)
Add a subscriber to the notification context.
Definition: nc.c:160
Handle to a client that is connected to a service.
Definition: service.c:250
static struct GNUNET_NotificationContext * notify_list
Clients to immediately notify about all changes.
void GNUNET_SERVICE_client_mark_monitor(struct GNUNET_SERVICE_Client *c)
Set the &#39;monitor&#39; flag on this client.
Definition: service.c:2407
static int add_to_tc(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Do transmit info about peer to given host.
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
Handle to a message queue.
Definition: mq.c:85
int GNUNET_CONTAINER_multipeermap_iterate(struct GNUNET_CONTAINER_MultiPeerMap *map, GNUNET_CONTAINER_PeerMapIterator it, void *it_cls)
Iterate over all entries in the map.
struct GNUNET_MQ_Handle * mq
Definition: 003.c:5
#define GNUNET_log(kind,...)
Header for all communications.
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:353
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END
End of information about other peers.
void GNUNET_SERVICE_client_continue(struct GNUNET_SERVICE_Client *c)
Continue receiving further messages from the given client.
Definition: service.c:2243
Here is the call graph for this function:

◆ client_connect_cb()

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

Client connect callback.

Parameters
clsunused
clientserver client
mqfor client
Returns
client

Definition at line 1170 of file gnunet-service-peerinfo.c.

Referenced by run().

1173 {
1174  (void) cls;
1175  (void) mq;
1176  return client;
1177 }
Here is the caller graph for this function:

◆ client_disconnect_cb()

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

Client disconnect callback.

Parameters
clsunused
clientserver client
app_ctxshould be client

Definition at line 1188 of file gnunet-service-peerinfo.c.

References GNUNET_assert.

Referenced by run().

1191 {
1192  (void) cls;
1193  GNUNET_assert (app_ctx == client);
1194 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
Here is the caller graph for this function:

◆ free_host_entry()

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

Release memory taken by a host entry.

Parameters
clsNULL
keykey of the host entry
valuethe struct HostEntry to free
Returns
GNUNET_YES (continue to iterate)

Definition at line 1206 of file gnunet-service-peerinfo.c.

References HostEntry::friend_only_hello, GNUNET_free, GNUNET_free_non_null, GNUNET_YES, HostEntry::hello, and value.

Referenced by shutdown_task().

1207 {
1208  struct HostEntry *he = value;
1209 
1210  (void) cls;
1211  (void) key;
1214  GNUNET_free (he);
1215  return GNUNET_YES;
1216 }
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static char * value
Value of the record to add/remove.
In-memory cache of known hosts.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_HELLO_Message * hello
Hello for the peer (can be NULL)
struct GNUNET_HELLO_Message * friend_only_hello
Friend only hello for the peer (can be NULL)
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ shutdown_task()

static void shutdown_task ( void *  cls)
static

Clean up our state.

Called during shutdown.

Parameters
clsunused

Definition at line 1225 of file gnunet-service-peerinfo.c.

References free_host_entry(), GNUNET_CONTAINER_multipeermap_destroy(), GNUNET_CONTAINER_multipeermap_iterate(), GNUNET_free, GNUNET_NO, GNUNET_notification_context_destroy(), GNUNET_SCHEDULER_cancel(), GNUNET_STATISTICS_destroy(), and networkIdDirectory.

Referenced by run().

1226 {
1227  (void) cls;
1229  notify_list = NULL;
1231  notify_friend_only_list = NULL;
1232 
1235  if (NULL != stats)
1236  {
1238  stats = NULL;
1239  }
1240  if (NULL != cron_clean)
1241  {
1243  cron_clean = NULL;
1244  }
1245  if (NULL != cron_scan)
1246  {
1248  cron_scan = NULL;
1249  }
1250  if (NULL != networkIdDirectory)
1251  {
1253  networkIdDirectory = NULL;
1254  }
1255 }
static struct GNUNET_SCHEDULER_Task * cron_scan
Handle for task to run cron_scan_directory_data_hosts()
static struct GNUNET_NotificationContext * notify_friend_only_list
Clients to immediately notify about all changes, even for friend-only HELLOs.
#define GNUNET_NO
Definition: gnunet_common.h:78
void GNUNET_STATISTICS_destroy(struct GNUNET_STATISTICS_Handle *h, int sync_first)
Destroy a handle (free all state associated with it).
void GNUNET_CONTAINER_multipeermap_destroy(struct GNUNET_CONTAINER_MultiPeerMap *map)
Destroy a hash map.
static struct GNUNET_NotificationContext * notify_list
Clients to immediately notify about all changes.
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
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 char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
void GNUNET_notification_context_destroy(struct GNUNET_NotificationContext *nc)
Destroy the context, force disconnect for all subscribers.
Definition: nc.c:137
static int free_host_entry(void *cls, const struct GNUNET_PeerIdentity *key, void *value)
Release memory taken by a host entry.
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_SCHEDULER_Task * cron_clean
Handle for task to run cron_clean_data_hosts()
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:966
Here is the call graph for this function:
Here is the caller graph for this function:

◆ run()

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

Start up peerinfo service.

Parameters
clsclosure
cfgconfiguration to use
servicethe initialized service

Definition at line 1266 of file gnunet-service-peerinfo.c.

References _, client_connect_cb(), client_disconnect_cb(), cron_clean_data_hosts(), cron_scan_directory_data_hosts(), GNUNET_asprintf(), GNUNET_assert, GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_yesno(), GNUNET_CONTAINER_multipeermap_create(), GNUNET_DISK_directory_create(), GNUNET_DISK_directory_scan(), GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_log, GNUNET_MESSAGE_TYPE_HELLO, GNUNET_MESSAGE_TYPE_PEERINFO_GET, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY, GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_NO, GNUNET_notification_context_create(), GNUNET_OK, GNUNET_OS_installation_get_path(), GNUNET_OS_IPK_DATADIR, GNUNET_SCHEDULER_add_shutdown(), GNUNET_SCHEDULER_add_with_priority(), GNUNET_SCHEDULER_PRIORITY_IDLE, GNUNET_SCHEDULER_shutdown(), GNUNET_SERVICE_MAIN(), GNUNET_SERVICE_OPTION_NONE, GNUNET_STATISTICS_create(), GNUNET_SYSERR, GNUNET_YES, hosts_directory_scan_callback(), DirScanContext::matched, networkIdDirectory, notify, DirScanContext::remove_files, and shutdown_task().

1269 {
1270  char *peerdir;
1271  char *ip;
1272  struct DirScanContext dsc;
1273  int noio;
1274  int use_included;
1275 
1276  (void) cls;
1277  (void) service;
1279  stats = GNUNET_STATISTICS_create ("peerinfo", cfg);
1282  noio = GNUNET_CONFIGURATION_get_value_yesno (cfg, "peerinfo", "NO_IO");
1283  use_included = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1284  "peerinfo",
1285  "USE_INCLUDED_HELLOS");
1286  if (GNUNET_SYSERR == use_included)
1287  use_included = GNUNET_NO;
1289  if (GNUNET_YES != noio)
1290  {
1291  GNUNET_assert (
1292  GNUNET_OK ==
1294  "peerinfo",
1295  "HOSTS",
1296  &networkIdDirectory));
1298  {
1300  return;
1301  }
1302 
1303  cron_scan =
1306  NULL);
1307 
1308  cron_clean =
1311  NULL);
1312  if (GNUNET_YES == use_included)
1313  {
1315  GNUNET_asprintf (&peerdir, "%shellos", ip);
1316  GNUNET_free (ip);
1317 
1319  _ ("Importing HELLOs from `%s'\n"),
1320  peerdir);
1321  dsc.matched = 0;
1322  dsc.remove_files = GNUNET_NO;
1323 
1324  GNUNET_DISK_directory_scan (peerdir,
1326  &dsc);
1327  GNUNET_free (peerdir);
1328  }
1329  else
1330  {
1332  _ ("Skipping import of included HELLOs\n"));
1333  }
1334  }
1335 }
static struct GNUNET_SCHEDULER_Task * cron_scan
Handle for task to run cron_scan_directory_data_hosts()
static void cron_scan_directory_data_hosts(void *cls)
Call this method periodically to scan data/hosts for new hosts.
static void cron_clean_data_hosts(void *cls)
Call this method periodically to scan peerinfo/ for ancient HELLOs to expire.
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:589
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_shutdown(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run on shutdown, that is when a CTRL-C signal is received, or when GNUNET_SCHEDULER_shutdown() is being invoked.
Definition: scheduler.c:1300
static struct GNUNET_NotificationContext * notify_friend_only_list
Clients to immediately notify about all changes, even for friend-only HELLOs.
struct GNUNET_STATISTICS_Handle * GNUNET_STATISTICS_create(const char *subsystem, const struct GNUNET_CONFIGURATION_Handle *cfg)
Get handle for the statistics service.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:912
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
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).
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_with_priority(enum GNUNET_SCHEDULER_Priority prio, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified priority.
Definition: scheduler.c:1207
static struct GNUNET_NotificationContext * notify_list
Clients to immediately notify about all changes.
static void shutdown_task(void *cls)
Clean up our state.
char * GNUNET_OS_installation_get_path(enum GNUNET_OS_InstallationPathKind dirkind)
Get the path to a specific GNUnet installation directory or, with GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation directory.
Closure for hosts_directory_scan_callback().
Run when otherwise idle.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static struct GNUNET_STATISTICS_Handle * stats
Handle for reporting statistics.
static struct GNUNET_CONTAINER_MultiPeerMap * hostmap
The in-memory list of known hosts, mapping of host IDs to &#39;struct HostEntry*&#39; values.
struct GNUNET_NotificationContext * GNUNET_notification_context_create(unsigned int queue_length)
Create a new notification context.
Definition: nc.c:121
static char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
#define GNUNET_log(kind,...)
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
#define GNUNET_YES
Definition: gnunet_common.h:77
static int hosts_directory_scan_callback(void *cls, const char *fullname)
Function that is called on each HELLO file in a particular directory.
int GNUNET_CONFIGURATION_get_value_yesno(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option)
Get a configuration value that should be in a set of "YES" or "NO".
Return the directory where data is installed (share/gnunet/)
#define GNUNET_free(ptr)
Wrapper around free.
static struct GNUNET_SCHEDULER_Task * cron_clean
Handle for task to run cron_clean_data_hosts()
Here is the call graph for this function:

◆ GNUNET_SERVICE_MAIN()

GNUNET_SERVICE_MAIN ( "peerinfo"  ,
GNUNET_SERVICE_OPTION_NONE  ,
run,
client_connect_cb,
client_disconnect_cb,
NULL  ,
GNUNET_MQ_hd_var_size(hello, GNUNET_MESSAGE_TYPE_HELLO, struct GNUNET_HELLO_Message, NULL)  ,
GNUNET_MQ_hd_fixed_size(get, GNUNET_MESSAGE_TYPE_PEERINFO_GET, struct ListPeerMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(get_all, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, struct ListAllPeersMessage, NULL)  ,
GNUNET_MQ_hd_fixed_size(notify, GNUNET_MESSAGE_TYPE_PEERINFO_NOTIFY, struct NotifyMessage, NULL)  ,
GNUNET_MQ_handler_end()   
)

Define "main" method using service macro.

Referenced by run().

Here is the caller graph for this function:

Variable Documentation

◆ hostmap

struct GNUNET_CONTAINER_MultiPeerMap* hostmap
static

The in-memory list of known hosts, mapping of host IDs to 'struct HostEntry*' values.

Definition at line 94 of file gnunet-service-peerinfo.c.

◆ notify_list

struct GNUNET_NotificationContext* notify_list
static

Clients to immediately notify about all changes.

Definition at line 99 of file gnunet-service-peerinfo.c.

◆ notify_friend_only_list

struct GNUNET_NotificationContext* notify_friend_only_list
static

Clients to immediately notify about all changes, even for friend-only HELLOs.

Definition at line 105 of file gnunet-service-peerinfo.c.

◆ networkIdDirectory

char* networkIdDirectory
static

Directory where the hellos are stored in (peerinfo/)

Definition at line 110 of file gnunet-service-peerinfo.c.

Referenced by cron_clean_data_hosts(), cron_scan_directory_data_hosts(), get_host_filename(), remove_garbage(), run(), and shutdown_task().

◆ stats

struct GNUNET_STATISTICS_Handle* stats
static

Handle for reporting statistics.

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

◆ cron_clean

struct GNUNET_SCHEDULER_Task* cron_clean
static

Handle for task to run cron_clean_data_hosts()

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

◆ cron_scan

struct GNUNET_SCHEDULER_Task* cron_scan
static

Handle for task to run cron_scan_directory_data_hosts()

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