mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-11-04 20:19:19 +02:00
cd4631ce99
* DNS: add clientip for specific nameserver * Refactoring: DNS App * DNS: add DNS over QUIC support * Feat: add disableCache option for DNS * Feat: add queryStrategy option for DNS * Feat: add disableFallback & skipFallback option for DNS * Feat: DNS hosts support multiple addresses * Feat: DNS transport over TCP * DNS: fix typo & refine code * DNS: refine code * Add disableFallbackIfMatch dns option * Feat: routing and freedom outbound ignore Fake DNS Turn off fake DNS for request sent from Routing and Freedom outbound. Fake DNS now only apply to DNS outbound. This is important for Android, where VPN service take over all system DNS traffic and pass it to core. "UseIp" option can be used in Freedom outbound to avoid getting fake IP and fail connection. * Fix test * Fix dns return * Fix local dns return empty * Apply timeout to dns outbound * Update app/dns/config.go Co-authored-by: Loyalsoldier <10487845+loyalsoldier@users.noreply.github.com> Co-authored-by: Ye Zhihao <vigilans@foxmail.com> Co-authored-by: maskedeken <52683904+maskedeken@users.noreply.github.com> Co-authored-by: V2Fly Team <51714622+vcptr@users.noreply.github.com> Co-authored-by: CalmLong <37164399+calmlong@users.noreply.github.com> Co-authored-by: Shelikhoo <xiaokangwang@outlook.com> Co-authored-by: 秋のかえで <autmaple@protonmail.com> Co-authored-by: 朱聖黎 <digglife@gmail.com> Co-authored-by: rurirei <72071920+rurirei@users.noreply.github.com> Co-authored-by: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Co-authored-by: Arthur Morgan <4637240+badO1a5A90@users.noreply.github.com>
209 lines
5.1 KiB
Go
209 lines
5.1 KiB
Go
package router_test
|
|
|
|
import (
|
|
"context"
|
|
"github.com/xtls/xray-core/features/dns"
|
|
"testing"
|
|
|
|
"github.com/golang/mock/gomock"
|
|
|
|
. "github.com/xtls/xray-core/app/router"
|
|
"github.com/xtls/xray-core/common"
|
|
"github.com/xtls/xray-core/common/net"
|
|
"github.com/xtls/xray-core/common/session"
|
|
"github.com/xtls/xray-core/features/outbound"
|
|
routing_session "github.com/xtls/xray-core/features/routing/session"
|
|
"github.com/xtls/xray-core/testing/mocks"
|
|
)
|
|
|
|
type mockOutboundManager struct {
|
|
outbound.Manager
|
|
outbound.HandlerSelector
|
|
}
|
|
|
|
func TestSimpleRouter(t *testing.T) {
|
|
config := &Config{
|
|
Rule: []*RoutingRule{
|
|
{
|
|
TargetTag: &RoutingRule_Tag{
|
|
Tag: "test",
|
|
},
|
|
Networks: []net.Network{net.Network_TCP},
|
|
},
|
|
},
|
|
}
|
|
|
|
mockCtl := gomock.NewController(t)
|
|
defer mockCtl.Finish()
|
|
|
|
mockDNS := mocks.NewDNSClient(mockCtl)
|
|
mockOhm := mocks.NewOutboundManager(mockCtl)
|
|
mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
|
|
|
|
r := new(Router)
|
|
common.Must(r.Init(config, mockDNS, &mockOutboundManager{
|
|
Manager: mockOhm,
|
|
HandlerSelector: mockHs,
|
|
}))
|
|
|
|
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)})
|
|
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
|
|
common.Must(err)
|
|
if tag := route.GetOutboundTag(); tag != "test" {
|
|
t.Error("expect tag 'test', bug actually ", tag)
|
|
}
|
|
}
|
|
|
|
func TestSimpleBalancer(t *testing.T) {
|
|
config := &Config{
|
|
Rule: []*RoutingRule{
|
|
{
|
|
TargetTag: &RoutingRule_BalancingTag{
|
|
BalancingTag: "balance",
|
|
},
|
|
Networks: []net.Network{net.Network_TCP},
|
|
},
|
|
},
|
|
BalancingRule: []*BalancingRule{
|
|
{
|
|
Tag: "balance",
|
|
OutboundSelector: []string{"test-"},
|
|
},
|
|
},
|
|
}
|
|
|
|
mockCtl := gomock.NewController(t)
|
|
defer mockCtl.Finish()
|
|
|
|
mockDNS := mocks.NewDNSClient(mockCtl)
|
|
mockOhm := mocks.NewOutboundManager(mockCtl)
|
|
mockHs := mocks.NewOutboundHandlerSelector(mockCtl)
|
|
|
|
mockHs.EXPECT().Select(gomock.Eq([]string{"test-"})).Return([]string{"test"})
|
|
|
|
r := new(Router)
|
|
common.Must(r.Init(config, mockDNS, &mockOutboundManager{
|
|
Manager: mockOhm,
|
|
HandlerSelector: mockHs,
|
|
}))
|
|
|
|
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)})
|
|
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
|
|
common.Must(err)
|
|
if tag := route.GetOutboundTag(); tag != "test" {
|
|
t.Error("expect tag 'test', bug actually ", tag)
|
|
}
|
|
}
|
|
|
|
func TestIPOnDemand(t *testing.T) {
|
|
config := &Config{
|
|
DomainStrategy: Config_IpOnDemand,
|
|
Rule: []*RoutingRule{
|
|
{
|
|
TargetTag: &RoutingRule_Tag{
|
|
Tag: "test",
|
|
},
|
|
Cidr: []*CIDR{
|
|
{
|
|
Ip: []byte{192, 168, 0, 0},
|
|
Prefix: 16,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
mockCtl := gomock.NewController(t)
|
|
defer mockCtl.Finish()
|
|
|
|
mockDNS := mocks.NewDNSClient(mockCtl)
|
|
mockDNS.EXPECT().LookupIP(gomock.Eq("example.com"), dns.IPOption{
|
|
IPv4Enable: true,
|
|
IPv6Enable: true,
|
|
FakeEnable: false,
|
|
}).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
|
|
|
|
r := new(Router)
|
|
common.Must(r.Init(config, mockDNS, nil))
|
|
|
|
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)})
|
|
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
|
|
common.Must(err)
|
|
if tag := route.GetOutboundTag(); tag != "test" {
|
|
t.Error("expect tag 'test', bug actually ", tag)
|
|
}
|
|
}
|
|
|
|
func TestIPIfNonMatchDomain(t *testing.T) {
|
|
config := &Config{
|
|
DomainStrategy: Config_IpIfNonMatch,
|
|
Rule: []*RoutingRule{
|
|
{
|
|
TargetTag: &RoutingRule_Tag{
|
|
Tag: "test",
|
|
},
|
|
Cidr: []*CIDR{
|
|
{
|
|
Ip: []byte{192, 168, 0, 0},
|
|
Prefix: 16,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
mockCtl := gomock.NewController(t)
|
|
defer mockCtl.Finish()
|
|
|
|
mockDNS := mocks.NewDNSClient(mockCtl)
|
|
mockDNS.EXPECT().LookupIP(gomock.Eq("example.com"), dns.IPOption{
|
|
IPv4Enable: true,
|
|
IPv6Enable: true,
|
|
FakeEnable: false,
|
|
}).Return([]net.IP{{192, 168, 0, 1}}, nil).AnyTimes()
|
|
|
|
r := new(Router)
|
|
common.Must(r.Init(config, mockDNS, nil))
|
|
|
|
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.DomainAddress("example.com"), 80)})
|
|
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
|
|
common.Must(err)
|
|
if tag := route.GetOutboundTag(); tag != "test" {
|
|
t.Error("expect tag 'test', bug actually ", tag)
|
|
}
|
|
}
|
|
|
|
func TestIPIfNonMatchIP(t *testing.T) {
|
|
config := &Config{
|
|
DomainStrategy: Config_IpIfNonMatch,
|
|
Rule: []*RoutingRule{
|
|
{
|
|
TargetTag: &RoutingRule_Tag{
|
|
Tag: "test",
|
|
},
|
|
Cidr: []*CIDR{
|
|
{
|
|
Ip: []byte{127, 0, 0, 0},
|
|
Prefix: 8,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
mockCtl := gomock.NewController(t)
|
|
defer mockCtl.Finish()
|
|
|
|
mockDNS := mocks.NewDNSClient(mockCtl)
|
|
|
|
r := new(Router)
|
|
common.Must(r.Init(config, mockDNS, nil))
|
|
|
|
ctx := session.ContextWithOutbound(context.Background(), &session.Outbound{Target: net.TCPDestination(net.LocalHostIP, 80)})
|
|
route, err := r.PickRoute(routing_session.AsRoutingContext(ctx))
|
|
common.Must(err)
|
|
if tag := route.GetOutboundTag(); tag != "test" {
|
|
t.Error("expect tag 'test', bug actually ", tag)
|
|
}
|
|
}
|