[Skip CI]

This commit is contained in:
MetaCubeX 2022-03-15 02:20:19 +08:00
parent cf52fbed65
commit 68fccfacc0
10 changed files with 56 additions and 13 deletions

View File

@ -103,7 +103,7 @@ func subIpCidr(ip net.IP, maskSize int, isIpv4 bool) ([]net.IP, int, error) {
lastByteMaskSize := maskSize % 8
lastByteMaskIndex := maskSize / 8
subIpCidrNum := 0xFF >> lastByteMaskSize
for i := 0; i < subIpCidrNum; i++ {
for i := 0; i <= subIpCidrNum; i++ {
subIpCidr := make([]byte, len(ip))
copy(subIpCidr, ip)
subIpCidr[lastByteMaskIndex] += byte(i)

View File

@ -26,12 +26,20 @@ func TestIpv4AddFail(t *testing.T) {
func TestIpv4Search(t *testing.T) {
trie := NewIpCidrTrie()
// Boundary testing
assert.NoError(t, trie.AddIpCidrForString("149.154.160.0/20"))
assert.Equal(t, true, trie.IsContainForString("149.154.160.0"))
assert.Equal(t, true, trie.IsContainForString("149.154.175.255"))
assert.Equal(t, false, trie.IsContainForString("149.154.176.0"))
assert.Equal(t, false, trie.IsContainForString("149.154.159.255"))
assert.NoError(t, trie.AddIpCidrForString("129.2.36.0/16"))
assert.NoError(t, trie.AddIpCidrForString("10.2.36.0/18"))
assert.NoError(t, trie.AddIpCidrForString("16.2.23.0/24"))
assert.NoError(t, trie.AddIpCidrForString("11.2.13.2/26"))
assert.NoError(t, trie.AddIpCidrForString("55.5.6.3/8"))
assert.NoError(t, trie.AddIpCidrForString("66.23.25.4/6"))
assert.Equal(t, true, trie.IsContainForString("129.2.3.65"))
assert.Equal(t, false, trie.IsContainForString("15.2.3.1"))
assert.Equal(t, true, trie.IsContainForString("11.2.13.1"))
@ -41,6 +49,7 @@ func TestIpv4Search(t *testing.T) {
assert.Equal(t, false, trie.IsContain(net.ParseIP("22")))
assert.Equal(t, false, trie.IsContain(net.ParseIP("")))
}
func TestIpv6AddSuccess(t *testing.T) {
@ -66,6 +75,14 @@ func TestIpv6AddFail(t *testing.T) {
func TestIpv6Search(t *testing.T) {
trie := NewIpCidrTrie()
// Boundary testing
assert.NoError(t, trie.AddIpCidrForString("2a0a:f280::/32"))
assert.Equal(t, true, trie.IsContainForString("2a0a:f280:0000:0000:0000:0000:0000:0000"))
assert.Equal(t, true, trie.IsContainForString("2a0a:f280:ffff:ffff:ffff:ffff:ffff:ffff"))
assert.Equal(t, false, trie.IsContainForString("2a0a:f279:ffff:ffff:ffff:ffff:ffff:ffff"))
assert.Equal(t, false, trie.IsContainForString("2a0a:f281:0000:0000:0000:0000:0000:0000"))
assert.NoError(t, trie.AddIpCidrForString("2001:b28:f23d:f001::e/128"))
assert.NoError(t, trie.AddIpCidrForString("2001:67c:4e8:f002::e/12"))
assert.NoError(t, trie.AddIpCidrForString("2001:b28:f23d:f003::e/96"))
@ -79,4 +96,5 @@ func TestIpv6Search(t *testing.T) {
assert.Equal(t, true, trie.IsContainForString("2001:67c:4e8:9666::1213"))
assert.Equal(t, false, trie.IsContain(net.ParseIP("22233:22")))
}

View File

@ -55,7 +55,6 @@ func (p *path) Resolve(path string) string {
if !filepath.IsAbs(path) {
return filepath.Join(p.HomeDir(), path)
}
return path
}

5
go.mod
View File

@ -46,11 +46,12 @@ require (
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
golang.org/x/tools v0.1.7 // indirect
golang.org/x/tools v0.1.9 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)

View File

@ -242,6 +242,9 @@ func updateGeneral(general *config.General, Tun *config.Tun, force bool) {
return
}
geodataLoader := general.GeodataLoader
G.SetLoader(geodataLoader)
allowLan := general.AllowLan
P.SetAllowLan(allowLan)

View File

@ -3,11 +3,11 @@ package tproxy
import (
"errors"
"fmt"
"github.com/Dreamacro/clash/component/dialer"
"os/exec"
"runtime"
"strings"
"github.com/Dreamacro/clash/component/dialer"
"github.com/Dreamacro/clash/log"
)

View File

@ -85,7 +85,8 @@ func (e *dnsEndpoint) HandlePacket(id stack.TransportEndpointID, pkt *stack.Pack
var msg D.Msg
msg.Unpack(pkt.Data().AsRange().ToOwnedView())
writer := dnsResponseWriter{s: e.stack, pkt: pkt, id: id}
log.Debugln("[DNS] hijack udp:%s:%d", id.LocalAddress.String(), id.LocalPort)
log.Debugln("[DNS] hijack udp:%s:%d from %s:%d", id.LocalAddress.String(), id.LocalPort,
id.RemoteAddress.String(), id.RemotePort)
go e.server.ServeDNS(&writer, &msg)
}
@ -139,9 +140,17 @@ func (w *dnsResponseWriter) Write(b []byte) (int, error) {
v := buffer.NewView(len(b))
copy(v, b)
data := v.ToVectorisedView()
// w.id.LocalAddress is the source ip of DNS response
r, _ := w.s.FindRoute(w.pkt.NICID, w.id.LocalAddress, w.id.RemoteAddress, w.pkt.NetworkProtocolNumber, false /* multicastLoop */)
return writeUDP(r, data, w.id.LocalPort, w.id.RemotePort)
if !w.pkt.NetworkHeader().View().IsEmpty() &&
(w.pkt.NetworkProtocolNumber == ipv4.ProtocolNumber ||
w.pkt.NetworkProtocolNumber == ipv6.ProtocolNumber) {
r, _ := w.s.FindRoute(w.pkt.NICID, w.id.LocalAddress, w.id.RemoteAddress, w.pkt.NetworkProtocolNumber, false /* multicastLoop */)
return writeUDP(r, data, w.id.LocalPort, w.id.RemotePort)
} else {
log.Debugln("the network protocl[%d] is not available", w.pkt.NetworkProtocolNumber)
return 0, fmt.Errorf("the network protocl[%d] is not available", w.pkt.NetworkProtocolNumber)
}
}
func (w *dnsResponseWriter) Close() error {

View File

@ -2,6 +2,9 @@ package gvisor
import (
"fmt"
"github.com/Dreamacro/clash/log"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv4"
"gvisor.dev/gvisor/pkg/tcpip/network/ipv6"
"net"
"github.com/Dreamacro/clash/component/resolver"
@ -40,8 +43,15 @@ func (c *fakeConn) WriteBack(b []byte, addr net.Addr) (n int, err error) {
localPort = uint16(udpaddr.Port)
}
r, _ := c.s.FindRoute(c.pkt.NICID, localAddress, c.id.RemoteAddress, c.pkt.NetworkProtocolNumber, false /* multicastLoop */)
return writeUDP(r, data, localPort, c.id.RemotePort)
if !c.pkt.NetworkHeader().View().IsEmpty() &&
(c.pkt.NetworkProtocolNumber == ipv4.ProtocolNumber ||
c.pkt.NetworkProtocolNumber == ipv6.ProtocolNumber) {
r, _ := c.s.FindRoute(c.pkt.NICID, localAddress, c.id.RemoteAddress, c.pkt.NetworkProtocolNumber, false /* multicastLoop */)
return writeUDP(r, data, localPort, c.id.RemotePort)
} else {
log.Debugln("the network protocl[%d] is not available", c.pkt.NetworkProtocolNumber)
return 0, fmt.Errorf("the network protocl[%d] is not available", c.pkt.NetworkProtocolNumber)
}
}
func (c *fakeConn) LocalAddr() net.Addr {

View File

@ -82,6 +82,9 @@ func parseRule(tp, payload, target string, params []string) (C.Rule, error) {
parsed, parseErr = RC.NewPort(payload, target, false, ruleExtra)
case "PROCESS-NAME":
parsed, parseErr = RC.NewProcess(payload, target, ruleExtra)
case "GEOIP":
noResolve := RC.HasNoResolve(params)
parsed, parseErr = RC.NewGEOIP(payload, target, noResolve, ruleExtra)
default:
parseErr = fmt.Errorf("unsupported rule type %s", tp)
}

View File

@ -81,9 +81,9 @@ func (rp *ruleSetProvider) Match(metadata *C.Metadata) bool {
switch rp.behavior {
case P.Domain:
return rp.DomainRules.Search(metadata.Host) != nil
return rp.DomainRules != nil && rp.DomainRules.Search(metadata.Host) != nil
case P.IPCIDR:
return rp.IPCIDRRules.IsContain(metadata.DstIP)
return rp.IPCIDRRules != nil && rp.IPCIDRRules.IsContain(metadata.DstIP)
case P.Classical:
for _, rule := range rp.ClassicalRules {
if rule.Match(metadata) {
@ -124,12 +124,12 @@ func NewRuleSetProvider(name string, behavior P.RuleType, interval time.Duration
onUpdate := func(elm interface{}) error {
rulesRaw := elm.([]string)
rp.count = len(rulesRaw)
rules, err := constructRules(rp.behavior, rulesRaw)
if err != nil {
return err
}
rp.count = len(rulesRaw)
rp.setRules(rules)
return nil
}