aboutsummaryrefslogtreecommitdiff
path: root/src/namestore
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-10-20 12:31:21 +0900
committerMartin Schanzenbach <schanzen@gnunet.org>2022-10-20 12:31:21 +0900
commitaa827c7e06a8f52334d5492627832582964747c4 (patch)
tree8ed1c797ea4b1a0f7f4d95815ee83d14b7d5c8e8 /src/namestore
parent03c7d8ec09d7e294bacd1aa1e5e61692d686629c (diff)
downloadgnunet-aa827c7e06a8f52334d5492627832582964747c4.tar.gz
gnunet-aa827c7e06a8f52334d5492627832582964747c4.zip
-zonefile import: support switching origins and automatically create identities for origins
Diffstat (limited to 'src/namestore')
-rw-r--r--src/namestore/example_zonefile3
-rw-r--r--src/namestore/gnunet-namestore-zonefile.c177
2 files changed, 151 insertions, 29 deletions
diff --git a/src/namestore/example_zonefile b/src/namestore/example_zonefile
index 0564368e8..5e380ff90 100644
--- a/src/namestore/example_zonefile
+++ b/src/namestore/example_zonefile
@@ -22,3 +22,6 @@ mail2 IN A 192.0.2.4 ; IPv4 address for mail2.example
22mail3 IN A 192.0.2.5 ; IPv4 address for mail3.example.com 22mail3 IN A 192.0.2.5 ; IPv4 address for mail3.example.com
23 23
24mail3 IN TXT "This is ; quoted" ; A quoted comment separator 24mail3 IN TXT "This is ; quoted" ; A quoted comment separator
25$ORIGIN example.de.
26www2 IN A 192.0.2.7 ; IPv4 address for www2.example.de
27
diff --git a/src/namestore/gnunet-namestore-zonefile.c b/src/namestore/gnunet-namestore-zonefile.c
index 733cdb380..14dc60acc 100644
--- a/src/namestore/gnunet-namestore-zonefile.c
+++ b/src/namestore/gnunet-namestore-zonefile.c
@@ -46,6 +46,16 @@
46static struct GNUNET_GNSRECORD_Data rd[MAX_RECORDS_PER_NAME]; 46static struct GNUNET_GNSRECORD_Data rd[MAX_RECORDS_PER_NAME];
47 47
48/** 48/**
49 * Current record $TTL to use
50 */
51static struct GNUNET_TIME_Relative ttl;
52
53/**
54 * Current origin
55 */
56static char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
57
58/**
49 * Number of records for currently parsed set 59 * Number of records for currently parsed set
50 */ 60 */
51static unsigned int rd_count = 0; 61static unsigned int rd_count = 0;
@@ -96,6 +106,41 @@ static struct GNUNET_NAMESTORE_QueueEntry *ns_qe;
96 */ 106 */
97static struct GNUNET_NAMESTORE_Handle *ns; 107static struct GNUNET_NAMESTORE_Handle *ns;
98 108
109/**
110 * Origin create operations
111 */
112static struct GNUNET_IDENTITY_Operation *id_op;
113
114/**
115 * Handle to IDENTITY
116 */
117static struct GNUNET_IDENTITY_Handle *id;
118
119/**
120 * Current configurataion
121 */
122static const struct GNUNET_CONFIGURATION_Handle *cfg;
123
124/**
125 * The current state of the parser
126 */
127static int state;
128
129enum ZonefileImportState
130{
131
132 /* The initial state */
133 ZS_READY,
134
135 /* The $ORIGIN has changed */
136 ZS_ORIGIN_CHANGED,
137
138 /* The record name/label has changed */
139 ZS_NAME_CHANGED
140
141};
142
143
99 144
100/** 145/**
101 * Task run on shutdown. Cleans up everything. 146 * Task run on shutdown. Cleans up everything.
@@ -115,8 +160,12 @@ do_shutdown (void *cls)
115 } 160 }
116 if (NULL != ns_qe) 161 if (NULL != ns_qe)
117 GNUNET_NAMESTORE_cancel (ns_qe); 162 GNUNET_NAMESTORE_cancel (ns_qe);
163 if (NULL != id_op)
164 GNUNET_IDENTITY_cancel (id_op);
118 if (NULL != ns) 165 if (NULL != ns)
119 GNUNET_NAMESTORE_disconnect (ns); 166 GNUNET_NAMESTORE_disconnect (ns);
167 if (NULL != id)
168 GNUNET_IDENTITY_disconnect (id);
120 for (int i = 0; i < rd_count; i++) 169 for (int i = 0; i < rd_count; i++)
121 { 170 {
122 void *rd_ptr = (void*) rd[i].data; 171 void *rd_ptr = (void*) rd[i].data;
@@ -143,20 +192,6 @@ tx_end (void *cls, int32_t success, const char *emsg)
143static void 192static void
144parse (void *cls); 193parse (void *cls);
145 194
146static void
147add_continuation (void *cls, int32_t success, const char *emsg)
148{
149 ns_qe = NULL;
150 if (GNUNET_SYSERR == success)
151 {
152 fprintf (stderr,
153 _ ("Failed to store records...\n"));
154 GNUNET_SCHEDULER_shutdown ();
155 ret = -1;
156 }
157 GNUNET_SCHEDULER_add_now (&parse, NULL);
158}
159
160static char* 195static char*
161trim (char *line) 196trim (char *line)
162{ 197{
@@ -236,6 +271,74 @@ parse_origin (char *token, char *origin)
236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin is: %s\n", origin); 271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Origin is: %s\n", origin);
237} 272}
238 273
274static void
275origin_create_cb (void *cls, const struct GNUNET_IDENTITY_PrivateKey *pk,
276 const char *emsg)
277{
278 id_op = NULL;
279 if (NULL != emsg)
280 {
281 fprintf (stderr, "Error: %s\n", emsg);
282 ret = 1;
283 GNUNET_SCHEDULER_shutdown ();
284 return;
285 }
286 state = ZS_READY;
287 zone_pkey = *pk;
288 GNUNET_SCHEDULER_add_now (&parse, NULL);
289}
290
291static void
292origin_lookup_cb (void *cls, struct GNUNET_IDENTITY_Ego *ego)
293{
294 const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
295
296 el = NULL;
297
298 if (NULL == ego)
299 {
300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
301 "$ORIGIN %s does not exist, creating...\n", ego_name);
302 id_op = GNUNET_IDENTITY_create (id, ego_name, NULL,
303 GNUNET_IDENTITY_TYPE_ECDSA, // FIXME make configurable
304 origin_create_cb,
305 NULL);
306 return;
307 }
308 state = ZS_READY;
309 zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (ego);
310 GNUNET_SCHEDULER_add_now (&parse, NULL);
311}
312
313static void
314add_continuation (void *cls, int32_t success, const char *emsg)
315{
316 ns_qe = NULL;
317 if (GNUNET_SYSERR == success)
318 {
319 fprintf (stderr,
320 _ ("Failed to store records...\n"));
321 GNUNET_SCHEDULER_shutdown ();
322 ret = -1;
323 }
324 if (ZS_ORIGIN_CHANGED == state)
325 {
326 if (NULL != ego_name)
327 GNUNET_free (ego_name);
328 ego_name = GNUNET_strdup (origin);
329 if (ego_name[strlen (ego_name) - 1] == '.')
330 ego_name[strlen (ego_name) - 1] = '\0';
331 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
332 "Changing origin to %s\n", ego_name);
333 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name,
334 &origin_lookup_cb, NULL);
335 return;
336 }
337 GNUNET_SCHEDULER_add_now (&parse, NULL);
338}
339
340
341
239/** 342/**
240 * Main function that will be run. 343 * Main function that will be run.
241 * 344 *
@@ -260,16 +363,12 @@ parse (void *cls)
260 char *next; 363 char *next;
261 char *token; 364 char *token;
262 char *payload_pos; 365 char *payload_pos;
263 char origin[GNUNET_DNSPARSER_MAX_NAME_LENGTH];
264 static char lastname[GNUNET_DNSPARSER_MAX_LABEL_LENGTH]; 366 static char lastname[GNUNET_DNSPARSER_MAX_LABEL_LENGTH];
265 char newname[GNUNET_DNSPARSER_MAX_LABEL_LENGTH]; 367 char newname[GNUNET_DNSPARSER_MAX_LABEL_LENGTH];
266 void *data; 368 void *data;
267 size_t data_size; 369 size_t data_size;
268 struct GNUNET_TIME_Relative ttl;
269 int origin_line = 0;
270 int ttl_line = 0; 370 int ttl_line = 0;
271 int type; 371 int type;
272 int name_changed = 0;
273 int bracket_unclosed = 0; 372 int bracket_unclosed = 0;
274 int quoted = 0; 373 int quoted = 0;
275 374
@@ -278,7 +377,6 @@ parse (void *cls)
278 while (res = fgets (buf, sizeof(buf), stdin)) /* read each line of input */ 377 while (res = fgets (buf, sizeof(buf), stdin)) /* read each line of input */
279 { 378 {
280 i++; 379 i++;
281 origin_line = 0;
282 ttl_line = 0; 380 ttl_line = 0;
283 token = trim (buf); 381 token = trim (buf);
284 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 382 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -302,7 +400,7 @@ parse (void *cls)
302 next++; 400 next++;
303 if (0 == (strcmp (token, "$ORIGIN"))) 401 if (0 == (strcmp (token, "$ORIGIN")))
304 { 402 {
305 origin_line = 1; 403 state = ZS_ORIGIN_CHANGED;
306 token = next_token (next); 404 token = next_token (next);
307 } 405 }
308 else if (0 == (strcmp (token, "$TTL"))) 406 else if (0 == (strcmp (token, "$TTL")))
@@ -373,10 +471,9 @@ parse (void *cls)
373 "Name changed %s->%s, storing record set of %u elements\n", 471 "Name changed %s->%s, storing record set of %u elements\n",
374 lastname, newname, 472 lastname, newname,
375 rd_count); 473 rd_count);
376 name_changed = 1; 474 state = ZS_NAME_CHANGED;
377 } 475 }
378 else { 476 else {
379 name_changed = 0;
380 strcpy (lastname, newname); 477 strcpy (lastname, newname);
381 } 478 }
382 } 479 }
@@ -391,7 +488,7 @@ parse (void *cls)
391 } 488 }
392 continue; 489 continue;
393 } 490 }
394 if (origin_line) 491 if (ZS_ORIGIN_CHANGED == state)
395 { 492 {
396 if (GNUNET_SYSERR == parse_origin (token, origin)) 493 if (GNUNET_SYSERR == parse_origin (token, origin))
397 { 494 {
@@ -399,7 +496,7 @@ parse (void *cls)
399 GNUNET_SCHEDULER_shutdown (); 496 GNUNET_SCHEDULER_shutdown ();
400 return; 497 return;
401 } 498 }
402 continue; 499 break;
403 } 500 }
404 // This is a record, let's go 501 // This is a record, let's go
405 if (MAX_RECORDS_PER_NAME == rd_count) 502 if (MAX_RECORDS_PER_NAME == rd_count)
@@ -476,7 +573,7 @@ parse (void *cls)
476 } 573 }
477 rd[rd_count].data = data; 574 rd[rd_count].data = data;
478 rd[rd_count].data_size = data_size; 575 rd[rd_count].data_size = data_size;
479 if (name_changed) 576 if (ZS_NAME_CHANGED == state)
480 break; 577 break;
481 rd_count++; 578 rd_count++;
482 } 579 }
@@ -496,16 +593,30 @@ parse (void *cls)
496 data = (void*) rd[i].data; 593 data = (void*) rd[i].data;
497 GNUNET_free (data); 594 GNUNET_free (data);
498 } 595 }
499 if (name_changed) 596 if (ZS_NAME_CHANGED == state)
500 { 597 {
501 rd[0] = rd[rd_count]; // recover last rd parsed. 598 rd[0] = rd[rd_count]; // recover last rd parsed.
502 rd_count = 1; 599 rd_count = 1;
503 strcpy (lastname, newname); 600 strcpy (lastname, newname);
601 state = ZS_READY;
504 } 602 }
505 else 603 else
506 rd_count = 0; 604 rd_count = 0;
507 return; 605 return;
508 } 606 }
607 if (ZS_ORIGIN_CHANGED == state)
608 {
609 if (NULL != ego_name)
610 GNUNET_free (ego_name);
611 ego_name = GNUNET_strdup (origin);
612 if (ego_name[strlen (ego_name) - 1] == '.')
613 ego_name[strlen (ego_name) - 1] = '\0';
614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
615 "Changing origin to %s\n", ego_name);
616 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name,
617 &origin_lookup_cb, NULL);
618 return;
619 }
509 printf ("Published %u records sets with total %u records\n", 620 printf ("Published %u records sets with total %u records\n",
510 published_sets, published_records); 621 published_sets, published_records);
511 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns, 622 ns_qe = GNUNET_NAMESTORE_transaction_commit (ns,
@@ -559,14 +670,22 @@ static void
559run (void *cls, 670run (void *cls,
560 char *const *args, 671 char *const *args,
561 const char *cfgfile, 672 const char *cfgfile,
562 const struct GNUNET_CONFIGURATION_Handle *cfg) 673 const struct GNUNET_CONFIGURATION_Handle *_cfg)
563{ 674{
675 cfg = _cfg;
564 ns = GNUNET_NAMESTORE_connect (cfg); 676 ns = GNUNET_NAMESTORE_connect (cfg);
565 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg); 677 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, (void *) cfg);
566 if (NULL == ns) 678 if (NULL == ns)
567 { 679 {
568 fprintf (stderr, 680 fprintf (stderr,
569 _ ("Failed to connect to namestore\n")); 681 _ ("Failed to connect to NAMESTORE\n"));
682 return;
683 }
684 id = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
685 if (NULL == id)
686 {
687 fprintf (stderr,
688 _ ("Failed to connect to IDENTITY\n"));
570 return; 689 return;
571 } 690 }
572 if (NULL == ego_name) 691 if (NULL == ego_name)
@@ -576,7 +695,7 @@ run (void *cls,
576 return; 695 return;
577 } 696 }
578 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) cfg); 697 el = GNUNET_IDENTITY_ego_lookup (cfg, ego_name, &identity_cb, (void *) cfg);
579 698 state = ZS_READY;
580} 699}
581 700
582 701