diff options
author | Philipp Tölke <toelke@in.tum.de> | 2010-11-02 21:40:05 +0000 |
---|---|---|
committer | Philipp Tölke <toelke@in.tum.de> | 2010-11-02 21:40:05 +0000 |
commit | 736b5e9964c384c85c3e00a128cefb34b15d9f11 (patch) | |
tree | 1afee399200b423c694e348a83e2aa807ca6b67c | |
parent | 55278d42655a4175ea222275966f7df10654908a (diff) | |
download | gnunet-736b5e9964c384c85c3e00a128cefb34b15d9f11.tar.gz gnunet-736b5e9964c384c85c3e00a128cefb34b15d9f11.zip |
Fixes and documentation
-rw-r--r-- | src/vpn/gnunet-dns-parser.c | 234 | ||||
-rw-r--r-- | src/vpn/gnunet-dns-parser.h | 2 | ||||
-rw-r--r-- | src/vpn/gnunet-service-dns-p.h | 19 | ||||
-rw-r--r-- | src/vpn/gnunet-service-dns.c | 5 |
4 files changed, 172 insertions, 88 deletions
diff --git a/src/vpn/gnunet-dns-parser.c b/src/vpn/gnunet-dns-parser.c index 7b81f6da4..e26638141 100644 --- a/src/vpn/gnunet-dns-parser.c +++ b/src/vpn/gnunet-dns-parser.c | |||
@@ -2,92 +2,160 @@ | |||
2 | #include "gnunet-dns-parser.h" | 2 | #include "gnunet-dns-parser.h" |
3 | #include "gnunet-vpn-packet.h" | 3 | #include "gnunet-vpn-packet.h" |
4 | 4 | ||
5 | unsigned int parse_dns_name(char* d, const unsigned char* src, unsigned short idx) {/*{{{*/ | 5 | /** |
6 | char* dest = d; | 6 | * Parse a name from DNS to a normal .-delimited, 0-terminated string. |
7 | 7 | * | |
8 | int len = src[idx++]; | 8 | * @param d The destination of the name. Should have at least 255 bytes allocated. |
9 | while (len != 0) { | 9 | * @param src The DNS-Packet |
10 | if (len & 0xC0) { /* Compressed name, offset in this and the next octet */ | 10 | * @param idx The offset inside the Packet from which on the name should be read |
11 | unsigned short offset = ((len & 0x3F) << 8) | src[idx++]; | 11 | * @returns The offset of the first unparsed byte (the byte right behind the name) |
12 | parse_dns_name(dest, src, offset - 12); /* 12 for the Header of the DNS-Packet, idx starts at 0 which is 12 bytes from the start of the packet */ | 12 | */ |
13 | return idx; | 13 | static unsigned int |
14 | } | 14 | parse_dns_name(char* d, const unsigned char* src, unsigned short idx) {/*{{{*/ |
15 | memcpy(dest, src+idx, len); | 15 | char* dest = d; |
16 | idx += len; | 16 | |
17 | dest += len; | 17 | int len = src[idx++]; |
18 | *dest = '.'; | 18 | while (len != 0) |
19 | dest++; | 19 | { |
20 | len = src[idx++]; | 20 | if (len & 0xC0) |
21 | }; | 21 | { /* Compressed name, offset in this and the next octet */ |
22 | *dest = 0; | 22 | unsigned short offset = ((len & 0x3F) << 8) | src[idx++]; |
23 | 23 | parse_dns_name(dest, src, offset - 12); /* 12 for the Header of the DNS-Packet, idx starts at 0 which is 12 bytes from the start of the packet */ | |
24 | return idx; | 24 | return idx; |
25 | } | ||
26 | memcpy(dest, src+idx, len); | ||
27 | idx += len; | ||
28 | dest += len; | ||
29 | *dest = '.'; | ||
30 | dest++; | ||
31 | len = src[idx++]; | ||
32 | }; | ||
33 | *dest = 0; | ||
34 | |||
35 | return idx; | ||
25 | } | 36 | } |
26 | /*}}}*/ | 37 | /*}}}*/ |
27 | 38 | ||
28 | unsigned short parse_dns_record(unsigned char* data, struct dns_record** dst, unsigned short count, unsigned short idx) {/*{{{*/ | 39 | /** |
29 | int i; | 40 | * Parse a complete DNS-Record from raw DNS-data to a struct dns_record |
30 | unsigned short _idx; | 41 | * |
31 | for (i = 0; i < count; i++) { | 42 | * @param data The DNS-data |
32 | dst[i] = GNUNET_malloc(sizeof(struct dns_record)); | 43 | * @param dst Pointer to count pointers; individual pointers will be allocated |
33 | dst[i]->name = alloca(255); // see RFC1035 | 44 | * @param count Number of records to parse |
34 | char* name = dst[i]->name; | 45 | * @param idx The offset inside the Packet from which on the name should be read |
35 | 46 | * @returns The offset of the first unparsed byte (the byte right behind the last record) | |
36 | _idx = parse_dns_name(name, data, idx); | 47 | */ |
37 | dst[i]->namelen = _idx - idx; | 48 | static unsigned short |
38 | idx = _idx; | 49 | parse_dns_record(unsigned char* data, /*{{{*/ |
39 | 50 | struct dns_record** dst, | |
40 | dst[i]->type = *((unsigned short*)(data+idx)); | 51 | unsigned short count, |
41 | idx += 2; | 52 | unsigned short idx) { |
42 | dst[i]->class = *((unsigned short*)(data+idx)); | 53 | int i; |
43 | idx += 2; | 54 | unsigned short _idx; |
44 | dst[i]->ttl = *((unsigned int*)(data+idx)); | 55 | for (i = 0; i < count; i++) { |
45 | idx += 4; | 56 | dst[i] = GNUNET_malloc(sizeof(struct dns_record)); |
46 | dst[i]->data_len = *((unsigned short*)(data+idx)); | 57 | dst[i]->name = alloca(255); // see RFC1035, no name can be longer than this. |
47 | idx += 2; | 58 | char* name = dst[i]->name; |
48 | dst[i]->data = GNUNET_malloc(ntohs(dst[i]->data_len)); | 59 | |
49 | memcpy(dst[i]->data, data+idx, ntohs(dst[i]->data_len)); | 60 | _idx = parse_dns_name(name, data, idx); |
50 | idx += ntohs(dst[i]->data_len); | 61 | dst[i]->namelen = _idx - idx; |
51 | } | 62 | |
52 | return idx; | 63 | dst[i]->name = GNUNET_malloc(dst[i]->namelen); |
64 | memcpy(dst[i]->name, name, dst[i]->namelen); | ||
65 | |||
66 | idx = _idx; | ||
67 | |||
68 | dst[i]->type = *((unsigned short*)(data+idx)); | ||
69 | idx += 2; | ||
70 | dst[i]->class = *((unsigned short*)(data+idx)); | ||
71 | idx += 2; | ||
72 | dst[i]->ttl = *((unsigned int*)(data+idx)); | ||
73 | idx += 4; | ||
74 | dst[i]->data_len = *((unsigned short*)(data+idx)); | ||
75 | idx += 2; | ||
76 | dst[i]->data = GNUNET_malloc(ntohs(dst[i]->data_len)); | ||
77 | memcpy(dst[i]->data, data+idx, ntohs(dst[i]->data_len)); | ||
78 | idx += ntohs(dst[i]->data_len); | ||
79 | } | ||
80 | return idx; | ||
53 | }/*}}}*/ | 81 | }/*}}}*/ |
54 | 82 | ||
55 | struct dns_pkt_parsed* parse_dns_packet(struct dns_pkt* pkt) {/*{{{*/ | 83 | /** |
56 | struct dns_pkt_parsed* ppkt = GNUNET_malloc(sizeof(struct dns_pkt_parsed)); | 84 | * Parse a raw DNS-Packet into an usable struct |
57 | memcpy(&ppkt->s, &pkt->s, sizeof pkt->s); | 85 | */ |
58 | 86 | struct dns_pkt_parsed* | |
59 | unsigned short qdcount = ntohs(ppkt->s.qdcount); | 87 | parse_dns_packet(struct dns_pkt* pkt) {/*{{{*/ |
60 | unsigned short ancount = ntohs(ppkt->s.ancount); | 88 | struct dns_pkt_parsed* ppkt = GNUNET_malloc(sizeof(struct dns_pkt_parsed)); |
61 | unsigned short nscount = ntohs(ppkt->s.nscount); | 89 | memcpy(&ppkt->s, &pkt->s, sizeof pkt->s); |
62 | unsigned short arcount = ntohs(ppkt->s.arcount); | 90 | |
63 | 91 | unsigned short qdcount = ntohs(ppkt->s.qdcount); | |
64 | ppkt->queries = GNUNET_malloc(qdcount*sizeof(struct dns_query*)); | 92 | unsigned short ancount = ntohs(ppkt->s.ancount); |
65 | ppkt->answers = GNUNET_malloc(ancount*sizeof(struct dns_record*)); | 93 | unsigned short nscount = ntohs(ppkt->s.nscount); |
66 | ppkt->nameservers = GNUNET_malloc(nscount*sizeof(struct dns_record*)); | 94 | unsigned short arcount = ntohs(ppkt->s.arcount); |
67 | ppkt->additional = GNUNET_malloc(arcount*sizeof(struct dns_record*)); | 95 | |
68 | 96 | ppkt->queries = GNUNET_malloc(qdcount*sizeof(struct dns_query*)); | |
69 | unsigned short idx = 0, _idx; /* This keeps track how far we have parsed the data */ | 97 | ppkt->answers = GNUNET_malloc(ancount*sizeof(struct dns_record*)); |
70 | 98 | ppkt->nameservers = GNUNET_malloc(nscount*sizeof(struct dns_record*)); | |
71 | int i; | 99 | ppkt->additional = GNUNET_malloc(arcount*sizeof(struct dns_record*)); |
72 | for (i = 0; i < qdcount; i++) { /*{{{*/ | 100 | |
73 | ppkt->queries[i] = GNUNET_malloc(sizeof(struct dns_query)); | 101 | unsigned short idx = 0, _idx; /* This keeps track how far we have parsed the data */ |
74 | char* name = alloca(255); /* see RFC1035, it can't be more than this. */ | 102 | |
75 | 103 | /* Parse the Query */ | |
76 | _idx = parse_dns_name(name, pkt->data, idx); | 104 | int i; |
77 | ppkt->queries[i]->namelen = _idx - idx; | 105 | for (i = 0; i < qdcount; i++) |
78 | idx = _idx; | 106 | { /*{{{*/ |
79 | 107 | ppkt->queries[i] = GNUNET_malloc(sizeof(struct dns_query)); | |
80 | ppkt->queries[i]->name = GNUNET_malloc(ppkt->queries[i]->namelen + 1); | 108 | char* name = alloca(255); /* see RFC1035, it can't be more than this. */ |
81 | memcpy(ppkt->queries[i]->name, name, ppkt->queries[i]->namelen + 1); | 109 | |
82 | 110 | _idx = parse_dns_name(name, pkt->data, idx); | |
83 | ppkt->queries[i]->qtype = *((unsigned short*)(pkt->data+idx)); | 111 | ppkt->queries[i]->namelen = _idx - idx; |
84 | idx += 2; | 112 | idx = _idx; |
85 | ppkt->queries[i]->qclass = *((unsigned short*)(pkt->data+idx)); | 113 | |
86 | idx += 2; | 114 | ppkt->queries[i]->name = GNUNET_malloc(ppkt->queries[i]->namelen); |
87 | } | 115 | memcpy(ppkt->queries[i]->name, name, ppkt->queries[i]->namelen); |
88 | /*}}}*/ | 116 | |
89 | idx = parse_dns_record(pkt->data, ppkt->answers, ancount, idx); | 117 | ppkt->queries[i]->qtype = *((unsigned short*)(pkt->data+idx)); |
90 | idx = parse_dns_record(pkt->data, ppkt->nameservers, nscount, idx); | 118 | idx += 2; |
91 | idx = parse_dns_record(pkt->data, ppkt->additional, arcount, idx); | 119 | ppkt->queries[i]->qclass = *((unsigned short*)(pkt->data+idx)); |
92 | return ppkt; | 120 | idx += 2; |
121 | } | ||
122 | /*}}}*/ | ||
123 | idx = parse_dns_record(pkt->data, ppkt->answers, ancount, idx); | ||
124 | idx = parse_dns_record(pkt->data, ppkt->nameservers, nscount, idx); | ||
125 | idx = parse_dns_record(pkt->data, ppkt->additional, arcount, idx); | ||
126 | return ppkt; | ||
93 | }/*}}}*/ | 127 | }/*}}}*/ |
128 | |||
129 | void | ||
130 | free_parsed_dns_packet(struct dns_pkt_parsed* ppkt) { | ||
131 | unsigned short qdcount = ntohs(ppkt->s.qdcount); | ||
132 | unsigned short ancount = ntohs(ppkt->s.ancount); | ||
133 | unsigned short nscount = ntohs(ppkt->s.nscount); | ||
134 | unsigned short arcount = ntohs(ppkt->s.arcount); | ||
135 | |||
136 | int i; | ||
137 | for (i = 0; i < qdcount; i++) { | ||
138 | GNUNET_free(ppkt->queries[i]->name); | ||
139 | GNUNET_free(ppkt->queries[i]); | ||
140 | } | ||
141 | GNUNET_free(ppkt->queries); | ||
142 | for (i = 0; i < ancount; i++) { | ||
143 | GNUNET_free(ppkt->answers[i]->name); | ||
144 | GNUNET_free(ppkt->answers[i]->data); | ||
145 | GNUNET_free(ppkt->answers[i]); | ||
146 | } | ||
147 | GNUNET_free(ppkt->answers); | ||
148 | for (i = 0; i < nscount; i++) { | ||
149 | GNUNET_free(ppkt->nameservers[i]->name); | ||
150 | GNUNET_free(ppkt->nameservers[i]->data); | ||
151 | GNUNET_free(ppkt->nameservers[i]); | ||
152 | } | ||
153 | GNUNET_free(ppkt->nameservers); | ||
154 | for (i = 0; i < arcount; i++) { | ||
155 | GNUNET_free(ppkt->additional[i]->name); | ||
156 | GNUNET_free(ppkt->additional[i]->data); | ||
157 | GNUNET_free(ppkt->additional[i]); | ||
158 | } | ||
159 | GNUNET_free(ppkt->additional); | ||
160 | GNUNET_free(ppkt); | ||
161 | } | ||
diff --git a/src/vpn/gnunet-dns-parser.h b/src/vpn/gnunet-dns-parser.h index 1ee82e7a3..ea1a5765c 100644 --- a/src/vpn/gnunet-dns-parser.h +++ b/src/vpn/gnunet-dns-parser.h | |||
@@ -6,4 +6,6 @@ | |||
6 | 6 | ||
7 | struct dns_pkt_parsed* parse_dns_packet(struct dns_pkt* pkt); | 7 | struct dns_pkt_parsed* parse_dns_packet(struct dns_pkt* pkt); |
8 | 8 | ||
9 | void free_parsed_dns_packet(struct dns_pkt_parsed* ppkt); | ||
10 | |||
9 | #endif | 11 | #endif |
diff --git a/src/vpn/gnunet-service-dns-p.h b/src/vpn/gnunet-service-dns-p.h index 01605dcf2..5b61ba653 100644 --- a/src/vpn/gnunet-service-dns-p.h +++ b/src/vpn/gnunet-service-dns-p.h | |||
@@ -5,9 +5,18 @@ | |||
5 | 5 | ||
6 | struct query_packet { | 6 | struct query_packet { |
7 | struct GNUNET_MessageHeader hdr; | 7 | struct GNUNET_MessageHeader hdr; |
8 | 8 | ||
9 | unsigned orig_to:32 GNUNET_PACKED; /* The IP-Address, this query was originally sent to */ | 9 | /** |
10 | * The IP-Address this query was originally sent to | ||
11 | */ | ||
12 | unsigned orig_to:32 GNUNET_PACKED; | ||
13 | /** | ||
14 | * The IP-Address this query was originally sent from | ||
15 | */ | ||
10 | unsigned orig_from:32 GNUNET_PACKED; | 16 | unsigned orig_from:32 GNUNET_PACKED; |
17 | /** | ||
18 | * The UDP-Portthis query was originally sent from | ||
19 | */ | ||
11 | unsigned src_port:16 GNUNET_PACKED; | 20 | unsigned src_port:16 GNUNET_PACKED; |
12 | 21 | ||
13 | unsigned char data[1]; /* The DNS-Packet */ | 22 | unsigned char data[1]; /* The DNS-Packet */ |
@@ -26,7 +35,8 @@ enum GNUNET_DNS_ANSWER_Subtype { | |||
26 | GNUNET_DNS_ANSWER_TYPE_IP, | 35 | GNUNET_DNS_ANSWER_TYPE_IP, |
27 | 36 | ||
28 | /** | 37 | /** |
29 | * Answers of this type contain an struct GNUNET_DNS_Record | 38 | * Answers of this type contain an incomplete dns-packet. The IP-Address |
39 | * is all 0s. The addroffset points to it. | ||
30 | */ | 40 | */ |
31 | GNUNET_DNS_ANSWER_TYPE_SERVICE | 41 | GNUNET_DNS_ANSWER_TYPE_SERVICE |
32 | }; | 42 | }; |
@@ -39,11 +49,14 @@ struct answer_packet { | |||
39 | unsigned to:32 GNUNET_PACKED; | 49 | unsigned to:32 GNUNET_PACKED; |
40 | unsigned dst_port:16 GNUNET_PACKED; | 50 | unsigned dst_port:16 GNUNET_PACKED; |
41 | 51 | ||
52 | /* Only sensible when subtype == GNUNET_DNS_ANSWER_TYPE_SERVICE */ | ||
42 | GNUNET_HashCode peer; | 53 | GNUNET_HashCode peer; |
43 | GNUNET_HashCode service_descriptor; | 54 | GNUNET_HashCode service_descriptor; |
44 | uint64_t ports; | 55 | uint64_t ports; |
45 | uint32_t service_type; | 56 | uint32_t service_type; |
46 | 57 | ||
58 | /* The offsett in octets from the beginning of the struct to the field | ||
59 | * in data where the IP-Address has to go. */ | ||
47 | unsigned addroffset:16 GNUNET_PACKED; | 60 | unsigned addroffset:16 GNUNET_PACKED; |
48 | 61 | ||
49 | unsigned char data[1]; | 62 | unsigned char data[1]; |
diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index ee2549d17..6c95c7789 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c | |||
@@ -331,7 +331,6 @@ receive_query(void *cls, | |||
331 | } | 331 | } |
332 | 332 | ||
333 | /* The query should be sent to the network */ | 333 | /* The query should be sent to the network */ |
334 | GNUNET_free(pdns); | ||
335 | 334 | ||
336 | struct sockaddr_in dest; | 335 | struct sockaddr_in dest; |
337 | memset(&dest, 0, sizeof dest); | 336 | memset(&dest, 0, sizeof dest); |
@@ -345,6 +344,8 @@ receive_query(void *cls, | |||
345 | sizeof dest); | 344 | sizeof dest); |
346 | 345 | ||
347 | out: | 346 | out: |
347 | free_parsed_dns_packet(pdns); | ||
348 | pdns = NULL; | ||
348 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | 349 | GNUNET_SERVER_receive_done(client, GNUNET_OK); |
349 | } | 350 | } |
350 | 351 | ||
@@ -459,7 +460,7 @@ publish_name (void *cls, | |||
459 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); | 460 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "could not sign DNS_Record\n"); |
460 | return; | 461 | return; |
461 | } | 462 | } |
462 | GNUNET_free(my_private_key); | 463 | GNUNET_CRYPTO_rsa_key_free(my_private_key); |
463 | 464 | ||
464 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 465 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
465 | "Putting with key %08x\n", | 466 | "Putting with key %08x\n", |