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