diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-09-25 18:14:37 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-09-25 18:14:37 +0000 |
commit | 023ce784e21caa4590ac1f5ea28234b2ba353413 (patch) | |
tree | cd9daf3985126d48f914426fdfba14d1130735df /src/namestore | |
parent | ee1787f39555c2295fb9629c856f467da82d94a2 (diff) | |
download | gnunet-023ce784e21caa4590ac1f5ea28234b2ba353413.tar.gz gnunet-023ce784e21caa4590ac1f5ea28234b2ba353413.zip |
-use dnsparser and consistently serialize DNS names in DNS binary format
Diffstat (limited to 'src/namestore')
-rw-r--r-- | src/namestore/namestore_api_common.c | 353 |
1 files changed, 243 insertions, 110 deletions
diff --git a/src/namestore/namestore_api_common.c b/src/namestore/namestore_api_common.c index e33508821..42969778f 100644 --- a/src/namestore/namestore_api_common.c +++ b/src/namestore/namestore_api_common.c | |||
@@ -509,18 +509,9 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type, | |||
509 | const void *data, | 509 | const void *data, |
510 | size_t data_size) | 510 | size_t data_size) |
511 | { | 511 | { |
512 | const struct GNUNET_TUN_DnsSoaRecord *soa; | ||
513 | const struct GNUNET_TUN_GnsVpnRecord *vpn; | ||
514 | const struct GNUNET_TUN_DnsSrvRecord *srv; | ||
515 | const struct GNUNET_TUN_DnsTlsaRecord *tlsa; | ||
516 | struct GNUNET_CRYPTO_HashAsciiEncoded s_peer; | 512 | struct GNUNET_CRYPTO_HashAsciiEncoded s_peer; |
517 | const char *cdata; | 513 | const char *cdata; |
518 | char* vpn_str; | ||
519 | char* srv_str; | ||
520 | char* tlsa_str; | ||
521 | char* result; | 514 | char* result; |
522 | const char* soa_rname; | ||
523 | const char* soa_mname; | ||
524 | char tmp[INET6_ADDRSTRLEN]; | 515 | char tmp[INET6_ADDRSTRLEN]; |
525 | 516 | ||
526 | switch (type) | 517 | switch (type) |
@@ -534,32 +525,83 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type, | |||
534 | return NULL; | 525 | return NULL; |
535 | return GNUNET_strdup (tmp); | 526 | return GNUNET_strdup (tmp); |
536 | case GNUNET_DNSPARSER_TYPE_NS: | 527 | case GNUNET_DNSPARSER_TYPE_NS: |
537 | return GNUNET_strndup (data, data_size); | 528 | { |
529 | char *ns; | ||
530 | size_t off; | ||
531 | |||
532 | off = 0; | ||
533 | ns = GNUNET_DNSPARSER_parse_name (data, | ||
534 | data_size, | ||
535 | &off); | ||
536 | if ( (NULL == ns) || | ||
537 | (off != data_size) ) | ||
538 | { | ||
539 | GNUNET_break_op (0); | ||
540 | return NULL; | ||
541 | } | ||
542 | return ns; | ||
543 | } | ||
538 | case GNUNET_DNSPARSER_TYPE_CNAME: | 544 | case GNUNET_DNSPARSER_TYPE_CNAME: |
539 | return GNUNET_strndup (data, data_size); | 545 | { |
546 | char *cname; | ||
547 | size_t off; | ||
548 | |||
549 | off = 0; | ||
550 | cname = GNUNET_DNSPARSER_parse_name (data, | ||
551 | data_size, | ||
552 | &off); | ||
553 | if ( (NULL == cname) || | ||
554 | (off != data_size) ) | ||
555 | { | ||
556 | GNUNET_break_op (0); | ||
557 | return NULL; | ||
558 | } | ||
559 | return cname; | ||
560 | } | ||
540 | case GNUNET_DNSPARSER_TYPE_SOA: | 561 | case GNUNET_DNSPARSER_TYPE_SOA: |
541 | if (data_size <= sizeof (struct GNUNET_TUN_DnsSoaRecord)) | 562 | { |
542 | return NULL; | 563 | struct GNUNET_DNSPARSER_SoaRecord *soa; |
543 | soa = data; | 564 | size_t off; |
544 | soa_rname = (const char*) &soa[1]; | 565 | |
545 | soa_mname = memchr (soa_rname, 0, data_size - sizeof (struct GNUNET_TUN_DnsSoaRecord) - 1); | 566 | off = 0; |
546 | if (NULL == soa_mname) | 567 | soa = GNUNET_DNSPARSER_parse_soa (data, |
547 | return NULL; | 568 | data_size, |
548 | soa_mname++; | 569 | &off); |
549 | if (NULL == memchr (soa_mname, 0, | 570 | if ( (NULL == soa) || |
550 | data_size - (sizeof (struct GNUNET_TUN_DnsSoaRecord) + strlen (soa_rname) + 1))) | 571 | (off != data_size) ) |
551 | return NULL; | 572 | { |
552 | GNUNET_asprintf (&result, | 573 | GNUNET_break_op (0); |
553 | "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", | 574 | return NULL; |
554 | soa_rname, soa_mname, | 575 | } |
555 | ntohl (soa->serial), | 576 | GNUNET_asprintf (&result, |
556 | ntohl (soa->refresh), | 577 | "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", |
557 | ntohl (soa->retry), | 578 | soa->rname, |
558 | ntohl (soa->expire), | 579 | soa->mname, |
559 | ntohl (soa->minimum)); | 580 | soa->serial, |
560 | return result; | 581 | soa->refresh, |
582 | soa->retry, | ||
583 | soa->expire, | ||
584 | soa->minimum_ttl); | ||
585 | GNUNET_DNSPARSER_free_soa (soa); | ||
586 | return result; | ||
587 | } | ||
561 | case GNUNET_DNSPARSER_TYPE_PTR: | 588 | case GNUNET_DNSPARSER_TYPE_PTR: |
562 | return GNUNET_strndup (data, data_size); | 589 | { |
590 | char *ptr; | ||
591 | size_t off; | ||
592 | |||
593 | off = 0; | ||
594 | ptr = GNUNET_DNSPARSER_parse_name (data, | ||
595 | data_size, | ||
596 | &off); | ||
597 | if ( (NULL == ptr) || | ||
598 | (off != data_size) ) | ||
599 | { | ||
600 | GNUNET_break_op (0); | ||
601 | return NULL; | ||
602 | } | ||
603 | return ptr; | ||
604 | } | ||
563 | case GNUNET_DNSPARSER_TYPE_MX: | 605 | case GNUNET_DNSPARSER_TYPE_MX: |
564 | { | 606 | { |
565 | struct GNUNET_DNSPARSER_MxRecord *mx; | 607 | struct GNUNET_DNSPARSER_MxRecord *mx; |
@@ -599,56 +641,75 @@ GNUNET_NAMESTORE_value_to_string (uint32_t type, | |||
599 | case GNUNET_NAMESTORE_TYPE_LEHO: | 641 | case GNUNET_NAMESTORE_TYPE_LEHO: |
600 | return GNUNET_strndup (data, data_size); | 642 | return GNUNET_strndup (data, data_size); |
601 | case GNUNET_NAMESTORE_TYPE_VPN: | 643 | case GNUNET_NAMESTORE_TYPE_VPN: |
602 | cdata = data; | ||
603 | if ( (data_size <= sizeof (struct GNUNET_TUN_GnsVpnRecord)) || | ||
604 | ('\0' != cdata[data_size - 1]) ) | ||
605 | return NULL; /* malformed */ | ||
606 | vpn = data; | ||
607 | GNUNET_CRYPTO_hash_to_enc (&vpn->peer.hashPubKey, &s_peer); | ||
608 | if (0 == GNUNET_asprintf (&vpn_str, "%u %s %s", | ||
609 | (unsigned int) ntohs (vpn->proto), | ||
610 | (const char*) &s_peer, | ||
611 | (const char*) &vpn[1])) | ||
612 | { | 644 | { |
613 | GNUNET_free (vpn_str); | 645 | const struct GNUNET_TUN_GnsVpnRecord *vpn; |
614 | return NULL; | 646 | char* vpn_str; |
647 | |||
648 | cdata = data; | ||
649 | if ( (data_size <= sizeof (struct GNUNET_TUN_GnsVpnRecord)) || | ||
650 | ('\0' != cdata[data_size - 1]) ) | ||
651 | return NULL; /* malformed */ | ||
652 | vpn = data; | ||
653 | GNUNET_CRYPTO_hash_to_enc (&vpn->peer.hashPubKey, &s_peer); | ||
654 | if (0 == GNUNET_asprintf (&vpn_str, "%u %s %s", | ||
655 | (unsigned int) ntohs (vpn->proto), | ||
656 | (const char*) &s_peer, | ||
657 | (const char*) &vpn[1])) | ||
658 | { | ||
659 | GNUNET_free (vpn_str); | ||
660 | return NULL; | ||
661 | } | ||
662 | return vpn_str; | ||
615 | } | 663 | } |
616 | return vpn_str; | ||
617 | case GNUNET_DNSPARSER_TYPE_SRV: | 664 | case GNUNET_DNSPARSER_TYPE_SRV: |
618 | cdata = data; | ||
619 | if ( (data_size <= sizeof (struct GNUNET_TUN_DnsSrvRecord)) || | ||
620 | ('\0' != cdata[data_size - 1]) ) | ||
621 | return NULL; /* malformed */ | ||
622 | srv = data; | ||
623 | |||
624 | if (0 == GNUNET_asprintf (&srv_str, | ||
625 | "%d %d %d %s", | ||
626 | ntohs (srv->prio), | ||
627 | ntohs (srv->weight), | ||
628 | ntohs (srv->port), | ||
629 | (const char *)&srv[1])) | ||
630 | { | 665 | { |
631 | GNUNET_free (srv_str); | 666 | struct GNUNET_DNSPARSER_SrvRecord *srv; |
632 | return NULL; | 667 | size_t off; |
668 | |||
669 | off = 0; | ||
670 | srv = GNUNET_DNSPARSER_parse_srv ("+", /* FIXME: is this OK? */ | ||
671 | data, | ||
672 | data_size, | ||
673 | &off); | ||
674 | if ( (NULL == srv) || | ||
675 | (off != data_size) ) | ||
676 | { | ||
677 | GNUNET_break_op (0); | ||
678 | return NULL; | ||
679 | } | ||
680 | GNUNET_asprintf (&result, | ||
681 | "%d %d %d _%s._%s.%s", | ||
682 | srv->priority, | ||
683 | srv->weight, | ||
684 | srv->port, | ||
685 | srv->service, | ||
686 | srv->proto, | ||
687 | srv->domain_name); | ||
688 | GNUNET_DNSPARSER_free_srv (srv); | ||
689 | return result; | ||
633 | } | 690 | } |
634 | return srv_str; | ||
635 | case GNUNET_DNSPARSER_TYPE_TLSA: | 691 | case GNUNET_DNSPARSER_TYPE_TLSA: |
636 | cdata = data; | ||
637 | if ( (data_size <= sizeof (struct GNUNET_TUN_DnsTlsaRecord)) || | ||
638 | ('\0' != cdata[data_size - 1]) ) | ||
639 | return NULL; /* malformed */ | ||
640 | tlsa = data; | ||
641 | if (0 == GNUNET_asprintf (&tlsa_str, | ||
642 | "%c %c %c %s", | ||
643 | tlsa->usage, | ||
644 | tlsa->selector, | ||
645 | tlsa->matching_type, | ||
646 | (const char *) &tlsa[1])) | ||
647 | { | 692 | { |
648 | GNUNET_free (tlsa_str); | 693 | const struct GNUNET_TUN_DnsTlsaRecord *tlsa; |
649 | return NULL; | 694 | char* tlsa_str; |
695 | |||
696 | cdata = data; | ||
697 | if ( (data_size <= sizeof (struct GNUNET_TUN_DnsTlsaRecord)) || | ||
698 | ('\0' != cdata[data_size - 1]) ) | ||
699 | return NULL; /* malformed */ | ||
700 | tlsa = data; | ||
701 | if (0 == GNUNET_asprintf (&tlsa_str, | ||
702 | "%c %c %c %s", | ||
703 | tlsa->usage, | ||
704 | tlsa->selector, | ||
705 | tlsa->matching_type, | ||
706 | (const char *) &tlsa[1])) | ||
707 | { | ||
708 | GNUNET_free (tlsa_str); | ||
709 | return NULL; | ||
710 | } | ||
711 | return tlsa_str; | ||
650 | } | 712 | } |
651 | return tlsa_str; | ||
652 | default: | 713 | default: |
653 | GNUNET_break (0); | 714 | GNUNET_break (0); |
654 | } | 715 | } |
@@ -676,18 +737,10 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type, | |||
676 | struct in_addr value_a; | 737 | struct in_addr value_a; |
677 | struct in6_addr value_aaaa; | 738 | struct in6_addr value_aaaa; |
678 | struct GNUNET_CRYPTO_EccPublicSignKey pkey; | 739 | struct GNUNET_CRYPTO_EccPublicSignKey pkey; |
679 | struct GNUNET_TUN_DnsSoaRecord *soa; | ||
680 | struct GNUNET_TUN_GnsVpnRecord *vpn; | 740 | struct GNUNET_TUN_GnsVpnRecord *vpn; |
681 | struct GNUNET_TUN_DnsTlsaRecord *tlsa; | 741 | struct GNUNET_TUN_DnsTlsaRecord *tlsa; |
682 | char soa_rname[253 + 1]; | ||
683 | char soa_mname[253 + 1]; | ||
684 | char s_peer[103 + 1]; | 742 | char s_peer[103 + 1]; |
685 | char s_serv[253 + 1]; | 743 | char s_serv[253 + 1]; |
686 | unsigned int soa_serial; | ||
687 | unsigned int soa_refresh; | ||
688 | unsigned int soa_retry; | ||
689 | unsigned int soa_expire; | ||
690 | unsigned int soa_min; | ||
691 | unsigned int proto; | 744 | unsigned int proto; |
692 | 745 | ||
693 | if (NULL == s) | 746 | if (NULL == s) |
@@ -712,39 +765,119 @@ GNUNET_NAMESTORE_string_to_value (uint32_t type, | |||
712 | *data_size = sizeof (value_a); | 765 | *data_size = sizeof (value_a); |
713 | return GNUNET_OK; | 766 | return GNUNET_OK; |
714 | case GNUNET_DNSPARSER_TYPE_NS: | 767 | case GNUNET_DNSPARSER_TYPE_NS: |
715 | *data = GNUNET_strdup (s); | 768 | { |
716 | *data_size = strlen (s) + 1; | 769 | char nsbuf[256]; |
717 | return GNUNET_OK; | 770 | size_t off; |
771 | |||
772 | off = 0; | ||
773 | if (GNUNET_OK != | ||
774 | GNUNET_DNSPARSER_builder_add_name (nsbuf, | ||
775 | sizeof (nsbuf), | ||
776 | &off, | ||
777 | s)) | ||
778 | { | ||
779 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
780 | _("Failed to serialize NS record with value `%s'\n"), | ||
781 | s); | ||
782 | return GNUNET_SYSERR; | ||
783 | } | ||
784 | *data_size = off; | ||
785 | *data = GNUNET_malloc (off); | ||
786 | memcpy (*data, nsbuf, off); | ||
787 | return GNUNET_OK; | ||
788 | } | ||
718 | case GNUNET_DNSPARSER_TYPE_CNAME: | 789 | case GNUNET_DNSPARSER_TYPE_CNAME: |
719 | *data = GNUNET_strdup (s); | 790 | { |
720 | *data_size = strlen (s) + 1; | 791 | char cnamebuf[256]; |
721 | return GNUNET_OK; | 792 | size_t off; |
793 | |||
794 | off = 0; | ||
795 | if (GNUNET_OK != | ||
796 | GNUNET_DNSPARSER_builder_add_name (cnamebuf, | ||
797 | sizeof (cnamebuf), | ||
798 | &off, | ||
799 | s)) | ||
800 | { | ||
801 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
802 | _("Failed to serialize CNAME record with value `%s'\n"), | ||
803 | s); | ||
804 | return GNUNET_SYSERR; | ||
805 | } | ||
806 | *data_size = off; | ||
807 | *data = GNUNET_malloc (off); | ||
808 | memcpy (*data, cnamebuf, off); | ||
809 | return GNUNET_OK; | ||
810 | } | ||
722 | case GNUNET_DNSPARSER_TYPE_SOA: | 811 | case GNUNET_DNSPARSER_TYPE_SOA: |
723 | if (7 != SSCANF (s, | ||
724 | "rname=%253s mname=%253s %u,%u,%u,%u,%u", | ||
725 | soa_rname, soa_mname, | ||
726 | &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min)) | ||
727 | { | 812 | { |
728 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 813 | struct GNUNET_DNSPARSER_SoaRecord soa; |
729 | _("Unable to parse SOA record `%s'\n"), | 814 | char soabuf[540]; |
730 | s); | 815 | char soa_rname[253 + 1]; |
731 | return GNUNET_SYSERR; | 816 | char soa_mname[253 + 1]; |
817 | unsigned int soa_serial; | ||
818 | unsigned int soa_refresh; | ||
819 | unsigned int soa_retry; | ||
820 | unsigned int soa_expire; | ||
821 | unsigned int soa_min; | ||
822 | size_t off; | ||
823 | |||
824 | if (7 != SSCANF (s, | ||
825 | "rname=%253s mname=%253s %u,%u,%u,%u,%u", | ||
826 | soa_rname, soa_mname, | ||
827 | &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min)) | ||
828 | { | ||
829 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
830 | _("Unable to parse SOA record `%s'\n"), | ||
831 | s); | ||
832 | return GNUNET_SYSERR; | ||
833 | } | ||
834 | soa.mname = soa_mname; | ||
835 | soa.rname = soa_rname; | ||
836 | soa.serial = (uint32_t) soa_serial; | ||
837 | soa.refresh =(uint32_t) soa_refresh; | ||
838 | soa.retry = (uint32_t) soa_retry; | ||
839 | soa.expire = (uint32_t) soa_expire; | ||
840 | soa.minimum_ttl = (uint32_t) soa_min; | ||
841 | off = 0; | ||
842 | if (GNUNET_OK != | ||
843 | GNUNET_DNSPARSER_builder_add_soa (soabuf, | ||
844 | sizeof (soabuf), | ||
845 | &off, | ||
846 | &soa)) | ||
847 | { | ||
848 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
849 | _("Failed to serialize SOA record with mname `%s' and rname `%s'\n"), | ||
850 | soa_mname, | ||
851 | soa_rname); | ||
852 | return GNUNET_SYSERR; | ||
853 | } | ||
854 | *data_size = off; | ||
855 | *data = GNUNET_malloc (off); | ||
856 | memcpy (*data, soabuf, off); | ||
857 | return GNUNET_OK; | ||
732 | } | 858 | } |
733 | *data_size = sizeof (struct GNUNET_TUN_DnsSoaRecord) + strlen(soa_rname) + strlen(soa_mname) + 2; | ||
734 | *data = GNUNET_malloc (*data_size); | ||
735 | soa = (struct GNUNET_TUN_DnsSoaRecord*)*data; | ||
736 | soa->serial = htonl(soa_serial); | ||
737 | soa->refresh = htonl(soa_refresh); | ||
738 | soa->retry = htonl(soa_retry); | ||
739 | soa->expire = htonl(soa_expire); | ||
740 | soa->minimum = htonl(soa_min); | ||
741 | strcpy((char*)&soa[1], soa_rname); | ||
742 | strcpy((char*)&soa[1]+strlen(*data)+1, soa_mname); | ||
743 | return GNUNET_OK; | ||
744 | case GNUNET_DNSPARSER_TYPE_PTR: | 859 | case GNUNET_DNSPARSER_TYPE_PTR: |
745 | *data = GNUNET_strdup (s); | 860 | { |
746 | *data_size = strlen (s); | 861 | char ptrbuf[256]; |
747 | return GNUNET_OK; | 862 | size_t off; |
863 | |||
864 | off = 0; | ||
865 | if (GNUNET_OK != | ||
866 | GNUNET_DNSPARSER_builder_add_name (ptrbuf, | ||
867 | sizeof (ptrbuf), | ||
868 | &off, | ||
869 | s)) | ||
870 | { | ||
871 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
872 | _("Failed to serialize PTR record with value `%s'\n"), | ||
873 | s); | ||
874 | return GNUNET_SYSERR; | ||
875 | } | ||
876 | *data_size = off; | ||
877 | *data = GNUNET_malloc (off); | ||
878 | memcpy (*data, ptrbuf, off); | ||
879 | return GNUNET_OK; | ||
880 | } | ||
748 | case GNUNET_DNSPARSER_TYPE_MX: | 881 | case GNUNET_DNSPARSER_TYPE_MX: |
749 | { | 882 | { |
750 | struct GNUNET_DNSPARSER_MxRecord mx; | 883 | struct GNUNET_DNSPARSER_MxRecord mx; |