diff options
author | Nils Gillmann <ng0@n0.is> | 2018-11-13 11:42:15 +0000 |
---|---|---|
committer | Nils Gillmann <ng0@n0.is> | 2018-11-13 11:42:15 +0000 |
commit | 9d1e77b9331acb9bd8b6c99aa942f62b9759e650 (patch) | |
tree | 85475b117fff75b563a6f9512d3ead476a830f7d /src/namestore | |
parent | e8a1a082555f98af40f98fd3a20ccd803ad478f8 (diff) | |
parent | 98288a7b26344294a3668101b9c2b502dfc19e12 (diff) | |
download | gnunet-9d1e77b9331acb9bd8b6c99aa942f62b9759e650.tar.gz gnunet-9d1e77b9331acb9bd8b6c99aa942f62b9759e650.zip |
Merge branch 'master' of gnunet.org:gnunet
Diffstat (limited to 'src/namestore')
-rw-r--r-- | src/namestore/gnunet-namestore.c | 330 |
1 files changed, 283 insertions, 47 deletions
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c index c5f48848e..619d0c528 100644 --- a/src/namestore/gnunet-namestore.c +++ b/src/namestore/gnunet-namestore.c | |||
@@ -33,6 +33,24 @@ | |||
33 | 33 | ||
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Entry in record set for bulk processing. | ||
37 | */ | ||
38 | struct RecordSetEntry | ||
39 | { | ||
40 | /** | ||
41 | * Kept in a linked list. | ||
42 | */ | ||
43 | struct RecordSetEntry *next; | ||
44 | |||
45 | /** | ||
46 | * The record to add/remove. | ||
47 | */ | ||
48 | struct GNUNET_GNSRECORD_Data record; | ||
49 | |||
50 | }; | ||
51 | |||
52 | |||
53 | /** | ||
36 | * Handle to the namestore. | 54 | * Handle to the namestore. |
37 | */ | 55 | */ |
38 | static struct GNUNET_NAMESTORE_Handle *ns; | 56 | static struct GNUNET_NAMESTORE_Handle *ns; |
@@ -173,14 +191,10 @@ static void *data; | |||
173 | static size_t data_size; | 191 | static size_t data_size; |
174 | 192 | ||
175 | /** | 193 | /** |
176 | * Expirationstring converted to relative time. | 194 | * Expiration string converted to numeric value. |
177 | */ | 195 | */ |
178 | static struct GNUNET_TIME_Relative etime_rel; | 196 | static uint64_t etime; |
179 | 197 | ||
180 | /** | ||
181 | * Expirationstring converted to absolute time. | ||
182 | */ | ||
183 | static struct GNUNET_TIME_Absolute etime_abs; | ||
184 | 198 | ||
185 | /** | 199 | /** |
186 | * Is expiration time relative or absolute time? | 200 | * Is expiration time relative or absolute time? |
@@ -197,6 +211,11 @@ static struct GNUNET_NAMESTORE_ZoneMonitor *zm; | |||
197 | */ | 211 | */ |
198 | static int monitor; | 212 | static int monitor; |
199 | 213 | ||
214 | /** | ||
215 | * Entry in record set for processing records in bulk. | ||
216 | */ | ||
217 | static struct RecordSetEntry *recordset; | ||
218 | |||
200 | 219 | ||
201 | /** | 220 | /** |
202 | * Task run on shutdown. Cleans up everything. | 221 | * Task run on shutdown. Cleans up everything. |
@@ -516,6 +535,8 @@ display_record_lookup (void *cls, | |||
516 | unsigned int rd_len, | 535 | unsigned int rd_len, |
517 | const struct GNUNET_GNSRECORD_Data *rd) | 536 | const struct GNUNET_GNSRECORD_Data *rd) |
518 | { | 537 | { |
538 | (void) cls; | ||
539 | (void) zone_key; | ||
519 | get_qe = NULL; | 540 | get_qe = NULL; |
520 | display_record (rname, | 541 | display_record (rname, |
521 | rd_len, | 542 | rd_len, |
@@ -694,14 +715,10 @@ get_existing_record (void *cls, | |||
694 | rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; | 715 | rde->flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; |
695 | if (1 != is_public) | 716 | if (1 != is_public) |
696 | rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE; | 717 | rde->flags |= GNUNET_GNSRECORD_RF_PRIVATE; |
718 | rde->expiration_time = etime; | ||
697 | if (GNUNET_YES == etime_is_rel) | 719 | if (GNUNET_YES == etime_is_rel) |
698 | { | ||
699 | rde->expiration_time = etime_rel.rel_value_us; | ||
700 | rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | 720 | rde->flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
701 | } | 721 | else if (GNUNET_NO != etime_is_rel) |
702 | else if (GNUNET_NO == etime_is_rel) | ||
703 | rde->expiration_time = etime_abs.abs_value_us; | ||
704 | else | ||
705 | rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | 722 | rde->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; |
706 | GNUNET_assert (NULL != name); | 723 | GNUNET_assert (NULL != name); |
707 | add_qe = GNUNET_NAMESTORE_records_store (ns, | 724 | add_qe = GNUNET_NAMESTORE_records_store (ns, |
@@ -864,6 +881,94 @@ del_monitor (void *cls, | |||
864 | 881 | ||
865 | 882 | ||
866 | /** | 883 | /** |
884 | * Parse expiration time. | ||
885 | * | ||
886 | * @param expirationstring text to parse | ||
887 | * @param etime_is_rel[out] set to #GNUNET_YES if time is relative | ||
888 | * @param etime[out] set to expiration time (abs or rel) | ||
889 | * @return #GNUNET_OK on success | ||
890 | */ | ||
891 | static int | ||
892 | parse_expiration (const char *expirationstring, | ||
893 | int *etime_is_rel, | ||
894 | uint64_t *etime) | ||
895 | { | ||
896 | struct GNUNET_TIME_Relative etime_rel; | ||
897 | struct GNUNET_TIME_Absolute etime_abs; | ||
898 | |||
899 | if (0 == strcmp (expirationstring, | ||
900 | "never")) | ||
901 | { | ||
902 | *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
903 | *etime_is_rel = GNUNET_NO; | ||
904 | return GNUNET_OK; | ||
905 | } | ||
906 | if (GNUNET_OK == | ||
907 | GNUNET_STRINGS_fancy_time_to_relative (expirationstring, | ||
908 | &etime_rel)) | ||
909 | { | ||
910 | *etime_is_rel = GNUNET_YES; | ||
911 | *etime = etime_rel.rel_value_us; | ||
912 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
913 | "Storing record with relative expiration time of %s\n", | ||
914 | GNUNET_STRINGS_relative_time_to_string (etime_rel, | ||
915 | GNUNET_NO)); | ||
916 | return GNUNET_OK; | ||
917 | } | ||
918 | if (GNUNET_OK == | ||
919 | GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, | ||
920 | &etime_abs)) | ||
921 | { | ||
922 | *etime_is_rel = GNUNET_NO; | ||
923 | *etime = etime_abs.abs_value_us; | ||
924 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
925 | "Storing record with absolute expiration time of %s\n", | ||
926 | GNUNET_STRINGS_absolute_time_to_string (etime_abs)); | ||
927 | return GNUNET_OK; | ||
928 | } | ||
929 | return GNUNET_SYSERR; | ||
930 | } | ||
931 | |||
932 | |||
933 | #if 0 | ||
934 | /* globals? */ | ||
935 | unsigned int rd_count; | ||
936 | struct GNUNET_GNSRECORD_Data *rd; | ||
937 | |||
938 | |||
939 | rd_count = 0; | ||
940 | for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next) | ||
941 | rd_count++; | ||
942 | rd = GNUNET_new_array (rd_count, | ||
943 | struct GNUNET_GNSRECORD_Data); | ||
944 | rd_count = 0; | ||
945 | for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next) | ||
946 | { | ||
947 | rd[rd_count] = e->record; | ||
948 | rd_count++; | ||
949 | } | ||
950 | |||
951 | /* if add: */ | ||
952 | qe = GNUNET_NAMESTORE_records_store (..., | ||
953 | rd_count, | ||
954 | rd, | ||
955 | &my_cont | ||
956 | ..); | ||
957 | |||
958 | in 'my_cont' and/or shutdown: | ||
959 | |||
960 | qe = NULL; | ||
961 | GNUNET_free (rd); | ||
962 | |||
963 | in shutdown: | ||
964 | |||
965 | if NULL != qe NAMESTORE_cancel (qe); | ||
966 | GNUNET_free (rd); | ||
967 | |||
968 | #endif | ||
969 | |||
970 | |||
971 | /** | ||
867 | * Callback invoked from identity service with ego information. | 972 | * Callback invoked from identity service with ego information. |
868 | * An @a ego of NULL means the ego was not found. | 973 | * An @a ego of NULL means the ego was not found. |
869 | * | 974 | * |
@@ -976,32 +1081,10 @@ identity_cb (void *cls, | |||
976 | ret = 1; | 1081 | ret = 1; |
977 | return; | 1082 | return; |
978 | } | 1083 | } |
979 | if (0 == strcmp (expirationstring, | 1084 | if (GNUNET_OK != |
980 | "never")) | 1085 | parse_expiration (expirationstring, |
981 | { | 1086 | &etime_is_rel, |
982 | etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS; | 1087 | &etime)) |
983 | etime_is_rel = GNUNET_NO; | ||
984 | } | ||
985 | else if (GNUNET_OK == | ||
986 | GNUNET_STRINGS_fancy_time_to_relative (expirationstring, | ||
987 | &etime_rel)) | ||
988 | { | ||
989 | etime_is_rel = GNUNET_YES; | ||
990 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
991 | "Storing record with relative expiration time of %s\n", | ||
992 | GNUNET_STRINGS_relative_time_to_string (etime_rel, | ||
993 | GNUNET_NO)); | ||
994 | } | ||
995 | else if (GNUNET_OK == | ||
996 | GNUNET_STRINGS_fancy_time_to_absolute (expirationstring, | ||
997 | &etime_abs)) | ||
998 | { | ||
999 | etime_is_rel = GNUNET_NO; | ||
1000 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1001 | "Storing record with absolute expiration time of %s\n", | ||
1002 | GNUNET_STRINGS_absolute_time_to_string (etime_abs)); | ||
1003 | } | ||
1004 | else | ||
1005 | { | 1088 | { |
1006 | fprintf (stderr, | 1089 | fprintf (stderr, |
1007 | _("Invalid time format `%s'\n"), | 1090 | _("Invalid time format `%s'\n"), |
@@ -1106,16 +1189,9 @@ identity_cb (void *cls, | |||
1106 | rd.data = &pkey; | 1189 | rd.data = &pkey; |
1107 | rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); | 1190 | rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); |
1108 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; | 1191 | rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; |
1109 | if (GNUNET_YES == etime_is_rel) | 1192 | rd.expiration_time = etime; |
1110 | { | 1193 | if (GNUNET_YES == etime_is_rel) |
1111 | rd.expiration_time = etime_rel.rel_value_us; | ||
1112 | rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | 1194 | rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; |
1113 | } | ||
1114 | else if (GNUNET_NO == etime_is_rel) | ||
1115 | rd.expiration_time = etime_abs.abs_value_us; | ||
1116 | else | ||
1117 | rd.expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; | ||
1118 | |||
1119 | if (1 == is_shadow) | 1195 | if (1 == is_shadow) |
1120 | rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; | 1196 | rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; |
1121 | add_qe_uri = GNUNET_NAMESTORE_records_store (ns, | 1197 | add_qe_uri = GNUNET_NAMESTORE_records_store (ns, |
@@ -1247,6 +1323,161 @@ run (void *cls, | |||
1247 | 1323 | ||
1248 | 1324 | ||
1249 | /** | 1325 | /** |
1326 | * Command-line option parser function that allows the user to specify | ||
1327 | * a complete record as one argument for adding/removing. A pointer | ||
1328 | * to the head of the list of record sets must be passed as the "scls" | ||
1329 | * argument. | ||
1330 | * | ||
1331 | * @param ctx command line processor context | ||
1332 | * @param scls must be of type "struct GNUNET_FS_Uri **" | ||
1333 | * @param option name of the option (typically 'R') | ||
1334 | * @param value command line argument given; format is | ||
1335 | * "TTL TYPE FLAGS VALUE" where TTL is an expiration time (rel or abs), | ||
1336 | * TYPE is a DNS/GNS record type, FLAGS is either "n" for no flags or | ||
1337 | * a combination of 's' (shadow) and 'p' (public) and VALUE is the | ||
1338 | * value (in human-readable format) | ||
1339 | * @return #GNUNET_OK on success | ||
1340 | */ | ||
1341 | static int | ||
1342 | multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx, | ||
1343 | void *scls, | ||
1344 | const char *option, | ||
1345 | const char *value) | ||
1346 | { | ||
1347 | struct RecordSetEntry **head = scls; | ||
1348 | struct RecordSetEntry *r; | ||
1349 | struct GNUNET_GNSRECORD_Data record; | ||
1350 | char *cp; | ||
1351 | char *tok; | ||
1352 | int etime_is_rel; | ||
1353 | void *raw_data; | ||
1354 | |||
1355 | (void) ctx; | ||
1356 | (void) option; | ||
1357 | cp = GNUNET_strdup (value); | ||
1358 | tok = strtok (cp, " "); | ||
1359 | if (NULL == tok) | ||
1360 | { | ||
1361 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1362 | _("Empty record line argument is not allowed.\n")); | ||
1363 | GNUNET_free (cp); | ||
1364 | return GNUNET_SYSERR; | ||
1365 | } | ||
1366 | if (GNUNET_OK != | ||
1367 | parse_expiration (tok, | ||
1368 | &etime_is_rel, | ||
1369 | &record.expiration_time)) | ||
1370 | { | ||
1371 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1372 | _("Invalid expiration time `%s'\n"), | ||
1373 | tok); | ||
1374 | GNUNET_free (cp); | ||
1375 | return GNUNET_SYSERR; | ||
1376 | } | ||
1377 | tok = strtok (NULL, " "); | ||
1378 | if (NULL == tok) | ||
1379 | { | ||
1380 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1381 | _("Missing entries in record line `%s'.\n"), | ||
1382 | value); | ||
1383 | GNUNET_free (cp); | ||
1384 | return GNUNET_SYSERR; | ||
1385 | } | ||
1386 | record.record_type = GNUNET_GNSRECORD_typename_to_number (tok); | ||
1387 | if (UINT32_MAX == record.record_type) | ||
1388 | { | ||
1389 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1390 | _("Unknown record type `%s'\n"), | ||
1391 | tok); | ||
1392 | GNUNET_free (cp); | ||
1393 | return GNUNET_SYSERR; | ||
1394 | } | ||
1395 | tok = strtok (NULL, " "); | ||
1396 | if (NULL == tok) | ||
1397 | { | ||
1398 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1399 | _("Missing entries in record line `%s'.\n"), | ||
1400 | value); | ||
1401 | GNUNET_free (cp); | ||
1402 | return GNUNET_SYSERR; | ||
1403 | } | ||
1404 | record.flags = GNUNET_GNSRECORD_RF_NONE; | ||
1405 | if (etime_is_rel) | ||
1406 | record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
1407 | if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */ | ||
1408 | record.flags |= GNUNET_GNSRECORD_RF_PRIVATE; | ||
1409 | if (NULL != strchr (tok, (unsigned char) 's')) | ||
1410 | record.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; | ||
1411 | /* find beginning of record value */ | ||
1412 | tok = strchr (&value[tok - cp], (unsigned char) ' '); | ||
1413 | if (NULL == tok) | ||
1414 | { | ||
1415 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1416 | _("Missing entries in record line `%s'.\n"), | ||
1417 | value); | ||
1418 | GNUNET_free (cp); | ||
1419 | return GNUNET_SYSERR; | ||
1420 | } | ||
1421 | GNUNET_free (cp); | ||
1422 | tok++; /* skip space */ | ||
1423 | if (GNUNET_OK != | ||
1424 | GNUNET_GNSRECORD_string_to_value (record.record_type, | ||
1425 | tok, | ||
1426 | &raw_data, | ||
1427 | &record.data_size)) | ||
1428 | { | ||
1429 | GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, | ||
1430 | _("Invalid record data for type %s: `%s'.\n"), | ||
1431 | GNUNET_GNSRECORD_number_to_typename (record.record_type), | ||
1432 | tok); | ||
1433 | return GNUNET_SYSERR; | ||
1434 | } | ||
1435 | |||
1436 | r = GNUNET_malloc (sizeof (struct RecordSetEntry) + record.data_size); | ||
1437 | r->next = *head; | ||
1438 | record.data = &r[1]; | ||
1439 | memcpy (&r[1], | ||
1440 | raw_data, | ||
1441 | record.data_size); | ||
1442 | GNUNET_free (raw_data); | ||
1443 | r->record = record; | ||
1444 | *head = r; | ||
1445 | return GNUNET_OK; | ||
1446 | } | ||
1447 | |||
1448 | |||
1449 | /** | ||
1450 | * Allow user to specify keywords. | ||
1451 | * | ||
1452 | * @param shortName short name of the option | ||
1453 | * @param name long name of the option | ||
1454 | * @param argumentHelp help text for the option argument | ||
1455 | * @param description long help text for the option | ||
1456 | * @param[out] topKeywords set to the desired value | ||
1457 | */ | ||
1458 | struct GNUNET_GETOPT_CommandLineOption | ||
1459 | multirecord_option (char shortName, | ||
1460 | const char *name, | ||
1461 | const char *argumentHelp, | ||
1462 | const char *description, | ||
1463 | struct RecordSetEntry **rs) | ||
1464 | { | ||
1465 | struct GNUNET_GETOPT_CommandLineOption clo = { | ||
1466 | .shortName = shortName, | ||
1467 | .name = name, | ||
1468 | .argumentHelp = argumentHelp, | ||
1469 | .description = description, | ||
1470 | .require_argument = 1, | ||
1471 | .processor = &multirecord_process, | ||
1472 | .scls = (void *) rs | ||
1473 | }; | ||
1474 | |||
1475 | return clo; | ||
1476 | } | ||
1477 | |||
1478 | |||
1479 | |||
1480 | /** | ||
1250 | * The main function for gnunet-namestore. | 1481 | * The main function for gnunet-namestore. |
1251 | * | 1482 | * |
1252 | * @param argc number of arguments from the command line | 1483 | * @param argc number of arguments from the command line |
@@ -1294,6 +1525,11 @@ main (int argc, | |||
1294 | "PKEY", | 1525 | "PKEY", |
1295 | gettext_noop ("determine our name for the given PKEY"), | 1526 | gettext_noop ("determine our name for the given PKEY"), |
1296 | &reverse_pkey), | 1527 | &reverse_pkey), |
1528 | multirecord_option ('R', | ||
1529 | "record", | ||
1530 | "RECORDLINE", | ||
1531 | gettext_noop ("complete record on one line to add/delete/display; can be specified multiple times"), | ||
1532 | &recordset), | ||
1297 | GNUNET_GETOPT_option_string ('t', | 1533 | GNUNET_GETOPT_option_string ('t', |
1298 | "type", | 1534 | "type", |
1299 | "TYPE", | 1535 | "TYPE", |