Skip to content

Commit

Permalink
add domain_strategy
Browse files Browse the repository at this point in the history
  • Loading branch information
p4gefau1t committed May 14, 2020
1 parent 117b2b6 commit c0b9c1c
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 61 deletions.
17 changes: 8 additions & 9 deletions conf/conf.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,14 @@ type CompressionConfig struct {
}

type RouterConfig struct {
Enabled bool `json:"enabled"`
Bypass []string `json:"bypass"`
Proxy []string `json:"proxy"`
Block []string `json:"block"`
DefaultPolicy string `json:"default_policy"`
RouteByIP bool `json:"route_by_ip"`
RouteByIPOnNonmatch bool `json:"route_by_ip_on_nonmatch"`
GeoIPFilename string `json:"geoip"`
GeoSiteFilename string `json:"geosite"`
Enabled bool `json:"enabled"`
Bypass []string `json:"bypass"`
Proxy []string `json:"proxy"`
Block []string `json:"block"`
DomainStrategy string `json:"domain_strategy"`
DefaultPolicy string `json:"default_policy"`
GeoIPFilename string `json:"geoip"`
GeoSiteFilename string `json:"geosite"`

BypassList []byte
ProxyList []byte
Expand Down
1 change: 1 addition & 0 deletions conf/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ func ParseJSON(data []byte) (*GlobalConfig, error) {
},
Router: RouterConfig{
DefaultPolicy: "proxy",
DomainStrategy: "as_is",
GeoIPFilename: common.GetProgramDir() + "/geoip.dat",
GeoSiteFilename: common.GetProgramDir() + "/geosite.dat",
},
Expand Down
27 changes: 17 additions & 10 deletions docs/content/basic/full-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,10 @@ weight: 30
"bypass": [],
"proxy": [],
"block": [],
"route_by_ip": false,
"route_by_ip_on_nonmatch": false,
"default_policy": "proxy"
"default_policy": "proxy",
"domain_strategy": "as_is",
"geoip": "./geoip.dat",
"geosite": "./geoip.dat"
},
"websocket": {
"enabled": false,
Expand Down Expand Up @@ -173,15 +174,15 @@ weight: 30

```fingerprint```用于指定TLS Client Hello指纹伪造类型,以抵抗GFW对于TLS Client Hello指纹的特征识别和阻断。trojan-go使用[utls](https://github.com/refraction-networking/utls)进行指纹伪造。合法的值有

- ""(空),默认,不使用指纹伪造
- "",不使用指纹伪造

- "auto",自动选择(推荐)

- "firefox",伪造Firefox指纹

- "chrome",伪造Chrome指纹

- "ios",伪造ios指纹
- "ios",伪造iOS指纹

- "randomized",随机指纹

Expand Down Expand Up @@ -215,11 +216,7 @@ weight: 30

```enabled```是否开启路由模块。

```route_by_ip```开启后,所有域名会被在本地解析为IP后,仅使用IP列表进行匹配。如果开启这个选项,可能导致DNS请求泄露和遭到污染。

```route_by_ip_on_nonmatch```开启后,如果一个域名不在三个列表中,则会被在本地解析为IP后,仅使用IP列表进行匹配。如果开启这个选项,可能导致DNS请求泄露和遭到污染。

```default_policy```指的是三个列表匹配均失败后,使用的默认策略,默认为Proxy,即进行代理。合法的值有
```default_policy```指的是三个列表匹配均失败后,使用的默认策略,默认为"bypass",即进行代理。合法的值有

- "proxy"

Expand All @@ -229,6 +226,16 @@ weight: 30

含义同上。

```domain_strategy```域名解析策略,默认"as_is"。合法的值有:

- "as_is",只在域名列表中进行匹配。

- "ip_if_nonmatch",在域名列表中进行匹配,如果不匹配,解析为IP后在IP列表中匹配。该策略可能导致DNS泄漏或遭到污染。

- "ip_on_demand",域名均解析为IP,在IP列表中匹配。该策略可能导致DNS泄漏或遭到污染。

```geoip``````geosite```字段指geoip和geosite数据库文件路径,默认使用当前目录的geoip.dat和geosite.dat。

### ```websocket```选项

Websocket传输是trojan-go的特性。在**正常的直接连接代理节点**的情况下,开启这个选项不会改善你的链路速度(甚至有可能下降),也不会提升你的连接安全性。你只应该在下面两种情况下启用它:
Expand Down
28 changes: 13 additions & 15 deletions router/mixed/geo.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ import (
)

type GeoRouter struct {
domains []*v2router.Domain
cidrs []*v2router.CIDR
matchPolicy router.Policy
nonMatchPolicy router.Policy
routeByIP bool
routeByIPOnNonmatch bool
domains []*v2router.Domain
cidrs []*v2router.CIDR
matchPolicy router.Policy
nonMatchPolicy router.Policy
strategy router.Strategy
}

func (r *GeoRouter) matchDomain(fulldomain string) bool {
Expand Down Expand Up @@ -64,11 +63,11 @@ func (r *GeoRouter) matchIP(ip net.IP) bool {
n := int(c.GetPrefix())
mask := net.CIDRMask(n, 8*len)
cidrIP := net.IP(c.GetIp())
if cidrIP.To4() != nil { //cidr is ipv4
if cidrIP.To4() != nil { //IPv4 CIDR
if isIPv6 {
continue
}
} else { //cidr is ipv6
} else { //IPv6 CIDR
if !isIPv6 {
continue
}
Expand Down Expand Up @@ -105,13 +104,13 @@ func (r *GeoRouter) RouteRequest(req *protocol.Request) (router.Policy, error) {
switch req.AddressType {
case common.DomainName:
domain := string(req.DomainName)
if r.routeByIP {
if r.strategy == router.IPOnDemand {
return r.routeRequestByIP(domain)
}
if r.matchDomain(domain) {
return r.matchPolicy, nil
}
if r.routeByIPOnNonmatch {
if r.strategy == router.IPIfNonMatch {
return r.routeRequestByIP(domain)
}
return r.nonMatchPolicy, nil
Expand Down Expand Up @@ -173,12 +172,11 @@ func (r *GeoRouter) LoadGeoData(geoipData []byte, ipCode []string, geositeData [
return nil
}

func NewGeoRouter(matchPolicy router.Policy, nonMatchPolicy router.Policy, routeByIP bool, routeByIPOnNonmatch bool) (*GeoRouter, error) {
func NewGeoRouter(matchPolicy router.Policy, nonMatchPolicy router.Policy, strategy router.Strategy) (*GeoRouter, error) {
r := GeoRouter{
matchPolicy: matchPolicy,
nonMatchPolicy: nonMatchPolicy,
routeByIP: routeByIP,
routeByIPOnNonmatch: routeByIPOnNonmatch,
matchPolicy: matchPolicy,
nonMatchPolicy: nonMatchPolicy,
strategy: strategy,
}
return &r, nil
}
2 changes: 1 addition & 1 deletion router/mixed/geo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestGeoRouter(t *testing.T) {
r, err := NewGeoRouter(router.Bypass, router.Proxy, false, false)
r, err := NewGeoRouter(router.Bypass, router.Proxy, router.IPIfNonMatch)
common.Must(err)
geoipData, err := ioutil.ReadFile("geoip.dat")
common.Must(err)
Expand Down
24 changes: 11 additions & 13 deletions router/mixed/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import (

type ListRouter struct {
router.Router
domainList []string
ipList []*net.IPNet
matchPolicy router.Policy
nonMatchPolicy router.Policy
routeByIP bool
routeByIPOnNonmatch bool
domainList []string
ipList []*net.IPNet
matchPolicy router.Policy
nonMatchPolicy router.Policy
strategy router.Strategy
}

func (r *ListRouter) isSubdomain(fulldomain, domain string) bool {
Expand All @@ -42,7 +41,7 @@ func (r *ListRouter) RouteRequest(req *protocol.Request) (router.Policy, error)
}
return r.nonMatchPolicy, nil
}
if r.routeByIP {
if r.strategy == router.IPOnDemand {
addr, err := net.ResolveIPAddr("ip", domain)
if err != nil {
return router.Unknown, err
Expand All @@ -63,7 +62,7 @@ func (r *ListRouter) RouteRequest(req *protocol.Request) (router.Policy, error)
return r.matchPolicy, nil
}
}
if r.routeByIPOnNonmatch {
if r.strategy == router.IPIfNonMatch {
addr, err := net.ResolveIPAddr("ip", domain)
if err != nil {
return router.Unknown, err
Expand Down Expand Up @@ -116,12 +115,11 @@ func (r *ListRouter) LoadList(data []byte) error {
return nil
}

func NewListRouter(matchPolicy router.Policy, nonMatchPolicy router.Policy, routeByIP bool, routeByIPOnNonmatch bool, list []byte) (*ListRouter, error) {
func NewListRouter(matchPolicy router.Policy, nonMatchPolicy router.Policy, strategy router.Strategy, list []byte) (*ListRouter, error) {
r := ListRouter{
matchPolicy: matchPolicy,
nonMatchPolicy: nonMatchPolicy,
routeByIP: routeByIP,
routeByIPOnNonmatch: routeByIPOnNonmatch,
matchPolicy: matchPolicy,
nonMatchPolicy: nonMatchPolicy,
strategy: strategy,
}
if err := r.LoadList(list); err != nil {
return nil, err
Expand Down
28 changes: 19 additions & 9 deletions router/mixed/mixed.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ func (r *MixedRouter) match(rr router.Router, req *protocol.Request) bool {
}

func (r *MixedRouter) RouteRequest(req *protocol.Request) (router.Policy, error) {

if r.match(r.blockGeo, req) {
return router.Block, nil
}
Expand Down Expand Up @@ -66,10 +65,21 @@ func NewMixedRouter(config *conf.RouterConfig) (router.Router, error) {
defaultPolicy = router.Bypass
case "block":
defaultPolicy = router.Block
default:
return nil, common.NewError("Invalid router policy " + config.DefaultPolicy)
}

routeByIP := config.RouteByIP
routeByIPOnNonmatch := config.RouteByIPOnNonmatch
var strategy router.Strategy
switch config.DomainStrategy {
case "as_is":
strategy = router.AsIs
case "ip_if_nonmatch":
strategy = router.IPIfNonMatch
case "ip_on_demand":
strategy = router.IPOnDemand
default:
return nil, common.NewError("Invalid domain strategy " + config.DomainStrategy)
}

block := config.BlockList
bypass := config.BypassList
Expand All @@ -80,19 +90,19 @@ func NewMixedRouter(config *conf.RouterConfig) (router.Router, error) {
}

var err error
if r.blockList, err = NewListRouter(router.Match, router.NonMatch, routeByIP, routeByIPOnNonmatch, block); err != nil {
if r.blockList, err = NewListRouter(router.Match, router.NonMatch, strategy, block); err != nil {
return nil, err
}
if r.bypassList, err = NewListRouter(router.Match, router.NonMatch, routeByIP, routeByIPOnNonmatch, bypass); err != nil {
if r.bypassList, err = NewListRouter(router.Match, router.NonMatch, strategy, bypass); err != nil {
return nil, err
}
if r.proxyList, err = NewListRouter(router.Match, router.NonMatch, routeByIP, routeByIPOnNonmatch, proxy); err != nil {
if r.proxyList, err = NewListRouter(router.Match, router.NonMatch, strategy, proxy); err != nil {
return nil, err
}

r.blockGeo, _ = NewGeoRouter(router.Match, router.NonMatch, routeByIP, false)
r.bypassGeo, _ = NewGeoRouter(router.Match, router.NonMatch, routeByIP, routeByIPOnNonmatch)
r.proxyGeo, _ = NewGeoRouter(router.Match, router.NonMatch, routeByIP, routeByIPOnNonmatch)
r.blockGeo, _ = NewGeoRouter(router.Match, router.NonMatch, strategy)
r.bypassGeo, _ = NewGeoRouter(router.Match, router.NonMatch, strategy)
r.proxyGeo, _ = NewGeoRouter(router.Match, router.NonMatch, strategy)

if err := r.blockGeo.LoadGeoData(config.GeoIP, config.BlockIPCode, config.GeoSite, config.BlockSiteCode); err != nil {
log.Warn(err)
Expand Down
15 changes: 11 additions & 4 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
)

type Policy int
type Strategy int

const (
Proxy Policy = iota
Expand All @@ -17,18 +18,24 @@ const (
NonMatch
)

const (
AsIs Strategy = iota
IPIfNonMatch
IPOnDemand
)

type EmptyRouter struct{}

func (r *EmptyRouter) RouteRequest(req *protocol.Request) (Policy, error) {
return Proxy, nil
}

func NewEmptyRouter(*conf.RouterConfig) (Router, error) {
return &EmptyRouter{}, nil
}

type Router interface {
RouteRequest(*protocol.Request) (Policy, error)
}

var NewRouter func(config *conf.RouterConfig) (Router, error) = NewEmptyRouter

func NewEmptyRouter(*conf.RouterConfig) (Router, error) {
return &EmptyRouter{}, nil
}

0 comments on commit c0b9c1c

Please sign in to comment.