dns: add settings dnstimeout/dnsmaxttl/dnsminttl

This commit is contained in:
nadoo 2018-08-07 19:43:52 +08:00
parent 6744f1ad25
commit a26e437b5d
7 changed files with 52 additions and 24 deletions

View File

@ -62,7 +62,7 @@ General:
TODO:
- [ ] IPv6 support
- [ ] IPv6 support in ipset manager
- [ ] Transparent UDP proxy (iptables tproxy)
- [ ] Performance tuning
- [ ] TUN/TAP device support

20
conf.go
View File

@ -17,15 +17,18 @@ var conf struct {
Verbose bool
Strategy string
CheckWebSite string
CheckDuration int
CheckInterval int
Listen []string
Forward []string
RuleFile []string
RulesDir string
DNS string
DNSServer []string
DNSRecord []string
DNS string
DNSServer []string
DNSTimeout int
DNSMaxTTL int
DNSMinTTL int
DNSRecord []string
IPSet string
@ -36,7 +39,7 @@ func confInit() {
flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode")
flag.StringVar(&conf.Strategy, "strategy", "rr", "forward strategy, default: rr")
flag.StringVar(&conf.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
flag.IntVar(&conf.CheckDuration, "checkduration", 30, "proxy check duration(seconds)")
flag.IntVar(&conf.CheckInterval, "checkduration", 30, "proxy check interval(seconds)")
flag.StringSliceUniqVar(&conf.Listen, "listen", nil, "listen url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS")
flag.StringSliceUniqVar(&conf.Forward, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]")
flag.StringSliceUniqVar(&conf.RuleFile, "rulefile", nil, "rule file path")
@ -44,6 +47,9 @@ func confInit() {
flag.StringVar(&conf.DNS, "dns", "", "dns forwarder server listen address")
flag.StringSliceUniqVar(&conf.DNSServer, "dnsserver", []string{"8.8.8.8:53"}, "remote dns server")
flag.IntVar(&conf.DNSTimeout, "dnstimeout", 3, "timeout value used in multiple dnsservers switch(seconds)")
flag.IntVar(&conf.DNSMaxTTL, "dnsmaxttl", 1800, "maximum TTL value for entries in the CACHE(seconds)")
flag.IntVar(&conf.DNSMinTTL, "dnsminttl", 0, "minimum TTL value for entries in the CACHE(seconds)")
flag.StringSliceUniqVar(&conf.DNSRecord, "dnsrecord", nil, "custom dns record, format: domain/ip")
flag.StringVar(&conf.IPSet, "ipset", "", "ipset name")
@ -116,7 +122,7 @@ type RuleConf struct {
Forward []string
Strategy string
CheckWebSite string
CheckDuration int
CheckInterval int
DNSServer []string
IPSet string
@ -134,7 +140,7 @@ func NewRuleConfFromFile(ruleFile string) (*RuleConf, error) {
f.StringSliceUniqVar(&p.Forward, "forward", nil, "forward url, format: SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS[,SCHEME://[USER|METHOD:PASSWORD@][HOST]:PORT?PARAMS]")
f.StringVar(&p.Strategy, "strategy", "rr", "forward strategy, default: rr")
f.StringVar(&p.CheckWebSite, "checkwebsite", "www.apple.com", "proxy check HTTP(NOT HTTPS) website address, format: HOST[:PORT], default port: 80")
f.IntVar(&p.CheckDuration, "checkduration", 30, "proxy check duration(seconds)")
f.IntVar(&p.CheckInterval, "checkduration", 30, "proxy check interval(seconds)")
f.StringSliceUniqVar(&p.DNSServer, "dnsserver", nil, "remote dns server")
f.StringVar(&p.IPSet, "ipset", "", "ipset name")

View File

@ -125,6 +125,12 @@ dns=:53
# global remote dns server (you can specify different dns server in rule file)
dnsserver=8.8.8.8:53
dnsserver=1.1.1.1:53
# timeout value used in multiple dnsservers switch(seconds)
dnstimeout=3
# maximum TTL value for entries in the CACHE(seconds)
dnsmaxttl=1800
# minimum TTL value for entries in the CACHE(seconds)
dnsminttl=0
# custom records
dnsrecord=www.example.com/1.2.3.4
dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946

View File

@ -13,26 +13,32 @@ import (
"github.com/nadoo/glider/proxy"
)
// DefaultTTL is default ttl in seconds
const DefaultTTL = 600
// HandleFunc function handles the dns TypeA or TypeAAAA answer
type HandleFunc func(Domain, ip string) error
// Config for dns
type Config struct {
Timeout int
MaxTTL int
MinTTL int
}
// Client is a dns client struct
type Client struct {
dialer proxy.Dialer
cache *Cache
config *Config
upServers []string
upServerMap map[string][]string
handlers []HandleFunc
}
// NewClient returns a new dns client
func NewClient(dialer proxy.Dialer, upServers []string) (*Client, error) {
func NewClient(dialer proxy.Dialer, upServers []string, config *Config) (*Client, error) {
c := &Client{
dialer: dialer,
cache: NewCache(),
config: config,
upServers: upServers,
upServerMap: make(map[string][]string),
}
@ -75,7 +81,7 @@ func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([
return respBytes, err
}
ttl := DefaultTTL
ttl := c.config.MinTTL
ips := []string{}
for _, answer := range resp.Answers {
if answer.TYPE == QTypeA || answer.TYPE == QTypeAAAA {
@ -85,14 +91,18 @@ func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([
if answer.IP != "" {
ips = append(ips, answer.IP)
}
if answer.TTL != 0 {
ttl = int(answer.TTL)
}
ttl = int(answer.TTL)
}
}
if ttl > c.config.MaxTTL {
ttl = c.config.MaxTTL
} else if ttl < c.config.MinTTL {
ttl = c.config.MinTTL
}
// add to cache only when there's a valid ip address
if len(ips) != 0 {
if len(ips) != 0 && ttl > 0 {
c.cache.Put(getKey(resp.Question), respBytes, ttl)
}
@ -113,9 +123,9 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (server
network = "udp"
}
var rc net.Conn
servers := c.GetServers(qname)
for _, server = range servers {
var rc net.Conn
rc, err = dialer.Dial(network, server)
if err != nil {
log.F("[dns] failed to connect to server %v: %v", server, err)
@ -125,7 +135,7 @@ func (c *Client) exchange(qname string, reqBytes []byte, preferTCP bool) (server
// TODO: support timeout setting for different upstream server
if len(servers) > 1 {
rc.SetDeadline(time.Now().Add(time.Duration(3) * time.Second))
rc.SetDeadline(time.Now().Add(time.Duration(c.config.Timeout) * time.Second))
}
switch network {

View File

@ -21,8 +21,8 @@ type Server struct {
}
// NewServer returns a new dns server
func NewServer(addr string, dialer proxy.Dialer, upServers []string) (*Server, error) {
c, err := NewClient(dialer, upServers)
func NewServer(addr string, dialer proxy.Dialer, upServers []string, config *Config) (*Server, error) {
c, err := NewClient(dialer, upServers, config)
s := &Server{
addr: addr,
Client: c,

10
main.go
View File

@ -42,7 +42,7 @@ func dialerFromConf() proxy.Dialer {
fwdrs = append(fwdrs, fwdr)
}
return NewStrategyDialer(conf.Strategy, fwdrs, conf.CheckWebSite, conf.CheckDuration)
return NewStrategyDialer(conf.Strategy, fwdrs, conf.CheckWebSite, conf.CheckInterval)
}
func main() {
@ -57,7 +57,13 @@ func main() {
dialer := NewRuleDialer(conf.rules, dialerFromConf())
ipsetM, _ := NewIPSetManager(conf.IPSet, conf.rules)
if conf.DNS != "" {
d, err := dns.NewServer(conf.DNS, dialer, conf.DNSServer)
dnscfg := &dns.Config{
Timeout: conf.DNSTimeout,
MaxTTL: conf.DNSMaxTTL,
MinTTL: conf.DNSMinTTL}
d, err := dns.NewServer(conf.DNS, dialer, conf.DNSServer, dnscfg)
if err != nil {
log.Fatal(err)
}

View File

@ -36,7 +36,7 @@ func NewRuleDialer(rules []*RuleConf, gDialer proxy.Dialer) *RuleDialer {
fwdrs = append(fwdrs, fwdr)
}
sDialer := NewStrategyDialer(r.Strategy, fwdrs, r.CheckWebSite, r.CheckDuration)
sDialer := NewStrategyDialer(r.Strategy, fwdrs, r.CheckWebSite, r.CheckInterval)
for _, domain := range r.Domain {
rd.domainMap.Store(strings.ToLower(domain), sDialer)