GNUnet  0.11.x
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 
523 struct GNUNET_HELLO_Message *
525  const struct GNUNET_HELLO_Message *h2)
526 {
527  struct MergeContext mc = { h1, h2, NULL, NULL, 0, 0, 0 };
528  int friend_only;
529 
530  if (h1->friend_only != h2->friend_only)
531  friend_only = GNUNET_YES; /* One of the HELLOs is friend only */
532  else
533  friend_only = ntohl (h1->friend_only); /* Both HELLO's have the same type */
534 
535  return GNUNET_HELLO_create (&h1->publicKey,
536  &merge_addr,
537  &mc,
538  friend_only);
539 }
540 
541 
547 {
552 
557 
561  void *it_cls;
562 
568 };
569 
570 
583 static int
584 delta_match (void *cls,
585  const struct GNUNET_HELLO_Address *address,
587 {
588  struct DeltaContext *dc = cls;
589  int ret;
590  struct ExpireContext ec;
591 
592  ec.address = address;
593  ec.found = GNUNET_NO;
595  GNUNET_NO,
596  &get_match_exp,
597  &ec);
598  if ((GNUNET_YES == ec.found) &&
599  ((ec.expiration.abs_value_us > expiration.abs_value_us) ||
600  (ec.expiration.abs_value_us >= dc->expiration_limit.abs_value_us)))
601  return GNUNET_YES; /* skip: found and boring */
602  ret = dc->it (dc->it_cls,
603  address,
604  expiration);
605  return ret;
606 }
607 
608 
622 void
624  GNUNET_HELLO_Message *new_hello,
625  const struct
626  GNUNET_HELLO_Message *old_hello,
627  struct GNUNET_TIME_Absolute
628  expiration_limit,
630  void *it_cls)
631 {
632  struct DeltaContext dc;
633 
634  dc.expiration_limit = expiration_limit;
635  dc.it = it;
636  dc.it_cls = it_cls;
637  dc.old_hello = old_hello;
638  GNUNET_assert (NULL ==
640  GNUNET_NO,
641  &delta_match,
642  &dc));
643 }
644 
645 
651 uint16_t
653 {
654  uint16_t ret = ntohs (hello->header.size);
655 
656  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
657  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
658  return 0;
659  return ret;
660 }
661 
662 
670 int
672  struct GNUNET_PeerIdentity *peer)
673 {
674  uint16_t ret = ntohs (hello->header.size);
675 
676  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
677  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
678  return GNUNET_SYSERR;
679  peer->public_key = hello->publicKey;
680  return GNUNET_OK;
681 }
682 
683 
692 struct GNUNET_MessageHeader *
694 {
695  uint16_t ret = ntohs (hello->header.size);
696 
697  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
698  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
699  return NULL;
700 
701  return &hello->header;
702 }
703 
704 
709 {
715 
722 
727  const struct GNUNET_HELLO_Message *ref;
728 
733 
738 
742  int found;
743 };
744 
745 
758 static int
760  const struct GNUNET_HELLO_Address *address,
762 {
763  struct EqualsContext *ec = cls;
764 
765  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
766  return GNUNET_YES;
767  if (0 == GNUNET_HELLO_address_cmp (address, ec->address))
768  {
769  ec->found = GNUNET_YES;
770  if (expiration.abs_value_us < ec->expiration.abs_value_us)
772  ec->result);
773  return GNUNET_SYSERR;
774  }
775  return GNUNET_YES;
776 }
777 
778 
791 static int
792 find_matching (void *cls,
793  const struct GNUNET_HELLO_Address *address,
795 {
796  struct EqualsContext *ec = cls;
797 
798  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
799  return GNUNET_OK; /* expired, we don't care */
800  ec->address = address;
801  ec->expiration = expiration;
802  ec->found = GNUNET_NO;
804  GNUNET_NO,
806  ec);
807  if (GNUNET_NO == ec->found)
808  {
809  /* not found, we differ *now* */
811  return GNUNET_SYSERR;
812  }
813  return GNUNET_OK;
814 }
815 
816 
834 GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1,
835  const struct GNUNET_HELLO_Message *h2,
836  struct GNUNET_TIME_Absolute now)
837 {
838  struct EqualsContext ec;
839 
840  if (h1->header.type != h2->header.type)
842  if (0 !=
843  GNUNET_memcmp (&h1->publicKey,
844  &h2->publicKey))
846  ec.expiration_limit = now;
847  ec.result = GNUNET_TIME_UNIT_FOREVER_ABS;
848  ec.ref = h2;
850  GNUNET_NO,
851  &find_matching,
852  &ec);
853  if (ec.result.abs_value_us == GNUNET_TIME_UNIT_ZERO.rel_value_us)
854  return ec.result;
855  ec.ref = h1;
857  GNUNET_NO,
858  &find_matching,
859  &ec);
860  return ec.result;
861 }
862 
863 
873 static int
874 find_max_expire (void *cls,
875  const struct GNUNET_HELLO_Address *address,
877 {
878  struct GNUNET_TIME_Absolute *max = cls;
879 
881  return GNUNET_OK;
882 }
883 
884 
893 {
894  struct GNUNET_TIME_Absolute ret;
895 
898  GNUNET_NO,
900  &ret);
901  return ret;
902 }
903 
904 
957 static int
959  const struct GNUNET_HELLO_Address *address,
961 {
962  struct GNUNET_HELLO_ComposeUriContext *ctx = cls;
964  const char *addr;
965  char *ret;
966  char *addr_dup;
967  char *pos;
968  char tbuf[16] = "";
969  char *client_str = "_client";
970  struct tm *t;
971  time_t seconds;
972 
973  papi = ctx->plugins_find (address->transport_name);
974  if (NULL == papi)
975  {
976  /* Not an error - we might just not have the right plugin. */
977  return GNUNET_OK;
978  }
979  if (NULL == papi->address_to_string)
980  {
982  "URI conversion not implemented for plugin `%s'\n",
983  address->transport_name);
984  return GNUNET_OK;
985  }
986  addr = papi->address_to_string (papi->cls,
987  address->address,
988  address->address_length);
989  if ((NULL == addr) ||
990  (0 == strlen (addr)))
991  return GNUNET_OK;
992 
993  addr_dup = GNUNET_strdup (addr);
994  if (NULL != (pos = strstr (addr_dup, "_server")))
995  GNUNET_memcpy (pos,
996  client_str,
997  strlen (client_str)); /* Replace all server addresses with client addresses */
998 
999  seconds = expiration.abs_value_us / 1000LL / 1000LL;
1000  t = gmtime (&seconds);
1001 
1002  GNUNET_asprintf (&ret,
1003  "%s%c%s%c%s%c%s",
1004  ctx->uri,
1006  strftime (tbuf,
1007  sizeof(tbuf),
1008  "%Y%m%d%H%M%S",
1009  t) ? tbuf : "0",
1011  address->transport_name,
1013  addr_dup);
1014  GNUNET_free (addr_dup);
1015  GNUNET_free (ctx->uri);
1016  ctx->uri = ret;
1017  return GNUNET_OK;
1018 }
1019 
1020 
1028 char *
1030  GNUNET_HELLO_TransportPluginsFind plugins_find)
1031 {
1033  char *pkey;
1034 
1035  ctx.plugins_find = plugins_find;
1037  GNUNET_asprintf (&ctx.uri,
1038  "%s%s",
1042  pkey);
1043  GNUNET_free (pkey);
1045  GNUNET_NO,
1047  &ctx);
1048  return ctx.uri;
1049 }
1050 
1051 
1052 /* ************************* Parse HELLO URI ********************* */
1053 
1054 
1064 static ssize_t
1066  size_t max,
1067  void *buffer)
1068 {
1069  struct GNUNET_HELLO_ParseUriContext *ctx = cls;
1070  const char *tname;
1071  const char *address;
1072  char *uri_address;
1073  const char *end;
1074  char *plugin_name;
1075  struct tm expiration_time;
1076  time_t expiration_seconds;
1078  struct GNUNET_TRANSPORT_PluginFunctions *papi;
1079  void *addr;
1080  size_t addr_len;
1081  struct GNUNET_HELLO_Address haddr;
1082  ssize_t ret;
1083 
1084  if (NULL == ctx->pos)
1085  return GNUNET_SYSERR;
1086  if (GNUNET_HELLO_URI_SEP != ctx->pos[0])
1087  {
1088  ctx->ret = GNUNET_SYSERR;
1089  GNUNET_break (0);
1090  return GNUNET_SYSERR;
1091  }
1092  ctx->pos++;
1093 
1094  if (('0' == ctx->pos[0]) &&
1095  (GNUNET_HELLO_URI_SEP == ctx->pos[1]))
1096  {
1098  tname = ctx->pos + 1;
1099  }
1100  else
1101  {
1102  memset (&expiration_time, 0, sizeof(expiration_time));
1103  tname = strptime (ctx->pos,
1104  "%Y%m%d%H%M%S",
1105  &expiration_time);
1106  if (NULL == tname)
1107  {
1108  ctx->ret = GNUNET_SYSERR;
1110  _ (
1111  "Failed to parse HELLO message: missing expiration time\n"));
1112  GNUNET_break (0);
1113  return GNUNET_SYSERR;
1114  }
1115 
1116  expiration_seconds = mktime (&expiration_time);
1117  if (expiration_seconds == (time_t) -1)
1118  {
1120  _ (
1121  "Failed to parse HELLO message: invalid expiration time\n"));
1122  ctx->ret = GNUNET_SYSERR;
1123  GNUNET_break (0);
1124  return GNUNET_SYSERR;
1125  }
1126  expire.abs_value_us = expiration_seconds * 1000LL * 1000LL;
1127  }
1128  if (GNUNET_HELLO_URI_SEP != tname[0])
1129  {
1131  _ ("Failed to parse HELLO message: malformed\n"));
1132  ctx->ret = GNUNET_SYSERR;
1133  GNUNET_break (0);
1134  return GNUNET_SYSERR;
1135  }
1136  tname++;
1137  address = strchr (tname,
1138  (int) GNUNET_HELLO_URI_SEP);
1139  if (NULL == address)
1140  {
1142  _ (
1143  "Failed to parse HELLO message: missing transport plugin\n"));
1144  ctx->ret = GNUNET_SYSERR;
1145  GNUNET_break (0);
1146  return GNUNET_SYSERR;
1147  }
1148  address++;
1149  end = strchr (address, (int) GNUNET_HELLO_URI_SEP);
1150  ctx->pos = end;
1151  ctx->counter_total++;
1152  plugin_name = GNUNET_strndup (tname, address - (tname + 1));
1153  papi = ctx->plugins_find (plugin_name);
1154  if (NULL == papi)
1155  {
1156  /* Not an error - we might just not have the right plugin.
1157  * Skip this part, advance to the next one and recurse.
1158  * But only if this is not the end of string.
1159  */
1161  _ ("Plugin `%s' not found, skipping address\n"),
1162  plugin_name);
1164  return 0;
1165  }
1166  if (NULL == papi->string_to_address)
1167  {
1169  _ ("Plugin `%s' does not support URIs yet\n"),
1170  plugin_name);
1172  GNUNET_break (0);
1173  return 0;
1174  }
1175  uri_address = GNUNET_strndup (address, end - address);
1176  if (GNUNET_OK !=
1177  papi->string_to_address (papi->cls,
1178  uri_address,
1179  strlen (uri_address) + 1,
1180  &addr,
1181  &addr_len))
1182  {
1184  _ ("Failed to parse `%s' as an address for plugin `%s'\n"),
1185  uri_address,
1186  plugin_name);
1188  GNUNET_free (uri_address);
1189  return 0;
1190  }
1191  GNUNET_free (uri_address);
1192  /* address.peer is unset - not used by add_address() */
1193  haddr.address_length = addr_len;
1194  haddr.address = addr;
1195  haddr.transport_name = plugin_name;
1196  ret = GNUNET_HELLO_add_address (&haddr,
1197  expire,
1198  buffer,
1199  max);
1200  ctx->counter_added++;
1201  GNUNET_free (addr);
1203  return ret;
1204 }
1205 
1206 
1216 int
1219  struct GNUNET_HELLO_Message **hello,
1220  GNUNET_HELLO_TransportPluginsFind plugins_find)
1221 {
1222  const char *pks;
1223  const char *exc;
1224  int friend_only;
1226 
1227  if (0 == strncmp (uri,
1229  strlen (GNUNET_HELLO_URI_PREFIX)))
1230  {
1231  pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)];
1232  friend_only = GNUNET_NO;
1233  }
1234  else if (0 == strncmp (uri,
1237  {
1238  pks = &uri[strlen (GNUNET_FRIEND_HELLO_URI_PREFIX)];
1239  friend_only = GNUNET_YES;
1240  }
1241  else
1242  return GNUNET_SYSERR;
1243  exc = strchr (pks, GNUNET_HELLO_URI_SEP);
1244 
1245  if (GNUNET_OK !=
1247  (NULL == exc) ? strlen (pks) : (exc - pks),
1248  (unsigned char *) pubkey,
1249  sizeof(*pubkey)))
1250  return GNUNET_SYSERR;
1251 
1252  ctx.pos = exc;
1253  ctx.ret = GNUNET_OK;
1254  ctx.counter_total = 0;
1255  ctx.counter_added = 0;
1256  ctx.plugins_find = plugins_find;
1257  *hello = GNUNET_HELLO_create (pubkey,
1259  &ctx,
1260  friend_only);
1261 
1263  "HELLO URI contained %u addresses, added %u addresses\n",
1264  ctx.counter_total,
1265  ctx.counter_added);
1266 
1267  return ctx.ret;
1268 }
1269 
1270 
1271 /* 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 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 void expire(void *cls)
Expire a PooledConnection object.
static char buf[2048]
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct GNUNET_SCHEDULER_Task * t
Main task.
#define GNUNET_log(kind,...)
#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
Definition: gnunet_common.h:95
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
@ GNUNET_SYSERR
Definition: gnunet_common.h:93
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_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:671
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:623
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
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:892
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:524
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:1217
#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:693
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:834
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:1029
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:130
@ GNUNET_HELLO_ADDRESS_INFO_NONE
No additional information.
#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:775
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:224
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:542
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:216
#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:464
#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:584
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:792
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:1065
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:958
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:759
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:874
#define max(x, y)
#define _(String)
GNU gettext support macro.
Definition: platform.h:177
Context used in GNUNET_HELLO_iterate_new_addresses() to figure out which addresses are in fact 'new'.
Definition: hello.c:547
void * it_cls
Closure for it.
Definition: hello.c:561
const struct GNUNET_HELLO_Message * old_hello
HELLO with known addresses, addresses in this HELLO we must always ignore.
Definition: hello.c:567
GNUNET_HELLO_AddressIterator it
Function to call on addresses that are indeed new.
Definition: hello.c:556
struct GNUNET_TIME_Absolute expiration_limit
We should ignore addresses that expire before this time.
Definition: hello.c:551
Context used for comparing HELLOs in GNUNET_HELLO_equals().
Definition: hello.c:709
struct GNUNET_TIME_Absolute expiration
Expiration time of address.
Definition: hello.c:737
struct GNUNET_TIME_Absolute result
Earliest expiration time for which we found a match with a difference in expiration times.
Definition: hello.c:721
const struct GNUNET_HELLO_Message * ref
HELLO message to compare against.
Definition: hello.c:727
struct GNUNET_TIME_Absolute expiration_limit
Addresses that expired before this date are ignored for the comparison.
Definition: hello.c:714
int found
Did we find the address we were looking for?
Definition: hello.c:742
const struct GNUNET_HELLO_Address * address
Address we are currently looking for.
Definition: hello.c:732
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.