shithub: mc

Download patch

ref: cdca4eaaeaab4c69491633aa7defa2144851b81d
parent: 4ccc52b8ed3c89262a3ee72bfdd05de1a3d0441c
author: Ori Bernstein <[email protected]>
date: Thu Jan 2 21:29:52 EST 2014

Add support for different record types in DNS

--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -21,6 +21,27 @@
 use "utf.use"
 
 pkg std =
+	type rectype = uint16
+
+	const DnsA	: rectype = 1  /* host address */
+	const DnsNS	: rectype = 2  /* authoritative name server */
+	const DnsMD	: rectype = 3  /* mail destination (Obsolete - use MX) */
+	const DnsMF	: rectype = 4  /* mail forwarder (Obsolete - use MX) */
+	const DnsCNAME	: rectype = 5  /* canonical name for an alias */
+	const DnsSOA	: rectype = 6  /* marks the start of a zone of authority */
+	const DnsMB	: rectype = 7  /* mailbox domain name (EXPERIMENTAL) */
+	const DnsMG	: rectype = 8  /* mail group member (EXPERIMENTAL) */
+	const DnsMR	: rectype = 9  /* mail rename domain name (EXPERIMENTAL) */
+	const DnsNULL	: rectype = 10 /* null RR (EXPERIMENTAL) */
+	const DnsWKS	: rectype = 11 /* well known service description */
+	const DnsPTR	: rectype = 12 /* domain name pointer */
+	const DnsHINFO	: rectype = 13 /* host information */
+	const DnsMINFO	: rectype = 14 /* mailbox or mail list information */
+	const DnsMX	: rectype = 15 /* mail exchange */
+	const DnsTXT	: rectype = 16 /* text strings */
+	const DnsAAAA	: rectype = 28 /* ipv6 host address */
+
+
 	type resolveerr = union
 		`Badhost
 		`Badsrv
@@ -34,15 +55,15 @@
 		ttl	: uint32
 		addr	: netaddr
 	/*
-		proto	: uint32
 		flags	: uint32
 		addr	: sockaddr[:]
 		canon	: byte[:]
-		next	: hostinfo#
 	*/
 	;;
 
 	const resolve	: (host : byte[:]	-> error(hostinfo[:], resolveerr))
+	const resolvemx	: (host : byte[:]	-> error(hostinfo[:], resolveerr))
+	const resolverec	: (host : byte[:], t : rectype	-> error(hostinfo[:], resolveerr))
 ;;
 
 const Hostfile = "/etc/hosts"
@@ -54,12 +75,20 @@
 var inited	: bool = false
 
 
-const resolve = {host : byte[:] -> error(hostinfo[:], resolveerr)
+const resolve = {host
+	-> resolverec(host, DnsA)
+}
+
+const resolvemx = {host
+	-> resolverec(host, DnsMX)
+}
+
+const resolverec = {host, t
 	match hostfind(host)
 	| `Some hinf:
 		-> `Success slpush([][:], hinf)
 	| `None:
-		-> dnsresolve(host)
+		-> dnsresolve(host, DnsA)
 	;;
 }
 
@@ -181,8 +210,7 @@
 }
 
 
-const dnsresolve = {host : byte[:]
-	/*var hosts*/
+const dnsresolve = {host, t
 	var nsrv
 
 	if !valid(host)
@@ -191,7 +219,7 @@
 	for ns in nameservers
 		nsrv = dnsconnect(ns)
 		if nsrv >= 0
-			-> dnsquery(nsrv, host)
+			-> dnsquery(nsrv, host, t)
 		;;
 	;;
 	-> `Failure (`Badsrv)
@@ -199,7 +227,7 @@
 
 const dnsconnect = {ns
 	match ns
-	| `Ipv4 addr:	-> dnsconnectv4(ns)
+	| `Ipv4 addr:	-> dnsconnectv4(addr)
 	| `Ipv6 addr:	die("don't support ipv6 yet\n")
 	;;
 }
@@ -213,11 +241,9 @@
 	if s < 0
 		-> -1
 	;;
-	/* hardcode Google DNS for now.
-	FIXME: parse /etc/resolv.conf */
 	sa.fam = Afinet
-	sa.port = hosttonet(53) /* port 53 */
-	sa.addr = [8,8,8,8]	/* 8.8.8.8 */
+	sa.port = hosttonet(53)
+	sa.addr = addr
 	status = connect(s, (&sa) castto(sockaddr#), sizeof(sockaddr_in))
 	if status < 0
 		-> -1
@@ -225,11 +251,11 @@
 	-> s
 }
 
-const dnsquery = {srv, host
+const dnsquery = {srv, host, t
 	var id
 	var r
 
-	id = tquery(srv, host)
+	id = tquery(srv, host, t)
 	r = rquery(srv, id)
 	-> r
 }
@@ -241,7 +267,7 @@
 const Ra : uint16 = 1 << 8
 
 var nextid : uint16 = 42
-const tquery = {srv, host
+const tquery = {srv, host, t
 	var pkt : byte[512] /* big enough */
 	var off : size
 
@@ -256,7 +282,7 @@
 
 	/* query */
 	off += packname(pkt[:], off, host)	/* host */
-	off += pack16(pkt[:], off, 0x1) /* qtype: a record */
+	off += pack16(pkt[:], off, t castto(uint16)) /* qtype: a record */
 	off += pack16(pkt[:], off, 0x1) /* qclass: inet4 */
 
 	write(srv, pkt[:off])
@@ -417,21 +443,18 @@
 const packname = {buf, off : size, host
 	var i
 	var start
-	var seglen, lastseg
+	var last
 
 	start = off
-	seglen = 0
-	lastseg = 0
+	last = 0
 	for i = 0; i < host.len; i++
-		seglen++
 		if host[i] == ('.' castto(byte))
-			off += addseg(buf, off, host[lastseg:lastseg+seglen-1])
-			lastseg = seglen
-			seglen = 0
+			off += addseg(buf, off, host[last:i])
+			last = i + 1
 		;;
 	;;
 	if host[host.len - 1] != ('.' castto(byte))
-		off += addseg(buf, off, host[lastseg:lastseg + seglen])
+		off += addseg(buf, off, host[last:])
 	;;
 	off += addseg(buf, off, "") /* null terminating segment */
 	-> off - start