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 46 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().

139 {
140  struct InfoMessage *im;
141  struct GNUNET_HELLO_Message *src;
142  size_t hs;
143 
145  src = he->friend_only_hello;
146  else
147  src = he->hello;
148  hs = (NULL == src) ? 0 : GNUNET_HELLO_size (src);
149  im = GNUNET_malloc (sizeof (struct InfoMessage) + hs);
150  im->header.size = htons (hs + sizeof (struct InfoMessage));
152  im->peer = he->identity;
153  GNUNET_memcpy (&im[1],
154  src,
155  hs);
156  return im;
157 }
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:107
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:123
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_PEERINFO_INFO.
Definition: peerinfo.h:113
#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:649
#define GNUNET_YES
Definition: gnunet_common.h:80
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 169 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().

172 {
173  const struct GNUNET_TIME_Absolute *now = cls;
174 
175  if (now->abs_value_us > expiration.abs_value_us)
176  {
178  _("Removing expired address of transport `%s'\n"),
179  address->transport_name);
180  return GNUNET_NO;
181  }
182  return GNUNET_OK;
183 }
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
uint64_t abs_value_us
The actual value.
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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 195 of file gnunet-service-peerinfo.c.

References GNUNET_OK.

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

198 {
199  unsigned int *cnt = cls;
200 
201  (void) address;
202  (void) expiration;
203  (*cnt)++;
204  return GNUNET_OK;
205 }
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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 216 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().

217 {
218  char *fn;
219 
220  if (NULL == networkIdDirectory)
221  return NULL;
222  GNUNET_asprintf (&fn,
223  "%s%s%s",
226  GNUNET_i2s_full (id));
227  return fn;
228 }
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.
static char * networkIdDirectory
Directory where the hellos are stored in (peerinfo/)
#define DIR_SEPARATOR_STR
Definition: plibc.h:632
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 238 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().

239 {
240  struct InfoMessage *msg_pub;
241  struct InfoMessage *msg_friend;
242 
244  "Notifying all clients about peer `%s'\n",
245  GNUNET_i2s(&entry->identity));
246  msg_pub = make_info_message (entry,
247  GNUNET_NO);
249  &msg_pub->header,
250  GNUNET_NO);
251  GNUNET_free (msg_pub);
252  msg_friend = make_info_message (entry,
253  GNUNET_YES);
255  &msg_friend->header,
256  GNUNET_NO);
257  GNUNET_free (msg_friend);
258 }
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:107
#define GNUNET_NO
Definition: gnunet_common.h:81
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:113
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:192
#define GNUNET_log(kind,...)
#define GNUNET_YES
Definition: gnunet_common.h:80
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 723 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, host, notify_all(), size, UNLINK, and update_friend_hello().

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

725 {
726  char *fn;
727  struct HostEntry *host;
728  struct GNUNET_HELLO_Message *mrg;
729  struct GNUNET_HELLO_Message **dest;
731  unsigned int cnt;
732  unsigned int size;
733  int friend_hello_type;
734  int store_hello;
735  int store_friend_hello;
736  unsigned int pos;
737  char *buffer;
738 
740  GNUNET_assert (NULL != host);
741 
742  friend_hello_type = GNUNET_HELLO_is_friend_only (hello);
744  "Updating %s HELLO for `%s'\n",
745  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
746  GNUNET_i2s (peer));
747 
748  dest = NULL;
749  if (GNUNET_YES == friend_hello_type)
750  {
751  dest = &host->friend_only_hello;
752  }
753  else
754  {
755  dest = &host->hello;
756  }
757 
758  if (NULL == (*dest))
759  {
760  (*dest) = GNUNET_malloc (GNUNET_HELLO_size (hello));
761  GNUNET_memcpy ((*dest), hello, GNUNET_HELLO_size (hello));
762  }
763  else
764  {
765  mrg = GNUNET_HELLO_merge ((*dest),
766  hello);
767  delta = GNUNET_HELLO_equals (mrg,
768  (*dest),
770  if (delta.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
771  {
772  /* no differences, just ignore the update */
774  "No change in %s HELLO for `%s'\n",
775  (GNUNET_YES == friend_hello_type) ? "friend-only" : "public",
776  GNUNET_i2s (peer));
777  GNUNET_free (mrg);
778  return;
779  }
780  GNUNET_free ((*dest));
781  (*dest) = mrg;
782  }
783 
784  if ( (NULL != (host->hello)) &&
785  (GNUNET_NO == friend_hello_type) )
786  {
787  /* Update friend only hello */
788  mrg = update_friend_hello (host->hello,
789  host->friend_only_hello);
790  if (NULL != host->friend_only_hello)
792  host->friend_only_hello = mrg;
793  }
794 
795  if (NULL != host->hello)
798  if (NULL != host->friend_only_hello)
801 
802  fn = get_host_filename (peer);
803  if ( (NULL != fn) &&
804  (GNUNET_OK ==
806  {
807  store_hello = GNUNET_NO;
808  size = 0;
809  cnt = 0;
810  if (NULL != host->hello)
812  GNUNET_NO,
814  &cnt);
815  if (cnt > 0)
816  {
817  store_hello = GNUNET_YES;
818  size += GNUNET_HELLO_size (host->hello);
819  }
820  cnt = 0;
821  if (NULL != host->friend_only_hello)
823  GNUNET_NO,
825  &cnt);
826  store_friend_hello = GNUNET_NO;
827  if (0 < cnt)
828  {
829  store_friend_hello = GNUNET_YES;
830  size += GNUNET_HELLO_size (host->friend_only_hello);
831  }
832 
833  if ( (GNUNET_NO == store_hello) &&
834  (GNUNET_NO == store_friend_hello) )
835  {
836  /* no valid addresses, don't put HELLO on disk; in fact,
837  if one exists on disk, remove it */
838  (void) UNLINK (fn);
839  }
840  else
841  {
842  buffer = GNUNET_malloc (size);
843  pos = 0;
844 
845  if (GNUNET_YES == store_hello)
846  {
847  GNUNET_memcpy (buffer,
848  host->hello,
849  GNUNET_HELLO_size (host->hello));
850  pos += GNUNET_HELLO_size (host->hello);
851  }
852  if (GNUNET_YES == store_friend_hello)
853  {
854  GNUNET_memcpy (&buffer[pos],
855  host->friend_only_hello,
857  pos += GNUNET_HELLO_size (host->friend_only_hello);
858  }
859  GNUNET_assert (pos == size);
860 
861  if (GNUNET_SYSERR == GNUNET_DISK_fn_write (fn, buffer, size,
867  else
869  "Stored %s %s HELLO in %s with total size %u\n",
870  (GNUNET_YES == store_friend_hello) ? "friend-only": "",
871  (GNUNET_YES == store_hello) ? "public": "",
872  fn,
873  size);
874  GNUNET_free (buffer);
875  }
876  }
878  notify_all (host);
879 }
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:832
int GNUNET_DISK_directory_create_for_file(const char *filename)
Create the directory structure for storing a file.
Definition: disk.c:833
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:1203
#define UNLINK(f)
Definition: plibc.h:666
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define GNUNET_memcpy(dst, src, n)
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:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
GUID host
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:649
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:80
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 284 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, ReadHostFileContext::hello, TRUNCATE, and UNLINK.

Referenced by add_host_to_known_hosts(), and hosts_directory_scan_callback().

287 {
288  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
289  ssize_t size_total;
290  struct GNUNET_TIME_Absolute now;
291  unsigned int left;
292  const struct GNUNET_HELLO_Message *hello;
293  struct GNUNET_HELLO_Message *hello_clean;
294  size_t read_pos;
295  uint16_t size_hello;
296 
297  r->friend_only_hello = NULL;
298  r->hello = NULL;
299 
301  return;
302  size_total = GNUNET_DISK_fn_read (fn,
303  buffer,
304  sizeof (buffer));
306  "Read %d bytes from `%s'\n",
307  (int) size_total,
308  fn);
309  if ( (size_total < 0) ||
310  (((size_t) size_total) < sizeof (struct GNUNET_MessageHeader)) )
311  {
313  _("Failed to parse HELLO in file `%s': %s\n"),
314  fn,
315  "File has invalid size");
316  if ( (GNUNET_YES == unlink_garbage) &&
317  (0 != UNLINK (fn)) &&
318  (ENOENT != errno) )
320  "unlink",
321  fn);
322  return;
323  }
324 
325  read_pos = 0;
326  while (read_pos < (size_t) size_total)
327  {
328  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
329  size_hello = GNUNET_HELLO_size (hello);
330  if ( (0 == size_hello) ||
331  (((size_t) size_total) - read_pos < size_hello) )
332  {
334  _("Failed to parse HELLO in file `%s'\n"),
335  fn);
336  if (0 == read_pos)
337  {
338  if ((GNUNET_YES == unlink_garbage) &&
339  (0 != UNLINK (fn)) &&
340  (ENOENT != errno) )
342  "unlink",
343  fn);
344  }
345  else
346  {
347  if ( (GNUNET_YES == unlink_garbage) &&
348  (0 != TRUNCATE (fn, read_pos)) &&
349  (ENOENT != errno) )
351  "truncate",
352  fn);
353  }
354  return;
355  }
356 
357  now = GNUNET_TIME_absolute_get ();
358  hello_clean = GNUNET_HELLO_iterate_addresses (hello,
359  GNUNET_YES,
361  &now);
362  if (NULL == hello_clean)
363  {
365  _("Failed to parse HELLO in file `%s'\n"),
366  fn);
367  if ((GNUNET_YES == unlink_garbage) &&
368  (0 != UNLINK (fn)) &&
369  (ENOENT != errno) )
371  "unlink",
372  fn);
373  return;
374  }
375  left = 0;
376  (void) GNUNET_HELLO_iterate_addresses (hello_clean,
377  GNUNET_NO,
379  &left);
380 
381  if (0 == left)
382  {
383  GNUNET_free (hello_clean);
384  break;
385  }
386 
387  if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello_clean))
388  {
389  if (NULL == r->hello)
390  r->hello = hello_clean;
391  else
392  {
393  GNUNET_break (0);
394  GNUNET_free (r->hello);
395  r->hello = hello_clean;
396  }
397  }
398  else
399  {
400  if (NULL == r->friend_only_hello)
401  r->friend_only_hello = hello_clean;
402  else
403  {
404  GNUNET_break (0);
406  r->friend_only_hello = hello_clean;
407  }
408  }
409  read_pos += size_hello;
410  }
411 
412  if (0 == left)
413  {
414  /* no addresses left, remove from disk */
415  if ( (GNUNET_YES == unlink_garbage) &&
416  (0 != UNLINK (fn)) )
418  "unlink",
419  fn);
420  }
422  "Found `%s' and `%s' HELLO message in file\n",
423  (NULL != r->hello) ? "public" : "NON-public",
424  (NULL != r->friend_only_hello) ? "friend only" : "NO friend only");
425 }
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:669
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:81
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define UNLINK(f)
Definition: plibc.h:666
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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,...)
#define TRUNCATE(f, l)
Definition: plibc.h:647
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:649
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:1019
#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 435 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().

436 {
437  struct HostEntry *entry;
438  struct ReadHostFileContext r;
439  char *fn;
440 
442  identity);
443  if (NULL == entry)
444  {
446  "Adding new peer `%s'\n",
447  GNUNET_i2s (identity));
449  gettext_noop ("# peers known"),
450  1,
451  GNUNET_NO);
452  entry = GNUNET_new (struct HostEntry);
453  entry->identity = *identity;
456  &entry->identity,
457  entry,
459  notify_all (entry);
460  fn = get_host_filename (identity);
461  if (NULL != fn)
462  {
463  read_host_file (fn,
464  GNUNET_YES,
465  &r);
466  if (NULL != r.hello)
467  update_hello (identity,
468  r.hello);
469  if (NULL != r.friend_only_hello)
470  update_hello (identity,
471  r.friend_only_hello);
472  GNUNET_free_non_null (r.hello);
473  GNUNET_free_non_null (r.friend_only_hello);
474  GNUNET_free (fn);
475  }
476  }
477  return entry;
478 }
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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
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:80
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 488 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, networkIdDirectory, and UNLINK.

Referenced by hosts_directory_scan_callback().

489 {
490  if (0 == UNLINK (fullname))
492  _("File `%s' in directory `%s' does not match naming convention. Removed.\n"),
493  fullname,
495  else
497  "unlink",
498  fullname);
499 }
#define UNLINK(f)
Definition: plibc.h:666
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
#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 532 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().

534 {
535  struct DirScanContext *dsc = cls;
537  struct ReadHostFileContext r;
538  const char *filename;
539  struct GNUNET_PeerIdentity id_public;
540  struct GNUNET_PeerIdentity id_friend;
541  struct GNUNET_PeerIdentity id;
542 
543  if (GNUNET_YES != GNUNET_DISK_file_test (fullname))
544  return GNUNET_OK; /* ignore non-files */
545 
546  filename = strrchr (fullname,
547  DIR_SEPARATOR);
548  if ( (NULL == filename) ||
549  (1 > strlen (filename)) )
550  filename = fullname;
551  else
552  filename ++;
553 
554  read_host_file (fullname,
555  dsc->remove_files,
556  &r);
557  if ( (NULL == r.hello) &&
558  (NULL == r.friend_only_hello))
559  return GNUNET_OK;
560  if (NULL != r.friend_only_hello)
561  {
562  if (GNUNET_OK !=
563  GNUNET_HELLO_get_id (r.friend_only_hello,
564  &id_friend))
565  {
566  if (GNUNET_YES == dsc->remove_files)
567  remove_garbage (fullname);
568  return GNUNET_OK;
569  }
570  id = id_friend;
571  }
572  if (NULL != r.hello)
573  {
574  if (GNUNET_OK !=
575  GNUNET_HELLO_get_id (r.hello,
576  &id_public))
577  {
578  if (GNUNET_YES == dsc->remove_files)
579  remove_garbage (fullname);
580  return GNUNET_OK;
581  }
582  id = id_public;
583  }
584 
585  if ( (NULL != r.hello) &&
586  (NULL != r.friend_only_hello) &&
587  (0 != GNUNET_memcmp (&id_friend,
588  &id_public)) )
589  {
590  /* HELLOs are not for the same peer */
591  GNUNET_break (0);
592  if (GNUNET_YES == dsc->remove_files)
593  remove_garbage (fullname);
594  return GNUNET_OK;
595  }
596  if (GNUNET_OK ==
598  strlen (filename),
599  &identity.public_key))
600  {
601  if (0 != GNUNET_memcmp (&id, &identity))
602  {
603  /* HELLOs are not for the same peer */
604  GNUNET_break (0);
605  if (GNUNET_YES == dsc->remove_files)
606  remove_garbage (fullname);
607  return GNUNET_OK;
608  }
609  }
610 
611  /* ok, found something valid, remember HELLO */
613  if (NULL != r.hello)
614  {
616  "Updating peer `%s' public HELLO \n",
617  GNUNET_i2s (&id));
618  update_hello (&id, r.hello);
619  GNUNET_free (r.hello);
620  }
621  if (NULL != r.friend_only_hello)
622  {
624  "Updating peer `%s' friend only HELLO \n",
625  GNUNET_i2s (&id));
626  update_hello (&id, r.friend_only_hello);
627  GNUNET_free (r.friend_only_hello);
628  }
629  dsc->matched++;
630  return GNUNET_OK;
631 }
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:669
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:668
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:78
#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: plibc.h:631
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:80
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 640 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().

641 {
642  static unsigned int retries;
643  struct DirScanContext dsc;
644 
645  (void) cls;
646  cron_scan = NULL;
647  if (GNUNET_SYSERR ==
649  {
653  return;
654  }
655  dsc.matched = 0;
656  dsc.remove_files = GNUNET_YES;
658  _("Scanning directory `%s'\n"),
662  &dsc);
663  if ( (0 == dsc.matched) &&
664  (0 == (++retries & 31)) )
666  _("Still no peers found in `%s'!\n"),
671  NULL);
672 }
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:1178
int GNUNET_DISK_directory_create(const char *dir)
Implementation of "mkdir -p".
Definition: disk.c:714
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:1233
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
Closure for hosts_directory_scan_callback().
Run when otherwise idle.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#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:80
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 683 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().

685 {
686  struct GNUNET_HELLO_Message * res;
687  struct GNUNET_HELLO_Message * tmp;
688  struct GNUNET_PeerIdentity pid;
689 
690  if (NULL != friend_hello)
691  {
692  res = GNUNET_HELLO_merge (hello,
693  friend_hello);
696  return res;
697  }
698 
699  if (GNUNET_OK !=
700  GNUNET_HELLO_get_id (hello, &pid))
701  {
702  GNUNET_break (0);
703  return NULL;
704  }
706  NULL,
707  NULL,
708  GNUNET_YES);
709  res = GNUNET_HELLO_merge (hello, tmp);
710  GNUNET_free (tmp);
712  return res;
713 }
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:668
A HELLO message is used to exchange information about transports with other peers.
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:78
#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:80
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 908 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().

911 {
912  struct TransmitContext *tc = cls;
913  struct HostEntry *pos = value;
914  struct InfoMessage *im;
915  uint16_t hs;
916  struct GNUNET_MQ_Envelope *env;
917 
918  hs = 0;
919 
920  if ( (NULL != pos->hello) &&
921  (GNUNET_NO == tc->friend_only) )
922  {
923  /* Copy public HELLO */
924  hs = GNUNET_HELLO_size (pos->hello);
926  sizeof (struct InfoMessage));
927  env = GNUNET_MQ_msg_extra (im,
928  hs,
930  GNUNET_memcpy (&im[1],
931  pos->hello,
932  hs);
934  "Sending public HELLO with size %u for peer `%s'\n",
935  hs,
936  GNUNET_i2s (key));
937  }
938  else if ( (NULL != pos->friend_only_hello) &&
939  (GNUNET_YES == tc->friend_only) )
940  {
941  /* Copy friend only HELLO */
944  sizeof (struct InfoMessage));
945  env = GNUNET_MQ_msg_extra (im,
946  hs,
948  GNUNET_memcpy (&im[1],
949  pos->friend_only_hello,
950  hs);
952  "Sending friend-only HELLO with size %u for peer `%s'\n",
953  hs,
954  GNUNET_i2s (key));
955  }
956  else
957  {
958  env = GNUNET_MQ_msg (im,
961  "Adding no HELLO for peer `%s'\n",
962  GNUNET_i2s (key));
963  }
964  im->peer = pos->identity;
966  env);
967  return GNUNET_YES;
968 }
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:2734
#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:107
static struct GNUNET_SCHEDULER_TaskContext tc
Task context of the current task.
Definition: scheduler.c:417
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:81
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:123
#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
#define GNUNET_memcpy(dst, src, n)
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:649
In-memory cache of known hosts.
#define GNUNET_YES
Definition: gnunet_common.h:80
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 979 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, HostEntry::hello, and UNLINK.

Referenced by cron_clean_data_hosts().

981 {
982  struct GNUNET_TIME_Absolute *now = cls;
983  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
984  const struct GNUNET_HELLO_Message *hello;
985  struct GNUNET_HELLO_Message *new_hello;
986  int read_size;
987  unsigned int cur_hello_size;
988  unsigned int new_hello_size;
989  int read_pos;
990  int write_pos;
991  unsigned int cnt;
992  char *writebuffer;
993  uint64_t fsize;
994 
995  if (GNUNET_OK !=
997  &fsize,
998  GNUNET_YES,
999  GNUNET_YES))
1000  {
1003  "fstat",
1004  fn);
1005  return GNUNET_OK;
1006  }
1007  read_size = GNUNET_DISK_fn_read (fn,
1008  buffer,
1009  sizeof (buffer));
1010 
1011  if ( (read_size < (int) sizeof (struct GNUNET_MessageHeader)) ||
1012  (fsize > GNUNET_MAX_MESSAGE_SIZE) )
1013  {
1014  if (0 != UNLINK (fn))
1017  "unlink",
1018  fn);
1019  return GNUNET_OK;
1020  }
1021 
1022  writebuffer = GNUNET_malloc (read_size);
1023  read_pos = 0;
1024  write_pos = 0;
1025  while (read_pos < read_size)
1026  {
1027  /* Check each HELLO */
1028  hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
1029  cur_hello_size = GNUNET_HELLO_size (hello);
1030  if (0 == cur_hello_size)
1031  {
1032  /* Invalid data, discard */
1033  if (0 != UNLINK (fn))
1036  "unlink",
1037  fn);
1038  GNUNET_free (writebuffer);
1039  return GNUNET_OK;
1040  }
1041  new_hello = GNUNET_HELLO_iterate_addresses (hello,
1042  GNUNET_YES,
1043  &discard_expired,
1044  now);
1045  cnt = 0;
1046  if (NULL != new_hello)
1047  (void) GNUNET_HELLO_iterate_addresses (hello,
1048  GNUNET_NO,
1049  &count_addresses,
1050  &cnt);
1051  if ( (NULL != new_hello) && (0 < cnt) )
1052  {
1053  /* Store new HELLO to write it when done */
1054  new_hello_size = GNUNET_HELLO_size (new_hello);
1055  GNUNET_memcpy (&writebuffer[write_pos],
1056  new_hello,
1057  new_hello_size);
1058  write_pos += new_hello_size;
1059  }
1060  read_pos += cur_hello_size;
1061  GNUNET_free_non_null (new_hello);
1062  }
1063 
1064  if (0 < write_pos)
1065  {
1067  writebuffer,
1068  write_pos,
1073  }
1074  else if (0 != UNLINK (fn))
1077  "unlink", fn);
1078 
1079  GNUNET_free (writebuffer);
1080  return GNUNET_OK;
1081 }
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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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:1203
#define UNLINK(f)
Definition: plibc.h:666
#define GNUNET_memcpy(dst, src, n)
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:289
#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:649
Header for all communications.
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:1019
#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 1091 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().

1092 {
1093  struct GNUNET_TIME_Absolute now;
1094 
1095  (void) cls;
1096  cron_clean = NULL;
1097  now = GNUNET_TIME_absolute_get ();
1099  _("Cleaning up directory `%s'\n"),
1103  &now);
1106  NULL);
1107 }
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:1233
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1246
static 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 1118 of file gnunet-service-peerinfo.c.

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

1120 {
1121  struct GNUNET_PeerIdentity pid;
1122 
1123  (void) cls;
1124  if (GNUNET_OK !=
1125  GNUNET_HELLO_get_id (hello,
1126  &pid))
1127  {
1128  GNUNET_break (0);
1129  return GNUNET_SYSERR;
1130  }
1131  return GNUNET_OK;
1132 }
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:668
#define GNUNET_OK
Named constants for return values.
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 GNUNET_SYSERR
Definition: gnunet_common.h:79
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 1142 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().

1144 {
1145  struct GNUNET_SERVICE_Client *client = cls;
1146  struct GNUNET_PeerIdentity pid;
1147 
1149  GNUNET_HELLO_get_id (hello,
1150  &pid));
1152  "HELLO message received for peer `%s'\n",
1153  GNUNET_i2s (&pid));
1155  update_hello (&pid,
1156  hello);
1158 }
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:668
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:78
Handle to a client that is connected to a service.
Definition: service.c:249
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:2533
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 1168 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.

1170 {
1171  struct GNUNET_SERVICE_Client *client = cls;
1172  struct TransmitContext tcx;
1173  struct GNUNET_MessageHeader *msg;
1174  struct GNUNET_MQ_Envelope *env;
1175 
1177  "GET message received for peer `%s'\n",
1178  GNUNET_i2s (&lpm->peer));
1179  tcx.friend_only = ntohl (lpm->include_friend_only);
1180  tcx.client = client;
1182  &lpm->peer,
1183  &add_to_tc,
1184  &tcx);
1185  env = GNUNET_MQ_msg (msg,
1188  env);
1190 }
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:53
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:59
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
#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:249
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:2533
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 1200 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.

1202 {
1203  struct GNUNET_SERVICE_Client *client = cls;
1204  struct TransmitContext tcx;
1205  struct GNUNET_MQ_Envelope *env;
1206  struct GNUNET_MessageHeader *msg;
1207 
1209  "GET_ALL message received\n");
1210  tcx.friend_only = ntohl (lapm->include_friend_only);
1211  tcx.client = client;
1213  &add_to_tc,
1214  &tcx);
1215  env = GNUNET_MQ_msg (msg,
1218  env);
1220 }
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:77
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:2734
#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:249
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:2533
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 1230 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.

1232 {
1233  struct GNUNET_SERVICE_Client *client = cls;
1234  struct GNUNET_MQ_Handle *mq;
1235  struct TransmitContext tcx;
1236  struct GNUNET_MQ_Envelope *env;
1237  struct GNUNET_MessageHeader *msg;
1238 
1240  "NOTIFY message received\n");
1241  mq = GNUNET_SERVICE_client_get_mq (client);
1243  if (ntohl (nm->include_friend_only))
1245  mq);
1246  else
1248  mq);
1249  tcx.friend_only = ntohl (nm->include_friend_only);
1250  tcx.client = client;
1252  &add_to_tc,
1253  &tcx);
1254  env = GNUNET_MQ_msg (msg,
1257  env);
1259 }
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:95
struct GNUNET_MQ_Handle * GNUNET_SERVICE_client_get_mq(struct GNUNET_SERVICE_Client *c)
Obtain the message queue of c.
Definition: service.c:2734
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:164
Handle to a client that is connected to a service.
Definition: service.c:249
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:2704
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:2533
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 1271 of file gnunet-service-peerinfo.c.

Referenced by run().

1274 {
1275  (void) cls;
1276  (void) mq;
1277  return client;
1278 }
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 1289 of file gnunet-service-peerinfo.c.

References GNUNET_assert.

Referenced by run().

1292 {
1293  (void) cls;
1294  GNUNET_assert (app_ctx == client);
1295 }
#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 1307 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().

1310 {
1311  struct HostEntry *he = value;
1312 
1313  (void) cls;
1314  (void) key;
1317  GNUNET_free (he);
1318  return GNUNET_YES;
1319 }
#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:80
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 1328 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().

1329 {
1330  (void) cls;
1332  notify_list = NULL;
1334  notify_friend_only_list = NULL;
1335 
1337  &free_host_entry,
1338  NULL);
1340  if (NULL != stats)
1341  {
1343  GNUNET_NO);
1344  stats = NULL;
1345  }
1346  if (NULL != cron_clean)
1347  {
1349  cron_clean = NULL;
1350  }
1351  if (NULL != cron_scan)
1352  {
1354  cron_scan = NULL;
1355  }
1356  if (NULL != networkIdDirectory)
1357  {
1359  networkIdDirectory = NULL;
1360  }
1361 }
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:81
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:141
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:965
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 1372 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().

1375 {
1376  char *peerdir;
1377  char *ip;
1378  struct DirScanContext dsc;
1379  int noio;
1380  int use_included;
1381 
1382  (void) cls;
1383  (void) service;
1384  hostmap
1386  GNUNET_YES);
1387  stats
1388  = GNUNET_STATISTICS_create ("peerinfo",
1389  cfg);
1390  notify_list
1395  "peerinfo",
1396  "NO_IO");
1397  use_included
1399  "peerinfo",
1400  "USE_INCLUDED_HELLOS");
1401  if (GNUNET_SYSERR == use_included)
1402  use_included = GNUNET_NO;
1404  NULL);
1405  if (GNUNET_YES != noio)
1406  {
1409  "peerinfo",
1410  "HOSTS",
1411  &networkIdDirectory));
1412  if (GNUNET_OK !=
1414  {
1416  return;
1417  }
1418 
1419  cron_scan
1422  NULL);
1423 
1424  cron_clean
1427  NULL);
1428  if (GNUNET_YES == use_included)
1429  {
1431  GNUNET_asprintf (&peerdir,
1432  "%shellos",
1433  ip);
1434  GNUNET_free (ip);
1435 
1437  _("Importing HELLOs from `%s'\n"),
1438  peerdir);
1439  dsc.matched = 0;
1440  dsc.remove_files = GNUNET_NO;
1441 
1442  GNUNET_DISK_directory_scan (peerdir,
1444  &dsc);
1445  GNUNET_free (peerdir);
1446  }
1447  else
1448  {
1450  _("Skipping import of included HELLOs\n"));
1451  }
1452  }
1453 }
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:714
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:1293
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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
int GNUNET_DISK_directory_scan(const char *dir_name, GNUNET_FileNameCallback callback, void *callback_cls)
Scan a directory for files.
Definition: disk.c:1233
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:524
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:208
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:1200
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:79
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:125
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:80
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.