aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authort3sserakt <t3ss@posteo.de>2023-08-03 10:48:39 +0200
committert3sserakt <t3ss@posteo.de>2023-08-03 10:48:39 +0200
commit0f8b71280614e9a69d7703d88cc35108e6cec052 (patch)
tree67ea484d6dba49b27e684a050dfa362a911bd035
parent39bcd0fd01fc552af43b7bd945ddba510172ad36 (diff)
downloadgnunet-0f8b71280614e9a69d7703d88cc35108e6cec052.tar.gz
gnunet-0f8b71280614e9a69d7703d88cc35108e6cec052.zip
NEWS: Added api to store hellos with peerstore service.
-rw-r--r--src/hello/hello-uri.c121
-rw-r--r--src/include/gnunet_hello_uri_lib.h17
-rw-r--r--src/include/gnunet_peerstore_service.h31
-rw-r--r--src/peerstore/peerstore_api.c238
4 files changed, 407 insertions, 0 deletions
diff --git a/src/hello/hello-uri.c b/src/hello/hello-uri.c
index 8f8f699e9..9e8d6909d 100644
--- a/src/hello/hello-uri.c
+++ b/src/hello/hello-uri.c
@@ -204,6 +204,32 @@ struct GNUNET_HELLO_Builder
204 204
205}; 205};
206 206
207/**
208 * Struct to wrap data to do the merge of to hello uris.
209 */
210struct AddressUriMergeResult
211{
212 /**
213 * The builder of the hello uri we merge with.
214 */
215 struct GNUNET_HELLO_Builder *builder;
216
217 /**
218 * The actual address to check, if it is allready in the hello uri we merge with.
219 */
220 const char *address_uri;
221
222 /**
223 * Did we found the actual address to check.
224 */
225 unsigned int found;
226
227 /**
228 * Did we found at least one address to merge.
229 */
230 unsigned int merged;
231};
232
207 233
208/** 234/**
209 * Compute @a hash over addresses in @a builder. 235 * Compute @a hash over addresses in @a builder.
@@ -315,6 +341,13 @@ GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid)
315} 341}
316 342
317 343
344struct GNUNET_PeerIdentity *
345GNUNET_HELLO_builder_get_id (struct GNUNET_HELLO_Builder *builder)
346{
347 return &builder->pid;
348}
349
350
318void 351void
319GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder) 352GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder)
320{ 353{
@@ -412,6 +445,94 @@ GNUNET_HELLO_builder_from_block (const void *block,
412} 445}
413 446
414 447
448static void
449merge_hellos2 (void *cls, const char *address_uri2)
450{
451 struct AddressUriMergeResult *aumr = cls;
452 const char *address_uri1 = aumr->address_uri;
453
454 if (GNUNET_NO == aumr->found && 0 != GNUNET_memcmp (address_uri1,
455 address_uri2))
456 {
457 aumr->found = GNUNET_YES;
458 }
459}
460
461
462static void
463merge_hellos1 (void *cls, const char *address_uri1)
464{
465 struct AddressUriMergeResult *aumr = cls;
466 struct GNUNET_HELLO_Builder *builder2 = aumr->builder;
467 struct GNUNET_PeerIdentity *peer2 = GNUNET_HELLO_builder_get_id (builder2);
468
469 aumr->address_uri = address_uri1;
470 GNUNET_HELLO_builder_iterate (builder2, peer2, &merge_hellos2, aumr);
471 if (GNUNET_YES == aumr->found)
472 {
473 GNUNET_HELLO_builder_add_address (builder2, address_uri1);
474 aumr->merged = GNUNET_YES;
475 }
476 aumr->found = GNUNET_NO;
477}
478
479
480struct GNUNET_MQ_Envelope *
481GNUNET_HELLO_builder_merge_hellos (const struct GNUNET_MessageHeader *msg1,
482 const struct GNUNET_MessageHeader *msg2,
483 const struct
484 GNUNET_CRYPTO_EddsaPrivateKey *priv)
485{
486 struct HelloUriMessage *hum1 = (struct HelloUriMessage *) msg1;
487 struct BlockHeader *bh1 = (struct BlockHeader *) &msg1[1];
488 struct GNUNET_TIME_Absolute expiration_time1 = GNUNET_TIME_absolute_ntoh (
489 bh1->expiration_time);
490 struct HelloUriMessage *hum2 = (struct HelloUriMessage *) msg2;
491 struct BlockHeader *bh2 = (struct BlockHeader *) &msg2[1];
492 struct GNUNET_TIME_Absolute expiration_time2 = GNUNET_TIME_absolute_ntoh (
493 bh1->expiration_time);
494 struct GNUNET_HELLO_Builder *builder1 = GNUNET_HELLO_builder_from_msg (msg1);
495 struct GNUNET_HELLO_Builder *builder2 = GNUNET_HELLO_builder_from_msg (msg2);
496 struct AddressUriMergeResult *aumr = GNUNET_new (struct
497 AddressUriMergeResult);
498 struct GNUNET_PeerIdentity *peer1 = GNUNET_HELLO_builder_get_id (builder1);
499 struct GNUNET_MQ_Envelope *env;
500 struct GNUNET_TIME_Absolute expiration_time;
501
502 aumr->builder = builder2;
503 GNUNET_HELLO_builder_iterate (builder1, peer1, &merge_hellos1, aumr);
504
505 if (GNUNET_YES == aumr->merged)
506 {
507 if (expiration_time1.abs_value_us < expiration_time2.abs_value_us)
508 expiration_time = expiration_time1;
509 else
510 expiration_time = expiration_time2;
511 env = GNUNET_HELLO_builder_to_env (builder2,
512 priv,
513 GNUNET_TIME_absolute_get_remaining (
514 expiration_time));
515 }
516 else if (expiration_time1.abs_value_us != expiration_time2.abs_value_us)
517 {
518 if (expiration_time1.abs_value_us < expiration_time2.abs_value_us)
519 expiration_time = expiration_time2;
520 else
521 expiration_time = expiration_time1;
522 env = GNUNET_HELLO_builder_to_env (builder2,
523 priv,
524 GNUNET_TIME_absolute_get_remaining (
525 expiration_time));
526 }
527
528 GNUNET_HELLO_builder_free (builder1);
529 GNUNET_HELLO_builder_free (builder2);
530 GNUNET_free (aumr);
531
532 return env;
533}
534
535
415struct GNUNET_HELLO_Builder * 536struct GNUNET_HELLO_Builder *
416GNUNET_HELLO_builder_from_url (const char *url) 537GNUNET_HELLO_builder_from_url (const char *url)
417{ 538{
diff --git a/src/include/gnunet_hello_uri_lib.h b/src/include/gnunet_hello_uri_lib.h
index 4e48bc1a0..3aa07d760 100644
--- a/src/include/gnunet_hello_uri_lib.h
+++ b/src/include/gnunet_hello_uri_lib.h
@@ -70,6 +70,13 @@ GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid);
70 70
71 71
72/** 72/**
73 * Get the PeerIdentity for this builder.
74 */
75struct GNUNET_PeerIdentity *
76GNUNET_HELLO_builder_get_id (struct GNUNET_HELLO_Builder *builder);
77
78
79/**
73 * Release resources of a @a builder. 80 * Release resources of a @a builder.
74 * 81 *
75 * @param[in] builder to free 82 * @param[in] builder to free
@@ -111,6 +118,16 @@ GNUNET_HELLO_builder_from_url (const char *url);
111 118
112 119
113/** 120/**
121 * Merge to hello uris.
122 */
123struct GNUNET_MQ_Envelope *
124GNUNET_HELLO_builder_merge_hellos (const struct GNUNET_MessageHeader *msg1,
125 const struct GNUNET_MessageHeader *msg2,
126 const struct
127 GNUNET_CRYPTO_EddsaPrivateKey *priv);
128
129
130/**
114 * Generate envelope with GNUnet HELLO message (including 131 * Generate envelope with GNUnet HELLO message (including
115 * peer ID) from a @a builder 132 * peer ID) from a @a builder
116 * 133 *
diff --git a/src/include/gnunet_peerstore_service.h b/src/include/gnunet_peerstore_service.h
index c4000c680..37d3ca7fe 100644
--- a/src/include/gnunet_peerstore_service.h
+++ b/src/include/gnunet_peerstore_service.h
@@ -46,6 +46,10 @@ extern "C" {
46#endif 46#endif
47#endif 47#endif
48 48
49/**
50 * Key used for storing HELLO in the peerstore
51 */
52#define GNUNET_PEERSTORE_HELLO_KEY "peerstore-peer-hello-uri"
49 53
50/** 54/**
51 * Key used for storing addresses in URL format in the peerstore 55 * Key used for storing addresses in URL format in the peerstore
@@ -182,6 +186,33 @@ typedef void (*GNUNET_PEERSTORE_Processor) (
182 const char *emsg); 186 const char *emsg);
183 187
184 188
189
190/**
191 * Add hello to peerstore.
192 *
193 * @param h handle for peerstore.
194 * @param msg The hello to add.
195 * @param cont The continuation function to execute after storing.
196 * @param cont_cls The continuation function closure.
197 * @return The context for storing.
198 */
199struct GNUNET_PEERSTORE_StoreHelloContext *
200GNUNET_PEERSTORE_hello_add (struct GNUNET_PEERSTORE_Handle *h,
201 const struct GNUNET_MessageHeader *msg,
202 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
203 GNUNET_PEERSTORE_Continuation cont,
204 void *cont_cls);
205
206
207/**
208 * Cancel the request to add a hello.
209 *
210 * @param huc The context for storing a hello.
211 */
212void
213GNUNET_PEERSTORE_hello_add_cancel (struct GNUNET_PEERSTORE_StoreHelloContext *huc);
214
215
185/** 216/**
186 * Connect to the PEERSTORE service. 217 * Connect to the PEERSTORE service.
187 * 218 *
diff --git a/src/peerstore/peerstore_api.c b/src/peerstore/peerstore_api.c
index 1c13369cf..3905b14e4 100644
--- a/src/peerstore/peerstore_api.c
+++ b/src/peerstore/peerstore_api.c
@@ -25,8 +25,10 @@
25 */ 25 */
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_hello_uri_lib.h"
28#include "peerstore.h" 29#include "peerstore.h"
29#include "peerstore_common.h" 30#include "peerstore_common.h"
31#include "gnunet_peerstore_service.h"
30 32
31#define LOG(kind, ...) GNUNET_log_from (kind, "peerstore-api", __VA_ARGS__) 33#define LOG(kind, ...) GNUNET_log_from (kind, "peerstore-api", __VA_ARGS__)
32 34
@@ -157,6 +159,22 @@ struct GNUNET_PEERSTORE_StoreContext
157}; 159};
158 160
159/** 161/**
162 * Closure for store callback when storing hello uris.
163 */
164struct StoreHelloCls
165{
166 /**
167 * The corresponding store context.
168 */
169 struct GNUNET_PEERSTORE_StoreContext *sc;
170
171 /**
172 * The corresponding hello uri add request.
173 */
174 struct GNUNET_PEERSTORE_StoreHelloContext *huc;
175};
176
177/**
160 * Context for a iterate request 178 * Context for a iterate request
161 */ 179 */
162struct GNUNET_PEERSTORE_IterateContext 180struct GNUNET_PEERSTORE_IterateContext
@@ -243,6 +261,62 @@ struct GNUNET_PEERSTORE_WatchContext
243 struct GNUNET_HashCode keyhash; 261 struct GNUNET_HashCode keyhash;
244}; 262};
245 263
264/**
265 * Context for a add hello uri request.
266 */
267struct GNUNET_PEERSTORE_StoreHelloContext
268{
269 /**
270 * Peerstore handle.
271 */
272 struct GNUNET_PEERSTORE_Handle *h;
273
274 /**
275 * Function to call with information.
276 */
277 GNUNET_PEERSTORE_Continuation cont;
278
279 /**
280 * Closure for @e callback.
281 */
282 void *cont_cls;
283
284 /**
285 * Head of active STORE requests.
286 */
287 struct GNUNET_PEERSTORE_StoreContext *sc_head;
288
289 /**
290 * Tail of active STORE requests.
291 */
292 struct GNUNET_PEERSTORE_StoreContext *sc_tail;
293
294 /**
295 * Iteration context to iterate through all the stored hellos.
296 */
297 struct GNUNET_PEERSTORE_IterateContext *ic;
298
299 /**
300 * Active watch to be notified about conflicting hello uri add requests.
301 */
302 struct GNUNET_PEERSTORE_WatchContext *wc;
303
304 /**
305 * Hello uri which was request for storing.
306 */
307 const struct GNUNET_MessageHeader *hello;
308
309 /**
310 * Key to sign merged hello.
311 */
312 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
313
314 /**
315 * Was this request successful.
316 */
317 int success;
318};
319
246/******************************************************************************/ 320/******************************************************************************/
247/******************* DECLARATIONS *********************/ 321/******************* DECLARATIONS *********************/
248/******************************************************************************/ 322/******************************************************************************/
@@ -935,4 +1009,168 @@ GNUNET_PEERSTORE_watch (struct GNUNET_PEERSTORE_Handle *h,
935} 1009}
936 1010
937 1011
1012
1013
1014static void
1015merge_success (void *cls, int success)
1016{
1017 struct StoreHelloCls *shu_cls = cls;
1018 struct GNUNET_PEERSTORE_StoreHelloContext *huc = shu_cls->huc;
1019 struct GNUNET_PEERSTORE_Handle *h = huc->h;
1020
1021 if (GNUNET_OK != success)
1022 {
1023 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1024 "Storing hello uri failed\n");
1025 huc->cont (huc->cont_cls, success);
1026 return;
1027 }
1028 GNUNET_CONTAINER_DLL_remove (huc->sc_head, huc->sc_tail, shu_cls->sc);
1029 if (NULL == huc->sc_head)
1030 {
1031 GNUNET_PEERSTORE_watch_cancel (huc->wc);
1032 huc->wc = NULL;
1033 huc->cont (huc->cont_cls, GNUNET_OK);
1034 huc->success = GNUNET_OK;
1035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1036 "Storing hello uri succeeded!\n");
1037 return;
1038 }
1039 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1040 "Got notified during storing hello uri!\n");
1041}
1042
1043
1044static void
1045store_hello (struct GNUNET_PEERSTORE_StoreHelloContext *huc,
1046 const struct GNUNET_MessageHeader *hello)
1047{
1048 struct GNUNET_PEERSTORE_Handle *h = huc->h;
1049 struct GNUNET_HELLO_Builder *builder;
1050 struct GNUNET_PeerIdentity *pid;
1051 struct GNUNET_PEERSTORE_StoreContext *sc;
1052 struct StoreHelloCls *shu_cls = GNUNET_new (struct StoreHelloCls);
1053
1054 shu_cls->huc = huc;
1055 builder = GNUNET_HELLO_builder_from_msg (hello);
1056 pid = GNUNET_HELLO_builder_get_id (builder);
1057 sc = GNUNET_PEERSTORE_store (h,
1058 "peerstore",
1059 pid,
1060 GNUNET_PEERSTORE_HELLO_KEY,
1061 hello,
1062 sizeof(hello),
1063 GNUNET_TIME_UNIT_FOREVER_ABS,
1064 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
1065 merge_success,
1066 shu_cls);
1067 shu_cls->sc = sc;
1068 GNUNET_CONTAINER_DLL_insert (huc->sc_head, huc->sc_tail, sc);
1069 GNUNET_HELLO_builder_free (builder);
1070}
1071
1072
1073static void
1074merge_uri (void *cls,
1075 const struct GNUNET_PEERSTORE_Record *record,
1076 const char *emsg)
1077{
1078 struct GNUNET_PEERSTORE_StoreHelloContext *huc = cls;
1079 struct GNUNET_PEERSTORE_Handle *h = huc->h;
1080 struct GNUNET_PEERSTORE_WatchContext *wc;
1081 struct GNUNET_MessageHeader *hello;
1082 const struct GNUNET_MessageHeader *merged_hello;
1083 struct GNUNET_MQ_Envelope *env;
1084 const char *val;
1085
1086 if (NULL != emsg)
1087 {
1088 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1089 "Got failure from PEERSTORE: %s\n",
1090 emsg);
1091 return;
1092 }
1093 if (NULL == record)
1094 return;
1095
1096 if (NULL == huc->wc && GNUNET_NO == huc->success)
1097 {
1098 wc = GNUNET_PEERSTORE_watch (h,
1099 "peerstore",
1100 &record->peer,
1101 GNUNET_PEERSTORE_HELLO_KEY,
1102 &merge_uri,
1103 huc);
1104 huc->wc = wc;
1105 }
1106
1107 if (NULL != record)
1108 {
1109 hello = record->value;
1110 if ((0 == record->value_size) || ('\0' != val[record->value_size - 1]))
1111 {
1112 GNUNET_break (0);
1113 return;
1114 }
1115
1116 env = GNUNET_HELLO_builder_merge_hellos (huc->hello, hello, huc->priv);
1117 merged_hello = GNUNET_MQ_env_get_msg (env);
1118 if (NULL != merged_hello)
1119 store_hello (huc, merged_hello);
1120
1121 GNUNET_free (env);
1122
1123 }
1124 else
1125 {
1126 store_hello (huc, huc->hello);
1127 }
1128}
1129
1130
1131struct GNUNET_PEERSTORE_StoreHelloContext *
1132GNUNET_PEERSTORE_hello_add (struct GNUNET_PEERSTORE_Handle *h,
1133 const struct GNUNET_MessageHeader *msg,
1134 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1135 GNUNET_PEERSTORE_Continuation cont,
1136 void *cont_cls)
1137{
1138 struct GNUNET_HELLO_Builder *builder;
1139 struct GNUNET_PEERSTORE_StoreHelloContext *huc;
1140 struct GNUNET_PEERSTORE_IterateContext *ic;
1141 struct GNUNET_PeerIdentity *pid;
1142
1143 huc = GNUNET_new (struct GNUNET_PEERSTORE_StoreHelloContext);
1144 huc->h = h;
1145 huc->cont = cont;
1146 huc->cont_cls = cont_cls;
1147 huc->hello = msg;
1148 huc->priv = priv;
1149
1150 builder = GNUNET_HELLO_builder_from_msg (msg);
1151 pid = GNUNET_HELLO_builder_get_id (builder);
1152 ic = GNUNET_PEERSTORE_iterate (h,
1153 "peerstore",
1154 pid,
1155 GNUNET_PEERSTORE_HELLO_KEY,
1156 &merge_uri,
1157 huc);
1158 GNUNET_HELLO_builder_free (builder);
1159 huc->ic = ic;
1160
1161 return huc;
1162}
1163
1164void
1165GNUNET_PEERSTORE_hello_add_cancel (struct GNUNET_PEERSTORE_StoreHelloContext *huc)
1166{
1167 struct GNUNET_PEERSTORE_StoreContext *sc;
1168
1169 GNUNET_PEERSTORE_iterate_cancel (huc->ic);
1170 GNUNET_PEERSTORE_watch_cancel (huc->wc);
1171 while (NULL != (sc = huc->sc_head))
1172 GNUNET_PEERSTORE_store_cancel (sc);
1173 GNUNET_free (huc);
1174}
1175
938/* end of peerstore_api.c */ 1176/* end of peerstore_api.c */