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