4cb46e
commit 0d71523ab58493e1b40e1c80d569ff8ebc5ea27d
4cb46e
Author: David Howells <dhowells@redhat.com>
4cb46e
Date: Wed, 9 May 2018 10:37:03 +0100
4cb46e
4cb46e
    DNS: Support AFS SRV records and cell db config files
4cb46e
4cb46e
    [dhowells: Cut down to only include generic changes as a prereq for the
4cb46e
    next patch]
4cb46e
4cb46e
Signed-off-by: David Howells <dhowells@redhat.com>
4cb46e
---
4cb46e
 key.dns_resolver.c |   47 +++++++++++++++++++++++++++++++----------------
4cb46e
 1 file changed, 31 insertions(+), 16 deletions(-)
4cb46e
4cb46e
4cb46e
diff --git a/key.dns_resolver.c b/key.dns_resolver.c
4cb46e
index 9c9d458..849c8fe 100644
4cb46e
--- a/key.dns_resolver.c
4cb46e
+++ b/key.dns_resolver.c
4cb46e
@@ -74,6 +74,7 @@ static int debug_mode;
4cb46e
 #define	INET_IP6_ONLY		0x2
4cb46e
 #define	INET_ALL		0xFF
4cb46e
 #define ONE_ADDR_ONLY		0x100
4cb46e
+unsigned mask = INET_ALL;
4cb46e
 
4cb46e
 /*
4cb46e
  * segmental payload
4cb46e
@@ -164,14 +165,10 @@ static const int ns_errno_map[] = {
4cb46e
 	[NO_DATA]		= ENODATA,
4cb46e
 };
4cb46e
 
4cb46e
-static __attribute__((noreturn))
4cb46e
-void nsError(int err, const char *domain)
4cb46e
+void _nsError(int err, const char *domain)
4cb46e
 {
4cb46e
-	unsigned timeout = 1 * 60;
4cb46e
-	int ret;
4cb46e
-
4cb46e
 	if (isatty(2))
4cb46e
-		fprintf(stderr, "%s: %s.\n", domain, hstrerror(err));
4cb46e
+		fprintf(stderr, "NS:%s: %s.\n", domain, hstrerror(err));
4cb46e
 	else
4cb46e
 		syslog(LOG_INFO, "%s: %s", domain, hstrerror(err));
4cb46e
 
4cb46e
@@ -181,11 +178,28 @@ void nsError(int err, const char *domain)
4cb46e
 		err = ns_errno_map[err];
4cb46e
 
4cb46e
 	info("Reject the key with error %d", err);
4cb46e
+}
4cb46e
+
4cb46e
+static __attribute__((noreturn))
4cb46e
+void nsError(int err, const char *domain)
4cb46e
+{
4cb46e
+	unsigned timeout;
4cb46e
+	int ret;
4cb46e
+
4cb46e
+	_nsError(err, domain);
4cb46e
 
4cb46e
-	if (err == EAGAIN)
4cb46e
+	switch (err) {
4cb46e
+	case TRY_AGAIN:
4cb46e
 		timeout = 1;
4cb46e
-	else if (err == ECONNREFUSED)
4cb46e
+		break;
4cb46e
+	case 0:
4cb46e
+	case NO_RECOVERY:
4cb46e
 		timeout = 10;
4cb46e
+		break;
4cb46e
+	default:
4cb46e
+		timeout = 1 * 60;
4cb46e
+		break;
4cb46e
+	}
4cb46e
 
4cb46e
 	if (!debug_mode) {
4cb46e
 		ret = keyctl_reject(key, timeout, err, KEY_REQKEY_DEFL_DEFAULT);
4cb46e
@@ -296,10 +310,10 @@ static void dump_payload(void)
4cb46e
  * string to the list of payload segments.
4cb46e
  */
4cb46e
 static int
4cb46e
-dns_resolver(const char *server_name, unsigned mask)
4cb46e
+dns_resolver(const char *server_name, const char *port)
4cb46e
 {
4cb46e
 	struct addrinfo hints, *addr, *ai;
4cb46e
-	char buf[INET6_ADDRSTRLEN + 1];
4cb46e
+	char buf[INET6_ADDRSTRLEN + 8 + 1];
4cb46e
 	int ret, len;
4cb46e
 	void *sa;
4cb46e
 
4cb46e
@@ -320,8 +334,6 @@ dns_resolver(const char *server_name, unsigned mask)
4cb46e
 		return -1;
4cb46e
 	}
4cb46e
 
4cb46e
-	debug("getaddrinfo = %d", ret);
4cb46e
-
4cb46e
 	for (ai = addr; ai; ai = ai->ai_next) {
4cb46e
 		debug("RR: %x,%x,%x,%x,%x,%s",
4cb46e
 		      ai->ai_flags, ai->ai_family,
4cb46e
@@ -350,6 +362,8 @@ dns_resolver(const char *server_name, unsigned mask)
4cb46e
 		if (!inet_ntop(ai->ai_family, sa, buf, len))
4cb46e
 			error("%s: inet_ntop: %m", __func__);
4cb46e
 
4cb46e
+		if (port)
4cb46e
+			strcat(buf, port);
4cb46e
 		append_address_to_payload(buf);
4cb46e
 		if (mask & ONE_ADDR_ONLY)
4cb46e
 			break;
4cb46e
@@ -413,7 +427,7 @@ static void afsdb_hosts_to_addrs(ns_msg handle,
4cb46e
 					goto next_one;
4cb46e
 
4cb46e
 			/* Turn the hostname into IP addresses */
4cb46e
-			ret = dns_resolver(vllist[vlsnum], mask);
4cb46e
+			ret = dns_resolver(vllist[vlsnum], NULL);
4cb46e
 			if (ret) {
4cb46e
 				debug("AFSDB RR can't resolve."
4cb46e
 				      "subtype:%d, server name:%s, netmask:%u",
4cb46e
@@ -523,7 +537,6 @@ int dns_query_afsdb(const char *cell, char *options)
4cb46e
 static __attribute__((noreturn))
4cb46e
 int dns_query_a_or_aaaa(const char *hostname, char *options)
4cb46e
 {
4cb46e
-	unsigned mask;
4cb46e
 	int ret;
4cb46e
 
4cb46e
 	debug("Get A/AAAA RR for hostname:'%s', options:'%s'",
4cb46e
@@ -569,7 +582,7 @@ int dns_query_a_or_aaaa(const char *hostname, char *options)
4cb46e
 	}
4cb46e
 
4cb46e
 	/* Turn the hostname into IP addresses */
4cb46e
-	ret = dns_resolver(hostname, mask);
4cb46e
+	ret = dns_resolver(hostname, NULL);
4cb46e
 	if (ret)
4cb46e
 		nsError(NO_DATA, hostname);
4cb46e
 
4cb46e
@@ -630,7 +643,7 @@ int main(int argc, char *argv[])
4cb46e
 
4cb46e
 	openlog(prog, 0, LOG_DAEMON);
4cb46e
 
4cb46e
-	while ((ret = getopt_long(argc, argv, "vD", long_options, NULL)) != -1) {
4cb46e
+	while ((ret = getopt_long(argc, argv, "vDV", long_options, NULL)) != -1) {
4cb46e
 		switch (ret) {
4cb46e
 		case 'D':
4cb46e
 			debug_mode = 1;
4cb46e
@@ -713,6 +726,8 @@ int main(int argc, char *argv[])
4cb46e
 	qtlen = name - keyend;
4cb46e
 	name++;
4cb46e
 
4cb46e
+	info("Query type: '%*.*s'", qtlen, qtlen, keyend);
4cb46e
+
4cb46e
 	if ((qtlen == sizeof(a_query_type) - 1 &&
4cb46e
 	     memcmp(keyend, a_query_type, sizeof(a_query_type) - 1) == 0) ||
4cb46e
 	    (qtlen == sizeof(aaaa_query_type) - 1 &&