Add resolv.conf(5) option to force lookups by TCP: "options tcp"
authordjm <djm@openbsd.org>
Fri, 15 Aug 2008 14:57:19 +0000 (14:57 +0000)
committerdjm <djm@openbsd.org>
Fri, 15 Aug 2008 14:57:19 +0000 (14:57 +0000)
Also Extend "nameserver" declaration syntax to support port
numbers.  To avoid ambiguity these are only parsed when the address
is enclosed in square brackets, e.g. "nameserver [127.0.0.1]:5353"

Together these changes make forwarding DNS over a SSH tunnel very
easy, but unfortunately some programs in ports/ implement their
own resolvers (e.g. firefox). These will need to be modified to
support these options separately.

fixes jsing@ reyk@
ok deraadt@ millert@ krw@ + "I like it" from lots

lib/libc/net/res_init.c
share/man/man5/resolv.conf.5

index ebfc5f3..42d3b3c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: res_init.c,v 1.36 2007/08/05 16:11:09 ray Exp $       */
+/*     $OpenBSD: res_init.c,v 1.37 2008/08/15 14:57:20 djm Exp $       */
 
 /*
  * ++Copyright++ 1985, 1989, 1993
@@ -376,18 +376,13 @@ _res_init(int usercall)
                }
                /* read nameservers to query */
                if (MATCH(buf, "nameserver") && nserv < MAXNS) {
-#ifdef INET6
                    char *q;
                    struct addrinfo hints, *res;
                    char pbuf[NI_MAXSERV];
-#else
-                   struct in_addr a;
-#endif /* INET6 */
 
                    cp = buf + sizeof("nameserver") - 1;
                    while (*cp == ' ' || *cp == '\t')
                        cp++;
-#ifdef INET6
                    if ((*cp == '\0') || (*cp == '\n'))
                        continue;
                    for (q = cp; *q; q++) {
@@ -396,10 +391,26 @@ _res_init(int usercall)
                            break;
                        }
                    }
+
+                   /* Handle addresses enclosed in [] */
+                   *pbuf = '\0';
+                   if (*cp == '[') {
+                       cp++;
+                       if ((q = strchr(cp, ']')) == NULL)
+                               continue;
+                       *q++ = '\0';
+                       /* Extract port, if specified */
+                       if (*q++ == ':') {
+                           if (strlcpy(pbuf, q, sizeof(pbuf)) >= sizeof(pbuf))
+                               continue;
+                       }
+                   }
+                   if (*pbuf == '\0')
+                       snprintf(pbuf, sizeof(pbuf), "%u", NAMESERVER_PORT);
+
                    memset(&hints, 0, sizeof(hints));
                    hints.ai_flags = AI_NUMERICHOST;
                    hints.ai_socktype = SOCK_DGRAM;
-                   snprintf(pbuf, sizeof(pbuf), "%u", NAMESERVER_PORT);
                    res = NULL;
                    if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
                            res->ai_next == NULL) {
@@ -421,17 +432,6 @@ _res_init(int usercall)
                    }
                    if (res)
                        freeaddrinfo(res);
-#else /* INET6 */
-                   if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
-                       _resp->nsaddr_list[nserv].sin_addr = a;
-                       _resp->nsaddr_list[nserv].sin_family = AF_INET;
-                       _resp->nsaddr_list[nserv].sin_port =
-                               htons(NAMESERVER_PORT);
-                       _resp->nsaddr_list[nserv].sin_len =
-                               sizeof(struct sockaddr_in);
-                       nserv++;
-                   }
-#endif /* INET6 */
                    continue;
                }
 #ifdef RESOLVSORT
@@ -641,6 +641,8 @@ res_setoptions(char *options, char *source)
                        _resp->options |= RES_INSECURE2;
                } else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
                        _resp->options |= RES_USE_EDNS0;
+               } else if (!strncmp(cp, "tcp", sizeof("tcp") - 1)) {
+                       _resp->options |= RES_USEVC;
                } else {
                        /* XXX - print a warning here? */
                }
index f038fe2..3e8d37e 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: resolv.conf.5,v 1.29 2007/05/31 19:19:58 jmc Exp $
+.\"    $OpenBSD: resolv.conf.5,v 1.30 2008/08/15 14:57:19 djm Exp $
 .\"    $NetBSD: resolv.conf.5,v 1.7 1996/03/06 18:22:16 scottr Exp $
 .\"
 .\" Copyright (c) 1986, 1991 The Regents of the University of California.
@@ -30,7 +30,7 @@
 .\"
 .\"     @(#)resolver.5 5.12 (Berkeley) 5/10/91
 .\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: August 15 2008 $
 .Dt RESOLV.CONF 5
 .Os
 .Sh NAME
@@ -108,6 +108,10 @@ Scoped IPv6 address notation is accepted as well
 (see
 .Xr inet6 4
 for details).
+A non-standard port may be specified using
+.Ar [host]:port
+syntax.
+.Pp
 Up to
 .Dv MAXNS
 (currently 3) name servers may be listed, one per line.
@@ -242,6 +246,9 @@ The default for
 .Ar n
 is 1, meaning that if there are any dots in a name, the name will be tried
 first as an absolute name before any search list elements are appended to it.
+.It Sy tcp
+Forces the use of TCP for queries.
+Normal behaviour is to query via UDP but fall back to TCP on failure.
 .El
 .El
 .Pp