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;
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
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,
317  GNUNET_TIME_absolute_ntoh (expire));
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,
372  struct GNUNET_TIME_Absolute expiration)
373 {
374  struct ExpireContext *ec = cls;
375 
376  if (0 != GNUNET_HELLO_address_cmp (address,
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,
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  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 
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 {
714  struct GNUNET_TIME_Absolute expiration_limit;
715 
722 
727  const struct GNUNET_HELLO_Message *ref;
728 
733 
737  struct GNUNET_TIME_Absolute expiration;
738 
742  int found;
743 };
744 
745 
758 static int
760  const struct GNUNET_HELLO_Address *address,
761  struct GNUNET_TIME_Absolute expiration)
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)
771  ec->result = GNUNET_TIME_absolute_min (expiration,
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,
794  struct GNUNET_TIME_Absolute expiration)
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 
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;
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,
876  struct GNUNET_TIME_Absolute expiration)
877 {
878  struct GNUNET_TIME_Absolute *max = cls;
879 
880  *max = GNUNET_TIME_absolute_max (*max, expiration);
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,
960  struct GNUNET_TIME_Absolute expiration)
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 *
1031 {
1032  struct GNUNET_HELLO_ComposeUriContext ctx;
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;
1077  struct GNUNET_TIME_Absolute expire;
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);
1163  GNUNET_free (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);
1171  GNUNET_free (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);
1187  GNUNET_free (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);
1202  GNUNET_free (plugin_name);
1203  return ret;
1204 }
1205 
1206 
1216 int
1219  struct GNUNET_HELLO_Message **hello,
1221 {
1222  const char *pks;
1223  const char *exc;
1224  int friend_only;
1225  struct GNUNET_HELLO_ParseUriContext ctx;
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 */
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:671
enum GNUNET_HELLO_AddressInfo local_info
Extended information about address.
int found
Set to GNUNET_YES if we found the address.
Definition: hello.c:352
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
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.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition: time.c:673
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:1065
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:393
#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:1029
#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:834
Context used in GNUNET_HELLO_iterate_new_addresses() to figure out which addresses are in fact &#39;new&#39;...
Definition: hello.c:546
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_TIME_Absolute expiration
Expiration time of address.
Definition: hello.c:737
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
GNUNET_HELLO_AddressIterator it
Function to call on addresses that are indeed new.
Definition: hello.c:556
#define GNUNET_NO
Definition: gnunet_common.h:78
struct GNUNET_TIME_Absolute expiration_limit
Addresses that expired before this date are ignored for the comparisson.
Definition: hello.c:714
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#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:693
#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:99
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:874
#define GNUNET_TIME_UNIT_FOREVER_ABS
Constant used to specify "forever".
#define _(String)
GNU gettext support macro.
Definition: platform.h:181
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 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:410
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:727
void * cls
Closure for all of the callbacks.
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:742
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:365
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
const struct GNUNET_HELLO_Address * address
Address we are looking for.
Definition: hello.c:347
#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:721
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.
unsigned int counter_added
Counter skipped addresses.
Definition: hello.c:73
static char * expiration
Credential TTL.
Definition: gnunet-abd.c:96
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:427
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:76
struct GNUNET_TIME_Absolute expiration
Set to the expiration of the match if found is GNUNET_YES.
Definition: hello.c:357
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
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:398
#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:420
#define GNUNET_log(kind,...)
size_t max
Number of bytes allocated in buf.
Definition: hello.c:415
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:652
Context used for building our own URI.
Definition: hello.c:36
Closure for get_match_exp().
Definition: hello.c:342
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:405
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:370
Time for absolute times used by GNUnet, in microseconds.
#define GNUNET_YES
Definition: gnunet_common.h:77
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:708
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:892
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:657
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
static char * plugin_name
Name of our plugin.
#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:952
const struct GNUNET_HELLO_Address * address
Address we are currently looking for.
Definition: hello.c:732
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...