GNUnet 0.28.0-dev.3-20-gf1136b0b8
 
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, 2026 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 "gnunet_time_lib.h"
38#include "platform.h"
39#include "gnunet_util_lib.h"
40#include "gnunet_signatures.h"
42#include "gnunet_protocols.h"
43
44
46
68
73{
78
83
88
89 /* followed by a 'block' */
90};
91
92
114
115
121{
126
131
136
141
146
147 /* followed by the serialized addresses of the 'block' */
148};
149
150
152
153
158{
162 struct Address *next;
163
167 struct Address *prev;
168
172 const char *uri;
173
177 size_t uri_len;
178};
179
180
185{
190
195
199 unsigned int a_length;
200
201};
202
207{
212
216 const char *address_uri;
217
221 unsigned int found;
222
226 unsigned int merged;
227};
228
233{
238
243
248
252 unsigned int a_length;
253
258
263};
264
265
266static void
267hash_addresses (const struct Address *addr_start,
268 struct GNUNET_HashCode *hash)
269{
270 struct GNUNET_HashContext *hc;
271
273
274#if HELLO_DETERMINISTIC_PID_DERIVATION
275 for (const struct Address *a = addr_start;
276 NULL != a;
277 a = a->next)
278 {
280 "Hashing over %.*s\n",
281 (int) a->uri_len,
282 a->uri);
284 a->uri,
285 a->uri_len);
286 }
287#endif
289 hash);
290
291}
292
293
304verify_hello (const struct GNUNET_HELLO_Parser *parser,
305 struct GNUNET_TIME_Absolute et,
306 const struct GNUNET_CRYPTO_EddsaSignature *sig)
307{
308 struct PilsHelloSignaturePurpose hsp = {
309 .purpose.size = htonl (sizeof (hsp)),
310 .purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_HELLO),
311 .expiration_time = GNUNET_TIME_absolute_hton (et)
312 };
313
314 hash_addresses (parser->a_head,
315 &hsp.h_addrs);
316 if (GNUNET_OK !=
318 &hsp,
319 sig,
320 &parser->pid.public_key))
321 {
323 "HELLO signature invalid, rejecting.\n");
324 return GNUNET_SYSERR;
325 }
327 return GNUNET_NO;
328 return GNUNET_OK;
329}
330
331
332static struct GNUNET_HELLO_Parser *
334{
335 struct GNUNET_HELLO_Parser *p;
336
338 p->pid = *pid;
339 return p;
340}
341
342
351
352
353const struct GNUNET_PeerIdentity *
355{
356 return &parser->pid;
357}
358
359
362 struct GNUNET_PeerIdentity *pid)
363{
365 struct Address *a;
366
368 if (NULL != pid)
369 *pid = p->pid;
370 /* check for duplicates */
371 for (a = p->a_head;
372 NULL != a;
373 a = a->next)
375 return builder;
376}
377
378
379void
381{
382 struct Address *a;
383
384 while (NULL != (a = parser->a_head))
385 {
386 GNUNET_CONTAINER_DLL_remove (parser->a_head,
387 parser->a_tail,
388 a);
389 parser->a_length--;
390 GNUNET_free (a);
391 }
392 GNUNET_assert (0 == parser->a_length);
393 GNUNET_free (parser);
394}
395
396
397void
399{
400 struct Address *a;
401
402 while (NULL != (a = builder->a_head))
403 {
405 builder->a_tail,
406 a);
407 builder->a_length--;
408 GNUNET_free (a);
409 }
410 GNUNET_assert (0 == builder->a_length);
412}
413
414
415struct GNUNET_HELLO_Parser *
417 const struct GNUNET_PeerIdentity *pid)
418{
419 uint16_t size = ntohs (msg->size);
420
421 switch (ntohs (msg->type))
422 {
424 {
425 const struct HelloUriMessage *h;
426
427 if (sizeof (struct HelloUriMessage) > size)
428 {
429 GNUNET_break_op (0);
430 return NULL;
431 }
432
433 h = (const struct HelloUriMessage *) msg;
434 size -= sizeof (*h);
436 size);
437 }
439 {
440 struct GNUNET_TIME_Absolute block_expiration;
441 struct GNUNET_HELLO_Parser *p;
442 size_t block_size;
443 void *block;
444
445 if (sizeof (struct DhtHelloMessage) > size)
446 {
447 GNUNET_break_op (0);
448 return NULL;
449 }
450
452 msg,
453 pid,
454 &block,
455 &block_size,
456 &block_expiration))
457 {
458 GNUNET_break_op (0);
459 return NULL;
460 }
461
463 block_size);
464 GNUNET_free (block);
465 return p;
466 }
467 default:
468 GNUNET_break (0);
469 return NULL;
470 }
471}
472
473
476{
477 const char *e;
478
479 if (NULL == (e = strstr (address,
480 "://")))
481 {
482 GNUNET_break_op (0);
484 "Invalid address `%s'\n",
485 address);
486 return GNUNET_SYSERR;
487 }
488 if (e == address)
489 {
490 GNUNET_break_op (0);
491 return GNUNET_SYSERR;
492 }
493 for (const char *p = address; p != e; p++)
494 if ( (! isalpha ((unsigned char) *p)) &&
495 ('+' != *p) )
496 {
497 GNUNET_break_op (0);
498 return GNUNET_SYSERR;
499 }
500 return GNUNET_OK;
501}
502
503
512int
513static
514cmp_address (void*cls, struct Address *a, struct Address *b)
515{
516 return strcmp (a->uri, b->uri);
517}
518
519
522 const char *address)
523{
524 struct Address *a;
526 size_t alen = strlen (address) + 1;
527
529 if (GNUNET_OK != ret)
530 {
532 "Failed to add address to builder\n");
533 return ret;
534 }
535 /* check for duplicates */
536 for (a = parser->a_head;
537 NULL != a;
538 a = a->next)
539 if (0 == strcmp (address,
540 a->uri))
541 return GNUNET_NO;
542 a = GNUNET_malloc (sizeof (struct Address) + alen);
543 a->uri_len = alen;
544 memcpy (&a[1],
545 address,
546 alen);
547 a->uri = (const char *) &a[1];
550 NULL,
551 parser->a_head,
552 parser->a_tail,
553 a);
554 parser->a_length++;
555 return GNUNET_OK;
556}
557
558
559struct GNUNET_HELLO_Parser *
561 size_t block_size)
562{
564 block_size,
565 GNUNET_NO);
566}
567
568
569struct GNUNET_HELLO_Parser *
571 size_t block_size,
572 int noverify)
573{
574 const struct BlockHeader *bh = block;
575 struct GNUNET_HELLO_Parser *p;
576
577 if (block_size < sizeof (*bh))
578 {
579 GNUNET_break_op (0);
580 return NULL;
581 }
582 p = parser_new (&bh->pid);
583 block += sizeof (*bh);
584 block_size -= sizeof (*bh);
585 while (block_size > 0)
586 {
587 const void *end = memchr (block,
588 '\0',
589 block_size);
590
591 if (NULL == end)
592 {
593 GNUNET_break_op (0);
595 return NULL;
596 }
597 if (GNUNET_OK !=
599 block))
600 {
601 GNUNET_break_op (0);
603 return NULL;
604 }
605 end++;
606 block_size -= (end - block);
607 block = end;
608 }
609 {
610 struct GNUNET_TIME_Absolute et;
612 if (GNUNET_YES != noverify)
613 {
615 ret = verify_hello (p,
616 et,
617 &bh->sig);
619 if (GNUNET_OK != ret)
620 {
622 return NULL;
623 }
624 }
625 p->et = et;
626 p->sig = bh->sig;
627 }
628 return p;
629}
630
631
635{
636 struct GNUNET_TIME_Absolute et;
637 if (GNUNET_MESSAGE_TYPE_HELLO_URI == ntohs (msg->type))
638 {
639 const struct HelloUriMessage *h = (const struct HelloUriMessage *) msg;
640 const struct BlockHeader *bh = (const struct BlockHeader *) &h[1];
641 if (ntohs (msg->size) <=
642 sizeof (struct HelloUriMessage) + sizeof (struct BlockHeader))
643 {
644 GNUNET_break (0);
646 }
647
649 return et;
650 }
651 else if (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO == ntohs (msg->type))
652 {
653 const struct DhtHelloMessage *dht_hello
654 = (const struct DhtHelloMessage *) msg;
655 if (ntohs (msg->size) < sizeof (struct DhtHelloMessage))
656 {
657 GNUNET_break (0);
659 }
660
662 return et;
663 }
664 else
665 GNUNET_break (0);
667}
668
669
672 const char *address)
673{
674 struct Address *a;
676 size_t alen = strlen (address) + 1;
677
679 if (GNUNET_OK != ret)
680 {
682 "Failed to add address to builder\n");
683 return ret;
684 }
685 /* check for duplicates */
686 for (a = builder->a_head;
687 NULL != a;
688 a = a->next)
689 if (0 == strcmp (address,
690 a->uri))
691 return GNUNET_NO;
692 a = GNUNET_malloc (sizeof (struct Address) + alen);
693 a->uri_len = alen;
694 memcpy (&a[1],
695 address,
696 alen);
697 a->uri = (const char *) &a[1];
700 NULL,
701 builder->a_head,
702 builder->a_tail,
703 a);
704 builder->a_length++;
705 return GNUNET_OK;
706}
707
708
709struct GNUNET_HELLO_Parser *
711{
712 const char *q;
713 const char *s1;
714 const char *s2;
716 struct GNUNET_TIME_Absolute et;
717 size_t len;
718 struct GNUNET_HELLO_Parser *p;
720
721 if (0 != strncasecmp (url,
722 "gnunet://hello/",
723 strlen ("gnunet://hello/")))
724 return NULL;
725 url += strlen ("gnunet://hello/");
726 s1 = strchr (url, '/');
727 if (NULL == s1)
728 {
729 GNUNET_break_op (0);
730 return NULL;
731 }
732 s2 = strchr (s1 + 1, '/');
733 if (NULL == s2)
734 {
735 GNUNET_break_op (0);
736 return NULL;
737 }
738 q = strchr (url, '?');
739 if (NULL == q)
740 q = url + strlen (url);
741 if (GNUNET_OK !=
743 s1 - url,
744 &pid,
745 sizeof(pid)))
746 {
747 GNUNET_break_op (0);
748 return NULL;
749 }
750 if (GNUNET_OK !=
752 s2 - (s1 + 1),
753 &sig,
754 sizeof(sig)))
755 {
756 GNUNET_break_op (0);
757 return NULL;
758 }
759 {
760 uint64_t sec;
761 char dummy = '?';
762
763 if ( (0 == sscanf (s2 + 1,
764 "%" PRIu64 "%c",
765 &sec,
766 &dummy)) ||
767 ('?' != dummy) )
768 {
769 GNUNET_break_op (0);
770 return NULL;
771 }
772 et.abs_value_us = sec;
773 }
774
775 p = parser_new (&pid);
776 p->et = et;
777 p->sig = sig;
778 len = strlen (q);
779 while (len > 0)
780 {
781 const char *eq;
782 const char *amp;
783 char *addr = NULL;
784 char *uri;
785
786 /* skip ?/& separator */
787 len--;
788 q++;
789 eq = strchr (q, '=');
790 if ( (eq == q) ||
791 (NULL == eq) )
792 {
793 GNUNET_break_op (0);
795 return NULL;
796 }
797 amp = strchr (eq, '&');
798 if (NULL == amp)
799 amp = &q[len];
801 amp - (eq + 1),
802 &addr);
803 if ( (NULL == addr) ||
804 (0 == strlen (addr)) )
805 {
806 GNUNET_free (addr);
807 GNUNET_break_op (0);
809 return NULL;
810 }
812 "%.*s://%s",
813 (int) (eq - q),
814 q,
815 addr);
816 GNUNET_free (addr);
817 if (GNUNET_OK !=
819 uri))
820 {
821 GNUNET_break_op (0);
824 return NULL;
825 }
827 /* move to next URL */
828 len -= (amp - q);
829 q = amp;
830 }
831
832 {
834
835 ret = verify_hello (p,
836 et,
837 &p->sig);
839 if (GNUNET_OK != ret)
840 {
842 return NULL;
843 }
844 }
845 return p;
846}
847
848
849char *
851{
852 char *result;
853 char *pids;
854 char *sigs;
855 const char *sep = "?";
856
857 pids = GNUNET_STRINGS_data_to_string_alloc (&parser->pid,
858 sizeof (parser->pid));
859 sigs = GNUNET_STRINGS_data_to_string_alloc (&parser->sig,
860 sizeof (parser->sig));
862 "gnunet://hello/%s/%s/%" PRIu64,
863 pids,
864 sigs,
865 parser->et.abs_value_us);
866 GNUNET_free (sigs);
867 GNUNET_free (pids);
868 for (struct Address *a = parser->a_head;
869 NULL != a;
870 a = a->next)
871 {
872 char *eou_url_encoded;
873 char *tmp;
874 int pfx_len;
875 const char *eou;
876
877 eou = strstr (a->uri,
878 "://");
879 if (NULL == eou)
880 {
881 GNUNET_break (0);
883 return NULL;
884 }
885 pfx_len = eou - a->uri;
886 eou += 3;
887 GNUNET_STRINGS_urlencode (a->uri_len - 4 - pfx_len,
888 eou,
889 &eou_url_encoded);
890 GNUNET_asprintf (&tmp,
891 "%s%s%.*s=%s",
892 result,
893 sep,
894 pfx_len,
895 a->uri,
896 eou_url_encoded);
897 GNUNET_free (eou_url_encoded);
899 result = tmp;
900 sep = "&";
901 }
902 return result;
903}
904
905
908 void *block,
909 size_t *block_size)
910{
911 struct BlockHeader bh;
912 size_t needed = sizeof (bh);
913 char *pos;
914
915 for (struct Address *a = parser->a_head;
916 NULL != a;
917 a = a->next)
918 {
919 GNUNET_assert (needed + a->uri_len > needed);
920 needed += a->uri_len;
921 }
922 if ( (NULL == block) ||
923 (needed > *block_size) )
924 {
925 *block_size = needed;
926 return GNUNET_NO;
927 }
928 bh.pid = parser->pid;
929 bh.sig = parser->sig;
931 memcpy (block,
932 &bh,
933 sizeof (bh));
934 pos = block + sizeof (bh);
935 for (struct Address *a = parser->a_head;
936 NULL != a;
937 a = a->next)
938 {
939 memcpy (pos,
940 a->uri,
941 a->uri_len);
942 pos += a->uri_len;
943 }
944 *block_size = needed;
945 return GNUNET_OK;
946}
947
948
949struct GNUNET_MQ_Envelope *
951{
952 struct GNUNET_MQ_Envelope *env;
953 struct HelloUriMessage *msg;
954 size_t blen;
955
956 if (parser->a_length > UINT16_MAX)
957 {
958 GNUNET_break (0);
959 return NULL;
960 }
961 blen = 0;
964 NULL,
965 &blen));
967 blen,
969 msg->url_counter = htons ((uint16_t) parser->a_length);
972 &msg[1],
973 &blen));
974 return env;
975}
976
977
980 const char *address)
981{
982 struct Address *a;
983
984 /* check for duplicates */
985 for (a = builder->a_head;
986 NULL != a;
987 a = a->next)
988 if (0 == strcmp (address,
989 a->uri))
990 break;
991 if (NULL == a)
992 return GNUNET_NO;
994 builder->a_tail,
995 a);
996 builder->a_length--;
997 GNUNET_free (a);
998 return GNUNET_OK;
999}
1000
1001
1002void
1005 void *uc_cls)
1006{
1007 struct Address *nxt;
1008
1009 for (struct Address *a = builder->a_head;
1010 NULL != a;
1011 a = nxt)
1012 {
1013 nxt = a->next;
1014 uc (uc_cls,
1015 NULL,
1016 a->uri);
1017 }
1018}
1019
1020
1021const struct GNUNET_PeerIdentity*
1024 void *uc_cls)
1025{
1026 struct Address *nxt;
1027
1028 if (NULL == uc)
1029 return &parser->pid;
1030 for (struct Address *a = parser->a_head;
1031 NULL != a;
1032 a = nxt)
1033 {
1034 nxt = a->next;
1035 uc (uc_cls,
1036 &parser->pid,
1037 a->uri);
1038 }
1039 return &parser->pid;
1040}
1041
1042
1045 const struct GNUNET_PeerIdentity *pid,
1046 void **block,
1047 size_t *block_size,
1048 struct GNUNET_TIME_Absolute *block_expiration)
1049{
1050 const struct DhtHelloMessage *msg
1051 = (const struct DhtHelloMessage *) hello;
1052 uint16_t len = ntohs (hello->size);
1053 struct BlockHeader *bh;
1054 struct GNUNET_HELLO_Parser *b;
1056
1057 if (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO != ntohs (hello->type))
1058 {
1059 GNUNET_break (0);
1060 return GNUNET_SYSERR;
1061 }
1062 if (len < sizeof (*msg))
1063 {
1064 GNUNET_break_op (0);
1065 return GNUNET_SYSERR;
1066 }
1067 len -= sizeof (*msg);
1068 *block_size = len + sizeof (*bh);
1069 *block = GNUNET_malloc (*block_size);
1070 bh = *block;
1071 bh->pid = *pid;
1072 bh->sig = msg->sig;
1073 bh->expiration_time = msg->expiration_time;
1074 *block_expiration = GNUNET_TIME_absolute_ntoh (msg->expiration_time);
1075 memcpy (&bh[1],
1076 &msg[1],
1077 len);
1079 *block_size);
1080 if (NULL == b)
1081 {
1082 GNUNET_break_op (0);
1083 GNUNET_free (*block);
1084 *block_size = 0;
1085 return GNUNET_SYSERR;
1086 }
1087 ret = verify_hello (b,
1088 *block_expiration,
1089 &msg->sig);
1091 if (GNUNET_SYSERR == ret)
1092 {
1093 GNUNET_free (*block);
1094 *block_size = 0;
1095 return GNUNET_SYSERR;
1096 }
1097 return ret;
1098}
1099
1100
1108char *
1110{
1111 const char *dash;
1112
1113 dash = strchr (address, '-');
1114 if (NULL == dash)
1115 return NULL;
1116 return GNUNET_strndup (address, dash - address);
1117}
1118
1119
1122 const struct GNUNET_PeerIdentity *pid,
1123 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1125 char **result)
1126{
1127 char *pids;
1128 char *sigs;
1129 const char *sep = "?";
1130
1132 sizeof (*pid));
1134 sizeof (*sig));
1136 "gnunet://hello/%s/%s/%" PRIu64,
1137 pids,
1138 sigs,
1139 expiration.abs_value_us);
1140 GNUNET_free (sigs);
1141 GNUNET_free (pids);
1142 for (struct Address *a = builder->a_head;
1143 NULL != a;
1144 a = a->next)
1145 {
1146 char *eou_url_encoded;
1147 char *tmp;
1148 int pfx_len;
1149 const char *eou;
1150
1151 eou = strstr (a->uri,
1152 "://");
1153 if (NULL == eou)
1154 {
1155 GNUNET_break (0);
1157 return GNUNET_SYSERR;
1158 }
1159 pfx_len = eou - a->uri;
1160 eou += 3;
1161 GNUNET_STRINGS_urlencode (a->uri_len - 4 - pfx_len,
1162 eou,
1163 &eou_url_encoded);
1164 GNUNET_asprintf (&tmp,
1165 "%s%s%.*s=%s",
1166 *result,
1167 sep,
1168 pfx_len,
1169 a->uri,
1170 eou_url_encoded);
1171 GNUNET_free (eou_url_encoded);
1173 *result = tmp;
1174 sep = "&";
1175 }
1176 return GNUNET_OK;
1177}
1178
1179
1180void
1182 struct GNUNET_HashCode *hash)
1183{
1184 hash_addresses (builder->a_head, hash);
1185}
1186
1187
1188struct GNUNET_MQ_Envelope*
1190 const struct GNUNET_HELLO_Builder *builder,
1191 const struct GNUNET_PeerIdentity *pid,
1192 const struct GNUNET_CRYPTO_EddsaSignature *hello_sig,
1193 struct GNUNET_TIME_Absolute expiration_time)
1194{
1195 struct GNUNET_MQ_Envelope *env;
1196 struct HelloUriMessage *msg;
1197 size_t blen;
1198
1199 if (builder->a_length > UINT16_MAX)
1200 {
1201 GNUNET_break (0);
1202 return NULL;
1203 }
1206 blen,
1208 msg->url_counter = htons ((uint16_t) builder->a_length);
1210 pid,
1211 hello_sig,
1212 expiration_time,
1213 (char*) &msg[1]);
1214 return env;
1215}
1216
1217
1218struct GNUNET_MessageHeader *
1220{
1221 struct BlockHeader *block;
1222 struct DhtHelloMessage *msg;
1223 size_t block_size;
1224
1225
1226 block_size = 0;
1229 NULL,
1230 &block_size));
1231 msg = GNUNET_malloc (sizeof (*msg)
1232 + block_size);
1233 if (GNUNET_OK !=
1235 &msg[1],
1236 &block_size))
1237 {
1238 GNUNET_free (msg);
1239 return NULL;
1240 }
1241 block = (struct BlockHeader*) &msg[1];
1242 msg->sig = block->sig;
1243 msg->expiration_time = block->expiration_time;
1244 memmove (&msg[1],
1245 (char*) block + sizeof (*block),
1246 block_size - sizeof (*block));
1247 msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO);
1248 msg->header.size = htons (sizeof (*msg)
1249 + block_size
1250 - sizeof (*block));
1251 msg->url_counter = htons ((uint16_t) parser->a_length);
1252 return &msg->header;
1253}
1254
1255
1256struct GNUNET_MessageHeader *
1258 const struct GNUNET_HELLO_Builder *builder,
1259 const struct GNUNET_PeerIdentity *pid,
1260 const struct GNUNET_CRYPTO_EddsaSignature *hello_sig,
1261 struct GNUNET_TIME_Absolute expiration_time)
1262{
1263 struct BlockHeader *block;
1264 struct DhtHelloMessage *msg;
1265 size_t block_size;
1266
1267
1269 msg = GNUNET_malloc (sizeof (*msg)
1270 + block_size);
1271 block = (struct BlockHeader*) &msg[1];
1273 pid,
1274 hello_sig,
1276 (char*) &msg[1]);
1277 msg->sig = block->sig;
1278 msg->expiration_time = block->expiration_time;
1279 memmove (&msg[1],
1280 (char*) block + sizeof (*block),
1281 block_size - sizeof (*block));
1282 msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO);
1283 msg->header.size = htons (sizeof (*msg)
1284 + block_size
1285 - sizeof (*block));
1286 msg->url_counter = htons ((uint16_t) builder->a_length);
1287 return &msg->header;
1288}
1289
1290
1291void
1293 const struct GNUNET_HELLO_Builder *builder,
1294 const struct GNUNET_PeerIdentity *pid,
1295 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1297 char *block)
1298{
1299 struct BlockHeader bh = { 0 };
1300 char *pos;
1301 struct GNUNET_TIME_Absolute et;
1302
1303 if (NULL != pid)
1304 bh.pid = *pid;
1305 if (NULL != sig)
1306 bh.sig = *sig;
1307 if (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us == expiration_time.abs_value_us)
1309 else
1310 et = expiration_time;
1312 memcpy (block,
1313 &bh,
1314 sizeof (bh));
1315 pos = block + sizeof (bh);
1316 for (struct Address *a = builder->a_head; NULL != a; a = a->next)
1317 {
1318 memcpy (pos,
1319 a->uri,
1320 a->uri_len);
1321 pos += a->uri_len;
1322 }
1323}
1324
1325
1328 const struct GNUNET_PeerIdentity *pid,
1329 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1330 struct GNUNET_TIME_Absolute validity,
1331 char **result)
1332{
1334 pid,
1335 sig,
1336 validity,
1337 result);
1338}
1339
1340
1343 const struct GNUNET_PeerIdentity *pid,
1344 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1345 char **result)
1346{
1347 struct GNUNET_TIME_Absolute et;
1348
1350
1352 pid,
1353 sig,
1354 et,
1355 result);
1356}
1357
1358
1359size_t
1361 const struct GNUNET_HELLO_Builder *builder)
1362{
1363 struct BlockHeader bh;
1364 size_t needed = sizeof (bh);
1365
1366 for (struct Address *a = builder->a_head;
1367 NULL != a;
1368 a = a->next)
1369 {
1370 GNUNET_assert (needed + a->uri_len > needed);
1371 needed += a->uri_len;
1372 }
1373 return needed;
1374}
1375
1376
1379 abuilder,
1380 const struct GNUNET_HELLO_Builder *
1381 bbuilder)
1382{
1383 bool found = false;
1384 for (struct Address *a = abuilder->a_head; NULL != a; a = a->next)
1385 {
1386 for (struct Address *b = bbuilder->a_head; NULL != b; b = b->next)
1387 {
1388 if (0 != strcmp (b->uri, a->uri))
1389 continue;
1390 found = true;
1391 break;
1392 }
1393 if (! found)
1394 return GNUNET_NO;
1395 found = false;
1396 }
1397 return GNUNET_YES;
1398}
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.
Functions related to time.
#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:380
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:1292
void GNUNET_HELLO_builder_free(struct GNUNET_HELLO_Builder *builder)
Release resources of a builder.
Definition hello-uri.c:398
char * GNUNET_HELLO_parser_to_url(const struct GNUNET_HELLO_Parser *parser)
Generate GNUnet HELLO URI from a parser.
Definition hello-uri.c:850
struct GNUNET_HELLO_Builder * GNUNET_HELLO_builder_new()
Allocate builder.
Definition hello-uri.c:344
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:1044
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_block_(const void *block, size_t block_size, int noverify)
Parse block.
Definition hello-uri.c:570
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:1003
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:907
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:1342
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:361
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:1022
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:1219
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:1121
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:950
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:1378
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:979
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:633
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:1360
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:354
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?
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_msg(const struct GNUNET_MessageHeader *msg, const struct GNUNET_PeerIdentity *pid)
Parse msg.
Definition hello-uri.c:416
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:671
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_url(const char *url)
Parse GNUnet HELLO url.
Definition hello-uri.c:710
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:1327
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:1257
struct GNUNET_HELLO_Parser * GNUNET_HELLO_parser_from_block(const void *block, size_t block_size)
Parse block.
Definition hello-uri.c:560
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:1109
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:1181
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:1189
#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:1893
char * GNUNET_STRINGS_data_to_string_alloc(const void *buf, size_t size)
Return the base32crockford encoding of the given buffer.
Definition strings.c:818
size_t GNUNET_STRINGS_urldecode(const char *data, size_t len, char **out)
url/percent encode (RFC3986).
Definition strings.c:1838
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:843
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:304
static void hash_addresses(const struct Address *addr_start, struct GNUNET_HashCode *hash)
Definition hello-uri.c:267
static struct GNUNET_HELLO_Parser * parser_new(const struct GNUNET_PeerIdentity *pid)
Definition hello-uri.c:333
static int cmp_address(void *cls, struct Address *a, struct Address *b)
Alphanumeric sorting for addresses.
Definition hello-uri.c:514
static enum GNUNET_GenericReturnValue check_address(const char *address)
Definition hello-uri.c:475
static enum GNUNET_GenericReturnValue parser_add_address(struct GNUNET_HELLO_Parser *parser, const char *address)
Definition hello-uri.c:521
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:207
unsigned int merged
Did we found at least one address to merge.
Definition hello-uri.c:226
struct GNUNET_HELLO_Builder * builder
The builder of the hello uri we merge with.
Definition hello-uri.c:211
unsigned int found
Did we found the actual address to check.
Definition hello-uri.c:221
const char * address_uri
The actual address to check, if it is already in the hello uri we merge with.
Definition hello-uri.c:216
Address of a peer.
Definition hello-uri.c:158
struct Address * next
Kept in a DLL.
Definition hello-uri.c:162
size_t uri_len
Length of uri including 0-terminator.
Definition hello-uri.c:177
struct Address * prev
Kept in a DLL.
Definition hello-uri.c:167
const char * uri
Actual URI, allocated at the end of this struct.
Definition hello-uri.c:172
Start of a 'block'.
Definition hello-uri.c:97
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the HELLO expire?
Definition hello-uri.c:111
struct GNUNET_CRYPTO_EddsaSignature sig
Signature over the block, of purpose GNUNET_SIGNATURE_PURPOSE_HELLO.
Definition hello-uri.c:106
struct GNUNET_PeerIdentity pid
Public key of the peer.
Definition hello-uri.c:101
Message used when a DHT provides its HELLO to direct neighbours.
Definition hello-uri.c:121
uint16_t reserved
Reserved.
Definition hello-uri.c:130
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the HELLO expire?
Definition hello-uri.c:145
struct GNUNET_MessageHeader header
Type must be GNUNET_MESSAGE_TYPE_DHT_P2P_HELLO.
Definition hello-uri.c:125
struct GNUNET_CRYPTO_EddsaSignature sig
Signature over the block, of purpose GNUNET_SIGNATURE_PURPOSE_HELLO.
Definition hello-uri.c:140
uint16_t url_counter
Number of URLs encoded after the end of the struct, in NBO.
Definition hello-uri.c:135
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:185
struct Address * a_tail
Tail of the addresses DLL.
Definition hello-uri.c:194
struct Address * a_head
Head of the addresses DLL.
Definition hello-uri.c:189
unsigned int a_length
Length of the a_head DLL.
Definition hello-uri.c:199
Context for parsing HELLOs.
Definition hello-uri.c:233
struct GNUNET_PeerIdentity pid
Public key of the peer.
Definition hello-uri.c:237
struct GNUNET_TIME_Absolute et
Expiration time parsed.
Definition hello-uri.c:262
struct GNUNET_CRYPTO_EddsaSignature sig
The signature (may have been provided)
Definition hello-uri.c:257
struct Address * a_tail
Tail of the addresses DLL.
Definition hello-uri.c:247
unsigned int a_length
Length of the a_head DLL.
Definition hello-uri.c:252
struct Address * a_head
Head of the addresses DLL.
Definition hello-uri.c:242
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:94
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:73
uint16_t reserved
Reserved.
Definition hello-uri.c:82
uint16_t url_counter
Number of URLs encoded after the end of the struct, in NBO.
Definition hello-uri.c:87
struct GNUNET_MessageHeader header
Type must be GNUNET_MESSAGE_TYPE_HELLO_URI.
Definition hello-uri.c:77
Message signed as part of a HELLO block/URL.
Definition hello-uri.c:51
struct GNUNET_HashCode h_addrs
Hash over all addresses.
Definition hello-uri.c:65
struct GNUNET_TIME_AbsoluteNBO expiration_time
When does the signature expire?
Definition hello-uri.c:60
struct GNUNET_CRYPTO_SignaturePurpose purpose
Purpose must be GNUNET_SIGNATURE_PURPOSE_HELLO.
Definition hello-uri.c:55