GNUnet  0.19.4
hello.c File Reference

helper library for handling HELLOs More...

#include "platform.h"
#include "gnunet_hello_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_util_lib.h"
#include "gnunet_transport_plugin.h"
Include dependency graph for hello.c:

Go to the source code of this file.

Data Structures

struct  GNUNET_HELLO_ComposeUriContext
 Context used for building our own URI. More...
 
struct  GNUNET_HELLO_ParseUriContext
 Context for add_address_to_hello(). More...
 
struct  ExpireContext
 Closure for get_match_exp(). More...
 
struct  MergeContext
 Closure for merge_pr(). More...
 
struct  DeltaContext
 Context used in GNUNET_HELLO_iterate_new_addresses() to figure out which addresses are in fact 'new'. More...
 
struct  EqualsContext
 Context used for comparing HELLOs in GNUNET_HELLO_equals(). More...
 

Functions

int GNUNET_HELLO_is_friend_only (const struct GNUNET_HELLO_Message *h)
 Return HELLO type. More...
 
size_t GNUNET_HELLO_add_address (const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration, char *target, size_t max)
 Copy the given address information into the given buffer using the format of HELLOs. More...
 
static size_t get_hello_address_size (const char *buf, size_t max, uint16_t *ralen)
 Get the size of an address entry in a HELLO message. More...
 
struct GNUNET_HELLO_MessageGNUNET_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 transport addresses. More...
 
struct GNUNET_HELLO_MessageGNUNET_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. More...
 
static int get_match_exp (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Store the expiration time of an address that matches the template. More...
 
static int copy_latest (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Append the address address to the buffer from the merge context IF it is more recent than equivalent addresses in other. More...
 
static ssize_t merge_addr (void *cls, size_t max, void *buf)
 Function called to build the HELLO during GNUNET_HELLO_merge() by merging addresses from two original HELLOs. More...
 
struct GNUNET_HELLO_MessageGNUNET_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 peer). More...
 
static int delta_match (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Check if the given address is 'new', and if so, call the iterator. More...
 
void GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message *new_hello, const struct GNUNET_HELLO_Message *old_hello, struct GNUNET_TIME_Absolute expiration_limit, GNUNET_HELLO_AddressIterator it, void *it_cls)
 Iterate over addresses in new_hello that are NOT already present in old_hello. More...
 
uint16_t GNUNET_HELLO_size (const struct GNUNET_HELLO_Message *hello)
 Return the size of the given HELLO message. More...
 
int GNUNET_HELLO_get_id (const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
 Get the peer identity from a HELLO message. More...
 
struct GNUNET_MessageHeaderGNUNET_HELLO_get_header (struct GNUNET_HELLO_Message *hello)
 Get the header from a HELLO message, used so other code can correctly send HELLO messages. More...
 
static int find_other_matching (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Check if the given address matches the address we are currently looking for. More...
 
static int find_matching (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Helper function for GNUNET_HELLO_equals(). More...
 
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. More...
 
static int find_max_expire (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 Iterator to find the time when the last address will expire. More...
 
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
 When does the last address in the given HELLO expire? More...
 
static int add_address_to_uri (void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
 GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER". More...
 
char * GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello, GNUNET_HELLO_TransportPluginsFind plugins_find)
 Compose a hello URI string from a hello message. More...
 
static ssize_t add_address_to_hello (void *cls, size_t max, void *buffer)
 We're building a HELLO. More...
 
int GNUNET_HELLO_parse_uri (const char *uri, struct GNUNET_CRYPTO_EddsaPublicKey *pubkey, struct GNUNET_HELLO_Message **hello, GNUNET_HELLO_TransportPluginsFind plugins_find)
 Parse a hello URI string to a hello message. More...
 

Detailed Description

helper library for handling HELLOs

Author
Christian Grothoff
Matthias Wachs

Definition in file hello.c.

Function Documentation

◆ get_hello_address_size()

static size_t get_hello_address_size ( const char *  buf,
size_t  max,
uint16_t *  ralen 
)
static

Get the size of an address entry in a HELLO message.

Parameters
bufpointer to the start of the address entry
maxmaximum size of the entry (end of buf)
ralenset to the address length
Returns
size of the entry, or 0 if max is not large enough

Definition at line 144 of file hello.c.

147 {
148  const char *pos;
149  uint16_t alen;
150  size_t left;
151  size_t slen;
152 
153  left = max;
154  pos = buf;
155  slen = 1;
156  while ((left > 0) && ('\0' != *pos))
157  {
158  left--;
159  pos++;
160  slen++;
161  }
162  if (0 == left)
163  {
164  /* 0-termination not found */
165  GNUNET_break_op (0);
166  return 0;
167  }
168  pos++;
169  if (left < sizeof(uint16_t) + sizeof(struct GNUNET_TIME_AbsoluteNBO))
170  {
171  /* not enough space for addrlen */
172  GNUNET_break_op (0);
173  return 0;
174  }
175  GNUNET_memcpy (&alen, pos, sizeof(uint16_t));
176  alen = ntohs (alen);
177  *ralen = alen;
178  slen += alen + sizeof(uint16_t) + sizeof(struct GNUNET_TIME_AbsoluteNBO);
179  if (max < slen)
180  {
181  /* not enough space for addr */
182  GNUNET_break_op (0);
183  return 0;
184  }
185  return slen;
186 }
static char buf[2048]
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define max(x, y)
Time for absolute time used by GNUnet, in microseconds and in network byte order.

References buf, GNUNET_break_op, GNUNET_memcpy, and max.

Referenced by GNUNET_HELLO_iterate_addresses().

Here is the caller graph for this function:

◆ get_match_exp()

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

Store the expiration time of an address that matches the template.

Parameters
clsthe struct ExpireContext
addressaddress to match against the template
expirationexpiration time of address, to store in cls
Returns
GNUNET_SYSERR if we found a matching address, GNUNET_OK otherwise

Definition at line 370 of file hello.c.

373 {
374  struct ExpireContext *ec = cls;
375 
377  ec->address))
378  return GNUNET_OK;
379  ec->found = GNUNET_YES;
380  ec->expiration = expiration;
381  return GNUNET_SYSERR; /* done here */
382 }
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static char * address
GNS address for this phone.
int GNUNET_HELLO_address_cmp(const struct GNUNET_HELLO_Address *a1, const struct GNUNET_HELLO_Address *a2)
Compare two addresses.
Definition: address.c:112
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_SYSERR
Closure for get_match_exp().
Definition: hello.c:343
const struct GNUNET_HELLO_Address * address
Address we are looking for.
Definition: hello.c:347
struct GNUNET_TIME_Absolute expiration
Set to the expiration of the match if found is GNUNET_YES.
Definition: hello.c:357
int found
Set to GNUNET_YES if we found the address.
Definition: hello.c:352

References address, ExpireContext::address, expiration, ExpireContext::expiration, ExpireContext::found, GNUNET_HELLO_address_cmp(), GNUNET_OK, GNUNET_SYSERR, and GNUNET_YES.

Referenced by copy_latest(), and delta_match().

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

◆ copy_latest()

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

Append the address address to the buffer from the merge context IF it is more recent than equivalent addresses in other.

Parameters
clsthe struct MergeContext
addressthe HELLO address we might copy
expirationexpiration time for address
Returns
always GNUNET_OK

Definition at line 442 of file hello.c.

445 {
446  struct MergeContext *mc = cls;
447  struct ExpireContext ec;
448 
449  ec.address = address;
450  ec.found = GNUNET_NO;
451  /* check if address exists in other */
453  GNUNET_NO,
454  &get_match_exp,
455  &ec);
456  if ((GNUNET_NO == ec.found) ||
457  (ec.expiration.abs_value_us < expiration.abs_value_us) ||
458  ((ec.expiration.abs_value_us == expiration.abs_value_us) &&
459  (GNUNET_YES == mc->take_equal)))
460  {
461  /* copy address to buffer */
462  mc->ret +=
464  expiration,
465  &mc->buf[mc->ret],
466  mc->max - mc->ret);
467  }
468  return GNUNET_OK;
469 }
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
size_t GNUNET_HELLO_add_address(const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration, char *target, size_t max)
Copy the given address information into the given buffer using the format of HELLOs.
Definition: hello.c:109
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
@ GNUNET_NO
static int get_match_exp(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Store the expiration time of an address that matches the template.
Definition: hello.c:370
Closure for merge_pr().

References GNUNET_TIME_Absolute::abs_value_us, address, ExpireContext::address, expiration, ExpireContext::expiration, ExpireContext::found, get_match_exp(), GNUNET_HELLO_add_address(), GNUNET_HELLO_iterate_addresses(), GNUNET_NO, GNUNET_OK, GNUNET_YES, and mc.

Referenced by merge_addr().

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

◆ merge_addr()

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

Function called to build the HELLO during GNUNET_HELLO_merge() by merging addresses from two original HELLOs.

Parameters
clsthe struct MergeContext
maxnumber of bytes we can write at most in buf
bufwhere to copy the addresses
Returns
GNUNET_SYSERR to end iteration, otherwise number of bytes written to buf

Definition at line 483 of file hello.c.

486 {
487  struct MergeContext *mc = cls;
488 
489  if (NULL == mc->h1)
490  return GNUNET_SYSERR; /* Stop iteration */
491  mc->ret = 0;
492  mc->max = max;
493  mc->buf = buf;
494  mc->take_equal = GNUNET_NO;
495  mc->other = mc->h2;
496  /* copy addresses from h1, if strictly larger expiration than h2 */
498  GNUNET_NO,
499  &copy_latest,
500  mc);
501  mc->take_equal = GNUNET_YES;
502  mc->other = mc->h1;
503  /* copy addresses from h2, if larger or equal expiration than h1 */
505  GNUNET_NO,
506  &copy_latest,
507  mc);
508  /* set marker to stop iteration */
509  mc->h1 = NULL;
510  return mc->ret;
511 }
static int copy_latest(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Append the address address to the buffer from the merge context IF it is more recent than equivalent ...
Definition: hello.c:442

References buf, copy_latest(), GNUNET_HELLO_iterate_addresses(), GNUNET_NO, GNUNET_SYSERR, GNUNET_YES, max, and mc.

Referenced by GNUNET_HELLO_merge().

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

◆ delta_match()

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

Check if the given address is 'new', and if so, call the iterator.

Compares the existing address against addresses in the context's old_hello and calls the iterator on those that are new (and not expired).

Parameters
clsthe struct DeltaContext
addressan address to check whether it is new
expirationexpiration time for address
Returns
GNUNET_YES if the address is ignored, otherwise whatever the iterator returned.

Definition at line 575 of file hello.c.

578 {
579  struct DeltaContext *dc = cls;
580  int ret;
581  struct ExpireContext ec;
582 
583  ec.address = address;
584  ec.found = GNUNET_NO;
586  GNUNET_NO,
587  &get_match_exp,
588  &ec);
589  if ((GNUNET_YES == ec.found) &&
590  ((ec.expiration.abs_value_us > expiration.abs_value_us) ||
591  (ec.expiration.abs_value_us >= dc->expiration_limit.abs_value_us)))
592  return GNUNET_YES; /* skip: found and boring */
593  ret = dc->it (dc->it_cls,
594  address,
595  expiration);
596  return ret;
597 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_FS_DownloadContext * dc
Context used in GNUNET_HELLO_iterate_new_addresses() to figure out which addresses are in fact 'new'.
Definition: hello.c:538

References GNUNET_TIME_Absolute::abs_value_us, address, ExpireContext::address, dc, expiration, ExpireContext::expiration, ExpireContext::found, get_match_exp(), GNUNET_HELLO_iterate_addresses(), GNUNET_NO, GNUNET_YES, and ret.

Referenced by GNUNET_HELLO_iterate_new_addresses().

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

◆ find_other_matching()

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

Check if the given address matches the address we are currently looking for.

If so, sets found to GNUNET_YES and, if the expiration times for the two addresses differ, updates result to the minimum of our expiration and the existing value

Parameters
clsthe struct EqualsContext
addressaddress from the reference HELLO
expirationexpiration time for address
Returns
GNUNET_YES if the address is expired or does not match GNUNET_SYSERR if the address does match.

Definition at line 737 of file hello.c.

740 {
741  struct EqualsContext *ec = cls;
742 
743  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
744  return GNUNET_YES;
745  if (0 == GNUNET_HELLO_address_cmp (address, ec->address))
746  {
747  ec->found = GNUNET_YES;
748  if (expiration.abs_value_us < ec->expiration.abs_value_us)
750  ec->result);
751  return GNUNET_SYSERR;
752  }
753  return GNUNET_YES;
754 }
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_min(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the minimum of two absolute time values.
Definition: time.c:359
Context used for comparing HELLOs in GNUNET_HELLO_equals().
Definition: hello.c:687
struct GNUNET_TIME_Absolute expiration
Expiration time of address.
Definition: hello.c:715
struct GNUNET_TIME_Absolute result
Earliest expiration time for which we found a match with a difference in expiration times.
Definition: hello.c:699
struct GNUNET_TIME_Absolute expiration_limit
Addresses that expired before this date are ignored for the comparison.
Definition: hello.c:692
int found
Did we find the address we were looking for?
Definition: hello.c:720
const struct GNUNET_HELLO_Address * address
Address we are currently looking for.
Definition: hello.c:710
uint64_t abs_value_us
The actual value.

References GNUNET_TIME_Absolute::abs_value_us, address, EqualsContext::address, expiration, EqualsContext::expiration, EqualsContext::expiration_limit, EqualsContext::found, GNUNET_HELLO_address_cmp(), GNUNET_SYSERR, GNUNET_TIME_absolute_min(), GNUNET_YES, and EqualsContext::result.

Referenced by find_matching().

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

◆ find_matching()

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

Helper function for GNUNET_HELLO_equals().

Checks if the given address exists also in the other HELLO; if not, the result time is set to zero and the iteration is aborted.

Parameters
clsthe struct EqualsContext
addressaddress to locate
expirationexpiration time of the current address
Returns
GNUNET_OK if the address exists or is expired, GNUNET_SYSERR if it was not found

Definition at line 770 of file hello.c.

773 {
774  struct EqualsContext *ec = cls;
775 
776  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
777  return GNUNET_OK; /* expired, we don't care */
778  ec->address = address;
779  ec->expiration = expiration;
780  ec->found = GNUNET_NO;
782  GNUNET_NO,
784  ec);
785  if (GNUNET_NO == ec->found)
786  {
787  /* not found, we differ *now* */
789  return GNUNET_SYSERR;
790  }
791  return GNUNET_OK;
792 }
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
static int find_other_matching(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Check if the given address matches the address we are currently looking for.
Definition: hello.c:737
const struct GNUNET_HELLO_Message * ref
HELLO message to compare against.
Definition: hello.c:705

References GNUNET_TIME_Absolute::abs_value_us, address, EqualsContext::address, expiration, EqualsContext::expiration, EqualsContext::expiration_limit, find_other_matching(), EqualsContext::found, GNUNET_HELLO_iterate_addresses(), GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_UNIT_ZERO_ABS, EqualsContext::ref, and EqualsContext::result.

Here is the call graph for this function:

◆ find_max_expire()

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

Iterator to find the time when the last address will expire.

Updates the maximum value stored in cls.

Parameters
clswhere to store the max, a struct GNUNET_TIME_Absolute
addressan address (ignored)
expirationexpiration time for address
Returns
GNUNET_OK (always)

Definition at line 852 of file hello.c.

855 {
856  struct GNUNET_TIME_Absolute *max = cls;
857 
859  return GNUNET_OK;
860 }
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_max(struct GNUNET_TIME_Absolute t1, struct GNUNET_TIME_Absolute t2)
Return the maximum of two absolute time values.
Definition: time.c:367
Time for absolute times used by GNUnet, in microseconds.

References expiration, GNUNET_OK, GNUNET_TIME_absolute_max(), and max.

Here is the call graph for this function:

◆ add_address_to_uri()

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

GNUnet URIs are of the general form "gnunet://MODULE/IDENTIFIER".

The specific structure of "IDENTIFIER" depends on the module and maybe differentiated into additional subcategories if applicable. This module only deals with hello identifiers (MODULE = "hello").

The concrete URI format is:

"gnunet://hello/PEER[+YYYYMMDDHHMMSS+<TYPE>+<ADDRESS>]...". These URIs can be used to add a peer record to peerinfo service. PEER is the string representation of peer's public key. YYYYMMDDHHMMSS is the expiration date. TYPE is a transport type. ADDRESS is the address, its format depends upon the transport type. The concrete transport types and corresponding address formats are:

  • <TCP|UDP>!IPADDRESS IPVDDRESS is either IPV4 .-delimited address in form of XXX.XXX.XXX.XXX:PPPPP or IPV6 :-delimited address with '[' and ']' (according to RFC2732):

    PPPPP is the port number. May be 0.

  • [add SMTP, HTTP and other addresses here]

The encoding for hexadecimal values is defined in the crypto_hash.c module in the gnunetutil library and discussed there.

Examples:

gnunet://hello/V8XXK9GAN5ZJFRFQP8MQX3D83BZTSBQVHKWWD0JPE63Z821906EG+20120302010059+TCP+192.168.0.1:2086+TCP+64.23.8.174:0 gnunet://hello/V8XXK9GAN5ZJFRFQP8MQX3D83BZTSBQVHKWWD0JPE63Z821906EG+20120302010059+TCP+[2001:db8:85a3:8d3:1319:8a2e:370:7348]:2086

Function that is called on each address of this peer. Expands the corresponding URI string.

Parameters
clsthe struct GNUNET_HELLO_ComposeUriContext
addressaddress to add
expirationexpiration time for the address
Returns
GNUNET_OK (continue iteration).

Definition at line 936 of file hello.c.

939 {
940  struct GNUNET_HELLO_ComposeUriContext *ctx = cls;
942  const char *addr;
943  char *ret;
944  char *addr_dup;
945  char *pos;
946  char tbuf[16] = "";
947  char *client_str = "_client";
948  struct tm *t;
949  time_t seconds;
950 
951  papi = ctx->plugins_find (address->transport_name);
952  if (NULL == papi)
953  {
954  /* Not an error - we might just not have the right plugin. */
955  return GNUNET_OK;
956  }
957  if (NULL == papi->address_to_string)
958  {
960  "URI conversion not implemented for plugin `%s'\n",
961  address->transport_name);
962  return GNUNET_OK;
963  }
964  addr = papi->address_to_string (papi->cls,
965  address->address,
966  address->address_length);
967  if ((NULL == addr) ||
968  (0 == strlen (addr)))
969  return GNUNET_OK;
970 
971  addr_dup = GNUNET_strdup (addr);
972  if (NULL != (pos = strstr (addr_dup, "_server")))
973  GNUNET_memcpy (pos,
974  client_str,
975  strlen (client_str)); /* Replace all server addresses with client addresses */
976 
977  seconds = expiration.abs_value_us / 1000LL / 1000LL;
978  t = gmtime (&seconds);
979 
981  "%s%c%s%c%s%c%s",
982  ctx->uri,
984  strftime (tbuf,
985  sizeof(tbuf),
986  "%Y%m%d%H%M%S",
987  t) ? tbuf : "0",
989  address->transport_name,
991  addr_dup);
992  GNUNET_free (addr_dup);
993  GNUNET_free (ctx->uri);
994  ctx->uri = ret;
995  return GNUNET_OK;
996 }
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_HELLO_URI_SEP
Separator used in HELLO URI.
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_free(ptr)
Wrapper around free.
Context used for building our own URI.
Definition: hello.c:37
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
void * cls
Closure for all of the callbacks.
GNUNET_TRANSPORT_AddressToString address_to_string
Function that will be called to convert a binary address to a string (numeric conversion only).

References address, GNUNET_TRANSPORT_PluginFunctions::address_to_string, GNUNET_TRANSPORT_PluginFunctions::cls, ctx, expiration, GNUNET_asprintf(), GNUNET_ERROR_TYPE_DEBUG, GNUNET_free, GNUNET_HELLO_URI_SEP, GNUNET_log, GNUNET_memcpy, GNUNET_OK, GNUNET_strdup, ret, and t.

Referenced by GNUNET_HELLO_compose_uri().

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

◆ add_address_to_hello()

static ssize_t add_address_to_hello ( void *  cls,
size_t  max,
void *  buffer 
)
static

We're building a HELLO.

Parse the next address from the parsing context and append it.

Parameters
clsthe struct GNUNET_HELLO_ParseUriContext
maxnumber of bytes available for HELLO construction
bufferwhere to copy the next address (in binary format)
Returns
number of bytes added to buffer, GNUNET_SYSERR on error

Definition at line 1043 of file hello.c.

1046 {
1047  struct GNUNET_HELLO_ParseUriContext *ctx = cls;
1048  const char *tname;
1049  const char *address;
1050  char *uri_address;
1051  const char *end;
1052  char *plugin_name;
1053  struct tm expiration_time;
1054  time_t expiration_seconds;
1056  struct GNUNET_TRANSPORT_PluginFunctions *papi;
1057  void *addr;
1058  size_t addr_len;
1059  struct GNUNET_HELLO_Address haddr;
1060  ssize_t ret;
1061 
1062  if (NULL == ctx->pos)
1063  return GNUNET_SYSERR;
1064  if (GNUNET_HELLO_URI_SEP != ctx->pos[0])
1065  {
1066  ctx->ret = GNUNET_SYSERR;
1067  GNUNET_break (0);
1068  return GNUNET_SYSERR;
1069  }
1070  ctx->pos++;
1071 
1072  if (('0' == ctx->pos[0]) &&
1073  (GNUNET_HELLO_URI_SEP == ctx->pos[1]))
1074  {
1076  tname = ctx->pos + 1;
1077  }
1078  else
1079  {
1080  memset (&expiration_time, 0, sizeof(expiration_time));
1081  tname = strptime (ctx->pos,
1082  "%Y%m%d%H%M%S",
1083  &expiration_time);
1084  if (NULL == tname)
1085  {
1086  ctx->ret = GNUNET_SYSERR;
1088  _ (
1089  "Failed to parse HELLO message: missing expiration time\n"));
1090  GNUNET_break (0);
1091  return GNUNET_SYSERR;
1092  }
1093 
1094  expiration_seconds = mktime (&expiration_time);
1095  if (expiration_seconds == (time_t) -1)
1096  {
1098  _ (
1099  "Failed to parse HELLO message: invalid expiration time\n"));
1100  ctx->ret = GNUNET_SYSERR;
1101  GNUNET_break (0);
1102  return GNUNET_SYSERR;
1103  }
1104  expire.abs_value_us = expiration_seconds * 1000LL * 1000LL;
1105  }
1106  if (GNUNET_HELLO_URI_SEP != tname[0])
1107  {
1109  _ ("Failed to parse HELLO message: malformed\n"));
1110  ctx->ret = GNUNET_SYSERR;
1111  GNUNET_break (0);
1112  return GNUNET_SYSERR;
1113  }
1114  tname++;
1115  address = strchr (tname,
1116  (int) GNUNET_HELLO_URI_SEP);
1117  if (NULL == address)
1118  {
1120  _ (
1121  "Failed to parse HELLO message: missing transport plugin\n"));
1122  ctx->ret = GNUNET_SYSERR;
1123  GNUNET_break (0);
1124  return GNUNET_SYSERR;
1125  }
1126  address++;
1127  end = strchr (address, (int) GNUNET_HELLO_URI_SEP);
1128  ctx->pos = end;
1129  ctx->counter_total++;
1130  plugin_name = GNUNET_strndup (tname, address - (tname + 1));
1131  papi = ctx->plugins_find (plugin_name);
1132  if (NULL == papi)
1133  {
1134  /* Not an error - we might just not have the right plugin.
1135  * Skip this part, advance to the next one and recurse.
1136  * But only if this is not the end of string.
1137  */
1139  _ ("Plugin `%s' not found, skipping address\n"),
1140  plugin_name);
1142  return 0;
1143  }
1144  if (NULL == papi->string_to_address)
1145  {
1147  _ ("Plugin `%s' does not support URIs yet\n"),
1148  plugin_name);
1150  GNUNET_break (0);
1151  return 0;
1152  }
1153  uri_address = GNUNET_strndup (address, end - address);
1154  if (GNUNET_OK !=
1155  papi->string_to_address (papi->cls,
1156  uri_address,
1157  strlen (uri_address) + 1,
1158  &addr,
1159  &addr_len))
1160  {
1162  _ ("Failed to parse `%s' as an address for plugin `%s'\n"),
1163  uri_address,
1164  plugin_name);
1166  GNUNET_free (uri_address);
1167  return 0;
1168  }
1169  GNUNET_free (uri_address);
1170  /* address.peer is unset - not used by add_address() */
1171  haddr.address_length = addr_len;
1172  haddr.address = addr;
1173  haddr.transport_name = plugin_name;
1174  ret = GNUNET_HELLO_add_address (&haddr,
1175  expire,
1176  buffer,
1177  max);
1178  ctx->counter_added++;
1179  GNUNET_free (addr);
1181  return ret;
1182 }
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static char * expire
DID Document expiration Date Attribut String.
Definition: gnunet-did.c:101
static char * plugin_name
Name of our plugin.
#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
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
An address for communicating with a peer.
Context for add_address_to_hello().
Definition: hello.c:54
GNUNET_TRANSPORT_StringToAddress string_to_address
Function that will be called to convert a string address to binary (numeric conversion only).

References _, address, GNUNET_HELLO_Address::address, GNUNET_HELLO_Address::address_length, GNUNET_TRANSPORT_PluginFunctions::cls, ctx, end, expire, GNUNET_break, GNUNET_ERROR_TYPE_ERROR, GNUNET_ERROR_TYPE_INFO, GNUNET_free, GNUNET_HELLO_add_address(), GNUNET_HELLO_URI_SEP, GNUNET_log, GNUNET_OK, GNUNET_strndup, GNUNET_SYSERR, GNUNET_TIME_UNIT_FOREVER_ABS, max, plugin_name, ret, GNUNET_TRANSPORT_PluginFunctions::string_to_address, and GNUNET_HELLO_Address::transport_name.

Referenced by GNUNET_HELLO_parse_uri().

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