aboutsummaryrefslogtreecommitdiff
path: root/src/dns
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-08-24 09:02:49 +0000
committerChristian Grothoff <christian@grothoff.org>2013-08-24 09:02:49 +0000
commit6c77a012bc057de0f0bbcb437463ec86a9ca088d (patch)
treefea13af5ad9bfb4192f4d47db142252b182738a1 /src/dns
parent748a9dd6a96000a30e813d41f1c4cb86ef04089d (diff)
downloadgnunet-6c77a012bc057de0f0bbcb437463ec86a9ca088d.tar.gz
gnunet-6c77a012bc057de0f0bbcb437463ec86a9ca088d.zip
-exposing dnsparser record packing API
Diffstat (limited to 'src/dns')
-rw-r--r--src/dns/dnsparser.c118
1 files changed, 62 insertions, 56 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c
index 2e0415ff9..06438fb74 100644
--- a/src/dns/dnsparser.c
+++ b/src/dns/dnsparser.c
@@ -311,7 +311,7 @@ parse_record (const char *udp_payload,
311 return GNUNET_OK; 311 return GNUNET_OK;
312 case GNUNET_DNSPARSER_TYPE_SOA: 312 case GNUNET_DNSPARSER_TYPE_SOA:
313 old_off = *off; 313 old_off = *off;
314 r->data.soa = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_SoaRecord)); 314 r->data.soa = GNUNET_new (struct GNUNET_DNSPARSER_SoaRecord);
315 r->data.soa->mname = parse_name (udp_payload, 315 r->data.soa->mname = parse_name (udp_payload,
316 udp_payload_length, 316 udp_payload_length,
317 off, 0); 317 off, 0);
@@ -338,7 +338,7 @@ parse_record (const char *udp_payload,
338 return GNUNET_SYSERR; 338 return GNUNET_SYSERR;
339 memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t)); 339 memcpy (&mxpref, &udp_payload[*off], sizeof (uint16_t));
340 (*off) += sizeof (uint16_t); 340 (*off) += sizeof (uint16_t);
341 r->data.mx = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_MxRecord)); 341 r->data.mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord);
342 r->data.mx->preference = ntohs (mxpref); 342 r->data.mx->preference = ntohs (mxpref);
343 r->data.mx->mxhost = parse_name (udp_payload, 343 r->data.mx->mxhost = parse_name (udp_payload,
344 udp_payload_length, 344 udp_payload_length,
@@ -356,7 +356,7 @@ parse_record (const char *udp_payload,
356 return GNUNET_SYSERR; 356 return GNUNET_SYSERR;
357 memcpy (&srv, &udp_payload[*off], sizeof (struct GNUNET_TUN_DnsSrvRecord)); 357 memcpy (&srv, &udp_payload[*off], sizeof (struct GNUNET_TUN_DnsSrvRecord));
358 (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord); 358 (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord);
359 r->data.srv = GNUNET_malloc (sizeof (struct GNUNET_DNSPARSER_SrvRecord)); 359 r->data.srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord);
360 r->data.srv->priority = ntohs (srv.prio); 360 r->data.srv->priority = ntohs (srv.prio);
361 r->data.srv->weight = ntohs (srv.weight); 361 r->data.srv->weight = ntohs (srv.weight);
362 r->data.srv->port = ntohs (srv.port); 362 r->data.srv->port = ntohs (srv.port);
@@ -534,6 +534,11 @@ free_mx (struct GNUNET_DNSPARSER_MxRecord *mx)
534} 534}
535 535
536 536
537/**
538 * Free the given DNS record.
539 *
540 * @param r record to free
541 */
537static void 542static void
538free_record (struct GNUNET_DNSPARSER_Record *r) 543free_record (struct GNUNET_DNSPARSER_Record *r)
539{ 544{
@@ -591,22 +596,23 @@ GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p)
591 596
592 597
593/** 598/**
594 * Add a DNS name to the UDP packet at the given location. 599 * Add a DNS name to the UDP packet at the given location, converting
600 * the name to IDNA notation as necessary.
595 * 601 *
596 * @param dst where to write the name 602 * @param dst where to write the name (UDP packet)
597 * @param dst_len number of bytes in @a dst 603 * @param dst_len number of bytes in @a dst
598 * @param off pointer to offset where to write the name (increment by bytes used) 604 * @param off pointer to offset where to write the name (increment by bytes used)
599 * must not be changed if there is an error 605 * must not be changed if there is an error
600 * @param name name to write 606 * @param name name to write
601 * @return #GNUNET_SYSERR if @a name is invalid 607 * @return #GNUNET_SYSERR if @a name is invalid
602 * #GNUNET_NO if @a name did not fit 608 * #GNUNET_NO if @a name did not fit
603 * #GNUNET_OK if @a name was added to 'dst' 609 * #GNUNET_OK if @a name was added to @a dst
604 */ 610 */
605static int 611int
606add_name (char *dst, 612GNUNET_DNSPARSER_builder_add_name (char *dst,
607 size_t dst_len, 613 size_t dst_len,
608 size_t *off, 614 size_t *off,
609 const char *name) 615 const char *name)
610{ 616{
611 const char *dot; 617 const char *dot;
612 const char *idna_name; 618 const char *idna_name;
@@ -670,24 +676,24 @@ add_name (char *dst,
670 * Add a DNS query to the UDP packet at the given location. 676 * Add a DNS query to the UDP packet at the given location.
671 * 677 *
672 * @param dst where to write the query 678 * @param dst where to write the query
673 * @param dst_len number of bytes in dst 679 * @param dst_len number of bytes in @a dst
674 * @param off pointer to offset where to write the query (increment by bytes used) 680 * @param off pointer to offset where to write the query (increment by bytes used)
675 * must not be changed if there is an error 681 * must not be changed if there is an error
676 * @param query query to write 682 * @param query query to write
677 * @return #GNUNET_SYSERR if 'query' is invalid 683 * @return #GNUNET_SYSERR if @a query is invalid
678 * #GNUNET_NO if 'query' did not fit 684 * #GNUNET_NO if @a query did not fit
679 * #GNUNET_OK if 'query' was added to @a dst 685 * #GNUNET_OK if @a query was added to @a dst
680 */ 686 */
681static int 687int
682add_query (char *dst, 688GNUNET_DNSPARSER_builder_add_query (char *dst,
683 size_t dst_len, 689 size_t dst_len,
684 size_t *off, 690 size_t *off,
685 const struct GNUNET_DNSPARSER_Query *query) 691 const struct GNUNET_DNSPARSER_Query *query)
686{ 692{
687 int ret; 693 int ret;
688 struct GNUNET_TUN_DnsQueryLine ql; 694 struct GNUNET_TUN_DnsQueryLine ql;
689 695
690 ret = add_name (dst, dst_len - sizeof (struct GNUNET_TUN_DnsQueryLine), off, query->name); 696 ret = GNUNET_DNSPARSER_builder_add_name (dst, dst_len - sizeof (struct GNUNET_TUN_DnsQueryLine), off, query->name);
691 if (ret != GNUNET_OK) 697 if (ret != GNUNET_OK)
692 return ret; 698 return ret;
693 ql.type = htons (query->type); 699 ql.type = htons (query->type);
@@ -702,7 +708,7 @@ add_query (char *dst,
702 * Add an MX record to the UDP packet at the given location. 708 * Add an MX record to the UDP packet at the given location.
703 * 709 *
704 * @param dst where to write the mx record 710 * @param dst where to write the mx record
705 * @param dst_len number of bytes in dst 711 * @param dst_len number of bytes in @a dst
706 * @param off pointer to offset where to write the mx information (increment by bytes used); 712 * @param off pointer to offset where to write the mx information (increment by bytes used);
707 * can also change if there was an error 713 * can also change if there was an error
708 * @param mx mx information to write 714 * @param mx mx information to write
@@ -710,11 +716,11 @@ add_query (char *dst,
710 * #GNUNET_NO if @a mx did not fit 716 * #GNUNET_NO if @a mx did not fit
711 * #GNUNET_OK if @a mx was added to @a dst 717 * #GNUNET_OK if @a mx was added to @a dst
712 */ 718 */
713static int 719int
714add_mx (char *dst, 720GNUNET_DNSPARSER_builder_add_mx (char *dst,
715 size_t dst_len, 721 size_t dst_len,
716 size_t *off, 722 size_t *off,
717 const struct GNUNET_DNSPARSER_MxRecord *mx) 723 const struct GNUNET_DNSPARSER_MxRecord *mx)
718{ 724{
719 uint16_t mxpref; 725 uint16_t mxpref;
720 726
@@ -723,7 +729,7 @@ add_mx (char *dst,
723 mxpref = htons (mx->preference); 729 mxpref = htons (mx->preference);
724 memcpy (&dst[*off], &mxpref, sizeof (mxpref)); 730 memcpy (&dst[*off], &mxpref, sizeof (mxpref));
725 (*off) += sizeof (mxpref); 731 (*off) += sizeof (mxpref);
726 return add_name (dst, dst_len, off, mx->mxhost); 732 return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost);
727} 733}
728 734
729 735
@@ -731,28 +737,28 @@ add_mx (char *dst,
731 * Add an SOA record to the UDP packet at the given location. 737 * Add an SOA record to the UDP packet at the given location.
732 * 738 *
733 * @param dst where to write the SOA record 739 * @param dst where to write the SOA record
734 * @param dst_len number of bytes in dst 740 * @param dst_len number of bytes in @a dst
735 * @param off pointer to offset where to write the SOA information (increment by bytes used) 741 * @param off pointer to offset where to write the SOA information (increment by bytes used)
736 * can also change if there was an error 742 * can also change if there was an error
737 * @param soa SOA information to write 743 * @param soa SOA information to write
738 * @return #GNUNET_SYSERR if @a soa is invalid 744 * @return #GNUNET_SYSERR if @a soa is invalid
739 * #GNUNET_NO if @a soa did not fit 745 * #GNUNET_NO if @a soa did not fit
740 * #GNUNET_OK if @a soa was added to 'dst' 746 * #GNUNET_OK if @a soa was added to @a dst
741 */ 747 */
742static int 748int
743add_soa (char *dst, 749GNUNET_DNSPARSER_builder_add_soa (char *dst,
744 size_t dst_len, 750 size_t dst_len,
745 size_t *off, 751 size_t *off,
746 const struct GNUNET_DNSPARSER_SoaRecord *soa) 752 const struct GNUNET_DNSPARSER_SoaRecord *soa)
747{ 753{
748 struct GNUNET_TUN_DnsSoaRecord sd; 754 struct GNUNET_TUN_DnsSoaRecord sd;
749 int ret; 755 int ret;
750 756
751 if ( (GNUNET_OK != (ret = add_name (dst, 757 if ( (GNUNET_OK != (ret = GNUNET_DNSPARSER_builder_add_name (dst,
752 dst_len, 758 dst_len,
753 off, 759 off,
754 soa->mname))) || 760 soa->mname))) ||
755 (GNUNET_OK != (ret = add_name (dst, 761 (GNUNET_OK != (ret = GNUNET_DNSPARSER_builder_add_name (dst,
756 dst_len, 762 dst_len,
757 off, 763 off,
758 soa->rname)) ) ) 764 soa->rname)) ) )
@@ -774,19 +780,19 @@ add_soa (char *dst,
774 * Add an SRV record to the UDP packet at the given location. 780 * Add an SRV record to the UDP packet at the given location.
775 * 781 *
776 * @param dst where to write the SRV record 782 * @param dst where to write the SRV record
777 * @param dst_len number of bytes in dst 783 * @param dst_len number of bytes in @a dst
778 * @param off pointer to offset where to write the SRV information (increment by bytes used) 784 * @param off pointer to offset where to write the SRV information (increment by bytes used)
779 * can also change if there was an error 785 * can also change if there was an error
780 * @param srv SRV information to write 786 * @param srv SRV information to write
781 * @return #GNUNET_SYSERR if @a srv is invalid 787 * @return #GNUNET_SYSERR if @a srv is invalid
782 * #GNUNET_NO if @a srv did not fit 788 * #GNUNET_NO if @a srv did not fit
783 * #GNUNET_OK if @a srv was added to 'dst' 789 * #GNUNET_OK if @a srv was added to @a dst
784 */ 790 */
785static int 791int
786add_srv (char *dst, 792GNUNET_DNSPARSER_builder_add_srv (char *dst,
787 size_t dst_len, 793 size_t dst_len,
788 size_t *off, 794 size_t *off,
789 const struct GNUNET_DNSPARSER_SrvRecord *srv) 795 const struct GNUNET_DNSPARSER_SrvRecord *srv)
790{ 796{
791 struct GNUNET_TUN_DnsSrvRecord sd; 797 struct GNUNET_TUN_DnsSrvRecord sd;
792 int ret; 798 int ret;
@@ -798,7 +804,7 @@ add_srv (char *dst,
798 sd.port = htons (srv->port); 804 sd.port = htons (srv->port);
799 memcpy (&dst[*off], &sd, sizeof (sd)); 805 memcpy (&dst[*off], &sd, sizeof (sd));
800 (*off) += sizeof (sd); 806 (*off) += sizeof (sd);
801 if (GNUNET_OK != (ret = add_name (dst, 807 if (GNUNET_OK != (ret = GNUNET_DNSPARSER_builder_add_name (dst,
802 dst_len, 808 dst_len,
803 off, 809 off,
804 srv->target))) 810 srv->target)))
@@ -811,13 +817,13 @@ add_srv (char *dst,
811 * Add a DNS record to the UDP packet at the given location. 817 * Add a DNS record to the UDP packet at the given location.
812 * 818 *
813 * @param dst where to write the query 819 * @param dst where to write the query
814 * @param dst_len number of bytes in dst 820 * @param dst_len number of bytes in @a dst
815 * @param off pointer to offset where to write the query (increment by bytes used) 821 * @param off pointer to offset where to write the query (increment by bytes used)
816 * must not be changed if there is an error 822 * must not be changed if there is an error
817 * @param record record to write 823 * @param record record to write
818 * @return #GNUNET_SYSERR if 'record' is invalid 824 * @return #GNUNET_SYSERR if @a record is invalid
819 * #GNUNET_NO if 'record' did not fit 825 * #GNUNET_NO if @a record did not fit
820 * #GNUNET_OK if 'record' was added to @a dst 826 * #GNUNET_OK if @a record was added to @a dst
821 */ 827 */
822static int 828static int
823add_record (char *dst, 829add_record (char *dst,
@@ -842,7 +848,7 @@ add_record (char *dst,
842 record->data.srv->service, 848 record->data.srv->service,
843 record->data.srv->proto, 849 record->data.srv->proto,
844 record->data.srv->domain_name); 850 record->data.srv->domain_name);
845 ret = add_name (dst, dst_len - sizeof (struct GNUNET_TUN_DnsRecordLine), off, name); 851 ret = GNUNET_DNSPARSER_builder_add_name (dst, dst_len - sizeof (struct GNUNET_TUN_DnsRecordLine), off, name);
846 if (name != record->name) 852 if (name != record->name)
847 GNUNET_free (name); 853 GNUNET_free (name);
848 if (GNUNET_OK != ret) 854 if (GNUNET_OK != ret)
@@ -853,18 +859,18 @@ add_record (char *dst,
853 switch (record->type) 859 switch (record->type)
854 { 860 {
855 case GNUNET_DNSPARSER_TYPE_MX: 861 case GNUNET_DNSPARSER_TYPE_MX:
856 ret = add_mx (dst, dst_len, &pos, record->data.mx); 862 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx);
857 break; 863 break;
858 case GNUNET_DNSPARSER_TYPE_SOA: 864 case GNUNET_DNSPARSER_TYPE_SOA:
859 ret = add_soa (dst, dst_len, &pos, record->data.soa); 865 ret = GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa);
860 break; 866 break;
861 case GNUNET_DNSPARSER_TYPE_NS: 867 case GNUNET_DNSPARSER_TYPE_NS:
862 case GNUNET_DNSPARSER_TYPE_CNAME: 868 case GNUNET_DNSPARSER_TYPE_CNAME:
863 case GNUNET_DNSPARSER_TYPE_PTR: 869 case GNUNET_DNSPARSER_TYPE_PTR:
864 ret = add_name (dst, dst_len, &pos, record->data.hostname); 870 ret = GNUNET_DNSPARSER_builder_add_name (dst, dst_len, &pos, record->data.hostname);
865 break; 871 break;
866 case GNUNET_DNSPARSER_TYPE_SRV: 872 case GNUNET_DNSPARSER_TYPE_SRV:
867 ret = add_srv (dst, dst_len, &pos, record->data.srv); 873 ret = GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv);
868 break; 874 break;
869 default: 875 default:
870 if (pos + record->data.raw.data_len > dst_len) 876 if (pos + record->data.raw.data_len > dst_len)
@@ -900,7 +906,7 @@ add_record (char *dst,
900 906
901 907
902/** 908/**
903 * Given a DNS packet, generate the corresponding UDP payload. 909 * Given a DNS packet @a p, generate the corresponding UDP payload.
904 * Note that we do not attempt to pack the strings with pointers 910 * Note that we do not attempt to pack the strings with pointers
905 * as this would complicate the code and this is about being 911 * as this would complicate the code and this is about being
906 * simple and secure, not fast, fancy and broken like bind. 912 * simple and secure, not fast, fancy and broken like bind.
@@ -942,7 +948,7 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
942 trc = GNUNET_NO; 948 trc = GNUNET_NO;
943 for (i=0;i<p->num_queries;i++) 949 for (i=0;i<p->num_queries;i++)
944 { 950 {
945 ret = add_query (tmp, sizeof (tmp), &off, &p->queries[i]); 951 ret = GNUNET_DNSPARSER_builder_add_query (tmp, sizeof (tmp), &off, &p->queries[i]);
946 if (GNUNET_SYSERR == ret) 952 if (GNUNET_SYSERR == ret)
947 return GNUNET_SYSERR; 953 return GNUNET_SYSERR;
948 if (GNUNET_NO == ret) 954 if (GNUNET_NO == ret)