mirror of
				https://github.com/nadoo/glider.git
				synced 2025-11-04 15:52:38 +08:00 
			
		
		
		
	dns: add settings dnstimeout/dnsmaxttl/dnsminttl
This commit is contained in:
		
							parent
							
								
									6744f1ad25
								
							
						
					
					
						commit
						a26e437b5d
					
				@ -62,7 +62,7 @@ General:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
TODO:
 | 
					TODO:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- [ ] IPv6 support
 | 
					- [ ] IPv6 support in ipset manager
 | 
				
			||||||
- [ ] Transparent UDP proxy (iptables tproxy)
 | 
					- [ ] Transparent UDP proxy (iptables tproxy)
 | 
				
			||||||
- [ ] Performance tuning
 | 
					- [ ] Performance tuning
 | 
				
			||||||
- [ ] TUN/TAP device support
 | 
					- [ ] TUN/TAP device support
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										14
									
								
								conf.go
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								conf.go
									
									
									
									
									
								
							@ -17,7 +17,7 @@ var conf struct {
 | 
				
			|||||||
	Verbose       bool
 | 
						Verbose       bool
 | 
				
			||||||
	Strategy      string
 | 
						Strategy      string
 | 
				
			||||||
	CheckWebSite  string
 | 
						CheckWebSite  string
 | 
				
			||||||
	CheckDuration int
 | 
						CheckInterval int
 | 
				
			||||||
	Listen        []string
 | 
						Listen        []string
 | 
				
			||||||
	Forward       []string
 | 
						Forward       []string
 | 
				
			||||||
	RuleFile      []string
 | 
						RuleFile      []string
 | 
				
			||||||
@ -25,6 +25,9 @@ var conf struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	DNS        string
 | 
						DNS        string
 | 
				
			||||||
	DNSServer  []string
 | 
						DNSServer  []string
 | 
				
			||||||
 | 
						DNSTimeout int
 | 
				
			||||||
 | 
						DNSMaxTTL  int
 | 
				
			||||||
 | 
						DNSMinTTL  int
 | 
				
			||||||
	DNSRecord  []string
 | 
						DNSRecord  []string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	IPSet string
 | 
						IPSet string
 | 
				
			||||||
@ -36,7 +39,7 @@ func confInit() {
 | 
				
			|||||||
	flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode")
 | 
						flag.BoolVar(&conf.Verbose, "verbose", false, "verbose mode")
 | 
				
			||||||
	flag.StringVar(&conf.Strategy, "strategy", "rr", "forward strategy, default: rr")
 | 
						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.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.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.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")
 | 
						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.StringVar(&conf.DNS, "dns", "", "dns forwarder server listen address")
 | 
				
			||||||
	flag.StringSliceUniqVar(&conf.DNSServer, "dnsserver", []string{"8.8.8.8:53"}, "remote dns server")
 | 
						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.StringSliceUniqVar(&conf.DNSRecord, "dnsrecord", nil, "custom dns record, format: domain/ip")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	flag.StringVar(&conf.IPSet, "ipset", "", "ipset name")
 | 
						flag.StringVar(&conf.IPSet, "ipset", "", "ipset name")
 | 
				
			||||||
@ -116,7 +122,7 @@ type RuleConf struct {
 | 
				
			|||||||
	Forward       []string
 | 
						Forward       []string
 | 
				
			||||||
	Strategy      string
 | 
						Strategy      string
 | 
				
			||||||
	CheckWebSite  string
 | 
						CheckWebSite  string
 | 
				
			||||||
	CheckDuration int
 | 
						CheckInterval int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DNSServer []string
 | 
						DNSServer []string
 | 
				
			||||||
	IPSet     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.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.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.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.StringSliceUniqVar(&p.DNSServer, "dnsserver", nil, "remote dns server")
 | 
				
			||||||
	f.StringVar(&p.IPSet, "ipset", "", "ipset name")
 | 
						f.StringVar(&p.IPSet, "ipset", "", "ipset name")
 | 
				
			||||||
 | 
				
			|||||||
@ -125,6 +125,12 @@ dns=:53
 | 
				
			|||||||
# global remote dns server (you can specify different dns server in rule file)
 | 
					# global remote dns server (you can specify different dns server in rule file)
 | 
				
			||||||
dnsserver=8.8.8.8:53
 | 
					dnsserver=8.8.8.8:53
 | 
				
			||||||
dnsserver=1.1.1.1: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
 | 
					# custom records
 | 
				
			||||||
dnsrecord=www.example.com/1.2.3.4
 | 
					dnsrecord=www.example.com/1.2.3.4
 | 
				
			||||||
dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946
 | 
					dnsrecord=www.example.com/2606:2800:220:1:248:1893:25c8:1946
 | 
				
			||||||
 | 
				
			|||||||
@ -13,26 +13,32 @@ import (
 | 
				
			|||||||
	"github.com/nadoo/glider/proxy"
 | 
						"github.com/nadoo/glider/proxy"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// DefaultTTL is default ttl in seconds
 | 
					 | 
				
			||||||
const DefaultTTL = 600
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// HandleFunc function handles the dns TypeA or TypeAAAA answer
 | 
					// HandleFunc function handles the dns TypeA or TypeAAAA answer
 | 
				
			||||||
type HandleFunc func(Domain, ip string) error
 | 
					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
 | 
					// Client is a dns client struct
 | 
				
			||||||
type Client struct {
 | 
					type Client struct {
 | 
				
			||||||
	dialer      proxy.Dialer
 | 
						dialer      proxy.Dialer
 | 
				
			||||||
	cache       *Cache
 | 
						cache       *Cache
 | 
				
			||||||
 | 
						config      *Config
 | 
				
			||||||
	upServers   []string
 | 
						upServers   []string
 | 
				
			||||||
	upServerMap map[string][]string
 | 
						upServerMap map[string][]string
 | 
				
			||||||
	handlers    []HandleFunc
 | 
						handlers    []HandleFunc
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewClient returns a new dns client
 | 
					// 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{
 | 
						c := &Client{
 | 
				
			||||||
		dialer:      dialer,
 | 
							dialer:      dialer,
 | 
				
			||||||
		cache:       NewCache(),
 | 
							cache:       NewCache(),
 | 
				
			||||||
 | 
							config:      config,
 | 
				
			||||||
		upServers:   upServers,
 | 
							upServers:   upServers,
 | 
				
			||||||
		upServerMap: make(map[string][]string),
 | 
							upServerMap: make(map[string][]string),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -75,7 +81,7 @@ func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([
 | 
				
			|||||||
		return respBytes, err
 | 
							return respBytes, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ttl := DefaultTTL
 | 
						ttl := c.config.MinTTL
 | 
				
			||||||
	ips := []string{}
 | 
						ips := []string{}
 | 
				
			||||||
	for _, answer := range resp.Answers {
 | 
						for _, answer := range resp.Answers {
 | 
				
			||||||
		if answer.TYPE == QTypeA || answer.TYPE == QTypeAAAA {
 | 
							if answer.TYPE == QTypeA || answer.TYPE == QTypeAAAA {
 | 
				
			||||||
@ -85,14 +91,18 @@ func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([
 | 
				
			|||||||
			if answer.IP != "" {
 | 
								if answer.IP != "" {
 | 
				
			||||||
				ips = append(ips, 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
 | 
						// 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)
 | 
							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"
 | 
							network = "udp"
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var rc net.Conn
 | 
					 | 
				
			||||||
	servers := c.GetServers(qname)
 | 
						servers := c.GetServers(qname)
 | 
				
			||||||
	for _, server = range servers {
 | 
						for _, server = range servers {
 | 
				
			||||||
 | 
							var rc net.Conn
 | 
				
			||||||
		rc, err = dialer.Dial(network, server)
 | 
							rc, err = dialer.Dial(network, server)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			log.F("[dns] failed to connect to server %v: %v", server, err)
 | 
								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
 | 
							// TODO: support timeout setting for different upstream server
 | 
				
			||||||
		if len(servers) > 1 {
 | 
							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 {
 | 
							switch network {
 | 
				
			||||||
 | 
				
			|||||||
@ -21,8 +21,8 @@ type Server struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewServer returns a new dns server
 | 
					// NewServer returns a new dns server
 | 
				
			||||||
func NewServer(addr string, dialer proxy.Dialer, upServers []string) (*Server, error) {
 | 
					func NewServer(addr string, dialer proxy.Dialer, upServers []string, config *Config) (*Server, error) {
 | 
				
			||||||
	c, err := NewClient(dialer, upServers)
 | 
						c, err := NewClient(dialer, upServers, config)
 | 
				
			||||||
	s := &Server{
 | 
						s := &Server{
 | 
				
			||||||
		addr:   addr,
 | 
							addr:   addr,
 | 
				
			||||||
		Client: c,
 | 
							Client: c,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								main.go
									
									
									
									
									
								
							@ -42,7 +42,7 @@ func dialerFromConf() proxy.Dialer {
 | 
				
			|||||||
		fwdrs = append(fwdrs, fwdr)
 | 
							fwdrs = append(fwdrs, fwdr)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return NewStrategyDialer(conf.Strategy, fwdrs, conf.CheckWebSite, conf.CheckDuration)
 | 
						return NewStrategyDialer(conf.Strategy, fwdrs, conf.CheckWebSite, conf.CheckInterval)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
@ -57,7 +57,13 @@ func main() {
 | 
				
			|||||||
	dialer := NewRuleDialer(conf.rules, dialerFromConf())
 | 
						dialer := NewRuleDialer(conf.rules, dialerFromConf())
 | 
				
			||||||
	ipsetM, _ := NewIPSetManager(conf.IPSet, conf.rules)
 | 
						ipsetM, _ := NewIPSetManager(conf.IPSet, conf.rules)
 | 
				
			||||||
	if conf.DNS != "" {
 | 
						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 {
 | 
							if err != nil {
 | 
				
			||||||
			log.Fatal(err)
 | 
								log.Fatal(err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								rule.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								rule.go
									
									
									
									
									
								
							@ -36,7 +36,7 @@ func NewRuleDialer(rules []*RuleConf, gDialer proxy.Dialer) *RuleDialer {
 | 
				
			|||||||
			fwdrs = append(fwdrs, fwdr)
 | 
								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 {
 | 
							for _, domain := range r.Domain {
 | 
				
			||||||
			rd.domainMap.Store(strings.ToLower(domain), sDialer)
 | 
								rd.domainMap.Store(strings.ToLower(domain), sDialer)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user