diff options
author | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-20 12:31:21 +0900 |
---|---|---|
committer | Martin Schanzenbach <schanzen@gnunet.org> | 2022-10-20 12:31:21 +0900 |
commit | aa827c7e06a8f52334d5492627832582964747c4 (patch) | |
tree | 8ed1c797ea4b1a0f7f4d95815ee83d14b7d5c8e8 /src/namestore | |
parent | 03c7d8ec09d7e294bacd1aa1e5e61692d686629c (diff) | |
download | gnunet-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_zonefile | 3 | ||||
-rw-r--r-- | src/namestore/gnunet-namestore-zonefile.c | 177 |
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 | |||
22 | mail3 IN A 192.0.2.5 ; IPv4 address for mail3.example.com | 22 | mail3 IN A 192.0.2.5 ; IPv4 address for mail3.example.com |
23 | 23 | ||
24 | mail3 IN TXT "This is ; quoted" ; A quoted comment separator | 24 | mail3 IN TXT "This is ; quoted" ; A quoted comment separator |
25 | $ORIGIN example.de. | ||
26 | www2 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 @@ | |||
46 | static struct GNUNET_GNSRECORD_Data rd[MAX_RECORDS_PER_NAME]; | 46 | static struct GNUNET_GNSRECORD_Data rd[MAX_RECORDS_PER_NAME]; |
47 | 47 | ||
48 | /** | 48 | /** |
49 | * Current record $TTL to use | ||
50 | */ | ||
51 | static struct GNUNET_TIME_Relative ttl; | ||
52 | |||
53 | /** | ||
54 | * Current origin | ||
55 | */ | ||
56 | static 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 | */ |
51 | static unsigned int rd_count = 0; | 61 | static unsigned int rd_count = 0; |
@@ -96,6 +106,41 @@ static struct GNUNET_NAMESTORE_QueueEntry *ns_qe; | |||
96 | */ | 106 | */ |
97 | static struct GNUNET_NAMESTORE_Handle *ns; | 107 | static struct GNUNET_NAMESTORE_Handle *ns; |
98 | 108 | ||
109 | /** | ||
110 | * Origin create operations | ||
111 | */ | ||
112 | static struct GNUNET_IDENTITY_Operation *id_op; | ||
113 | |||
114 | /** | ||
115 | * Handle to IDENTITY | ||
116 | */ | ||
117 | static struct GNUNET_IDENTITY_Handle *id; | ||
118 | |||
119 | /** | ||
120 | * Current configurataion | ||
121 | */ | ||
122 | static const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
123 | |||
124 | /** | ||
125 | * The current state of the parser | ||
126 | */ | ||
127 | static int state; | ||
128 | |||
129 | enum 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) | |||
143 | static void | 192 | static void |
144 | parse (void *cls); | 193 | parse (void *cls); |
145 | 194 | ||
146 | static void | ||
147 | add_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 | |||
160 | static char* | 195 | static char* |
161 | trim (char *line) | 196 | trim (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 | ||
274 | static void | ||
275 | origin_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 | |||
291 | static void | ||
292 | origin_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 | |||
313 | static void | ||
314 | add_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 | |||
559 | run (void *cls, | 670 | run (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 | ||