aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorNils Gillmann <ng0@n0.is>2018-11-13 11:42:15 +0000
committerNils Gillmann <ng0@n0.is>2018-11-13 11:42:15 +0000
commit9d1e77b9331acb9bd8b6c99aa942f62b9759e650 (patch)
tree85475b117fff75b563a6f9512d3ead476a830f7d /src/namestore
parente8a1a082555f98af40f98fd3a20ccd803ad478f8 (diff)
parent98288a7b26344294a3668101b9c2b502dfc19e12 (diff)
downloadgnunet-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.c330
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 */
38struct 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 */
38static struct GNUNET_NAMESTORE_Handle *ns; 56static struct GNUNET_NAMESTORE_Handle *ns;
@@ -173,14 +191,10 @@ static void *data;
173static size_t data_size; 191static size_t data_size;
174 192
175/** 193/**
176 * Expirationstring converted to relative time. 194 * Expiration string converted to numeric value.
177 */ 195 */
178static struct GNUNET_TIME_Relative etime_rel; 196static uint64_t etime;
179 197
180/**
181 * Expirationstring converted to absolute time.
182 */
183static 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 */
198static int monitor; 212static int monitor;
199 213
214/**
215 * Entry in record set for processing records in bulk.
216 */
217static 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 */
891static int
892parse_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? */
935unsigned int rd_count;
936struct GNUNET_GNSRECORD_Data *rd;
937
938
939rd_count = 0;
940for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
941 rd_count++;
942rd = GNUNET_new_array (rd_count,
943 struct GNUNET_GNSRECORD_Data);
944rd_count = 0;
945for (struct RecordSetEntry *e = recordset; NULL != e; e = e->next)
946{
947 rd[rd_count] = e->record;
948 rd_count++;
949}
950
951/* if add: */
952qe = GNUNET_NAMESTORE_records_store (...,
953 rd_count,
954 rd,
955 &my_cont
956 ..);
957
958in 'my_cont' and/or shutdown:
959
960qe = NULL;
961GNUNET_free (rd);
962
963in shutdown:
964
965if NULL != qe NAMESTORE_cancel (qe);
966GNUNET_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 */
1341static int
1342multirecord_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 */
1458struct GNUNET_GETOPT_CommandLineOption
1459multirecord_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",