mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 09:25:41 +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
|
||||||
|
20
conf.go
20
conf.go
@ -17,15 +17,18 @@ 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
|
||||||
RulesDir string
|
RulesDir string
|
||||||
|
|
||||||
DNS string
|
DNS string
|
||||||
DNSServer []string
|
DNSServer []string
|
||||||
DNSRecord []string
|
DNSTimeout int
|
||||||
|
DNSMaxTTL int
|
||||||
|
DNSMinTTL int
|
||||||
|
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