GNUnet 0.26.2-32-gd298f7855
 
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 *eou_url_encoded;
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 &eou_url_encoded);
843 GNUNET_asprintf (&tmp,
844 "%s%s%.*s=%s",
845 result,
846 sep,
847 pfx_len,
848 a->uri,
849 eou_url_encoded);
850 GNUNET_free (eou_url_encoded);
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 *eou_url_encoded;
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 &eou_url_encoded);
1117 GNUNET_asprintf (&tmp,
1118 "%s%s%.*s=%s",
1119 *result,
1120 sep,
1121 pfx_len,
1122 a->uri,
1123 eou_url_encoded);
1124 GNUNET_free (eou_url_encoded);
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_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:1887
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition strings.c:812
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition strings.c:1832
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:837
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_ntoh(struct GNUNET_TIME_AbsoluteNBO a)
Convert absolute time from network byte order.
Definition time.c:737
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:636
bool GNUNET_TIME_absolute_is_past(struct GNUNET_TIME_Absolute abs)
Test if abs is truly in the past (excluding now).
Definition time.c:667
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
an ECC signature using EdDSA.
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 (!...
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.
The identity of the host (wraps the signing key of the peer).
pid_t pid
PID of the process.
Definition os_process.c:89
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_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_HELLO.
Definition hello-uri.c:54