diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-10-18 09:43:08 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-10-18 09:43:08 +0000 |
commit | e2df1bd810956194018d233f1029207838c92946 (patch) | |
tree | 2546aace2e34b310a07bb07e4009f6a0d613e98d /src/dns | |
parent | 188988276482b3795b89da6c3814cefb4234abc6 (diff) | |
download | gnunet-e2df1bd810956194018d233f1029207838c92946.tar.gz gnunet-e2df1bd810956194018d233f1029207838c92946.zip |
-implementing #2475
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/dnsparser.c | 74 |
1 files changed, 64 insertions, 10 deletions
diff --git a/src/dns/dnsparser.c b/src/dns/dnsparser.c index c61c78164..8578e7572 100644 --- a/src/dns/dnsparser.c +++ b/src/dns/dnsparser.c | |||
@@ -81,6 +81,8 @@ parse_name (const char *udp_payload, | |||
81 | char *xstr; | 81 | char *xstr; |
82 | uint8_t len; | 82 | uint8_t len; |
83 | size_t xoff; | 83 | size_t xoff; |
84 | char *utf8; | ||
85 | Idna_rc rc; | ||
84 | 86 | ||
85 | ret = GNUNET_strdup (""); | 87 | ret = GNUNET_strdup (""); |
86 | while (1) | 88 | while (1) |
@@ -98,10 +100,36 @@ parse_name (const char *udp_payload, | |||
98 | if (*off + 1 + len > udp_payload_length) | 100 | if (*off + 1 + len > udp_payload_length) |
99 | goto error; | 101 | goto error; |
100 | GNUNET_asprintf (&tmp, | 102 | GNUNET_asprintf (&tmp, |
101 | "%s%.*s.", | 103 | "%.*s", |
102 | ret, | ||
103 | (int) len, | 104 | (int) len, |
104 | &udp_payload[*off + 1]); | 105 | &udp_payload[*off + 1]); |
106 | if (IDNA_SUCCESS != | ||
107 | (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_USE_STD3_ASCII_RULES))) | ||
108 | { | ||
109 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
110 | _("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"), | ||
111 | tmp, | ||
112 | idna_strerror (rc)); | ||
113 | GNUNET_free (tmp); | ||
114 | GNUNET_asprintf (&tmp, | ||
115 | "%s%.*s.", | ||
116 | ret, | ||
117 | (int) len, | ||
118 | &udp_payload[*off + 1]); | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | GNUNET_free (tmp); | ||
123 | GNUNET_asprintf (&tmp, | ||
124 | "%s%s.", | ||
125 | ret, | ||
126 | utf8); | ||
127 | #if WINDOWS | ||
128 | idn_free (utf8); | ||
129 | #else | ||
130 | free (utf8); | ||
131 | #endif | ||
132 | } | ||
105 | GNUNET_free (ret); | 133 | GNUNET_free (ret); |
106 | ret = tmp; | 134 | ret = tmp; |
107 | *off += 1 + len; | 135 | *off += 1 + len; |
@@ -539,34 +567,60 @@ add_name (char *dst, | |||
539 | const char *name) | 567 | const char *name) |
540 | { | 568 | { |
541 | const char *dot; | 569 | const char *dot; |
570 | const char *idna_name; | ||
571 | char *idna_start; | ||
542 | size_t start; | 572 | size_t start; |
543 | size_t pos; | 573 | size_t pos; |
544 | size_t len; | 574 | size_t len; |
575 | Idna_rc rc; | ||
545 | 576 | ||
546 | if (NULL == name) | 577 | if (NULL == name) |
547 | return GNUNET_SYSERR; | 578 | return GNUNET_SYSERR; |
548 | start = *off; | 579 | |
549 | if (start + strlen (name) + 2 > dst_len) | 580 | if (IDNA_SUCCESS != |
581 | (rc = idna_to_ascii_8z (name, &idna_start, IDNA_USE_STD3_ASCII_RULES))) | ||
582 | { | ||
583 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
584 | _("Failed to convert UTF-8 name `%s' to DNS IDNA format: %s\n"), | ||
585 | name, | ||
586 | idna_strerror (rc)); | ||
550 | return GNUNET_NO; | 587 | return GNUNET_NO; |
588 | } | ||
589 | idna_name = idna_start; | ||
590 | start = *off; | ||
591 | if (start + strlen (idna_name) + 2 > dst_len) | ||
592 | goto fail; | ||
551 | pos = start; | 593 | pos = start; |
552 | do | 594 | do |
553 | { | 595 | { |
554 | dot = strchr (name, '.'); | 596 | dot = strchr (idna_name, '.'); |
555 | if (NULL == dot) | 597 | if (NULL == dot) |
556 | len = strlen (name); | 598 | len = strlen (idna_name); |
557 | else | 599 | else |
558 | len = dot - name; | 600 | len = dot - idna_name; |
559 | if ( (len >= 64) || (len == 0) ) | 601 | if ( (len >= 64) || (len == 0) ) |
560 | return GNUNET_NO; /* segment too long or empty */ | 602 | goto fail; /* segment too long or empty */ |
561 | dst[pos++] = (char) (uint8_t) len; | 603 | dst[pos++] = (char) (uint8_t) len; |
562 | memcpy (&dst[pos], name, len); | 604 | memcpy (&dst[pos], idna_name, len); |
563 | pos += len; | 605 | pos += len; |
564 | name += len + 1; /* also skip dot */ | 606 | idna_name += len + 1; /* also skip dot */ |
565 | } | 607 | } |
566 | while (NULL != dot); | 608 | while (NULL != dot); |
567 | dst[pos++] = '\0'; /* terminator */ | 609 | dst[pos++] = '\0'; /* terminator */ |
568 | *off = pos; | 610 | *off = pos; |
611 | #if WINDOWS | ||
612 | idn_free (idna_start); | ||
613 | #else | ||
614 | free (idna_start); | ||
615 | #endif | ||
569 | return GNUNET_OK; | 616 | return GNUNET_OK; |
617 | fail: | ||
618 | #if WINDOWS | ||
619 | idn_free (idna_start); | ||
620 | #else | ||
621 | free (idna_start); | ||
622 | #endif | ||
623 | return GNUNET_NO; | ||
570 | } | 624 | } |
571 | 625 | ||
572 | 626 | ||