ref: b809eab49637ac9093c6295bdc3ba69f2a7b46c9
parent: 92dac618202997d1080597b377795f9cbba82742
author: Ori Bernstein <[email protected]>
date: Fri Jun 9 04:50:24 EDT 2017
Add dns cache.
--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -7,6 +7,7 @@
use "hashfuncs"
use "htab"
use "ipparse"
+use "now"
use "option"
use "result"
use "slcp"
@@ -53,6 +54,7 @@
stype : sys.socktype
ttl : uint32
addr : netaddr
+ stale : time
;;
const resolve : (host : byte[:] -> result(hostinfo[:], resolveerr))
@@ -65,11 +67,13 @@
const Timeout = 2_000
var hostmap : htab(byte[:], hostinfo)#
+var dnscache : htab(byte[:], hostinfo)#
var search : byte[:][:]
var nameservers : netaddr[:]
const __init__ = {
hostmap = mkht(strhash, streq)
+ dnscache = mkht(strhash, streq)
loadhosts()
loadresolv()
}
@@ -95,7 +99,16 @@
const hostfind = {host
var h
lock(netlck)
- h = htget(hostmap, host)
+ match htget(dnscache, host)
+ | `std.Some inf:
+ if inf.stale > std.now()
+ h = `std.Some inf
+ else
+ h = htget(hostmap, host)
+ ;;
+ | `std.None:
+ h = htget(hostmap, host)
+ ;;
unlock(netlck)
-> h
}
@@ -153,7 +166,6 @@
if hthas(hostmap, name)
continue
;;
- unlock(netlck)
hinf = [
.fam=fam,
.stype = 0,
@@ -234,17 +246,15 @@
if !valid(host)
-> `Err (`Badhost)
;;
- lock(netlck)
+ /* FIXME: Assumption: nameservers is not modified by other threads */
for ns in nameservers
nsrv = dnsconnect(ns)
if nsrv >= 0
r = dnsquery(nsrv, host, rt)
sys.close(nsrv)
- unlock(netlck)
-> r
;;
;;
- unlock(netlck)
-> `Err (`Badsrv)
}
@@ -278,11 +288,9 @@
const dnsquery = {srv, host, t
var id
- var r
id = tquery(srv, host, t)
- r = rquery(srv, id)
- -> r
+ -> rquery(srv, host, id)
}
const Qr : uint16 = 1 << 0
@@ -315,7 +323,7 @@
-> nextid
}
-const rquery = {srv, id
+const rquery = {srv, host, id
var pktbuf : byte[1024]
var pkt
var pfd
@@ -335,13 +343,13 @@
-> `Err `Badconn
;;
pkt = pktbuf[:n]
- -> hosts(pkt, id)
+ -> hosts(pkt, host, id)
;;
}
-const hosts = {pkt, id : uint16
+const hosts = {pkt, host, id
var off, ni
- var r, n, q, a, t
+ var r, n, q, a, t, ttl
var hinf : hostinfo[:]
var v6dat : byte[16]
@@ -371,8 +379,11 @@
off = skipname(pkt, off) /* name */
(t, off) = unpack16(pkt, off) /* type */
(_, off) = unpack16(pkt, off) /* class */
- (hinf[ni].ttl, off) = unpack32(pkt, off) /* ttl */
+ (ttl, off) = unpack32(pkt, off) /* ttl */
(n, off) = unpack16(pkt, off) /* rdatalen */
+
+ hinf[ni].ttl = ttl
+ hinf[ni].stale = (ttl * 1_000_000 : time) + std.now()
match id2type(t)
| `DnsA:
/* the thing we're interested in: our IP address */
@@ -388,6 +399,11 @@
off += (n : std.size)
;;
;;
+ lock(netlck)
+ if ni != 0 && hinf[0].ttl != 0
+ std.htput(dnscache, std.sldup(host), hinf[0])
+ ;;
+ unlock(netlck)
-> `Ok hinf[:ni]
}