aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/namestore/gnunet-namestore.c273
1 files changed, 238 insertions, 35 deletions
diff --git a/src/namestore/gnunet-namestore.c b/src/namestore/gnunet-namestore.c
index c5f48848e..0f0660edc 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;
@@ -197,6 +215,11 @@ static struct GNUNET_NAMESTORE_ZoneMonitor *zm;
197 */ 215 */
198static int monitor; 216static int monitor;
199 217
218/**
219 * Entry in record set for processing records in bulk.
220 */
221static struct RecordSetEntry *recordset;
222
200 223
201/** 224/**
202 * Task run on shutdown. Cleans up everything. 225 * Task run on shutdown. Cleans up everything.
@@ -864,6 +887,56 @@ del_monitor (void *cls,
864 887
865 888
866/** 889/**
890 * Parse expiration time.
891 *
892 * @param expirationstring text to parse
893 * @param etime_is_rel[out] set to #GNUNET_YES if time is relative
894 * @param etime[out] set to expiration time (abs or rel)
895 * @return #GNUNET_OK on success
896 */
897static int
898parse_expiration (const char *expirationstring,
899 int *etime_is_rel,
900 uint64_t *etime)
901{
902 struct GNUNET_TIME_Relative etime_rel;
903 struct GNUNET_TIME_Absolute etime_abs;
904
905 if (0 == strcmp (expirationstring,
906 "never"))
907 {
908 *etime = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
909 *etime_is_rel = GNUNET_NO;
910 return GNUNET_OK;
911 }
912 if (GNUNET_OK ==
913 GNUNET_STRINGS_fancy_time_to_relative (expirationstring,
914 &etime_rel))
915 {
916 *etime_is_rel = GNUNET_YES;
917 *etime = etime_rel.rel_value_us;
918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
919 "Storing record with relative expiration time of %s\n",
920 GNUNET_STRINGS_relative_time_to_string (etime_rel,
921 GNUNET_NO));
922 return GNUNET_OK;
923 }
924 if (GNUNET_OK ==
925 GNUNET_STRINGS_fancy_time_to_absolute (expirationstring,
926 &etime_abs))
927 {
928 *etime_is_rel = GNUNET_NO;
929 *etime = etime_abs.abs_value_us;
930 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
931 "Storing record with absolute expiration time of %s\n",
932 GNUNET_STRINGS_absolute_time_to_string (etime_abs));
933 return GNUNET_OK;
934 }
935 return GNUNET_SYSERR;
936}
937
938
939/**
867 * Callback invoked from identity service with ego information. 940 * Callback invoked from identity service with ego information.
868 * An @a ego of NULL means the ego was not found. 941 * An @a ego of NULL means the ego was not found.
869 * 942 *
@@ -877,6 +950,7 @@ identity_cb (void *cls,
877 const struct GNUNET_CONFIGURATION_Handle *cfg = cls; 950 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
878 struct GNUNET_CRYPTO_EcdsaPublicKey pub; 951 struct GNUNET_CRYPTO_EcdsaPublicKey pub;
879 struct GNUNET_GNSRECORD_Data rd; 952 struct GNUNET_GNSRECORD_Data rd;
953 uint64_t etime;
880 954
881 el = NULL; 955 el = NULL;
882 if (NULL == ego) 956 if (NULL == ego)
@@ -976,32 +1050,10 @@ identity_cb (void *cls,
976 ret = 1; 1050 ret = 1;
977 return; 1051 return;
978 } 1052 }
979 if (0 == strcmp (expirationstring, 1053 if (GNUNET_OK !=
980 "never")) 1054 parse_expiration (expirationstring,
981 { 1055 &etime_is_rel,
982 etime_abs = GNUNET_TIME_UNIT_FOREVER_ABS; 1056 &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 { 1057 {
1006 fprintf (stderr, 1058 fprintf (stderr,
1007 _("Invalid time format `%s'\n"), 1059 _("Invalid time format `%s'\n"),
@@ -1106,16 +1158,9 @@ identity_cb (void *cls,
1106 rd.data = &pkey; 1158 rd.data = &pkey;
1107 rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey); 1159 rd.data_size = sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey);
1108 rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY; 1160 rd.record_type = GNUNET_GNSRECORD_TYPE_PKEY;
1109 if (GNUNET_YES == etime_is_rel) 1161 rd.expiration_time = etime;
1110 { 1162 if (GNUNET_YES == etime_is_rel)
1111 rd.expiration_time = etime_rel.rel_value_us;
1112 rd.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; 1163 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) 1164 if (1 == is_shadow)
1120 rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD; 1165 rd.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
1121 add_qe_uri = GNUNET_NAMESTORE_records_store (ns, 1166 add_qe_uri = GNUNET_NAMESTORE_records_store (ns,
@@ -1247,6 +1292,159 @@ run (void *cls,
1247 1292
1248 1293
1249/** 1294/**
1295 * Command-line option parser function that allows the user to specify
1296 * a complete record as one argument for adding/removing. A pointer
1297 * to the head of the list of record sets must be passed as the "scls"
1298 * argument.
1299 *
1300 * @param ctx command line processor context
1301 * @param scls must be of type "struct GNUNET_FS_Uri **"
1302 * @param option name of the option (typically 'R')
1303 * @param value command line argument given; format is
1304 * "TTL TYPE FLAGS VALUE" where TTL is an expiration time (rel or abs),
1305 * TYPE is a DNS/GNS record type, FLAGS is either "n" for no flags or
1306 * a combination of 's' (shadow) and 'p' (public) and VALUE is the
1307 * value (in human-readable format)
1308 * @return #GNUNET_OK on success
1309 */
1310static int
1311multirecord_process (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
1312 void *scls,
1313 const char *option,
1314 const char *value)
1315{
1316 struct RecordSetEntry **head = scls;
1317 struct RecordSetEntry *r;
1318 struct GNUNET_GNSRECORD_Data record;
1319 char *cp;
1320 char *tok;
1321 int etime_is_rel;
1322 void *raw_data;
1323
1324 cp = GNUNET_strdup (value);
1325 tok = strtok (cp, " ");
1326 if (NULL == tok)
1327 {
1328 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1329 _("Empty record line argument is not allowed.\n"));
1330 GNUNET_free (cp);
1331 return GNUNET_SYSERR;
1332 }
1333 if (GNUNET_OK !=
1334 parse_expiration (tok,
1335 &etime_is_rel,
1336 &record.expiration_time))
1337 {
1338 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1339 _("Invalid expiration time `%s'\n"),
1340 tok);
1341 GNUNET_free (cp);
1342 return GNUNET_SYSERR;
1343 }
1344 tok = strtok (NULL, " ");
1345 if (NULL == tok)
1346 {
1347 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1348 _("Missing entries in record line `%s'.\n"),
1349 value);
1350 GNUNET_free (cp);
1351 return GNUNET_SYSERR;
1352 }
1353 record.record_type = GNUNET_GNSRECORD_typename_to_number (tok);
1354 if (UINT32_MAX == record.record_type)
1355 {
1356 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1357 _("Unknown record type `%s'\n"),
1358 tok);
1359 GNUNET_free (cp);
1360 return GNUNET_SYSERR;
1361 }
1362 tok = strtok (NULL, " ");
1363 if (NULL == tok)
1364 {
1365 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1366 _("Missing entries in record line `%s'.\n"),
1367 value);
1368 GNUNET_free (cp);
1369 return GNUNET_SYSERR;
1370 }
1371 record.flags = GNUNET_GNSRECORD_RF_NONE;
1372 if (etime_is_rel)
1373 record.flags |= GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
1374 if (NULL == strchr (tok, (unsigned char) 'p')) /* p = public */
1375 record.flags |= GNUNET_GNSRECORD_RF_PRIVATE;
1376 if (NULL != strchr (tok, (unsigned char) 's'))
1377 record.flags |= GNUNET_GNSRECORD_RF_SHADOW_RECORD;
1378 /* find beginning of record value */
1379 tok = strchr (&value[tok - cp], (unsigned char) ' ');
1380 if (NULL == tok)
1381 {
1382 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1383 _("Missing entries in record line `%s'.\n"),
1384 value);
1385 GNUNET_free (cp);
1386 return GNUNET_SYSERR;
1387 }
1388 GNUNET_free (cp);
1389 tok++; /* skip space */
1390 if (GNUNET_OK !=
1391 GNUNET_GNSRECORD_string_to_value (record.record_type,
1392 tok,
1393 &raw_data,
1394 &record.data_size))
1395 {
1396 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
1397 _("Invalid record data for type %s: `%s'.\n"),
1398 GNUNET_GNSRECORD_number_to_typename (record.record_type),
1399 tok);
1400 return GNUNET_SYSERR;
1401 }
1402
1403 r = GNUNET_malloc (sizeof (struct RecordSetEntry) + record.data_size);
1404 r->next = *head;
1405 record.data = &r[1];
1406 memcpy (&r[1],
1407 raw_data,
1408 record.data_size);
1409 GNUNET_free (raw_data);
1410 r->record = record;
1411 *head = r;
1412 return GNUNET_OK;
1413}
1414
1415
1416/**
1417 * Allow user to specify keywords.
1418 *
1419 * @param shortName short name of the option
1420 * @param name long name of the option
1421 * @param argumentHelp help text for the option argument
1422 * @param description long help text for the option
1423 * @param[out] topKeywords set to the desired value
1424 */
1425struct GNUNET_GETOPT_CommandLineOption
1426multirecord_option (char shortName,
1427 const char *name,
1428 const char *argumentHelp,
1429 const char *description,
1430 struct RecordSetEntry **rs)
1431{
1432 struct GNUNET_GETOPT_CommandLineOption clo = {
1433 .shortName = shortName,
1434 .name = name,
1435 .argumentHelp = argumentHelp,
1436 .description = description,
1437 .require_argument = 1,
1438 .processor = &multirecord_process,
1439 .scls = (void *) rs
1440 };
1441
1442 return clo;
1443}
1444
1445
1446
1447/**
1250 * The main function for gnunet-namestore. 1448 * The main function for gnunet-namestore.
1251 * 1449 *
1252 * @param argc number of arguments from the command line 1450 * @param argc number of arguments from the command line
@@ -1294,6 +1492,11 @@ main (int argc,
1294 "PKEY", 1492 "PKEY",
1295 gettext_noop ("determine our name for the given PKEY"), 1493 gettext_noop ("determine our name for the given PKEY"),
1296 &reverse_pkey), 1494 &reverse_pkey),
1495 multirecord_option ('R',
1496 "record",
1497 "RECORDLINE",
1498 gettext_noop ("complete record on one line to add/delete/display; can be specified multiple times"),
1499 &recordset),
1297 GNUNET_GETOPT_option_string ('t', 1500 GNUNET_GETOPT_option_string ('t',
1298 "type", 1501 "type",
1299 "TYPE", 1502 "TYPE",