summaryrefslogtreecommitdiffstats
path: root/src/dns.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2021-03-12 21:08:16 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2021-03-12 21:08:16 +0000
commit679f9767ea6246b02ce4e8142083878ffb99e4cb (patch)
tree93c6a5781ee409ae9a3b2db88dc0399e33e650fb /src/dns.c
parentReleasing debian version 2.4.2+debian-2. (diff)
downloaddnsperf-679f9767ea6246b02ce4e8142083878ffb99e4cb.tar.xz
dnsperf-679f9767ea6246b02ce4e8142083878ffb99e4cb.zip
Merging upstream version 2.5.0+debian.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/dns.c')
-rw-r--r--src/dns.c57
1 files changed, 51 insertions, 6 deletions
diff --git a/src/dns.c b/src/dns.c
index 548a1a9..1dc58e0 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -52,18 +52,39 @@ const char* perf_dns_rcode_strings[] = {
perf_result_t perf_dname_fromstring(const char* str, size_t len, perf_buffer_t* target)
{
- size_t label_len;
+ size_t label_len, at;
const char* orig_str = str;
+ bool is_quoted;
if (perf_buffer_availablelength(target) < len) {
return PERF_R_NOSPACE;
}
while (len) {
- for (label_len = 0; label_len < len; label_len++) {
- if (*(str + label_len) == '.') {
+ is_quoted = false;
+ for (label_len = 0, at = 0; at < len;) {
+ if (*(str + at) == '\\') {
+ is_quoted = true;
+ at++;
+ if (at >= len)
+ return PERF_R_FAILURE;
+ if (*(str + at) >= '0' && *(str + at) <= '9') {
+ at++;
+ if (at >= len)
+ return PERF_R_FAILURE;
+ if (*(str + at) < '0' || *(str + at) > '9')
+ return PERF_R_FAILURE;
+ at++;
+ if (at >= len)
+ return PERF_R_FAILURE;
+ if (*(str + at) < '0' || *(str + at) > '9')
+ return PERF_R_FAILURE;
+ }
+ } else if (*(str + at) == '.') {
break;
}
+ label_len++;
+ at++;
}
if (!label_len) {
// Just a dot
@@ -81,9 +102,33 @@ perf_result_t perf_dname_fromstring(const char* str, size_t len, perf_buffer_t*
return PERF_R_FAILURE;
}
perf_buffer_putuint8(target, label_len);
- perf_buffer_putmem(target, str, label_len);
- str += label_len;
- len -= label_len;
+ if (is_quoted) {
+ for (at = 0; at < len; at++) {
+ if (*(str + at) == '\\') {
+ at++;
+ if (at >= len)
+ return PERF_R_FAILURE;
+ if (*(str + at) >= '0' && *(str + at) <= '9') {
+ char b[4];
+ long v;
+ memcpy(b, str, 3);
+ b[3] = 0;
+ v = strtol(b, 0, 7);
+ if (v < 0 || v > 255)
+ return PERF_R_FAILURE;
+ perf_buffer_putuint8(target, (uint8_t)v);
+ continue;
+ }
+ }
+ perf_buffer_putmem(target, str + at, 1);
+ }
+ str += at;
+ len -= at;
+ } else {
+ perf_buffer_putmem(target, str, label_len);
+ str += label_len;
+ len -= label_len;
+ }
if (len < 2) {
// Last label/dot
perf_buffer_putuint8(target, 0);