dns, ipset, rule: change dns AnswerHandler to use netip instead of string

This commit is contained in:
nadoo 2022-02-03 00:04:17 +08:00
parent fdb32370e9
commit 7f925fb711
8 changed files with 53 additions and 48 deletions

View File

@ -29,7 +29,7 @@ jobs:
uses: actions/setup-go@v2
with:
stable: 'false'
go-version: '1.18.0-beta1'
go-version: '1.18.0-beta2'
# go-version: ${{ env.GO_VERSION}}
- name: Set up Cache

View File

@ -1,5 +1,5 @@
# Build Stage
FROM golang:1.18beta1-alpine AS build-env
FROM golang:1.18beta2-alpine AS build-env
ADD . /src

View File

@ -15,7 +15,7 @@ import (
)
// AnswerHandler function handles the dns TypeA or TypeAAAA answer.
type AnswerHandler func(domain, ip string) error
type AnswerHandler func(domain string, ip netip.Addr) error
// Config for dns.
type Config struct {
@ -138,12 +138,11 @@ func (c *Client) extractAnswer(resp *Message) ([]string, int) {
ttl := c.config.MinTTL
for _, answer := range resp.Answers {
if answer.TYPE == QTypeA || answer.TYPE == QTypeAAAA {
if answer.IP.IsValid() {
ip := answer.IP.String()
if answer.IP.IsValid() && !answer.IP.IsUnspecified() {
for _, h := range c.handlers {
h(resp.Question.QNAME, ip)
h(resp.Question.QNAME, answer.IP)
}
ips = append(ips, ip)
ips = append(ips, answer.IP.String())
}
if answer.TTL != 0 {
ttl = int(answer.TTL)

6
go.mod
View File

@ -9,15 +9,15 @@ require (
github.com/dgryski/go-rc2 v0.0.0-20150621095337-8a9021637152
github.com/insomniacslk/dhcp v0.0.0-20220119180841-3c283ff8b7dd
github.com/nadoo/conflag v0.2.3
github.com/nadoo/ipset v0.4.0
github.com/nadoo/ipset v0.4.1-0.20220202154244-ddbfbad6db35
github.com/xtaci/kcp-go/v5 v5.6.1
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27
)
require (
github.com/ebfe/rc2 v0.0.0-20131011165748-24b9757f5521 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/klauspost/cpuid/v2 v2.0.10 // indirect
github.com/klauspost/reedsolomon v1.9.15 // indirect
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7 // indirect
github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b // indirect

12
go.sum
View File

@ -49,8 +49,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
github.com/klauspost/cpuid v1.2.4/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd42rAQw4=
github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.0.10 h1:fv5GKR+e2UgD+gcxQECVT5rBwAmlFLl2mkKm7WK3ODY=
github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
github.com/klauspost/reedsolomon v1.9.9/go.mod h1:O7yFFHiQwDR6b2t63KPUpccPtNdp5ADgh1gg4fd12wo=
github.com/klauspost/reedsolomon v1.9.15 h1:g2erWKD2M6rgnPf89fCji6jNlhMKMdXcuNHMW1SYCIo=
github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk=
@ -67,8 +67,8 @@ github.com/mdlayher/raw v0.0.0-20211126142749-4eae47f3d54b/go.mod h1:7EpbotpCmVZ
github.com/mmcloughlin/avo v0.0.0-20200803215136-443f81d77104/go.mod h1:wqKykBG2QzQDJEzvRkcS8x6MiSJkF52hXZsXcjaB3ls=
github.com/nadoo/conflag v0.2.3 h1:/+rTaN0bHTIiQbPl1WZK78JRoqjlNqJ9Zf05ep0o5jI=
github.com/nadoo/conflag v0.2.3/go.mod h1:dzFfDUpXdr2uS2oV+udpy5N2vfNOu/bFzjhX1WI52co=
github.com/nadoo/ipset v0.4.0 h1:FBC4F6I0QP9+E2cYDelJfvPX4J7pGuml3ZKcAaplNQ4=
github.com/nadoo/ipset v0.4.0/go.mod h1:x/lqgubO+J0T1KnuzSrV35RzlcERchuzPFYhDg/kMaI=
github.com/nadoo/ipset v0.4.1-0.20220202154244-ddbfbad6db35 h1:ROGpIZqxtrO0mJhSS9bte1VNwVUmmavcjjtw3720t94=
github.com/nadoo/ipset v0.4.1-0.20220202154244-ddbfbad6db35/go.mod h1:rYF5DQLRGGoQ8ZSWeK+6eX5amAuPqwFkWjhQlEITGJQ=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@ -104,8 +104,8 @@ golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed h1:YoWVYYAfvQ4ddHv3OKmIvX7NCAhFGTj62VP2l2kfBbA=
golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE=
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=

View File

@ -1,7 +1,7 @@
package ipset
import (
"errors"
"net/netip"
"strings"
"sync"
@ -22,6 +22,13 @@ func addToSet(s, item string) error {
return ipset.Add(s, item)
}
func addAddrToSet(s string, ip netip.Addr) error {
if ip.Is4() {
return ipset.AddAddr(s, ip)
}
return ipset.AddAddr(s+"6", ip)
}
// NewManager returns a Manager
func NewManager(rules []*rule.Config) (*Manager, error) {
if err := ipset.Init(); err != nil {
@ -59,16 +66,12 @@ func NewManager(rules []*rule.Config) (*Manager, error) {
}
// AddDomainIP implements the dns AnswerHandler function, used to update ipset according to domainSet rule.
func (m *Manager) AddDomainIP(domain, ip string) error {
if domain == "" || ip == "" {
return errors.New("please specify the domain and ip address")
}
func (m *Manager) AddDomainIP(domain string, ip netip.Addr) error {
domain = strings.ToLower(domain)
for i := len(domain); i != -1; {
i = strings.LastIndexByte(domain[:i], '.')
if setName, ok := m.domainSet.Load(domain[i+1:]); ok {
addToSet(setName.(string), ip)
addAddrToSet(setName.(string), ip)
}
}
return nil

View File

@ -5,6 +5,7 @@ package ipset
import (
"errors"
"net/netip"
"github.com/nadoo/glider/rule"
)
@ -18,6 +19,6 @@ func NewManager(rules []*rule.Config) (*Manager, error) {
}
// AddDomainIP implements the DNSAnswerHandler function
func (m *Manager) AddDomainIP(domain, ip string) error {
func (m *Manager) AddDomainIP(domain string, ip netip.Addr) error {
return errors.New("ipset not supported on this os")
}

View File

@ -31,7 +31,12 @@ func NewProxy(mainForwarders []string, mainStrategy *Strategy, rules []*Config)
rd.domainMap.Store(strings.ToLower(domain), group)
}
for _, ip := range r.IP {
for _, s := range r.IP {
ip, err := netip.ParseAddr(s)
if err != nil {
log.F("[rule] parse ip error: %s", err)
continue
}
rd.ipMap.Store(ip, group)
}
@ -79,23 +84,13 @@ func (p *Proxy) findDialer(dstAddr string) *FwdrGroup {
return p.main
}
// check ip
// TODO: ipv4 should equal to ipv4-mapped ipv6? but it'll need to parse the ip address
if proxy, ok := p.ipMap.Load(host); ok {
return proxy.(*FwdrGroup)
}
// check host
host = strings.ToLower(host)
for i := len(host); i != -1; {
i = strings.LastIndexByte(host[:i], '.')
if proxy, ok := p.domainMap.Load(host[i+1:]); ok {
if ip, err := netip.ParseAddr(host); err == nil {
// check ip
if proxy, ok := p.ipMap.Load(ip); ok {
return proxy.(*FwdrGroup)
}
}
// check cidr
if ip, err := netip.ParseAddr(host); err == nil {
// check cidr
var ret *FwdrGroup
p.cidrMap.Range(func(key, value any) bool {
if key.(netip.Prefix).Contains(ip) {
@ -110,6 +105,15 @@ func (p *Proxy) findDialer(dstAddr string) *FwdrGroup {
}
}
// check host
host = strings.ToLower(host)
for i := len(host); i != -1; {
i = strings.LastIndexByte(host[:i], '.')
if proxy, ok := p.domainMap.Load(host[i+1:]); ok {
return proxy.(*FwdrGroup)
}
}
return p.main
}
@ -130,15 +134,13 @@ func (p *Proxy) Record(dialer proxy.Dialer, success bool) {
}
// AddDomainIP used to update ipMap rules according to domainMap rule.
func (p *Proxy) AddDomainIP(domain, ip string) error {
if ip != "" {
domain = strings.ToLower(domain)
for i := len(domain); i != -1; {
i = strings.LastIndexByte(domain[:i], '.')
if dialer, ok := p.domainMap.Load(domain[i+1:]); ok {
p.ipMap.Store(ip, dialer)
// log.F("[rule] update map: %s/%s based on rule: domain=%s\n", domain, ip, domain[i+1:])
}
func (p *Proxy) AddDomainIP(domain string, ip netip.Addr) error {
domain = strings.ToLower(domain)
for i := len(domain); i != -1; {
i = strings.LastIndexByte(domain[:i], '.')
if dialer, ok := p.domainMap.Load(domain[i+1:]); ok {
p.ipMap.Store(ip, dialer)
// log.F("[rule] update map: %s/%s based on rule: domain=%s\n", domain, ip, domain[i+1:])
}
}
return nil