aboutsummaryrefslogtreecommitdiff
path: root/src/peerstore/peerstore_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/peerstore/peerstore_api.c')
-rw-r--r--src/peerstore/peerstore_api.c238
1 files changed, 238 insertions, 0 deletions
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 */