chiark / gitweb /
resolve: add more record types and convert to gperf table
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 1 Aug 2014 23:37:16 +0000 (19:37 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 4 Aug 2014 02:02:32 +0000 (22:02 -0400)
We are unlikely to evert support most of them, but we can at least
display the types properly.

The list is taken from the IANA list.

The table of number->name mappings is converted to a switch
statement. gcc does a nice job of optimizing lookup (when optimization
is enabled).

systemd-resolve-host -t is now case insensitive.

Makefile.am
src/resolve/.gitignore
src/resolve/dns-type.c [new file with mode: 0644]
src/resolve/dns-type.h [new file with mode: 0644]
src/resolve/resolved-dns-rr.c
src/resolve/resolved-dns-rr.h

index 73aa420..45d2e58 100644 (file)
@@ -201,6 +201,7 @@ AM_CPPFLAGS = \
        -I $(top_srcdir)/src/timedate \
        -I $(top_srcdir)/src/timesync \
        -I $(top_srcdir)/src/resolve \
        -I $(top_srcdir)/src/timedate \
        -I $(top_srcdir)/src/timesync \
        -I $(top_srcdir)/src/resolve \
+       -I $(top_builddir)/src/resolve \
        -I $(top_srcdir)/src/systemd \
        -I $(top_builddir)/src/core \
        -I $(top_srcdir)/src/core \
        -I $(top_srcdir)/src/systemd \
        -I $(top_builddir)/src/core \
        -I $(top_srcdir)/src/core \
@@ -1148,19 +1149,23 @@ CLEANFILES += \
        src/shared/errno-list.txt \
        src/shared/errno-from-name.gperf \
        src/shared/af-list.txt \
        src/shared/errno-list.txt \
        src/shared/errno-from-name.gperf \
        src/shared/af-list.txt \
-       src/shared/af-from-name.gperf
+       src/shared/af-from-name.gperf \
+       src/shared/dns_type-list.txt \
+       src/shared/dns_type-from-name.gperf
 
 BUILT_SOURCES += \
        src/shared/errno-from-name.h \
        src/shared/errno-to-name.h \
        src/shared/af-from-name.h \
 
 BUILT_SOURCES += \
        src/shared/errno-from-name.h \
        src/shared/errno-to-name.h \
        src/shared/af-from-name.h \
-       src/shared/af-to-name.h
+       src/shared/af-to-name.h \
+       src/resolve/dns_type-from-name.h \
+       src/resolve/dns_type-to-name.h
 
 
-src/shared/%-from-name.gperf: src/shared/%-list.txt
-       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct $*_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, %s\n", $$1, $$1 }' <$< >$@
+%-from-name.gperf: %-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct $(notdir $*)_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, %s\n", $$1, $$1 }' <$< >$@
 
 
-src/shared/%-from-name.h: src/shared/%-from-name.gperf
-       $(AM_V_GPERF)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_$* -H hash_$*_name -p -C <$< >$@
+%-from-name.h: %-from-name.gperf
+       $(AM_V_GPERF)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_$(notdir $*) -H hash_$(notdir $*)_name -p -C <$< >$@
 
 
 src/shared/errno-list.txt:
 
 
 src/shared/errno-list.txt:
@@ -1178,6 +1183,17 @@ src/shared/af-list.txt:
 src/shared/af-to-name.h: src/shared/af-list.txt
        $(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const af_names[] = { "} !/AF_FILE/ && !/AF_ROUTE/ && !/AF_LOCAL/ { printf "[%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' <$< >$@
 
 src/shared/af-to-name.h: src/shared/af-list.txt
        $(AM_V_GEN)$(AWK) 'BEGIN{ print "static const char* const af_names[] = { "} !/AF_FILE/ && !/AF_ROUTE/ && !/AF_LOCAL/ { printf "[%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' <$< >$@
 
+
+src/resolve/dns_type-list.txt: src/resolve/dns-type.h
+       $(AM_V_at)$(MKDIR_P) $(dir $@)
+       $(AM_V_GEN)$(SED) -n -r 's/.* DNS_TYPE_(\w+).*/\1/p' <$< >$@
+
+src/resolve/dns_type-to-name.h: src/resolve/dns_type-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "const char *dns_type_to_string(uint16_t type) {\n\tswitch(type) {" } {printf "        case DNS_TYPE_%s: return ", $$1; sub(/_/, "-"); printf "\"%s\";\n", $$1 } END{ print "\ndefault: return NULL;\n\t}\n}\n" }' <$< >$@
+
+src/resolve/dns_type-from-name.gperf: src/resolve/dns_type-list.txt
+       $(AM_V_GEN)$(AWK) 'BEGIN{ print "struct dns_type_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { s=$$1; sub(/_/, "-", s); printf "%s, ", $$s; printf "DNS_TYPE_%s\n", $$1 }' <$< >$@
+
 # ------------------------------------------------------------------------------
 systemd_SOURCES = \
        src/core/main.c
 # ------------------------------------------------------------------------------
 systemd_SOURCES = \
        src/core/main.c
@@ -4754,13 +4770,18 @@ systemd_resolved_SOURCES = \
        src/resolve/resolved-dns-zone.h \
        src/resolve/resolved-dns-zone.c \
        src/resolve/resolved-dns-stream.h \
        src/resolve/resolved-dns-zone.h \
        src/resolve/resolved-dns-zone.c \
        src/resolve/resolved-dns-stream.h \
-       src/resolve/resolved-dns-stream.c
+       src/resolve/resolved-dns-stream.c \
+       src/resolve/dns-type.c \
+       src/resolve/dns-type.h \
+       src/resolve/dns_type-from-name.h \
+       src/resolve/dns_type-to-name.h
 
 nodist_systemd_resolved_SOURCES = \
        src/resolve/resolved-gperf.c
 
 EXTRA_DIST += \
 
 nodist_systemd_resolved_SOURCES = \
        src/resolve/resolved-gperf.c
 
 EXTRA_DIST += \
-       src/resolve/resolved-gperf.gperf
+       src/resolve/resolved-gperf.gperf \
+       src/resolve/dns_type-from-name.gperf
 
 CLEANFILES += \
        src/resolve/resolved-gperf.c
 
 CLEANFILES += \
        src/resolve/resolved-gperf.c
@@ -4857,7 +4878,11 @@ systemd_resolve_host_SOURCES = \
        src/resolve/resolved-dns-question.c \
        src/resolve/resolved-dns-question.h \
        src/resolve/resolved-dns-domain.c \
        src/resolve/resolved-dns-question.c \
        src/resolve/resolved-dns-question.h \
        src/resolve/resolved-dns-domain.c \
-       src/resolve/resolved-dns-domain.h
+       src/resolve/resolved-dns-domain.h \
+       src/resolve/dns-type.c \
+       src/resolve/dns-type.h \
+       src/resolve/dns_type-from-name.h \
+       src/resolve/dns_type-to-name.h
 
 systemd_resolve_host_LDADD = \
        libsystemd-internal.la \
 
 systemd_resolve_host_LDADD = \
        libsystemd-internal.la \
index ca3016e..f083592 100644 (file)
@@ -1,2 +1,6 @@
 /resolved-gperf.c
 /resolved.conf
 /resolved-gperf.c
 /resolved.conf
+/dns_type-from-name.gperf
+/dns_type-from-name.h
+/dns_type-list.txt
+/dns_type-to-name.h
diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c
new file mode 100644 (file)
index 0000000..271a7e1
--- /dev/null
@@ -0,0 +1,47 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "dns-type.h"
+
+typedef const struct {
+        uint16_t type;
+        const char *name;
+} dns_type;
+
+static const struct dns_type_name *
+lookup_dns_type (register const char *str, register unsigned int len);
+
+#include "dns_type-from-name.h"
+#include "dns_type-to-name.h"
+
+int dns_type_from_string(const char *s, uint16_t *type) {
+        const struct dns_type_name *sc;
+
+        assert(s);
+        assert(type);
+
+        sc = lookup_dns_type(s, strlen(s));
+        if (!sc)
+                return -EINVAL;
+
+        *type = sc->id;
+        return 0;
+}
diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h
new file mode 100644 (file)
index 0000000..6606315
--- /dev/null
@@ -0,0 +1,122 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#pragma once
+
+#include <inttypes.h>
+
+#include "macro.h"
+
+const char *dns_type_to_string(uint16_t type);
+int dns_type_from_string(const char *s, uint16_t *type);
+
+/* DNS record types, taken from
+ * http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml.
+ */
+enum {
+        /* Normal records */
+        DNS_TYPE_A          = 0x01,
+        DNS_TYPE_NS,
+        DNS_TYPE_MD,
+        DNS_TYPE_MF,
+        DNS_TYPE_CNAME,
+        DNS_TYPE_SOA,
+        DNS_TYPE_MB,
+        DNS_TYPE_MG,
+        DNS_TYPE_MR,
+        DNS_TYPE_NULL,
+        DNS_TYPE_WKS,
+        DNS_TYPE_PTR,
+        DNS_TYPE_HINFO,
+        DNS_TYPE_MINFO,
+        DNS_TYPE_MX,
+        DNS_TYPE_TXT,
+        DNS_TYPE_RP,
+        DNS_TYPE_AFSDB,
+        DNS_TYPE_X25,
+        DNS_TYPE_ISDN,
+        DNS_TYPE_RT,
+        DNS_TYPE_NSAP,
+        DNS_TYPE_NSAP_PTR,
+        DNS_TYPE_SIG,
+        DNS_TYPE_KEY,
+        DNS_TYPE_PX,
+        DNS_TYPE_GPOS,
+        DNS_TYPE_AAAA,
+        DNS_TYPE_LOC,
+        DNS_TYPE_NXT,
+        DNS_TYPE_EID,
+        DNS_TYPE_NIMLOC,
+        DNS_TYPE_SRV,
+        DNS_TYPE_ATMA,
+        DNS_TYPE_NAPTR,
+        DNS_TYPE_KX,
+        DNS_TYPE_CERT,
+        DNS_TYPE_A6,
+        DNS_TYPE_DNAME,
+        DNS_TYPE_SINK,
+        DNS_TYPE_OPT,          /* EDNS0 option */
+        DNS_TYPE_APL,
+        DNS_TYPE_DS,
+        DNS_TYPE_SSHFP,
+        DNS_TYPE_IPSECKEY,
+        DNS_TYPE_RRSIG,
+        DNS_TYPE_NSEC,
+        DNS_TYPE_DNSKEY,
+        DNS_TYPE_DHCID,
+        DNS_TYPE_NSEC3,
+        DNS_TYPE_NSEC3PARAM,
+        DNS_TYPE_TLSA,
+
+        DNS_TYPE_HIP        = 0x37,
+        DNS_TYPE_NINFO,
+        DNS_TYPE_RKEY,
+        DNS_TYPE_TALINK,
+        DNS_TYPE_CDS,
+        DNS_TYPE_CDNSKEY,
+
+        DNS_TYPE_SPF        = 0x63,
+        DNS_TYPE_NID,
+        DNS_TYPE_L32,
+        DNS_TYPE_L64,
+        DNS_TYPE_LP,
+        DNS_TYPE_EUI48,
+        DNS_TYPE_EUI64,
+
+        DNS_TYPE_TKEY       = 0xF9,
+        DNS_TYPE_TSIG,
+        DNS_TYPE_IXFR,
+        DNS_TYPE_AXFR,
+        DNS_TYPE_MAILB,
+        DNS_TYPE_MAILA,
+        DNS_TYPE_ANY,
+        DNS_TYPE_URI,
+        DNS_TYPE_CAA,
+        DNS_TYPE_TA         = 0x8000,
+        DNS_TYPE_DLV,
+
+        _DNS_TYPE_MAX,
+        _DNS_TYPE_INVALID = -1
+};
+
+assert_cc(DNS_TYPE_SSHFP == 44);
+assert_cc(DNS_TYPE_TLSA == 52);
+assert_cc(DNS_TYPE_ANY == 255);
index 7d1cfe4..af22a89 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "resolved-dns-domain.h"
 #include "resolved-dns-rr.h"
 
 #include "resolved-dns-domain.h"
 #include "resolved-dns-rr.h"
+#include "dns-type.h"
 
 DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
         DnsResourceKey *k;
 
 DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
         DnsResourceKey *k;
@@ -627,54 +628,3 @@ int dns_class_from_string(const char *s, uint16_t *class) {
 
         return 0;
 }
 
         return 0;
 }
-
-static const struct {
-        uint16_t type;
-        const char *name;
-} dns_types[] = {
-        { DNS_TYPE_A,     "A"     },
-        { DNS_TYPE_NS,    "NS"    },
-        { DNS_TYPE_CNAME, "CNAME" },
-        { DNS_TYPE_SOA,   "SOA"   },
-        { DNS_TYPE_PTR,   "PTR"   },
-        { DNS_TYPE_HINFO, "HINFO" },
-        { DNS_TYPE_MX,    "MX"    },
-        { DNS_TYPE_TXT,   "TXT"   },
-        { DNS_TYPE_AAAA,  "AAAA"  },
-        { DNS_TYPE_LOC,   "LOC"   },
-        { DNS_TYPE_SRV,   "SRV"   },
-        { DNS_TYPE_SSHFP, "SSHFP" },
-        { DNS_TYPE_SPF,   "SPF"   },
-        { DNS_TYPE_DNAME, "DNAME" },
-        { DNS_TYPE_ANY,   "ANY"   },
-        { DNS_TYPE_OPT,   "OPT"   },
-        { DNS_TYPE_TKEY,  "TKEY"  },
-        { DNS_TYPE_TSIG,  "TSIG"  },
-        { DNS_TYPE_IXFR,  "IXFR"  },
-        { DNS_TYPE_AXFR,  "AXFR"  },
-};
-
-const char *dns_type_to_string(uint16_t type) {
-        unsigned i;
-
-        for (i = 0; i < ELEMENTSOF(dns_types); i++)
-                if (dns_types[i].type == type)
-                        return dns_types[i].name;
-
-        return NULL;
-}
-
-int dns_type_from_string(const char *s, uint16_t *type) {
-        unsigned i;
-
-        assert(s);
-        assert(type);
-
-        for (i = 0; i < ELEMENTSOF(dns_types); i++)
-                if (strcaseeq(dns_types[i].name, s)) {
-                        *type = dns_types[i].type;
-                        return 0;
-                }
-
-        return -EINVAL;
-}
index 61c00d5..20a344b 100644 (file)
@@ -27,6 +27,7 @@
 #include "util.h"
 #include "hashmap.h"
 #include "in-addr-util.h"
 #include "util.h"
 #include "hashmap.h"
 #include "in-addr-util.h"
+#include "dns-type.h"
 
 typedef struct DnsResourceKey DnsResourceKey;
 typedef struct DnsResourceRecord DnsResourceRecord;
 
 typedef struct DnsResourceKey DnsResourceKey;
 typedef struct DnsResourceRecord DnsResourceRecord;
@@ -39,35 +40,6 @@ enum {
         _DNS_CLASS_INVALID = -1
 };
 
         _DNS_CLASS_INVALID = -1
 };
 
-/* DNS record types, see RFC 1035 */
-enum {
-        /* Normal records */
-        DNS_TYPE_A     = 0x01,
-        DNS_TYPE_NS    = 0x02,
-        DNS_TYPE_CNAME = 0x05,
-        DNS_TYPE_SOA   = 0x06,
-        DNS_TYPE_PTR   = 0x0C,
-        DNS_TYPE_HINFO = 0x0D,
-        DNS_TYPE_MX    = 0x0F,
-        DNS_TYPE_TXT   = 0x10,
-        DNS_TYPE_AAAA  = 0x1C,
-        DNS_TYPE_LOC   = 0x1D,
-        DNS_TYPE_SRV   = 0x21,
-        DNS_TYPE_DNAME = 0x27,
-        DNS_TYPE_SSHFP = 0x2C,
-        DNS_TYPE_SPF   = 0x63,
-
-        /* Special records */
-        DNS_TYPE_ANY   = 0xFF,
-        DNS_TYPE_OPT   = 0x29,      /* EDNS0 option */
-        DNS_TYPE_TKEY  = 0xF9,
-        DNS_TYPE_TSIG  = 0xFA,
-        DNS_TYPE_IXFR  = 0xFB,
-        DNS_TYPE_AXFR  = 0xFC,
-        _DNS_TYPE_MAX,
-        _DNS_TYPE_INVALID = -1
-};
-
 struct DnsResourceKey {
         unsigned n_ref;
         uint16_t class, type;
 struct DnsResourceKey {
         unsigned n_ref;
         uint16_t class, type;
@@ -178,8 +150,5 @@ int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecor
 int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret);
 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
 
 int dns_resource_record_to_string(const DnsResourceRecord *rr, char **ret);
 DEFINE_TRIVIAL_CLEANUP_FUNC(DnsResourceRecord*, dns_resource_record_unref);
 
-const char *dns_type_to_string(uint16_t type);
-int dns_type_from_string(const char *name, uint16_t *type);
-
 const char *dns_class_to_string(uint16_t type);
 int dns_class_from_string(const char *name, uint16_t *class);
 const char *dns_class_to_string(uint16_t type);
 int dns_class_from_string(const char *name, uint16_t *class);