GNUnet  0.10.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;
122  exp = GNUNET_TIME_absolute_hton (expiration);
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);
217  GNUNET_assert ( (GNUNET_YES == friend_only) ||
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 {
259  struct GNUNET_HELLO_Address address;
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;
268  struct GNUNET_TIME_AbsoluteNBO expire;
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);
282  GNUNET_memcpy (ret,
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_non_null (ret);
304  return NULL;
305  }
306  /* need GNUNET_memcpy() due to possibility of misalignment */
307  GNUNET_memcpy (&expire,
308  &inptr[esize - alen - sizeof (struct GNUNET_TIME_AbsoluteNBO)],
309  sizeof (struct GNUNET_TIME_AbsoluteNBO));
310  address.address = &inptr[esize - alen];
311  address.address_length = alen;
312  address.transport_name = inptr;
314  iret = it (it_cls,
315  &address,
316  GNUNET_TIME_absolute_ntoh (expire));
317  if (GNUNET_SYSERR == iret)
318  break;
319  if ( (GNUNET_OK == iret) &&
320  (NULL != ret) )
321  {
322  /* copy address over */
323  GNUNET_memcpy (woff,
324  inptr,
325  esize);
326  woff += esize;
327  wpos += esize;
328  }
329  insize -= esize;
330  inptr += esize;
331  }
332  if (NULL != ret)
333  ret->header.size = ntohs (sizeof (struct GNUNET_HELLO_Message) + wpos);
334  return ret;
335 }
336 
337 
342 {
347 
351  int found;
352 
357 };
358 
359 
368 static int
369 get_match_exp (void *cls,
370  const struct GNUNET_HELLO_Address *address,
371  struct GNUNET_TIME_Absolute expiration)
372 {
373  struct ExpireContext *ec = cls;
374 
375  if (0 != GNUNET_HELLO_address_cmp (address,
376  ec->address))
377  return GNUNET_OK;
378  ec->found = GNUNET_YES;
379  ec->expiration = expiration;
380  return GNUNET_SYSERR; /* done here */
381 }
382 
383 
387 struct MergeContext
388 {
392  const struct GNUNET_HELLO_Message *h1;
393 
397  const struct GNUNET_HELLO_Message *h2;
398 
405 
409  char *buf;
410 
414  size_t max;
415 
419  size_t ret;
420 
427 
428 };
429 
430 
441 static int
442 copy_latest (void *cls,
443  const struct GNUNET_HELLO_Address *address,
444  struct GNUNET_TIME_Absolute expiration)
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 +=
463  GNUNET_HELLO_add_address (address,
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 {
551  struct GNUNET_TIME_Absolute expiration_limit;
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,
586  struct GNUNET_TIME_Absolute expiration)
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) ||
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  const struct GNUNET_HELLO_Message *old_hello,
625  struct GNUNET_TIME_Absolute expiration_limit,
627  void *it_cls)
628 {
629  struct DeltaContext dc;
630 
632  dc.it = it;
633  dc.it_cls = it_cls;
634  dc.old_hello = old_hello;
635  GNUNET_assert (NULL ==
637  GNUNET_NO,
638  &delta_match,
639  &dc));
640 }
641 
642 
648 uint16_t
650 {
651  uint16_t ret = ntohs (hello->header.size);
652 
653  if ((ret < sizeof (struct GNUNET_HELLO_Message)) ||
654  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
655  return 0;
656  return ret;
657 }
658 
659 
667 int
669  struct GNUNET_PeerIdentity *peer)
670 {
671  uint16_t ret = ntohs (hello->header.size);
672 
673  if ((ret < sizeof (struct GNUNET_HELLO_Message)) ||
674  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
675  return GNUNET_SYSERR;
676  peer->public_key = hello->publicKey;
677  return GNUNET_OK;
678 }
679 
680 
689 struct GNUNET_MessageHeader *
691 {
692  uint16_t ret = ntohs (hello->header.size);
693 
694  if ((ret < sizeof (struct GNUNET_HELLO_Message)) ||
695  (ntohs (hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
696  return NULL;
697 
698  return &hello->header;
699 }
700 
701 
706 {
711  struct GNUNET_TIME_Absolute expiration_limit;
712 
719 
724  const struct GNUNET_HELLO_Message *ref;
725 
730 
734  struct GNUNET_TIME_Absolute expiration;
735 
739  int found;
740 
741 };
742 
743 
756 static int
758  const struct GNUNET_HELLO_Address *address,
759  struct GNUNET_TIME_Absolute expiration)
760 {
761  struct EqualsContext *ec = cls;
762 
763  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
764  return GNUNET_YES;
765  if (0 == GNUNET_HELLO_address_cmp (address, ec->address))
766  {
767  ec->found = GNUNET_YES;
768  if (expiration.abs_value_us < ec->expiration.abs_value_us)
769  ec->result = GNUNET_TIME_absolute_min (expiration,
770  ec->result);
771  return GNUNET_SYSERR;
772  }
773  return GNUNET_YES;
774 }
775 
776 
789 static int
790 find_matching (void *cls,
791  const struct GNUNET_HELLO_Address *address,
792  struct GNUNET_TIME_Absolute expiration)
793 {
794  struct EqualsContext *ec = cls;
795 
796  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
797  return GNUNET_OK; /* expired, we don't care */
798  ec->address = address;
799  ec->expiration = expiration;
800  ec->found = GNUNET_NO;
802  GNUNET_NO,
804  ec);
805  if (GNUNET_NO == ec->found)
806  {
807  /* not found, we differ *now* */
809  return GNUNET_SYSERR;
810  }
811  return GNUNET_OK;
812 }
813 
814 
833  const struct GNUNET_HELLO_Message *h2,
834  struct GNUNET_TIME_Absolute now)
835 {
836  struct EqualsContext ec;
837 
838  if (h1->header.type != h2->header.type)
840  if (0 !=
841  GNUNET_memcmp (&h1->publicKey,
842  &h2->publicKey))
844  ec.expiration_limit = now;
846  ec.ref = h2;
848  GNUNET_NO,
849  &find_matching,
850  &ec);
851  if (ec.result.abs_value_us == GNUNET_TIME_UNIT_ZERO.rel_value_us)
852  return ec.result;
853  ec.ref = h1;
855  GNUNET_NO,
856  &find_matching,
857  &ec);
858  return ec.result;
859 }
860 
861 
871 static int
872 find_max_expire (void *cls,
873  const struct GNUNET_HELLO_Address *address,
874  struct GNUNET_TIME_Absolute expiration)
875 {
876  struct GNUNET_TIME_Absolute *max = cls;
877 
878  *max = GNUNET_TIME_absolute_max (*max, expiration);
879  return GNUNET_OK;
880 }
881 
882 
891 {
892  struct GNUNET_TIME_Absolute ret;
893 
896  GNUNET_NO,
898  &ret);
899  return ret;
900 }
901 
902 
956 static int
958  const struct GNUNET_HELLO_Address *address,
959  struct GNUNET_TIME_Absolute expiration)
960 {
961  struct GNUNET_HELLO_ComposeUriContext *ctx = cls;
963  const char *addr;
964  char *ret;
965  char *addr_dup;
966  char *pos;
967  char tbuf[16] = "";
968  char *client_str = "_client";
969  struct tm *t;
970  time_t seconds;
971 
972  papi = ctx->plugins_find (address->transport_name);
973  if (NULL == papi)
974  {
975  /* Not an error - we might just not have the right plugin. */
976  return GNUNET_OK;
977  }
978  if (NULL == papi->address_to_string)
979  {
981  "URI conversion not implemented for plugin `%s'\n",
982  address->transport_name);
983  return GNUNET_OK;
984  }
985  addr = papi->address_to_string (papi->cls,
986  address->address,
987  address->address_length);
988  if ( (NULL == addr) ||
989  (0 == strlen(addr)) )
990  return GNUNET_OK;
991 
992  addr_dup = GNUNET_strdup (addr);
993  if (NULL != (pos = strstr (addr_dup, "_server")))
994  GNUNET_memcpy (pos,
995  client_str,
996  strlen (client_str)); /* Replace all server addresses with client addresses */
997 
998  seconds = expiration.abs_value_us / 1000LL / 1000LL;
999  t = gmtime (&seconds);
1000 
1001  GNUNET_asprintf (&ret,
1002  "%s%c%s%c%s%c%s",
1003  ctx->uri,
1005  strftime (tbuf,
1006  sizeof (tbuf),
1007  "%Y%m%d%H%M%S",
1008  t) ? tbuf : "0",
1010  address->transport_name,
1012  addr_dup);
1013  GNUNET_free (addr_dup);
1014  GNUNET_free (ctx->uri);
1015  ctx->uri = ret;
1016  return GNUNET_OK;
1017 }
1018 
1019 
1027 char *
1030 {
1031  struct GNUNET_HELLO_ComposeUriContext ctx;
1032  char *pkey;
1033 
1034  ctx.plugins_find = plugins_find;
1036  GNUNET_asprintf (&ctx.uri,
1037  "%s%s",
1041  pkey);
1042  GNUNET_free (pkey);
1044  GNUNET_NO,
1046  &ctx);
1047  return ctx.uri;
1048 }
1049 
1050 
1051 /* ************************* Parse HELLO URI ********************* */
1052 
1053 
1063 static ssize_t
1065  size_t max,
1066  void *buffer)
1067 {
1068  struct GNUNET_HELLO_ParseUriContext *ctx = cls;
1069  const char *tname;
1070  const char *address;
1071  char *uri_address;
1072  const char *end;
1073  char *plugin_name;
1074  struct tm expiration_time;
1075  time_t expiration_seconds;
1076  struct GNUNET_TIME_Absolute expire;
1077  struct GNUNET_TRANSPORT_PluginFunctions *papi;
1078  void *addr;
1079  size_t addr_len;
1080  struct GNUNET_HELLO_Address haddr;
1081  ssize_t ret;
1082 
1083  if (NULL == ctx->pos)
1084  return GNUNET_SYSERR;
1085  if (GNUNET_HELLO_URI_SEP != ctx->pos[0])
1086  {
1087  ctx->ret = GNUNET_SYSERR;
1088  GNUNET_break (0);
1089  return GNUNET_SYSERR;
1090  }
1091  ctx->pos++;
1092 
1093  if ( ('0' == ctx->pos[0]) &&
1094  (GNUNET_HELLO_URI_SEP == ctx->pos[1]) )
1095  {
1097  tname = ctx->pos + 1;
1098  }
1099  else
1100  {
1101  memset (&expiration_time, 0, sizeof (expiration_time));
1102  tname = strptime (ctx->pos,
1103  "%Y%m%d%H%M%S",
1104  &expiration_time);
1105  if (NULL == tname)
1106  {
1107  ctx->ret = GNUNET_SYSERR;
1109  _("Failed to parse HELLO message: missing expiration time\n"));
1110  GNUNET_break (0);
1111  return GNUNET_SYSERR;
1112  }
1113 
1114  expiration_seconds = mktime (&expiration_time);
1115  if (expiration_seconds == (time_t) -1)
1116  {
1118  _("Failed to parse HELLO message: invalid expiration time\n"));
1119  ctx->ret = GNUNET_SYSERR;
1120  GNUNET_break (0);
1121  return GNUNET_SYSERR;
1122  }
1123  expire.abs_value_us = expiration_seconds * 1000LL * 1000LL;
1124  }
1125  if (GNUNET_HELLO_URI_SEP != tname[0])
1126  {
1128  _("Failed to parse HELLO message: malformed\n"));
1129  ctx->ret = GNUNET_SYSERR;
1130  GNUNET_break (0);
1131  return GNUNET_SYSERR;
1132  }
1133  tname++;
1134  address = strchr (tname,
1135  (int) GNUNET_HELLO_URI_SEP);
1136  if (NULL == address)
1137  {
1139  _("Failed to parse HELLO message: missing transport plugin\n"));
1140  ctx->ret = GNUNET_SYSERR;
1141  GNUNET_break (0);
1142  return GNUNET_SYSERR;
1143  }
1144  address++;
1145  end = strchr (address, (int) GNUNET_HELLO_URI_SEP);
1146  ctx->pos = end;
1147  ctx->counter_total ++;
1148  plugin_name = GNUNET_strndup (tname, address - (tname+1));
1149  papi = ctx->plugins_find (plugin_name);
1150  if (NULL == papi)
1151  {
1152  /* Not an error - we might just not have the right plugin.
1153  * Skip this part, advance to the next one and recurse.
1154  * But only if this is not the end of string.
1155  */
1157  _("Plugin `%s' not found, skipping address\n"),
1158  plugin_name);
1159  GNUNET_free (plugin_name);
1160  return 0;
1161  }
1162  if (NULL == papi->string_to_address)
1163  {
1165  _("Plugin `%s' does not support URIs yet\n"),
1166  plugin_name);
1167  GNUNET_free (plugin_name);
1168  GNUNET_break (0);
1169  return 0;
1170  }
1171  uri_address = GNUNET_strndup (address, end - address);
1172  if (GNUNET_OK !=
1173  papi->string_to_address (papi->cls,
1174  uri_address,
1175  strlen (uri_address) + 1,
1176  &addr,
1177  &addr_len))
1178  {
1180  _("Failed to parse `%s' as an address for plugin `%s'\n"),
1181  uri_address,
1182  plugin_name);
1183  GNUNET_free (plugin_name);
1184  GNUNET_free (uri_address);
1185  return 0;
1186  }
1187  GNUNET_free (uri_address);
1188  /* address.peer is unset - not used by add_address() */
1189  haddr.address_length = addr_len;
1190  haddr.address = addr;
1191  haddr.transport_name = plugin_name;
1192  ret = GNUNET_HELLO_add_address (&haddr,
1193  expire,
1194  buffer,
1195  max);
1196  ctx->counter_added ++;
1197  GNUNET_free (addr);
1198  GNUNET_free (plugin_name);
1199  return ret;
1200 }
1201 
1202 
1212 int
1215  struct GNUNET_HELLO_Message **hello,
1217 {
1218  const char *pks;
1219  const char *exc;
1220  int friend_only;
1221  struct GNUNET_HELLO_ParseUriContext ctx;
1222 
1223  if (0 == strncmp (uri,
1225  strlen (GNUNET_HELLO_URI_PREFIX)))
1226  {
1227  pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)];
1228  friend_only = GNUNET_NO;
1229  }
1230  else if (0 == strncmp (uri,
1233  {
1234  pks = &uri[strlen (GNUNET_FRIEND_HELLO_URI_PREFIX)];
1235  friend_only = GNUNET_YES;
1236  }
1237  else
1238  return GNUNET_SYSERR;
1239  exc = strchr (pks, GNUNET_HELLO_URI_SEP);
1240 
1241  if (GNUNET_OK !=
1243  (NULL == exc) ? strlen (pks) : (exc - pks),
1244  (unsigned char *) pubkey,
1245  sizeof (*pubkey)))
1246  return GNUNET_SYSERR;
1247 
1248  ctx.pos = exc;
1249  ctx.ret = GNUNET_OK;
1250  ctx.counter_total = 0;
1251  ctx.counter_added = 0;
1252  ctx.plugins_find = plugins_find;
1253  *hello = GNUNET_HELLO_create (pubkey,
1255  &ctx,
1256  friend_only);
1257 
1259  "HELLO URI contained %u addresses, added %u addresses\n",
1260  ctx.counter_total,
1261  ctx.counter_added);
1262 
1263  return ctx.ret;
1264 }
1265 
1266 
1267 /* end of hello.c */
size_t address_length
Number of bytes in address.
int GNUNET_HELLO_get_id(const struct GNUNET_HELLO_Message *hello, struct GNUNET_PeerIdentity *peer)
Get the peer identity from a HELLO message.
Definition: hello.c:668
enum GNUNET_HELLO_AddressInfo local_info
Extended information about address.
int found
Set to GNUNET_YES if we found the address.
Definition: hello.c:351
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:957
Closure for merge_pr().
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
A HELLO message is used to exchange information about transports with other peers.
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
#define GNUNET_FRIEND_HELLO_URI_PREFIX
Prefix that every FRIEND HELLO URI must start with.
static struct GNUNET_CRYPTO_EcdsaPublicKey pubkey
Public key of the zone to look in.
static char * expiration
Credential TTL.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:670
GNUNET_TRANSPORT_AddressToString address_to_string
Function that will be called to convert a binary address to a string (numeric conversion only)...
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
static ssize_t add_address_to_hello(void *cls, size_t max, void *buffer)
We&#39;re building a HELLO.
Definition: hello.c:1064
static char * pkey
Public key of the zone to look in, in ASCII.
const void * address
Binary representation of the address (plugin-specific).
static int end
Set if we are to shutdown all services (including ARM).
Definition: gnunet-arm.c:34
struct GNUNET_HELLO_Message * GNUNET_HELLO_merge(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2)
Construct a HELLO message by merging the addresses in two existing HELLOs (which must be for the same...
Definition: hello.c:524
struct GNUNET_HELLO_Message * GNUNET_HELLO_create(const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, GNUNET_HELLO_GenerateAddressListCallback addrgen, void *addrgen_cls, int friend_only)
Construct a HELLO message given the public key, expiration time and an iterator that spews the transp...
Definition: hello.c:204
const struct GNUNET_HELLO_Message * h1
First HELLO we are merging.
Definition: hello.c:392
#define GNUNET_HELLO_URI_SEP
Separator used in HELLO URI.
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:1028
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
const char * pos
Position in the URI with the next address to parse.
Definition: hello.c:58
int ret
Set to GNUNET_SYSERR to indicate parse errors.
Definition: hello.c:63
Each plugin is required to return a pointer to a struct of this type as the return value from its ent...
Context for add_address_to_hello().
Definition: hello.c:53
struct GNUNET_TIME_Absolute GNUNET_HELLO_equals(const struct GNUNET_HELLO_Message *h1, const struct GNUNET_HELLO_Message *h2, struct GNUNET_TIME_Absolute now)
Test if two HELLO messages contain the same addresses.
Definition: hello.c:832
Context used in GNUNET_HELLO_iterate_new_addresses() to figure out which addresses are in fact &#39;new&#39;...
Definition: hello.c:546
struct GNUNET_TIME_Absolute expiration
Expiration time of address.
Definition: hello.c:734
GNUNET_HELLO_AddressIterator it
Function to call on addresses that are indeed new.
Definition: hello.c:556
#define GNUNET_NO
Definition: gnunet_common.h:81
struct GNUNET_TIME_Absolute expiration_limit
Addresses that expired before this date are ignored for the comparisson.
Definition: hello.c:711
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
static struct GNUNET_SCHEDULER_Task * t
Main task.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
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:690
static int ret
Final status code.
Definition: gnunet-arm.c:89
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
Time for absolute time used by GNUnet, in microseconds and in network byte order. ...
uint64_t abs_value_us
The actual value.
char * uri
Final URI.
Definition: hello.c:41
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
struct GNUNET_TRANSPORT_PluginFunctions *(* GNUNET_HELLO_TransportPluginsFind)(const char *name)
Helper function to load/access transport plugins.
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:872
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:208
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:757
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
char * buf
Buffer where we copy to.
Definition: hello.c:409
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
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_TransportPluginsFind plugins_find
Function for finding transport plugins by name.
Definition: hello.c:46
const struct GNUNET_HELLO_Message * old_hello
HELLO with known addresses, addresses in this HELLO we must always ignore.
Definition: hello.c:567
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
const struct GNUNET_HELLO_Message * ref
HELLO message to compare against.
Definition: hello.c:724
void * cls
Closure for all of the callbacks.
#define GNUNET_memcpy(dst, src, n)
GNUNET_TRANSPORT_StringToAddress string_to_address
Function that will be called to convert a string address to binary (numeric conversion only)...
int found
Did we find the address we were looking for?
Definition: hello.c:739
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_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
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:367
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:1213
const struct GNUNET_HELLO_Address * address
Address we are looking for.
Definition: hello.c:346
#define GNUNET_HELLO_URI_PREFIX
Prefix that every HELLO URI must start with.
struct GNUNET_TIME_Absolute result
Earliest expiration time for which we found a match with a difference in expiration times...
Definition: hello.c:718
static char buf[2048]
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:317
const char * transport_name
Name of the transport plugin enabling the communication using this address.
static int result
Global testing status.
static char * plugin_name
Solver plugin name as string.
unsigned int counter_added
Counter skipped addresses.
Definition: hello.c:73
static struct GNUNET_TESTBED_Controller * mc
Handle to the master controller.
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:426
void * it_cls
Closure for it.
Definition: hello.c:561
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_TIME_Absolute expiration_limit
We should ignore addresses that expire before this time.
Definition: hello.c:551
static int delta_match(void *cls, const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration)
Check if the given address is &#39;new&#39;, and if so, call the iterator.
Definition: hello.c:584
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
struct GNUNET_TIME_Absolute expiration
Set to the expiration of the match if found is GNUNET_YES.
Definition: hello.c:356
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:790
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:89
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
struct GNUNET_PeerIdentity peer
For which peer is this an address?
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
#define GNUNET_MAX_MESSAGE_SIZE
Largest supported message (to be precise, one byte more than the largest possible message...
const struct GNUNET_HELLO_Message * h2
Second HELLO we are merging.
Definition: hello.c:397
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
The identity of the host (wraps the signing key of the peer).
No additional information.
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_MessageHeader header
Type will be GNUNET_MESSAGE_TYPE_HELLO.
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:302
An address for communicating with a peer.
size_t ret
Current (write) offset in buf.
Definition: hello.c:419
#define GNUNET_log(kind,...)
size_t max
Number of bytes allocated in buf.
Definition: hello.c:414
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:649
Context used for building our own URI.
Definition: hello.c:36
Closure for get_match_exp().
Definition: hello.c:341
struct GNUNET_CRYPTO_EddsaPublicKey publicKey
The public key of the peer.
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:404
Header for all communications.
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:369
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:80
GNUNET_HELLO_TransportPluginsFind plugins_find
Function for finding transport plugins by name.
Definition: hello.c:78
Context used for comparing HELLOs in GNUNET_HELLO_equals().
Definition: hello.c:705
unsigned int counter_total
Counter.
Definition: hello.c:68
#define GNUNET_MESSAGE_TYPE_HELLO
HELLO message with friend only flag used for communicating peer addresses.
uint32_t friend_only
Use in F2F mode: Do not gossip this HELLO message.
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:890
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:654
static char * address
GNS address for this phone.
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...
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
#define GNUNET_malloc(size)
Wrapper around malloc.
int 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:1021
const struct GNUNET_HELLO_Address * address
Address we are currently looking for.
Definition: hello.c:729
static struct GNUNET_FS_DownloadContext * dc
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_CRYPTO_EddsaPublicKey public_key
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...