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 
40  char *uri;
41 
46 };
47 
48 
56  const char *pos;
57 
61  int ret;
62 
66  unsigned int counter_total;
67 
71  unsigned int counter_added;
72 
77 };
78 
79 
86 int
88 {
89  if (GNUNET_YES == ntohl(h->friend_only))
90  return GNUNET_YES;
91  return GNUNET_NO;
92 }
93 
94 
106 size_t
109  char *target,
110  size_t max)
111 {
112  uint16_t alen;
113  size_t slen;
114  struct GNUNET_TIME_AbsoluteNBO exp;
115 
116  slen = strlen(address->transport_name) + 1;
117  if (slen + sizeof(uint16_t) + sizeof(struct GNUNET_TIME_AbsoluteNBO) +
118  address->address_length > max)
119  return 0;
120  exp = GNUNET_TIME_absolute_hton(expiration);
121  alen = htons((uint16_t)address->address_length);
122  GNUNET_memcpy(target, address->transport_name, slen);
123  GNUNET_memcpy(&target[slen], &alen, sizeof(uint16_t));
124  slen += sizeof(uint16_t);
125  GNUNET_memcpy(&target[slen], &exp, sizeof(struct GNUNET_TIME_AbsoluteNBO));
126  slen += sizeof(struct GNUNET_TIME_AbsoluteNBO);
127  GNUNET_memcpy(&target[slen], address->address, address->address_length);
128  slen += address->address_length;
129  return slen;
130 }
131 
132 
141 static size_t
143  size_t max,
144  uint16_t *ralen)
145 {
146  const char *pos;
147  uint16_t alen;
148  size_t left;
149  size_t slen;
150 
151  left = max;
152  pos = buf;
153  slen = 1;
154  while ((left > 0) && ('\0' != *pos))
155  {
156  left--;
157  pos++;
158  slen++;
159  }
160  if (0 == left)
161  {
162  /* 0-termination not found */
163  GNUNET_break_op(0);
164  return 0;
165  }
166  pos++;
167  if (left < sizeof(uint16_t) + sizeof(struct GNUNET_TIME_AbsoluteNBO))
168  {
169  /* not enough space for addrlen */
170  GNUNET_break_op(0);
171  return 0;
172  }
173  GNUNET_memcpy(&alen, pos, sizeof(uint16_t));
174  alen = ntohs(alen);
175  *ralen = alen;
176  slen += alen + sizeof(uint16_t) + sizeof(struct GNUNET_TIME_AbsoluteNBO);
177  if (max < slen)
178  {
179  /* not enough space for addr */
180  GNUNET_break_op(0);
181  return 0;
182  }
183  return slen;
184 }
185 
186 
201 struct GNUNET_HELLO_Message *
204  void *addrgen_cls,
205  int friend_only)
206 {
207  char buffer[GNUNET_MAX_MESSAGE_SIZE - 1 - 256 -
208  sizeof(struct GNUNET_HELLO_Message)];
209  size_t max;
210  size_t used;
211  size_t ret;
212  struct GNUNET_HELLO_Message *hello;
213 
214  GNUNET_assert(NULL != public_key);
215  GNUNET_assert((GNUNET_YES == friend_only) ||
216  (GNUNET_NO == friend_only));
217  max = sizeof(buffer);
218  used = 0;
219  if (NULL != addrgen)
220  {
221  while (GNUNET_SYSERR != (ret = addrgen(addrgen_cls,
222  max,
223  &buffer[used])))
224  {
225  max -= ret;
226  used += ret;
227  }
228  }
229  hello = GNUNET_malloc(sizeof(struct GNUNET_HELLO_Message) + used);
230  hello->header.type = htons(GNUNET_MESSAGE_TYPE_HELLO);
231  hello->header.size = htons(sizeof(struct GNUNET_HELLO_Message) + used);
232  hello->friend_only = htonl(friend_only);
233  hello->publicKey = *public_key;
234  GNUNET_memcpy(&hello[1],
235  buffer,
236  used);
237  return hello;
238 }
239 
240 
251 struct GNUNET_HELLO_Message *
253  int return_modified,
255  void *it_cls)
256 {
257  struct GNUNET_HELLO_Address address;
258  uint16_t msize;
259  struct GNUNET_HELLO_Message *ret;
260  const char *inptr;
261  size_t insize;
262  size_t esize;
263  size_t wpos;
264  char *woff;
265  uint16_t alen;
266  struct GNUNET_TIME_AbsoluteNBO expire;
267  int iret;
268 
269  msize = GNUNET_HELLO_size(msg);
270  if ((msize < sizeof(struct GNUNET_HELLO_Message)) ||
271  (ntohs(msg->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
272  {
273  GNUNET_break_op(0);
274  return NULL;
275  }
276  ret = NULL;
277  if (return_modified)
278  {
279  ret = GNUNET_malloc(msize);
280  GNUNET_memcpy(ret,
281  msg,
282  msize);
283  }
284  inptr = (const char *)&msg[1];
285  insize = msize - sizeof(struct GNUNET_HELLO_Message);
286  wpos = 0;
287  woff = (NULL != ret) ? (char *)&ret[1] : NULL;
288  address.peer.public_key = msg->publicKey;
290  "HELLO has %u bytes of address data\n",
291  (unsigned int)insize);
292 
293  while (insize > 0)
294  {
295  esize = get_hello_address_size(inptr,
296  insize,
297  &alen);
298  if (0 == esize)
299  {
300  GNUNET_break(0);
302  return NULL;
303  }
304  /* need GNUNET_memcpy() due to possibility of misalignment */
305  GNUNET_memcpy(&expire,
306  &inptr[esize - alen - sizeof(struct GNUNET_TIME_AbsoluteNBO)],
307  sizeof(struct GNUNET_TIME_AbsoluteNBO));
308  address.address = &inptr[esize - alen];
309  address.address_length = alen;
310  address.transport_name = inptr;
312  iret = it(it_cls,
313  &address,
314  GNUNET_TIME_absolute_ntoh(expire));
315  if (GNUNET_SYSERR == iret)
316  break;
317  if ((GNUNET_OK == iret) &&
318  (NULL != ret))
319  {
320  /* copy address over */
321  GNUNET_memcpy(woff,
322  inptr,
323  esize);
324  woff += esize;
325  wpos += esize;
326  }
327  insize -= esize;
328  inptr += esize;
329  }
330  if (NULL != ret)
331  ret->header.size = ntohs(sizeof(struct GNUNET_HELLO_Message) + wpos);
332  return ret;
333 }
334 
335 
344 
348  int found;
349 
354 };
355 
356 
365 static int
366 get_match_exp(void *cls,
367  const struct GNUNET_HELLO_Address *address,
368  struct GNUNET_TIME_Absolute expiration)
369 {
370  struct ExpireContext *ec = cls;
371 
372  if (0 != GNUNET_HELLO_address_cmp(address,
373  ec->address))
374  return GNUNET_OK;
375  ec->found = GNUNET_YES;
376  ec->expiration = expiration;
377  return GNUNET_SYSERR; /* done here */
378 }
379 
380 
384 struct MergeContext {
388  const struct GNUNET_HELLO_Message *h1;
389 
393  const struct GNUNET_HELLO_Message *h2;
394 
401 
405  char *buf;
406 
410  size_t max;
411 
415  size_t ret;
416 
423 };
424 
425 
436 static int
437 copy_latest(void *cls,
438  const struct GNUNET_HELLO_Address *address,
439  struct GNUNET_TIME_Absolute expiration)
440 {
441  struct MergeContext *mc = cls;
442  struct ExpireContext ec;
443 
444  ec.address = address;
445  ec.found = GNUNET_NO;
446  /* check if address exists in other */
448  GNUNET_NO,
449  &get_match_exp,
450  &ec);
451  if ((GNUNET_NO == ec.found) ||
452  (ec.expiration.abs_value_us < expiration.abs_value_us) ||
453  ((ec.expiration.abs_value_us == expiration.abs_value_us) &&
454  (GNUNET_YES == mc->take_equal)))
455  {
456  /* copy address to buffer */
457  mc->ret +=
458  GNUNET_HELLO_add_address(address,
459  expiration,
460  &mc->buf[mc->ret],
461  mc->max - mc->ret);
462  }
463  return GNUNET_OK;
464 }
465 
466 
477 static ssize_t
478 merge_addr(void *cls,
479  size_t max,
480  void *buf)
481 {
482  struct MergeContext *mc = cls;
483 
484  if (NULL == mc->h1)
485  return GNUNET_SYSERR; /* Stop iteration */
486  mc->ret = 0;
487  mc->max = max;
488  mc->buf = buf;
489  mc->take_equal = GNUNET_NO;
490  mc->other = mc->h2;
491  /* copy addresses from h1, if strictly larger expiration than h2 */
493  GNUNET_NO,
494  &copy_latest,
495  mc);
496  mc->take_equal = GNUNET_YES;
497  mc->other = mc->h1;
498  /* copy addresses from h2, if larger or equal expiration than h1 */
500  GNUNET_NO,
501  &copy_latest,
502  mc);
503  /* set marker to stop iteration */
504  mc->h1 = NULL;
505  return mc->ret;
506 }
507 
508 
518 struct GNUNET_HELLO_Message *
520  const struct GNUNET_HELLO_Message *h2)
521 {
522  struct MergeContext mc = { h1, h2, NULL, NULL, 0, 0, 0 };
523  int friend_only;
524 
525  if (h1->friend_only != h2->friend_only)
526  friend_only = GNUNET_YES; /* One of the HELLOs is friend only */
527  else
528  friend_only = ntohl(h1->friend_only); /* Both HELLO's have the same type */
529 
530  return GNUNET_HELLO_create(&h1->publicKey,
531  &merge_addr,
532  &mc,
533  friend_only);
534 }
535 
536 
541 struct DeltaContext {
545  struct GNUNET_TIME_Absolute expiration_limit;
546 
551 
555  void *it_cls;
556 
562 };
563 
564 
577 static int
578 delta_match(void *cls,
579  const struct GNUNET_HELLO_Address *address,
580  struct GNUNET_TIME_Absolute expiration)
581 {
582  struct DeltaContext *dc = cls;
583  int ret;
584  struct ExpireContext ec;
585 
586  ec.address = address;
587  ec.found = GNUNET_NO;
589  GNUNET_NO,
590  &get_match_exp,
591  &ec);
592  if ((GNUNET_YES == ec.found) &&
593  ((ec.expiration.abs_value_us > expiration.abs_value_us) ||
595  return GNUNET_YES; /* skip: found and boring */
596  ret = dc->it(dc->it_cls,
597  address,
598  expiration);
599  return ret;
600 }
601 
602 
616 void
618  const struct GNUNET_HELLO_Message *old_hello,
619  struct GNUNET_TIME_Absolute expiration_limit,
621  void *it_cls)
622 {
623  struct DeltaContext dc;
624 
626  dc.it = it;
627  dc.it_cls = it_cls;
628  dc.old_hello = old_hello;
629  GNUNET_assert(NULL ==
631  GNUNET_NO,
632  &delta_match,
633  &dc));
634 }
635 
636 
642 uint16_t
644 {
645  uint16_t ret = ntohs(hello->header.size);
646 
647  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
648  (ntohs(hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
649  return 0;
650  return ret;
651 }
652 
653 
661 int
663  struct GNUNET_PeerIdentity *peer)
664 {
665  uint16_t ret = ntohs(hello->header.size);
666 
667  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
668  (ntohs(hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
669  return GNUNET_SYSERR;
670  peer->public_key = hello->publicKey;
671  return GNUNET_OK;
672 }
673 
674 
683 struct GNUNET_MessageHeader *
685 {
686  uint16_t ret = ntohs(hello->header.size);
687 
688  if ((ret < sizeof(struct GNUNET_HELLO_Message)) ||
689  (ntohs(hello->header.type) != GNUNET_MESSAGE_TYPE_HELLO))
690  return NULL;
691 
692  return &hello->header;
693 }
694 
695 
704  struct GNUNET_TIME_Absolute expiration_limit;
705 
712 
717  const struct GNUNET_HELLO_Message *ref;
718 
723 
727  struct GNUNET_TIME_Absolute expiration;
728 
732  int found;
733 };
734 
735 
748 static int
750  const struct GNUNET_HELLO_Address *address,
751  struct GNUNET_TIME_Absolute expiration)
752 {
753  struct EqualsContext *ec = cls;
754 
755  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
756  return GNUNET_YES;
757  if (0 == GNUNET_HELLO_address_cmp(address, ec->address))
758  {
759  ec->found = GNUNET_YES;
760  if (expiration.abs_value_us < ec->expiration.abs_value_us)
761  ec->result = GNUNET_TIME_absolute_min(expiration,
762  ec->result);
763  return GNUNET_SYSERR;
764  }
765  return GNUNET_YES;
766 }
767 
768 
781 static int
782 find_matching(void *cls,
783  const struct GNUNET_HELLO_Address *address,
784  struct GNUNET_TIME_Absolute expiration)
785 {
786  struct EqualsContext *ec = cls;
787 
788  if (expiration.abs_value_us < ec->expiration_limit.abs_value_us)
789  return GNUNET_OK; /* expired, we don't care */
790  ec->address = address;
791  ec->expiration = expiration;
792  ec->found = GNUNET_NO;
794  GNUNET_NO,
796  ec);
797  if (GNUNET_NO == ec->found)
798  {
799  /* not found, we differ *now* */
801  return GNUNET_SYSERR;
802  }
803  return GNUNET_OK;
804 }
805 
806 
825  const struct GNUNET_HELLO_Message *h2,
826  struct GNUNET_TIME_Absolute now)
827 {
828  struct EqualsContext ec;
829 
830  if (h1->header.type != h2->header.type)
832  if (0 !=
833  GNUNET_memcmp(&h1->publicKey,
834  &h2->publicKey))
836  ec.expiration_limit = now;
838  ec.ref = h2;
840  GNUNET_NO,
841  &find_matching,
842  &ec);
843  if (ec.result.abs_value_us == GNUNET_TIME_UNIT_ZERO.rel_value_us)
844  return ec.result;
845  ec.ref = h1;
847  GNUNET_NO,
848  &find_matching,
849  &ec);
850  return ec.result;
851 }
852 
853 
863 static int
864 find_max_expire(void *cls,
865  const struct GNUNET_HELLO_Address *address,
866  struct GNUNET_TIME_Absolute expiration)
867 {
868  struct GNUNET_TIME_Absolute *max = cls;
869 
870  *max = GNUNET_TIME_absolute_max(*max, expiration);
871  return GNUNET_OK;
872 }
873 
874 
883 {
884  struct GNUNET_TIME_Absolute ret;
885 
888  GNUNET_NO,
890  &ret);
891  return ret;
892 }
893 
894 
948 static int
950  const struct GNUNET_HELLO_Address *address,
951  struct GNUNET_TIME_Absolute expiration)
952 {
953  struct GNUNET_HELLO_ComposeUriContext *ctx = cls;
955  const char *addr;
956  char *ret;
957  char *addr_dup;
958  char *pos;
959  char tbuf[16] = "";
960  char *client_str = "_client";
961  struct tm *t;
962  time_t seconds;
963 
964  papi = ctx->plugins_find(address->transport_name);
965  if (NULL == papi)
966  {
967  /* Not an error - we might just not have the right plugin. */
968  return GNUNET_OK;
969  }
970  if (NULL == papi->address_to_string)
971  {
973  "URI conversion not implemented for plugin `%s'\n",
974  address->transport_name);
975  return GNUNET_OK;
976  }
977  addr = papi->address_to_string(papi->cls,
978  address->address,
979  address->address_length);
980  if ((NULL == addr) ||
981  (0 == strlen(addr)))
982  return GNUNET_OK;
983 
984  addr_dup = GNUNET_strdup(addr);
985  if (NULL != (pos = strstr(addr_dup, "_server")))
986  GNUNET_memcpy(pos,
987  client_str,
988  strlen(client_str)); /* Replace all server addresses with client addresses */
989 
990  seconds = expiration.abs_value_us / 1000LL / 1000LL;
991  t = gmtime(&seconds);
992 
993  GNUNET_asprintf(&ret,
994  "%s%c%s%c%s%c%s",
995  ctx->uri,
997  strftime(tbuf,
998  sizeof(tbuf),
999  "%Y%m%d%H%M%S",
1000  t) ? tbuf : "0",
1002  address->transport_name,
1004  addr_dup);
1005  GNUNET_free(addr_dup);
1006  GNUNET_free(ctx->uri);
1007  ctx->uri = ret;
1008  return GNUNET_OK;
1009 }
1010 
1011 
1019 char *
1022 {
1023  struct GNUNET_HELLO_ComposeUriContext ctx;
1024  char *pkey;
1025 
1026  ctx.plugins_find = plugins_find;
1028  GNUNET_asprintf(&ctx.uri,
1029  "%s%s",
1033  pkey);
1034  GNUNET_free(pkey);
1036  GNUNET_NO,
1038  &ctx);
1039  return ctx.uri;
1040 }
1041 
1042 
1043 /* ************************* Parse HELLO URI ********************* */
1044 
1045 
1055 static ssize_t
1057  size_t max,
1058  void *buffer)
1059 {
1060  struct GNUNET_HELLO_ParseUriContext *ctx = cls;
1061  const char *tname;
1062  const char *address;
1063  char *uri_address;
1064  const char *end;
1065  char *plugin_name;
1066  struct tm expiration_time;
1067  time_t expiration_seconds;
1068  struct GNUNET_TIME_Absolute expire;
1069  struct GNUNET_TRANSPORT_PluginFunctions *papi;
1070  void *addr;
1071  size_t addr_len;
1072  struct GNUNET_HELLO_Address haddr;
1073  ssize_t ret;
1074 
1075  if (NULL == ctx->pos)
1076  return GNUNET_SYSERR;
1077  if (GNUNET_HELLO_URI_SEP != ctx->pos[0])
1078  {
1079  ctx->ret = GNUNET_SYSERR;
1080  GNUNET_break(0);
1081  return GNUNET_SYSERR;
1082  }
1083  ctx->pos++;
1084 
1085  if (('0' == ctx->pos[0]) &&
1086  (GNUNET_HELLO_URI_SEP == ctx->pos[1]))
1087  {
1089  tname = ctx->pos + 1;
1090  }
1091  else
1092  {
1093  memset(&expiration_time, 0, sizeof(expiration_time));
1094  tname = strptime(ctx->pos,
1095  "%Y%m%d%H%M%S",
1096  &expiration_time);
1097  if (NULL == tname)
1098  {
1099  ctx->ret = GNUNET_SYSERR;
1101  _("Failed to parse HELLO message: missing expiration time\n"));
1102  GNUNET_break(0);
1103  return GNUNET_SYSERR;
1104  }
1105 
1106  expiration_seconds = mktime(&expiration_time);
1107  if (expiration_seconds == (time_t)-1)
1108  {
1110  _("Failed to parse HELLO message: invalid expiration time\n"));
1111  ctx->ret = GNUNET_SYSERR;
1112  GNUNET_break(0);
1113  return GNUNET_SYSERR;
1114  }
1115  expire.abs_value_us = expiration_seconds * 1000LL * 1000LL;
1116  }
1117  if (GNUNET_HELLO_URI_SEP != tname[0])
1118  {
1120  _("Failed to parse HELLO message: malformed\n"));
1121  ctx->ret = GNUNET_SYSERR;
1122  GNUNET_break(0);
1123  return GNUNET_SYSERR;
1124  }
1125  tname++;
1126  address = strchr(tname,
1127  (int)GNUNET_HELLO_URI_SEP);
1128  if (NULL == address)
1129  {
1131  _("Failed to parse HELLO message: missing transport plugin\n"));
1132  ctx->ret = GNUNET_SYSERR;
1133  GNUNET_break(0);
1134  return GNUNET_SYSERR;
1135  }
1136  address++;
1137  end = strchr(address, (int)GNUNET_HELLO_URI_SEP);
1138  ctx->pos = end;
1139  ctx->counter_total++;
1140  plugin_name = GNUNET_strndup(tname, address - (tname + 1));
1141  papi = ctx->plugins_find(plugin_name);
1142  if (NULL == papi)
1143  {
1144  /* Not an error - we might just not have the right plugin.
1145  * Skip this part, advance to the next one and recurse.
1146  * But only if this is not the end of string.
1147  */
1149  _("Plugin `%s' not found, skipping address\n"),
1150  plugin_name);
1151  GNUNET_free(plugin_name);
1152  return 0;
1153  }
1154  if (NULL == papi->string_to_address)
1155  {
1157  _("Plugin `%s' does not support URIs yet\n"),
1158  plugin_name);
1159  GNUNET_free(plugin_name);
1160  GNUNET_break(0);
1161  return 0;
1162  }
1163  uri_address = GNUNET_strndup(address, end - address);
1164  if (GNUNET_OK !=
1165  papi->string_to_address(papi->cls,
1166  uri_address,
1167  strlen(uri_address) + 1,
1168  &addr,
1169  &addr_len))
1170  {
1172  _("Failed to parse `%s' as an address for plugin `%s'\n"),
1173  uri_address,
1174  plugin_name);
1175  GNUNET_free(plugin_name);
1176  GNUNET_free(uri_address);
1177  return 0;
1178  }
1179  GNUNET_free(uri_address);
1180  /* address.peer is unset - not used by add_address() */
1181  haddr.address_length = addr_len;
1182  haddr.address = addr;
1183  haddr.transport_name = plugin_name;
1184  ret = GNUNET_HELLO_add_address(&haddr,
1185  expire,
1186  buffer,
1187  max);
1188  ctx->counter_added++;
1189  GNUNET_free(addr);
1190  GNUNET_free(plugin_name);
1191  return ret;
1192 }
1193 
1194 
1204 int
1207  struct GNUNET_HELLO_Message **hello,
1209 {
1210  const char *pks;
1211  const char *exc;
1212  int friend_only;
1213  struct GNUNET_HELLO_ParseUriContext ctx;
1214 
1215  if (0 == strncmp(uri,
1217  strlen(GNUNET_HELLO_URI_PREFIX)))
1218  {
1219  pks = &uri[strlen(GNUNET_HELLO_URI_PREFIX)];
1220  friend_only = GNUNET_NO;
1221  }
1222  else if (0 == strncmp(uri,
1225  {
1226  pks = &uri[strlen(GNUNET_FRIEND_HELLO_URI_PREFIX)];
1227  friend_only = GNUNET_YES;
1228  }
1229  else
1230  return GNUNET_SYSERR;
1231  exc = strchr(pks, GNUNET_HELLO_URI_SEP);
1232 
1233  if (GNUNET_OK !=
1235  (NULL == exc) ? strlen(pks) : (exc - pks),
1236  (unsigned char *)pubkey,
1237  sizeof(*pubkey)))
1238  return GNUNET_SYSERR;
1239 
1240  ctx.pos = exc;
1241  ctx.ret = GNUNET_OK;
1242  ctx.counter_total = 0;
1243  ctx.counter_added = 0;
1244  ctx.plugins_find = plugins_find;
1245  *hello = GNUNET_HELLO_create(pubkey,
1247  &ctx,
1248  friend_only);
1249 
1251  "HELLO URI contained %u addresses, added %u addresses\n",
1252  ctx.counter_total,
1253  ctx.counter_added);
1254 
1255  return ctx.ret;
1256 }
1257 
1258 
1259 /* 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:662
enum GNUNET_HELLO_AddressInfo local_info
Extended information about address.
int found
Set to GNUNET_YES if we found the address.
Definition: hello.c:348
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:949
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:142
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:671
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:1056
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:519
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:202
const struct GNUNET_HELLO_Message * h1
First HELLO we are merging.
Definition: hello.c:388
#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:1020
#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:56
int ret
Set to GNUNET_SYSERR to indicate parse errors.
Definition: hello.c:61
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:52
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:824
Context used in GNUNET_HELLO_iterate_new_addresses() to figure out which addresses are in fact &#39;new&#39;...
Definition: hello.c:541
#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:727
GNUNET_HELLO_AddressIterator it
Function to call on addresses that are indeed new.
Definition: hello.c:550
#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:704
#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:684
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:40
#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:864
#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:749
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:478
char * buf
Buffer where we copy to.
Definition: hello.c:405
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:45
const struct GNUNET_HELLO_Message * old_hello
HELLO with known addresses, addresses in this HELLO we must always ignore.
Definition: hello.c:561
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:717
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:732
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:252
#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:1205
const struct GNUNET_HELLO_Address * address
Address we are looking for.
Definition: hello.c:343
#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:711
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:71
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:422
void * it_cls
Closure for it.
Definition: hello.c:555
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:107
struct GNUNET_TIME_Absolute expiration_limit
We should ignore addresses that expire before this time.
Definition: hello.c:545
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:578
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:353
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:782
int GNUNET_HELLO_is_friend_only(const struct GNUNET_HELLO_Message *h)
Return HELLO type.
Definition: hello.c:87
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:437
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:393
#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:415
#define GNUNET_log(kind,...)
size_t max
Number of bytes allocated in buf.
Definition: hello.c:410
uint16_t GNUNET_HELLO_size(const struct GNUNET_HELLO_Message *hello)
Return the size of the given HELLO message.
Definition: hello.c:643
Context used for building our own URI.
Definition: hello.c:36
Closure for get_match_exp().
Definition: hello.c:339
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:400
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:366
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:76
Context used for comparing HELLOs in GNUNET_HELLO_equals().
Definition: hello.c:699
unsigned int counter_total
Counter.
Definition: hello.c:66
#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:882
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition: time.c:655
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:617
#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:953
const struct GNUNET_HELLO_Address * address
Address we are currently looking for.
Definition: hello.c:722
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...