diff options
Diffstat (limited to 'src/gnsrecord/plugin_gnsrecord_dns.c')
-rw-r--r-- | src/gnsrecord/plugin_gnsrecord_dns.c | 1167 |
1 files changed, 594 insertions, 573 deletions
diff --git a/src/gnsrecord/plugin_gnsrecord_dns.c b/src/gnsrecord/plugin_gnsrecord_dns.c index 3f62d3d77..8c39603e3 100644 --- a/src/gnsrecord/plugin_gnsrecord_dns.c +++ b/src/gnsrecord/plugin_gnsrecord_dns.c | |||
@@ -16,7 +16,7 @@ | |||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | 17 | ||
18 | SPDX-License-Identifier: AGPL3.0-or-later | 18 | SPDX-License-Identifier: AGPL3.0-or-later |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file gnsrecord/plugin_gnsrecord_dns.c | 22 | * @file gnsrecord/plugin_gnsrecord_dns.c |
@@ -39,222 +39,234 @@ | |||
39 | * @return NULL on error, otherwise human-readable representation of the value | 39 | * @return NULL on error, otherwise human-readable representation of the value |
40 | */ | 40 | */ |
41 | static char * | 41 | static char * |
42 | dns_value_to_string (void *cls, | 42 | dns_value_to_string(void *cls, |
43 | uint32_t type, | 43 | uint32_t type, |
44 | const void *data, | 44 | const void *data, |
45 | size_t data_size) | 45 | size_t data_size) |
46 | { | 46 | { |
47 | char *result; | 47 | char *result; |
48 | char tmp[INET6_ADDRSTRLEN]; | 48 | char tmp[INET6_ADDRSTRLEN]; |
49 | 49 | ||
50 | switch (type) | 50 | switch (type) |
51 | { | ||
52 | case GNUNET_DNSPARSER_TYPE_A: | ||
53 | if (data_size != sizeof (struct in_addr)) | ||
54 | return NULL; | ||
55 | if (NULL == inet_ntop (AF_INET, data, tmp, sizeof (tmp))) | ||
56 | return NULL; | ||
57 | return GNUNET_strdup (tmp); | ||
58 | case GNUNET_DNSPARSER_TYPE_NS: { | ||
59 | char *ns; | ||
60 | size_t off; | ||
61 | |||
62 | off = 0; | ||
63 | ns = GNUNET_DNSPARSER_parse_name (data, data_size, &off); | ||
64 | if ((NULL == ns) || (off != data_size)) | ||
65 | { | 51 | { |
66 | GNUNET_break_op (0); | 52 | case GNUNET_DNSPARSER_TYPE_A: |
67 | GNUNET_free_non_null (ns); | 53 | if (data_size != sizeof(struct in_addr)) |
68 | return NULL; | 54 | return NULL; |
55 | if (NULL == inet_ntop(AF_INET, data, tmp, sizeof(tmp))) | ||
56 | return NULL; | ||
57 | return GNUNET_strdup(tmp); | ||
58 | |||
59 | case GNUNET_DNSPARSER_TYPE_NS: { | ||
60 | char *ns; | ||
61 | size_t off; | ||
62 | |||
63 | off = 0; | ||
64 | ns = GNUNET_DNSPARSER_parse_name(data, data_size, &off); | ||
65 | if ((NULL == ns) || (off != data_size)) | ||
66 | { | ||
67 | GNUNET_break_op(0); | ||
68 | GNUNET_free_non_null(ns); | ||
69 | return NULL; | ||
70 | } | ||
71 | return ns; | ||
69 | } | 72 | } |
70 | return ns; | 73 | |
71 | } | 74 | case GNUNET_DNSPARSER_TYPE_CNAME: { |
72 | case GNUNET_DNSPARSER_TYPE_CNAME: { | 75 | char *cname; |
73 | char *cname; | 76 | size_t off; |
74 | size_t off; | 77 | |
75 | 78 | off = 0; | |
76 | off = 0; | 79 | cname = GNUNET_DNSPARSER_parse_name(data, data_size, &off); |
77 | cname = GNUNET_DNSPARSER_parse_name (data, data_size, &off); | 80 | if ((NULL == cname) || (off != data_size)) |
78 | if ((NULL == cname) || (off != data_size)) | 81 | { |
79 | { | 82 | GNUNET_break_op(0); |
80 | GNUNET_break_op (0); | 83 | GNUNET_free_non_null(cname); |
81 | GNUNET_free_non_null (cname); | 84 | return NULL; |
82 | return NULL; | 85 | } |
86 | return cname; | ||
83 | } | 87 | } |
84 | return cname; | 88 | |
85 | } | 89 | case GNUNET_DNSPARSER_TYPE_SOA: { |
86 | case GNUNET_DNSPARSER_TYPE_SOA: { | 90 | struct GNUNET_DNSPARSER_SoaRecord *soa; |
87 | struct GNUNET_DNSPARSER_SoaRecord *soa; | 91 | size_t off; |
88 | size_t off; | 92 | |
89 | 93 | off = 0; | |
90 | off = 0; | 94 | soa = GNUNET_DNSPARSER_parse_soa(data, data_size, &off); |
91 | soa = GNUNET_DNSPARSER_parse_soa (data, data_size, &off); | 95 | if ((NULL == soa) || (off != data_size)) |
92 | if ((NULL == soa) || (off != data_size)) | 96 | { |
93 | { | 97 | GNUNET_break_op(0); |
94 | GNUNET_break_op (0); | 98 | if (NULL != soa) |
95 | if (NULL != soa) | 99 | GNUNET_DNSPARSER_free_soa(soa); |
96 | GNUNET_DNSPARSER_free_soa (soa); | 100 | return NULL; |
97 | return NULL; | 101 | } |
102 | GNUNET_asprintf(&result, | ||
103 | "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", | ||
104 | soa->rname, | ||
105 | soa->mname, | ||
106 | soa->serial, | ||
107 | soa->refresh, | ||
108 | soa->retry, | ||
109 | soa->expire, | ||
110 | soa->minimum_ttl); | ||
111 | GNUNET_DNSPARSER_free_soa(soa); | ||
112 | return result; | ||
98 | } | 113 | } |
99 | GNUNET_asprintf (&result, | 114 | |
100 | "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu", | 115 | case GNUNET_DNSPARSER_TYPE_PTR: { |
101 | soa->rname, | 116 | char *ptr; |
102 | soa->mname, | 117 | size_t off; |
103 | soa->serial, | 118 | |
104 | soa->refresh, | 119 | off = 0; |
105 | soa->retry, | 120 | ptr = GNUNET_DNSPARSER_parse_name(data, data_size, &off); |
106 | soa->expire, | 121 | if ((NULL == ptr) || (off != data_size)) |
107 | soa->minimum_ttl); | 122 | { |
108 | GNUNET_DNSPARSER_free_soa (soa); | 123 | GNUNET_break_op(0); |
109 | return result; | 124 | GNUNET_free_non_null(ptr); |
110 | } | 125 | return NULL; |
111 | case GNUNET_DNSPARSER_TYPE_PTR: { | 126 | } |
112 | char *ptr; | 127 | return ptr; |
113 | size_t off; | ||
114 | |||
115 | off = 0; | ||
116 | ptr = GNUNET_DNSPARSER_parse_name (data, data_size, &off); | ||
117 | if ((NULL == ptr) || (off != data_size)) | ||
118 | { | ||
119 | GNUNET_break_op (0); | ||
120 | GNUNET_free_non_null (ptr); | ||
121 | return NULL; | ||
122 | } | 128 | } |
123 | return ptr; | 129 | |
124 | } | 130 | case GNUNET_DNSPARSER_TYPE_CERT: { |
125 | case GNUNET_DNSPARSER_TYPE_CERT: { | 131 | struct GNUNET_DNSPARSER_CertRecord *cert; |
126 | struct GNUNET_DNSPARSER_CertRecord *cert; | 132 | size_t off; |
127 | size_t off; | 133 | char *base64; |
128 | char *base64; | 134 | int len; |
129 | int len; | 135 | |
130 | 136 | off = 0; | |
131 | off = 0; | 137 | cert = GNUNET_DNSPARSER_parse_cert(data, data_size, &off); |
132 | cert = GNUNET_DNSPARSER_parse_cert (data, data_size, &off); | 138 | if ((NULL == cert) || (off != data_size)) |
133 | if ((NULL == cert) || (off != data_size)) | 139 | { |
134 | { | 140 | GNUNET_break_op(0); |
135 | GNUNET_break_op (0); | 141 | GNUNET_DNSPARSER_free_cert(cert); |
136 | GNUNET_DNSPARSER_free_cert (cert); | 142 | return NULL; |
137 | return NULL; | 143 | } |
144 | len = GNUNET_STRINGS_base64_encode(cert->certificate_data, | ||
145 | cert->certificate_size, | ||
146 | &base64); | ||
147 | GNUNET_asprintf(&result, | ||
148 | "%u %u %u %.*s", | ||
149 | cert->cert_type, | ||
150 | cert->cert_tag, | ||
151 | cert->algorithm, | ||
152 | len, | ||
153 | base64); | ||
154 | GNUNET_free(base64); | ||
155 | GNUNET_DNSPARSER_free_cert(cert); | ||
156 | return result; | ||
138 | } | 157 | } |
139 | len = GNUNET_STRINGS_base64_encode (cert->certificate_data, | 158 | |
140 | cert->certificate_size, | 159 | case GNUNET_DNSPARSER_TYPE_MX: { |
141 | &base64); | 160 | struct GNUNET_DNSPARSER_MxRecord *mx; |
142 | GNUNET_asprintf (&result, | 161 | size_t off; |
143 | "%u %u %u %.*s", | 162 | |
144 | cert->cert_type, | 163 | off = 0; |
145 | cert->cert_tag, | 164 | mx = GNUNET_DNSPARSER_parse_mx(data, data_size, &off); |
146 | cert->algorithm, | 165 | if ((NULL == mx) || (off != data_size)) |
147 | len, | 166 | { |
148 | base64); | 167 | GNUNET_break_op(0); |
149 | GNUNET_free (base64); | 168 | GNUNET_DNSPARSER_free_mx(mx); |
150 | GNUNET_DNSPARSER_free_cert (cert); | 169 | return NULL; |
151 | return result; | 170 | } |
152 | } | 171 | GNUNET_asprintf(&result, |
153 | case GNUNET_DNSPARSER_TYPE_MX: { | 172 | "%u,%s", |
154 | struct GNUNET_DNSPARSER_MxRecord *mx; | 173 | (unsigned int)mx->preference, |
155 | size_t off; | 174 | mx->mxhost); |
156 | 175 | GNUNET_DNSPARSER_free_mx(mx); | |
157 | off = 0; | 176 | return result; |
158 | mx = GNUNET_DNSPARSER_parse_mx (data, data_size, &off); | ||
159 | if ((NULL == mx) || (off != data_size)) | ||
160 | { | ||
161 | GNUNET_break_op (0); | ||
162 | GNUNET_DNSPARSER_free_mx (mx); | ||
163 | return NULL; | ||
164 | } | 177 | } |
165 | GNUNET_asprintf (&result, | 178 | |
166 | "%u,%s", | 179 | case GNUNET_DNSPARSER_TYPE_TXT: |
167 | (unsigned int) mx->preference, | 180 | return GNUNET_strndup(data, data_size); |
168 | mx->mxhost); | 181 | |
169 | GNUNET_DNSPARSER_free_mx (mx); | 182 | case GNUNET_DNSPARSER_TYPE_AAAA: |
170 | return result; | 183 | if (data_size != sizeof(struct in6_addr)) |
171 | } | 184 | return NULL; |
172 | case GNUNET_DNSPARSER_TYPE_TXT: | 185 | if (NULL == inet_ntop(AF_INET6, data, tmp, sizeof(tmp))) |
173 | return GNUNET_strndup (data, data_size); | 186 | return NULL; |
174 | case GNUNET_DNSPARSER_TYPE_AAAA: | 187 | return GNUNET_strdup(tmp); |
175 | if (data_size != sizeof (struct in6_addr)) | 188 | |
176 | return NULL; | 189 | case GNUNET_DNSPARSER_TYPE_SRV: { |
177 | if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof (tmp))) | 190 | struct GNUNET_DNSPARSER_SrvRecord *srv; |
178 | return NULL; | 191 | size_t off; |
179 | return GNUNET_strdup (tmp); | 192 | |
180 | case GNUNET_DNSPARSER_TYPE_SRV: { | 193 | off = 0; |
181 | struct GNUNET_DNSPARSER_SrvRecord *srv; | 194 | srv = GNUNET_DNSPARSER_parse_srv(data, data_size, &off); |
182 | size_t off; | 195 | if ((NULL == srv) || (off != data_size)) |
183 | 196 | { | |
184 | off = 0; | 197 | GNUNET_break_op(0); |
185 | srv = GNUNET_DNSPARSER_parse_srv (data, data_size, &off); | 198 | if (NULL != srv) |
186 | if ((NULL == srv) || (off != data_size)) | 199 | GNUNET_DNSPARSER_free_srv(srv); |
187 | { | 200 | return NULL; |
188 | GNUNET_break_op (0); | 201 | } |
189 | if (NULL != srv) | 202 | GNUNET_asprintf(&result, |
190 | GNUNET_DNSPARSER_free_srv (srv); | 203 | "%d %d %d %s", |
191 | return NULL; | 204 | srv->priority, |
205 | srv->weight, | ||
206 | srv->port, | ||
207 | srv->target); | ||
208 | GNUNET_DNSPARSER_free_srv(srv); | ||
209 | return result; | ||
192 | } | 210 | } |
193 | GNUNET_asprintf (&result, | 211 | |
194 | "%d %d %d %s", | 212 | case GNUNET_DNSPARSER_TYPE_TLSA: { |
195 | srv->priority, | 213 | const struct GNUNET_TUN_DnsTlsaRecord *tlsa; |
196 | srv->weight, | 214 | char *tlsa_str; |
197 | srv->port, | 215 | char *hex; |
198 | srv->target); | 216 | |
199 | GNUNET_DNSPARSER_free_srv (srv); | 217 | if (data_size < sizeof(struct GNUNET_TUN_DnsTlsaRecord)) |
200 | return result; | 218 | return NULL; /* malformed */ |
201 | } | 219 | tlsa = data; |
202 | case GNUNET_DNSPARSER_TYPE_TLSA: { | 220 | hex = |
203 | const struct GNUNET_TUN_DnsTlsaRecord *tlsa; | 221 | GNUNET_DNSPARSER_bin_to_hex(&tlsa[1], |
204 | char *tlsa_str; | 222 | data_size - |
205 | char *hex; | 223 | sizeof(struct GNUNET_TUN_DnsTlsaRecord)); |
206 | 224 | if (0 == GNUNET_asprintf(&tlsa_str, | |
207 | if (data_size < sizeof (struct GNUNET_TUN_DnsTlsaRecord)) | 225 | "%u %u %u %s", |
208 | return NULL; /* malformed */ | 226 | (unsigned int)tlsa->usage, |
209 | tlsa = data; | 227 | (unsigned int)tlsa->selector, |
210 | hex = | 228 | (unsigned int)tlsa->matching_type, |
211 | GNUNET_DNSPARSER_bin_to_hex (&tlsa[1], | 229 | hex)) |
212 | data_size - | 230 | { |
213 | sizeof (struct GNUNET_TUN_DnsTlsaRecord)); | 231 | GNUNET_free(hex); |
214 | if (0 == GNUNET_asprintf (&tlsa_str, | 232 | GNUNET_free(tlsa_str); |
215 | "%u %u %u %s", | 233 | return NULL; |
216 | (unsigned int) tlsa->usage, | 234 | } |
217 | (unsigned int) tlsa->selector, | 235 | GNUNET_free(hex); |
218 | (unsigned int) tlsa->matching_type, | 236 | return tlsa_str; |
219 | hex)) | ||
220 | { | ||
221 | GNUNET_free (hex); | ||
222 | GNUNET_free (tlsa_str); | ||
223 | return NULL; | ||
224 | } | 237 | } |
225 | GNUNET_free (hex); | 238 | |
226 | return tlsa_str; | 239 | case GNUNET_DNSPARSER_TYPE_CAA: { //RFC6844 |
227 | } | 240 | const struct GNUNET_DNSPARSER_CaaRecord *caa; |
228 | case GNUNET_DNSPARSER_TYPE_CAA: { //RFC6844 | 241 | char tag[15]; // between 1 and 15 bytes |
229 | const struct GNUNET_DNSPARSER_CaaRecord *caa; | 242 | char value[data_size]; |
230 | char tag[15]; // between 1 and 15 bytes | 243 | char *caa_str; |
231 | char value[data_size]; | 244 | if (data_size < sizeof(struct GNUNET_DNSPARSER_CaaRecord)) |
232 | char *caa_str; | 245 | return NULL; /* malformed */ |
233 | if (data_size < sizeof (struct GNUNET_DNSPARSER_CaaRecord)) | 246 | caa = data; |
234 | return NULL; /* malformed */ | 247 | if ((1 > caa->tag_len) || (15 < caa->tag_len)) |
235 | caa = data; | 248 | return NULL; /* malformed */ |
236 | if ((1 > caa->tag_len) || (15 < caa->tag_len)) | 249 | memset(tag, 0, sizeof(tag)); |
237 | return NULL; /* malformed */ | 250 | memset(value, 0, data_size); |
238 | memset (tag, 0, sizeof (tag)); | 251 | memcpy(tag, &caa[1], caa->tag_len); |
239 | memset (value, 0, data_size); | 252 | memcpy(value, |
240 | memcpy (tag, &caa[1], caa->tag_len); | 253 | (char *)&caa[1] + caa->tag_len, |
241 | memcpy (value, | 254 | data_size - caa->tag_len - 2); |
242 | (char *) &caa[1] + caa->tag_len, | 255 | if (0 == GNUNET_asprintf(&caa_str, |
243 | data_size - caa->tag_len - 2); | 256 | "%u %s %s", |
244 | if (0 == GNUNET_asprintf (&caa_str, | 257 | (unsigned int)caa->flags, |
245 | "%u %s %s", | 258 | tag, |
246 | (unsigned int) caa->flags, | 259 | value)) |
247 | tag, | 260 | { |
248 | value)) | 261 | GNUNET_free(caa_str); |
249 | { | 262 | return NULL; |
250 | GNUNET_free (caa_str); | 263 | } |
264 | return caa_str; | ||
265 | } | ||
266 | |||
267 | default: | ||
251 | return NULL; | 268 | return NULL; |
252 | } | 269 | } |
253 | return caa_str; | ||
254 | } | ||
255 | default: | ||
256 | return NULL; | ||
257 | } | ||
258 | } | 270 | } |
259 | 271 | ||
260 | 272 | ||
@@ -265,27 +277,26 @@ dns_value_to_string (void *cls, | |||
265 | * @return the value, 0 if not found | 277 | * @return the value, 0 if not found |
266 | */ | 278 | */ |
267 | static unsigned int | 279 | static unsigned int |
268 | rfc4398_mnemonic_to_value (const char *mnemonic) | 280 | rfc4398_mnemonic_to_value(const char *mnemonic) |
269 | { | 281 | { |
270 | static struct | 282 | static struct { |
271 | { | ||
272 | const char *mnemonic; | 283 | const char *mnemonic; |
273 | unsigned int val; | 284 | unsigned int val; |
274 | } table[] = {{"PKIX", 1}, | 285 | } table[] = { { "PKIX", 1 }, |
275 | {"SPKI", 2}, | 286 | { "SPKI", 2 }, |
276 | {"PGP", 3}, | 287 | { "PGP", 3 }, |
277 | {"IPKIX", 4}, | 288 | { "IPKIX", 4 }, |
278 | {"ISPKI", 5}, | 289 | { "ISPKI", 5 }, |
279 | {"IPGP", 6}, | 290 | { "IPGP", 6 }, |
280 | {"ACPKIX", 7}, | 291 | { "ACPKIX", 7 }, |
281 | {"IACPKIX", 8}, | 292 | { "IACPKIX", 8 }, |
282 | {"URI", 253}, | 293 | { "URI", 253 }, |
283 | {"OID", 254}, | 294 | { "OID", 254 }, |
284 | {NULL, 0}}; | 295 | { NULL, 0 } }; |
285 | unsigned int i; | 296 | unsigned int i; |
286 | 297 | ||
287 | for (i = 0; NULL != table[i].mnemonic; i++) | 298 | for (i = 0; NULL != table[i].mnemonic; i++) |
288 | if (0 == strcasecmp (mnemonic, table[i].mnemonic)) | 299 | if (0 == strcasecmp(mnemonic, table[i].mnemonic)) |
289 | return table[i].val; | 300 | return table[i].val; |
290 | return 0; | 301 | return 0; |
291 | } | 302 | } |
@@ -298,25 +309,24 @@ rfc4398_mnemonic_to_value (const char *mnemonic) | |||
298 | * @return the value, 0 if not found | 309 | * @return the value, 0 if not found |
299 | */ | 310 | */ |
300 | static unsigned int | 311 | static unsigned int |
301 | rfc4034_mnemonic_to_value (const char *mnemonic) | 312 | rfc4034_mnemonic_to_value(const char *mnemonic) |
302 | { | 313 | { |
303 | static struct | 314 | static struct { |
304 | { | ||
305 | const char *mnemonic; | 315 | const char *mnemonic; |
306 | unsigned int val; | 316 | unsigned int val; |
307 | } table[] = {{"RSAMD5", 1}, | 317 | } table[] = { { "RSAMD5", 1 }, |
308 | {"DH", 2}, | 318 | { "DH", 2 }, |
309 | {"DSA", 3}, | 319 | { "DSA", 3 }, |
310 | {"ECC", 4}, | 320 | { "ECC", 4 }, |
311 | {"RSASHA1", 5}, | 321 | { "RSASHA1", 5 }, |
312 | {"INDIRECT", 252}, | 322 | { "INDIRECT", 252 }, |
313 | {"PRIVATEDNS", 253}, | 323 | { "PRIVATEDNS", 253 }, |
314 | {"PRIVATEOID", 254}, | 324 | { "PRIVATEOID", 254 }, |
315 | {NULL, 0}}; | 325 | { NULL, 0 } }; |
316 | unsigned int i; | 326 | unsigned int i; |
317 | 327 | ||
318 | for (i = 0; NULL != table[i].mnemonic; i++) | 328 | for (i = 0; NULL != table[i].mnemonic; i++) |
319 | if (0 == strcasecmp (mnemonic, table[i].mnemonic)) | 329 | if (0 == strcasecmp(mnemonic, table[i].mnemonic)) |
320 | return table[i].val; | 330 | return table[i].val; |
321 | return 0; | 331 | return 0; |
322 | } | 332 | } |
@@ -334,11 +344,11 @@ rfc4034_mnemonic_to_value (const char *mnemonic) | |||
334 | * @return #GNUNET_OK on success | 344 | * @return #GNUNET_OK on success |
335 | */ | 345 | */ |
336 | static int | 346 | static int |
337 | dns_string_to_value (void *cls, | 347 | dns_string_to_value(void *cls, |
338 | uint32_t type, | 348 | uint32_t type, |
339 | const char *s, | 349 | const char *s, |
340 | void **data, | 350 | void **data, |
341 | size_t *data_size) | 351 | size_t *data_size) |
342 | { | 352 | { |
343 | struct in_addr value_a; | 353 | struct in_addr value_a; |
344 | struct in6_addr value_aaaa; | 354 | struct in6_addr value_aaaa; |
@@ -347,341 +357,353 @@ dns_string_to_value (void *cls, | |||
347 | if (NULL == s) | 357 | if (NULL == s) |
348 | return GNUNET_SYSERR; | 358 | return GNUNET_SYSERR; |
349 | switch (type) | 359 | switch (type) |
350 | { | ||
351 | case GNUNET_DNSPARSER_TYPE_A: | ||
352 | if (1 != inet_pton (AF_INET, s, &value_a)) | ||
353 | { | ||
354 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
355 | _ ("Unable to parse IPv4 address `%s'\n"), | ||
356 | s); | ||
357 | return GNUNET_SYSERR; | ||
358 | } | ||
359 | *data = GNUNET_new (struct in_addr); | ||
360 | GNUNET_memcpy (*data, &value_a, sizeof (value_a)); | ||
361 | *data_size = sizeof (value_a); | ||
362 | return GNUNET_OK; | ||
363 | case GNUNET_DNSPARSER_TYPE_NS: { | ||
364 | char nsbuf[256]; | ||
365 | size_t off; | ||
366 | |||
367 | off = 0; | ||
368 | if (GNUNET_OK != | ||
369 | GNUNET_DNSPARSER_builder_add_name (nsbuf, sizeof (nsbuf), &off, s)) | ||
370 | { | ||
371 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
372 | _ ("Failed to serialize NS record with value `%s'\n"), | ||
373 | s); | ||
374 | return GNUNET_SYSERR; | ||
375 | } | ||
376 | *data_size = off; | ||
377 | *data = GNUNET_malloc (off); | ||
378 | GNUNET_memcpy (*data, nsbuf, off); | ||
379 | return GNUNET_OK; | ||
380 | } | ||
381 | case GNUNET_DNSPARSER_TYPE_CNAME: { | ||
382 | char cnamebuf[256]; | ||
383 | size_t off; | ||
384 | |||
385 | off = 0; | ||
386 | if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name (cnamebuf, | ||
387 | sizeof (cnamebuf), | ||
388 | &off, | ||
389 | s)) | ||
390 | { | ||
391 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
392 | _ ("Failed to serialize CNAME record with value `%s'\n"), | ||
393 | s); | ||
394 | return GNUNET_SYSERR; | ||
395 | } | ||
396 | *data_size = off; | ||
397 | *data = GNUNET_malloc (off); | ||
398 | GNUNET_memcpy (*data, cnamebuf, off); | ||
399 | return GNUNET_OK; | ||
400 | } | ||
401 | case GNUNET_DNSPARSER_TYPE_CERT: { | ||
402 | char *sdup; | ||
403 | const char *typep; | ||
404 | const char *keyp; | ||
405 | const char *algp; | ||
406 | const char *certp; | ||
407 | unsigned int type; | ||
408 | unsigned int key; | ||
409 | unsigned int alg; | ||
410 | size_t cert_size; | ||
411 | char *cert_data; | ||
412 | struct GNUNET_DNSPARSER_CertRecord cert; | ||
413 | |||
414 | sdup = GNUNET_strdup (s); | ||
415 | typep = strtok (sdup, " "); | ||
416 | if ((NULL == typep) || | ||
417 | ((0 == (type = rfc4398_mnemonic_to_value (typep))) && | ||
418 | ((1 != sscanf (typep, "%u", &type)) || (type > UINT16_MAX)))) | ||
419 | { | ||
420 | GNUNET_free (sdup); | ||
421 | return GNUNET_SYSERR; | ||
422 | } | ||
423 | keyp = strtok (NULL, " "); | ||
424 | if ((NULL == keyp) || (1 != sscanf (keyp, "%u", &key)) || | ||
425 | (key > UINT16_MAX)) | ||
426 | { | 360 | { |
427 | GNUNET_free (sdup); | 361 | case GNUNET_DNSPARSER_TYPE_A: |
428 | return GNUNET_SYSERR; | 362 | if (1 != inet_pton(AF_INET, s, &value_a)) |
429 | } | 363 | { |
430 | alg = 0; | 364 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
431 | algp = strtok (NULL, " "); | 365 | _("Unable to parse IPv4 address `%s'\n"), |
432 | if ((NULL == algp) || | 366 | s); |
433 | ((0 == (type = rfc4034_mnemonic_to_value (typep))) && | 367 | return GNUNET_SYSERR; |
434 | ((1 != sscanf (algp, "%u", &alg)) || (alg > UINT8_MAX)))) | 368 | } |
435 | { | 369 | *data = GNUNET_new(struct in_addr); |
436 | GNUNET_free (sdup); | 370 | GNUNET_memcpy(*data, &value_a, sizeof(value_a)); |
437 | return GNUNET_SYSERR; | 371 | *data_size = sizeof(value_a); |
438 | } | 372 | return GNUNET_OK; |
439 | certp = strtok (NULL, " "); | 373 | |
440 | if ((NULL == certp) || (0 == strlen (certp))) | 374 | case GNUNET_DNSPARSER_TYPE_NS: { |
441 | { | 375 | char nsbuf[256]; |
442 | GNUNET_free (sdup); | ||
443 | return GNUNET_SYSERR; | ||
444 | } | ||
445 | cert_size = GNUNET_STRINGS_base64_decode (certp, | ||
446 | strlen (certp), | ||
447 | (void **) &cert_data); | ||
448 | GNUNET_free (sdup); | ||
449 | cert.cert_type = type; | ||
450 | cert.cert_tag = key; | ||
451 | cert.algorithm = alg; | ||
452 | cert.certificate_size = cert_size; | ||
453 | cert.certificate_data = cert_data; | ||
454 | { | ||
455 | char certbuf[cert_size + sizeof (struct GNUNET_TUN_DnsCertRecord)]; | ||
456 | size_t off; | 376 | size_t off; |
457 | 377 | ||
458 | off = 0; | 378 | off = 0; |
459 | if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_cert (certbuf, | 379 | if (GNUNET_OK != |
460 | sizeof (certbuf), | 380 | GNUNET_DNSPARSER_builder_add_name(nsbuf, sizeof(nsbuf), &off, s)) |
461 | &off, | 381 | { |
462 | &cert)) | 382 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
463 | { | 383 | _("Failed to serialize NS record with value `%s'\n"), |
464 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 384 | s); |
465 | _ ("Failed to serialize CERT record with %u bytes\n"), | 385 | return GNUNET_SYSERR; |
466 | (unsigned int) cert_size); | 386 | } |
467 | GNUNET_free (cert_data); | ||
468 | return GNUNET_SYSERR; | ||
469 | } | ||
470 | *data_size = off; | 387 | *data_size = off; |
471 | *data = GNUNET_malloc (off); | 388 | *data = GNUNET_malloc(off); |
472 | GNUNET_memcpy (*data, certbuf, off); | 389 | GNUNET_memcpy(*data, nsbuf, off); |
473 | } | 390 | return GNUNET_OK; |
474 | GNUNET_free (cert_data); | ||
475 | return GNUNET_OK; | ||
476 | } | ||
477 | case GNUNET_DNSPARSER_TYPE_SOA: { | ||
478 | struct GNUNET_DNSPARSER_SoaRecord soa; | ||
479 | char soabuf[540]; | ||
480 | char soa_rname[253 + 1]; | ||
481 | char soa_mname[253 + 1]; | ||
482 | unsigned int soa_serial; | ||
483 | unsigned int soa_refresh; | ||
484 | unsigned int soa_retry; | ||
485 | unsigned int soa_expire; | ||
486 | unsigned int soa_min; | ||
487 | size_t off; | ||
488 | |||
489 | if (7 != sscanf (s, | ||
490 | "rname=%253s mname=%253s %u,%u,%u,%u,%u", | ||
491 | soa_rname, | ||
492 | soa_mname, | ||
493 | &soa_serial, | ||
494 | &soa_refresh, | ||
495 | &soa_retry, | ||
496 | &soa_expire, | ||
497 | &soa_min)) | ||
498 | { | ||
499 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
500 | _ ("Unable to parse SOA record `%s'\n"), | ||
501 | s); | ||
502 | return GNUNET_SYSERR; | ||
503 | } | ||
504 | soa.mname = soa_mname; | ||
505 | soa.rname = soa_rname; | ||
506 | soa.serial = (uint32_t) soa_serial; | ||
507 | soa.refresh = (uint32_t) soa_refresh; | ||
508 | soa.retry = (uint32_t) soa_retry; | ||
509 | soa.expire = (uint32_t) soa_expire; | ||
510 | soa.minimum_ttl = (uint32_t) soa_min; | ||
511 | off = 0; | ||
512 | if (GNUNET_OK != | ||
513 | GNUNET_DNSPARSER_builder_add_soa (soabuf, sizeof (soabuf), &off, &soa)) | ||
514 | { | ||
515 | GNUNET_log ( | ||
516 | GNUNET_ERROR_TYPE_ERROR, | ||
517 | _ ("Failed to serialize SOA record with mname `%s' and rname `%s'\n"), | ||
518 | soa_mname, | ||
519 | soa_rname); | ||
520 | return GNUNET_SYSERR; | ||
521 | } | 391 | } |
522 | *data_size = off; | 392 | |
523 | *data = GNUNET_malloc (off); | 393 | case GNUNET_DNSPARSER_TYPE_CNAME: { |
524 | GNUNET_memcpy (*data, soabuf, off); | 394 | char cnamebuf[256]; |
525 | return GNUNET_OK; | 395 | size_t off; |
526 | } | 396 | |
527 | case GNUNET_DNSPARSER_TYPE_PTR: { | 397 | off = 0; |
528 | char ptrbuf[256]; | 398 | if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_name(cnamebuf, |
529 | size_t off; | 399 | sizeof(cnamebuf), |
530 | 400 | &off, | |
531 | off = 0; | 401 | s)) |
532 | if (GNUNET_OK != | 402 | { |
533 | GNUNET_DNSPARSER_builder_add_name (ptrbuf, sizeof (ptrbuf), &off, s)) | 403 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
534 | { | 404 | _("Failed to serialize CNAME record with value `%s'\n"), |
535 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 405 | s); |
536 | _ ("Failed to serialize PTR record with value `%s'\n"), | 406 | return GNUNET_SYSERR; |
537 | s); | 407 | } |
538 | return GNUNET_SYSERR; | 408 | *data_size = off; |
409 | *data = GNUNET_malloc(off); | ||
410 | GNUNET_memcpy(*data, cnamebuf, off); | ||
411 | return GNUNET_OK; | ||
539 | } | 412 | } |
540 | *data_size = off; | 413 | |
541 | *data = GNUNET_malloc (off); | 414 | case GNUNET_DNSPARSER_TYPE_CERT: { |
542 | GNUNET_memcpy (*data, ptrbuf, off); | 415 | char *sdup; |
543 | return GNUNET_OK; | 416 | const char *typep; |
544 | } | 417 | const char *keyp; |
545 | case GNUNET_DNSPARSER_TYPE_MX: { | 418 | const char *algp; |
546 | struct GNUNET_DNSPARSER_MxRecord mx; | 419 | const char *certp; |
547 | char mxbuf[258]; | 420 | unsigned int type; |
548 | char mxhost[253 + 1]; | 421 | unsigned int key; |
549 | unsigned int mx_pref; | 422 | unsigned int alg; |
550 | size_t off; | 423 | size_t cert_size; |
551 | 424 | char *cert_data; | |
552 | if (2 != sscanf (s, "%u,%253s", &mx_pref, mxhost)) | 425 | struct GNUNET_DNSPARSER_CertRecord cert; |
553 | { | 426 | |
554 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 427 | sdup = GNUNET_strdup(s); |
555 | _ ("Unable to parse MX record `%s'\n"), | 428 | typep = strtok(sdup, " "); |
556 | s); | 429 | if ((NULL == typep) || |
557 | return GNUNET_SYSERR; | 430 | ((0 == (type = rfc4398_mnemonic_to_value(typep))) && |
431 | ((1 != sscanf(typep, "%u", &type)) || (type > UINT16_MAX)))) | ||
432 | { | ||
433 | GNUNET_free(sdup); | ||
434 | return GNUNET_SYSERR; | ||
435 | } | ||
436 | keyp = strtok(NULL, " "); | ||
437 | if ((NULL == keyp) || (1 != sscanf(keyp, "%u", &key)) || | ||
438 | (key > UINT16_MAX)) | ||
439 | { | ||
440 | GNUNET_free(sdup); | ||
441 | return GNUNET_SYSERR; | ||
442 | } | ||
443 | alg = 0; | ||
444 | algp = strtok(NULL, " "); | ||
445 | if ((NULL == algp) || | ||
446 | ((0 == (type = rfc4034_mnemonic_to_value(typep))) && | ||
447 | ((1 != sscanf(algp, "%u", &alg)) || (alg > UINT8_MAX)))) | ||
448 | { | ||
449 | GNUNET_free(sdup); | ||
450 | return GNUNET_SYSERR; | ||
451 | } | ||
452 | certp = strtok(NULL, " "); | ||
453 | if ((NULL == certp) || (0 == strlen(certp))) | ||
454 | { | ||
455 | GNUNET_free(sdup); | ||
456 | return GNUNET_SYSERR; | ||
457 | } | ||
458 | cert_size = GNUNET_STRINGS_base64_decode(certp, | ||
459 | strlen(certp), | ||
460 | (void **)&cert_data); | ||
461 | GNUNET_free(sdup); | ||
462 | cert.cert_type = type; | ||
463 | cert.cert_tag = key; | ||
464 | cert.algorithm = alg; | ||
465 | cert.certificate_size = cert_size; | ||
466 | cert.certificate_data = cert_data; | ||
467 | { | ||
468 | char certbuf[cert_size + sizeof(struct GNUNET_TUN_DnsCertRecord)]; | ||
469 | size_t off; | ||
470 | |||
471 | off = 0; | ||
472 | if (GNUNET_OK != GNUNET_DNSPARSER_builder_add_cert(certbuf, | ||
473 | sizeof(certbuf), | ||
474 | &off, | ||
475 | &cert)) | ||
476 | { | ||
477 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
478 | _("Failed to serialize CERT record with %u bytes\n"), | ||
479 | (unsigned int)cert_size); | ||
480 | GNUNET_free(cert_data); | ||
481 | return GNUNET_SYSERR; | ||
482 | } | ||
483 | *data_size = off; | ||
484 | *data = GNUNET_malloc(off); | ||
485 | GNUNET_memcpy(*data, certbuf, off); | ||
486 | } | ||
487 | GNUNET_free(cert_data); | ||
488 | return GNUNET_OK; | ||
558 | } | 489 | } |
559 | mx.preference = (uint16_t) mx_pref; | ||
560 | mx.mxhost = mxhost; | ||
561 | off = 0; | ||
562 | 490 | ||
563 | if (GNUNET_OK != | 491 | case GNUNET_DNSPARSER_TYPE_SOA: { |
564 | GNUNET_DNSPARSER_builder_add_mx (mxbuf, sizeof (mxbuf), &off, &mx)) | 492 | struct GNUNET_DNSPARSER_SoaRecord soa; |
565 | { | 493 | char soabuf[540]; |
566 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 494 | char soa_rname[253 + 1]; |
567 | _ ("Failed to serialize MX record with hostname `%s'\n"), | 495 | char soa_mname[253 + 1]; |
568 | mxhost); | 496 | unsigned int soa_serial; |
569 | return GNUNET_SYSERR; | 497 | unsigned int soa_refresh; |
498 | unsigned int soa_retry; | ||
499 | unsigned int soa_expire; | ||
500 | unsigned int soa_min; | ||
501 | size_t off; | ||
502 | |||
503 | if (7 != sscanf(s, | ||
504 | "rname=%253s mname=%253s %u,%u,%u,%u,%u", | ||
505 | soa_rname, | ||
506 | soa_mname, | ||
507 | &soa_serial, | ||
508 | &soa_refresh, | ||
509 | &soa_retry, | ||
510 | &soa_expire, | ||
511 | &soa_min)) | ||
512 | { | ||
513 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
514 | _("Unable to parse SOA record `%s'\n"), | ||
515 | s); | ||
516 | return GNUNET_SYSERR; | ||
517 | } | ||
518 | soa.mname = soa_mname; | ||
519 | soa.rname = soa_rname; | ||
520 | soa.serial = (uint32_t)soa_serial; | ||
521 | soa.refresh = (uint32_t)soa_refresh; | ||
522 | soa.retry = (uint32_t)soa_retry; | ||
523 | soa.expire = (uint32_t)soa_expire; | ||
524 | soa.minimum_ttl = (uint32_t)soa_min; | ||
525 | off = 0; | ||
526 | if (GNUNET_OK != | ||
527 | GNUNET_DNSPARSER_builder_add_soa(soabuf, sizeof(soabuf), &off, &soa)) | ||
528 | { | ||
529 | GNUNET_log( | ||
530 | GNUNET_ERROR_TYPE_ERROR, | ||
531 | _("Failed to serialize SOA record with mname `%s' and rname `%s'\n"), | ||
532 | soa_mname, | ||
533 | soa_rname); | ||
534 | return GNUNET_SYSERR; | ||
535 | } | ||
536 | *data_size = off; | ||
537 | *data = GNUNET_malloc(off); | ||
538 | GNUNET_memcpy(*data, soabuf, off); | ||
539 | return GNUNET_OK; | ||
570 | } | 540 | } |
571 | *data_size = off; | 541 | |
572 | *data = GNUNET_malloc (off); | 542 | case GNUNET_DNSPARSER_TYPE_PTR: { |
573 | GNUNET_memcpy (*data, mxbuf, off); | 543 | char ptrbuf[256]; |
574 | return GNUNET_OK; | 544 | size_t off; |
575 | } | 545 | |
576 | case GNUNET_DNSPARSER_TYPE_SRV: { | 546 | off = 0; |
577 | struct GNUNET_DNSPARSER_SrvRecord srv; | 547 | if (GNUNET_OK != |
578 | char srvbuf[270]; | 548 | GNUNET_DNSPARSER_builder_add_name(ptrbuf, sizeof(ptrbuf), &off, s)) |
579 | char srvtarget[253 + 1]; | 549 | { |
580 | unsigned int priority; | 550 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
581 | unsigned int weight; | 551 | _("Failed to serialize PTR record with value `%s'\n"), |
582 | unsigned int port; | 552 | s); |
583 | size_t off; | 553 | return GNUNET_SYSERR; |
584 | 554 | } | |
585 | if (4 != sscanf (s, "%u %u %u %253s", &priority, &weight, &port, srvtarget)) | 555 | *data_size = off; |
586 | { | 556 | *data = GNUNET_malloc(off); |
587 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 557 | GNUNET_memcpy(*data, ptrbuf, off); |
588 | _ ("Unable to parse SRV record `%s'\n"), | 558 | return GNUNET_OK; |
589 | s); | ||
590 | return GNUNET_SYSERR; | ||
591 | } | 559 | } |
592 | srv.priority = (uint16_t) priority; | 560 | |
593 | srv.weight = (uint16_t) weight; | 561 | case GNUNET_DNSPARSER_TYPE_MX: { |
594 | srv.port = (uint16_t) port; | 562 | struct GNUNET_DNSPARSER_MxRecord mx; |
595 | srv.target = srvtarget; | 563 | char mxbuf[258]; |
596 | off = 0; | 564 | char mxhost[253 + 1]; |
597 | if (GNUNET_OK != | 565 | unsigned int mx_pref; |
598 | GNUNET_DNSPARSER_builder_add_srv (srvbuf, sizeof (srvbuf), &off, &srv)) | 566 | size_t off; |
599 | { | 567 | |
600 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 568 | if (2 != sscanf(s, "%u,%253s", &mx_pref, mxhost)) |
601 | _ ("Failed to serialize SRV record with target `%s'\n"), | 569 | { |
602 | srvtarget); | 570 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
603 | return GNUNET_SYSERR; | 571 | _("Unable to parse MX record `%s'\n"), |
572 | s); | ||
573 | return GNUNET_SYSERR; | ||
574 | } | ||
575 | mx.preference = (uint16_t)mx_pref; | ||
576 | mx.mxhost = mxhost; | ||
577 | off = 0; | ||
578 | |||
579 | if (GNUNET_OK != | ||
580 | GNUNET_DNSPARSER_builder_add_mx(mxbuf, sizeof(mxbuf), &off, &mx)) | ||
581 | { | ||
582 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
583 | _("Failed to serialize MX record with hostname `%s'\n"), | ||
584 | mxhost); | ||
585 | return GNUNET_SYSERR; | ||
586 | } | ||
587 | *data_size = off; | ||
588 | *data = GNUNET_malloc(off); | ||
589 | GNUNET_memcpy(*data, mxbuf, off); | ||
590 | return GNUNET_OK; | ||
604 | } | 591 | } |
605 | *data_size = off; | 592 | |
606 | *data = GNUNET_malloc (off); | 593 | case GNUNET_DNSPARSER_TYPE_SRV: { |
607 | GNUNET_memcpy (*data, srvbuf, off); | 594 | struct GNUNET_DNSPARSER_SrvRecord srv; |
608 | return GNUNET_OK; | 595 | char srvbuf[270]; |
609 | } | 596 | char srvtarget[253 + 1]; |
610 | case GNUNET_DNSPARSER_TYPE_TXT: | 597 | unsigned int priority; |
611 | *data = GNUNET_strdup (s); | 598 | unsigned int weight; |
612 | *data_size = strlen (s); | 599 | unsigned int port; |
613 | return GNUNET_OK; | 600 | size_t off; |
614 | case GNUNET_DNSPARSER_TYPE_AAAA: | 601 | |
615 | if (1 != inet_pton (AF_INET6, s, &value_aaaa)) | 602 | if (4 != sscanf(s, "%u %u %u %253s", &priority, &weight, &port, srvtarget)) |
616 | { | 603 | { |
617 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 604 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
618 | _ ("Unable to parse IPv6 address `%s'\n"), | 605 | _("Unable to parse SRV record `%s'\n"), |
619 | s); | 606 | s); |
620 | return GNUNET_SYSERR; | 607 | return GNUNET_SYSERR; |
608 | } | ||
609 | srv.priority = (uint16_t)priority; | ||
610 | srv.weight = (uint16_t)weight; | ||
611 | srv.port = (uint16_t)port; | ||
612 | srv.target = srvtarget; | ||
613 | off = 0; | ||
614 | if (GNUNET_OK != | ||
615 | GNUNET_DNSPARSER_builder_add_srv(srvbuf, sizeof(srvbuf), &off, &srv)) | ||
616 | { | ||
617 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
618 | _("Failed to serialize SRV record with target `%s'\n"), | ||
619 | srvtarget); | ||
620 | return GNUNET_SYSERR; | ||
621 | } | ||
622 | *data_size = off; | ||
623 | *data = GNUNET_malloc(off); | ||
624 | GNUNET_memcpy(*data, srvbuf, off); | ||
625 | return GNUNET_OK; | ||
621 | } | 626 | } |
622 | *data = GNUNET_new (struct in6_addr); | 627 | |
623 | *data_size = sizeof (struct in6_addr); | 628 | case GNUNET_DNSPARSER_TYPE_TXT: |
624 | GNUNET_memcpy (*data, &value_aaaa, sizeof (value_aaaa)); | 629 | *data = GNUNET_strdup(s); |
625 | return GNUNET_OK; | 630 | *data_size = strlen(s); |
626 | case GNUNET_DNSPARSER_TYPE_TLSA: { | 631 | return GNUNET_OK; |
627 | unsigned int usage; | 632 | |
628 | unsigned int selector; | 633 | case GNUNET_DNSPARSER_TYPE_AAAA: |
629 | unsigned int matching_type; | 634 | if (1 != inet_pton(AF_INET6, s, &value_aaaa)) |
630 | size_t slen = strlen (s) + 1; | 635 | { |
631 | char hex[slen]; | 636 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
632 | 637 | _("Unable to parse IPv6 address `%s'\n"), | |
633 | if (4 != sscanf (s, "%u %u %u %s", &usage, &selector, &matching_type, hex)) | 638 | s); |
634 | { | 639 | return GNUNET_SYSERR; |
635 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 640 | } |
636 | _ ("Unable to parse TLSA record string `%s'\n"), | 641 | *data = GNUNET_new(struct in6_addr); |
637 | s); | 642 | *data_size = sizeof(struct in6_addr); |
638 | *data_size = 0; | 643 | GNUNET_memcpy(*data, &value_aaaa, sizeof(value_aaaa)); |
639 | return GNUNET_SYSERR; | 644 | return GNUNET_OK; |
645 | |||
646 | case GNUNET_DNSPARSER_TYPE_TLSA: { | ||
647 | unsigned int usage; | ||
648 | unsigned int selector; | ||
649 | unsigned int matching_type; | ||
650 | size_t slen = strlen(s) + 1; | ||
651 | char hex[slen]; | ||
652 | |||
653 | if (4 != sscanf(s, "%u %u %u %s", &usage, &selector, &matching_type, hex)) | ||
654 | { | ||
655 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
656 | _("Unable to parse TLSA record string `%s'\n"), | ||
657 | s); | ||
658 | *data_size = 0; | ||
659 | return GNUNET_SYSERR; | ||
660 | } | ||
661 | |||
662 | *data_size = sizeof(struct GNUNET_TUN_DnsTlsaRecord) + strlen(hex) / 2; | ||
663 | *data = tlsa = GNUNET_malloc(*data_size); | ||
664 | tlsa->usage = (uint8_t)usage; | ||
665 | tlsa->selector = (uint8_t)selector; | ||
666 | tlsa->matching_type = (uint8_t)matching_type; | ||
667 | if (strlen(hex) / 2 != GNUNET_DNSPARSER_hex_to_bin(hex, &tlsa[1])) | ||
668 | { | ||
669 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
670 | _("Unable to parse TLSA record string `%s'\n"), | ||
671 | s); | ||
672 | GNUNET_free(*data); | ||
673 | *data = NULL; | ||
674 | *data_size = 0; | ||
675 | return GNUNET_SYSERR; | ||
676 | } | ||
677 | return GNUNET_OK; | ||
640 | } | 678 | } |
641 | 679 | ||
642 | *data_size = sizeof (struct GNUNET_TUN_DnsTlsaRecord) + strlen (hex) / 2; | 680 | case GNUNET_DNSPARSER_TYPE_CAA: { //RFC6844 |
643 | *data = tlsa = GNUNET_malloc (*data_size); | 681 | struct GNUNET_DNSPARSER_CaaRecord *caa; |
644 | tlsa->usage = (uint8_t) usage; | 682 | unsigned int flags; |
645 | tlsa->selector = (uint8_t) selector; | 683 | char tag[15]; //Max tag length 15 |
646 | tlsa->matching_type = (uint8_t) matching_type; | 684 | char value[strlen(s) + 1]; //Should be more than enough |
647 | if (strlen (hex) / 2 != GNUNET_DNSPARSER_hex_to_bin (hex, &tlsa[1])) | 685 | |
648 | { | 686 | if (3 != sscanf(s, "%u %s %[^\n]", &flags, tag, value)) |
649 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 687 | { |
650 | _ ("Unable to parse TLSA record string `%s'\n"), | 688 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
651 | s); | 689 | _("Unable to parse CAA record string `%s'\n"), |
652 | GNUNET_free (*data); | 690 | s); |
653 | *data = NULL; | 691 | *data_size = 0; |
654 | *data_size = 0; | 692 | return GNUNET_SYSERR; |
655 | return GNUNET_SYSERR; | 693 | } |
694 | *data_size = sizeof(struct GNUNET_DNSPARSER_CaaRecord) + strlen(tag) + | ||
695 | strlen(value); | ||
696 | *data = caa = GNUNET_malloc(*data_size); | ||
697 | caa->flags = flags; | ||
698 | memcpy(&caa[1], tag, strlen(tag)); | ||
699 | caa->tag_len = strlen(tag); | ||
700 | memcpy((char *)&caa[1] + caa->tag_len, value, strlen(value)); | ||
701 | return GNUNET_OK; | ||
656 | } | 702 | } |
657 | return GNUNET_OK; | 703 | |
658 | } | 704 | default: |
659 | case GNUNET_DNSPARSER_TYPE_CAA: { //RFC6844 | ||
660 | struct GNUNET_DNSPARSER_CaaRecord *caa; | ||
661 | unsigned int flags; | ||
662 | char tag[15]; //Max tag length 15 | ||
663 | char value[strlen (s) + 1]; //Should be more than enough | ||
664 | |||
665 | if (3 != sscanf (s, "%u %s %[^\n]", &flags, tag, value)) | ||
666 | { | ||
667 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
668 | _ ("Unable to parse CAA record string `%s'\n"), | ||
669 | s); | ||
670 | *data_size = 0; | ||
671 | return GNUNET_SYSERR; | 705 | return GNUNET_SYSERR; |
672 | } | 706 | } |
673 | *data_size = sizeof (struct GNUNET_DNSPARSER_CaaRecord) + strlen (tag) + | ||
674 | strlen (value); | ||
675 | *data = caa = GNUNET_malloc (*data_size); | ||
676 | caa->flags = flags; | ||
677 | memcpy (&caa[1], tag, strlen (tag)); | ||
678 | caa->tag_len = strlen (tag); | ||
679 | memcpy ((char *) &caa[1] + caa->tag_len, value, strlen (value)); | ||
680 | return GNUNET_OK; | ||
681 | } | ||
682 | default: | ||
683 | return GNUNET_SYSERR; | ||
684 | } | ||
685 | } | 707 | } |
686 | 708 | ||
687 | 709 | ||
@@ -689,23 +711,22 @@ dns_string_to_value (void *cls, | |||
689 | * Mapping of record type numbers to human-readable | 711 | * Mapping of record type numbers to human-readable |
690 | * record type names. | 712 | * record type names. |
691 | */ | 713 | */ |
692 | static struct | 714 | static struct { |
693 | { | ||
694 | const char *name; | 715 | const char *name; |
695 | uint32_t number; | 716 | uint32_t number; |
696 | } name_map[] = {{"A", GNUNET_DNSPARSER_TYPE_A}, | 717 | } name_map[] = { { "A", GNUNET_DNSPARSER_TYPE_A }, |
697 | {"NS", GNUNET_DNSPARSER_TYPE_NS}, | 718 | { "NS", GNUNET_DNSPARSER_TYPE_NS }, |
698 | {"CNAME", GNUNET_DNSPARSER_TYPE_CNAME}, | 719 | { "CNAME", GNUNET_DNSPARSER_TYPE_CNAME }, |
699 | {"SOA", GNUNET_DNSPARSER_TYPE_SOA}, | 720 | { "SOA", GNUNET_DNSPARSER_TYPE_SOA }, |
700 | {"PTR", GNUNET_DNSPARSER_TYPE_PTR}, | 721 | { "PTR", GNUNET_DNSPARSER_TYPE_PTR }, |
701 | {"MX", GNUNET_DNSPARSER_TYPE_MX}, | 722 | { "MX", GNUNET_DNSPARSER_TYPE_MX }, |
702 | {"TXT", GNUNET_DNSPARSER_TYPE_TXT}, | 723 | { "TXT", GNUNET_DNSPARSER_TYPE_TXT }, |
703 | {"AAAA", GNUNET_DNSPARSER_TYPE_AAAA}, | 724 | { "AAAA", GNUNET_DNSPARSER_TYPE_AAAA }, |
704 | {"SRV", GNUNET_DNSPARSER_TYPE_SRV}, | 725 | { "SRV", GNUNET_DNSPARSER_TYPE_SRV }, |
705 | {"TLSA", GNUNET_DNSPARSER_TYPE_TLSA}, | 726 | { "TLSA", GNUNET_DNSPARSER_TYPE_TLSA }, |
706 | {"CERT", GNUNET_DNSPARSER_TYPE_CERT}, | 727 | { "CERT", GNUNET_DNSPARSER_TYPE_CERT }, |
707 | {"CAA", GNUNET_DNSPARSER_TYPE_CAA}, | 728 | { "CAA", GNUNET_DNSPARSER_TYPE_CAA }, |
708 | {NULL, UINT32_MAX}}; | 729 | { NULL, UINT32_MAX } }; |
709 | 730 | ||
710 | 731 | ||
711 | /** | 732 | /** |
@@ -716,13 +737,13 @@ static struct | |||
716 | * @return corresponding number, UINT32_MAX on error | 737 | * @return corresponding number, UINT32_MAX on error |
717 | */ | 738 | */ |
718 | static uint32_t | 739 | static uint32_t |
719 | dns_typename_to_number (void *cls, const char *dns_typename) | 740 | dns_typename_to_number(void *cls, const char *dns_typename) |
720 | { | 741 | { |
721 | unsigned int i; | 742 | unsigned int i; |
722 | 743 | ||
723 | i = 0; | 744 | i = 0; |
724 | while ((NULL != name_map[i].name) && | 745 | while ((NULL != name_map[i].name) && |
725 | (0 != strcasecmp (dns_typename, name_map[i].name))) | 746 | (0 != strcasecmp(dns_typename, name_map[i].name))) |
726 | i++; | 747 | i++; |
727 | return name_map[i].number; | 748 | return name_map[i].number; |
728 | } | 749 | } |
@@ -736,7 +757,7 @@ dns_typename_to_number (void *cls, const char *dns_typename) | |||
736 | * @return corresponding typestring, NULL on error | 757 | * @return corresponding typestring, NULL on error |
737 | */ | 758 | */ |
738 | static const char * | 759 | static const char * |
739 | dns_number_to_typename (void *cls, uint32_t type) | 760 | dns_number_to_typename(void *cls, uint32_t type) |
740 | { | 761 | { |
741 | unsigned int i; | 762 | unsigned int i; |
742 | 763 | ||
@@ -754,11 +775,11 @@ dns_number_to_typename (void *cls, uint32_t type) | |||
754 | * @return the exported block API | 775 | * @return the exported block API |
755 | */ | 776 | */ |
756 | void * | 777 | void * |
757 | libgnunet_plugin_gnsrecord_dns_init (void *cls) | 778 | libgnunet_plugin_gnsrecord_dns_init(void *cls) |
758 | { | 779 | { |
759 | struct GNUNET_GNSRECORD_PluginFunctions *api; | 780 | struct GNUNET_GNSRECORD_PluginFunctions *api; |
760 | 781 | ||
761 | api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions); | 782 | api = GNUNET_new(struct GNUNET_GNSRECORD_PluginFunctions); |
762 | api->value_to_string = &dns_value_to_string; | 783 | api->value_to_string = &dns_value_to_string; |
763 | api->string_to_value = &dns_string_to_value; | 784 | api->string_to_value = &dns_string_to_value; |
764 | api->typename_to_number = &dns_typename_to_number; | 785 | api->typename_to_number = &dns_typename_to_number; |
@@ -774,11 +795,11 @@ libgnunet_plugin_gnsrecord_dns_init (void *cls) | |||
774 | * @return NULL | 795 | * @return NULL |
775 | */ | 796 | */ |
776 | void * | 797 | void * |
777 | libgnunet_plugin_gnsrecord_dns_done (void *cls) | 798 | libgnunet_plugin_gnsrecord_dns_done(void *cls) |
778 | { | 799 | { |
779 | struct GNUNET_GNSRECORD_PluginFunctions *api = cls; | 800 | struct GNUNET_GNSRECORD_PluginFunctions *api = cls; |
780 | 801 | ||
781 | GNUNET_free (api); | 802 | GNUNET_free(api); |
782 | return NULL; | 803 | return NULL; |
783 | } | 804 | } |
784 | 805 | ||