GNUnet  0.19.5
hello.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2009, 2015 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
20 
27 #include "platform.h"
28 #include "gnunet_hello_lib.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_util_lib.h"
32 
37 {
41  char *uri;
42 
47 };
48 
49 
54 {
58  const char *pos;
59 
63  int ret;
64 
68  unsigned int counter_total;
69 
73  unsigned int counter_added;
74 
79 };
80 
81 
88 int
90 {
91  if (GNUNET_YES == ntohl (h->friend_only))
92  return GNUNET_YES;
93  return GNUNET_NO;
94 }
95 
96 
108 size_t
111  char *target,
112  size_t max)
113 {
114  uint16_t alen;
115  size_t slen;
116  struct GNUNET_TIME_AbsoluteNBO exp;
117 
118  slen = strlen (address->transport_name) + 1;
119  if (slen + sizeof(uint16_t) + sizeof(struct GNUNET_TIME_AbsoluteNBO)
120  + address->address_length > max)
121  return 0;
123  alen = htons ((uint16_t) address->address_length);
124  GNUNET_memcpy (target, address->transport_name, slen);
125  GNUNET_memcpy (&target[slen], &alen, sizeof(uint16_t));
126  slen += sizeof(uint16_t);
127  GNUNET_memcpy (&target[slen], &exp, sizeof(struct GNUNET_TIME_AbsoluteNBO));
128  slen += sizeof(struct GNUNET_TIME_AbsoluteNBO);
129  GNUNET_memcpy (&target[slen], address->address, address->address_length);
130  slen += address->address_length;
131  return slen;
132 }
133 
134 
143 static size_t
145  size_t max,
146  uint16_t *ralen)
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 }
187 
188 
203 struct GNUNET_HELLO_Message *
206  void *addrgen_cls,
207  int friend_only)
208 {
209  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1 - 256
210  - sizeof(struct GNUNET_HELLO_Message)];
211  size_t max;
212  size_t used;
213  size_t ret;
214  struct GNUNET_HELLO_Message *hello;
215 
216  GNUNET_assert (NULL != public_key);
218  (GNUNET_NO == friend_only));
219  max = sizeof(buffer);
220  used = 0;
221  if (NULL != addrgen)
222  {
223  while (GNUNET_SYSERR != (ret = addrgen (addrgen_cls,
224  max,
225  &buffer[used])))
226  {
227  max -= ret;
228  used += ret;
229  }
230  }
231  hello = GNUNET_malloc (sizeof(struct GNUNET_HELLO_Message) + used);
232  hello->header.type = htons (GNUNET_MESSAGE_TYPE_HELLO);
233  hello->header.size = htons (sizeof(struct GNUNET_HELLO_Message) + used);
234  hello->friend_only = htonl (friend_only);
235  hello->publicKey = *public_key;
236  GNUNET_memcpy (&hello[1],
237  buffer,
238  used);
239  return hello;
240 }
241 
242 
253 struct GNUNET_HELLO_Message *
255  int return_modified,
257  void *it_cls)
258 {
260  uint16_t msize;
261  struct GNUNET_HELLO_Message *ret;
262  const char *inptr;
263  size_t insize;
264  size_t esize;
265  size_t wpos;
266  char *woff;
267  uint16_t alen;
269  int iret;
270 
271  msize = GNUNET_HELLO_size (msg);
272  if ((msize < sizeof(struct GNUNET_HELLO_Message)) ||
273  (ntohs (msg->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
274  {
275  GNUNET_break_op (0);
276  return NULL;
277  }
278  ret = NULL;
279  if (return_modified)
280  {
281  ret = GNUNET_malloc (msize);
283  msg,
284  msize);
285  }
286  inptr = (const char *) &msg[1];
287  insize = msize - sizeof(struct GNUNET_HELLO_Message);
288  wpos = 0;
289  woff = (NULL != ret) ? (char *) &ret[1] : NULL;
290  address.peer.public_key = msg->publicKey;
292  "HELLO has %u bytes of address data\n",
293  (unsigned int) insize);
294 
295  while (insize > 0)
296  {
297  esize = get_hello_address_size (inptr,
298  insize,
299  &alen);
300  if (0 == esize)
301  {
302  GNUNET_break (0);
303  GNUNET_free (ret);
304  return NULL;
305  }
306  /* need GNUNET_memcpy() due to possibility of misalignment */
308  &inptr[esize - alen - sizeof(struct
310  sizeof(struct GNUNET_TIME_AbsoluteNBO));
311  address.address = &inptr[esize - alen];
312  address.address_length = alen;
313  address.transport_name = inptr;
315  iret = it (it_cls,
316  &address,
318  if (GNUNET_SYSERR == iret)
319  break;
320  if ((GNUNET_OK == iret) &&
321  (NULL != ret))
322  {
323  /* copy address over */
324  GNUNET_memcpy (woff,
325  inptr,
326  esize);
327  woff += esize;
328  wpos += esize;
329  }
330  insize -= esize;
331  inptr += esize;
332  }
333  if (NULL != ret)
334  ret->header.size = ntohs (sizeof(struct GNUNET_HELLO_Message) + wpos);
335  return ret;
336 }
337 
338 
343 {
348 
352  int found;
353 
358 };
359 
360 
369 static int
370 get_match_exp (void *cls,
371  const struct GNUNET_HELLO_Address *address,
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 }
383 
384 
388 struct MergeContext
389 {
393  const struct GNUNET_HELLO_Message *h1;
394 
398  const struct GNUNET_HELLO_Message *h2;
399 
406 
410  char *buf;
411 
415  size_t max;
416 
420  size_t ret;
421 
428 };
429 
430 
441 static int
442 copy_latest (void *cls,
443  const struct GNUNET_HELLO_Address *address,
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 }
470 
471 
482 static ssize_t
483 merge_addr (void *cls,
484  size_t max,
485  void *buf)
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 }
512 
513 
514 struct GNUNET_HELLO_Message *
516  const struct GNUNET_HELLO_Message *h2)
517 {
518  struct MergeContext mc = { h1, h2, NULL, NULL, 0, 0, 0 };
519  int friend_only;
520 
521  if (h1->friend_only != h2->friend_only)
522  friend_only = GNUNET_YES; /* One of the HELLOs is friend only */
523  else
524  friend_only = ntohl (h1->friend_only); /* Both HELLO's have the same type */
525 
526  return GNUNET_HELLO_create (&h1->publicKey,
527  &merge_addr,
528  &mc,
529  friend_only);
530 }
531 
532 
538 {
543 
548 
552  void *it_cls;
553 
559 };
560 
561 
574 static int
575 delta_match (void *cls,
576  const struct GNUNET_HELLO_Address *address,
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 }
598 
599 
600 void
602  GNUNET_HELLO_Message *new_hello,
603  const struct
604  GNUNET_HELLO_Message *old_hello,
605  struct GNUNET_TIME_Absolute
606  expiration_limit,
608  void *it_cls)
609 {
610  struct DeltaContext dc;
611 
612  dc.expiration_limit = expiration_limit;
613  dc.it = it;
614  dc.it_cls = it_cls;
615  dc.old_hello = old_hello;
616  GNUNET_assert (NULL ==
618  GNUNET_NO,
619  &delta_match,
620  &dc));
621 }
622 
623 
629 uint16_t
631 {
632  uint16_t ret = ntohs (hello->header.size);
633 
634  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
635  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
636  return 0;
637  return ret;
638 }
639 
640 
648 int
650  struct GNUNET_PeerIdentity *peer)
651 {
652  uint16_t ret = ntohs (hello->header.size);
653 
654  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
655  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
656  return GNUNET_SYSERR;
657  peer->public_key = hello->publicKey;
658  return GNUNET_OK;
659 }
660 
661 
670 struct GNUNET_MessageHeader *
672 {
673  uint16_t ret = ntohs (hello->header.size);
674 
675  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
676  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
677  return NULL;
678 
679  return &hello->header;
680 }
681 
682 
687 {
693 
700 
705  const struct GNUNET_HELLO_Message *ref;
706 
711 
716 
720  int found;
721 };
722 
723 
736 static int
738  const struct GNUNET_HELLO_Address *address,
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 }
755 
756 
769 static int
770 find_matching (void *cls,
771  const struct GNUNET_HELLO_Address *address,
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 }
793 
794 
812 GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1,
813  const struct GNUNET_HELLO_Message *h2,
814  struct GNUNET_TIME_Absolute now)
815 {
816  struct EqualsContext ec;
817 
818  if (h1->header.type != h2->header.type)
820  if (0 !=
821  GNUNET_memcmp (&h1->publicKey,
822  &h2->publicKey))
824  ec.expiration_limit = now;
825  ec.result = GNUNET_TIME_UNIT_FOREVER_ABS;
826  ec.ref = h2;
828  GNUNET_NO,
829  &find_matching,
830  &ec);
831  if (ec.result.abs_value_us == GNUNET_TIME_UNIT_ZERO.rel_value_us)
832  return ec.result;
833  ec.ref = h1;
835  GNUNET_NO,
836  &find_matching,
837  &ec);
838  return ec.result;
839 }
840 
841 
851 static int
852 find_max_expire (void *cls,
853  const struct GNUNET_HELLO_Address *address,
855 {
856  struct GNUNET_TIME_Absolute *max = cls;
857 
859  return GNUNET_OK;
860 }
861 
862 
871 {
872  struct GNUNET_TIME_Absolute ret;
873 
876  GNUNET_NO,
878  &ret);
879  return ret;
880 }
881 
882 
935 static int
937  const struct GNUNET_HELLO_Address *address,
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 }
997 
998 
1006 char *
1008  GNUNET_HELLO_TransportPluginsFind plugins_find)
1009 {
1011  char *pkey;
1012 
1013  ctx.plugins_find = plugins_find;
1015  GNUNET_asprintf (&ctx.uri,
1016  "%s%s",
1020  pkey);
1021  GNUNET_free (pkey);
1023  GNUNET_NO,
1025  &ctx);
1026  return ctx.uri;
1027 }
1028 
1029 
1030 /* ************************* Parse HELLO URI ********************* */
1031 
1032 
1042 static ssize_t
1044  size_t max,
1045  void *buffer)
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 }
1183 
1184 
1194 int
1197  struct GNUNET_HELLO_Message **hello,
1198  GNUNET_HELLO_TransportPluginsFind plugins_find)
1199 {
1200  const char *pks;
1201  const char *exc;
1202  int friend_only;
1204 
1205  if (0 == strncmp (uri,
1207  strlen (GNUNET_HELLO_URI_PREFIX)))
1208  {
1209  pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)];
1210  friend_only = GNUNET_NO;
1211  }
1212  else if (0 == strncmp (uri,
1215  {
1216  pks = &uri[strlen (GNUNET_FRIEND_HELLO_URI_PREFIX)];
1217  friend_only = GNUNET_YES;
1218  }
1219  else
1220  return GNUNET_SYSERR;
1221  exc = strchr (pks, GNUNET_HELLO_URI_SEP);
1222 
1223  if (GNUNET_OK !=
1225  (NULL == exc) ? strlen (pks) : (exc - pks),
1226  (unsigned char *) pubkey,
1227  sizeof(*pubkey)))
1228  return GNUNET_SYSERR;
1229 
1230  ctx.pos = exc;
1231  ctx.ret = GNUNET_OK;
1232  ctx.counter_total = 0;
1233  ctx.counter_added = 0;
1234  ctx.plugins_find = plugins_find;
1235  *hello = GNUNET_HELLO_create (pubkey,
1237  &ctx,
1238  friend_only);
1239 
1241  "HELLO URI contained %u addresses, added %u addresses\n",
1242  ctx.counter_total,
1243  ctx.counter_added);
1244 
1245  return ctx.ret;
1246 }
1247 
1248 
1249 /* end of hello.c */
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
static char * address
GNS address for this phone.
static char * expire
DID Document expiration Date Attribut String.
Definition: gnunet-did.c:101
static struct GNUNET_FS_DownloadContext * dc
static char * pkey
Public key of the zone to look in, in ASCII.
static struct GNUNET_IDENTITY_PublicKey pubkey
Public key of the zone to look in.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
static char * plugin_name
Name of our plugin.
static char buf[2048]
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct GNUNET_SCHEDULER_Task * t
Main task.
Helper library for handling HELLOs.
Constants for network protocols.
Transport service plugin API.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message,...
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
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.
Definition: hello.c:601
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:630
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?
Definition: hello.c:870
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
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:515
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.
Definition: hello.c:1195
#define GNUNET_FRIEND_HELLO_URI_PREFIX
Prefix that every FRIEND HELLO URI must start with.
ssize_t(* GNUNET_HELLO_GenerateAddressListCallback)(void *cls, size_t max, void *buf)
Callback function used to fill a buffer of max bytes with a list of addresses in the format used by H...
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:89
struct GNUNET_MessageHeader * GNUNET_HELLO_get_header(struct GNUNET_HELLO_Message *hello)
Get the header from a HELLO message, used so other code can correctly send HELLO messages.
Definition: hello.c:671
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
#define GNUNET_HELLO_URI_PREFIX
Prefix that every HELLO URI must start with.
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:812
int(* GNUNET_HELLO_AddressIterator)(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Iterator callback to go over all addresses.
struct GNUNET_TRANSPORT_PluginFunctions *(* GNUNET_HELLO_TransportPluginsFind)(const char *name)
Helper function to load/access transport plugins.
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.
Definition: hello.c:1007
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_HELLO_URI_SEP
Separator used in HELLO URI.
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_HELLO_ADDRESS_INFO_NONE
No additional information.
#define GNUNET_log(kind,...)
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition: crypto_ecc.c:251
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#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_DEBUG
@ GNUNET_ERROR_TYPE_INFO
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_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MESSAGE_TYPE_HELLO
HELLO message with friend only flag used for communicating peer addresses.
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition: strings.c:788
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
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:737
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
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:638
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
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...
Definition: hello.c:483
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.
Definition: hello.c:575
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.
Definition: hello.c:144
static int find_matching(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Helper function for GNUNET_HELLO_equals().
Definition: hello.c:770
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
static ssize_t add_address_to_hello(void *cls, size_t max, void *buffer)
We're building a HELLO.
Definition: hello.c:1043
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".
Definition: hello.c:936
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
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
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.
Definition: hello.c:852
#define max(x, y)
#define _(String)
GNU gettext support macro.
Definition: platform.h:178
Context used in GNUNET_HELLO_iterate_new_addresses() to figure out which addresses are in fact 'new'.
Definition: hello.c:538
void * it_cls
Closure for it.
Definition: hello.c:552
const struct GNUNET_HELLO_Message * old_hello
HELLO with known addresses, addresses in this HELLO we must always ignore.
Definition: hello.c:558
GNUNET_HELLO_AddressIterator it
Function to call on addresses that are indeed new.
Definition: hello.c:547
struct GNUNET_TIME_Absolute expiration_limit
We should ignore addresses that expire before this time.
Definition: hello.c:542
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
const struct GNUNET_HELLO_Message * ref
HELLO message to compare against.
Definition: hello.c:705
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
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
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
An address for communicating with a peer.
const char * transport_name
Name of the transport plugin enabling the communication using this address.
size_t address_length
Number of bytes in address.
const void * address
Binary representation of the address (plugin-specific).
Context used for building our own URI.
Definition: hello.c:37
GNUNET_HELLO_TransportPluginsFind plugins_find
Function for finding transport plugins by name.
Definition: hello.c:46
char * uri
Final URI.
Definition: hello.c:41
A HELLO message is used to exchange information about transports with other peers.
uint32_t friend_only
Use in F2F mode: Do not gossip this HELLO message.
struct GNUNET_CRYPTO_EddsaPublicKey publicKey
The public key of the peer.
struct GNUNET_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_HELLO.
Context for add_address_to_hello().
Definition: hello.c:54
unsigned int counter_total
Counter.
Definition: hello.c:68
int ret
Set to GNUNET_SYSERR to indicate parse errors.
Definition: hello.c:63
const char * pos
Position in the URI with the next address to parse.
Definition: hello.c:58
unsigned int counter_added
Counter skipped addresses.
Definition: hello.c:73
GNUNET_HELLO_TransportPluginsFind plugins_find
Function for finding transport plugins by name.
Definition: hello.c:78
Header for all communications.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
The identity of the host (wraps the signing key of the peer).
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
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).
GNUNET_TRANSPORT_StringToAddress string_to_address
Function that will be called to convert a string address to binary (numeric conversion only).
Closure for merge_pr().
const struct GNUNET_HELLO_Message * other
Either h1 or h2, used when copying to compare against (so we only copy the most recent entry).
Definition: hello.c:405
size_t max
Number of bytes allocated in buf.
Definition: hello.c:415
int take_equal
Should we copy addresses with an identical value and expiration time in other, or do we only copy add...
Definition: hello.c:427
const struct GNUNET_HELLO_Message * h1
First HELLO we are merging.
Definition: hello.c:393
size_t ret
Current (write) offset in buf.
Definition: hello.c:420
const struct GNUNET_HELLO_Message * h2
Second HELLO we are merging.
Definition: hello.c:398
char * buf
Buffer where we copy to.
Definition: hello.c:410
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.