GNUnet  0.19.4
peerinfo_api.c File Reference

API to access peerinfo service. More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "peerinfo.h"
Include dependency graph for peerinfo_api.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_PEERINFO_IteratorContext
 Context for an iteration request. More...
 
struct  GNUNET_PEERINFO_Handle
 Handle to the peerinfo service. More...
 

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "peerinfo-api", __VA_ARGS__)
 

Functions

static void reconnect (struct GNUNET_PEERINFO_Handle *h)
 Close the existing connection to PEERINFO and reconnect. More...
 
struct GNUNET_PEERINFO_HandleGNUNET_PEERINFO_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
 Connect to the peerinfo service. More...
 
void GNUNET_PEERINFO_disconnect (struct GNUNET_PEERINFO_Handle *h)
 Disconnect from the peerinfo service. More...
 
static void reconnect_task (void *cls)
 Task scheduled to re-try connecting to the peerinfo service. More...
 
static void do_reconnect (struct GNUNET_PEERINFO_Handle *h)
 We encountered an error, reconnect to the PEERINFO service. More...
 
static void mq_error_handler (void *cls, enum GNUNET_MQ_Error error)
 We got a disconnect after asking regex to do the announcement. More...
 
static int check_info (void *cls, const struct InfoMessage *im)
 Function called when we receive an info message. More...
 
static void handle_info (void *cls, const struct InfoMessage *im)
 Handle info message. More...
 
static void send_ic_request (struct GNUNET_PEERINFO_Handle *h)
 Send the next IC request at the head of the queue. More...
 
static void handle_end_iteration (void *cls, const struct GNUNET_MessageHeader *msg)
 Type of a function to call when we receive a message from the service. More...
 
struct GNUNET_PEERINFO_IteratorContextGNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h, int include_friend_only, const struct GNUNET_PeerIdentity *peer, GNUNET_PEERINFO_Processor callback, void *callback_cls)
 Call a method for each known matching host. More...
 
void GNUNET_PEERINFO_iterate_cancel (struct GNUNET_PEERINFO_IteratorContext *ic)
 Cancel an iteration over peer information. More...
 
struct GNUNET_MQ_EnvelopeGNUNET_PEERINFO_add_peer (struct GNUNET_PEERINFO_Handle *h, const struct GNUNET_HELLO_Message *hello, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
 Add a host to the persistent list. More...
 

Detailed Description

API to access peerinfo service.

Author
Christian Grothoff

Definition in file peerinfo_api.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "peerinfo-api", __VA_ARGS__)

Definition at line 31 of file peerinfo_api.c.

Function Documentation

◆ reconnect()

static void reconnect ( struct GNUNET_PEERINFO_Handle h)
static

Close the existing connection to PEERINFO and reconnect.

Parameters
hhandle to the service

Definition at line 429 of file peerinfo_api.c.

430 {
434  struct InfoMessage,
435  h),
436  GNUNET_MQ_hd_fixed_size (end_iteration,
438  struct GNUNET_MessageHeader,
439  h),
441  };
442 
443  if (NULL != h->r_task)
444  {
445  GNUNET_SCHEDULER_cancel (h->r_task);
446  h->r_task = NULL;
447  }
448  if (NULL != h->mq)
449  {
451  h->mq = NULL;
452  }
454  "peerinfo",
455  handlers,
457  h);
458  if (NULL != h->ic_head)
459  send_ic_request (h);
460 }
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static struct GNUNET_CADET_MessageHandler handlers[]
Handlers, for diverse services.
#define info
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:1057
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_MQ_hd_var_size(name, code, str, ctx)
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:683
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END
End of information about other peers.
#define GNUNET_MESSAGE_TYPE_PEERINFO_INFO
Information about one of the peers.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
static void send_ic_request(struct GNUNET_PEERINFO_Handle *h)
Send the next IC request at the head of the queue.
Definition: peerinfo_api.c:344
static void mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
We got a disconnect after asking regex to do the announcement.
Definition: peerinfo_api.c:226
struct GNUNET_MQ_Handle * mq
Our connection to the ARM service.
Definition: arm_api.c:107
const struct GNUNET_CONFIGURATION_Handle * cfg
The configuration that we are using.
Definition: arm_api.c:112
Message handler for a specific message type.
Header for all communications.
Message used to inform the client about a particular peer; this message is optionally followed by a H...
Definition: peerinfo.h:102

References GNUNET_ARM_Handle::cfg, GNUNET_CLIENT_connect(), GNUNET_MESSAGE_TYPE_PEERINFO_INFO, GNUNET_MESSAGE_TYPE_PEERINFO_INFO_END, GNUNET_MQ_destroy(), GNUNET_MQ_handler_end, GNUNET_MQ_hd_fixed_size, GNUNET_MQ_hd_var_size, GNUNET_SCHEDULER_cancel(), h, handlers, info, GNUNET_ARM_Handle::mq, mq_error_handler(), and send_ic_request().

Referenced by GNUNET_PEERINFO_connect(), handle_end_iteration(), and reconnect_task().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reconnect_task()

static void reconnect_task ( void *  cls)
static

Task scheduled to re-try connecting to the peerinfo service.

Parameters
clsthe struct GNUNET_PEERINFO_Handle *

Definition at line 180 of file peerinfo_api.c.

181 {
182  struct GNUNET_PEERINFO_Handle *h = cls;
183 
184  h->r_task = NULL;
185  reconnect (h);
186 }
static void reconnect(struct GNUNET_PEERINFO_Handle *h)
Close the existing connection to PEERINFO and reconnect.
Definition: peerinfo_api.c:429
Handle to the peerinfo service.
Definition: peerinfo_api.c:85

References h, and reconnect().

Referenced by do_reconnect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ do_reconnect()

static void do_reconnect ( struct GNUNET_PEERINFO_Handle h)
static

We encountered an error, reconnect to the PEERINFO service.

Parameters
hhandle to reconnect

Definition at line 195 of file peerinfo_api.c.

196 {
197  struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
198 
200  h->mq = NULL;
201  if (NULL != ic)
202  {
203  GNUNET_CONTAINER_DLL_remove (h->ic_head,
204  h->ic_tail,
205  ic);
206  if (NULL != ic->callback)
207  ic->callback (ic->callback_cls,
208  NULL,
209  NULL,
210  _ ("Failed to receive response from `PEERINFO' service."));
211  GNUNET_free (ic);
212  }
214  h);
215 }
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_now(GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run as soon as possible.
Definition: scheduler.c:1299
static void reconnect_task(void *cls)
Task scheduled to re-try connecting to the peerinfo service.
Definition: peerinfo_api.c:180
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Context for an iteration request.
Definition: peerinfo_api.c:38
void * callback_cls
Closure for callback.
Definition: peerinfo_api.c:62
GNUNET_PEERINFO_Processor callback
Function to call with the results.
Definition: peerinfo_api.c:57

References _, GNUNET_PEERINFO_IteratorContext::callback, GNUNET_PEERINFO_IteratorContext::callback_cls, GNUNET_CONTAINER_DLL_remove, GNUNET_free, GNUNET_MQ_destroy(), GNUNET_SCHEDULER_add_now(), h, GNUNET_ARM_Handle::mq, and reconnect_task().

Referenced by mq_error_handler().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mq_error_handler()

static void mq_error_handler ( void *  cls,
enum GNUNET_MQ_Error  error 
)
static

We got a disconnect after asking regex to do the announcement.

Retry.

Parameters
clsthe struct GNUNET_PEERINFO_Handle to retry
errorerror code

Definition at line 226 of file peerinfo_api.c.

228 {
229  struct GNUNET_PEERINFO_Handle *h = cls;
230 
231  do_reconnect (h);
232 }
static void do_reconnect(struct GNUNET_PEERINFO_Handle *h)
We encountered an error, reconnect to the PEERINFO service.
Definition: peerinfo_api.c:195

References do_reconnect(), and h.

Referenced by reconnect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_info()

static int check_info ( void *  cls,
const struct InfoMessage im 
)
static

Function called when we receive an info message.

Check it is well-formed.

Parameters
clsclosure
immessage received
Returns
GNUNET_OK if the message is OK

Definition at line 244 of file peerinfo_api.c.

246 {
247  struct GNUNET_PEERINFO_Handle *h = cls;
248  struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
249  uint16_t ms = ntohs (im->header.size) - sizeof(*im);
250 
251  if (0 != ntohl (im->reserved))
252  {
253  GNUNET_break (0);
254  return GNUNET_SYSERR;
255  }
256  if (NULL == ic)
257  {
258  /* didn't expect a response, bad */
259  GNUNET_break (0);
260  return GNUNET_SYSERR;
261  }
262  if ((GNUNET_YES == ic->have_peer) &&
263  (0 != GNUNET_memcmp (&ic->peer,
264  &im->peer)))
265  {
266  /* bogus message (from a different iteration call?); out of sequence! */
268  "Received HELLO for peer `%s', expected peer `%s'\n",
269  GNUNET_i2s (&im->peer),
270  GNUNET_i2s (&ic->peer));
271  GNUNET_break (0);
272  return GNUNET_SYSERR;
273  }
274  if (ms > sizeof(struct GNUNET_MessageHeader))
275  {
276  const struct GNUNET_HELLO_Message *hello;
277  struct GNUNET_PeerIdentity id;
278 
279  hello = (const struct GNUNET_HELLO_Message *) &im[1];
280  if (ms != GNUNET_HELLO_size (hello))
281  {
282  /* malformed message */
283  GNUNET_break (0);
284  return GNUNET_SYSERR;
285  }
286  if (GNUNET_OK !=
287  GNUNET_HELLO_get_id (hello,
288  &id))
289  {
290  /* malformed message */
291  GNUNET_break (0);
292  return GNUNET_SYSERR;
293  }
294  if (0 != GNUNET_memcmp (&im->peer,
295  &id))
296  {
297  /* malformed message */
298  GNUNET_break (0);
299  return GNUNET_SYSERR;
300  }
301  }
302  else if (0 != ms)
303  {
304  /* malformed message */
305  GNUNET_break (0);
306  return GNUNET_SYSERR;
307  }
308  return GNUNET_OK;
309 }
static struct GNUNET_IDENTITY_Handle * id
Handle to identity service.
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:649
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:630
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_SYSERR
const char * GNUNET_i2s(const struct GNUNET_PeerIdentity *pid)
Convert a peer identity to a string (for printing debug messages).
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
#define LOG(kind,...)
Definition: peerinfo_api.c:31
A HELLO message is used to exchange information about transports with other peers.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_PeerIdentity peer
Peer we are interested in (only valid if iteration was restricted to one peer).
Definition: peerinfo_api.c:67
The identity of the host (wraps the signing key of the peer).
uint32_t reserved
Always zero.
Definition: peerinfo.h:111
struct GNUNET_PeerIdentity peer
About which peer are we talking here?
Definition: peerinfo.h:116
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_PEERINFO_INFO.
Definition: peerinfo.h:106

References GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_HELLO_get_id(), GNUNET_HELLO_size(), GNUNET_i2s(), GNUNET_memcmp, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, h, GNUNET_PEERINFO_IteratorContext::have_peer, InfoMessage::header, id, LOG, InfoMessage::peer, GNUNET_PEERINFO_IteratorContext::peer, InfoMessage::reserved, and GNUNET_MessageHeader::size.

Here is the call graph for this function:

◆ handle_info()

static void handle_info ( void *  cls,
const struct InfoMessage im 
)
static

Handle info message.

Parameters
clsclosure
immessage received

Definition at line 319 of file peerinfo_api.c.

321 {
322  struct GNUNET_PEERINFO_Handle *h = cls;
323  struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
324  const struct GNUNET_HELLO_Message *hello = NULL;
325  uint16_t ms;
326 
327  ms = ntohs (im->header.size);
328  if (ms > sizeof(struct InfoMessage))
329  hello = (const struct GNUNET_HELLO_Message *) &im[1];
330  if (NULL != ic->callback)
331  ic->callback (ic->callback_cls,
332  &im->peer,
333  hello,
334  NULL);
335 }

References GNUNET_PEERINFO_IteratorContext::callback, GNUNET_PEERINFO_IteratorContext::callback_cls, h, InfoMessage::header, InfoMessage::peer, and GNUNET_MessageHeader::size.

◆ send_ic_request()

static void send_ic_request ( struct GNUNET_PEERINFO_Handle h)
static

Send the next IC request at the head of the queue.

Parameters
hhandle

Definition at line 344 of file peerinfo_api.c.

345 {
346  struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
347  struct GNUNET_MQ_Envelope *env;
348  struct ListAllPeersMessage *lapm;
349  struct ListPeerMessage *lpm;
350 
351  if (NULL == ic)
352  {
353  GNUNET_break (0);
354  return;
355  }
356  if (NULL == h->mq)
357  {
358  GNUNET_break (0);
359  return;
360  }
361  if (GNUNET_NO == ic->have_peer)
362  {
364  "Requesting list of peers from PEERINFO service\n");
365  env = GNUNET_MQ_msg (lapm,
367  lapm->include_friend_only = htonl (ic->include_friend_only);
368  }
369  else
370  {
372  "Requesting information on peer `%s' from PEERINFO service\n",
373  GNUNET_i2s (&ic->peer));
374  env = GNUNET_MQ_msg (lpm,
376  lpm->include_friend_only = htonl (ic->include_friend_only);
377  lpm->peer = ic->peer;
378  }
379  GNUNET_MQ_send (h->mq,
380  env);
381 }
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
@ GNUNET_NO
@ GNUNET_ERROR_TYPE_DEBUG
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:304
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:77
#define GNUNET_MESSAGE_TYPE_PEERINFO_GET
Request update and listing of a peer.
#define GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL
Request update and listing of all peers.
int include_friend_only
Only include friends in reply?
Definition: peerinfo_api.c:77
Message requesting a listing of all peers, restricted to the specified peer identity.
Definition: peerinfo.h:64
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:73
Message requesting a listing of peers, restricted to the specified peer identity.
Definition: peerinfo.h:41
struct GNUNET_PeerIdentity peer
Restrict to peers with this identity (optional field, check header.size!).
Definition: peerinfo.h:56
uint32_t include_friend_only
Include friend only HELLOs and peers in callbacks.
Definition: peerinfo.h:50

References env, GNUNET_break, GNUNET_ERROR_TYPE_DEBUG, GNUNET_i2s(), GNUNET_MESSAGE_TYPE_PEERINFO_GET, GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL, GNUNET_MQ_msg, GNUNET_MQ_send(), GNUNET_NO, h, GNUNET_PEERINFO_IteratorContext::have_peer, ListPeerMessage::include_friend_only, ListAllPeersMessage::include_friend_only, GNUNET_PEERINFO_IteratorContext::include_friend_only, LOG, GNUNET_ARM_Handle::mq, ListPeerMessage::peer, and GNUNET_PEERINFO_IteratorContext::peer.

Referenced by GNUNET_PEERINFO_iterate(), handle_end_iteration(), and reconnect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_end_iteration()

static void handle_end_iteration ( void *  cls,
const struct GNUNET_MessageHeader msg 
)
static

Type of a function to call when we receive a message from the service.

Call the iterator with the result and (if applicable) continue to receive more messages or trigger processing the next event (if applicable).

Parameters
clsclosure
msgmessage received, NULL on timeout or fatal error

Definition at line 394 of file peerinfo_api.c.

396 {
397  struct GNUNET_PEERINFO_Handle *h = cls;
398  struct GNUNET_PEERINFO_IteratorContext *ic = h->ic_head;
399 
400  if (NULL == ic)
401  {
402  /* didn't expect a response, reconnect */
403  GNUNET_break (0);
404  reconnect (h);
405  return;
406  }
408  "Received end of list of peers from PEERINFO service\n");
409  GNUNET_CONTAINER_DLL_remove (h->ic_head,
410  h->ic_tail,
411  ic);
412  if (NULL != h->ic_head)
413  send_ic_request (h);
414  if (NULL != ic->callback)
415  ic->callback (ic->callback_cls,
416  NULL,
417  NULL,
418  NULL);
419  GNUNET_free (ic);
420 }

References GNUNET_PEERINFO_IteratorContext::callback, GNUNET_PEERINFO_IteratorContext::callback_cls, GNUNET_break, GNUNET_CONTAINER_DLL_remove, GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, h, LOG, reconnect(), and send_ic_request().

Here is the call graph for this function: