GNUnet  0.10.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 135 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().

136 {
137  struct InfoMessage *im;
138  struct GNUNET_HELLO_Message *src;
139  size_t hs;
140 
142  src = he->friend_only_hello;
143  else
144  src = he->hello;
145  hs = (NULL == src) ? 0 : GNUNET_HELLO_size(src);
146  im = GNUNET_malloc(sizeof(struct InfoMessage) + hs);
147  im->header.size = htons(hs + sizeof(struct InfoMessage));
149  im->peer = he->identity;
150  GNUNET_memcpy(&im[1], src, hs);
151  return im;
152 }
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:100
#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:114
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:104
#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:643
#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 164 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().

167 {
168  const struct GNUNET_TIME_Absolute *now = cls;
169 
170  if (now->abs_value_us > expiration.abs_value_us)
171  {
173  _("Removing expired address of transport `%s'\n"),
174  address->transport_name);
175  return GNUNET_NO;
176  }
177  return GNUNET_OK;
178 }
#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 190 of file gnunet-service-peerinfo.c.

References GNUNET_OK.

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

193 {
194  unsigned int *cnt = cls;
195 
196  (void)address;
197  (void)expiration;
198  (*cnt)++;
199  return GNUNET_OK;
200 }
#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 211 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().

212 {
213  char *fn;
214 
215  if (NULL == networkIdDirectory)
216  return NULL;
217  GNUNET_asprintf(&fn,
218  "%s%s%s",
221  GNUNET_i2s_full(id));
222  return fn;
223 }
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 233 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().

234 {
235  struct InfoMessage *msg_pub;
236  struct InfoMessage *msg_friend;
237 
239  "Notifying all clients about peer `%s'\n",
240  GNUNET_i2s(&entry->identity));
241  msg_pub = make_info_message(entry, GNUNET_NO);
243  &msg_pub->header,
244  GNUNET_NO);
245  GNUNET_free(msg_pub);
246  msg_friend = make_info_message(entry, GNUNET_YES);
248  &msg_friend->header,
249  GNUNET_NO);
250  GNUNET_free(msg_friend);
251 }
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:100
#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:104
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:187
#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 679 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().

681 {
682  char *fn;
683  struct HostEntry *host;
684  struct GNUNET_HELLO_Message *mrg;
685  struct GNUNET_HELLO_Message **dest;
687  unsigned int cnt;
688  unsigned int size;
689  int friend_hello_type;
690  int store_hello;
691  int store_friend_hello;
692  unsigned int pos;
693  char *buffer;
694 
696  GNUNET_assert(NULL != host);
697 
698  friend_hello_type = GNUNET_HELLO_is_friend_only(hello);
700  "Updating %s HELLO for `%s'\n",
701  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
702  GNUNET_i2s(peer));
703 
704  dest = NULL;
705  if (GNUNET_YES == friend_hello_type)
706  {
707  dest = &host->friend_only_hello;
708  }
709  else
710  {
711  dest = &host->hello;
712  }
713 
714  if (NULL == (*dest))
715  {
716  (*dest) = GNUNET_malloc(GNUNET_HELLO_size(hello));
717  GNUNET_memcpy((*dest), hello, GNUNET_HELLO_size(hello));
718  }
719  else
720  {
721  mrg = GNUNET_HELLO_merge((*dest), hello);
723  if (delta.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
724  {
725  /* no differences, just ignore the update */
727  "No change in %s HELLO for `%s'\n",
728  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
729  GNUNET_i2s(peer));
730  GNUNET_free(mrg);
731  return;
732  }
733  GNUNET_free((*dest));
734  (*dest) = mrg;
735  }
736 
737  if ((NULL != (host->hello)) && (GNUNET_NO == friend_hello_type))
738  {
739  /* Update friend only hello */
740  mrg = update_friend_hello(host->hello, host->friend_only_hello);
741  if (NULL != host->friend_only_hello)
743  host->friend_only_hello = mrg;
744  }
745 
746  if (NULL != host->hello)
748  if (NULL != host->friend_only_hello)
751 
752  fn = get_host_filename(peer);
753  if ((NULL != fn) && (GNUNET_OK == GNUNET_DISK_directory_create_for_file(fn)))
754  {
755  store_hello = GNUNET_NO;
756  size = 0;
757  cnt = 0;
758  if (NULL != host->hello)
760  GNUNET_NO,
762  &cnt);
763  if (cnt > 0)
764  {
765  store_hello = GNUNET_YES;
766  size += GNUNET_HELLO_size(host->hello);
767  }
768  cnt = 0;
769  if (NULL != host->friend_only_hello)
771  GNUNET_NO,
773  &cnt);
774  store_friend_hello = GNUNET_NO;
775  if (0 < cnt)
776  {
777  store_friend_hello = GNUNET_YES;
778  size += GNUNET_HELLO_size(host->friend_only_hello);
779  }
780 
781  if ((GNUNET_NO == store_hello) && (GNUNET_NO == store_friend_hello))
782  {
783  /* no valid addresses, don't put HELLO on disk; in fact,
784  if one exists on disk, remove it */
785  (void)unlink(fn);
786  }
787  else
788  {
789  buffer = GNUNET_malloc(size);
790  pos = 0;
791 
792  if (GNUNET_YES == store_hello)
793  {
794  GNUNET_memcpy(buffer, host->hello, GNUNET_HELLO_size(host->hello));
795  pos += GNUNET_HELLO_size(host->hello);
796  }
797  if (GNUNET_YES == store_friend_hello)
798  {
799  GNUNET_memcpy(&buffer[pos],
800  host->friend_only_hello,
802  pos += GNUNET_HELLO_size(host->friend_only_hello);
803  }
804  GNUNET_assert(pos == size);
805 
807  buffer,
808  size,
814  else
816  "Stored %s %s HELLO in %s with total size %u\n",
817  (GNUNET_YES == store_friend_hello) ? "friend-only" : "",
818  (GNUNET_YES == store_hello) ? "public" : "",
819  fn,
820  size);
821  GNUNET_free(buffer);
822  }
823  }
825  notify_all(host);
826 }
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:519
#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:824
#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:681
#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:877
#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:252
#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:66
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:87
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:643
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 277 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().

280 {
281  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
282  ssize_t size_total;
283  struct GNUNET_TIME_Absolute now;
284  unsigned int left;
285  const struct GNUNET_HELLO_Message *hello;
286  struct GNUNET_HELLO_Message *hello_clean;
287  size_t read_pos;
288  uint16_t size_hello;
289 
290  r->friend_only_hello = NULL;
291  r->hello = NULL;
292 
294  return;
295  size_total = GNUNET_DISK_fn_read(fn, buffer, sizeof(buffer));
297  "Read %d bytes from `%s'\n",
298  (int)size_total,
299  fn);
300  if ((size_total < 0) ||
301  (((size_t)size_total) < sizeof(struct GNUNET_MessageHeader)))
302  {
304  _("Failed to parse HELLO in file `%s': %s\n"),
305  fn,
306  "File has invalid size");
307  if ((GNUNET_YES == unlink_garbage) && (0 != unlink(fn)) &&
308  (ENOENT != errno))
310  return;
311  }
312 
313  read_pos = 0;
314  while (read_pos < (size_t)size_total)
315  {
316  hello = (const struct GNUNET_HELLO_Message *)&buffer[read_pos];
317  size_hello = GNUNET_HELLO_size(hello);
318  if ((0 == size_hello) || (((size_t)size_total) - read_pos < size_hello))
319  {
321  _("Failed to parse HELLO in file `%s'\n"),
322  fn);
323  if (0 == read_pos)
324  {
325  if ((GNUNET_YES == unlink_garbage) && (0 != unlink(fn)) &&
326  (ENOENT != errno))
328  }
329  else
330  {
331  if ((GNUNET_YES == unlink_garbage) && (0 != truncate(fn, read_pos)) &&
332  (ENOENT != errno))
334  }
335  return;
336  }
337 
338  now = GNUNET_TIME_absolute_get();
339  hello_clean = GNUNET_HELLO_iterate_addresses(hello,
340  GNUNET_YES,
342  &now);
343  if (NULL == hello_clean)
344  {
346  _("Failed to parse HELLO in file `%s'\n"),
347  fn);
348  if ((GNUNET_YES == unlink_garbage) && (0 != unlink(fn)) &&
349  (ENOENT != errno))
351  return;
352  }
353  left = 0;
354  (void)GNUNET_HELLO_iterate_addresses(hello_clean,
355  GNUNET_NO,
357  &left);
358 
359  if (0 == left)
360  {
361  GNUNET_free(hello_clean);
362  break;
363  }
364 
365  if (GNUNET_NO == GNUNET_HELLO_is_friend_only(hello_clean))
366  {
367  if (NULL == r->hello)
368  r->hello = hello_clean;
369  else
370  {
371  GNUNET_break(0);
372  GNUNET_free(r->hello);
373  r->hello = hello_clean;
374  }
375  }
376  else
377  {
378  if (NULL == r->friend_only_hello)
379  r->friend_only_hello = hello_clean;
380  else
381  {
382  GNUNET_break(0);
384  r->friend_only_hello = hello_clean;
385  }
386  }
387  read_pos += size_hello;
388  }
389 
390  if (0 == left)
391  {
392  /* no addresses left, remove from disk */
393  if ((GNUNET_YES == unlink_garbage) && (0 != unlink(fn)))
395  }
397  "Found `%s' and `%s' HELLO message in file\n",
398  (NULL != r->hello) ? "public" : "NON-public",
399  (NULL != r->friend_only_hello) ? "friend only"
400  : "NO friend only");
401 }
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:541
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:252
#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:87
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:643
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:791
#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 411 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().

412 {
413  struct HostEntry *entry;
414  struct ReadHostFileContext r;
415  char *fn;
416 
417  entry = GNUNET_CONTAINER_multipeermap_get(hostmap, identity);
418  if (NULL == entry)
419  {
421  "Adding new peer `%s'\n",
422  GNUNET_i2s(identity));
424  gettext_noop("# peers known"),
425  1,
426  GNUNET_NO);
427  entry = GNUNET_new(struct HostEntry);
428  entry->identity = *identity;
431  hostmap,
432  &entry->identity,
433  entry,
435  notify_all(entry);
436  fn = get_host_filename(identity);
437  if (NULL != fn)
438  {
439  read_host_file(fn, GNUNET_YES, &r);
440  if (NULL != r.hello)
441  update_hello(identity, r.hello);
442  if (NULL != r.friend_only_hello)
443  update_hello(identity, r.friend_only_hello);
444  GNUNET_free_non_null(r.hello);
445  GNUNET_free_non_null(r.friend_only_hello);
446  GNUNET_free(fn);
447  }
448  }
449  return entry;
450 }
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 460 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().

461 {
462  if (0 == unlink(fullname))
463  GNUNET_log(
465  _(
466  "File `%s' in directory `%s' does not match naming convention. Removed.\n"),
467  fullname,
469  else
471  "unlink",
472  fullname);
473 }
#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 505 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().

506 {
507  struct DirScanContext *dsc = cls;
509  struct ReadHostFileContext r;
510  const char *filename;
511  struct GNUNET_PeerIdentity id_public;
512  struct GNUNET_PeerIdentity id_friend;
513  struct GNUNET_PeerIdentity id;
514 
515  if (GNUNET_YES != GNUNET_DISK_file_test(fullname))
516  return GNUNET_OK; /* ignore non-files */
517 
518  filename = strrchr(fullname, DIR_SEPARATOR);
519  if ((NULL == filename) || (1 > strlen(filename)))
520  filename = fullname;
521  else
522  filename++;
523 
524  read_host_file(fullname, dsc->remove_files, &r);
525  if ((NULL == r.hello) && (NULL == r.friend_only_hello))
526  return GNUNET_OK;
527  if (NULL != r.friend_only_hello)
528  {
529  if (GNUNET_OK != GNUNET_HELLO_get_id(r.friend_only_hello, &id_friend))
530  {
531  if (GNUNET_YES == dsc->remove_files)
532  remove_garbage(fullname);
533  return GNUNET_OK;
534  }
535  id = id_friend;
536  }
537  if (NULL != r.hello)
538  {
539  if (GNUNET_OK != GNUNET_HELLO_get_id(r.hello, &id_public))
540  {
541  if (GNUNET_YES == dsc->remove_files)
542  remove_garbage(fullname);
543  return GNUNET_OK;
544  }
545  id = id_public;
546  }
547 
548  if ((NULL != r.hello) && (NULL != r.friend_only_hello) &&
549  (0 != GNUNET_memcmp(&id_friend, &id_public)))
550  {
551  /* HELLOs are not for the same peer */
552  GNUNET_break(0);
553  if (GNUNET_YES == dsc->remove_files)
554  remove_garbage(fullname);
555  return GNUNET_OK;
556  }
557  if (GNUNET_OK ==
559  strlen(filename),
560  &identity.public_key))
561  {
562  if (0 != GNUNET_memcmp(&id, &identity))
563  {
564  /* HELLOs are not for the same peer */
565  GNUNET_break(0);
566  if (GNUNET_YES == dsc->remove_files)
567  remove_garbage(fullname);
568  return GNUNET_OK;
569  }
570  }
571 
572  /* ok, found something valid, remember HELLO */
574  if (NULL != r.hello)
575  {
577  "Updating peer `%s' public HELLO \n",
578  GNUNET_i2s(&id));
579  update_hello(&id, r.hello);
580  GNUNET_free(r.hello);
581  }
582  if (NULL != r.friend_only_hello)
583  {
585  "Updating peer `%s' friend only HELLO \n",
586  GNUNET_i2s(&id));
587  update_hello(&id, r.friend_only_hello);
588  GNUNET_free(r.friend_only_hello);
589  }
590  dsc->matched++;
591  return GNUNET_OK;
592 }
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:541
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:662
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:501
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 601 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().

602 {
603  static unsigned int retries;
604  struct DirScanContext dsc;
605 
606  (void)cls;
607  cron_scan = NULL;
609  {
610  cron_scan =
614  NULL);
615  return;
616  }
617  dsc.matched = 0;
618  dsc.remove_files = GNUNET_YES;
620  _("Scanning directory `%s'\n"),
624  &dsc);
625  if ((0 == dsc.matched) && (0 == (++retries & 31)))
627  _("Still no peers found in `%s'!\n"),
629  cron_scan =
633  NULL);
634 }
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:1169
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:586
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:909
#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 645 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().

647 {
648  struct GNUNET_HELLO_Message *res;
649  struct GNUNET_HELLO_Message *tmp;
650  struct GNUNET_PeerIdentity pid;
651 
652  if (NULL != friend_hello)
653  {
654  res = GNUNET_HELLO_merge(hello, friend_hello);
656  return res;
657  }
658 
659  if (GNUNET_OK != GNUNET_HELLO_get_id(hello, &pid))
660  {
661  GNUNET_break(0);
662  return NULL;
663  }
664  tmp = GNUNET_HELLO_create(&pid.public_key, NULL, NULL, GNUNET_YES);
665  res = GNUNET_HELLO_merge(hello, tmp);
666  GNUNET_free(tmp);
668  return res;
669 }
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:662
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:519
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:202
#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:87
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 854 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().

855 {
856  struct TransmitContext *tc = cls;
857  struct HostEntry *pos = value;
858  struct InfoMessage *im;
859  uint16_t hs;
860  struct GNUNET_MQ_Envelope *env;
861 
862  hs = 0;
863 
864  if ((NULL != pos->hello) && (GNUNET_NO == tc->friend_only))
865  {
866  /* Copy public HELLO */
867  hs = GNUNET_HELLO_size(pos->hello);
868  GNUNET_assert(hs < GNUNET_MAX_MESSAGE_SIZE - sizeof(struct InfoMessage));
870  GNUNET_memcpy(&im[1], pos->hello, hs);
872  "Sending public HELLO with size %u for peer `%s'\n",
873  hs,
874  GNUNET_i2s(key));
875  }
876  else if ((NULL != pos->friend_only_hello) && (GNUNET_YES == tc->friend_only))
877  {
878  /* Copy friend only HELLO */
880  GNUNET_assert(hs < GNUNET_MAX_MESSAGE_SIZE - sizeof(struct InfoMessage));
882  GNUNET_memcpy(&im[1], pos->friend_only_hello, hs);
884  "Sending friend-only HELLO with size %u for peer `%s'\n",
885  hs,
886  GNUNET_i2s(key));
887  }
888  else
889  {
892  "Adding no HELLO for peer `%s'\n",
893  GNUNET_i2s(key));
894  }
895  im->peer = pos->identity;
897  return GNUNET_YES;
898 }
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:2424
#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:100
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:410
#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:114
#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:643
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:351
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 909 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().

910 {
911  struct GNUNET_TIME_Absolute *now = cls;
912  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
913  const struct GNUNET_HELLO_Message *hello;
914  struct GNUNET_HELLO_Message *new_hello;
915  int read_size;
916  unsigned int cur_hello_size;
917  unsigned int new_hello_size;
918  int read_pos;
919  int write_pos;
920  unsigned int cnt;
921  char *writebuffer;
922  uint64_t fsize;
923 
925  {
928  "fstat",
929  fn);
930  return GNUNET_OK;
931  }
932  read_size = GNUNET_DISK_fn_read(fn, buffer, sizeof(buffer));
933 
934  if ((read_size < (int)sizeof(struct GNUNET_MessageHeader)) ||
935  (fsize > GNUNET_MAX_MESSAGE_SIZE))
936  {
937  if (0 != unlink(fn))
940  "unlink",
941  fn);
942  return GNUNET_OK;
943  }
944 
945  writebuffer = GNUNET_malloc(read_size);
946  read_pos = 0;
947  write_pos = 0;
948  while (read_pos < read_size)
949  {
950  /* Check each HELLO */
951  hello = (const struct GNUNET_HELLO_Message *)&buffer[read_pos];
952  cur_hello_size = GNUNET_HELLO_size(hello);
953  if (0 == cur_hello_size)
954  {
955  /* Invalid data, discard */
956  if (0 != unlink(fn))
959  "unlink",
960  fn);
961  GNUNET_free(writebuffer);
962  return GNUNET_OK;
963  }
964  new_hello =
966  cnt = 0;
967  if (NULL != new_hello)
968  (void)GNUNET_HELLO_iterate_addresses(hello,
969  GNUNET_NO,
971  &cnt);
972  if ((NULL != new_hello) && (0 < cnt))
973  {
974  /* Store new HELLO to write it when done */
975  new_hello_size = GNUNET_HELLO_size(new_hello);
976  GNUNET_memcpy(&writebuffer[write_pos], new_hello, new_hello_size);
977  write_pos += new_hello_size;
978  }
979  read_pos += cur_hello_size;
980  GNUNET_free_non_null(new_hello);
981  }
982 
983  if (0 < write_pos)
984  {
986  writebuffer,
987  write_pos,
992  }
993  else if (0 != unlink(fn))
996  "unlink",
997  fn);
998 
999  GNUNET_free(writebuffer);
1000  return GNUNET_OK;
1001 }
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:877
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:252
#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:254
#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:643
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:791
#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 1011 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().

1012 {
1013  struct GNUNET_TIME_Absolute now;
1014 
1015  (void)cls;
1016  cron_clean = NULL;
1017  now = GNUNET_TIME_absolute_get();
1019  _("Cleaning up directory `%s'\n"),
1024  NULL);
1025 }
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:909
#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:1237
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 1036 of file gnunet-service-peerinfo.c.

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

1037 {
1038  struct GNUNET_PeerIdentity pid;
1039 
1040  (void)cls;
1041  if (GNUNET_OK != GNUNET_HELLO_get_id(hello, &pid))
1042  {
1043  GNUNET_break(0);
1044  return GNUNET_SYSERR;
1045  }
1046  return GNUNET_OK;
1047 }
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:662
#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 1057 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().

1058 {
1059  struct GNUNET_SERVICE_Client *client = cls;
1060  struct GNUNET_PeerIdentity pid;
1061 
1064  "HELLO message received for peer `%s'\n",
1065  GNUNET_i2s(&pid));
1067  update_hello(&pid, hello);
1069 }
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:662
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:246
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:2234
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 1079 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.

1080 {
1081  struct GNUNET_SERVICE_Client *client = cls;
1082  struct TransmitContext tcx;
1083  struct GNUNET_MessageHeader *msg;
1084  struct GNUNET_MQ_Envelope *env;
1085 
1087  "GET message received for peer `%s'\n",
1088  GNUNET_i2s(&lpm->peer));
1089  tcx.friend_only = ntohl(lpm->include_friend_only);
1090  tcx.client = client;
1092  &lpm->peer,
1093  &add_to_tc,
1094  &tcx);
1098 }
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:2424
#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:246
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:351
#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:2234
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 1108 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.

1109 {
1110  struct GNUNET_SERVICE_Client *client = cls;
1111  struct TransmitContext tcx;
1112  struct GNUNET_MQ_Envelope *env;
1113  struct GNUNET_MessageHeader *msg;
1114 
1115  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "GET_ALL message received\n");
1116  tcx.friend_only = ntohl(lapm->include_friend_only);
1117  tcx.client = client;
1122 }
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:73
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:2424
#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:246
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:351
#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:2234
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 1132 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.

1133 {
1134  struct GNUNET_SERVICE_Client *client = cls;
1135  struct GNUNET_MQ_Handle *mq;
1136  struct TransmitContext tcx;
1137  struct GNUNET_MQ_Envelope *env;
1138  struct GNUNET_MessageHeader *msg;
1139 
1140  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "NOTIFY message received\n");
1141  mq = GNUNET_SERVICE_client_get_mq(client);
1143  if (ntohl(nm->include_friend_only))
1145  else
1147  tcx.friend_only = ntohl(nm->include_friend_only);
1148  tcx.client = client;
1153 }
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:89
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2424
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:158
Handle to a client that is connected to a service.
Definition: service.c:246
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:2394
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:84
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:351
#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:2234
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 1165 of file gnunet-service-peerinfo.c.

Referenced by run().

1168 {
1169  (void)cls;
1170  (void)mq;
1171  return client;
1172 }
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 1183 of file gnunet-service-peerinfo.c.

References GNUNET_assert.

Referenced by run().

1186 {
1187  (void)cls;
1188  GNUNET_assert(app_ctx == client);
1189 }
#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 1201 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().

1202 {
1203  struct HostEntry *he = value;
1204 
1205  (void)cls;
1206  (void)key;
1209  GNUNET_free(he);
1210  return GNUNET_YES;
1211 }
#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 1220 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().

1221 {
1222  (void)cls;
1224  notify_list = NULL;
1226  notify_friend_only_list = NULL;
1227 
1230  if (NULL != stats)
1231  {
1233  stats = NULL;
1234  }
1235  if (NULL != cron_clean)
1236  {
1238  cron_clean = NULL;
1239  }
1240  if (NULL != cron_scan)
1241  {
1243  cron_scan = NULL;
1244  }
1245  if (NULL != networkIdDirectory)
1246  {
1248  networkIdDirectory = NULL;
1249  }
1250 }
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:135
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:956
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 1261 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().

1264 {
1265  char *peerdir;
1266  char *ip;
1267  struct DirScanContext dsc;
1268  int noio;
1269  int use_included;
1270 
1271  (void)cls;
1272  (void)service;
1274  stats = GNUNET_STATISTICS_create("peerinfo", cfg);
1277  noio = GNUNET_CONFIGURATION_get_value_yesno(cfg, "peerinfo", "NO_IO");
1278  use_included = GNUNET_CONFIGURATION_get_value_yesno(cfg,
1279  "peerinfo",
1280  "USE_INCLUDED_HELLOS");
1281  if (GNUNET_SYSERR == use_included)
1282  use_included = GNUNET_NO;
1284  if (GNUNET_YES != noio)
1285  {
1286  GNUNET_assert(
1287  GNUNET_OK ==
1289  "peerinfo",
1290  "HOSTS",
1291  &networkIdDirectory));
1293  {
1295  return;
1296  }
1297 
1298  cron_scan =
1301  NULL);
1302 
1303  cron_clean =
1306  NULL);
1307  if (GNUNET_YES == use_included)
1308  {
1310  GNUNET_asprintf(&peerdir, "%shellos", ip);
1311  GNUNET_free(ip);
1312 
1314  _("Importing HELLOs from `%s'\n"),
1315  peerdir);
1316  dsc.matched = 0;
1317  dsc.remove_files = GNUNET_NO;
1318 
1321  &dsc);
1322  GNUNET_free(peerdir);
1323  }
1324  else
1325  {
1327  _("Skipping import of included HELLOs\n"));
1328  }
1329  }
1330 }
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:586
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:1284
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:909
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:517
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:1191
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:119
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 92 of file gnunet-service-peerinfo.c.

◆ notify_list

struct GNUNET_NotificationContext* notify_list
static

Clients to immediately notify about all changes.

Definition at line 97 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 103 of file gnunet-service-peerinfo.c.

◆ networkIdDirectory

char* networkIdDirectory
static

Directory where the hellos are stored in (peerinfo/)

Definition at line 108 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 113 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 118 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 123 of file gnunet-service-peerinfo.c.