shithub: mc

Download patch

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]
 }