summaryrefslogtreecommitdiff
path: root/src/namestore/gnunet-zoneimport.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/namestore/gnunet-zoneimport.c')
-rw-r--r--src/namestore/gnunet-zoneimport.c1759
1 files changed, 882 insertions, 877 deletions
diff --git a/src/namestore/gnunet-zoneimport.c b/src/namestore/gnunet-zoneimport.c
index 60d8b0537..bbbe7d783 100644
--- a/src/namestore/gnunet-zoneimport.c
+++ b/src/namestore/gnunet-zoneimport.c
@@ -57,7 +57,7 @@
57 * How long do we wait at least between series of requests? 57 * How long do we wait at least between series of requests?
58 */ 58 */
59#define SERIES_DELAY \ 59#define SERIES_DELAY \
60 GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MICROSECONDS, 10) 60 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, 10)
61 61
62/** 62/**
63 * How long do DNS records have to last at least after being imported? 63 * How long do DNS records have to last at least after being imported?
@@ -76,7 +76,8 @@ static struct GNUNET_TIME_Relative minimum_expiration_time;
76 * each dot represents a zone cut, we then need to create a 76 * each dot represents a zone cut, we then need to create a
77 * zone on-the-fly to capture those records properly. 77 * zone on-the-fly to capture those records properly.
78 */ 78 */
79struct Zone { 79struct Zone
80{
80 /** 81 /**
81 * Kept in a DLL. 82 * Kept in a DLL.
82 */ 83 */
@@ -102,7 +103,8 @@ struct Zone {
102/** 103/**
103 * Record for the request to be stored by GNS. 104 * Record for the request to be stored by GNS.
104 */ 105 */
105struct Record { 106struct Record
107{
106 /** 108 /**
107 * Kept in a DLL. 109 * Kept in a DLL.
108 */ 110 */
@@ -125,7 +127,8 @@ struct Record {
125 * thus optimizing it is crucial for the overall memory consumption of 127 * thus optimizing it is crucial for the overall memory consumption of
126 * the zone importer. 128 * the zone importer.
127 */ 129 */
128struct Request { 130struct Request
131{
129 /** 132 /**
130 * Requests are kept in a heap while waiting to be resolved. 133 * Requests are kept in a heap while waiting to be resolved.
131 */ 134 */
@@ -375,28 +378,28 @@ typedef void (*RecordProcessor) (void *cls,
375 * @param rp_cls closure for @a rp 378 * @param rp_cls closure for @a rp
376 */ 379 */
377static void 380static void
378for_all_records(const struct GNUNET_DNSPARSER_Packet *p, 381for_all_records (const struct GNUNET_DNSPARSER_Packet *p,
379 RecordProcessor rp, 382 RecordProcessor rp,
380 void *rp_cls) 383 void *rp_cls)
381{ 384{
382 for (unsigned int i = 0; i < p->num_answers; i++) 385 for (unsigned int i = 0; i < p->num_answers; i++)
383 { 386 {
384 struct GNUNET_DNSPARSER_Record *rs = &p->answers[i]; 387 struct GNUNET_DNSPARSER_Record *rs = &p->answers[i];
385 388
386 rp(rp_cls, rs); 389 rp (rp_cls, rs);
387 } 390 }
388 for (unsigned int i = 0; i < p->num_authority_records; i++) 391 for (unsigned int i = 0; i < p->num_authority_records; i++)
389 { 392 {
390 struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i]; 393 struct GNUNET_DNSPARSER_Record *rs = &p->authority_records[i];
391 394
392 rp(rp_cls, rs); 395 rp (rp_cls, rs);
393 } 396 }
394 for (unsigned int i = 0; i < p->num_additional_records; i++) 397 for (unsigned int i = 0; i < p->num_additional_records; i++)
395 { 398 {
396 struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i]; 399 struct GNUNET_DNSPARSER_Record *rs = &p->additional_records[i];
397 400
398 rp(rp_cls, rs); 401 rp (rp_cls, rs);
399 } 402 }
400} 403}
401 404
402 405
@@ -408,23 +411,23 @@ for_all_records(const struct GNUNET_DNSPARSER_Packet *p,
408 * overwritten upon the next request! 411 * overwritten upon the next request!
409 */ 412 */
410static const char * 413static const char *
411get_label(struct Request *req) 414get_label (struct Request *req)
412{ 415{
413 static char label[64]; 416 static char label[64];
414 const char *dot; 417 const char *dot;
415 418
416 dot = strchr(req->hostname, (unsigned char)'.'); 419 dot = strchr (req->hostname, (unsigned char) '.');
417 if (NULL == dot) 420 if (NULL == dot)
418 { 421 {
419 GNUNET_break(0); 422 GNUNET_break (0);
420 return NULL; 423 return NULL;
421 } 424 }
422 if (((size_t)(dot - req->hostname)) >= sizeof(label)) 425 if (((size_t) (dot - req->hostname)) >= sizeof(label))
423 { 426 {
424 GNUNET_break(0); 427 GNUNET_break (0);
425 return NULL; 428 return NULL;
426 } 429 }
427 GNUNET_memcpy(label, req->hostname, dot - req->hostname); 430 GNUNET_memcpy (label, req->hostname, dot - req->hostname);
428 label[dot - req->hostname] = '\0'; 431 label[dot - req->hostname] = '\0';
429 return label; 432 return label;
430} 433}
@@ -439,7 +442,7 @@ get_label(struct Request *req)
439 * allocated query buffer 442 * allocated query buffer
440 */ 443 */
441static void * 444static void *
442build_dns_query(struct Request *req, size_t *raw_size) 445build_dns_query (struct Request *req, size_t *raw_size)
443{ 446{
444 static char raw[512]; 447 static char raw[512];
445 char *rawp; 448 char *rawp;
@@ -447,37 +450,37 @@ build_dns_query(struct Request *req, size_t *raw_size)
447 struct GNUNET_DNSPARSER_Query q; 450 struct GNUNET_DNSPARSER_Query q;
448 int ret; 451 int ret;
449 452
450 q.name = (char *)req->hostname; 453 q.name = (char *) req->hostname;
451 q.type = GNUNET_DNSPARSER_TYPE_NS; 454 q.type = GNUNET_DNSPARSER_TYPE_NS;
452 q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET; 455 q.dns_traffic_class = GNUNET_TUN_DNS_CLASS_INTERNET;
453 456
454 memset(&p, 0, sizeof(p)); 457 memset (&p, 0, sizeof(p));
455 p.num_queries = 1; 458 p.num_queries = 1;
456 p.queries = &q; 459 p.queries = &q;
457 p.id = req->id; 460 p.id = req->id;
458 ret = GNUNET_DNSPARSER_pack(&p, UINT16_MAX, &rawp, raw_size); 461 ret = GNUNET_DNSPARSER_pack (&p, UINT16_MAX, &rawp, raw_size);
459 if (GNUNET_OK != ret) 462 if (GNUNET_OK != ret)
460 { 463 {
461 if (GNUNET_NO == ret) 464 if (GNUNET_NO == ret)
462 GNUNET_free(rawp); 465 GNUNET_free (rawp);
463 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 466 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
464 "Failed to pack query for hostname `%s'\n", 467 "Failed to pack query for hostname `%s'\n",
465 req->hostname); 468 req->hostname);
466 rejects++; 469 rejects++;
467 return NULL; 470 return NULL;
468 } 471 }
469 if (*raw_size > sizeof(raw)) 472 if (*raw_size > sizeof(raw))
470 { 473 {
471 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 474 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
472 "Failed to pack query for hostname `%s'\n", 475 "Failed to pack query for hostname `%s'\n",
473 req->hostname); 476 req->hostname);
474 rejects++; 477 rejects++;
475 GNUNET_break(0); 478 GNUNET_break (0);
476 GNUNET_free(rawp); 479 GNUNET_free (rawp);
477 return NULL; 480 return NULL;
478 } 481 }
479 GNUNET_memcpy(raw, rawp, *raw_size); 482 GNUNET_memcpy (raw, rawp, *raw_size);
480 GNUNET_free(rawp); 483 GNUNET_free (rawp);
481 return raw; 484 return raw;
482} 485}
483 486
@@ -488,16 +491,16 @@ build_dns_query(struct Request *req, size_t *raw_size)
488 * @param req request to free records of 491 * @param req request to free records of
489 */ 492 */
490static void 493static void
491free_records(struct Request *req) 494free_records (struct Request *req)
492{ 495{
493 struct Record *rec; 496 struct Record *rec;
494 497
495 /* Free records */ 498 /* Free records */
496 while (NULL != (rec = req->rec_head)) 499 while (NULL != (rec = req->rec_head))
497 { 500 {
498 GNUNET_CONTAINER_DLL_remove(req->rec_head, req->rec_tail, rec); 501 GNUNET_CONTAINER_DLL_remove (req->rec_head, req->rec_tail, rec);
499 GNUNET_free(rec); 502 GNUNET_free (rec);
500 } 503 }
501} 504}
502 505
503 506
@@ -507,10 +510,10 @@ free_records(struct Request *req)
507 * @param req request to free 510 * @param req request to free
508 */ 511 */
509static void 512static void
510free_request(struct Request *req) 513free_request (struct Request *req)
511{ 514{
512 free_records(req); 515 free_records (req);
513 GNUNET_free(req); 516 GNUNET_free (req);
514} 517}
515 518
516 519
@@ -520,7 +523,7 @@ free_request(struct Request *req)
520 * @param cls NULL 523 * @param cls NULL
521 */ 524 */
522static void 525static void
523process_queue(void *cls); 526process_queue (void *cls);
524 527
525 528
526/** 529/**
@@ -529,17 +532,17 @@ process_queue(void *cls);
529 * @param req request to insert into #req_heap 532 * @param req request to insert into #req_heap
530 */ 533 */
531static void 534static void
532insert_sorted(struct Request *req) 535insert_sorted (struct Request *req)
533{ 536{
534 req->hn = 537 req->hn =
535 GNUNET_CONTAINER_heap_insert(req_heap, req, req->expires.abs_value_us); 538 GNUNET_CONTAINER_heap_insert (req_heap, req, req->expires.abs_value_us);
536 if (req == GNUNET_CONTAINER_heap_peek(req_heap)) 539 if (req == GNUNET_CONTAINER_heap_peek (req_heap))
537 { 540 {
538 if (NULL != t) 541 if (NULL != t)
539 GNUNET_SCHEDULER_cancel(t); 542 GNUNET_SCHEDULER_cancel (t);
540 sleep_time_reg_proc = GNUNET_TIME_absolute_get(); 543 sleep_time_reg_proc = GNUNET_TIME_absolute_get ();
541 t = GNUNET_SCHEDULER_add_at(req->expires, &process_queue, NULL); 544 t = GNUNET_SCHEDULER_add_at (req->expires, &process_queue, NULL);
542 } 545 }
543} 546}
544 547
545 548
@@ -553,29 +556,30 @@ insert_sorted(struct Request *req)
553 * @param data_len number of bytes in @a data 556 * @param data_len number of bytes in @a data
554 */ 557 */
555static void 558static void
556add_record(struct Request *req, 559add_record (struct Request *req,
557 uint32_t type, 560 uint32_t type,
558 struct GNUNET_TIME_Absolute expiration_time, 561 struct GNUNET_TIME_Absolute expiration_time,
559 const void *data, 562 const void *data,
560 size_t data_len) 563 size_t data_len)
561{ 564{
562 struct Record *rec; 565 struct Record *rec;
563 566
564 rec = GNUNET_malloc(sizeof(struct Record) + data_len); 567 rec = GNUNET_malloc (sizeof(struct Record) + data_len);
565 rec->grd.data = &rec[1]; 568 rec->grd.data = &rec[1];
566 rec->grd.expiration_time = expiration_time.abs_value_us; 569 rec->grd.expiration_time = expiration_time.abs_value_us;
567 rec->grd.data_size = data_len; 570 rec->grd.data_size = data_len;
568 rec->grd.record_type = type; 571 rec->grd.record_type = type;
569 rec->grd.flags = GNUNET_GNSRECORD_RF_NONE; 572 rec->grd.flags = GNUNET_GNSRECORD_RF_NONE;
570 GNUNET_memcpy(&rec[1], data, data_len); 573 GNUNET_memcpy (&rec[1], data, data_len);
571 GNUNET_CONTAINER_DLL_insert(req->rec_head, req->rec_tail, rec); 574 GNUNET_CONTAINER_DLL_insert (req->rec_head, req->rec_tail, rec);
572} 575}
573 576
574 577
575/** 578/**
576 * Closure for #check_for_glue. 579 * Closure for #check_for_glue.
577 */ 580 */
578struct GlueClosure { 581struct GlueClosure
582{
579 /** 583 /**
580 * Overall request we are processing. 584 * Overall request we are processing.
581 */ 585 */
@@ -600,115 +604,116 @@ struct GlueClosure {
600 * @param rec record that may contain glue information 604 * @param rec record that may contain glue information
601 */ 605 */
602static void 606static void
603check_for_glue(void *cls, const struct GNUNET_DNSPARSER_Record *rec) 607check_for_glue (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
604{ 608{
605 struct GlueClosure *gc = cls; 609 struct GlueClosure *gc = cls;
606 char dst[65536]; 610 char dst[65536];
607 size_t dst_len; 611 size_t dst_len;
608 size_t off; 612 size_t off;
609 char ip[INET6_ADDRSTRLEN + 1]; 613 char ip[INET6_ADDRSTRLEN + 1];
610 socklen_t ip_size = (socklen_t)sizeof(ip); 614 socklen_t ip_size = (socklen_t) sizeof(ip);
611 struct GNUNET_TIME_Absolute expiration_time; 615 struct GNUNET_TIME_Absolute expiration_time;
612 struct GNUNET_TIME_Relative left; 616 struct GNUNET_TIME_Relative left;
613 617
614 if (0 != strcasecmp(rec->name, gc->ns)) 618 if (0 != strcasecmp (rec->name, gc->ns))
615 return; 619 return;
616 expiration_time = rec->expiration_time; 620 expiration_time = rec->expiration_time;
617 left = GNUNET_TIME_absolute_get_remaining(expiration_time); 621 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
618 if (0 == left.rel_value_us) 622 if (0 == left.rel_value_us)
619 return; /* ignore expired glue records */ 623 return; /* ignore expired glue records */
620 /* if expiration window is too short, bump it to configured minimum */ 624 /* if expiration window is too short, bump it to configured minimum */
621 if (left.rel_value_us < minimum_expiration_time.rel_value_us) 625 if (left.rel_value_us < minimum_expiration_time.rel_value_us)
622 expiration_time = 626 expiration_time =
623 GNUNET_TIME_relative_to_absolute(minimum_expiration_time); 627 GNUNET_TIME_relative_to_absolute (minimum_expiration_time);
624 dst_len = sizeof(dst); 628 dst_len = sizeof(dst);
625 off = 0; 629 off = 0;
626 switch (rec->type) 630 switch (rec->type)
631 {
632 case GNUNET_DNSPARSER_TYPE_A:
633 if (sizeof(struct in_addr) != rec->data.raw.data_len)
627 { 634 {
628 case GNUNET_DNSPARSER_TYPE_A: 635 GNUNET_break (0);
629 if (sizeof(struct in_addr) != rec->data.raw.data_len) 636 return;
630 { 637 }
631 GNUNET_break(0); 638 if (NULL == inet_ntop (AF_INET, rec->data.raw.data, ip, ip_size))
632 return; 639 {
633 } 640 GNUNET_break (0);
634 if (NULL == inet_ntop(AF_INET, rec->data.raw.data, ip, ip_size)) 641 return;
635 { 642 }
636 GNUNET_break(0); 643 if ((GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
637 return; 644 dst_len,
638 } 645 &off,
639 if ((GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst, 646 gc->req->hostname)) &&
640 dst_len, 647 (GNUNET_OK ==
641 &off, 648 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
642 gc->req->hostname)) && 649 {
643 (GNUNET_OK == 650 add_record (gc->req,
644 GNUNET_DNSPARSER_builder_add_name(dst, dst_len, &off, ip))) 651 GNUNET_GNSRECORD_TYPE_GNS2DNS,
645 { 652 expiration_time,
646 add_record(gc->req, 653 dst,
647 GNUNET_GNSRECORD_TYPE_GNS2DNS, 654 off);
648 expiration_time, 655 gc->found = GNUNET_YES;
649 dst, 656 }
650 off); 657 break;
651 gc->found = GNUNET_YES;
652 }
653 break;
654
655 case GNUNET_DNSPARSER_TYPE_AAAA:
656 if (sizeof(struct in6_addr) != rec->data.raw.data_len)
657 {
658 GNUNET_break(0);
659 return;
660 }
661 if (NULL == inet_ntop(AF_INET6, rec->data.raw.data, ip, ip_size))
662 {
663 GNUNET_break(0);
664 return;
665 }
666 if ((GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst,
667 dst_len,
668 &off,
669 gc->req->hostname)) &&
670 (GNUNET_OK ==
671 GNUNET_DNSPARSER_builder_add_name(dst, dst_len, &off, ip)))
672 {
673 add_record(gc->req,
674 GNUNET_GNSRECORD_TYPE_GNS2DNS,
675 expiration_time,
676 dst,
677 off);
678 gc->found = GNUNET_YES;
679 }
680 break;
681 658
682 case GNUNET_DNSPARSER_TYPE_CNAME: 659 case GNUNET_DNSPARSER_TYPE_AAAA:
683 if ((GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst, 660 if (sizeof(struct in6_addr) != rec->data.raw.data_len)
684 dst_len, 661 {
685 &off, 662 GNUNET_break (0);
686 gc->req->hostname)) && 663 return;
687 (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst, 664 }
688 dst_len, 665 if (NULL == inet_ntop (AF_INET6, rec->data.raw.data, ip, ip_size))
689 &off, 666 {
690 rec->data.hostname))) 667 GNUNET_break (0);
691 { 668 return;
692 add_record(gc->req, 669 }
693 GNUNET_GNSRECORD_TYPE_GNS2DNS, 670 if ((GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
694 expiration_time, 671 dst_len,
695 dst, 672 &off,
696 off); 673 gc->req->hostname)) &&
697 gc->found = GNUNET_YES; 674 (GNUNET_OK ==
698 } 675 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &off, ip)))
699 break; 676 {
677 add_record (gc->req,
678 GNUNET_GNSRECORD_TYPE_GNS2DNS,
679 expiration_time,
680 dst,
681 off);
682 gc->found = GNUNET_YES;
683 }
684 break;
700 685
701 default: 686 case GNUNET_DNSPARSER_TYPE_CNAME:
702 /* useless, do nothing */ 687 if ((GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
703 break; 688 dst_len,
689 &off,
690 gc->req->hostname)) &&
691 (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
692 dst_len,
693 &off,
694 rec->data.hostname)))
695 {
696 add_record (gc->req,
697 GNUNET_GNSRECORD_TYPE_GNS2DNS,
698 expiration_time,
699 dst,
700 off);
701 gc->found = GNUNET_YES;
704 } 702 }
703 break;
704
705 default:
706 /* useless, do nothing */
707 break;
708 }
705} 709}
706 710
707 711
708/** 712/**
709 * Closure for #process_record(). 713 * Closure for #process_record().
710 */ 714 */
711struct ProcessRecordContext { 715struct ProcessRecordContext
716{
712 /** 717 /**
713 * Answer we got back and are currently parsing, or NULL 718 * Answer we got back and are currently parsing, or NULL
714 * if not active. 719 * if not active.
@@ -729,7 +734,7 @@ struct ProcessRecordContext {
729 * @param rec response 734 * @param rec response
730 */ 735 */
731static void 736static void
732process_record(void *cls, const struct GNUNET_DNSPARSER_Record *rec) 737process_record (void *cls, const struct GNUNET_DNSPARSER_Record *rec)
733{ 738{
734 struct ProcessRecordContext *prc = cls; 739 struct ProcessRecordContext *prc = cls;
735 struct Request *req = prc->req; 740 struct Request *req = prc->req;
@@ -742,180 +747,180 @@ process_record(void *cls, const struct GNUNET_DNSPARSER_Record *rec)
742 dst_len = sizeof(dst); 747 dst_len = sizeof(dst);
743 off = 0; 748 off = 0;
744 records++; 749 records++;
745 if (0 != strcasecmp(rec->name, req->hostname)) 750 if (0 != strcasecmp (rec->name, req->hostname))
746 { 751 {
747 GNUNET_log( 752 GNUNET_log (
748 GNUNET_ERROR_TYPE_DEBUG, 753 GNUNET_ERROR_TYPE_DEBUG,
749 "DNS returned record from zone `%s' of type %u while resolving `%s'\n", 754 "DNS returned record from zone `%s' of type %u while resolving `%s'\n",
750 rec->name, 755 rec->name,
751 (unsigned int)rec->type, 756 (unsigned int) rec->type,
752 req->hostname); 757 req->hostname);
753 return; /* does not match hostname, might be glue, but 758 return; /* does not match hostname, might be glue, but
754 not useful for this pass! */ 759 not useful for this pass! */
755 } 760 }
756 expiration_time = rec->expiration_time; 761 expiration_time = rec->expiration_time;
757 left = GNUNET_TIME_absolute_get_remaining(expiration_time); 762 left = GNUNET_TIME_absolute_get_remaining (expiration_time);
758 if (0 == left.rel_value_us) 763 if (0 == left.rel_value_us)
759 { 764 {
760 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 765 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
761 "DNS returned expired record for `%s'\n", 766 "DNS returned expired record for `%s'\n",
762 req->hostname); 767 req->hostname);
763 GNUNET_STATISTICS_update(stats, 768 GNUNET_STATISTICS_update (stats,
764 "# expired records obtained from DNS", 769 "# expired records obtained from DNS",
765 1, 770 1,
766 GNUNET_NO); 771 GNUNET_NO);
767 return; /* record expired */ 772 return; /* record expired */
768 } 773 }
769 774
770 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 775 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
771 "DNS returned record that expires at %s for `%s'\n", 776 "DNS returned record that expires at %s for `%s'\n",
772 GNUNET_STRINGS_absolute_time_to_string(expiration_time), 777 GNUNET_STRINGS_absolute_time_to_string (expiration_time),
773 req->hostname); 778 req->hostname);
774 /* if expiration window is too short, bump it to configured minimum */ 779 /* if expiration window is too short, bump it to configured minimum */
775 if (left.rel_value_us < minimum_expiration_time.rel_value_us) 780 if (left.rel_value_us < minimum_expiration_time.rel_value_us)
776 expiration_time = 781 expiration_time =
777 GNUNET_TIME_relative_to_absolute(minimum_expiration_time); 782 GNUNET_TIME_relative_to_absolute (minimum_expiration_time);
778 switch (rec->type) 783 switch (rec->type)
779 { 784 {
780 case GNUNET_DNSPARSER_TYPE_NS: { 785 case GNUNET_DNSPARSER_TYPE_NS: {
781 struct GlueClosure gc; 786 struct GlueClosure gc;
782 787
783 /* check for glue */ 788 /* check for glue */
784 gc.req = req; 789 gc.req = req;
785 gc.ns = rec->data.hostname; 790 gc.ns = rec->data.hostname;
786 gc.found = GNUNET_NO; 791 gc.found = GNUNET_NO;
787 for_all_records(prc->p, &check_for_glue, &gc); 792 for_all_records (prc->p, &check_for_glue, &gc);
788 if ((GNUNET_NO == gc.found) && 793 if ((GNUNET_NO == gc.found) &&
789 (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst, 794 (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
790 dst_len, 795 dst_len,
791 &off, 796 &off,
792 req->hostname)) && 797 req->hostname)) &&
793 (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst, 798 (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
794 dst_len, 799 dst_len,
795 &off, 800 &off,
796 rec->data.hostname))) 801 rec->data.hostname)))
797 { 802 {
798 /* FIXME: actually check if this is out-of-bailiwick, 803 /* FIXME: actually check if this is out-of-bailiwick,
799 and if not request explicit resolution... */ 804 and if not request explicit resolution... */
800 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 805 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
801 "Converted OOB (`%s') NS record for `%s'\n", 806 "Converted OOB (`%s') NS record for `%s'\n",
802 rec->data.hostname, 807 rec->data.hostname,
803 rec->name); 808 rec->name);
804 add_record(req, 809 add_record (req,
805 GNUNET_GNSRECORD_TYPE_GNS2DNS, 810 GNUNET_GNSRECORD_TYPE_GNS2DNS,
806 expiration_time, 811 expiration_time,
807 dst, 812 dst,
808 off); 813 off);
809 } 814 }
810 else 815 else
811 { 816 {
812 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
813 "Converted NS record for `%s' using glue\n", 818 "Converted NS record for `%s' using glue\n",
814 rec->name); 819 rec->name);
815 } 820 }
816 break; 821 break;
817 } 822 }
818 823
819 case GNUNET_DNSPARSER_TYPE_CNAME: 824 case GNUNET_DNSPARSER_TYPE_CNAME:
820 if (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst, 825 if (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
821 dst_len, 826 dst_len,
822 &off, 827 &off,
823 rec->data.hostname)) 828 rec->data.hostname))
824 { 829 {
825 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
826 "Converting CNAME (`%s') record for `%s'\n", 831 "Converting CNAME (`%s') record for `%s'\n",
827 rec->data.hostname, 832 rec->data.hostname,
828 rec->name); 833 rec->name);
829 add_record(req, rec->type, expiration_time, dst, off); 834 add_record (req, rec->type, expiration_time, dst, off);
830 } 835 }
831 break; 836 break;
832 837
833 case GNUNET_DNSPARSER_TYPE_DNAME: 838 case GNUNET_DNSPARSER_TYPE_DNAME:
834 /* No support for DNAME in GNS yet! FIXME: support later! */ 839 /* No support for DNAME in GNS yet! FIXME: support later! */
835 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 840 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
836 "FIXME: not supported: %s DNAME %s\n", 841 "FIXME: not supported: %s DNAME %s\n",
837 rec->name, 842 rec->name,
838 rec->data.hostname); 843 rec->data.hostname);
839 break; 844 break;
840 845
841 case GNUNET_DNSPARSER_TYPE_MX: 846 case GNUNET_DNSPARSER_TYPE_MX:
842 if (GNUNET_OK == 847 if (GNUNET_OK ==
843 GNUNET_DNSPARSER_builder_add_mx(dst, dst_len, &off, rec->data.mx)) 848 GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &off, rec->data.mx))
844 { 849 {
845 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 850 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
846 "Converting MX (`%s') record for `%s'\n", 851 "Converting MX (`%s') record for `%s'\n",
847 rec->data.mx->mxhost, 852 rec->data.mx->mxhost,
848 rec->name); 853 rec->name);
849 add_record(req, rec->type, expiration_time, dst, off); 854 add_record (req, rec->type, expiration_time, dst, off);
850 } 855 }
851 break; 856 break;
852
853 case GNUNET_DNSPARSER_TYPE_SOA:
854 if (GNUNET_OK ==
855 GNUNET_DNSPARSER_builder_add_soa(dst, dst_len, &off, rec->data.soa))
856 {
857 /* NOTE: GNS does not really use SOAs */
858 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
859 "Converting SOA record for `%s'\n",
860 rec->name);
861 add_record(req, rec->type, expiration_time, dst, off);
862 }
863 break;
864 857
865 case GNUNET_DNSPARSER_TYPE_SRV: 858 case GNUNET_DNSPARSER_TYPE_SOA:
866 if (GNUNET_OK == 859 if (GNUNET_OK ==
867 GNUNET_DNSPARSER_builder_add_srv(dst, dst_len, &off, rec->data.srv)) 860 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &off, rec->data.soa))
868 { 861 {
869 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 862 /* NOTE: GNS does not really use SOAs */
870 "Converting SRV record for `%s'\n", 863 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
871 rec->name); 864 "Converting SOA record for `%s'\n",
872 add_record(req, rec->type, expiration_time, dst, off); 865 rec->name);
873 } 866 add_record (req, rec->type, expiration_time, dst, off);
874 break; 867 }
868 break;
875 869
876 case GNUNET_DNSPARSER_TYPE_PTR: 870 case GNUNET_DNSPARSER_TYPE_SRV:
877 if (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name(dst, 871 if (GNUNET_OK ==
878 dst_len, 872 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &off, rec->data.srv))
879 &off, 873 {
880 rec->data.hostname)) 874 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
881 { 875 "Converting SRV record for `%s'\n",
882 /* !?: what does a PTR record do in a regular TLD??? */ 876 rec->name);
883 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 877 add_record (req, rec->type, expiration_time, dst, off);
884 "Converting PTR record for `%s' (weird)\n", 878 }
885 rec->name); 879 break;
886 add_record(req, rec->type, expiration_time, dst, off);
887 }
888 break;
889 880
890 case GNUNET_DNSPARSER_TYPE_CERT: 881 case GNUNET_DNSPARSER_TYPE_PTR:
891 if (GNUNET_OK == 882 if (GNUNET_OK == GNUNET_DNSPARSER_builder_add_name (dst,
892 GNUNET_DNSPARSER_builder_add_cert(dst, dst_len, &off, rec->data.cert)) 883 dst_len,
893 { 884 &off,
894 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 885 rec->data.hostname))
895 "Converting CERT record for `%s'\n", 886 {
896 rec->name); 887 /* !?: what does a PTR record do in a regular TLD??? */
897 add_record(req, rec->type, expiration_time, dst, off); 888 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
898 } 889 "Converting PTR record for `%s' (weird)\n",
899 break; 890 rec->name);
891 add_record (req, rec->type, expiration_time, dst, off);
892 }
893 break;
900 894
901 /* Rest is 'raw' encoded and just needs to be copied IF 895 case GNUNET_DNSPARSER_TYPE_CERT:
902 the hostname matches the requested name; otherwise we 896 if (GNUNET_OK ==
903 simply cannot use it. */ 897 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &off, rec->data.cert))
904 case GNUNET_DNSPARSER_TYPE_A: 898 {
905 case GNUNET_DNSPARSER_TYPE_AAAA: 899 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
906 case GNUNET_DNSPARSER_TYPE_TXT: 900 "Converting CERT record for `%s'\n",
907 default: 901 rec->name);
908 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 902 add_record (req, rec->type, expiration_time, dst, off);
909 "Converting record of type %u for `%s'\n",
910 (unsigned int)rec->type,
911 rec->name);
912 add_record(req,
913 rec->type,
914 expiration_time,
915 rec->data.raw.data,
916 rec->data.raw.data_len);
917 break;
918 } 903 }
904 break;
905
906 /* Rest is 'raw' encoded and just needs to be copied IF
907 the hostname matches the requested name; otherwise we
908 simply cannot use it. */
909 case GNUNET_DNSPARSER_TYPE_A:
910 case GNUNET_DNSPARSER_TYPE_AAAA:
911 case GNUNET_DNSPARSER_TYPE_TXT:
912 default:
913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
914 "Converting record of type %u for `%s'\n",
915 (unsigned int) rec->type,
916 rec->name);
917 add_record (req,
918 rec->type,
919 expiration_time,
920 rec->data.raw.data,
921 rec->data.raw.data_len);
922 break;
923 }
919} 924}
920 925
921 926
@@ -930,89 +935,89 @@ process_record(void *cls, const struct GNUNET_DNSPARSER_Record *rec)
930 * @param emsg NULL on success, otherwise an error message 935 * @param emsg NULL on success, otherwise an error message
931 */ 936 */
932static void 937static void
933store_completed_cb(void *cls, int32_t success, const char *emsg) 938store_completed_cb (void *cls, int32_t success, const char *emsg)
934{ 939{
935 static struct GNUNET_TIME_Absolute last; 940 static struct GNUNET_TIME_Absolute last;
936 struct Request *req = cls; 941 struct Request *req = cls;
937 942
938 req->qe = NULL; 943 req->qe = NULL;
939 if (GNUNET_SYSERR == success) 944 if (GNUNET_SYSERR == success)
940 { 945 {
941 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 946 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
942 "Failed to store zone data for `%s': %s\n", 947 "Failed to store zone data for `%s': %s\n",
943 req->hostname, 948 req->hostname,
944 emsg); 949 emsg);
945 } 950 }
946 else 951 else
947 { 952 {
948 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 953 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
949 "Stored records under `%s' (%d)\n", 954 "Stored records under `%s' (%d)\n",
950 req->hostname, 955 req->hostname,
951 success); 956 success);
952 } 957 }
953 total_reg_proc_dns_ns++; /* finished regular processing */ 958 total_reg_proc_dns_ns++; /* finished regular processing */
954 pending_rs--; 959 pending_rs--;
955 free_records(req); 960 free_records (req);
956 /* compute NAMESTORE statistics */ 961 /* compute NAMESTORE statistics */
957 { 962 {
958 static uint64_t total_ns_latency_cnt; 963 static uint64_t total_ns_latency_cnt;
959 static struct GNUNET_TIME_Relative total_ns_latency; 964 static struct GNUNET_TIME_Relative total_ns_latency;
960 struct GNUNET_TIME_Relative ns_latency; 965 struct GNUNET_TIME_Relative ns_latency;
961 966
962 ns_latency = GNUNET_TIME_absolute_get_duration(req->op_start_time); 967 ns_latency = GNUNET_TIME_absolute_get_duration (req->op_start_time);
963 total_ns_latency = GNUNET_TIME_relative_add(total_ns_latency, ns_latency); 968 total_ns_latency = GNUNET_TIME_relative_add (total_ns_latency, ns_latency);
964 if (0 == total_ns_latency_cnt) 969 if (0 == total_ns_latency_cnt)
965 last = GNUNET_TIME_absolute_get(); 970 last = GNUNET_TIME_absolute_get ();
966 total_ns_latency_cnt++; 971 total_ns_latency_cnt++;
967 if (0 == (total_ns_latency_cnt % 1000)) 972 if (0 == (total_ns_latency_cnt % 1000))
968 { 973 {
969 struct GNUNET_TIME_Relative delta; 974 struct GNUNET_TIME_Relative delta;
970 975
971 delta = GNUNET_TIME_absolute_get_duration(last); 976 delta = GNUNET_TIME_absolute_get_duration (last);
972 last = GNUNET_TIME_absolute_get(); 977 last = GNUNET_TIME_absolute_get ();
973 fprintf(stderr, 978 fprintf (stderr,
974 "Processed 1000 records in %s\n", 979 "Processed 1000 records in %s\n",
975 GNUNET_STRINGS_relative_time_to_string(delta, GNUNET_YES)); 980 GNUNET_STRINGS_relative_time_to_string (delta, GNUNET_YES));
976 GNUNET_STATISTICS_set(stats, 981 GNUNET_STATISTICS_set (stats,
977 "# average NAMESTORE PUT latency (μs)", 982 "# average NAMESTORE PUT latency (μs)",
978 total_ns_latency.rel_value_us / 983 total_ns_latency.rel_value_us
979 total_ns_latency_cnt, 984 / total_ns_latency_cnt,
980 GNUNET_NO); 985 GNUNET_NO);
981 } 986 }
982 } 987 }
983 /* compute and publish overall velocity */ 988 /* compute and publish overall velocity */
984 if (0 == (total_reg_proc_dns_ns % 100)) 989 if (0 == (total_reg_proc_dns_ns % 100))
985 { 990 {
986 struct GNUNET_TIME_Relative runtime; 991 struct GNUNET_TIME_Relative runtime;
987 992
988 runtime = GNUNET_TIME_absolute_get_duration(start_time_reg_proc); 993 runtime = GNUNET_TIME_absolute_get_duration (start_time_reg_proc);
989 runtime = GNUNET_TIME_relative_subtract(runtime, idle_time); 994 runtime = GNUNET_TIME_relative_subtract (runtime, idle_time);
990 runtime = 995 runtime =
991 GNUNET_TIME_relative_divide(runtime, 996 GNUNET_TIME_relative_divide (runtime,
992 total_reg_proc_dns + total_reg_proc_dns_ns); 997 total_reg_proc_dns + total_reg_proc_dns_ns);
993 GNUNET_STATISTICS_set(stats, 998 GNUNET_STATISTICS_set (stats,
994 "# Regular processing completed without NAMESTORE", 999 "# Regular processing completed without NAMESTORE",
995 total_reg_proc_dns, 1000 total_reg_proc_dns,
996 GNUNET_NO); 1001 GNUNET_NO);
997 GNUNET_STATISTICS_set(stats, 1002 GNUNET_STATISTICS_set (stats,
998 "# Regular processing completed with NAMESTORE PUT", 1003 "# Regular processing completed with NAMESTORE PUT",
999 total_reg_proc_dns_ns, 1004 total_reg_proc_dns_ns,
1000 GNUNET_NO); 1005 GNUNET_NO);
1001 GNUNET_STATISTICS_set(stats, 1006 GNUNET_STATISTICS_set (stats,
1002 "# average request processing latency (μs)", 1007 "# average request processing latency (μs)",
1003 runtime.rel_value_us, 1008 runtime.rel_value_us,
1004 GNUNET_NO); 1009 GNUNET_NO);
1005 GNUNET_STATISTICS_set(stats, 1010 GNUNET_STATISTICS_set (stats,
1006 "# total time spent idle (μs)", 1011 "# total time spent idle (μs)",
1007 idle_time.rel_value_us, 1012 idle_time.rel_value_us,
1008 GNUNET_NO); 1013 GNUNET_NO);
1009 } 1014 }
1010 1015
1011 if (NULL == t) 1016 if (NULL == t)
1012 { 1017 {
1013 sleep_time_reg_proc = GNUNET_TIME_absolute_get(); 1018 sleep_time_reg_proc = GNUNET_TIME_absolute_get ();
1014 t = GNUNET_SCHEDULER_add_now(&process_queue, NULL); 1019 t = GNUNET_SCHEDULER_add_now (&process_queue, NULL);
1015 } 1020 }
1016} 1021}
1017 1022
1018 1023
@@ -1024,148 +1029,148 @@ store_completed_cb(void *cls, int32_t success, const char *emsg)
1024 * @param dns_len number of bytes in @a dns 1029 * @param dns_len number of bytes in @a dns
1025 */ 1030 */
1026static void 1031static void
1027process_result(void *cls, 1032process_result (void *cls,
1028 const struct GNUNET_TUN_DnsHeader *dns, 1033 const struct GNUNET_TUN_DnsHeader *dns,
1029 size_t dns_len) 1034 size_t dns_len)
1030{ 1035{
1031 struct Request *req = cls; 1036 struct Request *req = cls;
1032 struct Record *rec; 1037 struct Record *rec;
1033 struct GNUNET_DNSPARSER_Packet *p; 1038 struct GNUNET_DNSPARSER_Packet *p;
1034 unsigned int rd_count; 1039 unsigned int rd_count;
1035 1040
1036 GNUNET_assert(NULL == req->hn); 1041 GNUNET_assert (NULL == req->hn);
1037 if (NULL == dns) 1042 if (NULL == dns)
1043 {
1044 /* stub gave up */
1045 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, req);
1046 pending--;
1047 if (NULL == t)
1038 { 1048 {
1039 /* stub gave up */ 1049 sleep_time_reg_proc = GNUNET_TIME_absolute_get ();
1040 GNUNET_CONTAINER_DLL_remove(req_head, req_tail, req); 1050 t = GNUNET_SCHEDULER_add_now (&process_queue, NULL);
1041 pending--;
1042 if (NULL == t)
1043 {
1044 sleep_time_reg_proc = GNUNET_TIME_absolute_get();
1045 t = GNUNET_SCHEDULER_add_now(&process_queue, NULL);
1046 }
1047 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1048 "Stub gave up on DNS reply for `%s'\n",
1049 req->hostname);
1050 GNUNET_STATISTICS_update(stats, "# DNS lookups timed out", 1, GNUNET_NO);
1051 if (req->issue_num > MAX_RETRIES)
1052 {
1053 failures++;
1054 free_request(req);
1055 GNUNET_STATISTICS_update(stats, "# requests given up on", 1, GNUNET_NO);
1056 return;
1057 }
1058 total_reg_proc_dns++;
1059 req->rs = NULL;
1060 insert_sorted(req);
1061 return;
1062 } 1051 }
1063 if (req->id != dns->id) 1052 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1053 "Stub gave up on DNS reply for `%s'\n",
1054 req->hostname);
1055 GNUNET_STATISTICS_update (stats, "# DNS lookups timed out", 1, GNUNET_NO);
1056 if (req->issue_num > MAX_RETRIES)
1064 { 1057 {
1065 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1058 failures++;
1066 "DNS ID did not match request, ignoring reply\n"); 1059 free_request (req);
1067 GNUNET_STATISTICS_update(stats, "# DNS ID mismatches", 1, GNUNET_NO); 1060 GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1068 return; 1061 return;
1069 } 1062 }
1070 GNUNET_CONTAINER_DLL_remove(req_head, req_tail, req); 1063 total_reg_proc_dns++;
1071 GNUNET_DNSSTUB_resolve_cancel(req->rs); 1064 req->rs = NULL;
1065 insert_sorted (req);
1066 return;
1067 }
1068 if (req->id != dns->id)
1069 {
1070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1071 "DNS ID did not match request, ignoring reply\n");
1072 GNUNET_STATISTICS_update (stats, "# DNS ID mismatches", 1, GNUNET_NO);
1073 return;
1074 }
1075 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, req);
1076 GNUNET_DNSSTUB_resolve_cancel (req->rs);
1072 req->rs = NULL; 1077 req->rs = NULL;
1073 pending--; 1078 pending--;
1074 p = GNUNET_DNSPARSER_parse((const char *)dns, dns_len); 1079 p = GNUNET_DNSPARSER_parse ((const char *) dns, dns_len);
1075 if (NULL == p) 1080 if (NULL == p)
1081 {
1082 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1083 "Failed to parse DNS reply for `%s'\n",
1084 req->hostname);
1085 GNUNET_STATISTICS_update (stats, "# DNS parser errors", 1, GNUNET_NO);
1086 if (NULL == t)
1076 { 1087 {
1077 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1088 sleep_time_reg_proc = GNUNET_TIME_absolute_get ();
1078 "Failed to parse DNS reply for `%s'\n", 1089 t = GNUNET_SCHEDULER_add_now (&process_queue, NULL);
1079 req->hostname); 1090 }
1080 GNUNET_STATISTICS_update(stats, "# DNS parser errors", 1, GNUNET_NO); 1091 if (req->issue_num > MAX_RETRIES)
1081 if (NULL == t) 1092 {
1082 { 1093 failures++;
1083 sleep_time_reg_proc = GNUNET_TIME_absolute_get(); 1094 free_request (req);
1084 t = GNUNET_SCHEDULER_add_now(&process_queue, NULL); 1095 GNUNET_STATISTICS_update (stats, "# requests given up on", 1, GNUNET_NO);
1085 }
1086 if (req->issue_num > MAX_RETRIES)
1087 {
1088 failures++;
1089 free_request(req);
1090 GNUNET_STATISTICS_update(stats, "# requests given up on", 1, GNUNET_NO);
1091 return;
1092 }
1093 insert_sorted(req);
1094 return; 1096 return;
1095 } 1097 }
1098 insert_sorted (req);
1099 return;
1100 }
1096 /* import new records */ 1101 /* import new records */
1097 req->issue_num = 0; /* success, reset counter! */ 1102 req->issue_num = 0; /* success, reset counter! */
1098 { 1103 {
1099 struct ProcessRecordContext prc = { .req = req, .p = p }; 1104 struct ProcessRecordContext prc = { .req = req, .p = p };
1100 1105
1101 for_all_records(p, &process_record, &prc); 1106 for_all_records (p, &process_record, &prc);
1102 } 1107 }
1103 GNUNET_DNSPARSER_free_packet(p); 1108 GNUNET_DNSPARSER_free_packet (p);
1104 /* count records found, determine minimum expiration time */ 1109 /* count records found, determine minimum expiration time */
1105 req->expires = GNUNET_TIME_UNIT_FOREVER_ABS; 1110 req->expires = GNUNET_TIME_UNIT_FOREVER_ABS;
1106 { 1111 {
1107 struct GNUNET_TIME_Relative dns_latency; 1112 struct GNUNET_TIME_Relative dns_latency;
1108 1113
1109 dns_latency = GNUNET_TIME_absolute_get_duration(req->op_start_time); 1114 dns_latency = GNUNET_TIME_absolute_get_duration (req->op_start_time);
1110 total_dns_latency = 1115 total_dns_latency =
1111 GNUNET_TIME_relative_add(total_dns_latency, dns_latency); 1116 GNUNET_TIME_relative_add (total_dns_latency, dns_latency);
1112 total_dns_latency_cnt++; 1117 total_dns_latency_cnt++;
1113 if (0 == (total_dns_latency_cnt % 1000)) 1118 if (0 == (total_dns_latency_cnt % 1000))
1114 { 1119 {
1115 GNUNET_STATISTICS_set(stats, 1120 GNUNET_STATISTICS_set (stats,
1116 "# average DNS lookup latency (μs)", 1121 "# average DNS lookup latency (μs)",
1117 total_dns_latency.rel_value_us / 1122 total_dns_latency.rel_value_us
1118 total_dns_latency_cnt, 1123 / total_dns_latency_cnt,
1119 GNUNET_NO); 1124 GNUNET_NO);
1120 } 1125 }
1121 } 1126 }
1122 rd_count = 0; 1127 rd_count = 0;
1123 for (rec = req->rec_head; NULL != rec; rec = rec->next) 1128 for (rec = req->rec_head; NULL != rec; rec = rec->next)
1124 { 1129 {
1125 struct GNUNET_TIME_Absolute at; 1130 struct GNUNET_TIME_Absolute at;
1126 1131
1127 at.abs_value_us = rec->grd.expiration_time; 1132 at.abs_value_us = rec->grd.expiration_time;
1128 req->expires = GNUNET_TIME_absolute_min(req->expires, at); 1133 req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1129 rd_count++; 1134 rd_count++;
1130 } 1135 }
1131 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1136 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1132 "Obtained %u records for `%s'\n", 1137 "Obtained %u records for `%s'\n",
1133 rd_count, 1138 rd_count,
1134 req->hostname); 1139 req->hostname);
1135 /* Instead of going for SOA, simplified for now to look each 1140 /* Instead of going for SOA, simplified for now to look each
1136 day in case we got an empty response */ 1141 day in case we got an empty response */
1137 if (0 == rd_count) 1142 if (0 == rd_count)
1138 { 1143 {
1139 req->expires = GNUNET_TIME_relative_to_absolute(GNUNET_TIME_UNIT_DAYS); 1144 req->expires = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_DAYS);
1140 GNUNET_STATISTICS_update(stats, 1145 GNUNET_STATISTICS_update (stats,
1141 "# empty DNS replies (usually NXDOMAIN)", 1146 "# empty DNS replies (usually NXDOMAIN)",
1142 1, 1147 1,
1143 GNUNET_NO); 1148 GNUNET_NO);
1144 } 1149 }
1145 else 1150 else
1146 { 1151 {
1147 record_sets++; 1152 record_sets++;
1148 } 1153 }
1149 /* convert records to namestore import format */ 1154 /* convert records to namestore import format */
1150 { 1155 {
1151 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL(rd_count)]; 1156 struct GNUNET_GNSRECORD_Data rd[GNUNET_NZL (rd_count)];
1152 unsigned int off = 0; 1157 unsigned int off = 0;
1153 1158
1154 /* convert linked list into array */ 1159 /* convert linked list into array */
1155 for (rec = req->rec_head; NULL != rec; rec = rec->next) 1160 for (rec = req->rec_head; NULL != rec; rec = rec->next)
1156 rd[off++] = rec->grd; 1161 rd[off++] = rec->grd;
1157 pending_rs++; 1162 pending_rs++;
1158 req->op_start_time = GNUNET_TIME_absolute_get(); 1163 req->op_start_time = GNUNET_TIME_absolute_get ();
1159 req->qe = GNUNET_NAMESTORE_records_store(ns, 1164 req->qe = GNUNET_NAMESTORE_records_store (ns,
1160 &req->zone->key, 1165 &req->zone->key,
1161 get_label(req), 1166 get_label (req),
1162 rd_count, 1167 rd_count,
1163 rd, 1168 rd,
1164 &store_completed_cb, 1169 &store_completed_cb,
1165 req); 1170 req);
1166 GNUNET_assert(NULL != req->qe); 1171 GNUNET_assert (NULL != req->qe);
1167 } 1172 }
1168 insert_sorted(req); 1173 insert_sorted (req);
1169} 1174}
1170 1175
1171 1176
@@ -1175,7 +1180,7 @@ process_result(void *cls,
1175 * @param cls NULL 1180 * @param cls NULL
1176 */ 1181 */
1177static void 1182static void
1178process_queue(void *cls) 1183process_queue (void *cls)
1179{ 1184{
1180 struct Request *req; 1185 struct Request *req;
1181 unsigned int series; 1186 unsigned int series;
@@ -1183,82 +1188,82 @@ process_queue(void *cls)
1183 size_t raw_size; 1188 size_t raw_size;
1184 struct GNUNET_TIME_Relative delay; 1189 struct GNUNET_TIME_Relative delay;
1185 1190
1186 (void)cls; 1191 (void) cls;
1187 delay = GNUNET_TIME_absolute_get_duration(sleep_time_reg_proc); 1192 delay = GNUNET_TIME_absolute_get_duration (sleep_time_reg_proc);
1188 idle_time = GNUNET_TIME_relative_add(idle_time, delay); 1193 idle_time = GNUNET_TIME_relative_add (idle_time, delay);
1189 series = 0; 1194 series = 0;
1190 t = NULL; 1195 t = NULL;
1191 while (pending + pending_rs < THRESH) 1196 while (pending + pending_rs < THRESH)
1197 {
1198 req = GNUNET_CONTAINER_heap_peek (req_heap);
1199 if (NULL == req)
1200 break;
1201 if (NULL != req->qe)
1202 return; /* namestore op still pending */
1203 if (NULL != req->rs)
1192 { 1204 {
1193 req = GNUNET_CONTAINER_heap_peek(req_heap); 1205 GNUNET_break (0);
1194 if (NULL == req) 1206 return; /* already submitted */
1195 break;
1196 if (NULL != req->qe)
1197 return; /* namestore op still pending */
1198 if (NULL != req->rs)
1199 {
1200 GNUNET_break(0);
1201 return; /* already submitted */
1202 }
1203 if (GNUNET_TIME_absolute_get_remaining(req->expires).rel_value_us > 0)
1204 break;
1205 GNUNET_assert(req == GNUNET_CONTAINER_heap_remove_root(req_heap));
1206 req->hn = NULL;
1207 GNUNET_CONTAINER_DLL_insert(req_head, req_tail, req);
1208 GNUNET_assert(NULL == req->rs);
1209 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1210 "Requesting resolution for `%s'\n",
1211 req->hostname);
1212 raw = build_dns_query(req, &raw_size);
1213 if (NULL == raw)
1214 {
1215 GNUNET_break(0);
1216 free_request(req);
1217 continue;
1218 }
1219 req->op_start_time = GNUNET_TIME_absolute_get();
1220 req->rs = GNUNET_DNSSTUB_resolve(ctx, raw, raw_size, &process_result, req);
1221 GNUNET_assert(NULL != req->rs);
1222 req->issue_num++;
1223 lookups++;
1224 pending++;
1225 series++;
1226 if (series > MAX_SERIES)
1227 break;
1228 } 1207 }
1229 if (pending + pending_rs >= THRESH) 1208 if (GNUNET_TIME_absolute_get_remaining (req->expires).rel_value_us > 0)
1209 break;
1210 GNUNET_assert (req == GNUNET_CONTAINER_heap_remove_root (req_heap));
1211 req->hn = NULL;
1212 GNUNET_CONTAINER_DLL_insert (req_head, req_tail, req);
1213 GNUNET_assert (NULL == req->rs);
1214 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1215 "Requesting resolution for `%s'\n",
1216 req->hostname);
1217 raw = build_dns_query (req, &raw_size);
1218 if (NULL == raw)
1230 { 1219 {
1231 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1220 GNUNET_break (0);
1232 "Stopped processing queue (%u+%u/%u)]\n", 1221 free_request (req);
1233 pending, 1222 continue;
1234 pending_rs,
1235 THRESH);
1236 return; /* wait for replies */
1237 } 1223 }
1238 req = GNUNET_CONTAINER_heap_peek(req_heap); 1224 req->op_start_time = GNUNET_TIME_absolute_get ();
1225 req->rs = GNUNET_DNSSTUB_resolve (ctx, raw, raw_size, &process_result, req);
1226 GNUNET_assert (NULL != req->rs);
1227 req->issue_num++;
1228 lookups++;
1229 pending++;
1230 series++;
1231 if (series > MAX_SERIES)
1232 break;
1233 }
1234 if (pending + pending_rs >= THRESH)
1235 {
1236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1237 "Stopped processing queue (%u+%u/%u)]\n",
1238 pending,
1239 pending_rs,
1240 THRESH);
1241 return; /* wait for replies */
1242 }
1243 req = GNUNET_CONTAINER_heap_peek (req_heap);
1239 if (NULL == req) 1244 if (NULL == req)
1240 { 1245 {
1241 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1242 "Stopped processing queue: empty queue\n"); 1247 "Stopped processing queue: empty queue\n");
1243 return; 1248 return;
1244 } 1249 }
1245 if (GNUNET_TIME_absolute_get_remaining(req->expires).rel_value_us > 0) 1250 if (GNUNET_TIME_absolute_get_remaining (req->expires).rel_value_us > 0)
1246 { 1251 {
1247 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1252 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1248 "Waiting until %s for next record (`%s') to expire\n", 1253 "Waiting until %s for next record (`%s') to expire\n",
1249 GNUNET_STRINGS_absolute_time_to_string(req->expires), 1254 GNUNET_STRINGS_absolute_time_to_string (req->expires),
1250 req->hostname); 1255 req->hostname);
1251 if (NULL != t) 1256 if (NULL != t)
1252 GNUNET_SCHEDULER_cancel(t); 1257 GNUNET_SCHEDULER_cancel (t);
1253 sleep_time_reg_proc = GNUNET_TIME_absolute_get(); 1258 sleep_time_reg_proc = GNUNET_TIME_absolute_get ();
1254 t = GNUNET_SCHEDULER_add_at(req->expires, &process_queue, NULL); 1259 t = GNUNET_SCHEDULER_add_at (req->expires, &process_queue, NULL);
1255 return; 1260 return;
1256 } 1261 }
1257 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Throttling\n"); 1262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Throttling\n");
1258 if (NULL != t) 1263 if (NULL != t)
1259 GNUNET_SCHEDULER_cancel(t); 1264 GNUNET_SCHEDULER_cancel (t);
1260 sleep_time_reg_proc = GNUNET_TIME_absolute_get(); 1265 sleep_time_reg_proc = GNUNET_TIME_absolute_get ();
1261 t = GNUNET_SCHEDULER_add_delayed(SERIES_DELAY, &process_queue, NULL); 1266 t = GNUNET_SCHEDULER_add_delayed (SERIES_DELAY, &process_queue, NULL);
1262} 1267}
1263 1268
1264 1269
@@ -1272,13 +1277,13 @@ process_queue(void *cls)
1272 * @return #GNUNET_OK 1277 * @return #GNUNET_OK
1273 */ 1278 */
1274static int 1279static int
1275free_request_it(void *cls, const struct GNUNET_HashCode *key, void *value) 1280free_request_it (void *cls, const struct GNUNET_HashCode *key, void *value)
1276{ 1281{
1277 struct Request *req = value; 1282 struct Request *req = value;
1278 1283
1279 (void)cls; 1284 (void) cls;
1280 (void)key; 1285 (void) key;
1281 free_request(req); 1286 free_request (req);
1282 return GNUNET_OK; 1287 return GNUNET_OK;
1283} 1288}
1284 1289
@@ -1289,73 +1294,73 @@ free_request_it(void *cls, const struct GNUNET_HashCode *key, void *value)
1289 * @param cls NULL 1294 * @param cls NULL
1290 */ 1295 */
1291static void 1296static void
1292do_shutdown(void *cls) 1297do_shutdown (void *cls)
1293{ 1298{
1294 struct Request *req; 1299 struct Request *req;
1295 struct Zone *zone; 1300 struct Zone *zone;
1296 1301
1297 (void)cls; 1302 (void) cls;
1298 if (NULL != id) 1303 if (NULL != id)
1299 { 1304 {
1300 GNUNET_IDENTITY_disconnect(id); 1305 GNUNET_IDENTITY_disconnect (id);
1301 id = NULL; 1306 id = NULL;
1302 } 1307 }
1303 if (NULL != t) 1308 if (NULL != t)
1304 { 1309 {
1305 GNUNET_SCHEDULER_cancel(t); 1310 GNUNET_SCHEDULER_cancel (t);
1306 t = NULL; 1311 t = NULL;
1307 } 1312 }
1308 while (NULL != (req = req_head)) 1313 while (NULL != (req = req_head))
1309 { 1314 {
1310 GNUNET_CONTAINER_DLL_remove(req_head, req_tail, req); 1315 GNUNET_CONTAINER_DLL_remove (req_head, req_tail, req);
1311 if (NULL != req->qe) 1316 if (NULL != req->qe)
1312 GNUNET_NAMESTORE_cancel(req->qe); 1317 GNUNET_NAMESTORE_cancel (req->qe);
1313 free_request(req); 1318 free_request (req);
1314 } 1319 }
1315 while (NULL != (req = GNUNET_CONTAINER_heap_remove_root(req_heap))) 1320 while (NULL != (req = GNUNET_CONTAINER_heap_remove_root (req_heap)))
1316 { 1321 {
1317 req->hn = NULL; 1322 req->hn = NULL;
1318 if (NULL != req->qe) 1323 if (NULL != req->qe)
1319 GNUNET_NAMESTORE_cancel(req->qe); 1324 GNUNET_NAMESTORE_cancel (req->qe);
1320 free_request(req); 1325 free_request (req);
1321 } 1326 }
1322 if (NULL != zone_it) 1327 if (NULL != zone_it)
1323 { 1328 {
1324 GNUNET_NAMESTORE_zone_iteration_stop(zone_it); 1329 GNUNET_NAMESTORE_zone_iteration_stop (zone_it);
1325 zone_it = NULL; 1330 zone_it = NULL;
1326 } 1331 }
1327 if (NULL != ns) 1332 if (NULL != ns)
1328 { 1333 {
1329 GNUNET_NAMESTORE_disconnect(ns); 1334 GNUNET_NAMESTORE_disconnect (ns);
1330 ns = NULL; 1335 ns = NULL;
1331 } 1336 }
1332 if (NULL != ctx) 1337 if (NULL != ctx)
1333 { 1338 {
1334 GNUNET_DNSSTUB_stop(ctx); 1339 GNUNET_DNSSTUB_stop (ctx);
1335 ctx = NULL; 1340 ctx = NULL;
1336 } 1341 }
1337 if (NULL != req_heap) 1342 if (NULL != req_heap)
1338 { 1343 {
1339 GNUNET_CONTAINER_heap_destroy(req_heap); 1344 GNUNET_CONTAINER_heap_destroy (req_heap);
1340 req_heap = NULL; 1345 req_heap = NULL;
1341 } 1346 }
1342 if (NULL != ns_pending) 1347 if (NULL != ns_pending)
1343 { 1348 {
1344 GNUNET_CONTAINER_multihashmap_iterate(ns_pending, &free_request_it, NULL); 1349 GNUNET_CONTAINER_multihashmap_iterate (ns_pending, &free_request_it, NULL);
1345 GNUNET_CONTAINER_multihashmap_destroy(ns_pending); 1350 GNUNET_CONTAINER_multihashmap_destroy (ns_pending);
1346 ns_pending = NULL; 1351 ns_pending = NULL;
1347 } 1352 }
1348 while (NULL != (zone = zone_head)) 1353 while (NULL != (zone = zone_head))
1349 { 1354 {
1350 GNUNET_CONTAINER_DLL_remove(zone_head, zone_tail, zone); 1355 GNUNET_CONTAINER_DLL_remove (zone_head, zone_tail, zone);
1351 GNUNET_free(zone->domain); 1356 GNUNET_free (zone->domain);
1352 GNUNET_free(zone); 1357 GNUNET_free (zone);
1353 } 1358 }
1354 if (NULL != stats) 1359 if (NULL != stats)
1355 { 1360 {
1356 GNUNET_STATISTICS_destroy(stats, GNUNET_NO); 1361 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
1357 stats = NULL; 1362 stats = NULL;
1358 } 1363 }
1359} 1364}
1360 1365
1361 1366
@@ -1366,7 +1371,7 @@ do_shutdown(void *cls)
1366 * @param cls NULL 1371 * @param cls NULL
1367 */ 1372 */
1368static void 1373static void
1369iterate_zones(void *cls); 1374iterate_zones (void *cls);
1370 1375
1371 1376
1372/** 1377/**
@@ -1376,16 +1381,16 @@ iterate_zones(void *cls);
1376 * @param cls a `struct Zone` 1381 * @param cls a `struct Zone`
1377 */ 1382 */
1378static void 1383static void
1379ns_lookup_error_cb(void *cls) 1384ns_lookup_error_cb (void *cls)
1380{ 1385{
1381 struct Zone *zone = cls; 1386 struct Zone *zone = cls;
1382 1387
1383 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1388 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1384 "Failed to load data from namestore for zone `%s'\n", 1389 "Failed to load data from namestore for zone `%s'\n",
1385 zone->domain); 1390 zone->domain);
1386 zone_it = NULL; 1391 zone_it = NULL;
1387 ns_iterator_trigger_next = 0; 1392 ns_iterator_trigger_next = 0;
1388 iterate_zones(NULL); 1393 iterate_zones (NULL);
1389} 1394}
1390 1395
1391 1396
@@ -1399,11 +1404,11 @@ ns_lookup_error_cb(void *cls)
1399 * @param rd array of records with data to store 1404 * @param rd array of records with data to store
1400 */ 1405 */
1401static void 1406static void
1402ns_lookup_result_cb(void *cls, 1407ns_lookup_result_cb (void *cls,
1403 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, 1408 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
1404 const char *label, 1409 const char *label,
1405 unsigned int rd_count, 1410 unsigned int rd_count,
1406 const struct GNUNET_GNSRECORD_Data *rd) 1411 const struct GNUNET_GNSRECORD_Data *rd)
1407{ 1412{
1408 struct Zone *zone = cls; 1413 struct Zone *zone = cls;
1409 struct Request *req; 1414 struct Request *req;
@@ -1411,85 +1416,85 @@ ns_lookup_result_cb(void *cls,
1411 char *fqdn; 1416 char *fqdn;
1412 1417
1413 ns_iterator_trigger_next--; 1418 ns_iterator_trigger_next--;
1414 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1415 "Obtained NAMESTORE reply, %llu left in round\n", 1420 "Obtained NAMESTORE reply, %llu left in round\n",
1416 (unsigned long long)ns_iterator_trigger_next); 1421 (unsigned long long) ns_iterator_trigger_next);
1417 if (0 == ns_iterator_trigger_next) 1422 if (0 == ns_iterator_trigger_next)
1418 { 1423 {
1419 ns_iterator_trigger_next = NS_BATCH_SIZE; 1424 ns_iterator_trigger_next = NS_BATCH_SIZE;
1420 GNUNET_STATISTICS_update(stats, 1425 GNUNET_STATISTICS_update (stats,
1421 "# NAMESTORE records requested from cache", 1426 "# NAMESTORE records requested from cache",
1422 ns_iterator_trigger_next, 1427 ns_iterator_trigger_next,
1423 GNUNET_NO); 1428 GNUNET_NO);
1424 GNUNET_NAMESTORE_zone_iterator_next(zone_it, ns_iterator_trigger_next); 1429 GNUNET_NAMESTORE_zone_iterator_next (zone_it, ns_iterator_trigger_next);
1425 } 1430 }
1426 GNUNET_asprintf(&fqdn, "%s.%s", label, zone->domain); 1431 GNUNET_asprintf (&fqdn, "%s.%s", label, zone->domain);
1427 GNUNET_CRYPTO_hash(fqdn, strlen(fqdn) + 1, &hc); 1432 GNUNET_CRYPTO_hash (fqdn, strlen (fqdn) + 1, &hc);
1428 GNUNET_free(fqdn); 1433 GNUNET_free (fqdn);
1429 req = GNUNET_CONTAINER_multihashmap_get(ns_pending, &hc); 1434 req = GNUNET_CONTAINER_multihashmap_get (ns_pending, &hc);
1430 if (NULL == req) 1435 if (NULL == req)
1431 { 1436 {
1432 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1437 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1433 "Ignoring record `%s' in zone `%s': not on my list!\n", 1438 "Ignoring record `%s' in zone `%s': not on my list!\n",
1434 label, 1439 label,
1435 zone->domain); 1440 zone->domain);
1436 return; 1441 return;
1437 } 1442 }
1438 GNUNET_assert(GNUNET_OK == 1443 GNUNET_assert (GNUNET_OK ==
1439 GNUNET_CONTAINER_multihashmap_remove(ns_pending, &hc, req)); 1444 GNUNET_CONTAINER_multihashmap_remove (ns_pending, &hc, req));
1440 GNUNET_break(0 == GNUNET_memcmp(key, &req->zone->key)); 1445 GNUNET_break (0 == GNUNET_memcmp (key, &req->zone->key));
1441 GNUNET_break(0 == strcasecmp(label, get_label(req))); 1446 GNUNET_break (0 == strcasecmp (label, get_label (req)));
1442 for (unsigned int i = 0; i < rd_count; i++) 1447 for (unsigned int i = 0; i < rd_count; i++)
1443 { 1448 {
1444 struct GNUNET_TIME_Absolute at; 1449 struct GNUNET_TIME_Absolute at;
1445 1450
1446 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION)) 1451 if (0 != (rd->flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
1447 { 1452 {
1448 struct GNUNET_TIME_Relative rel; 1453 struct GNUNET_TIME_Relative rel;
1449 1454
1450 rel.rel_value_us = rd->expiration_time; 1455 rel.rel_value_us = rd->expiration_time;
1451 at = GNUNET_TIME_relative_to_absolute(rel); 1456 at = GNUNET_TIME_relative_to_absolute (rel);
1452 }
1453 else
1454 {
1455 at.abs_value_us = rd->expiration_time;
1456 }
1457 add_record(req, rd->record_type, at, rd->data, rd->data_size);
1458 } 1457 }
1459 if (0 == rd_count) 1458 else
1460 { 1459 {
1461 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 1460 at.abs_value_us = rd->expiration_time;
1462 "Empty record set in namestore for `%s'\n",
1463 req->hostname);
1464 } 1461 }
1462 add_record (req, rd->record_type, at, rd->data, rd->data_size);
1463 }
1464 if (0 == rd_count)
1465 {
1466 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1467 "Empty record set in namestore for `%s'\n",
1468 req->hostname);
1469 }
1465 else 1470 else
1471 {
1472 unsigned int pos = 0;
1473
1474 cached++;
1475 req->expires = GNUNET_TIME_UNIT_FOREVER_ABS;
1476 for (struct Record *rec = req->rec_head; NULL != rec; rec = rec->next)
1466 { 1477 {
1467 unsigned int pos = 0; 1478 struct GNUNET_TIME_Absolute at;
1468 1479
1469 cached++; 1480 at.abs_value_us = rec->grd.expiration_time;
1470 req->expires = GNUNET_TIME_UNIT_FOREVER_ABS; 1481 req->expires = GNUNET_TIME_absolute_min (req->expires, at);
1471 for (struct Record *rec = req->rec_head; NULL != rec; rec = rec->next) 1482 pos++;
1472 {
1473 struct GNUNET_TIME_Absolute at;
1474
1475 at.abs_value_us = rec->grd.expiration_time;
1476 req->expires = GNUNET_TIME_absolute_min(req->expires, at);
1477 pos++;
1478 }
1479 if (0 == pos)
1480 req->expires = GNUNET_TIME_UNIT_ZERO_ABS;
1481 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1482 "Hot-start with %u existing records for `%s'\n",
1483 pos,
1484 req->hostname);
1485 } 1483 }
1486 free_records(req); 1484 if (0 == pos)
1485 req->expires = GNUNET_TIME_UNIT_ZERO_ABS;
1486 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1487 "Hot-start with %u existing records for `%s'\n",
1488 pos,
1489 req->hostname);
1490 }
1491 free_records (req);
1487 1492
1488 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1493 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1489 "Adding `%s' to worklist to start at %s\n", 1494 "Adding `%s' to worklist to start at %s\n",
1490 req->hostname, 1495 req->hostname,
1491 GNUNET_STRINGS_absolute_time_to_string(req->expires)); 1496 GNUNET_STRINGS_absolute_time_to_string (req->expires));
1492 insert_sorted(req); 1497 insert_sorted (req);
1493} 1498}
1494 1499
1495 1500
@@ -1499,7 +1504,7 @@ ns_lookup_result_cb(void *cls,
1499 * @param hostname name to resolve 1504 * @param hostname name to resolve
1500 */ 1505 */
1501static void 1506static void
1502queue(const char *hostname) 1507queue (const char *hostname)
1503{ 1508{
1504 struct Request *req; 1509 struct Request *req;
1505 const char *dot; 1510 const char *dot;
@@ -1507,55 +1512,55 @@ queue(const char *hostname)
1507 size_t hlen; 1512 size_t hlen;
1508 struct GNUNET_HashCode hc; 1513 struct GNUNET_HashCode hc;
1509 1514
1510 if (GNUNET_OK != GNUNET_DNSPARSER_check_name(hostname)) 1515 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (hostname))
1511 { 1516 {
1512 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1517 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1513 "Refusing invalid hostname `%s'\n", 1518 "Refusing invalid hostname `%s'\n",
1514 hostname); 1519 hostname);
1515 rejects++; 1520 rejects++;
1516 return; 1521 return;
1517 } 1522 }
1518 dot = strchr(hostname, (unsigned char)'.'); 1523 dot = strchr (hostname, (unsigned char) '.');
1519 if (NULL == dot) 1524 if (NULL == dot)
1520 { 1525 {
1521 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1526 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1522 "Refusing invalid hostname `%s' (lacks '.')\n", 1527 "Refusing invalid hostname `%s' (lacks '.')\n",
1523 hostname); 1528 hostname);
1524 rejects++; 1529 rejects++;
1525 return; 1530 return;
1526 } 1531 }
1527 for (zone = zone_head; NULL != zone; zone = zone->next) 1532 for (zone = zone_head; NULL != zone; zone = zone->next)
1528 if (0 == strcmp(zone->domain, dot + 1)) 1533 if (0 == strcmp (zone->domain, dot + 1))
1529 break; 1534 break;
1530 if (NULL == zone) 1535 if (NULL == zone)
1531 { 1536 {
1532 rejects++; 1537 rejects++;
1533 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, 1538 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1534 "Domain name `%s' not in ego list!\n", 1539 "Domain name `%s' not in ego list!\n",
1535 dot + 1); 1540 dot + 1);
1536 return; 1541 return;
1537 } 1542 }
1538 1543
1539 hlen = strlen(hostname) + 1; 1544 hlen = strlen (hostname) + 1;
1540 req = GNUNET_malloc(sizeof(struct Request) + hlen); 1545 req = GNUNET_malloc (sizeof(struct Request) + hlen);
1541 req->zone = zone; 1546 req->zone = zone;
1542 req->hostname = (char *)&req[1]; 1547 req->hostname = (char *) &req[1];
1543 GNUNET_memcpy(req->hostname, hostname, hlen); 1548 GNUNET_memcpy (req->hostname, hostname, hlen);
1544 req->id = (uint16_t)GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, 1549 req->id = (uint16_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
1545 UINT16_MAX); 1550 UINT16_MAX);
1546 GNUNET_CRYPTO_hash(req->hostname, hlen, &hc); 1551 GNUNET_CRYPTO_hash (req->hostname, hlen, &hc);
1547 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( 1552 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (
1548 ns_pending, 1553 ns_pending,
1549 &hc, 1554 &hc,
1550 req, 1555 req,
1551 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 1556 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1552 { 1557 {
1553 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1558 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1554 "Duplicate hostname `%s' ignored\n", 1559 "Duplicate hostname `%s' ignored\n",
1555 hostname); 1560 hostname);
1556 GNUNET_free(req); 1561 GNUNET_free (req);
1557 return; 1562 return;
1558 } 1563 }
1559} 1564}
1560 1565
1561 1566
@@ -1571,13 +1576,13 @@ queue(const char *hostname)
1571 * @return #GNUNET_OK (continue to iterate) 1576 * @return #GNUNET_OK (continue to iterate)
1572 */ 1577 */
1573static int 1578static int
1574move_to_queue(void *cls, const struct GNUNET_HashCode *key, void *value) 1579move_to_queue (void *cls, const struct GNUNET_HashCode *key, void *value)
1575{ 1580{
1576 struct Request *req = value; 1581 struct Request *req = value;
1577 1582
1578 (void)cls; 1583 (void) cls;
1579 (void)key; 1584 (void) key;
1580 insert_sorted(req); 1585 insert_sorted (req);
1581 return GNUNET_OK; 1586 return GNUNET_OK;
1582} 1587}
1583 1588
@@ -1589,65 +1594,65 @@ move_to_queue(void *cls, const struct GNUNET_HashCode *key, void *value)
1589 * @param cls NULL 1594 * @param cls NULL
1590 */ 1595 */
1591static void 1596static void
1592iterate_zones(void *cls) 1597iterate_zones (void *cls)
1593{ 1598{
1594 static struct Zone *last; 1599 static struct Zone *last;
1595 1600
1596 (void)cls; 1601 (void) cls;
1597 if (NULL != zone_it) 1602 if (NULL != zone_it)
1598 { 1603 {
1599 zone_it = NULL; 1604 zone_it = NULL;
1600 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1601 "Finished iteration over zone `%s'!\n", 1606 "Finished iteration over zone `%s'!\n",
1602 last->domain); 1607 last->domain);
1603 /* subtract left-overs from previous iteration */ 1608 /* subtract left-overs from previous iteration */
1604 GNUNET_STATISTICS_update(stats, 1609 GNUNET_STATISTICS_update (stats,
1605 "# NAMESTORE records requested from cache", 1610 "# NAMESTORE records requested from cache",
1606 (long long)(-ns_iterator_trigger_next), 1611 (long long) (-ns_iterator_trigger_next),
1607 GNUNET_NO); 1612 GNUNET_NO);
1608 ns_iterator_trigger_next = 0; 1613 ns_iterator_trigger_next = 0;
1609 } 1614 }
1610 GNUNET_assert(NULL != zone_tail); 1615 GNUNET_assert (NULL != zone_tail);
1611 if (zone_tail == last) 1616 if (zone_tail == last)
1612 { 1617 {
1613 /* Done iterating over relevant zones in NAMESTORE, move 1618 /* Done iterating over relevant zones in NAMESTORE, move
1614 rest of hash map to work queue as well. */ 1619 rest of hash map to work queue as well. */
1615 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1620 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1616 "Finished all NAMESTORE iterations!\n"); 1621 "Finished all NAMESTORE iterations!\n");
1617 GNUNET_STATISTICS_set(stats, 1622 GNUNET_STATISTICS_set (stats,
1618 "# Domain names without cached reply", 1623 "# Domain names without cached reply",
1619 GNUNET_CONTAINER_multihashmap_size(ns_pending), 1624 GNUNET_CONTAINER_multihashmap_size (ns_pending),
1620 GNUNET_NO); 1625 GNUNET_NO);
1621 GNUNET_CONTAINER_multihashmap_iterate(ns_pending, &move_to_queue, NULL); 1626 GNUNET_CONTAINER_multihashmap_iterate (ns_pending, &move_to_queue, NULL);
1622 GNUNET_CONTAINER_multihashmap_destroy(ns_pending); 1627 GNUNET_CONTAINER_multihashmap_destroy (ns_pending);
1623 ns_pending = NULL; 1628 ns_pending = NULL;
1624 start_time_reg_proc = GNUNET_TIME_absolute_get(); 1629 start_time_reg_proc = GNUNET_TIME_absolute_get ();
1625 total_reg_proc_dns = 0; 1630 total_reg_proc_dns = 0;
1626 total_reg_proc_dns_ns = 0; 1631 total_reg_proc_dns_ns = 0;
1627 return; 1632 return;
1628 } 1633 }
1629 if (NULL == last) 1634 if (NULL == last)
1630 last = zone_head; 1635 last = zone_head;
1631 else 1636 else
1632 last = last->next; 1637 last = last->next;
1633 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1634 "Starting iteration over zone `%s'!\n", 1639 "Starting iteration over zone `%s'!\n",
1635 last->domain); 1640 last->domain);
1636 /* subtract left-overs from previous iteration */ 1641 /* subtract left-overs from previous iteration */
1637 GNUNET_STATISTICS_update(stats, 1642 GNUNET_STATISTICS_update (stats,
1638 "# NAMESTORE records requested from cache", 1643 "# NAMESTORE records requested from cache",
1639 1, 1644 1,
1640 GNUNET_NO); 1645 GNUNET_NO);
1641 ns_iterator_trigger_next = 1; 1646 ns_iterator_trigger_next = 1;
1642 GNUNET_STATISTICS_update(stats, "# zones iterated", 1, GNUNET_NO); 1647 GNUNET_STATISTICS_update (stats, "# zones iterated", 1, GNUNET_NO);
1643 zone_it = GNUNET_NAMESTORE_zone_iteration_start(ns, 1648 zone_it = GNUNET_NAMESTORE_zone_iteration_start (ns,
1644 &last->key, 1649 &last->key,
1645 &ns_lookup_error_cb, 1650 &ns_lookup_error_cb,
1646 NULL, 1651 NULL,
1647 &ns_lookup_result_cb, 1652 &ns_lookup_result_cb,
1648 last, 1653 last,
1649 &iterate_zones, 1654 &iterate_zones,
1650 NULL); 1655 NULL);
1651} 1656}
1652 1657
1653 1658
@@ -1657,44 +1662,44 @@ iterate_zones(void *cls)
1657 * @param cls NULL 1662 * @param cls NULL
1658 */ 1663 */
1659static void 1664static void
1660process_stdin(void *cls) 1665process_stdin (void *cls)
1661{ 1666{
1662 static struct GNUNET_TIME_Absolute last; 1667 static struct GNUNET_TIME_Absolute last;
1663 static uint64_t idot; 1668 static uint64_t idot;
1664 char hn[256]; 1669 char hn[256];
1665 1670
1666 (void)cls; 1671 (void) cls;
1667 t = NULL; 1672 t = NULL;
1668 if (NULL != id) 1673 if (NULL != id)
1674 {
1675 GNUNET_IDENTITY_disconnect (id);
1676 id = NULL;
1677 }
1678 while (NULL != fgets (hn, sizeof(hn), stdin))
1679 {
1680 if (strlen (hn) > 0)
1681 hn[strlen (hn) - 1] = '\0'; /* eat newline */
1682 if (0 == idot)
1683 last = GNUNET_TIME_absolute_get ();
1684 idot++;
1685 if (0 == idot % 100000)
1669 { 1686 {
1670 GNUNET_IDENTITY_disconnect(id); 1687 struct GNUNET_TIME_Relative delta;
1671 id = NULL; 1688
1672 } 1689 delta = GNUNET_TIME_absolute_get_duration (last);
1673 while (NULL != fgets(hn, sizeof(hn), stdin)) 1690 last = GNUNET_TIME_absolute_get ();
1674 { 1691 fprintf (stderr,
1675 if (strlen(hn) > 0) 1692 "Read 100000 domain names in %s\n",
1676 hn[strlen(hn) - 1] = '\0'; /* eat newline */ 1693 GNUNET_STRINGS_relative_time_to_string (delta, GNUNET_YES));
1677 if (0 == idot) 1694 GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1678 last = GNUNET_TIME_absolute_get();
1679 idot++;
1680 if (0 == idot % 100000)
1681 {
1682 struct GNUNET_TIME_Relative delta;
1683
1684 delta = GNUNET_TIME_absolute_get_duration(last);
1685 last = GNUNET_TIME_absolute_get();
1686 fprintf(stderr,
1687 "Read 100000 domain names in %s\n",
1688 GNUNET_STRINGS_relative_time_to_string(delta, GNUNET_YES));
1689 GNUNET_STATISTICS_set(stats, "# domain names provided", idot, GNUNET_NO);
1690 }
1691 queue(hn);
1692 } 1695 }
1693 fprintf(stderr, 1696 queue (hn);
1694 "Done reading %llu domain names\n", 1697 }
1695 (unsigned long long)idot); 1698 fprintf (stderr,
1696 GNUNET_STATISTICS_set(stats, "# domain names provided", idot, GNUNET_NO); 1699 "Done reading %llu domain names\n",
1697 iterate_zones(NULL); 1700 (unsigned long long) idot);
1701 GNUNET_STATISTICS_set (stats, "# domain names provided", idot, GNUNET_NO);
1702 iterate_zones (NULL);
1698} 1703}
1699 1704
1700 1705
@@ -1733,36 +1738,36 @@ process_stdin(void *cls)
1733 * must thus no longer be used 1738 * must thus no longer be used
1734 */ 1739 */
1735static void 1740static void
1736identity_cb(void *cls, 1741identity_cb (void *cls,
1737 struct GNUNET_IDENTITY_Ego *ego, 1742 struct GNUNET_IDENTITY_Ego *ego,
1738 void **ctx, 1743 void **ctx,
1739 const char *name) 1744 const char *name)
1740{ 1745{
1741 (void)cls; 1746 (void) cls;
1742 (void)ctx; 1747 (void) ctx;
1743 1748
1744 if (NULL == ego) 1749 if (NULL == ego)
1750 {
1751 /* end of iteration */
1752 if (NULL == zone_head)
1745 { 1753 {
1746 /* end of iteration */ 1754 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No zone found\n");
1747 if (NULL == zone_head) 1755 GNUNET_SCHEDULER_shutdown ();
1748 {
1749 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No zone found\n");
1750 GNUNET_SCHEDULER_shutdown();
1751 return;
1752 }
1753 /* zone_head non-null, process hostnames from stdin */
1754 t = GNUNET_SCHEDULER_add_now(&process_stdin, NULL);
1755 return; 1756 return;
1756 } 1757 }
1758 /* zone_head non-null, process hostnames from stdin */
1759 t = GNUNET_SCHEDULER_add_now (&process_stdin, NULL);
1760 return;
1761 }
1757 if (NULL != name) 1762 if (NULL != name)
1758 { 1763 {
1759 struct Zone *zone; 1764 struct Zone *zone;
1760 1765
1761 zone = GNUNET_new(struct Zone); 1766 zone = GNUNET_new (struct Zone);
1762 zone->key = *GNUNET_IDENTITY_ego_get_private_key(ego); 1767 zone->key = *GNUNET_IDENTITY_ego_get_private_key (ego);
1763 zone->domain = GNUNET_strdup(name); 1768 zone->domain = GNUNET_strdup (name);
1764 GNUNET_CONTAINER_DLL_insert(zone_head, zone_tail, zone); 1769 GNUNET_CONTAINER_DLL_insert (zone_head, zone_tail, zone);
1765 } 1770 }
1766} 1771}
1767 1772
1768 1773
@@ -1776,52 +1781,52 @@ identity_cb(void *cls,
1776 * @param cfg configuration 1781 * @param cfg configuration
1777 */ 1782 */
1778static void 1783static void
1779run(void *cls, 1784run (void *cls,
1780 char *const *args, 1785 char *const *args,
1781 const char *cfgfile, 1786 const char *cfgfile,
1782 const struct GNUNET_CONFIGURATION_Handle *cfg) 1787 const struct GNUNET_CONFIGURATION_Handle *cfg)
1783{ 1788{
1784 (void)cls; 1789 (void) cls;
1785 (void)args; 1790 (void) args;
1786 (void)cfgfile; 1791 (void) cfgfile;
1787 stats = GNUNET_STATISTICS_create("zoneimport", cfg); 1792 stats = GNUNET_STATISTICS_create ("zoneimport", cfg);
1788 req_heap = GNUNET_CONTAINER_heap_create(GNUNET_CONTAINER_HEAP_ORDER_MIN); 1793 req_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
1789 ns_pending = GNUNET_CONTAINER_multihashmap_create(map_size, GNUNET_NO); 1794 ns_pending = GNUNET_CONTAINER_multihashmap_create (map_size, GNUNET_NO);
1790 if (NULL == ns_pending) 1795 if (NULL == ns_pending)
1791 { 1796 {
1792 fprintf(stderr, "Failed to allocate memory for main hash map\n"); 1797 fprintf (stderr, "Failed to allocate memory for main hash map\n");
1793 return; 1798 return;
1794 } 1799 }
1795 ctx = GNUNET_DNSSTUB_start(256); 1800 ctx = GNUNET_DNSSTUB_start (256);
1796 if (NULL == ctx) 1801 if (NULL == ctx)
1797 { 1802 {
1798 fprintf(stderr, "Failed to initialize GNUnet DNS STUB\n"); 1803 fprintf (stderr, "Failed to initialize GNUnet DNS STUB\n");
1799 return; 1804 return;
1800 } 1805 }
1801 if (NULL == args[0]) 1806 if (NULL == args[0])
1802 { 1807 {
1803 fprintf(stderr, 1808 fprintf (stderr,
1804 "You must provide a list of DNS resolvers on the command line\n"); 1809 "You must provide a list of DNS resolvers on the command line\n");
1805 return; 1810 return;
1806 } 1811 }
1807 for (unsigned int i = 0; NULL != args[i]; i++) 1812 for (unsigned int i = 0; NULL != args[i]; i++)
1813 {
1814 if (GNUNET_OK != GNUNET_DNSSTUB_add_dns_ip (ctx, args[i]))
1808 { 1815 {
1809 if (GNUNET_OK != GNUNET_DNSSTUB_add_dns_ip(ctx, args[i])) 1816 fprintf (stderr, "Failed to use `%s' for DNS resolver\n", args[i]);
1810 { 1817 return;
1811 fprintf(stderr, "Failed to use `%s' for DNS resolver\n", args[i]);
1812 return;
1813 }
1814 } 1818 }
1819 }
1815 1820
1816 1821
1817 GNUNET_SCHEDULER_add_shutdown(&do_shutdown, NULL); 1822 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1818 ns = GNUNET_NAMESTORE_connect(cfg); 1823 ns = GNUNET_NAMESTORE_connect (cfg);
1819 if (NULL == ns) 1824 if (NULL == ns)
1820 { 1825 {
1821 GNUNET_SCHEDULER_shutdown(); 1826 GNUNET_SCHEDULER_shutdown ();
1822 return; 1827 return;
1823 } 1828 }
1824 id = GNUNET_IDENTITY_connect(cfg, &identity_cb, NULL); 1829 id = GNUNET_IDENTITY_connect (cfg, &identity_cb, NULL);
1825} 1830}
1826 1831
1827 1832
@@ -1833,46 +1838,46 @@ run(void *cls,
1833 * @return 0 on success 1838 * @return 0 on success
1834 */ 1839 */
1835int 1840int
1836main(int argc, char *const *argv) 1841main (int argc, char *const *argv)
1837{ 1842{
1838 struct GNUNET_GETOPT_CommandLineOption options[] = 1843 struct GNUNET_GETOPT_CommandLineOption options[] =
1839 { GNUNET_GETOPT_option_uint('s', 1844 { GNUNET_GETOPT_option_uint ('s',
1840 "size", 1845 "size",
1841 "MAPSIZE", 1846 "MAPSIZE",
1842 gettext_noop( 1847 gettext_noop (
1843 "size to use for the main hash map"), 1848 "size to use for the main hash map"),
1844 &map_size), 1849 &map_size),
1845 GNUNET_GETOPT_option_relative_time( 1850 GNUNET_GETOPT_option_relative_time (
1846 'm', 1851 'm',
1847 "minimum-expiration", 1852 "minimum-expiration",
1848 "RELATIVETIME", 1853 "RELATIVETIME",
1849 gettext_noop("minimum expiration time we assume for imported records"), 1854 gettext_noop ("minimum expiration time we assume for imported records"),
1850 &minimum_expiration_time), 1855 &minimum_expiration_time),
1851 GNUNET_GETOPT_OPTION_END }; 1856 GNUNET_GETOPT_OPTION_END };
1852 int ret; 1857 int ret;
1853 1858
1854 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args(argc, argv, &argc, &argv)) 1859 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1855 return 2; 1860 return 2;
1856 if (GNUNET_OK != (ret = GNUNET_PROGRAM_run(argc, 1861 if (GNUNET_OK != (ret = GNUNET_PROGRAM_run (argc,
1857 argv, 1862 argv,
1858 "gnunet-zoneimport", 1863 "gnunet-zoneimport",
1859 "import DNS zone into namestore", 1864 "import DNS zone into namestore",
1860 options, 1865 options,
1861 &run, 1866 &run,
1862 NULL))) 1867 NULL)))
1863 return ret; 1868 return ret;
1864 GNUNET_free((void *)argv); 1869 GNUNET_free ((void *) argv);
1865 fprintf(stderr, 1870 fprintf (stderr,
1866 "Rejected %u names, had %u cached, did %u lookups, stored %u record sets\n" 1871 "Rejected %u names, had %u cached, did %u lookups, stored %u record sets\n"
1867 "Found %u records, %u lookups failed, %u/%u pending on shutdown\n", 1872 "Found %u records, %u lookups failed, %u/%u pending on shutdown\n",
1868 rejects, 1873 rejects,
1869 cached, 1874 cached,
1870 lookups, 1875 lookups,
1871 record_sets, 1876 record_sets,
1872 records, 1877 records,
1873 failures, 1878 failures,
1874 pending, 1879 pending,
1875 pending_rs); 1880 pending_rs);
1876 return 0; 1881 return 0;
1877} 1882}
1878 1883