aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2019-05-02 08:00:21 +0200
committerChristian Grothoff <christian@grothoff.org>2019-05-02 08:00:21 +0200
commite46a601f124108ec5e76a22998618b0c630eae74 (patch)
treedbec145dfc14b011a4cfce6e4ecde5f71af70526 /src
parentb930db26d6b166404a3262687750e5aec2b3befc (diff)
downloadgnunet-e46a601f124108ec5e76a22998618b0c630eae74.tar.gz
gnunet-e46a601f124108ec5e76a22998618b0c630eae74.zip
reject '@' as a label in domain names, this is usually a mistake
Diffstat (limited to 'src')
-rw-r--r--src/gns/gnunet-gns.c115
-rw-r--r--src/util/dnsparser.c586
2 files changed, 310 insertions, 391 deletions
diff --git a/src/gns/gnunet-gns.c b/src/gns/gnunet-gns.c
index 83dd7b27b..1cda84c59 100644
--- a/src/gns/gnunet-gns.c
+++ b/src/gns/gnunet-gns.c
@@ -106,13 +106,13 @@ do_shutdown (void *cls)
106 */ 106 */
107static void 107static void
108process_lookup_result (void *cls, 108process_lookup_result (void *cls,
109 int was_gns, 109 int was_gns,
110 uint32_t rd_count, 110 uint32_t rd_count,
111 const struct GNUNET_GNSRECORD_Data *rd) 111 const struct GNUNET_GNSRECORD_Data *rd)
112{ 112{
113 const char *name = cls; 113 const char *name = cls;
114 const char *typename; 114 const char *typename;
115 char* string_val; 115 char *string_val;
116 116
117 lr = NULL; 117 lr = NULL;
118 if (GNUNET_NO == was_gns) 118 if (GNUNET_NO == was_gns)
@@ -126,33 +126,28 @@ process_lookup_result (void *cls,
126 if (0 == rd_count) 126 if (0 == rd_count)
127 printf ("No results.\n"); 127 printf ("No results.\n");
128 else 128 else
129 printf ("%s:\n", 129 printf ("%s:\n", name);
130 name);
131 } 130 }
132 for (uint32_t i=0; i<rd_count; i++) 131 for (uint32_t i = 0; i < rd_count; i++)
133 { 132 {
134 if ( (rd[i].record_type != rtype) && 133 if ((rd[i].record_type != rtype) && (GNUNET_GNSRECORD_TYPE_ANY != rtype))
135 (GNUNET_GNSRECORD_TYPE_ANY != rtype) )
136 continue; 134 continue;
137 typename = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type); 135 typename = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
138 string_val = GNUNET_GNSRECORD_value_to_string (rd[i].record_type, 136 string_val = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
139 rd[i].data, 137 rd[i].data,
140 rd[i].data_size); 138 rd[i].data_size);
141 if (NULL == string_val) 139 if (NULL == string_val)
142 { 140 {
143 fprintf (stderr, 141 fprintf (stderr,
144 "Record %u of type %d malformed, skipping\n", 142 "Record %u of type %d malformed, skipping\n",
145 (unsigned int) i, 143 (unsigned int) i,
146 (int) rd[i].record_type); 144 (int) rd[i].record_type);
147 continue; 145 continue;
148 } 146 }
149 if (raw) 147 if (raw)
150 printf ("%s\n", 148 printf ("%s\n", string_val);
151 string_val);
152 else 149 else
153 printf ("Got `%s' record: %s\n", 150 printf ("Got `%s' record: %s\n", typename, string_val);
154 typename,
155 string_val);
156 GNUNET_free (string_val); 151 GNUNET_free (string_val);
157 } 152 }
158 GNUNET_SCHEDULER_shutdown (); 153 GNUNET_SCHEDULER_shutdown ();
@@ -178,33 +173,35 @@ run (void *cls,
178 (void) cfgfile; 173 (void) cfgfile;
179 174
180 cfg = c; 175 cfg = c;
176 if (GNUNET_OK != GNUNET_DNSPARSER_check_name (lookup_name))
177 {
178 fprintf (stderr, _ ("`%s' is not a valid domain name\n"), lookup_name);
179 global_ret = 3;
180 return;
181 }
181 gns = GNUNET_GNS_connect (cfg); 182 gns = GNUNET_GNS_connect (cfg);
182 if (NULL == gns) 183 if (NULL == gns)
183 { 184 {
184 fprintf (stderr, 185 fprintf (stderr, _ ("Failed to connect to GNS\n"));
185 _("Failed to connect to GNS\n"));
186 global_ret = 2; 186 global_ret = 2;
187 return; 187 return;
188 } 188 }
189 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, 189 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
190 NULL);
191
192 if (NULL != lookup_type) 190 if (NULL != lookup_type)
193 rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type); 191 rtype = GNUNET_GNSRECORD_typename_to_number (lookup_type);
194 else 192 else
195 rtype = GNUNET_DNSPARSER_TYPE_A; 193 rtype = GNUNET_DNSPARSER_TYPE_A;
196 if (UINT32_MAX == rtype) 194 if (UINT32_MAX == rtype)
197 { 195 {
198 fprintf (stderr, 196 fprintf (stderr, _ ("Invalid typename specified, assuming `ANY'\n"));
199 _("Invalid typename specified, assuming `ANY'\n"));
200 rtype = GNUNET_GNSRECORD_TYPE_ANY; 197 rtype = GNUNET_GNSRECORD_TYPE_ANY;
201 } 198 }
202 lr = GNUNET_GNS_lookup_with_tld (gns, 199 lr = GNUNET_GNS_lookup_with_tld (gns,
203 lookup_name, 200 lookup_name,
204 rtype, 201 rtype,
205 GNUNET_GNS_LO_DEFAULT, 202 GNUNET_GNS_LO_DEFAULT,
206 &process_lookup_result, 203 &process_lookup_result,
207 lookup_name); 204 lookup_name);
208 if (NULL == lr) 205 if (NULL == lr)
209 { 206 {
210 global_ret = 2; 207 global_ret = 2;
@@ -222,43 +219,41 @@ run (void *cls,
222 * @return 0 ok, 1 on error 219 * @return 0 ok, 1 on error
223 */ 220 */
224int 221int
225main (int argc, 222main (int argc, char *const *argv)
226 char *const *argv)
227{ 223{
228 struct GNUNET_GETOPT_CommandLineOption options[] = { 224 struct GNUNET_GETOPT_CommandLineOption options[] =
229 GNUNET_GETOPT_option_mandatory 225 {GNUNET_GETOPT_option_mandatory (
230 (GNUNET_GETOPT_option_string ('u', 226 GNUNET_GETOPT_option_string ('u',
231 "lookup", 227 "lookup",
232 "NAME", 228 "NAME",
233 gettext_noop ("Lookup a record for the given name"), 229 gettext_noop (
234 &lookup_name)), 230 "Lookup a record for the given name"),
235 GNUNET_GETOPT_option_string ('t', 231 &lookup_name)),
236 "type", 232 GNUNET_GETOPT_option_string ('t',
237 "TYPE", 233 "type",
238 gettext_noop ("Specify the type of the record to lookup"), 234 "TYPE",
239 &lookup_type), 235 gettext_noop (
240 GNUNET_GETOPT_option_flag ('r', 236 "Specify the type of the record to lookup"),
241 "raw", 237 &lookup_type),
242 gettext_noop ("No unneeded output"), 238 GNUNET_GETOPT_option_flag ('r',
243 &raw), 239 "raw",
244 GNUNET_GETOPT_OPTION_END 240 gettext_noop ("No unneeded output"),
245 }; 241 &raw),
242 GNUNET_GETOPT_OPTION_END};
246 int ret; 243 int ret;
247 244
248 if (GNUNET_OK != 245 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
249 GNUNET_STRINGS_get_utf8_args (argc, argv,
250 &argc, &argv))
251 return 2; 246 return 2;
252 247
253 GNUNET_log_setup ("gnunet-gns", 248 GNUNET_log_setup ("gnunet-gns", "WARNING", NULL);
254 "WARNING", 249 ret = GNUNET_PROGRAM_run (argc,
255 NULL); 250 argv,
256 ret = GNUNET_PROGRAM_run (argc, argv,
257 "gnunet-gns", 251 "gnunet-gns",
258 _("GNUnet GNS resolver tool"), 252 _ ("GNUnet GNS resolver tool"),
259 options, 253 options,
260 &run, NULL); 254 &run,
261 GNUNET_free ((void*) argv); 255 NULL);
256 GNUNET_free ((void *) argv);
262 if (GNUNET_OK != ret) 257 if (GNUNET_OK != ret)
263 return 1; 258 return 1;
264 return global_ret; 259 return global_ret;
diff --git a/src/util/dnsparser.c b/src/util/dnsparser.c
index 7546ca1e9..0e830170e 100644
--- a/src/util/dnsparser.c
+++ b/src/util/dnsparser.c
@@ -60,8 +60,10 @@ GNUNET_DNSPARSER_check_label (const char *label)
60 60
61 if (NULL != strchr (label, '.')) 61 if (NULL != strchr (label, '.'))
62 return GNUNET_SYSERR; /* not a label! Did you mean GNUNET_DNSPARSER_check_name? */ 62 return GNUNET_SYSERR; /* not a label! Did you mean GNUNET_DNSPARSER_check_name? */
63 if (IDNA_SUCCESS != 63 if (0 == strcmp (label, "@"))
64 idna_to_ascii_8z (label, &output, IDNA_ALLOW_UNASSIGNED)) 64 return GNUNET_SYSERR; /* '@' is reserved for the empty label,
65 see #GNUNET_GNS_EMPTY_LABEL_AT */
66 if (IDNA_SUCCESS != idna_to_ascii_8z (label, &output, IDNA_ALLOW_UNASSIGNED))
65 return GNUNET_SYSERR; 67 return GNUNET_SYSERR;
66 slen = strlen (output); 68 slen = strlen (output);
67#if WINDOWS 69#if WINDOWS
@@ -91,15 +93,13 @@ GNUNET_DNSPARSER_check_name (const char *name)
91 93
92 ldup = GNUNET_strdup (name); 94 ldup = GNUNET_strdup (name);
93 for (tok = strtok (ldup, "."); NULL != tok; tok = strtok (NULL, ".")) 95 for (tok = strtok (ldup, "."); NULL != tok; tok = strtok (NULL, "."))
94 if (GNUNET_OK != 96 if (GNUNET_OK != GNUNET_DNSPARSER_check_label (tok))
95 GNUNET_DNSPARSER_check_label (tok))
96 { 97 {
97 GNUNET_free (ldup); 98 GNUNET_free (ldup);
98 return GNUNET_SYSERR; 99 return GNUNET_SYSERR;
99 } 100 }
100 GNUNET_free (ldup); 101 GNUNET_free (ldup);
101 if (IDNA_SUCCESS != 102 if (IDNA_SUCCESS != idna_to_ascii_8z (name, &output, IDNA_ALLOW_UNASSIGNED))
102 idna_to_ascii_8z (name, &output, IDNA_ALLOW_UNASSIGNED))
103 return GNUNET_SYSERR; 103 return GNUNET_SYSERR;
104 slen = strlen (output); 104 slen = strlen (output);
105#if WINDOWS 105#if WINDOWS
@@ -219,9 +219,9 @@ GNUNET_DNSPARSER_free_record (struct GNUNET_DNSPARSER_Record *r)
219 */ 219 */
220static char * 220static char *
221parse_name (const char *udp_payload, 221parse_name (const char *udp_payload,
222 size_t udp_payload_length, 222 size_t udp_payload_length,
223 size_t *off, 223 size_t *off,
224 unsigned int depth) 224 unsigned int depth)
225{ 225{
226 const uint8_t *input = (const uint8_t *) udp_payload; 226 const uint8_t *input = (const uint8_t *) udp_payload;
227 char *ret; 227 char *ret;
@@ -250,78 +250,66 @@ parse_name (const char *udp_payload,
250 { 250 {
251 if (*off + 1 + len > udp_payload_length) 251 if (*off + 1 + len > udp_payload_length)
252 { 252 {
253 GNUNET_break_op (0); 253 GNUNET_break_op (0);
254 goto error; 254 goto error;
255 } 255 }
256 GNUNET_asprintf (&tmp, 256 GNUNET_asprintf (&tmp, "%.*s", (int) len, &udp_payload[*off + 1]);
257 "%.*s",
258 (int) len,
259 &udp_payload[*off + 1]);
260 if (IDNA_SUCCESS != 257 if (IDNA_SUCCESS !=
261 (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED))) 258 (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED)))
262 { 259 {
263 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 260 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
264 _("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"), 261 _ ("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"),
265 tmp, 262 tmp,
266 idna_strerror (rc)); 263 idna_strerror (rc));
267 GNUNET_free (tmp); 264 GNUNET_free (tmp);
268 GNUNET_asprintf (&tmp, 265 GNUNET_asprintf (&tmp,
269 "%s%.*s.", 266 "%s%.*s.",
270 ret, 267 ret,
271 (int) len, 268 (int) len,
272 &udp_payload[*off + 1]); 269 &udp_payload[*off + 1]);
273 } 270 }
274 else 271 else
275 { 272 {
276 GNUNET_free (tmp); 273 GNUNET_free (tmp);
277 GNUNET_asprintf (&tmp, 274 GNUNET_asprintf (&tmp, "%s%s.", ret, utf8);
278 "%s%s.",
279 ret,
280 utf8);
281#if WINDOWS 275#if WINDOWS
282 idn_free (utf8); 276 idn_free (utf8);
283#else 277#else
284 free (utf8); 278 free (utf8);
285#endif 279#endif
286 } 280 }
287 GNUNET_free (ret); 281 GNUNET_free (ret);
288 ret = tmp; 282 ret = tmp;
289 *off += 1 + len; 283 *off += 1 + len;
290 } 284 }
291 else if ((64 | 128) == (len & (64 | 128)) ) 285 else if ((64 | 128) == (len & (64 | 128)))
292 { 286 {
293 if (depth > 32) 287 if (depth > 32)
294 { 288 {
295 GNUNET_break_op (0); 289 GNUNET_break_op (0);
296 goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */ 290 goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */
297 } 291 }
298 /* pointer to string */ 292 /* pointer to string */
299 if (*off + 1 > udp_payload_length) 293 if (*off + 1 > udp_payload_length)
300 { 294 {
301 GNUNET_break_op (0); 295 GNUNET_break_op (0);
302 goto error; 296 goto error;
303 } 297 }
304 xoff = ((len - (64 | 128)) << 8) + input[*off+1]; 298 xoff = ((len - (64 | 128)) << 8) + input[*off + 1];
305 xstr = parse_name (udp_payload, 299 xstr = parse_name (udp_payload, udp_payload_length, &xoff, depth + 1);
306 udp_payload_length,
307 &xoff,
308 depth + 1);
309 if (NULL == xstr) 300 if (NULL == xstr)
310 { 301 {
311 GNUNET_break_op (0); 302 GNUNET_break_op (0);
312 goto error; 303 goto error;
313 } 304 }
314 GNUNET_asprintf (&tmp, 305 GNUNET_asprintf (&tmp, "%s%s.", ret, xstr);
315 "%s%s.",
316 ret,
317 xstr);
318 GNUNET_free (ret); 306 GNUNET_free (ret);
319 GNUNET_free (xstr); 307 GNUNET_free (xstr);
320 ret = tmp; 308 ret = tmp;
321 if (strlen (ret) > udp_payload_length) 309 if (strlen (ret) > udp_payload_length)
322 { 310 {
323 GNUNET_break_op (0); 311 GNUNET_break_op (0);
324 goto error; /* we are looping (building an infinite string) */ 312 goto error; /* we are looping (building an infinite string) */
325 } 313 }
326 *off += 2; 314 *off += 2;
327 /* pointers always terminate names */ 315 /* pointers always terminate names */
@@ -334,10 +322,10 @@ parse_name (const char *udp_payload,
334 goto error; 322 goto error;
335 } 323 }
336 } 324 }
337 if (0 < strlen(ret)) 325 if (0 < strlen (ret))
338 ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */ 326 ret[strlen (ret) - 1] = '\0'; /* eat tailing '.' */
339 return ret; 327 return ret;
340 error: 328error:
341 GNUNET_break_op (0); 329 GNUNET_break_op (0);
342 GNUNET_free (ret); 330 GNUNET_free (ret);
343 return NULL; 331 return NULL;
@@ -355,8 +343,8 @@ parse_name (const char *udp_payload,
355 */ 343 */
356char * 344char *
357GNUNET_DNSPARSER_parse_name (const char *udp_payload, 345GNUNET_DNSPARSER_parse_name (const char *udp_payload,
358 size_t udp_payload_length, 346 size_t udp_payload_length,
359 size_t *off) 347 size_t *off)
360{ 348{
361 return parse_name (udp_payload, udp_payload_length, off, 0); 349 return parse_name (udp_payload, udp_payload_length, off, 0);
362} 350}
@@ -374,16 +362,14 @@ GNUNET_DNSPARSER_parse_name (const char *udp_payload,
374 */ 362 */
375int 363int
376GNUNET_DNSPARSER_parse_query (const char *udp_payload, 364GNUNET_DNSPARSER_parse_query (const char *udp_payload,
377 size_t udp_payload_length, 365 size_t udp_payload_length,
378 size_t *off, 366 size_t *off,
379 struct GNUNET_DNSPARSER_Query *q) 367 struct GNUNET_DNSPARSER_Query *q)
380{ 368{
381 char *name; 369 char *name;
382 struct GNUNET_TUN_DnsQueryLine ql; 370 struct GNUNET_TUN_DnsQueryLine ql;
383 371
384 name = GNUNET_DNSPARSER_parse_name (udp_payload, 372 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
385 udp_payload_length,
386 off);
387 if (NULL == name) 373 if (NULL == name)
388 { 374 {
389 GNUNET_break_op (0); 375 GNUNET_break_op (0);
@@ -414,8 +400,8 @@ GNUNET_DNSPARSER_parse_query (const char *udp_payload,
414 */ 400 */
415struct GNUNET_DNSPARSER_SoaRecord * 401struct GNUNET_DNSPARSER_SoaRecord *
416GNUNET_DNSPARSER_parse_soa (const char *udp_payload, 402GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
417 size_t udp_payload_length, 403 size_t udp_payload_length,
418 size_t *off) 404 size_t *off)
419{ 405{
420 struct GNUNET_DNSPARSER_SoaRecord *soa; 406 struct GNUNET_DNSPARSER_SoaRecord *soa;
421 struct GNUNET_TUN_DnsSoaRecord soa_bin; 407 struct GNUNET_TUN_DnsSoaRecord soa_bin;
@@ -423,15 +409,12 @@ GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
423 409
424 old_off = *off; 410 old_off = *off;
425 soa = GNUNET_new (struct GNUNET_DNSPARSER_SoaRecord); 411 soa = GNUNET_new (struct GNUNET_DNSPARSER_SoaRecord);
426 soa->mname = GNUNET_DNSPARSER_parse_name (udp_payload, 412 soa->mname =
427 udp_payload_length, 413 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
428 off); 414 soa->rname =
429 soa->rname = GNUNET_DNSPARSER_parse_name (udp_payload, 415 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
430 udp_payload_length, 416 if ((NULL == soa->mname) || (NULL == soa->rname) ||
431 off); 417 (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length))
432 if ( (NULL == soa->mname) ||
433 (NULL == soa->rname) ||
434 (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > udp_payload_length) )
435 { 418 {
436 GNUNET_break_op (0); 419 GNUNET_break_op (0);
437 GNUNET_DNSPARSER_free_soa (soa); 420 GNUNET_DNSPARSER_free_soa (soa);
@@ -439,8 +422,8 @@ GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
439 return NULL; 422 return NULL;
440 } 423 }
441 GNUNET_memcpy (&soa_bin, 424 GNUNET_memcpy (&soa_bin,
442 &udp_payload[*off], 425 &udp_payload[*off],
443 sizeof (struct GNUNET_TUN_DnsSoaRecord)); 426 sizeof (struct GNUNET_TUN_DnsSoaRecord));
444 soa->serial = ntohl (soa_bin.serial); 427 soa->serial = ntohl (soa_bin.serial);
445 soa->refresh = ntohl (soa_bin.refresh); 428 soa->refresh = ntohl (soa_bin.refresh);
446 soa->retry = ntohl (soa_bin.retry); 429 soa->retry = ntohl (soa_bin.retry);
@@ -462,8 +445,8 @@ GNUNET_DNSPARSER_parse_soa (const char *udp_payload,
462 */ 445 */
463struct GNUNET_DNSPARSER_MxRecord * 446struct GNUNET_DNSPARSER_MxRecord *
464GNUNET_DNSPARSER_parse_mx (const char *udp_payload, 447GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
465 size_t udp_payload_length, 448 size_t udp_payload_length,
466 size_t *off) 449 size_t *off)
467{ 450{
468 struct GNUNET_DNSPARSER_MxRecord *mx; 451 struct GNUNET_DNSPARSER_MxRecord *mx;
469 uint16_t mxpref; 452 uint16_t mxpref;
@@ -479,9 +462,8 @@ GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
479 (*off) += sizeof (uint16_t); 462 (*off) += sizeof (uint16_t);
480 mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord); 463 mx = GNUNET_new (struct GNUNET_DNSPARSER_MxRecord);
481 mx->preference = ntohs (mxpref); 464 mx->preference = ntohs (mxpref);
482 mx->mxhost = GNUNET_DNSPARSER_parse_name (udp_payload, 465 mx->mxhost =
483 udp_payload_length, 466 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
484 off);
485 if (NULL == mx->mxhost) 467 if (NULL == mx->mxhost)
486 { 468 {
487 GNUNET_break_op (0); 469 GNUNET_break_op (0);
@@ -504,8 +486,8 @@ GNUNET_DNSPARSER_parse_mx (const char *udp_payload,
504 */ 486 */
505struct GNUNET_DNSPARSER_SrvRecord * 487struct GNUNET_DNSPARSER_SrvRecord *
506GNUNET_DNSPARSER_parse_srv (const char *udp_payload, 488GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
507 size_t udp_payload_length, 489 size_t udp_payload_length,
508 size_t *off) 490 size_t *off)
509{ 491{
510 struct GNUNET_DNSPARSER_SrvRecord *srv; 492 struct GNUNET_DNSPARSER_SrvRecord *srv;
511 struct GNUNET_TUN_DnsSrvRecord srv_bin; 493 struct GNUNET_TUN_DnsSrvRecord srv_bin;
@@ -515,16 +497,15 @@ GNUNET_DNSPARSER_parse_srv (const char *udp_payload,
515 if (*off + sizeof (struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length) 497 if (*off + sizeof (struct GNUNET_TUN_DnsSrvRecord) > udp_payload_length)
516 return NULL; 498 return NULL;
517 GNUNET_memcpy (&srv_bin, 499 GNUNET_memcpy (&srv_bin,
518 &udp_payload[*off], 500 &udp_payload[*off],
519 sizeof (struct GNUNET_TUN_DnsSrvRecord)); 501 sizeof (struct GNUNET_TUN_DnsSrvRecord));
520 (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord); 502 (*off) += sizeof (struct GNUNET_TUN_DnsSrvRecord);
521 srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord); 503 srv = GNUNET_new (struct GNUNET_DNSPARSER_SrvRecord);
522 srv->priority = ntohs (srv_bin.prio); 504 srv->priority = ntohs (srv_bin.prio);
523 srv->weight = ntohs (srv_bin.weight); 505 srv->weight = ntohs (srv_bin.weight);
524 srv->port = ntohs (srv_bin.port); 506 srv->port = ntohs (srv_bin.port);
525 srv->target = GNUNET_DNSPARSER_parse_name (udp_payload, 507 srv->target =
526 udp_payload_length, 508 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
527 off);
528 if (NULL == srv->target) 509 if (NULL == srv->target)
529 { 510 {
530 GNUNET_DNSPARSER_free_srv (srv); 511 GNUNET_DNSPARSER_free_srv (srv);
@@ -558,8 +539,8 @@ GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
558 return NULL; 539 return NULL;
559 } 540 }
560 GNUNET_memcpy (&dcert, 541 GNUNET_memcpy (&dcert,
561 &udp_payload[*off], 542 &udp_payload[*off],
562 sizeof (struct GNUNET_TUN_DnsCertRecord)); 543 sizeof (struct GNUNET_TUN_DnsCertRecord));
563 (*off) += sizeof (struct GNUNET_TUN_DnsCertRecord); 544 (*off) += sizeof (struct GNUNET_TUN_DnsCertRecord);
564 cert = GNUNET_new (struct GNUNET_DNSPARSER_CertRecord); 545 cert = GNUNET_new (struct GNUNET_DNSPARSER_CertRecord);
565 cert->cert_type = ntohs (dcert.cert_type); 546 cert->cert_type = ntohs (dcert.cert_type);
@@ -568,8 +549,8 @@ GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
568 cert->certificate_size = udp_payload_length - (*off); 549 cert->certificate_size = udp_payload_length - (*off);
569 cert->certificate_data = GNUNET_malloc (cert->certificate_size); 550 cert->certificate_data = GNUNET_malloc (cert->certificate_size);
570 GNUNET_memcpy (cert->certificate_data, 551 GNUNET_memcpy (cert->certificate_data,
571 &udp_payload[*off], 552 &udp_payload[*off],
572 cert->certificate_size); 553 cert->certificate_size);
573 (*off) += cert->certificate_size; 554 (*off) += cert->certificate_size;
574 return cert; 555 return cert;
575} 556}
@@ -587,18 +568,16 @@ GNUNET_DNSPARSER_parse_cert (const char *udp_payload,
587 */ 568 */
588int 569int
589GNUNET_DNSPARSER_parse_record (const char *udp_payload, 570GNUNET_DNSPARSER_parse_record (const char *udp_payload,
590 size_t udp_payload_length, 571 size_t udp_payload_length,
591 size_t *off, 572 size_t *off,
592 struct GNUNET_DNSPARSER_Record *r) 573 struct GNUNET_DNSPARSER_Record *r)
593{ 574{
594 char *name; 575 char *name;
595 struct GNUNET_TUN_DnsRecordLine rl; 576 struct GNUNET_TUN_DnsRecordLine rl;
596 size_t old_off; 577 size_t old_off;
597 uint16_t data_len; 578 uint16_t data_len;
598 579
599 name = GNUNET_DNSPARSER_parse_name (udp_payload, 580 name = GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
600 udp_payload_length,
601 off);
602 if (NULL == name) 581 if (NULL == name)
603 { 582 {
604 GNUNET_break_op (0); 583 GNUNET_break_op (0);
@@ -614,8 +593,8 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
614 (*off) += sizeof (rl); 593 (*off) += sizeof (rl);
615 r->type = ntohs (rl.type); 594 r->type = ntohs (rl.type);
616 r->dns_traffic_class = ntohs (rl.dns_traffic_class); 595 r->dns_traffic_class = ntohs (rl.dns_traffic_class);
617 r->expiration_time = GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 596 r->expiration_time = GNUNET_TIME_relative_to_absolute (
618 ntohl (rl.ttl))); 597 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, ntohl (rl.ttl)));
619 data_len = ntohs (rl.data_len); 598 data_len = ntohs (rl.data_len);
620 if (*off + data_len > udp_payload_length) 599 if (*off + data_len > udp_payload_length)
621 { 600 {
@@ -629,41 +608,33 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
629 case GNUNET_DNSPARSER_TYPE_CNAME: 608 case GNUNET_DNSPARSER_TYPE_CNAME:
630 case GNUNET_DNSPARSER_TYPE_DNAME: 609 case GNUNET_DNSPARSER_TYPE_DNAME:
631 case GNUNET_DNSPARSER_TYPE_PTR: 610 case GNUNET_DNSPARSER_TYPE_PTR:
632 r->data.hostname = GNUNET_DNSPARSER_parse_name (udp_payload, 611 r->data.hostname =
633 udp_payload_length, 612 GNUNET_DNSPARSER_parse_name (udp_payload, udp_payload_length, off);
634 off); 613 if ((NULL == r->data.hostname) || (old_off + data_len != *off))
635 if ( (NULL == r->data.hostname) ||
636 (old_off + data_len != *off) )
637 return GNUNET_SYSERR; 614 return GNUNET_SYSERR;
638 return GNUNET_OK; 615 return GNUNET_OK;
639 case GNUNET_DNSPARSER_TYPE_SOA: 616 case GNUNET_DNSPARSER_TYPE_SOA:
640 r->data.soa = GNUNET_DNSPARSER_parse_soa (udp_payload, 617 r->data.soa =
641 udp_payload_length, 618 GNUNET_DNSPARSER_parse_soa (udp_payload, udp_payload_length, off);
642 off); 619 if ((NULL == r->data.soa) || (old_off + data_len != *off))
643 if ( (NULL == r->data.soa) ||
644 (old_off + data_len != *off) )
645 { 620 {
646 GNUNET_break_op (0); 621 GNUNET_break_op (0);
647 return GNUNET_SYSERR; 622 return GNUNET_SYSERR;
648 } 623 }
649 return GNUNET_OK; 624 return GNUNET_OK;
650 case GNUNET_DNSPARSER_TYPE_MX: 625 case GNUNET_DNSPARSER_TYPE_MX:
651 r->data.mx = GNUNET_DNSPARSER_parse_mx (udp_payload, 626 r->data.mx =
652 udp_payload_length, 627 GNUNET_DNSPARSER_parse_mx (udp_payload, udp_payload_length, off);
653 off); 628 if ((NULL == r->data.mx) || (old_off + data_len != *off))
654 if ( (NULL == r->data.mx) ||
655 (old_off + data_len != *off) )
656 { 629 {
657 GNUNET_break_op (0); 630 GNUNET_break_op (0);
658 return GNUNET_SYSERR; 631 return GNUNET_SYSERR;
659 } 632 }
660 return GNUNET_OK; 633 return GNUNET_OK;
661 case GNUNET_DNSPARSER_TYPE_SRV: 634 case GNUNET_DNSPARSER_TYPE_SRV:
662 r->data.srv = GNUNET_DNSPARSER_parse_srv (udp_payload, 635 r->data.srv =
663 udp_payload_length, 636 GNUNET_DNSPARSER_parse_srv (udp_payload, udp_payload_length, off);
664 off); 637 if ((NULL == r->data.srv) || (old_off + data_len != *off))
665 if ( (NULL == r->data.srv) ||
666 (old_off + data_len != *off) )
667 { 638 {
668 GNUNET_break_op (0); 639 GNUNET_break_op (0);
669 return GNUNET_SYSERR; 640 return GNUNET_SYSERR;
@@ -672,9 +643,7 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
672 default: 643 default:
673 r->data.raw.data = GNUNET_malloc (data_len); 644 r->data.raw.data = GNUNET_malloc (data_len);
674 r->data.raw.data_len = data_len; 645 r->data.raw.data_len = data_len;
675 GNUNET_memcpy (r->data.raw.data, 646 GNUNET_memcpy (r->data.raw.data, &udp_payload[*off], data_len);
676 &udp_payload[*off],
677 data_len);
678 break; 647 break;
679 } 648 }
680 (*off) += data_len; 649 (*off) += data_len;
@@ -691,8 +660,7 @@ GNUNET_DNSPARSER_parse_record (const char *udp_payload,
691 * @return NULL on error, otherwise the parsed packet 660 * @return NULL on error, otherwise the parsed packet
692 */ 661 */
693struct GNUNET_DNSPARSER_Packet * 662struct GNUNET_DNSPARSER_Packet *
694GNUNET_DNSPARSER_parse (const char *udp_payload, 663GNUNET_DNSPARSER_parse (const char *udp_payload, size_t udp_payload_length)
695 size_t udp_payload_length)
696{ 664{
697 struct GNUNET_DNSPARSER_Packet *p; 665 struct GNUNET_DNSPARSER_Packet *p;
698 const struct GNUNET_TUN_DnsHeader *dns; 666 const struct GNUNET_TUN_DnsHeader *dns;
@@ -709,63 +677,57 @@ GNUNET_DNSPARSER_parse (const char *udp_payload,
709 n = ntohs (dns->query_count); 677 n = ntohs (dns->query_count);
710 if (n > 0) 678 if (n > 0)
711 { 679 {
712 p->queries = GNUNET_new_array (n, 680 p->queries = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Query);
713 struct GNUNET_DNSPARSER_Query);
714 p->num_queries = n; 681 p->num_queries = n;
715 for (unsigned int i=0;i<n;i++) 682 for (unsigned int i = 0; i < n; i++)
716 if (GNUNET_OK != 683 if (GNUNET_OK != GNUNET_DNSPARSER_parse_query (udp_payload,
717 GNUNET_DNSPARSER_parse_query (udp_payload, 684 udp_payload_length,
718 udp_payload_length, 685 &off,
719 &off, 686 &p->queries[i]))
720 &p->queries[i])) 687 goto error;
721 goto error;
722 } 688 }
723 n = ntohs (dns->answer_rcount); 689 n = ntohs (dns->answer_rcount);
724 if (n > 0) 690 if (n > 0)
725 { 691 {
726 p->answers = GNUNET_new_array (n, 692 p->answers = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
727 struct GNUNET_DNSPARSER_Record);
728 p->num_answers = n; 693 p->num_answers = n;
729 for (unsigned int i=0;i<n;i++) 694 for (unsigned int i = 0; i < n; i++)
730 if (GNUNET_OK != 695 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
731 GNUNET_DNSPARSER_parse_record (udp_payload, 696 udp_payload_length,
732 udp_payload_length, 697 &off,
733 &off, 698 &p->answers[i]))
734 &p->answers[i])) 699 goto error;
735 goto error;
736 } 700 }
737 n = ntohs (dns->authority_rcount); 701 n = ntohs (dns->authority_rcount);
738 if (n > 0) 702 if (n > 0)
739 { 703 {
740 p->authority_records = GNUNET_new_array (n, 704 p->authority_records = GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
741 struct GNUNET_DNSPARSER_Record);
742 p->num_authority_records = n; 705 p->num_authority_records = n;
743 for (unsigned int i=0;i<n;i++) 706 for (unsigned int i = 0; i < n; i++)
744 if (GNUNET_OK != 707 if (GNUNET_OK != GNUNET_DNSPARSER_parse_record (udp_payload,
745 GNUNET_DNSPARSER_parse_record (udp_payload, 708 udp_payload_length,
746 udp_payload_length, 709 &off,
747 &off, 710 &p->authority_records[i]))
748 &p->authority_records[i])) 711 goto error;
749 goto error;
750 } 712 }
751 n = ntohs (dns->additional_rcount); 713 n = ntohs (dns->additional_rcount);
752 if (n > 0) 714 if (n > 0)
753 { 715 {
754 p->additional_records = GNUNET_new_array (n, 716 p->additional_records =
755 struct GNUNET_DNSPARSER_Record); 717 GNUNET_new_array (n, struct GNUNET_DNSPARSER_Record);
756 p->num_additional_records = n; 718 p->num_additional_records = n;
757 for (unsigned int i=0;i<n;i++) 719 for (unsigned int i = 0; i < n; i++)
758 { 720 {
759 if (GNUNET_OK != 721 if (GNUNET_OK !=
760 GNUNET_DNSPARSER_parse_record (udp_payload, 722 GNUNET_DNSPARSER_parse_record (udp_payload,
761 udp_payload_length, 723 udp_payload_length,
762 &off, 724 &off,
763 &p->additional_records[i])) 725 &p->additional_records[i]))
764 goto error; 726 goto error;
765 } 727 }
766 } 728 }
767 return p; 729 return p;
768 error: 730error:
769 GNUNET_break_op (0); 731 GNUNET_break_op (0);
770 GNUNET_DNSPARSER_free_packet (p); 732 GNUNET_DNSPARSER_free_packet (p);
771 return NULL; 733 return NULL;
@@ -786,38 +748,31 @@ GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r)
786 dup->name = GNUNET_strdup (r->name); 748 dup->name = GNUNET_strdup (r->name);
787 switch (r->type) 749 switch (r->type)
788 { 750 {
789 case GNUNET_DNSPARSER_TYPE_NS: 751 case GNUNET_DNSPARSER_TYPE_NS:
790 case GNUNET_DNSPARSER_TYPE_CNAME: 752 case GNUNET_DNSPARSER_TYPE_CNAME:
791 case GNUNET_DNSPARSER_TYPE_PTR: 753 case GNUNET_DNSPARSER_TYPE_PTR: {
792 { 754 dup->data.hostname = GNUNET_strdup (r->data.hostname);
793 dup->data.hostname = GNUNET_strdup (r->data.hostname); 755 break;
794 break; 756 }
795 } 757 case GNUNET_DNSPARSER_TYPE_SOA: {
796 case GNUNET_DNSPARSER_TYPE_SOA: 758 dup->data.soa = GNUNET_DNSPARSER_duplicate_soa_record (r->data.soa);
797 { 759 break;
798 dup->data.soa = GNUNET_DNSPARSER_duplicate_soa_record (r->data.soa); 760 }
799 break; 761 case GNUNET_DNSPARSER_TYPE_CERT: {
800 } 762 dup->data.cert = GNUNET_DNSPARSER_duplicate_cert_record (r->data.cert);
801 case GNUNET_DNSPARSER_TYPE_CERT: 763 break;
802 { 764 }
803 dup->data.cert = GNUNET_DNSPARSER_duplicate_cert_record (r->data.cert); 765 case GNUNET_DNSPARSER_TYPE_MX: {
804 break; 766 dup->data.mx = GNUNET_DNSPARSER_duplicate_mx_record (r->data.mx);
805 } 767 break;
806 case GNUNET_DNSPARSER_TYPE_MX: 768 }
807 { 769 case GNUNET_DNSPARSER_TYPE_SRV: {
808 dup->data.mx = GNUNET_DNSPARSER_duplicate_mx_record (r->data.mx); 770 dup->data.srv = GNUNET_DNSPARSER_duplicate_srv_record (r->data.srv);
809 break; 771 break;
810 } 772 }
811 case GNUNET_DNSPARSER_TYPE_SRV: 773 default: {
812 { 774 dup->data.raw.data = GNUNET_memdup (r->data.raw.data, r->data.raw.data_len);
813 dup->data.srv = GNUNET_DNSPARSER_duplicate_srv_record (r->data.srv); 775 }
814 break;
815 }
816 default:
817 {
818 dup->data.raw.data = GNUNET_memdup (r->data.raw.data,
819 r->data.raw.data_len);
820 }
821 } 776 }
822 return dup; 777 return dup;
823} 778}
@@ -830,7 +785,8 @@ GNUNET_DNSPARSER_duplicate_record (const struct GNUNET_DNSPARSER_Record *r)
830 * @return the newly allocated record 785 * @return the newly allocated record
831 */ 786 */
832struct GNUNET_DNSPARSER_SoaRecord * 787struct GNUNET_DNSPARSER_SoaRecord *
833GNUNET_DNSPARSER_duplicate_soa_record (const struct GNUNET_DNSPARSER_SoaRecord *r) 788GNUNET_DNSPARSER_duplicate_soa_record (
789 const struct GNUNET_DNSPARSER_SoaRecord *r)
834{ 790{
835 struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof (*r)); 791 struct GNUNET_DNSPARSER_SoaRecord *dup = GNUNET_memdup (r, sizeof (*r));
836 792
@@ -847,7 +803,8 @@ GNUNET_DNSPARSER_duplicate_soa_record (const struct GNUNET_DNSPARSER_SoaRecord *
847 * @return the newly allocated record 803 * @return the newly allocated record
848 */ 804 */
849struct GNUNET_DNSPARSER_CertRecord * 805struct GNUNET_DNSPARSER_CertRecord *
850GNUNET_DNSPARSER_duplicate_cert_record (const struct GNUNET_DNSPARSER_CertRecord *r) 806GNUNET_DNSPARSER_duplicate_cert_record (
807 const struct GNUNET_DNSPARSER_CertRecord *r)
851{ 808{
852 struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof (*r)); 809 struct GNUNET_DNSPARSER_CertRecord *dup = GNUNET_memdup (r, sizeof (*r));
853 810
@@ -879,7 +836,8 @@ GNUNET_DNSPARSER_duplicate_mx_record (const struct GNUNET_DNSPARSER_MxRecord *r)
879 * @return the newly allocated record 836 * @return the newly allocated record
880 */ 837 */
881struct GNUNET_DNSPARSER_SrvRecord * 838struct GNUNET_DNSPARSER_SrvRecord *
882GNUNET_DNSPARSER_duplicate_srv_record (const struct GNUNET_DNSPARSER_SrvRecord *r) 839GNUNET_DNSPARSER_duplicate_srv_record (
840 const struct GNUNET_DNSPARSER_SrvRecord *r)
883{ 841{
884 struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof (*r)); 842 struct GNUNET_DNSPARSER_SrvRecord *dup = GNUNET_memdup (r, sizeof (*r));
885 843
@@ -896,16 +854,16 @@ GNUNET_DNSPARSER_duplicate_srv_record (const struct GNUNET_DNSPARSER_SrvRecord *
896void 854void
897GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p) 855GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p)
898{ 856{
899 for (unsigned int i=0;i<p->num_queries;i++) 857 for (unsigned int i = 0; i < p->num_queries; i++)
900 GNUNET_free_non_null (p->queries[i].name); 858 GNUNET_free_non_null (p->queries[i].name);
901 GNUNET_free_non_null (p->queries); 859 GNUNET_free_non_null (p->queries);
902 for (unsigned int i=0;i<p->num_answers;i++) 860 for (unsigned int i = 0; i < p->num_answers; i++)
903 GNUNET_DNSPARSER_free_record (&p->answers[i]); 861 GNUNET_DNSPARSER_free_record (&p->answers[i]);
904 GNUNET_free_non_null (p->answers); 862 GNUNET_free_non_null (p->answers);
905 for (unsigned int i=0;i<p->num_authority_records;i++) 863 for (unsigned int i = 0; i < p->num_authority_records; i++)
906 GNUNET_DNSPARSER_free_record (&p->authority_records[i]); 864 GNUNET_DNSPARSER_free_record (&p->authority_records[i]);
907 GNUNET_free_non_null (p->authority_records); 865 GNUNET_free_non_null (p->authority_records);
908 for (unsigned int i=0;i<p->num_additional_records;i++) 866 for (unsigned int i = 0; i < p->num_additional_records; i++)
909 GNUNET_DNSPARSER_free_record (&p->additional_records[i]); 867 GNUNET_DNSPARSER_free_record (&p->additional_records[i]);
910 GNUNET_free_non_null (p->additional_records); 868 GNUNET_free_non_null (p->additional_records);
911 GNUNET_free (p); 869 GNUNET_free (p);
@@ -930,9 +888,9 @@ GNUNET_DNSPARSER_free_packet (struct GNUNET_DNSPARSER_Packet *p)
930 */ 888 */
931int 889int
932GNUNET_DNSPARSER_builder_add_name (char *dst, 890GNUNET_DNSPARSER_builder_add_name (char *dst,
933 size_t dst_len, 891 size_t dst_len,
934 size_t *off, 892 size_t *off,
935 const char *name) 893 const char *name)
936{ 894{
937 const char *dot; 895 const char *dot;
938 const char *idna_name; 896 const char *idna_name;
@@ -946,14 +904,13 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
946 return GNUNET_SYSERR; 904 return GNUNET_SYSERR;
947 905
948 if (IDNA_SUCCESS != 906 if (IDNA_SUCCESS !=
949 (rc = idna_to_ascii_8z (name, 907 (rc = idna_to_ascii_8z (name, &idna_start, IDNA_ALLOW_UNASSIGNED)))
950 &idna_start,
951 IDNA_ALLOW_UNASSIGNED)))
952 { 908 {
953 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 909 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
954 _("Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"), 910 _ (
955 name, 911 "Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"),
956 idna_strerror (rc)); 912 name,
913 idna_strerror (rc));
957 return GNUNET_NO; 914 return GNUNET_NO;
958 } 915 }
959 idna_name = idna_start; 916 idna_name = idna_start;
@@ -968,7 +925,7 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
968 len = strlen (idna_name); 925 len = strlen (idna_name);
969 else 926 else
970 len = dot - idna_name; 927 len = dot - idna_name;
971 if ( (len >= 64) || (0 == len) ) 928 if ((len >= 64) || (0 == len))
972 { 929 {
973 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 930 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
974 "Invalid DNS name `%s': label with %u characters encountered\n", 931 "Invalid DNS name `%s': label with %u characters encountered\n",
@@ -977,13 +934,10 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
977 goto fail; /* label too long or empty */ 934 goto fail; /* label too long or empty */
978 } 935 }
979 dst[pos++] = (char) (uint8_t) len; 936 dst[pos++] = (char) (uint8_t) len;
980 GNUNET_memcpy (&dst[pos], 937 GNUNET_memcpy (&dst[pos], idna_name, len);
981 idna_name,
982 len);
983 pos += len; 938 pos += len;
984 idna_name += len + 1; /* also skip dot */ 939 idna_name += len + 1; /* also skip dot */
985 } 940 } while (NULL != dot);
986 while (NULL != dot);
987 dst[pos++] = '\0'; /* terminator */ 941 dst[pos++] = '\0'; /* terminator */
988 *off = pos; 942 *off = pos;
989#if WINDOWS 943#if WINDOWS
@@ -992,7 +946,7 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
992 free (idna_start); 946 free (idna_start);
993#endif 947#endif
994 return GNUNET_OK; 948 return GNUNET_OK;
995 fail: 949fail:
996#if WINDOWS 950#if WINDOWS
997 idn_free (idna_start); 951 idn_free (idna_start);
998#else 952#else
@@ -1016,14 +970,19 @@ GNUNET_DNSPARSER_builder_add_name (char *dst,
1016 */ 970 */
1017int 971int
1018GNUNET_DNSPARSER_builder_add_query (char *dst, 972GNUNET_DNSPARSER_builder_add_query (char *dst,
1019 size_t dst_len, 973 size_t dst_len,
1020 size_t *off, 974 size_t *off,
1021 const struct GNUNET_DNSPARSER_Query *query) 975 const struct GNUNET_DNSPARSER_Query *query)
1022{ 976{
1023 int ret; 977 int ret;
1024 struct GNUNET_TUN_DnsQueryLine ql; 978 struct GNUNET_TUN_DnsQueryLine ql;
1025 979
1026 ret = GNUNET_DNSPARSER_builder_add_name (dst, dst_len - sizeof (struct GNUNET_TUN_DnsQueryLine), off, query->name); 980 ret = GNUNET_DNSPARSER_builder_add_name (dst,
981 dst_len -
982 sizeof (
983 struct GNUNET_TUN_DnsQueryLine),
984 off,
985 query->name);
1027 if (ret != GNUNET_OK) 986 if (ret != GNUNET_OK)
1028 return ret; 987 return ret;
1029 ql.type = htons (query->type); 988 ql.type = htons (query->type);
@@ -1048,23 +1007,18 @@ GNUNET_DNSPARSER_builder_add_query (char *dst,
1048 */ 1007 */
1049int 1008int
1050GNUNET_DNSPARSER_builder_add_mx (char *dst, 1009GNUNET_DNSPARSER_builder_add_mx (char *dst,
1051 size_t dst_len, 1010 size_t dst_len,
1052 size_t *off, 1011 size_t *off,
1053 const struct GNUNET_DNSPARSER_MxRecord *mx) 1012 const struct GNUNET_DNSPARSER_MxRecord *mx)
1054{ 1013{
1055 uint16_t mxpref; 1014 uint16_t mxpref;
1056 1015
1057 if (*off + sizeof (uint16_t) > dst_len) 1016 if (*off + sizeof (uint16_t) > dst_len)
1058 return GNUNET_NO; 1017 return GNUNET_NO;
1059 mxpref = htons (mx->preference); 1018 mxpref = htons (mx->preference);
1060 GNUNET_memcpy (&dst[*off], 1019 GNUNET_memcpy (&dst[*off], &mxpref, sizeof (mxpref));
1061 &mxpref,
1062 sizeof (mxpref));
1063 (*off) += sizeof (mxpref); 1020 (*off) += sizeof (mxpref);
1064 return GNUNET_DNSPARSER_builder_add_name (dst, 1021 return GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, mx->mxhost);
1065 dst_len,
1066 off,
1067 mx->mxhost);
1068} 1022}
1069 1023
1070 1024
@@ -1081,10 +1035,11 @@ GNUNET_DNSPARSER_builder_add_mx (char *dst,
1081 * #GNUNET_OK if @a cert was added to @a dst 1035 * #GNUNET_OK if @a cert was added to @a dst
1082 */ 1036 */
1083int 1037int
1084GNUNET_DNSPARSER_builder_add_cert (char *dst, 1038GNUNET_DNSPARSER_builder_add_cert (
1085 size_t dst_len, 1039 char *dst,
1086 size_t *off, 1040 size_t dst_len,
1087 const struct GNUNET_DNSPARSER_CertRecord *cert) 1041 size_t *off,
1042 const struct GNUNET_DNSPARSER_CertRecord *cert)
1088{ 1043{
1089 struct GNUNET_TUN_DnsCertRecord dcert; 1044 struct GNUNET_TUN_DnsCertRecord dcert;
1090 1045
@@ -1092,8 +1047,7 @@ GNUNET_DNSPARSER_builder_add_cert (char *dst,
1092#pragma clang diagnostic push 1047#pragma clang diagnostic push
1093#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" 1048#pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
1094#endif 1049#endif
1095 if ( (cert->cert_type > UINT16_MAX) || 1050 if ((cert->cert_type > UINT16_MAX) || (cert->algorithm > UINT8_MAX))
1096 (cert->algorithm > UINT8_MAX) )
1097 { 1051 {
1098 GNUNET_break (0); 1052 GNUNET_break (0);
1099 return GNUNET_SYSERR; 1053 return GNUNET_SYSERR;
@@ -1101,7 +1055,8 @@ GNUNET_DNSPARSER_builder_add_cert (char *dst,
1101#ifdef __clang__ 1055#ifdef __clang__
1102#pragma clang diagnostic pop 1056#pragma clang diagnostic pop
1103#endif 1057#endif
1104 if (*off + sizeof (struct GNUNET_TUN_DnsCertRecord) + cert->certificate_size > dst_len) 1058 if (*off + sizeof (struct GNUNET_TUN_DnsCertRecord) + cert->certificate_size >
1059 dst_len)
1105 return GNUNET_NO; 1060 return GNUNET_NO;
1106 dcert.cert_type = htons ((uint16_t) cert->cert_type); 1061 dcert.cert_type = htons ((uint16_t) cert->cert_type);
1107 dcert.cert_tag = htons ((uint16_t) cert->cert_tag); 1062 dcert.cert_tag = htons ((uint16_t) cert->cert_tag);
@@ -1128,21 +1083,19 @@ GNUNET_DNSPARSER_builder_add_cert (char *dst,
1128 */ 1083 */
1129int 1084int
1130GNUNET_DNSPARSER_builder_add_soa (char *dst, 1085GNUNET_DNSPARSER_builder_add_soa (char *dst,
1131 size_t dst_len, 1086 size_t dst_len,
1132 size_t *off, 1087 size_t *off,
1133 const struct GNUNET_DNSPARSER_SoaRecord *soa) 1088 const struct GNUNET_DNSPARSER_SoaRecord *soa)
1134{ 1089{
1135 struct GNUNET_TUN_DnsSoaRecord sd; 1090 struct GNUNET_TUN_DnsSoaRecord sd;
1136 int ret; 1091 int ret;
1137 1092
1138 if ( (GNUNET_OK != (ret = GNUNET_DNSPARSER_builder_add_name (dst, 1093 if ((GNUNET_OK !=
1139 dst_len, 1094 (ret =
1140 off, 1095 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->mname))) ||
1141 soa->mname))) || 1096 (GNUNET_OK !=
1142 (GNUNET_OK != (ret = GNUNET_DNSPARSER_builder_add_name (dst, 1097 (ret =
1143 dst_len, 1098 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, soa->rname))))
1144 off,
1145 soa->rname)) ) )
1146 return ret; 1099 return ret;
1147 if (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > dst_len) 1100 if (*off + sizeof (struct GNUNET_TUN_DnsSoaRecord) > dst_len)
1148 return GNUNET_NO; 1101 return GNUNET_NO;
@@ -1171,9 +1124,9 @@ GNUNET_DNSPARSER_builder_add_soa (char *dst,
1171 */ 1124 */
1172int 1125int
1173GNUNET_DNSPARSER_builder_add_srv (char *dst, 1126GNUNET_DNSPARSER_builder_add_srv (char *dst,
1174 size_t dst_len, 1127 size_t dst_len,
1175 size_t *off, 1128 size_t *off,
1176 const struct GNUNET_DNSPARSER_SrvRecord *srv) 1129 const struct GNUNET_DNSPARSER_SrvRecord *srv)
1177{ 1130{
1178 struct GNUNET_TUN_DnsSrvRecord sd; 1131 struct GNUNET_TUN_DnsSrvRecord sd;
1179 int ret; 1132 int ret;
@@ -1183,14 +1136,11 @@ GNUNET_DNSPARSER_builder_add_srv (char *dst,
1183 sd.prio = htons (srv->priority); 1136 sd.prio = htons (srv->priority);
1184 sd.weight = htons (srv->weight); 1137 sd.weight = htons (srv->weight);
1185 sd.port = htons (srv->port); 1138 sd.port = htons (srv->port);
1186 GNUNET_memcpy (&dst[*off], 1139 GNUNET_memcpy (&dst[*off], &sd, sizeof (sd));
1187 &sd,
1188 sizeof (sd));
1189 (*off) += sizeof (sd); 1140 (*off) += sizeof (sd);
1190 if (GNUNET_OK != (ret = GNUNET_DNSPARSER_builder_add_name (dst, 1141 if (GNUNET_OK !=
1191 dst_len, 1142 (ret =
1192 off, 1143 GNUNET_DNSPARSER_builder_add_name (dst, dst_len, off, srv->target)))
1193 srv->target)))
1194 return ret; 1144 return ret;
1195 return GNUNET_OK; 1145 return GNUNET_OK;
1196} 1146}
@@ -1210,9 +1160,9 @@ GNUNET_DNSPARSER_builder_add_srv (char *dst,
1210 */ 1160 */
1211static int 1161static int
1212add_record (char *dst, 1162add_record (char *dst,
1213 size_t dst_len, 1163 size_t dst_len,
1214 size_t *off, 1164 size_t *off,
1215 const struct GNUNET_DNSPARSER_Record *record) 1165 const struct GNUNET_DNSPARSER_Record *record)
1216{ 1166{
1217 int ret; 1167 int ret;
1218 size_t start; 1168 size_t start;
@@ -1221,7 +1171,9 @@ add_record (char *dst,
1221 1171
1222 start = *off; 1172 start = *off;
1223 ret = GNUNET_DNSPARSER_builder_add_name (dst, 1173 ret = GNUNET_DNSPARSER_builder_add_name (dst,
1224 dst_len - sizeof (struct GNUNET_TUN_DnsRecordLine), 1174 dst_len -
1175 sizeof (
1176 struct GNUNET_TUN_DnsRecordLine),
1225 off, 1177 off,
1226 record->name); 1178 record->name);
1227 if (GNUNET_OK != ret) 1179 if (GNUNET_OK != ret)
@@ -1232,36 +1184,27 @@ add_record (char *dst,
1232 switch (record->type) 1184 switch (record->type)
1233 { 1185 {
1234 case GNUNET_DNSPARSER_TYPE_MX: 1186 case GNUNET_DNSPARSER_TYPE_MX:
1235 ret = GNUNET_DNSPARSER_builder_add_mx (dst, 1187 ret = GNUNET_DNSPARSER_builder_add_mx (dst, dst_len, &pos, record->data.mx);
1236 dst_len,
1237 &pos,
1238 record->data.mx);
1239 break; 1188 break;
1240 case GNUNET_DNSPARSER_TYPE_CERT: 1189 case GNUNET_DNSPARSER_TYPE_CERT:
1241 ret = GNUNET_DNSPARSER_builder_add_cert (dst, 1190 ret =
1242 dst_len, 1191 GNUNET_DNSPARSER_builder_add_cert (dst, dst_len, &pos, record->data.cert);
1243 &pos,
1244 record->data.cert);
1245 break; 1192 break;
1246 case GNUNET_DNSPARSER_TYPE_SOA: 1193 case GNUNET_DNSPARSER_TYPE_SOA:
1247 ret = GNUNET_DNSPARSER_builder_add_soa (dst, 1194 ret =
1248 dst_len, 1195 GNUNET_DNSPARSER_builder_add_soa (dst, dst_len, &pos, record->data.soa);
1249 &pos,
1250 record->data.soa);
1251 break; 1196 break;
1252 case GNUNET_DNSPARSER_TYPE_NS: 1197 case GNUNET_DNSPARSER_TYPE_NS:
1253 case GNUNET_DNSPARSER_TYPE_CNAME: 1198 case GNUNET_DNSPARSER_TYPE_CNAME:
1254 case GNUNET_DNSPARSER_TYPE_PTR: 1199 case GNUNET_DNSPARSER_TYPE_PTR:
1255 ret = GNUNET_DNSPARSER_builder_add_name (dst, 1200 ret = GNUNET_DNSPARSER_builder_add_name (dst,
1256 dst_len, 1201 dst_len,
1257 &pos, 1202 &pos,
1258 record->data.hostname); 1203 record->data.hostname);
1259 break; 1204 break;
1260 case GNUNET_DNSPARSER_TYPE_SRV: 1205 case GNUNET_DNSPARSER_TYPE_SRV:
1261 ret = GNUNET_DNSPARSER_builder_add_srv (dst, 1206 ret =
1262 dst_len, 1207 GNUNET_DNSPARSER_builder_add_srv (dst, dst_len, &pos, record->data.srv);
1263 &pos,
1264 record->data.srv);
1265 break; 1208 break;
1266 default: 1209 default:
1267 if (pos + record->data.raw.data_len > dst_len) 1210 if (pos + record->data.raw.data_len > dst_len)
@@ -1269,9 +1212,7 @@ add_record (char *dst,
1269 ret = GNUNET_NO; 1212 ret = GNUNET_NO;
1270 break; 1213 break;
1271 } 1214 }
1272 GNUNET_memcpy (&dst[pos], 1215 GNUNET_memcpy (&dst[pos], record->data.raw.data, record->data.raw.data_len);
1273 record->data.raw.data,
1274 record->data.raw.data_len);
1275 pos += record->data.raw.data_len; 1216 pos += record->data.raw.data_len;
1276 ret = GNUNET_OK; 1217 ret = GNUNET_OK;
1277 break; 1218 break;
@@ -1290,11 +1231,12 @@ add_record (char *dst,
1290 } 1231 }
1291 rl.type = htons (record->type); 1232 rl.type = htons (record->type);
1292 rl.dns_traffic_class = htons (record->dns_traffic_class); 1233 rl.dns_traffic_class = htons (record->dns_traffic_class);
1293 rl.ttl = htonl (GNUNET_TIME_absolute_get_remaining (record->expiration_time).rel_value_us / 1000LL / 1000LL); /* in seconds */ 1234 rl.ttl = htonl (
1294 rl.data_len = htons ((uint16_t) (pos - (*off + sizeof (struct GNUNET_TUN_DnsRecordLine)))); 1235 GNUNET_TIME_absolute_get_remaining (record->expiration_time).rel_value_us /
1295 GNUNET_memcpy (&dst[*off], 1236 1000LL / 1000LL); /* in seconds */
1296 &rl, 1237 rl.data_len = htons (
1297 sizeof (struct GNUNET_TUN_DnsRecordLine)); 1238 (uint16_t) (pos - (*off + sizeof (struct GNUNET_TUN_DnsRecordLine))));
1239 GNUNET_memcpy (&dst[*off], &rl, sizeof (struct GNUNET_TUN_DnsRecordLine));
1298 *off = pos; 1240 *off = pos;
1299 return GNUNET_OK; 1241 return GNUNET_OK;
1300} 1242}
@@ -1316,9 +1258,9 @@ add_record (char *dst,
1316 */ 1258 */
1317int 1259int
1318GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p, 1260GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
1319 uint16_t max, 1261 uint16_t max,
1320 char **buf, 1262 char **buf,
1321 size_t *buf_length) 1263 size_t *buf_length)
1322{ 1264{
1323 struct GNUNET_TUN_DnsHeader dns; 1265 struct GNUNET_TUN_DnsHeader dns;
1324 size_t off; 1266 size_t off;
@@ -1326,10 +1268,9 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
1326 int ret; 1268 int ret;
1327 int trc; 1269 int trc;
1328 1270
1329 if ( (p->num_queries > UINT16_MAX) || 1271 if ((p->num_queries > UINT16_MAX) || (p->num_answers > UINT16_MAX) ||
1330 (p->num_answers > UINT16_MAX) || 1272 (p->num_authority_records > UINT16_MAX) ||
1331 (p->num_authority_records > UINT16_MAX) || 1273 (p->num_additional_records > UINT16_MAX))
1332 (p->num_additional_records > UINT16_MAX) )
1333 return GNUNET_SYSERR; 1274 return GNUNET_SYSERR;
1334 dns.id = p->id; 1275 dns.id = p->id;
1335 dns.flags = p->flags; 1276 dns.flags = p->flags;
@@ -1340,62 +1281,53 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
1340 1281
1341 off = sizeof (struct GNUNET_TUN_DnsHeader); 1282 off = sizeof (struct GNUNET_TUN_DnsHeader);
1342 trc = GNUNET_NO; 1283 trc = GNUNET_NO;
1343 for (unsigned int i=0;i<p->num_queries;i++) 1284 for (unsigned int i = 0; i < p->num_queries; i++)
1344 { 1285 {
1345 ret = GNUNET_DNSPARSER_builder_add_query (tmp, 1286 ret = GNUNET_DNSPARSER_builder_add_query (tmp,
1346 sizeof (tmp), 1287 sizeof (tmp),
1347 &off, 1288 &off,
1348 &p->queries[i]); 1289 &p->queries[i]);
1349 if (GNUNET_SYSERR == ret) 1290 if (GNUNET_SYSERR == ret)
1350 return GNUNET_SYSERR; 1291 return GNUNET_SYSERR;
1351 if (GNUNET_NO == ret) 1292 if (GNUNET_NO == ret)
1352 { 1293 {
1353 dns.query_count = htons ((uint16_t) (i-1)); 1294 dns.query_count = htons ((uint16_t) (i - 1));
1354 trc = GNUNET_YES; 1295 trc = GNUNET_YES;
1355 break; 1296 break;
1356 } 1297 }
1357 } 1298 }
1358 for (unsigned int i=0;i<p->num_answers;i++) 1299 for (unsigned int i = 0; i < p->num_answers; i++)
1359 { 1300 {
1360 ret = add_record (tmp, 1301 ret = add_record (tmp, sizeof (tmp), &off, &p->answers[i]);
1361 sizeof (tmp),
1362 &off,
1363 &p->answers[i]);
1364 if (GNUNET_SYSERR == ret) 1302 if (GNUNET_SYSERR == ret)
1365 return GNUNET_SYSERR; 1303 return GNUNET_SYSERR;
1366 if (GNUNET_NO == ret) 1304 if (GNUNET_NO == ret)
1367 { 1305 {
1368 dns.answer_rcount = htons ((uint16_t) (i-1)); 1306 dns.answer_rcount = htons ((uint16_t) (i - 1));
1369 trc = GNUNET_YES; 1307 trc = GNUNET_YES;
1370 break; 1308 break;
1371 } 1309 }
1372 } 1310 }
1373 for (unsigned int i=0;i<p->num_authority_records;i++) 1311 for (unsigned int i = 0; i < p->num_authority_records; i++)
1374 { 1312 {
1375 ret = add_record (tmp, 1313 ret = add_record (tmp, sizeof (tmp), &off, &p->authority_records[i]);
1376 sizeof (tmp),
1377 &off,
1378 &p->authority_records[i]);
1379 if (GNUNET_SYSERR == ret) 1314 if (GNUNET_SYSERR == ret)
1380 return GNUNET_SYSERR; 1315 return GNUNET_SYSERR;
1381 if (GNUNET_NO == ret) 1316 if (GNUNET_NO == ret)
1382 { 1317 {
1383 dns.authority_rcount = htons ((uint16_t) (i-1)); 1318 dns.authority_rcount = htons ((uint16_t) (i - 1));
1384 trc = GNUNET_YES; 1319 trc = GNUNET_YES;
1385 break; 1320 break;
1386 } 1321 }
1387 } 1322 }
1388 for (unsigned int i=0;i<p->num_additional_records;i++) 1323 for (unsigned int i = 0; i < p->num_additional_records; i++)
1389 { 1324 {
1390 ret = add_record (tmp, 1325 ret = add_record (tmp, sizeof (tmp), &off, &p->additional_records[i]);
1391 sizeof (tmp),
1392 &off,
1393 &p->additional_records[i]);
1394 if (GNUNET_SYSERR == ret) 1326 if (GNUNET_SYSERR == ret)
1395 return GNUNET_SYSERR; 1327 return GNUNET_SYSERR;
1396 if (GNUNET_NO == ret) 1328 if (GNUNET_NO == ret)
1397 { 1329 {
1398 dns.additional_rcount = htons (i-1); 1330 dns.additional_rcount = htons (i - 1);
1399 trc = GNUNET_YES; 1331 trc = GNUNET_YES;
1400 break; 1332 break;
1401 } 1333 }
@@ -1403,15 +1335,11 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
1403 1335
1404 if (GNUNET_YES == trc) 1336 if (GNUNET_YES == trc)
1405 dns.flags.message_truncated = 1; 1337 dns.flags.message_truncated = 1;
1406 GNUNET_memcpy (tmp, 1338 GNUNET_memcpy (tmp, &dns, sizeof (struct GNUNET_TUN_DnsHeader));
1407 &dns,
1408 sizeof (struct GNUNET_TUN_DnsHeader));
1409 1339
1410 *buf = GNUNET_malloc (off); 1340 *buf = GNUNET_malloc (off);
1411 *buf_length = off; 1341 *buf_length = off;
1412 GNUNET_memcpy (*buf, 1342 GNUNET_memcpy (*buf, tmp, off);
1413 tmp,
1414 off);
1415 if (GNUNET_YES == trc) 1343 if (GNUNET_YES == trc)
1416 return GNUNET_NO; 1344 return GNUNET_NO;
1417 return GNUNET_OK; 1345 return GNUNET_OK;
@@ -1426,8 +1354,7 @@ GNUNET_DNSPARSER_pack (const struct GNUNET_DNSPARSER_Packet *p,
1426 * @return HEX string (lower case) 1354 * @return HEX string (lower case)
1427 */ 1355 */
1428char * 1356char *
1429GNUNET_DNSPARSER_bin_to_hex (const void *data, 1357GNUNET_DNSPARSER_bin_to_hex (const void *data, size_t data_size)
1430 size_t data_size)
1431{ 1358{
1432 char *ret; 1359 char *ret;
1433 size_t off; 1360 size_t off;
@@ -1436,9 +1363,7 @@ GNUNET_DNSPARSER_bin_to_hex (const void *data,
1436 idata = data; 1363 idata = data;
1437 ret = GNUNET_malloc (data_size * 2 + 1); 1364 ret = GNUNET_malloc (data_size * 2 + 1);
1438 for (off = 0; off < data_size; off++) 1365 for (off = 0; off < data_size; off++)
1439 sprintf (&ret[off * 2], 1366 sprintf (&ret[off * 2], "%02x", idata[off]);
1440 "%02x",
1441 idata[off]);
1442 return ret; 1367 return ret;
1443} 1368}
1444 1369
@@ -1452,8 +1377,7 @@ GNUNET_DNSPARSER_bin_to_hex (const void *data,
1452 * @return number of bytes written to data 1377 * @return number of bytes written to data
1453 */ 1378 */
1454size_t 1379size_t
1455GNUNET_DNSPARSER_hex_to_bin (const char *hex, 1380GNUNET_DNSPARSER_hex_to_bin (const char *hex, void *data)
1456 void *data)
1457{ 1381{
1458 size_t data_size; 1382 size_t data_size;
1459 size_t off; 1383 size_t off;