shithub: mc

Download patch

ref: 22dfaa6b4c03222803ae97cf4ff9401788b5d4ea
parent: 2698fe288642465ec636dca1c8f4ff88a22c5afe
author: Ori Bernstein <ori@markovcorp.com>
date: Mon Jun 5 05:45:34 EDT 2017

Don't assume DNS returned record types are A records.

--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -36,6 +36,7 @@
 		`DnsMX		/* mail exchange */
 		`DnsTXT		/* text strings */
 		`DnsAAAA	/* ipv6 host address */
+		`DnsInval	/* invalid */
 	;;
 
 	type resolveerr = union
@@ -325,42 +326,55 @@
 }
 
 const hosts = {pkt, id : uint16
-	var off
-	var v, q, a
+	var off, ni
+	var r, n, q, a, t
 	var hinf : hostinfo[:]
+	var v6dat : byte[16]
 
 	off = 0
 	/* parse header */
-	(v, off) = unpack16(pkt, off)	/* id */
-	if v != id
+	(r, off) = unpack16(pkt, off)	/* id */
+	if r != id
 		-> `Err `Badresp
 	;;
-	(v, off) = unpack16(pkt, off)	/* flags */
+	(_, off) = unpack16(pkt, off)	/* flags */
 	(q, off) = unpack16(pkt, off)	/* qdcount */
 	(a, off) = unpack16(pkt, off)	/* ancount */
-	(v, off) = unpack16(pkt, off)	/* nscount */
-	(v, off) = unpack16(pkt, off)	/* arcount */
+	(_, off) = unpack16(pkt, off)	/* nscount */
+	(_, off) = unpack16(pkt, off)	/* arcount */
 
 	/* skip past query records */
 	for var i = 0; i < q; i++
 		off = skipname(pkt, off)	/* name */
-		(v, off) = unpack16(pkt, off)	/* type */
-		(v, off) = unpack16(pkt, off)	/* class */
+		(_, off) = unpack16(pkt, off)	/* type */
+		(_, off) = unpack16(pkt, off)	/* class */
 	;;
 
 	/* parse answer records */
+	ni = 0
 	hinf = slalloc((a : size))
 	for var i = 0; i < a; i++
 		off = skipname(pkt, off)	/* name */
-		(v, off) = unpack16(pkt, off)	/* type */
-		(v, off) = unpack16(pkt, off)	/* class */
-		(hinf[i].ttl, off) = unpack32(pkt, off)	/* ttl */
-		(v, off) = unpack16(pkt, off)	/* rdatalen */
-		/* the thing we're interested in: our IP address */
-		hinf[i].addr = `Ipv4 [pkt[off], pkt[off+1], pkt[off+2], pkt[off+3]]
-		off += 4;
+		(t, off) = unpack16(pkt, off)	/* type */
+		(_, off) = unpack16(pkt, off)	/* class */
+		(hinf[ni].ttl, off) = unpack32(pkt, off)	/* ttl */
+		(n, off) = unpack16(pkt, off)	/* rdatalen */
+		match id2type(t)
+		| `DnsA:
+			/* the thing we're interested in: our IP address */
+			hinf[ni].addr = `Ipv4 [pkt[off], pkt[off+1], pkt[off+2], pkt[off+3]]
+			off += 4;
+			ni++
+		| `DnsAAAA:
+			std.slcp(v6dat[:], pkt[off:off+16])
+			hinf[ni].addr = `Ipv6 v6dat
+			off += 16
+			ni++
+		| _:
+			off += (n : std.size)
+		;;
 	;;
-	-> `Ok hinf
+	-> `Ok hinf[:ni]
 }
 
 
@@ -454,6 +468,23 @@
 	-> true
 }
 
+const id2type = {rtype
+	match rtype
+	| 1:	-> `DnsA
+	| 2:	-> `DnsNS
+	| 5:	-> `DnsCNAME
+	| 6:	-> `DnsSOA
+	| 11:	-> `DnsWKS
+	| 12:	-> `DnsPTR
+	| 13:	-> `DnsHINFO
+	| 14:	-> `DnsMINFO
+	| 15:	-> `DnsMX
+	| 16:	-> `DnsTXT
+	| 28:	-> `DnsAAAA
+	| _:	-> `DnsInval
+	;;
+}
+
 const rectype = {rtype
 	match rtype
 	| `DnsA:	-> 1  /* host address */
@@ -467,6 +498,7 @@
 	| `DnsMX:	-> 15 /* mail exchange */
 	| `DnsTXT:	-> 16 /* text strings */
 	| `DnsAAAA:	-> 28 /* ipv6 host address */
+	| `DnsInval:	-> -1
 	;;
 }