diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2020-05-17 18:07:58 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2020-05-17 18:07:58 +0000 |
commit | 91e808f1db0b76f3625f516ec73a95b4e32decb2 (patch) | |
tree | cacbb0f21daa96bffa4a74c8395c82983b185be5 | |
parent | 8e3663ba249b572af9332f2762f29ba514620a27 (diff) | |
download | s6-dns-91e808f1db0b76f3625f516ec73a95b4e32decb2.tar.xz |
Add s6-dnsip, prepare for 2.3.3.0, fix resolvenoq_aaaaa
TODO: resolveq_aaaaa returns the best (1 answer) whereas we
want both ip6 and ip4 when available. It works with noq, it
should work with q too.
-rw-r--r-- | NEWS | 7 | ||||
-rw-r--r-- | doc/index.html | 3 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-resolve.html | 4 | ||||
-rw-r--r-- | doc/s6-dnsip.html | 72 | ||||
-rw-r--r-- | doc/upgrade.html | 6 | ||||
-rw-r--r-- | package/deps.mak | 3 | ||||
-rw-r--r-- | package/info | 2 | ||||
-rw-r--r-- | package/targets.mak | 1 | ||||
-rw-r--r-- | src/clients/deps-exe/s6-dnsip | 4 | ||||
-rw-r--r-- | src/clients/s6-dnsip.c | 67 | ||||
-rw-r--r-- | src/include/s6-dns/s6dns-resolve.h | 2 | ||||
-rw-r--r-- | src/libs6dns/s6dns_resolvenoq_aaaaa.c | 12 | ||||
-rw-r--r-- | src/libs6dns/s6dns_resolveq_aaaaa.c | 12 |
13 files changed, 181 insertions, 14 deletions
@@ -1,5 +1,12 @@ Changelog for s6-dns. +In 2.3.3.0 +---------- + + - Bugfixes. + - New binary: s6-dnsip, returning both v4 and v6 addresses. + + In 2.3.2.0 ---------- diff --git a/doc/index.html b/doc/index.html index 036dca0..4bd7ca3 100644 --- a/doc/index.html +++ b/doc/index.html @@ -60,7 +60,7 @@ requirement if you link against the shared version of the skalibs library. </li> <h3> Download </h3> <ul> - <li> The current released version of s6-dns is <a href="s6-dns-2.3.2.0.tar.gz">2.3.2.0</a>. </li> + <li> The current released version of s6-dns is <a href="s6-dns-2.3.3.0.tar.gz">2.3.3.0</a>. </li> <li> Alternatively, you can checkout a copy of the <a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-dns/">s6-dns git repository</a>: @@ -100,6 +100,7 @@ relevant page. <h4> Command-line DNS clients programs </h4> <ul> +<li><a href="s6-dnsip.html">The <tt>s6-dnsip</tt> program</a></li> <li><a href="s6-dnsip4.html">The <tt>s6-dnsip4</tt> program</a></li> <li><a href="s6-dnsip6.html">The <tt>s6-dnsip6</tt> program</a></li> <li><a href="s6-dnsname.html">The <tt>s6-dnsname</tt> program</a></li> diff --git a/doc/libs6dns/s6dns-resolve.html b/doc/libs6dns/s6dns-resolve.html index 69596f8..5d021aa 100644 --- a/doc/libs6dns/s6dns-resolve.html +++ b/doc/libs6dns/s6dns-resolve.html @@ -191,7 +191,7 @@ Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or a positive number if it succeeds: 1 if IPv4 addresses were found, 2 if IPv6 addresses were found, and 3 if both were found. The IPs are appended to the genalloc *<em>ips</em>, which contains an array of -<tt>ip46_t</tt>, the skalibs structure used to store IPv4 and IPv6 addresses +<tt>ip46full_t</tt>, the skalibs structure used to store IPv4 and IPv6 addresses indiscriminately. </p> @@ -222,7 +222,7 @@ appended to the genalloc *<em>ds</em>, which contains an array of <tt>s6dns_doma </p> <p> -<code> int s6dns_resolve_name46_g (genalloc *ds, ip46_t const *ip, tain_t const *deadline) </code> <br /> +<code> int s6dns_resolve_name46_g (genalloc *ds, ip46full_t const *ip, tain_t const *deadline) </code> <br /> Calls <tt>s6dns_resolve_name6_g()</tt> or <tt>s6dns_resolve_name4_g()</tt> depending on which <em>ip</em> is an IPv6 or IPv4 address. </p> diff --git a/doc/s6-dnsip.html b/doc/s6-dnsip.html new file mode 100644 index 0000000..47c4970 --- /dev/null +++ b/doc/s6-dnsip.html @@ -0,0 +1,72 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsip program</title> + <meta name="Description" content="s6-dns: the s6-dnsip program" /> + <meta name="Keywords" content="s6-dns client s6-dnsip dnsip s6-dnsip6 s6-dnsip4 domain name ip address ipv6 ipv4" /> + <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsip program </h1> + +<p> + s6-dnsip finds both the IPv6 and IPv4 addresses associated to a domain name. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsip [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>domain</em> +</pre> + +<ul> + <li> s6-dnsip makes both an A and an AAAA query for the name <em>domain</em>, +in parallel. It waits for the results and prints the obtained addresses, +one per line, then exits 0. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnsip looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +<h2> Notes </h2> + +<p> +Even if the underlying skalibs has been compiled without IPv6 support, +or IPv6 DNS transport is unavailable for any reason, s6-dnsip will still +return IPv6 addresses if the AAAA query has a positive result. +</p> + +</body> +</html> diff --git a/doc/upgrade.html b/doc/upgrade.html index 3bf4b67..97dde72 100644 --- a/doc/upgrade.html +++ b/doc/upgrade.html @@ -18,6 +18,12 @@ <h1> What has changed in s6-dns </h1> +<h2> in 2.3.3.0 </h2> + +<ul> + <li> New executable: <a href="s6-dnsip.html">s6-dnsip</a>. </li> +</ul> + <h2> in 2.3.2.0 </h2> <ul> diff --git a/package/deps.mak b/package/deps.mak index b10d4b8..9b58f8b 100644 --- a/package/deps.mak +++ b/package/deps.mak @@ -24,6 +24,7 @@ src/caches/shibari_whitelist_add6.o src/caches/shibari_whitelist_add6.lo: src/ca src/caches/shibari_whitelist_ip4_match.o src/caches/shibari_whitelist_ip4_match.lo: src/caches/shibari_whitelist_ip4_match.c src/caches/shibari-internal.h src/caches/shibari_whitelist_ip6_match.o src/caches/shibari_whitelist_ip6_match.lo: src/caches/shibari_whitelist_ip6_match.c src/caches/shibari-internal.h src/caches/shibari_whitelist_read.o src/caches/shibari_whitelist_read.lo: src/caches/shibari_whitelist_read.c src/caches/shibari-internal.h +src/clients/s6-dnsip.o src/clients/s6-dnsip.lo: src/clients/s6-dnsip.c src/include/s6-dns/s6dns.h src/clients/s6-dnsip4-filter.o src/clients/s6-dnsip4-filter.lo: src/clients/s6-dnsip4-filter.c src/include/s6-dns/s6dns-constants.h src/include/s6-dns/s6dns-message.h src/clients/s6dns-generic-filter.h src/clients/s6-dnsip4.o src/clients/s6-dnsip4.lo: src/clients/s6-dnsip4.c src/include/s6-dns/s6dns.h src/clients/s6-dnsip6-filter.o src/clients/s6-dnsip6-filter.lo: src/clients/s6-dnsip6-filter.c src/include/s6-dns/s6dns-constants.h src/include/s6-dns/s6dns-message.h src/clients/s6dns-generic-filter.h @@ -163,6 +164,8 @@ libshibari.so.xyzzy: EXTRA_LIBS := libshibari.so.xyzzy: src/caches/shibari_whitelist_add6.lo src/caches/shibari_whitelist_ip4_match.lo src/caches/shibari_whitelist_ip6_match.lo src/caches/shibari_whitelist_read.lo shibari: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB} shibari: src/caches/shibari.o libshibari.a.xyzzy ${LIBDCACHE} ${LIBS6DNS} +s6-dnsip: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB} +s6-dnsip: src/clients/s6-dnsip.o ${LIBS6DNS} s6-dnsip4: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB} s6-dnsip4: src/clients/s6-dnsip4.o ${LIBS6DNS} s6-dnsip4-filter: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB} ${SPAWN_LIB} diff --git a/package/info b/package/info index 2e264fb..432358a 100644 --- a/package/info +++ b/package/info @@ -1,4 +1,4 @@ package=s6-dns -version=2.3.2.0 +version=2.3.3.0 category=web package_macro_name=S6_DNS diff --git a/package/targets.mak b/package/targets.mak index 9d7a60f..ffab27d 100644 --- a/package/targets.mak +++ b/package/targets.mak @@ -2,6 +2,7 @@ BIN_TARGETS := \ skadnsd \ s6-randomip \ s6-dnsqualify \ +s6-dnsip \ s6-dnsip4 \ s6-dnsip6 \ s6-dnsmx \ diff --git a/src/clients/deps-exe/s6-dnsip b/src/clients/deps-exe/s6-dnsip new file mode 100644 index 0000000..9bc872f --- /dev/null +++ b/src/clients/deps-exe/s6-dnsip @@ -0,0 +1,4 @@ +${LIBS6DNS} +-lskarnet +${SOCKET_LIB} +${SYSCLOCK_LIB} diff --git a/src/clients/s6-dnsip.c b/src/clients/s6-dnsip.c new file mode 100644 index 0000000..f4c1a58 --- /dev/null +++ b/src/clients/s6-dnsip.c @@ -0,0 +1,67 @@ +/* ISC license. */ + +#include <string.h> +#include <errno.h> + +#include <skalibs/types.h> +#include <skalibs/sgetopt.h> +#include <skalibs/strerr2.h> +#include <skalibs/ip46.h> +#include <skalibs/genalloc.h> +#include <skalibs/buffer.h> +#include <skalibs/tai.h> +#include <skalibs/random.h> +#include <s6-dns/s6dns.h> + +#define USAGE "s6-dnsip [ -q ] [ -r ] [ -t timeout ] domain" +#define dieusage() strerr_dieusage(100, USAGE) + +int main (int argc, char const *const *argv) +{ + genalloc ips = GENALLOC_ZERO ; /* ip46full_t */ + tain_t deadline ; + size_t i = 0 ; + unsigned int t = 0 ; + int flagqualify = 0 ; + int flagunsort = 0 ; + PROG = "s6-dnsip" ; + + for (;;) + { + int opt = subgetopt(argc, argv, "qrt:") ; + if (opt == -1) break ; + switch (opt) + { + case 'q' : flagqualify = 1 ; break ; + case 'r' : flagunsort = 1 ; break ; + case 't' : if (!uint0_scan(subgetopt_here.arg, &t)) dieusage() ; break ; + default : dieusage() ; + } + } + argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; + if (argc < 1) dieusage() ; + + tain_now_set_stopwatch_g() ; + if (t) tain_from_millisecs(&deadline, t) ; else deadline = tain_infinite_relative ; + tain_add_g(&deadline, &deadline) ; + if (!s6dns_init()) strerr_diefu1sys(111, "s6dns_init") ; + { + int r = s6dns_resolve_aaaaa_g(&ips, argv[0], strlen(argv[0]), flagqualify, &deadline) ; + if (r < 0) strerr_diefu2sys((errno == ETIMEDOUT) ? 99 : 111, "resolve ", argv[0]) ; + if (!r) strerr_diefu4x(2, "resolve ", argv[0], ": ", s6dns_constants_error_str(errno)) ; + } + if (!genalloc_len(ip46full_t, &ips)) return 1 ; + + if (flagunsort) random_unsort(ips.s, genalloc_len(ip46full_t, &ips), sizeof(ip46full_t)) ; + for (i = 0 ; i < genalloc_len(ip46full_t, &ips) ; i++) + { + char fmt[IP6_FMT] ; + size_t n = ip46full_fmt(fmt, genalloc_s(ip46full_t, &ips) + i) ; + fmt[n++] = '\n' ; + if (buffer_put(buffer_1small, fmt, n) < (ssize_t)n) + strerr_diefu1sys(111, "write to stdout") ; + } + if (!buffer_flush(buffer_1small)) + strerr_diefu1sys(111, "write to stdout") ; + return 0 ; +} diff --git a/src/include/s6-dns/s6dns-resolve.h b/src/include/s6-dns/s6dns-resolve.h index a571103..7369ffd 100644 --- a/src/include/s6-dns/s6dns-resolve.h +++ b/src/include/s6-dns/s6dns-resolve.h @@ -155,7 +155,7 @@ extern int s6dns_resolve_name6_r (genalloc *, char const *, s6dns_engine_t *, s6 #define s6dns_resolve_name46(ds, i, deadline, stamp) s6dns_resolve_name46_r(ds, i, &s6dns_engine_here, &s6dns_rci_here.servers, &s6dns_debughook_zero, deadline, stamp) #define s6dns_resolve_name46_g(ds, i, deadline) s6dns_resolve_name46(ds, i, (deadline), &STAMP) -#define s6dns_resolve_name46_r(ds, i, dt, servers, dbh, deadline, stamp) (ip46_is6(i) ? s6dns_resolve_name6_r(ds, (i)->ip, dt, servers, dbh, deadline, stamp) : s6dns_resolve_name4_r(ds, (i)->ip, dt, servers, dbh, deadline, stamp)) +#define s6dns_resolve_name46_r(ds, i, dt, servers, dbh, deadline, stamp) (ip46full_is6(i) ? s6dns_resolve_name6_r(ds, (i)->ip, dt, servers, dbh, deadline, stamp) : s6dns_resolve_name4_r(ds, (i)->ip, dt, servers, dbh, deadline, stamp)) #define s6dns_resolve_name46_r_g(ds, i, dt, servers, dbh, deadline) s6dns_resolve_name46_r(ds, i, dt, servers, dbh, (deadline), &STAMP) #define s6dns_resolve_txt(sa, offsets, name, len, qualif, deadline, stamp) s6dns_resolve_txt_r(sa, offsets, name, len, qualif, &s6dns_engine_here, &s6dns_rci_here, &s6dns_debughook_zero, deadline, stamp) diff --git a/src/libs6dns/s6dns_resolvenoq_aaaaa.c b/src/libs6dns/s6dns_resolvenoq_aaaaa.c index 734d048..7012594 100644 --- a/src/libs6dns/s6dns_resolvenoq_aaaaa.c +++ b/src/libs6dns/s6dns_resolvenoq_aaaaa.c @@ -26,7 +26,7 @@ int s6dns_resolvenoq_aaaaa_r (genalloc *ips, char const *name, size_t len, s6dns blob[1].data = &sa[1] ; if (!s6dns_resolven_parse_r(blob, 2, servers, dbh, deadline, stamp)) return -1 ; if (blob[0].status && blob[1].status) return (errno = blob[1].status, 0) ; - if (!genalloc_readyplus(ip46_t, ips, (sa[0].len >> 4) + (sa[1].len >> 2))) + if (!genalloc_readyplus(ip46full_t, ips, (sa[0].len >> 4) + (sa[1].len >> 2))) { stralloc_free(&sa[0]) ; stralloc_free(&sa[1]) ; @@ -34,13 +34,15 @@ int s6dns_resolvenoq_aaaaa_r (genalloc *ips, char const *name, size_t len, s6dns } { int e = (!!sa[0].len << 1) | !!sa[1].len ; - size_t n = genalloc_len(ip46_t, ips) ; + size_t n = genalloc_len(ip46full_t, ips) ; size_t i = 0 ; for (; i < (sa[0].len >> 4) ; i++) - ip46_from_ip6(genalloc_s(ip46_t, ips) + n++, sa[0].s + (i << 4)) ; + ip46full_from_ip6(genalloc_s(ip46full_t, ips) + n + i, sa[0].s + (i << 4)) ; + n += i ; for (i = 0 ; i < (sa[1].len >> 2) ; i++) - ip46_from_ip4(genalloc_s(ip46_t, ips) + n++, sa[1].s + (i << 2)) ; - genalloc_setlen(ip46_t, ips, n) ; + ip46full_from_ip4(genalloc_s(ip46full_t, ips) + n + i, sa[1].s + (i << 2)) ; + n += i ; + genalloc_setlen(ip46full_t, ips, n) ; stralloc_free(&sa[0]) ; stralloc_free(&sa[1]) ; return e ; diff --git a/src/libs6dns/s6dns_resolveq_aaaaa.c b/src/libs6dns/s6dns_resolveq_aaaaa.c index 5a0a358..f990a7c 100644 --- a/src/libs6dns/s6dns_resolveq_aaaaa.c +++ b/src/libs6dns/s6dns_resolveq_aaaaa.c @@ -1,16 +1,20 @@ /* ISC license. */ #include <errno.h> + #include <skalibs/error.h> #include <skalibs/stralloc.h> #include <skalibs/genalloc.h> #include <skalibs/ip46.h> + #include <s6-dns/s6dns-constants.h> #include <s6-dns/s6dns-domain.h> #include <s6-dns/s6dns-message.h> #include <s6-dns/s6dns-engine.h> #include <s6-dns/s6dns-resolve.h> +#define d_ip46full_from_ip(i, s, h) ((h) ? ip46full_from_ip6(i, s) : ip46full_from_ip4(i, s)) + int s6dns_resolveq_aaaaa_r (genalloc *ips, char const *name, size_t len, s6dns_rci_t const *rci, s6dns_debughook_t const *dbh, tain_t const *deadline, tain_t *stamp) { s6dns_engine_t dtl[rci->rulesnum << 1] ; @@ -75,11 +79,11 @@ int s6dns_resolveq_aaaaa_r (genalloc *ips, char const *name, size_t len, s6dns_r { size_t len = data.len >> ((best & 1) ? 2 : 4) ; size_t i = 0 ; - size_t base = genalloc_len(ip46_t, ips) ; - if (!genalloc_readyplus(ip46_t, ips, len)) return -1 ; + size_t base = genalloc_len(ip46full_t, ips) ; + if (!genalloc_readyplus(ip46full_t, ips, len)) return -1 ; for (; i < len ; i++) - ip46_from_ip(genalloc_s(ip46_t, ips) + base + i, data.s + (i << ((best & 1) ? 2 : 4)), !(best & 1)) ; - genalloc_setlen(ip46_t, ips, base + len) ; + d_ip46full_from_ip(genalloc_s(ip46full_t, ips) + base + i, data.s + (i << ((best & 1) ? 2 : 4)), !(best & 1)) ; + genalloc_setlen(ip46full_t, ips, base + len) ; } stralloc_free(&data) ; return 1 ; |