GNUnet debian-0.24.3-29-g453fda2cf
 
Loading...
Searching...
No Matches
hello-uri.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 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
37#include "platform.h"
38#include "gnunet_util_lib.h"
39#include "gnunet_signatures.h"
41#include "gnunet_protocols.h"
42
43
45
67
72{
77
82
87
88 /* followed by a 'block' */
89};
90
91
113
114
120{
125
130
135
140
145
146 /* followed by the serialized addresses of the 'block' */
147};
148
149
151
152
157{
161 struct Address *next;
162
166 struct Address *prev;
167
171 const char *uri;
172
176 size_t uri_len;
177};
178
179
184{
189
194
198 unsigned int a_length;
199
200};
201
206{
211
215 const char *address_uri;
216
220 unsigned int found;
221
225 unsigned int merged;
226};
227
232{
237
242
247
251 unsigned int a_length;
252
257
262};
263
264
265static void
266hash_addresses (const struct Address *addr_start,
267 struct GNUNET_HashCode *hash)
268{
269 struct GNUNET_HashContext *hc;
270
272
273#if HELLO_DETERMINISTIC_PID_DERIVATION
274 for (const struct Address *a = addr_start;
275 NULL != a;
276 a = a->next)
277 {
279 "Hashing over %.*s\n",
280 (int) a->uri_len,
281 a->uri);
283 a->uri,
284 a->uri_len);
285 }
286#endif
288 hash);
289
290}
291
292
303verify_hello (const struct GNUNET_HELLO_Parser *parser,
304 struct GNUNET_TIME_Absolute et,
305 const struct GNUNET_CRYPTO_EddsaSignature *sig)
306{
307 struct PilsHelloSignaturePurpose hsp = {
308 .purpose.size = htonl (sizeof (hsp)),
309 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_HELLO),
310 .expiration_time = GNUNET_TIME_absolute_hton (et)
311 };
312
313 hash_addresses (parser->a_head,
314 &hsp.h_addrs);
315 if (GNUNET_OK !=
317 &hsp,
318 sig,
319 &parser->pid.public_key))
320 {
322 "HELLO signature invalid, rejecting.\n");
323 return GNUNET_SYSERR;
324 }
326 return GNUNET_NO;
327 return GNUNET_OK;
328}
329
330
331static struct GNUNET_HELLO_Parser *
333{
334 struct GNUNET_HELLO_Parser *p;
335
337 p->pid = *pid;
338 return p;
339}
340
341
350
351
352const struct GNUNET_PeerIdentity *
354{
355 return &parser->pid;
356}
357
358
361 struct GNUNET_PeerIdentity *pid)
362{
364 struct Address *a;
365
367 if (NULL != pid)
368 *pid = p->pid;
369 /* check for duplicates */
370 for (a = p->a_head;
371 NULL != a;
372 a = a->next)
374 return builder;
375}
376
377
378void
380{
381 struct Address *a;
382
383 while (NULL != (a = parser->a_head))
384 {
385 GNUNET_CONTAINER_DLL_remove (parser->a_head,
386 parser->a_tail,
387 a);
388 parser->a_length--;
389 GNUNET_free (a);
390 }
391 GNUNET_assert (0 == parser->a_length);
392 GNUNET_free (parser);
393}
394
395
396void
398{
399 struct Address *a;
400
401 while (NULL != (a = builder->a_head))
402 {
404 builder->a_tail,
405 a);
406 builder->a_length--;
407 GNUNET_free (a);
408 }
409 GNUNET_assert (0 == builder->a_length);
411}
412
413
414struct GNUNET_HELLO_Parser *
416{
417 const struct HelloUriMessage *h;
418 uint16_t size = ntohs (msg->size);
419
420 if (GNUNET_MESSAGE_TYPE_HELLO_URI != ntohs (msg->type))
421 {
422 GNUNET_break (0);
423 return NULL;
424 }
425 if (sizeof (struct HelloUriMessage) > size)
426 {
427 GNUNET_break_op (0);
428 return NULL;
429 }
430 h = (const struct HelloUriMessage *) msg;
431 size -= sizeof (*h);
433 size);
434}
435
436
439{
440 const char *e;
441
442 if (NULL == (e = strstr (address,
443 "://")))
444 {
445 GNUNET_break_op (0);
447 "Invalid address `%s'\n",
448 address);
449 return GNUNET_SYSERR;
450 }
451 if (e == address)
452 {
453 GNUNET_break_op (0);
454 return GNUNET_SYSERR;
455 }
456 for (const char *p = address; p != e; p++)
457 if ( (! isalpha ((unsigned char) *p)) &&
458 ('+' != *p) )
459 {
460 GNUNET_break_op (0);
461 return GNUNET_SYSERR;
462 }
463 return GNUNET_OK;
464}
465
466
475int
476static
477cmp_address (void*cls, struct Address *a, struct Address *b)
478{
479 return strcmp (a->uri, b->uri);
480}
481
482
485 const char *address)
486{
487 struct Address *a;
489 size_t alen = strlen (address) + 1;
490
492 if (GNUNET_OK != ret)
493 {
495 "Failed to add address to builder\n");
496 return ret;
497 }
498 /* check for duplicates */
499 for (a = parser->a_head;
500 NULL != a;
501 a = a->next)
502 if (0 == strcmp (address,
503 a->uri))
504 return GNUNET_NO;
505 a = GNUNET_malloc (sizeof (struct Address) + alen);
506 a->uri_len = alen;
507 memcpy (&a[1],
508 address,
509 alen);
510 a->uri = (const char *) &a[1];
513 NULL,
514 parser->a_head,
515 parser->a_tail,
516 a);
517 parser->a_length++;
518 return GNUNET_OK;
519}
520
521
522struct GNUNET_HELLO_Parser *
524 size_t block_size)
525{
527 block_size,
528 GNUNET_NO);
529}
530
531
532struct GNUNET_HELLO_Parser *
534 size_t block_size,
535 int noverify)
536{
537 const struct BlockHeader *bh = block;
538 struct GNUNET_HELLO_Parser *p;
539
540 if (block_size < sizeof (*bh))
541 {
542 GNUNET_break_op (0);
543 return NULL;
544 }
545 p = parser_new (&bh->pid);
546 block += sizeof (*bh);
547 block_size -= sizeof (*bh);
548 while (block_size > 0)
549 {
550 const void *end = memchr (block,
551 '\0',
552 block_size);
553
554 if (NULL == end)
555 {
556 GNUNET_break_op (0);
558 return NULL;
559 }
560 if (GNUNET_OK !=
562 block))
563 {
564 GNUNET_break_op (0);
566 return NULL;
567 }
568 end++;
569 block_size -= (end - block);
570 block = end;
571 }
572 {
573 struct GNUNET_TIME_Absolute et;
574
576 if (GNUNET_YES != noverify)
577 {
579 ret = verify_hello (p,
580 et,
581 &bh->sig);
583 if (GNUNET_OK != ret)
584 {
586 return NULL;
587 }
588 }
590 p->sig = bh->sig;
591 }
592 return p;
593}
594
595
599{
600 struct GNUNET_TIME_Absolute et;
601 if (GNUNET_MESSAGE_TYPE_HELLO_URI == ntohs (msg->type))
602 {
603 const struct HelloUriMessage *h = (const struct HelloUriMessage *) msg;
604 const struct BlockHeader *bh = (const struct BlockHeader *) &h[1];
605
607 return et;
608 }
609 else if (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO == ntohs (msg->type))
610 {
611 const struct DhtHelloMessage *dht_hello
612 = (const struct DhtHelloMessage *) msg;
613
615 return et;
616 }
617 else
618 GNUNET_break (0);
620}
621
622
625 const char *address)
626{
627 struct Address *a;
629 size_t alen = strlen (address) + 1;
630
632 if (GNUNET_OK != ret)
633 {
635 "Failed to add address to builder\n");
636 return ret;
637 }
638 /* check for duplicates */
639 for (a = builder->a_head;
640 NULL != a;
641 a = a->next)
642 if (0 == strcmp (address,
643 a->uri))
644 return GNUNET_NO;
645 a = GNUNET_malloc (sizeof (struct Address) + alen);
646 a->uri_len = alen;
647 memcpy (&a[1],
648 address,
649 alen);
650 a->uri = (const char *) &a[1];
653 NULL,
654 builder->a_head,
655 builder->a_tail,
656 a);
657 builder->a_length++;
658 return GNUNET_OK;
659}
660
661
662struct GNUNET_HELLO_Parser *
664{
665 const char *q;
666 const char *s1;
667 const char *s2;
669 struct GNUNET_TIME_Absolute et;
670 size_t len;
671 struct GNUNET_HELLO_Parser *p;
673
674 if (0 != strncasecmp (url,
675 "gnunet://hello/",
676 strlen ("gnunet://hello/")))
677 return NULL;
678 url += strlen ("gnunet://hello/");
679 s1 = strchr (url, '/');
680 if (NULL == s1)
681 {
682 GNUNET_break_op (0);
683 return NULL;
684 }
685 s2 = strchr (s1 + 1, '/');
686 if (NULL == s1)
687 {
688 GNUNET_break_op (0);
689 return NULL;
690 }
691 q = strchr (url, '?');
692 if (NULL == q)
693 q = url + strlen (url);
694 if (GNUNET_OK !=
696 s1 - url,
697 &pid,
698 sizeof(pid)))
699 {
700 GNUNET_break_op (0);
701 return NULL;
702 }
703 if (GNUNET_OK !=
705 s2 - (s1 + 1),
706 &sig,
707 sizeof(sig)))
708 {
709 GNUNET_break_op (0);
710 return NULL;
711 }
712 {
713 uint64_t sec;
714 char dummy = '?';
715
716 if ( (0 == sscanf (s2 + 1,
717 "%" PRIu64 "%c",
718 &sec,
719 &dummy)) ||
720 ('?' != dummy) )
721 {
722 GNUNET_break_op (0);
723 return NULL;
724 }
725 et.abs_value_us = sec;
726 }
727
728 p = parser_new (&pid);
729 p->et = et;
730 p->sig = sig;
731 len = strlen (q);
732 while (len > 0)
733 {
734 const char *eq;
735 const char *amp;
736 char *addr = NULL;
737 char *uri;
738
739 /* skip ?/& separator */
740 len--;
741 q++;
742 eq = strchr (q, '=');
743 if ( (eq == q) ||
744 (NULL == eq) )
745 {
746 GNUNET_break_op (0);
748 return NULL;
749 }
750 amp = strchr (eq, '&');
751 if (NULL == amp)
752 amp = &q[len];
754 amp - (eq + 1),
755 &addr);
756 if ( (NULL == addr) ||
757 (0 == strlen (addr)) )
758 {
759 GNUNET_free (addr);
760 GNUNET_break_op (0);
762 return NULL;
763 }
765 "%.*s://%s",
766 (int) (eq - q),
767 q,
768 addr);
769 GNUNET_free (addr);
770 if (GNUNET_OK !=
772 uri))
773 {
774 GNUNET_break_op (0);
777 return NULL;
778 }
780 /* move to next URL */
781 len -= (amp - q);
782 q = amp;
783 }
784
785 {
787
788 ret = verify_hello (p,
789 et,
790 &p->sig);
792 if (GNUNET_OK != ret)
793 {
795 return NULL;
796 }
797 }
798 return p;
799}
800
801
802char *
804{
805 char *result;
806 char *pids;
807 char *sigs;
808 const char *sep = "?";
809
810 pids = GNUNET_STRINGS_data_to_string_alloc (&parser->pid,
811 sizeof (parser->pid));
812 sigs = GNUNET_STRINGS_data_to_string_alloc (&parser->sig,
813 sizeof (parser->sig));
815 "gnunet://hello/%s/%s/%" PRIu64,
816 pids,
817 sigs,
818 parser->et.abs_value_us);
819 GNUNET_free (sigs);
820 GNUNET_free (pids);
821 for (struct Address *a = parser->a_head;
822 NULL != a;
823 a = a->next)
824 {
825 char *ue;
826 char *tmp;
827 int pfx_len;
828 const char *eou;
829
830 eou = strstr (a->uri,
831 "://");
832 if (NULL == eou)
833 {
834 GNUNET_break (0);
836 return NULL;
837 }
838 pfx_len = eou - a->uri;
839 eou += 3;
840 GNUNET_STRINGS_urlencode (a->uri_len - 4 - pfx_len,
841 eou,
842 &ue);
843 GNUNET_asprintf (&tmp,
844 "%s%s%.*s=%s",
845 result,
846 sep,
847 pfx_len,
848 a->uri,
849 ue);
850 GNUNET_free (ue);
852 result = tmp;
853 sep = "&";
854 }
855 return result;
856}
857
858
861 void *block,
862 size_t *block_size)
863{
864 struct BlockHeader bh;
865 size_t needed = sizeof (bh);
866 char *pos;
867
868 for (struct Address *a = parser->a_head;
869 NULL != a;
870 a = a->next)
871 {
872 GNUNET_assert (needed + a->uri_len > needed);
873 needed += a->uri_len;
874 }
875 if ( (NULL == block) ||
876 (needed < *block_size) )
877 {
878 *block_size = needed;
879 return GNUNET_NO;
880 }
881 bh.pid = parser->pid;
882 bh.sig = parser->sig;
884 memcpy (block,
885 &bh,
886 sizeof (bh));
887 pos = block + sizeof (bh);
888 for (struct Address *a = parser->a_head;
889 NULL != a;
890 a = a->next)
891 {
892 memcpy (pos,
893 a->uri,
894 a->uri_len);
895 pos += a->uri_len;
896 }
897 *block_size = needed;
898 return GNUNET_OK;
899}
900
901
902struct GNUNET_MQ_Envelope *
904{
905 struct GNUNET_MQ_Envelope *env;
906 struct HelloUriMessage *msg;
907 size_t blen;
908
909 if (parser->a_length > UINT16_MAX)
910 {
911 GNUNET_break (0);
912 return NULL;
913 }
914 blen = 0;
917 NULL,
918 &blen));
920 blen,
922 msg->url_counter = htons ((uint16_t) parser->a_length);
925 &msg[1],
926 &blen));
927 return env;
928}
929
930
933 const char *address)
934{
935 struct Address *a;
936
937 /* check for duplicates */
938 for (a = builder->a_head;
939 NULL != a;
940 a = a->next)
941 if (0 == strcmp (address,
942 a->uri))
943 break;
944 if (NULL == a)
945 return GNUNET_NO;
947 builder->a_tail,
948 a);
949 builder->a_length--;
950 GNUNET_free (a);
951 return GNUNET_OK;
952}
953
954
955void
958 void *uc_cls)
959{
960 struct Address *nxt;
961
962 for (struct Address *a = builder->a_head;
963 NULL != a;
964 a = nxt)
965 {
966 nxt = a->next;
967 uc (uc_cls,
968 NULL,
969 a->uri);
970 }
971}
972
973
974const struct GNUNET_PeerIdentity*
977 void *uc_cls)
978{
979 struct Address *nxt;
980
981 if (NULL == uc)
982 return &parser->pid;
983 for (struct Address *a = parser->a_head;
984 NULL != a;
985 a = nxt)
986 {
987 nxt = a->next;
988 uc (uc_cls,
989 &parser->pid,
990 a->uri);
991 }
992 return &parser->pid;
993}
994
995
998 const struct GNUNET_PeerIdentity *pid,
999 void **block,
1000 size_t *block_size,
1001 struct GNUNET_TIME_Absolute *block_expiration)
1002{
1003 const struct DhtHelloMessage *msg
1004 = (const struct DhtHelloMessage *) hello;
1005 uint16_t len = ntohs (hello->size);
1006 struct BlockHeader *bh;
1007 struct GNUNET_HELLO_Parser *b;
1009
1010 if (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO != ntohs (hello->type))
1011 {
1012 GNUNET_break (0);
1013 return GNUNET_SYSERR;
1014 }
1015 if (len < sizeof (*msg))
1016 {
1017 GNUNET_break_op (0);
1018 return GNUNET_SYSERR;
1019 }
1020 len -= sizeof (*msg);
1021 *block_size = len + sizeof (*bh);
1022 *block = GNUNET_malloc (*block_size);
1023 bh = *block;
1024 bh->pid = *pid;
1025 bh->sig = msg->sig;
1026 bh->expiration_time = msg->expiration_time;
1027 *block_expiration = GNUNET_TIME_absolute_ntoh (msg->expiration_time);
1028 memcpy (&bh[1],
1029 &msg[1],
1030 len);
1032 *block_size);
1033 if (NULL == b)
1034 {
1035 GNUNET_break_op (0);
1036 GNUNET_free (*block);
1037 *block_size = 0;
1038 return GNUNET_SYSERR;
1039 }
1040 ret = verify_hello (b,
1041 *block_expiration,
1042 &msg->sig);
1044 if (GNUNET_SYSERR == ret)
1045 {
1046 GNUNET_free (*block);
1047 *block_size = 0;
1048 return GNUNET_SYSERR;
1049 }
1050 return ret;
1051}
1052
1053
1061char *
1063{
1064 const char *dash;
1065
1066 dash = strchr (address, '-');
1067 if (NULL == dash)
1068 return NULL;
1069 return GNUNET_strndup (address, dash - address);
1070}
1071
1072
1075 const struct GNUNET_PeerIdentity *pid,
1076 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1078 char **result)
1079{
1080 char *pids;
1081 char *sigs;
1082 const char *sep = "?";
1083
1085 sizeof (*pid));
1087 sizeof (*sig));
1089 "gnunet://hello/%s/%s/%" PRIu64,
1090 pids,
1091 sigs,
1092 expiration.abs_value_us);
1093 GNUNET_free (sigs);
1094 GNUNET_free (pids);
1095 for (struct Address *a = builder->a_head;
1096 NULL != a;
1097 a = a->next)
1098 {
1099 char *ue;
1100 char *tmp;
1101 int pfx_len;
1102 const char *eou;
1103
1104 eou = strstr (a->uri,
1105 "://");
1106 if (NULL == eou)
1107 {
1108 GNUNET_break (0);
1110 return GNUNET_SYSERR;
1111 }
1112 pfx_len = eou - a->uri;
1113 eou += 3;
1114 GNUNET_STRINGS_urlencode (a->uri_len - 4 - pfx_len,
1115 eou,
1116 &ue);
1117 GNUNET_asprintf (&tmp,
1118 "%s%s%.*s=%s",
1119 *result,
1120 sep,
1121 pfx_len,
1122 a->uri,
1123 ue);
1124 GNUNET_free (ue);
1126 *result = tmp;
1127 sep = "&";
1128 }
1129 return GNUNET_OK;
1130}
1131
1132
1133void
1135 struct GNUNET_HashCode *hash)
1136{
1137 hash_addresses (builder->a_head, hash);
1138}
1139
1140
1141struct GNUNET_MQ_Envelope*
1143 const struct GNUNET_HELLO_Builder *builder,
1144 const struct GNUNET_PeerIdentity *pid,
1145 const struct GNUNET_CRYPTO_EddsaSignature *hello_sig,
1146 struct GNUNET_TIME_Absolute expiration_time)
1147{
1148 struct GNUNET_MQ_Envelope *env;
1149 struct HelloUriMessage *msg;
1150 size_t blen;
1151
1152 if (builder->a_length > UINT16_MAX)
1153 {
1154 GNUNET_break (0);
1155 return NULL;
1156 }
1159 blen,
1161 msg->url_counter = htons ((uint16_t) builder->a_length);
1163 pid,
1164 hello_sig,
1165 expiration_time,
1166 (char*) &msg[1]);
1167 return env;
1168}
1169
1170
1171struct GNUNET_MessageHeader *
1173{
1174 struct BlockHeader *block;
1175 struct DhtHelloMessage *msg;
1176 size_t block_size;
1177
1178
1179 block_size = 0;
1182 NULL,
1183 &block_size));
1184 msg = GNUNET_malloc (sizeof (*msg)
1185 + block_size);
1186 if (GNUNET_OK !=
1188 &msg[1],
1189 &block_size))
1190 {
1191 return NULL;
1192 }
1193 block = (struct BlockHeader*) &msg[1];
1194 msg->sig = block->sig;
1195 msg->expiration_time = block->expiration_time;
1196 memmove (&msg[1],
1197 (char*) block + sizeof (*block),
1198 block_size - sizeof (*block));
1199 msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO);
1200 msg->header.size = htons (sizeof (*msg)
1201 + block_size
1202 - sizeof (*block));
1203 msg->url_counter = htons ((uint16_t) parser->a_length);
1204 return &msg->header;
1205}
1206
1207
1208struct GNUNET_MessageHeader *
1210 const struct GNUNET_HELLO_Builder *builder,
1211 const struct GNUNET_PeerIdentity *pid,
1212 const struct GNUNET_CRYPTO_EddsaSignature *hello_sig,
1213 struct GNUNET_TIME_Absolute expiration_time)
1214{
1215 struct BlockHeader *block;
1216 struct DhtHelloMessage *msg;
1217 size_t block_size;
1218
1219
1221 msg = GNUNET_malloc (sizeof (*msg)
1222 + block_size);
1223 block = (struct BlockHeader*) &msg[1];
1225 pid,
1226 hello_sig,
1228 (char*) &msg[1]);
1229 msg->sig = block->sig;
1230 msg->expiration_time = block->expiration_time;
1231 memmove (&msg[1],
1232 (char*) block + sizeof (*block),
1233 block_size - sizeof (*block));
1234 msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO);
1235 msg->header.size = htons (sizeof (*msg)
1236 + block_size
1237 - sizeof (*block));
1238 msg->url_counter = htons ((uint16_t) builder->a_length);
1239 return &msg->header;
1240}
1241
1242
1243void
1245 const struct GNUNET_HELLO_Builder *builder,
1246 const struct GNUNET_PeerIdentity *pid,
1247 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1249 char *block)
1250{
1251 struct BlockHeader bh = { 0 };
1252 char *pos;
1253 struct GNUNET_TIME_Absolute et;
1254
1255 if (NULL != pid)
1256 bh.pid = *pid;
1257 if (NULL != sig)
1258 bh.sig = *sig;
1259 if (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us == expiration_time.abs_value_us)
1261 else
1262 et = expiration_time;
1264 memcpy (block,
1265 &bh,
1266 sizeof (bh));
1267 pos = block + sizeof (bh);
1268 for (struct Address *a = builder->a_head; NULL != a; a = a->next)
1269 {
1270 memcpy (pos,
1271 a->uri,
1272 a->uri_len);
1273 pos += a->uri_len;
1274 }
1275}
1276
1277
1280 const struct GNUNET_PeerIdentity *pid,
1281 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1282 struct GNUNET_TIME_Absolute validity,
1283 char **result)
1284{
1286 pid,
1287 sig,
1288 validity,
1289 result);
1290}
1291
1292
1295 const struct GNUNET_PeerIdentity *pid,
1296 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1297 char **result)
1298{
1299 struct GNUNET_TIME_Absolute et;
1300
1302
1304 pid,
1305 sig,
1306 et,
1307 result);
1308}
1309
1310
1311size_t
1313 const struct GNUNET_HELLO_Builder *builder)
1314{
1315 struct BlockHeader bh;
1316 size_t needed = sizeof (bh);
1317
1318 for (struct Address *a = builder->a_head;
1319 NULL != a;
1320 a = a->next)
1321 {
1322 GNUNET_assert (needed + a->uri_len > needed);
1323 needed += a->uri_len;
1324 }
1325 return needed;
1326}
1327
1328
1331 abuilder,
1332 const struct GNUNET_HELLO_Builder *
1333 bbuilder)
1334{
1335 bool found = false;
1336 for (struct Address *a = abuilder->a_head; NULL != a; a = a->next)
1337 {
1338 for (struct Address *b = bbuilder->a_head; NULL != b; b = b->next)
1339 {
1340 if (0 != strcmp (b->uri, a->uri))
1341 continue;
1342 found = true;
1343 break;
1344 }
1345 if (!found)
1346 return GNUNET_NO;
1347 found = false;
1348 }
1349 return GNUNET_YES;
1350}
struct GNUNET_MessageHeader * msg
Definition 005.c:2
struct GNUNET_MQ_Envelope * env
Definition 005.c:1
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition gnunet-arm.c:98
static int ret
Final status code.
Definition gnunet-arm.c:93
static int end
Set if we are to shutdown all services (including ARM).
Definition gnunet-arm.c:33
static char * address
GNS address for this phone.
static struct HostSet * builder
NULL if we are not currently iterating over peer information.
static struct GNUNET_TIME_Relative expiration
User supplied expiration value.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
static struct GNUNET_FS_Uri * uri
Value of URI provided on command-line (when not publishing a file but just creating UBlocks to refer ...
static int result
Global testing status.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static struct GNUNET_PeerIdentity pid
Identity of the peer we transmit to / connect to.
static struct GNUNET_FS_UnindexContext * uc
static struct GNUNET_OS_Process * p
Helper process we started.
Definition gnunet-uri.c:38
Helper library for handling HELLO URIs.
Constants for network protocols.
#define GNUNET_SIGNATURE_PURPOSE_HELLO
Signature by which a peer affirms its address.
#define GNUNET_CRYPTO_eddsa_verify(purp, ps, sig, pub)
Verify EdDSA signature.
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
void GNUNET_HELLO_parser_free(struct GNUNET_HELLO_Parser *parser)
Release resources of a builder.
Definition hello-uri.c:379
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg)
Parse msg.
Definition hello-uri.c:415
void GNUNET_HELLO_builder_to_block(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig, struct GNUNET_TIME_Absolute expiration_time, char *block)
Generate DHT block from a builder.
Definition hello-uri.c:1244
void GNUNET_HELLO_builder_free(struct GNUNET_HELLO_Builder *builder)
Release resources of a builder.
Definition hello-uri.c:397
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
Definition hello-uri.c:803
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_new()
Allocate builder.
Definition hello-uri.c:343
enum GNUNET_GenericReturnValue GNUNET_HELLO_dht_msg_to_block(const struct GNUNET_MessageHeader *hello, const struct GNUNET_PeerIdentity *pid, void **block, size_t *block_size, struct GNUNET_TIME_Absolute *block_expiration)
Convert a DHT hello message to a HELLO block.
Definition hello-uri.c:997
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_block_(const void *block, size_t block_size, int noverify)
Parse block.
Definition hello-uri.c:533
void GNUNET_HELLO_builder_iterate(const struct GNUNET_HELLO_Builder *builder, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a builder.
Definition hello-uri.c:956
enum GNUNET_GenericReturnValue GNUNET_HELLO_parser_to_block(const struct GNUNET_HELLO_Parser *parser, void *block, size_t *block_size)
Generate DHT block from a parser.
Definition hello-uri.c:860
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_to_url(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig, char **result)
Generate GNUnet HELLO URI from a builder.
Definition hello-uri.c:1294
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_from_parser(const struct GNUNET_HELLO_Parser *p, struct GNUNET_PeerIdentity *pid)
Allocate builder from parser.
Definition hello-uri.c:360
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_iterate(const struct GNUNET_HELLO_Parser *parser, GNUNET_HELLO_UriCallback uc, void *uc_cls)
Iterate over URIs in a parser.
Definition hello-uri.c:975
struct GNUNET_MessageHeader * GNUNET_HELLO_parser_to_dht_hello_msg(const struct GNUNET_HELLO_Parser *parser)
Generate DHT HELLO message from a parser.
Definition hello-uri.c:1172
enum GNUNET_GenericReturnValue GNUNET_HELLO_build_url(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig, struct GNUNET_TIME_Absolute expiration, char **result)
Definition hello-uri.c:1074
struct GNUNET_MQ_Envelope * GNUNET_HELLO_parser_to_env(const struct GNUNET_HELLO_Parser *parser)
Generate envelope with GNUnet HELLO message (including peer ID) from a parser.
Definition hello-uri.c:903
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_address_list_cmp(const struct GNUNET_HELLO_Builder *abuilder, const struct GNUNET_HELLO_Builder *bbuilder)
Compare address lists of two builders.
Definition hello-uri.c:1330
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_del_address(struct GNUNET_HELLO_Builder *builder, const char *address)
Remove individual address from the builder.
Definition hello-uri.c:932
struct GNUNET_TIME_Absolute GNUNET_HELLO_get_expiration_time_from_msg(const struct GNUNET_MessageHeader *msg)
Get the expiration time for this HELLO.
Definition hello-uri.c:597
size_t GNUNET_HELLO_get_builder_to_block_size(const struct GNUNET_HELLO_Builder *builder)
Get projected block size for builder.
Definition hello-uri.c:1312
const struct GNUNET_PeerIdentity * GNUNET_HELLO_parser_get_id(const struct GNUNET_HELLO_Parser *parser)
Get the PeerIdentity for this builder.
Definition hello-uri.c:353
void(* GNUNET_HELLO_UriCallback)(void *cls, const struct GNUNET_PeerIdentity *pid, const char *uri)
Callback function used to extract URIs from a builder.
#define GNUNET_HELLO_ADDRESS_EXPIRATION
For how long are HELLO signatures valid?
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_add_address(struct GNUNET_HELLO_Builder *builder, const char *address)
Add individual address to the builder.
Definition hello-uri.c:624
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_url(const char *url)
Parse GNUnet HELLO url.
Definition hello-uri.c:663
enum GNUNET_GenericReturnValue GNUNET_HELLO_builder_to_url2(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *sig, struct GNUNET_TIME_Absolute validity, char **result)
Generate GNUnet HELLO URI from a builder.
Definition hello-uri.c:1279
struct GNUNET_MessageHeader * GNUNET_HELLO_builder_to_dht_hello_msg(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *hello_sig, struct GNUNET_TIME_Absolute expiration_time)
Generate DHT HELLO message (without peer ID) from a builder.
Definition hello-uri.c:1209
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_block(const void *block, size_t block_size)
Parse block.
Definition hello-uri.c:523
char * GNUNET_HELLO_address_to_prefix(const char *address)
Given an address as a string, extract the prefix that identifies the communicator offering transmissi...
Definition hello-uri.c:1062
void GNUNET_HELLO_builder_hash_addresses(const struct GNUNET_HELLO_Builder *builder, struct GNUNET_HashCode *hash)
Compute hash over addresses in builder.
Definition hello-uri.c:1134
struct GNUNET_MQ_Envelope * GNUNET_HELLO_builder_to_env(const struct GNUNET_HELLO_Builder *builder, const struct GNUNET_PeerIdentity *pid, const struct GNUNET_CRYPTO_EddsaSignature *hello_sig, struct GNUNET_TIME_Absolute expiration_time)
Generate envelope with GNUnet HELLO message (including peer ID) from a builder.
Definition hello-uri.c:1142
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_log(kind,...)
void GNUNET_CRYPTO_hash_context_read(struct GNUNET_HashContext *hc, const void *buf, size_t size)
Add data to be hashed.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
void GNUNET_CRYPTO_hash_context_finish(struct GNUNET_HashContext *hc, struct GNUNET_HashCode *r_hash)
Finish the hash computation.
#define GNUNET_CONTAINER_DLL_insert_sorted(TYPE, comparator, comparator_cls, head, tail, element)
Insertion sort of element into DLL from head to tail sorted by comparator.
GNUNET_GenericReturnValue
Named constants for return values.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_HashContext * GNUNET_CRYPTO_hash_context_start(void)
Start incremental hashing operation.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define GNUNET_strndup(a, length)
Wrapper around GNUNET_xstrndup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_MQ_msg_extra(mvar, esize, type)
Allocate an envelope, with extra space allocated after the space needed by the message struct.
#define GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO
HELLO advertising a neighbours addresses.
#define GNUNET_MESSAGE_TYPE_HELLO_URI
Latest HELLO messages used for communicating peer addresses.
size_t GNUNET_STRINGS_urlencode(size_t len, const char data[static len], char **out)
url/percent encode (RFC3986).
Definition strings.c:1882
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition strings.c:807
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition strings.c:1827
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition strings.c:832
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:741
struct GNUNET_TIME_Absolute GNUNET_TIME_relative_to_absolute(struct GNUNET_TIME_Relative rel)
Convert relative time to an absolute time in the future.
Definition time.c:316
#define GNUNET_TIME_UNIT_ZERO_ABS
Absolute time zero.
struct GNUNET_TIME_AbsoluteNBO GNUNET_TIME_absolute_hton(struct GNUNET_TIME_Absolute a)
Convert absolute time to network byte order.
Definition time.c:640
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition time.c:671
static enum GNUNET_GenericReturnValue verify_hello(const struct GNUNET_HELLO_Parser *parser, struct GNUNET_TIME_Absolute et, const struct GNUNET_CRYPTO_EddsaSignature *sig)
Verify HELLO signature.
Definition hello-uri.c:303
static void hash_addresses(const struct Address *addr_start, struct GNUNET_HashCode *hash)
Definition hello-uri.c:266
static struct GNUNET_HELLO_Parser * parser_new(const struct GNUNET_PeerIdentity *pid)
Definition hello-uri.c:332
static int cmp_address(void *cls, struct Address *a, struct Address *b)
Alphanumeric sorting for addresses.
Definition hello-uri.c:477
static enum GNUNET_GenericReturnValue check_address(const char *address)
Definition hello-uri.c:438
static enum GNUNET_GenericReturnValue parser_add_address(struct GNUNET_HELLO_Parser *parser, const char *address)
Definition hello-uri.c:484
static unsigned int size
Size of the "table".
Definition peer.c:68
Struct to wrap data to do the merge of to hello uris.
Definition hello-uri.c:206
unsigned int merged
Did we found at least one address to merge.
Definition hello-uri.c:225
struct GNUNET_HELLO_Builder * builder
The builder of the hello uri we merge with.
Definition hello-uri.c:210
unsigned int found
Did we found the actual address to check.
Definition hello-uri.c:220
const char * address_uri
The actual address to check, if it is already in the hello uri we merge with.
Definition hello-uri.c:215
Address of a peer.
Definition hello-uri.c:157
struct Address * next
Kept in a DLL.
Definition hello-uri.c:161
size_t uri_len
Length of uri including 0-terminator.
Definition hello-uri.c:176
struct Address * prev
Kept in a DLL.
Definition hello-uri.c:166
const char * uri
Actual URI, allocated at the end of this struct.
Definition hello-uri.c:171
Start of a 'block'.
Definition hello-uri.c:96
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the HELLO expire?
Definition hello-uri.c:110
struct GNUNET_CRYPTO_EddsaSignature sig
Signature over the block, of purpose GNUNET_SIGNATURE_PURPOSE_HELLO.
Definition hello-uri.c:105
struct GNUNET_PeerIdentity pid
Public key of the peer.
Definition hello-uri.c:100
Message used when a DHT provides its HELLO to direct neighbours.
Definition hello-uri.c:120
uint16_t reserved
Reserved.
Definition hello-uri.c:129
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the HELLO expire?
Definition hello-uri.c:144
struct GNUNET_MessageHeader header
Type must be GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO.
Definition hello-uri.c:124
struct GNUNET_CRYPTO_EddsaSignature sig
Signature over the block, of purpose GNUNET_SIGNATURE_PURPOSE_HELLO.
Definition hello-uri.c:139
uint16_t url_counter
Number of URLs encoded after the end of the struct, in NBO.
Definition hello-uri.c:134
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
an ECC signature using EdDSA.
Context for building (or parsing) HELLO URIs.
Definition hello-uri.c:184
struct Address * a_tail
Tail of the addresses DLL.
Definition hello-uri.c:193
struct Address * a_head
Head of the addresses DLL.
Definition hello-uri.c:188
unsigned int a_length
Length of the a_head DLL.
Definition hello-uri.c:198
Context for parsing HELLOs.
Definition hello-uri.c:232
struct GNUNET_PeerIdentity pid
Public key of the peer.
Definition hello-uri.c:236
struct GNUNET_TIME_Absolute et
Expiration time parsed.
Definition hello-uri.c:261
struct GNUNET_CRYPTO_EddsaSignature sig
The signature (may have been provided)
Definition hello-uri.c:256
struct Address * a_tail
Tail of the addresses DLL.
Definition hello-uri.c:246
unsigned int a_length
Length of the a_head DLL.
Definition hello-uri.c:251
struct Address * a_head
Head of the addresses DLL.
Definition hello-uri.c:241
A 512-bit hashcode.
Header for all communications.
pid_t pid
PID of the process.
Definition os_priority.c:50
The identity of the host (wraps the signing key of the peer).
Time for absolute time used by GNUnet, in microseconds and in network byte order.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Message used when gossiping HELLOs between peers.
Definition hello-uri.c:72
uint16_t reserved
Reserved.
Definition hello-uri.c:81
uint16_t url_counter
Number of URLs encoded after the end of the struct, in NBO.
Definition hello-uri.c:86
struct GNUNET_MessageHeader header
Type must be GNUNET_MESSAGE_TYPE_HELLO_URI.
Definition hello-uri.c:76
Message signed as part of a HELLO block/URL.
Definition hello-uri.c:50
struct GNUNET_HashCode h_addrs
Hash over all addresses.
Definition hello-uri.c:64
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition hello-uri.c:59
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_HELLO.
Definition hello-uri.c:54