diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-04 20:31:16 +0900 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-04 20:31:16 +0900 |
commit | 4aeb9686fb4bd0fa686d1aa8c99211312726fcf0 (patch) | |
tree | 22c4b918f5881cf9dc19b58644b6d28f41fc850e | |
parent | 34ae70a81bbfddc877593079e2e5f94f179deffc (diff) | |
download | gnunet-4aeb9686fb4bd0fa686d1aa8c99211312726fcf0.tar.gz gnunet-4aeb9686fb4bd0fa686d1aa8c99211312726fcf0.zip |
NAMESTORE: Move Namecache block refresh into zonemonitor
-rw-r--r-- | src/namestore/gnunet-service-namestore.c | 264 | ||||
-rw-r--r-- | src/namestore/test_namestore_api.conf | 13 | ||||
-rw-r--r-- | src/namestore/test_namestore_api_lookup_public.c | 29 | ||||
-rw-r--r-- | src/zonemaster/Makefile.am | 2 | ||||
-rw-r--r-- | src/zonemaster/gnunet-service-zonemaster-monitor.c | 177 | ||||
-rw-r--r-- | src/zonemaster/gnunet-service-zonemaster.c | 189 |
6 files changed, 400 insertions, 274 deletions
diff --git a/src/namestore/gnunet-service-namestore.c b/src/namestore/gnunet-service-namestore.c index 027b19a2e..57818ac63 100644 --- a/src/namestore/gnunet-service-namestore.c +++ b/src/namestore/gnunet-service-namestore.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include "gnunet_util_lib.h" | 28 | #include "gnunet_util_lib.h" |
29 | #include "gnunet_dnsparser_lib.h" | 29 | #include "gnunet_dnsparser_lib.h" |
30 | #include "gnunet_gns_service.h" | 30 | #include "gnunet_gns_service.h" |
31 | #include "gnunet_namecache_service.h" | ||
32 | #include "gnunet_namestore_service.h" | 31 | #include "gnunet_namestore_service.h" |
33 | #include "gnunet_namestore_plugin.h" | 32 | #include "gnunet_namestore_plugin.h" |
34 | #include "gnunet_statistics_service.h" | 33 | #include "gnunet_statistics_service.h" |
@@ -253,43 +252,6 @@ struct ZoneMonitor | |||
253 | }; | 252 | }; |
254 | 253 | ||
255 | 254 | ||
256 | /** | ||
257 | * Pending operation on the namecache. | ||
258 | */ | ||
259 | struct CacheOperation | ||
260 | { | ||
261 | /** | ||
262 | * Kept in a DLL. | ||
263 | */ | ||
264 | struct CacheOperation *prev; | ||
265 | |||
266 | /** | ||
267 | * Kept in a DLL. | ||
268 | */ | ||
269 | struct CacheOperation *next; | ||
270 | |||
271 | /** | ||
272 | * Handle to namecache queue. | ||
273 | */ | ||
274 | struct GNUNET_NAMECACHE_QueueEntry *qe; | ||
275 | |||
276 | /** | ||
277 | * Client to notify about the result, can be NULL. | ||
278 | */ | ||
279 | struct NamestoreClient *nc; | ||
280 | |||
281 | /** | ||
282 | * Zone iteration to call #zone_iteration_done_client_continue() | ||
283 | * for if applicable, can be NULL. | ||
284 | */ | ||
285 | struct ZoneIteration *zi; | ||
286 | |||
287 | /** | ||
288 | * Client's request ID. | ||
289 | */ | ||
290 | uint32_t rid; | ||
291 | }; | ||
292 | |||
293 | 255 | ||
294 | /** | 256 | /** |
295 | * Information for an ongoing #handle_record_store() operation. | 257 | * Information for an ongoing #handle_record_store() operation. |
@@ -395,11 +357,6 @@ static const struct GNUNET_CONFIGURATION_Handle *GSN_cfg; | |||
395 | static struct GNUNET_STATISTICS_Handle *statistics; | 357 | static struct GNUNET_STATISTICS_Handle *statistics; |
396 | 358 | ||
397 | /** | 359 | /** |
398 | * Namecache handle. | ||
399 | */ | ||
400 | static struct GNUNET_NAMECACHE_Handle *namecache; | ||
401 | |||
402 | /** | ||
403 | * Name of the database plugin | 360 | * Name of the database plugin |
404 | */ | 361 | */ |
405 | static char *db_lib_name; | 362 | static char *db_lib_name; |
@@ -411,16 +368,6 @@ struct GNUNET_NAMESTORE_PluginFunctions *GSN_database; | |||
411 | 368 | ||
412 | 369 | ||
413 | /** | 370 | /** |
414 | * Head of cop DLL. | ||
415 | */ | ||
416 | static struct CacheOperation *cop_head; | ||
417 | |||
418 | /** | ||
419 | * Tail of cop DLL. | ||
420 | */ | ||
421 | static struct CacheOperation *cop_tail; | ||
422 | |||
423 | /** | ||
424 | * First active zone monitor. | 371 | * First active zone monitor. |
425 | */ | 372 | */ |
426 | static struct ZoneMonitor *monitor_head; | 373 | static struct ZoneMonitor *monitor_head; |
@@ -452,13 +399,6 @@ static struct GNUNET_NotificationContext *monitor_nc; | |||
452 | static int cache_keys; | 399 | static int cache_keys; |
453 | 400 | ||
454 | /** | 401 | /** |
455 | * Use the namecache? Doing so creates additional cryptographic | ||
456 | * operations whenever we touch a record. | ||
457 | */ | ||
458 | static int disable_namecache; | ||
459 | |||
460 | |||
461 | /** | ||
462 | * Task run during shutdown. | 402 | * Task run during shutdown. |
463 | * | 403 | * |
464 | * @param cls unused | 404 | * @param cls unused |
@@ -466,24 +406,8 @@ static int disable_namecache; | |||
466 | static void | 406 | static void |
467 | cleanup_task (void *cls) | 407 | cleanup_task (void *cls) |
468 | { | 408 | { |
469 | struct CacheOperation *cop; | ||
470 | |||
471 | (void) cls; | 409 | (void) cls; |
472 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); | 410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Stopping namestore service\n"); |
473 | while (NULL != (cop = cop_head)) | ||
474 | { | ||
475 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
476 | "Aborting incomplete namecache operation\n"); | ||
477 | GNUNET_NAMECACHE_cancel (cop->qe); | ||
478 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | ||
479 | GNUNET_free (cop); | ||
480 | } | ||
481 | |||
482 | if (NULL != namecache) | ||
483 | { | ||
484 | GNUNET_NAMECACHE_disconnect (namecache); | ||
485 | namecache = NULL; | ||
486 | } | ||
487 | if (NULL != monitor_nc) | 411 | if (NULL != monitor_nc) |
488 | { | 412 | { |
489 | GNUNET_notification_context_destroy (monitor_nc); | 413 | GNUNET_notification_context_destroy (monitor_nc); |
@@ -958,150 +882,6 @@ zone_iteration_done_client_continue (struct ZoneIteration *zi) | |||
958 | } | 882 | } |
959 | 883 | ||
960 | 884 | ||
961 | /** | ||
962 | * Cache operation complete, clean up. | ||
963 | * | ||
964 | * @param cls the `struct CacheOperation` | ||
965 | * @param success success | ||
966 | * @param emsg error messages | ||
967 | */ | ||
968 | static void | ||
969 | finish_cache_operation (void *cls, int32_t success, const char *emsg) | ||
970 | { | ||
971 | struct CacheOperation *cop = cls; | ||
972 | struct ZoneIteration *zi; | ||
973 | |||
974 | if (NULL != emsg) | ||
975 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
976 | _ ("Failed to replicate block in namecache: %s\n"), | ||
977 | emsg); | ||
978 | else | ||
979 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); | ||
980 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | ||
981 | if (NULL != cop->nc) | ||
982 | send_store_response (cop->nc, success, emsg, cop->rid); | ||
983 | if (NULL != (zi = cop->zi)) | ||
984 | { | ||
985 | zi->cache_ops--; | ||
986 | if (0 == zi->cache_ops) | ||
987 | { | ||
988 | /* unchoke zone iteration, cache has caught up */ | ||
989 | zone_iteration_done_client_continue (zi); | ||
990 | } | ||
991 | } | ||
992 | GNUNET_free (cop); | ||
993 | } | ||
994 | |||
995 | |||
996 | /** | ||
997 | * We just touched the plaintext information about a name in our zone; | ||
998 | * refresh the corresponding (encrypted) block in the namecache. | ||
999 | * | ||
1000 | * @param nc client responsible for the request, can be NULL | ||
1001 | * @param zi zone iteration response for the request, can be NULL | ||
1002 | * @param rid request ID of the client | ||
1003 | * @param zone_key private key of the zone | ||
1004 | * @param name label for the records | ||
1005 | * @param rd_count number of records | ||
1006 | * @param rd records stored under the given @a name | ||
1007 | */ | ||
1008 | static void | ||
1009 | refresh_block (struct NamestoreClient *nc, | ||
1010 | struct ZoneIteration *zi, | ||
1011 | uint32_t rid, | ||
1012 | const struct GNUNET_IDENTITY_PrivateKey *zone_key, | ||
1013 | const char *name, | ||
1014 | unsigned int rd_count, | ||
1015 | const struct GNUNET_GNSRECORD_Data *rd) | ||
1016 | { | ||
1017 | struct GNUNET_GNSRECORD_Block *block; | ||
1018 | struct GNUNET_GNSRECORD_Data rd_clean[rd_count]; | ||
1019 | struct CacheOperation *cop; | ||
1020 | struct GNUNET_IDENTITY_PublicKey pkey; | ||
1021 | struct GNUNET_GNSRECORD_Data *nick; | ||
1022 | struct GNUNET_GNSRECORD_Data *res; | ||
1023 | unsigned int res_count; | ||
1024 | unsigned int rd_count_clean; | ||
1025 | struct GNUNET_TIME_Absolute exp_time; | ||
1026 | |||
1027 | /** Do not block-cache tombstones */ | ||
1028 | rd_count_clean = 0; | ||
1029 | for (int i = 0; i < rd_count; i++) | ||
1030 | { | ||
1031 | if (GNUNET_GNSRECORD_TYPE_TOMBSTONE == rd[i].record_type) | ||
1032 | continue; | ||
1033 | rd_clean[rd_count_clean++] = rd[i]; | ||
1034 | } | ||
1035 | |||
1036 | nick = get_nick_record (zone_key); | ||
1037 | res_count = rd_count_clean; | ||
1038 | res = (struct GNUNET_GNSRECORD_Data *) rd_clean; /* fixme: a bit unclean... */ | ||
1039 | if ((NULL != nick) && (0 != strcmp (name, GNUNET_GNS_EMPTY_LABEL_AT))) | ||
1040 | { | ||
1041 | nick->flags = | ||
1042 | (nick->flags | GNUNET_GNSRECORD_RF_PRIVATE) ^ GNUNET_GNSRECORD_RF_PRIVATE; | ||
1043 | merge_with_nick_records (nick, rd_count_clean, rd_clean, &res_count, &res); | ||
1044 | } | ||
1045 | if (NULL != nick) | ||
1046 | GNUNET_free (nick); | ||
1047 | if (0 == res_count) | ||
1048 | { | ||
1049 | if (NULL != nc) | ||
1050 | send_store_response (nc, GNUNET_OK, NULL, rid); | ||
1051 | if (rd_clean != res) | ||
1052 | GNUNET_free (res); | ||
1053 | return; /* no data, no need to update cache */ | ||
1054 | } | ||
1055 | if (GNUNET_YES == disable_namecache) | ||
1056 | { | ||
1057 | GNUNET_STATISTICS_update (statistics, | ||
1058 | "Namecache updates skipped (NC disabled)", | ||
1059 | 1, | ||
1060 | GNUNET_NO); | ||
1061 | if (NULL != nc) | ||
1062 | send_store_response (nc, GNUNET_OK, NULL, rid); | ||
1063 | if (rd_clean != res) | ||
1064 | GNUNET_free (res); | ||
1065 | return; | ||
1066 | } | ||
1067 | exp_time = GNUNET_GNSRECORD_record_get_expiration_time (res_count, res, | ||
1068 | GNUNET_TIME_UNIT_ZERO_ABS); | ||
1069 | if (cache_keys) | ||
1070 | GNUNET_assert (GNUNET_OK == | ||
1071 | GNUNET_GNSRECORD_block_create2 (zone_key, exp_time, name, | ||
1072 | res, res_count, &block)); | ||
1073 | else | ||
1074 | GNUNET_assert (GNUNET_OK == | ||
1075 | GNUNET_GNSRECORD_block_create (zone_key, exp_time, name, | ||
1076 | res, res_count, &block)); | ||
1077 | GNUNET_assert (NULL != block); | ||
1078 | GNUNET_IDENTITY_key_get_public (zone_key, &pkey); | ||
1079 | GNUNET_log ( | ||
1080 | GNUNET_ERROR_TYPE_DEBUG, | ||
1081 | "Caching block for label `%s' with %u records and expiration %s in zone `%s' in namecache\n", | ||
1082 | name, | ||
1083 | res_count, | ||
1084 | GNUNET_STRINGS_absolute_time_to_string (exp_time), | ||
1085 | GNUNET_GNSRECORD_z2s (&pkey)); | ||
1086 | GNUNET_STATISTICS_update (statistics, | ||
1087 | "Namecache updates pushed", | ||
1088 | 1, | ||
1089 | GNUNET_NO); | ||
1090 | cop = GNUNET_new (struct CacheOperation); | ||
1091 | cop->nc = nc; | ||
1092 | cop->zi = zi; | ||
1093 | if (NULL != zi) | ||
1094 | zi->cache_ops++; | ||
1095 | cop->rid = rid; | ||
1096 | GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); | ||
1097 | cop->qe = GNUNET_NAMECACHE_block_cache (namecache, | ||
1098 | block, | ||
1099 | &finish_cache_operation, | ||
1100 | cop); | ||
1101 | GNUNET_free (block); | ||
1102 | if (rd_clean != res) | ||
1103 | GNUNET_free (res); | ||
1104 | } | ||
1105 | 885 | ||
1106 | 886 | ||
1107 | /** | 887 | /** |
@@ -1173,6 +953,9 @@ continue_store_activity (struct StoreActivity *sa, | |||
1173 | GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, | 953 | GNUNET_GNSRECORD_records_deserialize (rd_ser_len, rd_ser, rd_count, |
1174 | rd)); | 954 | rd)); |
1175 | 955 | ||
956 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
957 | "Checking monitors watching for `%s'\n", | ||
958 | conv_name); | ||
1176 | for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos) | 959 | for (struct ZoneMonitor *zm = sa->zm_pos; NULL != zm; zm = sa->zm_pos) |
1177 | { | 960 | { |
1178 | if ((0 != GNUNET_memcmp (&sa->private_key, &zm->zone)) && | 961 | if ((0 != GNUNET_memcmp (&sa->private_key, &zm->zone)) && |
@@ -1191,8 +974,11 @@ continue_store_activity (struct StoreActivity *sa, | |||
1191 | GNUNET_SCHEDULER_add_delayed (MONITOR_STALL_WARN_DELAY, | 974 | GNUNET_SCHEDULER_add_delayed (MONITOR_STALL_WARN_DELAY, |
1192 | &warn_monitor_slow, | 975 | &warn_monitor_slow, |
1193 | zm); | 976 | zm); |
977 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
978 | "Monitor is blocking client for `%s'\n", | ||
979 | conv_name); | ||
1194 | GNUNET_free (conv_name); | 980 | GNUNET_free (conv_name); |
1195 | return GNUNET_NO; /* blocked on zone monitor */ | 981 | return GNUNET_NO; /* blocked on zone monitor */ |
1196 | } | 982 | } |
1197 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 983 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1198 | "Notifying monitor about changes under label `%s'\n", | 984 | "Notifying monitor about changes under label `%s'\n", |
@@ -1207,20 +993,13 @@ continue_store_activity (struct StoreActivity *sa, | |||
1207 | zm->filter); | 993 | zm->filter); |
1208 | sa->zm_pos = zm->next; | 994 | sa->zm_pos = zm->next; |
1209 | } | 995 | } |
1210 | /* great, done with the monitors, unpack (again) for refresh_block operation */ | ||
1211 | sa->rd_set_pos++; | 996 | sa->rd_set_pos++; |
1212 | refresh_block ((sa->rd_set_pos == sa->rd_set_count) ? sa->nc : NULL, | ||
1213 | NULL, | ||
1214 | sa->rid, | ||
1215 | &sa->private_key, | ||
1216 | conv_name, | ||
1217 | rd_count, | ||
1218 | rd); | ||
1219 | GNUNET_free (conv_name); | 997 | GNUNET_free (conv_name); |
1220 | } | 998 | } |
1221 | } | 999 | } |
1222 | if (GNUNET_YES == call_continue) | 1000 | if (GNUNET_YES == call_continue) |
1223 | GNUNET_SERVICE_client_continue (sa->nc->client); | 1001 | GNUNET_SERVICE_client_continue (sa->nc->client); |
1002 | send_store_response (sa->nc, GNUNET_YES, NULL, sa->rid); | ||
1224 | free_store_activity (sa); | 1003 | free_store_activity (sa); |
1225 | return GNUNET_OK; | 1004 | return GNUNET_OK; |
1226 | } | 1005 | } |
@@ -1241,7 +1020,6 @@ client_disconnect_cb (void *cls, | |||
1241 | { | 1020 | { |
1242 | struct NamestoreClient *nc = app_ctx; | 1021 | struct NamestoreClient *nc = app_ctx; |
1243 | struct ZoneIteration *no; | 1022 | struct ZoneIteration *no; |
1244 | struct CacheOperation *cop; | ||
1245 | struct StoreActivity *sa; | 1023 | struct StoreActivity *sa; |
1246 | struct StoreActivity *sn; | 1024 | struct StoreActivity *sn; |
1247 | char *emsg; | 1025 | char *emsg; |
@@ -1319,9 +1097,6 @@ client_disconnect_cb (void *cls, | |||
1319 | GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no); | 1097 | GNUNET_CONTAINER_DLL_remove (nc->op_head, nc->op_tail, no); |
1320 | GNUNET_free (no); | 1098 | GNUNET_free (no); |
1321 | } | 1099 | } |
1322 | for (cop = cop_head; NULL != cop; cop = cop->next) | ||
1323 | if (nc == cop->nc) | ||
1324 | cop->nc = NULL; | ||
1325 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name, | 1100 | GNUNET_break (NULL == GNUNET_PLUGIN_unload (nc->db_lib_name, |
1326 | nc->GSN_database)); | 1101 | nc->GSN_database)); |
1327 | GNUNET_free (nc->db_lib_name); | 1102 | GNUNET_free (nc->db_lib_name); |
@@ -2212,7 +1987,6 @@ zone_iterate_proc (void *cls, | |||
2212 | const struct GNUNET_GNSRECORD_Data *rd) | 1987 | const struct GNUNET_GNSRECORD_Data *rd) |
2213 | { | 1988 | { |
2214 | struct ZoneIterationProcResult *proc = cls; | 1989 | struct ZoneIterationProcResult *proc = cls; |
2215 | int do_refresh_block; | ||
2216 | 1990 | ||
2217 | GNUNET_assert (0 != seq); | 1991 | GNUNET_assert (0 != seq); |
2218 | if ((NULL == zone_key) && (NULL == name)) | 1992 | if ((NULL == zone_key) && (NULL == name)) |
@@ -2241,17 +2015,6 @@ zone_iterate_proc (void *cls, | |||
2241 | rd_count, | 2015 | rd_count, |
2242 | rd, | 2016 | rd, |
2243 | proc->zi->filter); | 2017 | proc->zi->filter); |
2244 | |||
2245 | |||
2246 | do_refresh_block = GNUNET_NO; | ||
2247 | for (unsigned int i = 0; i < rd_count; i++) | ||
2248 | if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) | ||
2249 | { | ||
2250 | do_refresh_block = GNUNET_YES; | ||
2251 | break; | ||
2252 | } | ||
2253 | if (GNUNET_YES == do_refresh_block) | ||
2254 | refresh_block (NULL, proc->zi, 0, zone_key, name, rd_count, rd); | ||
2255 | } | 2018 | } |
2256 | 2019 | ||
2257 | 2020 | ||
@@ -2410,6 +2173,8 @@ monitor_unblock (struct ZoneMonitor *zm) | |||
2410 | struct StoreActivity *sa = sa_head; | 2173 | struct StoreActivity *sa = sa_head; |
2411 | int blocked = GNUNET_NO; | 2174 | int blocked = GNUNET_NO; |
2412 | 2175 | ||
2176 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2177 | "Unblocking zone monitor %p\n", zm); | ||
2413 | while ((NULL != sa) && (zm->limit > zm->iteration_cnt)) | 2178 | while ((NULL != sa) && (zm->limit > zm->iteration_cnt)) |
2414 | { | 2179 | { |
2415 | struct StoreActivity *sn = sa->next; | 2180 | struct StoreActivity *sn = sa->next; |
@@ -2450,6 +2215,8 @@ monitor_sync (struct ZoneMonitor *zm) | |||
2450 | { | 2215 | { |
2451 | struct GNUNET_MQ_Envelope *env; | 2216 | struct GNUNET_MQ_Envelope *env; |
2452 | struct GNUNET_MessageHeader *sync; | 2217 | struct GNUNET_MessageHeader *sync; |
2218 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
2219 | "Synching zone monitor %p\n", zm); | ||
2453 | 2220 | ||
2454 | env = GNUNET_MQ_msg (sync, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC); | 2221 | env = GNUNET_MQ_msg (sync, GNUNET_MESSAGE_TYPE_NAMESTORE_MONITOR_SYNC); |
2455 | GNUNET_MQ_send (zm->nc->mq, env); | 2222 | GNUNET_MQ_send (zm->nc->mq, env); |
@@ -2658,15 +2425,8 @@ run (void *cls, | |||
2658 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n"); | 2425 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting namestore service\n"); |
2659 | cache_keys = | 2426 | cache_keys = |
2660 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS"); | 2427 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "namestore", "CACHE_KEYS"); |
2661 | disable_namecache = | ||
2662 | GNUNET_CONFIGURATION_get_value_yesno (cfg, "namecache", "DISABLE"); | ||
2663 | GSN_cfg = cfg; | 2428 | GSN_cfg = cfg; |
2664 | monitor_nc = GNUNET_notification_context_create (1); | 2429 | monitor_nc = GNUNET_notification_context_create (1); |
2665 | if (GNUNET_YES != disable_namecache) | ||
2666 | { | ||
2667 | namecache = GNUNET_NAMECACHE_connect (cfg); | ||
2668 | GNUNET_assert (NULL != namecache); | ||
2669 | } | ||
2670 | statistics = GNUNET_STATISTICS_create ("namestore", cfg); | 2430 | statistics = GNUNET_STATISTICS_create ("namestore", cfg); |
2671 | /* Loading database plugin */ | 2431 | /* Loading database plugin */ |
2672 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, | 2432 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, |
diff --git a/src/namestore/test_namestore_api.conf b/src/namestore/test_namestore_api.conf index f79c91dc1..e718196fc 100644 --- a/src/namestore/test_namestore_api.conf +++ b/src/namestore/test_namestore_api.conf | |||
@@ -13,6 +13,19 @@ START_ON_DEMAND = YES | |||
13 | DATABASE = sqlite | 13 | DATABASE = sqlite |
14 | START_ON_DEMAND = YES | 14 | START_ON_DEMAND = YES |
15 | 15 | ||
16 | [zonemaster] | ||
17 | START_ON_DEMAND = YES | ||
18 | IMMEDIATE_START = NO | ||
19 | |||
20 | [dht] | ||
21 | START_ON_DEMAND = YES | ||
22 | IMMEDIATE_START = NO | ||
23 | |||
24 | |||
25 | [zonemaster-monitor] | ||
26 | START_ON_DEMAND = YES | ||
27 | IMMEDIATE_START = YES | ||
28 | |||
16 | [identity] | 29 | [identity] |
17 | START_ON_DEMAND = YES | 30 | START_ON_DEMAND = YES |
18 | 31 | ||
diff --git a/src/namestore/test_namestore_api_lookup_public.c b/src/namestore/test_namestore_api_lookup_public.c index cd69b96ef..311fa83ad 100644 --- a/src/namestore/test_namestore_api_lookup_public.c +++ b/src/namestore/test_namestore_api_lookup_public.c | |||
@@ -150,21 +150,36 @@ name_lookup_proc (void *cls, | |||
150 | } | 150 | } |
151 | 151 | ||
152 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 152 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
153 | "Namestore returned block, decrypting \n"); | 153 | "Namecache returned block, decrypting \n"); |
154 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_decrypt (block, | 154 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_decrypt (block, |
155 | &pubkey, name, | 155 | &pubkey, name, |
156 | &rd_decrypt_cb, | 156 | &rd_decrypt_cb, |
157 | (void *) name)); | 157 | (void *) name)); |
158 | } | 158 | } |
159 | 159 | ||
160 | |||
161 | static void | 160 | static void |
162 | put_cont (void *cls, int32_t success, const char *emsg) | 161 | lookup_block (void *cls) |
163 | { | 162 | { |
164 | const char *name = cls; | 163 | const char *name = cls; |
165 | struct GNUNET_HashCode derived_hash; | 164 | struct GNUNET_HashCode derived_hash; |
166 | struct GNUNET_IDENTITY_PublicKey pubkey; | 165 | struct GNUNET_IDENTITY_PublicKey pubkey; |
167 | 166 | ||
167 | /* Create derived hash */ | ||
168 | GNUNET_IDENTITY_key_get_public (&privkey, | ||
169 | &pubkey); | ||
170 | GNUNET_GNSRECORD_query_from_public_key (&pubkey, name, &derived_hash); | ||
171 | |||
172 | ncqe = GNUNET_NAMECACHE_lookup_block (nch, &derived_hash, | ||
173 | &name_lookup_proc, cls); | ||
174 | } | ||
175 | |||
176 | |||
177 | |||
178 | static void | ||
179 | put_cont (void *cls, int32_t success, const char *emsg) | ||
180 | { | ||
181 | const char *name = cls; | ||
182 | |||
168 | nsqe = NULL; | 183 | nsqe = NULL; |
169 | GNUNET_assert (NULL != cls); | 184 | GNUNET_assert (NULL != cls); |
170 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 185 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -172,13 +187,9 @@ put_cont (void *cls, int32_t success, const char *emsg) | |||
172 | name, | 187 | name, |
173 | (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); | 188 | (success == GNUNET_OK) ? "SUCCESS" : "FAIL"); |
174 | 189 | ||
175 | /* Create derived hash */ | ||
176 | GNUNET_IDENTITY_key_get_public (&privkey, | ||
177 | &pubkey); | ||
178 | GNUNET_GNSRECORD_query_from_public_key (&pubkey, name, &derived_hash); | ||
179 | 190 | ||
180 | ncqe = GNUNET_NAMECACHE_lookup_block (nch, &derived_hash, | 191 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, |
181 | &name_lookup_proc, (void *) name); | 192 | &lookup_block, (void *) name); |
182 | } | 193 | } |
183 | 194 | ||
184 | 195 | ||
diff --git a/src/zonemaster/Makefile.am b/src/zonemaster/Makefile.am index f2d569c75..90b70f58a 100644 --- a/src/zonemaster/Makefile.am +++ b/src/zonemaster/Makefile.am | |||
@@ -28,6 +28,7 @@ gnunet_service_zonemaster_LDADD = \ | |||
28 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 28 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
29 | $(top_builddir)/src/util/libgnunetutil.la \ | 29 | $(top_builddir)/src/util/libgnunetutil.la \ |
30 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | 30 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
31 | $(top_builddir)/src/namecache/libgnunetnamecache.la \ | ||
31 | $(GN_LIBINTL) | 32 | $(GN_LIBINTL) |
32 | 33 | ||
33 | 34 | ||
@@ -40,4 +41,5 @@ gnunet_service_zonemaster_monitor_LDADD = \ | |||
40 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 41 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
41 | $(top_builddir)/src/util/libgnunetutil.la \ | 42 | $(top_builddir)/src/util/libgnunetutil.la \ |
42 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ | 43 | $(top_builddir)/src/namestore/libgnunetnamestore.la \ |
44 | $(top_builddir)/src/namecache/libgnunetnamecache.la \ | ||
43 | $(GN_LIBINTL) | 45 | $(GN_LIBINTL) |
diff --git a/src/zonemaster/gnunet-service-zonemaster-monitor.c b/src/zonemaster/gnunet-service-zonemaster-monitor.c index 08749bede..d2bc5e89d 100644 --- a/src/zonemaster/gnunet-service-zonemaster-monitor.c +++ b/src/zonemaster/gnunet-service-zonemaster-monitor.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "gnunet_util_lib.h" | 27 | #include "gnunet_util_lib.h" |
28 | #include "gnunet_dht_service.h" | 28 | #include "gnunet_dht_service.h" |
29 | #include "gnunet_namestore_service.h" | 29 | #include "gnunet_namestore_service.h" |
30 | #include "gnunet_namecache_service.h" | ||
30 | #include "gnunet_statistics_service.h" | 31 | #include "gnunet_statistics_service.h" |
31 | 32 | ||
32 | #define LOG_STRERROR_FILE(kind, syscall, \ | 33 | #define LOG_STRERROR_FILE(kind, syscall, \ |
@@ -83,6 +84,28 @@ struct DhtPutActivity | |||
83 | struct GNUNET_TIME_Absolute start_date; | 84 | struct GNUNET_TIME_Absolute start_date; |
84 | }; | 85 | }; |
85 | 86 | ||
87 | /** | ||
88 | * Pending operation on the namecache. | ||
89 | */ | ||
90 | struct CacheOperation | ||
91 | { | ||
92 | /** | ||
93 | * Kept in a DLL. | ||
94 | */ | ||
95 | struct CacheOperation *prev; | ||
96 | |||
97 | /** | ||
98 | * Kept in a DLL. | ||
99 | */ | ||
100 | struct CacheOperation *next; | ||
101 | |||
102 | /** | ||
103 | * Handle to namecache queue. | ||
104 | */ | ||
105 | struct GNUNET_NAMECACHE_QueueEntry *qe; | ||
106 | |||
107 | }; | ||
108 | |||
86 | 109 | ||
87 | /** | 110 | /** |
88 | * Handle to the statistics service | 111 | * Handle to the statistics service |
@@ -115,6 +138,18 @@ static struct DhtPutActivity *ma_head; | |||
115 | static struct DhtPutActivity *ma_tail; | 138 | static struct DhtPutActivity *ma_tail; |
116 | 139 | ||
117 | /** | 140 | /** |
141 | * Our handle to the namecache service | ||
142 | */ | ||
143 | static struct GNUNET_NAMECACHE_Handle *namecache; | ||
144 | |||
145 | /** | ||
146 | * Use the namecache? Doing so creates additional cryptographic | ||
147 | * operations whenever we touch a record. | ||
148 | */ | ||
149 | static int disable_namecache; | ||
150 | |||
151 | |||
152 | /** | ||
118 | * Number of entries in the DHT queue #ma_head. | 153 | * Number of entries in the DHT queue #ma_head. |
119 | */ | 154 | */ |
120 | static unsigned int ma_queue_length; | 155 | static unsigned int ma_queue_length; |
@@ -125,6 +160,16 @@ static unsigned int ma_queue_length; | |||
125 | */ | 160 | */ |
126 | static int cache_keys; | 161 | static int cache_keys; |
127 | 162 | ||
163 | /** | ||
164 | * Head of cop DLL. | ||
165 | */ | ||
166 | static struct CacheOperation *cop_head; | ||
167 | |||
168 | /** | ||
169 | * Tail of cop DLL. | ||
170 | */ | ||
171 | static struct CacheOperation *cop_tail; | ||
172 | |||
128 | 173 | ||
129 | /** | 174 | /** |
130 | * Task run during shutdown. | 175 | * Task run during shutdown. |
@@ -136,10 +181,20 @@ static void | |||
136 | shutdown_task (void *cls) | 181 | shutdown_task (void *cls) |
137 | { | 182 | { |
138 | struct DhtPutActivity *ma; | 183 | struct DhtPutActivity *ma; |
184 | struct CacheOperation *cop; | ||
185 | |||
139 | 186 | ||
140 | (void) cls; | 187 | (void) cls; |
141 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 188 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
142 | "Shutting down!\n"); | 189 | "Shutting down!\n"); |
190 | while (NULL != (cop = cop_head)) | ||
191 | { | ||
192 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
193 | "Aborting incomplete namecache operation\n"); | ||
194 | GNUNET_NAMECACHE_cancel (cop->qe); | ||
195 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | ||
196 | GNUNET_free (cop); | ||
197 | } | ||
143 | while (NULL != (ma = ma_head)) | 198 | while (NULL != (ma = ma_head)) |
144 | { | 199 | { |
145 | GNUNET_DHT_put_cancel (ma->ph); | 200 | GNUNET_DHT_put_cancel (ma->ph); |
@@ -165,6 +220,11 @@ shutdown_task (void *cls) | |||
165 | GNUNET_NAMESTORE_disconnect (namestore_handle); | 220 | GNUNET_NAMESTORE_disconnect (namestore_handle); |
166 | namestore_handle = NULL; | 221 | namestore_handle = NULL; |
167 | } | 222 | } |
223 | if (NULL != namecache) | ||
224 | { | ||
225 | GNUNET_NAMECACHE_disconnect (namecache); | ||
226 | namecache = NULL; | ||
227 | } | ||
168 | if (NULL != dht_handle) | 228 | if (NULL != dht_handle) |
169 | { | 229 | { |
170 | GNUNET_DHT_disconnect (dht_handle); | 230 | GNUNET_DHT_disconnect (dht_handle); |
@@ -172,6 +232,66 @@ shutdown_task (void *cls) | |||
172 | } | 232 | } |
173 | } | 233 | } |
174 | 234 | ||
235 | /** | ||
236 | * Cache operation complete, clean up. | ||
237 | * | ||
238 | * @param cls the `struct CacheOperation` | ||
239 | * @param success success | ||
240 | * @param emsg error messages | ||
241 | */ | ||
242 | static void | ||
243 | finish_cache_operation (void *cls, int32_t success, const char *emsg) | ||
244 | { | ||
245 | struct CacheOperation *cop = cls; | ||
246 | |||
247 | if (NULL != emsg) | ||
248 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
249 | _ ("Failed to replicate block in namecache: %s\n"), | ||
250 | emsg); | ||
251 | else | ||
252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); | ||
253 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | ||
254 | GNUNET_free (cop); | ||
255 | } | ||
256 | |||
257 | |||
258 | /** | ||
259 | * Refresh the (encrypted) block in the namecache. | ||
260 | * | ||
261 | * @param zone_key private key of the zone | ||
262 | * @param name label for the records | ||
263 | * @param rd_count number of records | ||
264 | * @param rd records stored under the given @a name | ||
265 | */ | ||
266 | static void | ||
267 | refresh_block (const struct GNUNET_GNSRECORD_Block *block) | ||
268 | { | ||
269 | struct CacheOperation *cop; | ||
270 | struct GNUNET_TIME_Absolute exp_time; | ||
271 | |||
272 | if (GNUNET_YES == disable_namecache) | ||
273 | { | ||
274 | GNUNET_STATISTICS_update (statistics, | ||
275 | "Namecache updates skipped (NC disabled)", | ||
276 | 1, | ||
277 | GNUNET_NO); | ||
278 | return; | ||
279 | } | ||
280 | GNUNET_assert (NULL != block); | ||
281 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Caching block in namecache\n"); | ||
282 | GNUNET_STATISTICS_update (statistics, | ||
283 | "Namecache updates pushed", | ||
284 | 1, | ||
285 | GNUNET_NO); | ||
286 | cop = GNUNET_new (struct CacheOperation); | ||
287 | GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); | ||
288 | cop->qe = GNUNET_NAMECACHE_block_cache (namecache, | ||
289 | block, | ||
290 | &finish_cache_operation, | ||
291 | cop); | ||
292 | } | ||
293 | |||
294 | |||
175 | 295 | ||
176 | /** | 296 | /** |
177 | * Continuation called from DHT once the PUT operation triggered | 297 | * Continuation called from DHT once the PUT operation triggered |
@@ -207,15 +327,35 @@ dht_put_monitor_continuation (void *cls) | |||
207 | static struct GNUNET_DHT_PutHandle * | 327 | static struct GNUNET_DHT_PutHandle * |
208 | perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | 328 | perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, |
209 | const char *label, | 329 | const char *label, |
210 | const struct GNUNET_GNSRECORD_Data *rd_public, | 330 | const struct GNUNET_GNSRECORD_Data *rd, |
211 | unsigned int rd_public_count, | 331 | unsigned int rd_count, |
212 | struct GNUNET_TIME_Absolute expire, | 332 | struct GNUNET_TIME_Absolute expire, |
213 | struct DhtPutActivity *ma) | 333 | struct DhtPutActivity *ma) |
214 | { | 334 | { |
335 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | ||
215 | struct GNUNET_GNSRECORD_Block *block; | 336 | struct GNUNET_GNSRECORD_Block *block; |
337 | struct GNUNET_GNSRECORD_Block *block_priv; | ||
216 | struct GNUNET_HashCode query; | 338 | struct GNUNET_HashCode query; |
339 | struct GNUNET_TIME_Absolute expire_priv; | ||
217 | size_t block_size; | 340 | size_t block_size; |
341 | unsigned int rd_public_count = 0; | ||
218 | struct GNUNET_DHT_PutHandle *ret; | 342 | struct GNUNET_DHT_PutHandle *ret; |
343 | char *emsg; | ||
344 | |||
345 | if (GNUNET_OK != | ||
346 | GNUNET_GNSRECORD_normalize_record_set (label, | ||
347 | rd, | ||
348 | rd_count, | ||
349 | rd_public, | ||
350 | &rd_public_count, | ||
351 | &expire_priv, | ||
352 | GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, | ||
353 | &emsg)) | ||
354 | { | ||
355 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
356 | "%s\n", emsg); | ||
357 | GNUNET_free (emsg); | ||
358 | } | ||
219 | 359 | ||
220 | if (cache_keys) | 360 | if (cache_keys) |
221 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, | 361 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, |
@@ -236,6 +376,15 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
236 | GNUNET_break (0); | 376 | GNUNET_break (0); |
237 | return NULL; /* whoops */ | 377 | return NULL; /* whoops */ |
238 | } | 378 | } |
379 | if (rd_count != rd_public_count) | ||
380 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, | ||
381 | expire_priv, | ||
382 | label, | ||
383 | rd, | ||
384 | rd_count, | ||
385 | &block_priv)); | ||
386 | else | ||
387 | block_priv = block; | ||
239 | block_size = GNUNET_GNSRECORD_block_get_size (block); | 388 | block_size = GNUNET_GNSRECORD_block_get_size (block); |
240 | GNUNET_GNSRECORD_query_from_private_key (key, | 389 | GNUNET_GNSRECORD_query_from_private_key (key, |
241 | label, | 390 | label, |
@@ -260,6 +409,9 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
260 | expire, | 409 | expire, |
261 | &dht_put_monitor_continuation, | 410 | &dht_put_monitor_continuation, |
262 | ma); | 411 | ma); |
412 | refresh_block (block_priv); | ||
413 | if (block != block_priv) | ||
414 | GNUNET_free (block_priv); | ||
263 | GNUNET_free (block); | 415 | GNUNET_free (block); |
264 | return ret; | 416 | return ret; |
265 | } | 417 | } |
@@ -379,6 +531,25 @@ run (void *cls, | |||
379 | GNUNET_SCHEDULER_shutdown (); | 531 | GNUNET_SCHEDULER_shutdown (); |
380 | return; | 532 | return; |
381 | } | 533 | } |
534 | disable_namecache = GNUNET_CONFIGURATION_get_value_yesno (c, | ||
535 | "namecache", | ||
536 | "DISABLE"); | ||
537 | if (GNUNET_NO == disable_namecache) | ||
538 | { | ||
539 | namecache = GNUNET_NAMECACHE_connect (c); | ||
540 | if (NULL == namecache) | ||
541 | { | ||
542 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
543 | _ ("Failed to connect to the namecache!\n")); | ||
544 | GNUNET_SCHEDULER_shutdown (); | ||
545 | return; | ||
546 | } | ||
547 | } | ||
548 | else | ||
549 | { | ||
550 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
551 | _ ("Namecache is disabled!\n")); | ||
552 | } | ||
382 | cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c, | 553 | cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c, |
383 | "namestore", | 554 | "namestore", |
384 | "CACHE_KEYS"); | 555 | "CACHE_KEYS"); |
@@ -417,7 +588,7 @@ run (void *cls, | |||
417 | NULL, | 588 | NULL, |
418 | NULL /* sync_cb */, | 589 | NULL /* sync_cb */, |
419 | NULL, | 590 | NULL, |
420 | GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE); | 591 | GNUNET_GNSRECORD_FILTER_NONE); |
421 | GNUNET_NAMESTORE_zone_monitor_next (zmon, | 592 | GNUNET_NAMESTORE_zone_monitor_next (zmon, |
422 | NAMESTORE_QUEUE_LIMIT - 1); | 593 | NAMESTORE_QUEUE_LIMIT - 1); |
423 | GNUNET_break (NULL != zmon); | 594 | GNUNET_break (NULL != zmon); |
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c index dba1b24ce..ded86c7fa 100644 --- a/src/zonemaster/gnunet-service-zonemaster.c +++ b/src/zonemaster/gnunet-service-zonemaster.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "gnunet_dnsparser_lib.h" | 28 | #include "gnunet_dnsparser_lib.h" |
29 | #include "gnunet_dht_service.h" | 29 | #include "gnunet_dht_service.h" |
30 | #include "gnunet_namestore_service.h" | 30 | #include "gnunet_namestore_service.h" |
31 | #include "gnunet_namecache_service.h" | ||
31 | #include "gnunet_statistics_service.h" | 32 | #include "gnunet_statistics_service.h" |
32 | 33 | ||
33 | #define LOG_STRERROR_FILE(kind, syscall, \ | 34 | #define LOG_STRERROR_FILE(kind, syscall, \ |
@@ -115,6 +116,28 @@ struct DhtPutActivity | |||
115 | struct GNUNET_TIME_Absolute start_date; | 116 | struct GNUNET_TIME_Absolute start_date; |
116 | }; | 117 | }; |
117 | 118 | ||
119 | /** | ||
120 | * Pending operation on the namecache. | ||
121 | */ | ||
122 | struct CacheOperation | ||
123 | { | ||
124 | /** | ||
125 | * Kept in a DLL. | ||
126 | */ | ||
127 | struct CacheOperation *prev; | ||
128 | |||
129 | /** | ||
130 | * Kept in a DLL. | ||
131 | */ | ||
132 | struct CacheOperation *next; | ||
133 | |||
134 | /** | ||
135 | * Handle to namecache queue. | ||
136 | */ | ||
137 | struct GNUNET_NAMECACHE_QueueEntry *qe; | ||
138 | |||
139 | }; | ||
140 | |||
118 | 141 | ||
119 | /** | 142 | /** |
120 | * Handle to the statistics service | 143 | * Handle to the statistics service |
@@ -132,6 +155,17 @@ static struct GNUNET_DHT_Handle *dht_handle; | |||
132 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; | 155 | static struct GNUNET_NAMESTORE_Handle *namestore_handle; |
133 | 156 | ||
134 | /** | 157 | /** |
158 | * Our handle to the namecache service | ||
159 | */ | ||
160 | static struct GNUNET_NAMECACHE_Handle *namecache; | ||
161 | |||
162 | /** | ||
163 | * Use the namecache? Doing so creates additional cryptographic | ||
164 | * operations whenever we touch a record. | ||
165 | */ | ||
166 | static int disable_namecache; | ||
167 | |||
168 | /** | ||
135 | * Handle to iterate over our authoritative zone in namestore | 169 | * Handle to iterate over our authoritative zone in namestore |
136 | */ | 170 | */ |
137 | static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; | 171 | static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; |
@@ -235,6 +269,16 @@ static int first_zone_iteration; | |||
235 | */ | 269 | */ |
236 | static int cache_keys; | 270 | static int cache_keys; |
237 | 271 | ||
272 | /** | ||
273 | * Head of cop DLL. | ||
274 | */ | ||
275 | static struct CacheOperation *cop_head; | ||
276 | |||
277 | /** | ||
278 | * Tail of cop DLL. | ||
279 | */ | ||
280 | static struct CacheOperation *cop_tail; | ||
281 | |||
238 | 282 | ||
239 | /** | 283 | /** |
240 | * Task run during shutdown. | 284 | * Task run during shutdown. |
@@ -246,10 +290,20 @@ static void | |||
246 | shutdown_task (void *cls) | 290 | shutdown_task (void *cls) |
247 | { | 291 | { |
248 | struct DhtPutActivity *ma; | 292 | struct DhtPutActivity *ma; |
293 | struct CacheOperation *cop; | ||
249 | 294 | ||
250 | (void) cls; | 295 | (void) cls; |
251 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 296 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
252 | "Shutting down!\n"); | 297 | "Shutting down!\n"); |
298 | while (NULL != (cop = cop_head)) | ||
299 | { | ||
300 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
301 | "Aborting incomplete namecache operation\n"); | ||
302 | GNUNET_NAMECACHE_cancel (cop->qe); | ||
303 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | ||
304 | GNUNET_free (cop); | ||
305 | } | ||
306 | |||
253 | while (NULL != (ma = it_head)) | 307 | while (NULL != (ma = it_head)) |
254 | { | 308 | { |
255 | GNUNET_DHT_put_cancel (ma->ph); | 309 | GNUNET_DHT_put_cancel (ma->ph); |
@@ -281,13 +335,78 @@ shutdown_task (void *cls) | |||
281 | GNUNET_NAMESTORE_disconnect (namestore_handle); | 335 | GNUNET_NAMESTORE_disconnect (namestore_handle); |
282 | namestore_handle = NULL; | 336 | namestore_handle = NULL; |
283 | } | 337 | } |
284 | if (NULL != dht_handle) | 338 | if (NULL != namecache) |
339 | { | ||
340 | GNUNET_NAMECACHE_disconnect (namecache); | ||
341 | namecache = NULL; | ||
342 | } | ||
343 | if (NULL != dht_handle) | ||
285 | { | 344 | { |
286 | GNUNET_DHT_disconnect (dht_handle); | 345 | GNUNET_DHT_disconnect (dht_handle); |
287 | dht_handle = NULL; | 346 | dht_handle = NULL; |
288 | } | 347 | } |
289 | } | 348 | } |
290 | 349 | ||
350 | /** | ||
351 | * Cache operation complete, clean up. | ||
352 | * | ||
353 | * @param cls the `struct CacheOperation` | ||
354 | * @param success success | ||
355 | * @param emsg error messages | ||
356 | */ | ||
357 | static void | ||
358 | finish_cache_operation (void *cls, int32_t success, const char *emsg) | ||
359 | { | ||
360 | struct CacheOperation *cop = cls; | ||
361 | |||
362 | if (NULL != emsg) | ||
363 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
364 | _ ("Failed to replicate block in namecache: %s\n"), | ||
365 | emsg); | ||
366 | else | ||
367 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CACHE operation completed\n"); | ||
368 | GNUNET_CONTAINER_DLL_remove (cop_head, cop_tail, cop); | ||
369 | GNUNET_free (cop); | ||
370 | } | ||
371 | |||
372 | |||
373 | /** | ||
374 | * Refresh the (encrypted) block in the namecache. | ||
375 | * | ||
376 | * @param zone_key private key of the zone | ||
377 | * @param name label for the records | ||
378 | * @param rd_count number of records | ||
379 | * @param rd records stored under the given @a name | ||
380 | */ | ||
381 | static void | ||
382 | refresh_block (const struct GNUNET_GNSRECORD_Block *block) | ||
383 | { | ||
384 | struct CacheOperation *cop; | ||
385 | struct GNUNET_TIME_Absolute exp_time; | ||
386 | |||
387 | if (GNUNET_YES == disable_namecache) | ||
388 | { | ||
389 | GNUNET_STATISTICS_update (statistics, | ||
390 | "Namecache updates skipped (NC disabled)", | ||
391 | 1, | ||
392 | GNUNET_NO); | ||
393 | return; | ||
394 | } | ||
395 | GNUNET_assert (NULL != block); | ||
396 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Caching block in namecache\n"); | ||
397 | GNUNET_STATISTICS_update (statistics, | ||
398 | "Namecache updates pushed", | ||
399 | 1, | ||
400 | GNUNET_NO); | ||
401 | cop = GNUNET_new (struct CacheOperation); | ||
402 | GNUNET_CONTAINER_DLL_insert (cop_head, cop_tail, cop); | ||
403 | cop->qe = GNUNET_NAMECACHE_block_cache (namecache, | ||
404 | block, | ||
405 | &finish_cache_operation, | ||
406 | cop); | ||
407 | } | ||
408 | |||
409 | |||
291 | 410 | ||
292 | /** | 411 | /** |
293 | * Method called periodically that triggers iteration over authoritative records | 412 | * Method called periodically that triggers iteration over authoritative records |
@@ -539,35 +658,68 @@ dht_put_continuation (void *cls) | |||
539 | static struct GNUNET_DHT_PutHandle * | 658 | static struct GNUNET_DHT_PutHandle * |
540 | perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | 659 | perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, |
541 | const char *label, | 660 | const char *label, |
542 | const struct GNUNET_GNSRECORD_Data *rd_public, | 661 | const struct GNUNET_GNSRECORD_Data *rd, |
543 | unsigned int rd_public_count, | 662 | unsigned int rd_count, |
544 | const struct GNUNET_TIME_Absolute expire, | 663 | const struct GNUNET_TIME_Absolute expire, |
545 | struct DhtPutActivity *ma) | 664 | struct DhtPutActivity *ma) |
546 | { | 665 | { |
666 | struct GNUNET_GNSRECORD_Data rd_public[rd_count]; | ||
547 | struct GNUNET_GNSRECORD_Block *block; | 667 | struct GNUNET_GNSRECORD_Block *block; |
668 | struct GNUNET_GNSRECORD_Block *block_priv; | ||
548 | struct GNUNET_HashCode query; | 669 | struct GNUNET_HashCode query; |
670 | struct GNUNET_TIME_Absolute expire_priv; | ||
549 | size_t block_size; | 671 | size_t block_size; |
672 | unsigned int rd_public_count = 0; | ||
550 | struct GNUNET_DHT_PutHandle *ret; | 673 | struct GNUNET_DHT_PutHandle *ret; |
674 | char *emsg; | ||
675 | |||
676 | if (GNUNET_OK != | ||
677 | GNUNET_GNSRECORD_normalize_record_set (label, | ||
678 | rd, | ||
679 | rd_count, | ||
680 | rd_public, | ||
681 | &rd_public_count, | ||
682 | &expire_priv, | ||
683 | GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE, | ||
684 | &emsg)) | ||
685 | { | ||
686 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
687 | "%s\n", emsg); | ||
688 | GNUNET_free (emsg); | ||
689 | } | ||
551 | 690 | ||
552 | if (cache_keys) | 691 | if (cache_keys) |
692 | { | ||
553 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, | 693 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create2 (key, |
554 | expire, | 694 | expire, |
555 | label, | 695 | label, |
556 | rd_public, | 696 | rd_public, |
557 | rd_public_count, | 697 | rd_public_count, |
558 | &block)); | 698 | &block)); |
699 | } | ||
559 | else | 700 | else |
560 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, | 701 | { |
561 | expire, | 702 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, |
562 | label, | 703 | expire, |
563 | rd_public, | 704 | label, |
564 | rd_public_count, | 705 | rd_public, |
565 | &block)); | 706 | rd_public_count, |
707 | &block)); | ||
708 | } | ||
566 | if (NULL == block) | 709 | if (NULL == block) |
567 | { | 710 | { |
568 | GNUNET_break (0); | 711 | GNUNET_break (0); |
569 | return NULL; /* whoops */ | 712 | return NULL; /* whoops */ |
570 | } | 713 | } |
714 | if (rd_count != rd_public_count) | ||
715 | GNUNET_assert (GNUNET_OK == GNUNET_GNSRECORD_block_create (key, | ||
716 | expire_priv, | ||
717 | label, | ||
718 | rd, | ||
719 | rd_count, | ||
720 | &block_priv)); | ||
721 | else | ||
722 | block_priv = block; | ||
571 | block_size = GNUNET_GNSRECORD_block_get_size (block); | 723 | block_size = GNUNET_GNSRECORD_block_get_size (block); |
572 | GNUNET_GNSRECORD_query_from_private_key (key, | 724 | GNUNET_GNSRECORD_query_from_private_key (key, |
573 | label, | 725 | label, |
@@ -593,6 +745,9 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key, | |||
593 | expire, | 745 | expire, |
594 | &dht_put_continuation, | 746 | &dht_put_continuation, |
595 | ma); | 747 | ma); |
748 | refresh_block (block_priv); | ||
749 | if (block != block_priv) | ||
750 | GNUNET_free (block_priv); | ||
596 | GNUNET_free (block); | 751 | GNUNET_free (block); |
597 | return ret; | 752 | return ret; |
598 | } | 753 | } |
@@ -783,7 +938,7 @@ publish_zone_dht_start (void *cls) | |||
783 | NULL, | 938 | NULL, |
784 | &zone_iteration_finished, | 939 | &zone_iteration_finished, |
785 | NULL, | 940 | NULL, |
786 | GNUNET_GNSRECORD_FILTER_OMIT_PRIVATE); | 941 | GNUNET_GNSRECORD_FILTER_NONE); |
787 | GNUNET_assert (NULL != namestore_iter); | 942 | GNUNET_assert (NULL != namestore_iter); |
788 | } | 943 | } |
789 | 944 | ||
@@ -816,6 +971,20 @@ run (void *cls, | |||
816 | GNUNET_SCHEDULER_shutdown (); | 971 | GNUNET_SCHEDULER_shutdown (); |
817 | return; | 972 | return; |
818 | } | 973 | } |
974 | disable_namecache = GNUNET_CONFIGURATION_get_value_yesno (c, | ||
975 | "namecache", | ||
976 | "DISABLE"); | ||
977 | if (GNUNET_NO == disable_namecache) | ||
978 | { | ||
979 | namecache = GNUNET_NAMECACHE_connect (c); | ||
980 | if (NULL == namecache) | ||
981 | { | ||
982 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
983 | _ ("Failed to connect to the namecache!\n")); | ||
984 | GNUNET_SCHEDULER_shutdown (); | ||
985 | return; | ||
986 | } | ||
987 | } | ||
819 | cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c, | 988 | cache_keys = GNUNET_CONFIGURATION_get_value_yesno (c, |
820 | "namestore", | 989 | "namestore", |
821 | "CACHE_KEYS"); | 990 | "CACHE_KEYS"); |