diff --git a/config/config.go b/config/config.go index f1b925e..2989b0c 100644 --- a/config/config.go +++ b/config/config.go @@ -22,8 +22,10 @@ type CacheConf struct { // Group 配置文件中每个groups section对应的结构 type Group struct { - ECS string `toml:"ecs"` - NoCookie bool `toml:"no_cookie"` + DisableIPv6 bool `toml:"disable_ipv6"` + DisableQTypes []string `toml:"disable_qtypes"` + ECS string `toml:"ecs"` + NoCookie bool `toml:"no_cookie"` Rules []string `toml:"rules"` RulesFile string `toml:"rules_file"` diff --git a/outbound/groups.go b/outbound/groups.go index 4b7af87..2f42059 100644 --- a/outbound/groups.go +++ b/outbound/groups.go @@ -5,13 +5,6 @@ import ( "encoding/base64" "errors" "fmt" - "github.com/miekg/dns" - "github.com/sirupsen/logrus" - "github.com/wolf-joe/go-ipset/ipset" - "github.com/wolf-joe/ts-dns/config" - "github.com/wolf-joe/ts-dns/matcher" - "github.com/wolf-joe/ts-dns/utils" - "golang.org/x/net/proxy" "io/ioutil" "net" "net/http" @@ -19,6 +12,14 @@ import ( "sync/atomic" "time" "unsafe" + + "github.com/miekg/dns" + "github.com/sirupsen/logrus" + "github.com/wolf-joe/go-ipset/ipset" + "github.com/wolf-joe/ts-dns/config" + "github.com/wolf-joe/ts-dns/matcher" + "github.com/wolf-joe/ts-dns/utils" + "golang.org/x/net/proxy" ) type IGroup interface { @@ -55,22 +56,35 @@ func BuildGroups(globalConf config.Conf) (map[string]IGroup, error) { seenGFWList = true } g := &groupImpl{ - name: name, - fallback: conf.Fallback, - matcher: nil, - gfwList: nil, - gfwListURL: conf.GFWListURL, - noCookie: conf.NoCookie, - withECS: nil, - callers: nil, - concurrent: conf.Concurrent, - proxy: nil, - fastestIP: conf.FastestV4, - tcpPingPort: conf.TCPPingPort, - ipSet: nil, - stopCh: make(chan struct{}), - stopped: make(chan struct{}), + name: name, + fallback: conf.Fallback, + matcher: nil, + gfwList: nil, + gfwListURL: conf.GFWListURL, + noCookie: conf.NoCookie, + withECS: nil, + callers: nil, + concurrent: conf.Concurrent, + proxy: nil, + fastestIP: conf.FastestV4, + tcpPingPort: conf.TCPPingPort, + ipSet: nil, + stopCh: make(chan struct{}), + stopped: make(chan struct{}), + disableQTypes: map[uint16]bool{}, + } + // disable query types + if conf.DisableIPv6 { + g.disableQTypes[dns.TypeAAAA] = true } + for _, qTypeStr := range conf.DisableQTypes { + qTypeStr = strings.ToUpper(qTypeStr) + if _, exists := dns.StringToType[qTypeStr]; !exists { + return nil, fmt.Errorf("unknown query type: %q", qTypeStr) + } + g.disableQTypes[dns.StringToType[qTypeStr]] = true + } + // read rules text := strings.Join(conf.Rules, "\n") g.matcher = matcher.NewABPByText(text) @@ -165,9 +179,10 @@ type groupImpl struct { name string fallback bool - matcher *matcher.ABPlus - gfwList unsafe.Pointer // type: *matcher.ABPlus - gfwListURL string + disableQTypes map[uint16]bool + matcher *matcher.ABPlus + gfwList unsafe.Pointer // type: *matcher.ABPlus + gfwListURL string noCookie bool // 是否删除请求中的cookie withECS *dns.EDNS0_SUBNET // 是否在请求中附加ECS信息 @@ -210,6 +225,11 @@ func (g *groupImpl) Match(req *dns.Msg) bool { } func (g *groupImpl) Handle(req *dns.Msg) *dns.Msg { + for _, question := range req.Question { + if g.disableQTypes[question.Qtype] { + return nil // disabled + } + } // 预处理请求 if g.noCookie || g.withECS != nil { req = req.Copy() diff --git a/outbound/groups_test.go b/outbound/groups_test.go index f812292..a4f6504 100644 --- a/outbound/groups_test.go +++ b/outbound/groups_test.go @@ -1,9 +1,11 @@ package outbound import ( + "testing" + + "github.com/miekg/dns" "github.com/stretchr/testify/assert" "github.com/wolf-joe/ts-dns/config" - "testing" ) func TestBuildGroups(t *testing.T) { @@ -46,3 +48,20 @@ func TestBuildGroups(t *testing.T) { t.Log(err) }) } + +func TestDisableIPv6(t *testing.T) { + groups, err := BuildGroups(config.Conf{Groups: map[string]config.Group{ + "g1": {DisableIPv6: true, DisableQTypes: []string{"AAAA"}}, + }}) + assert.Nil(t, err) + g := groups["g1"] + assert.NotNil(t, g) + resp := g.Handle(&dns.Msg{ + Question: []dns.Question{{ + Name: "z.cn.", + Qtype: dns.TypeAAAA, + Qclass: 0, + }}, + }) + assert.Nil(t, resp) +} diff --git a/ts-dns-full.toml b/ts-dns-full.toml index 1123b32..2c4a82e 100644 --- a/ts-dns-full.toml +++ b/ts-dns-full.toml @@ -32,6 +32,8 @@ max_ttl = 86400 # 最大ttl,单位为秒 redirector = "oversea_ip2dirty" # 解析后判断是否需要重定向 [groups.dirty] + disable_qtypes = ["AAAA", "HTTPS"] # 对指定组单独屏蔽IPv6/HTTPS查询 + gfwlist_file = "gfwlist.txt" # 匹配到gfwlist规则时使用该组 socks5 = "127.0.0.1:1080" # 当使用国外53端口dns解析时推荐用socks5代理解析