mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 01:15:41 +08:00
rule: optimized codes
This commit is contained in:
parent
84b00d6db6
commit
04c65fb444
@ -88,10 +88,10 @@ Use the linux server's ip as your dns server.
|
||||
|
||||
#### When client requesting to access http://example1.com (in office.rule), the whole process:
|
||||
DNS Resolving:
|
||||
1. client sends a udp dns request to linux server, and glider will receive the request(as it listen on default dns port :53)
|
||||
1. client sends a udp dns request to linux server, and glider will receive the request(as it listens on the default dns port :53)
|
||||
2. upstream dns server choice: glider will lookup it's rule config and find out the dns server to use for this domain(matched "example1.com" in office.rule, so 208.67.222.222:53 will be chosen)
|
||||
3. glider uses the forwarder in office.rule to ask 208.67.222.222:53 for the resolve answers.
|
||||
4. glider updates it's office rule config, add the resolved ip address to it.
|
||||
3. glider uses the forwarder in office.rule to ask 208.67.222.222:53 for the resolve answers(dns over proxy).
|
||||
4. glider updates it's office rule config, adds the resolved ip address to it.
|
||||
5. glider adds the resolved ip into ipset "glider", and return the dns answer to client.
|
||||
|
||||
Destination Accessing:
|
||||
|
6
go.mod
6
go.mod
@ -9,9 +9,9 @@ require (
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/xtaci/kcp-go/v5 v5.5.15
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
|
||||
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 // indirect
|
||||
golang.org/x/tools v0.0.0-20200923053713-ba800b16d873 // indirect
|
||||
golang.org/x/net v0.0.0-20200923182212-328152dc79b1 // indirect
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d // indirect
|
||||
golang.org/x/tools v0.0.0-20200923182640-463111b69878 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
)
|
||||
|
||||
|
12
go.sum
12
go.sum
@ -104,8 +104,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgN
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
|
||||
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200923182212-328152dc79b1 h1:Iu68XRPd67wN4aRGGWwwq6bZo/25jR6uu52l/j2KkUE=
|
||||
golang.org/x/net v0.0.0-20200923182212-328152dc79b1/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -120,15 +120,15 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9 h1:yi1hN8dcqI9l8klZfy4B8mJvFmmAxJEePIQQFNSd7Cs=
|
||||
golang.org/x/sys v0.0.0-20200808120158-1030fc2bf1d9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 h1:YEu4SMq7D0cmT7CBbXfcH0NZeuChAXwsHe/9XueUO6o=
|
||||
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d h1:L/IKR6COd7ubZrs2oTnTi73IhgqJ71c9s80WsQnh0Es=
|
||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c h1:iHhCR0b26amDCiiO+kBguKZom9aMF+NrFxh9zeKR/XU=
|
||||
golang.org/x/tools v0.0.0-20200425043458-8463f397d07c/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200808161706-5bf02b21f123/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200923053713-ba800b16d873 h1:Q5Sq7Lt0bkn6Ax1NAraQhKRN7xxxy1LV4guxsyFHZx4=
|
||||
golang.org/x/tools v0.0.0-20200923053713-ba800b16d873/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20200923182640-463111b69878 h1:VUw1+Jf6KJPf82mbTQMia6HCnNMv2BbAipkEZ4KTcqQ=
|
||||
golang.org/x/tools v0.0.0-20200923182640-463111b69878/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
|
10
main.go
10
main.go
@ -50,14 +50,14 @@ func main() {
|
||||
}
|
||||
|
||||
// global rule proxy
|
||||
p := rule.NewProxy(conf.Forward, &conf.StrategyConfig, conf.rules)
|
||||
pxy := rule.NewProxy(conf.Forward, &conf.StrategyConfig, conf.rules)
|
||||
|
||||
// ipset manager
|
||||
ipsetM, _ := ipset.NewManager(conf.rules)
|
||||
|
||||
// check and setup dns server
|
||||
if conf.DNS != "" {
|
||||
d, err := dns.NewServer(conf.DNS, p, &conf.DNSConfig)
|
||||
d, err := dns.NewServer(conf.DNS, pxy, &conf.DNSConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@ -81,7 +81,7 @@ func main() {
|
||||
}
|
||||
|
||||
// add a handler to update proxy rules when a domain resolved
|
||||
d.AddHandler(p.AddDomainIP)
|
||||
d.AddHandler(pxy.AddDomainIP)
|
||||
if ipsetM != nil {
|
||||
d.AddHandler(ipsetM.AddDomainIP)
|
||||
}
|
||||
@ -90,11 +90,11 @@ func main() {
|
||||
}
|
||||
|
||||
// enable checkers
|
||||
p.Check()
|
||||
pxy.Check()
|
||||
|
||||
// Proxy Servers
|
||||
for _, listen := range conf.Listen {
|
||||
local, err := proxy.ServerFromURL(listen, p)
|
||||
local, err := proxy.ServerFromURL(listen, pxy)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"github.com/nadoo/glider/common/log"
|
||||
)
|
||||
|
||||
// Direct proxy
|
||||
// Direct proxy.
|
||||
type Direct struct {
|
||||
iface *net.Interface // interface specified by user
|
||||
ip net.IP
|
||||
@ -16,7 +16,7 @@ type Direct struct {
|
||||
relayTimeout time.Duration
|
||||
}
|
||||
|
||||
// Default dialer
|
||||
// Default dialer.
|
||||
var Default = &Direct{dialTimeout: time.Second * 3}
|
||||
|
||||
// NewDirect returns a Direct dialer.
|
||||
|
@ -2,7 +2,7 @@ package proxy
|
||||
|
||||
import "net"
|
||||
|
||||
// Proxy is a dialer manager
|
||||
// Proxy is a dialer manager.
|
||||
type Proxy interface {
|
||||
// Dial connects to the given address via the proxy.
|
||||
Dial(network, addr string) (c net.Conn, dialer Dialer, err error)
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/nadoo/conflag"
|
||||
)
|
||||
|
||||
// Config of rule dialer.
|
||||
// Config is config of rule.
|
||||
type Config struct {
|
||||
Name string
|
||||
|
||||
@ -24,6 +24,19 @@ type Config struct {
|
||||
CIDR []string
|
||||
}
|
||||
|
||||
// StrategyConfig is config of strategy.
|
||||
type StrategyConfig struct {
|
||||
Strategy string
|
||||
CheckWebSite string
|
||||
CheckInterval int
|
||||
CheckTimeout int
|
||||
CheckDisabledOnly bool
|
||||
MaxFailures int
|
||||
DialTimeout int
|
||||
RelayTimeout int
|
||||
IntFace string
|
||||
}
|
||||
|
||||
// NewConfFromFile returns a new config from file.
|
||||
func NewConfFromFile(ruleFile string) (*Config, error) {
|
||||
p := &Config{Name: ruleFile}
|
||||
|
@ -12,10 +12,10 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// StatusHandler function will be called when the forwarder's status changed
|
||||
// StatusHandler function will be called when the forwarder's status changed.
|
||||
type StatusHandler func(*Forwarder)
|
||||
|
||||
// Forwarder is a forwarder
|
||||
// Forwarder associates with a `-forward` command, usually a dialer or a chain of dialers.
|
||||
type Forwarder struct {
|
||||
proxy.Dialer
|
||||
addr string
|
||||
|
@ -15,20 +15,7 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// StrategyConfig is strategy config struct.
|
||||
type StrategyConfig struct {
|
||||
Strategy string
|
||||
CheckWebSite string
|
||||
CheckInterval int
|
||||
CheckTimeout int
|
||||
CheckDisabledOnly bool
|
||||
MaxFailures int
|
||||
DialTimeout int
|
||||
RelayTimeout int
|
||||
IntFace string
|
||||
}
|
||||
|
||||
// forwarder slice orderd by priority
|
||||
// forwarder slice orderd by priority.
|
||||
type priSlice []*Forwarder
|
||||
|
||||
func (p priSlice) Len() int { return len(p) }
|
||||
@ -69,7 +56,7 @@ func NewFwdrGroup(name string, s []string, c *StrategyConfig) *FwdrGroup {
|
||||
return newFwdrGroup(name, fwdrs, c)
|
||||
}
|
||||
|
||||
// newFwdrGroup returns a new Proxy.
|
||||
// newFwdrGroup returns a new FwdrGroup.
|
||||
func newFwdrGroup(name string, fwdrs []*Forwarder, c *StrategyConfig) *FwdrGroup {
|
||||
p := &FwdrGroup{fwdrs: fwdrs, config: c}
|
||||
sort.Sort(p.fwdrs)
|
||||
@ -80,22 +67,28 @@ func newFwdrGroup(name string, fwdrs []*Forwarder, c *StrategyConfig) *FwdrGroup
|
||||
p.config.CheckWebSite += ":80"
|
||||
}
|
||||
|
||||
switch c.Strategy {
|
||||
case "rr":
|
||||
p.next = p.scheduleRR
|
||||
log.F("[strategy] %s: forward in round robin mode.", name)
|
||||
case "ha":
|
||||
p.next = p.scheduleHA
|
||||
log.F("[strategy] %s: forward in high availability mode.", name)
|
||||
case "lha":
|
||||
p.next = p.scheduleLHA
|
||||
log.F("[strategy] %s: forward in latency based high availability mode.", name)
|
||||
case "dh":
|
||||
p.next = p.scheduleDH
|
||||
log.F("[strategy] %s: forward in destination hashing mode.", name)
|
||||
default:
|
||||
p.next = p.scheduleRR
|
||||
log.F("[strategy] %s: not supported forward mode '%s', use round robin mode.", name, c.Strategy)
|
||||
// default scheduler
|
||||
p.next = p.scheduleRR
|
||||
|
||||
// if there're more than 1 forwarders, we care about the strategy.
|
||||
if count := len(fwdrs); count > 1 {
|
||||
switch c.Strategy {
|
||||
case "rr":
|
||||
p.next = p.scheduleRR
|
||||
log.F("[strategy] %s: %d forwarders forward in round robin mode.", name, count)
|
||||
case "ha":
|
||||
p.next = p.scheduleHA
|
||||
log.F("[strategy] %s: %d forwarders forward in high availability mode.", name, count)
|
||||
case "lha":
|
||||
p.next = p.scheduleLHA
|
||||
log.F("[strategy] %s: %d forwarders forward in latency based high availability mode.", name, count)
|
||||
case "dh":
|
||||
p.next = p.scheduleDH
|
||||
log.F("[strategy] %s: %d forwarders forward in destination hashing mode.", name, count)
|
||||
default:
|
||||
p.next = p.scheduleRR
|
||||
log.F("[strategy] %s: not supported forward mode '%s', use round robin mode for %d forwarders.", name, c.Strategy, count)
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range fwdrs {
|
||||
@ -129,22 +122,6 @@ func (p *FwdrGroup) NextDialer(dstAddr string) proxy.Dialer {
|
||||
return p.next(dstAddr)
|
||||
}
|
||||
|
||||
// Record records result while using the dialer from proxy.
|
||||
func (p *FwdrGroup) Record(dialer proxy.Dialer, success bool) {
|
||||
OnRecord(dialer, success)
|
||||
}
|
||||
|
||||
// OnRecord records result while using the dialer from proxy.
|
||||
func OnRecord(dialer proxy.Dialer, success bool) {
|
||||
if fwdr, ok := dialer.(*Forwarder); ok {
|
||||
if !success {
|
||||
fwdr.IncFailures()
|
||||
} else {
|
||||
fwdr.Enable()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Priority returns the active priority of dialer.
|
||||
func (p *FwdrGroup) Priority() uint32 { return atomic.LoadUint32(&p.priority) }
|
||||
|
||||
@ -170,7 +147,7 @@ func (p *FwdrGroup) init() {
|
||||
if len(p.avail) == 0 {
|
||||
// no available forwarders, set priority to 0 to check all forwarders in check func
|
||||
p.SetPriority(0)
|
||||
// log.F("[strategy] no available forwarders, please check your config file or network settings")
|
||||
// log.F("[group] no available forwarders, please check your config file or network settings")
|
||||
}
|
||||
}
|
||||
|
||||
@ -180,14 +157,14 @@ func (p *FwdrGroup) onStatusChanged(fwdr *Forwarder) {
|
||||
defer p.mu.Unlock()
|
||||
|
||||
if fwdr.Enabled() {
|
||||
log.F("[strategy] %s changed status from Disabled to Enabled ", fwdr.Addr())
|
||||
log.F("[group] %s(%d) changed status from DISABLED to ENABLED ", fwdr.Addr(), fwdr.Priority())
|
||||
if fwdr.Priority() == p.Priority() {
|
||||
p.avail = append(p.avail, fwdr)
|
||||
} else if fwdr.Priority() > p.Priority() {
|
||||
p.init()
|
||||
}
|
||||
} else {
|
||||
log.F("[strategy] %s changed status from Enabled to Disabled", fwdr.Addr())
|
||||
log.F("[group] %s(%d) changed status from ENABLED to DISABLED", fwdr.Addr(), fwdr.Priority())
|
||||
for i, f := range p.avail {
|
||||
if f == fwdr {
|
||||
p.avail[i], p.avail = p.avail[len(p.avail)-1], p.avail[:len(p.avail)-1]
|
||||
@ -250,7 +227,7 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
||||
rc, err := fwdr.Dial("tcp", website)
|
||||
if err != nil {
|
||||
fwdr.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. error in dial: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
log.F("[check] %s(%d) -> %s, FAILED. error in dial: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
website, err)
|
||||
return false
|
||||
}
|
||||
@ -263,7 +240,7 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
||||
_, err = io.WriteString(rc, "GET / HTTP/1.0\r\n\r\n")
|
||||
if err != nil {
|
||||
fwdr.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. error in write: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
log.F("[check] %s(%d) -> %s, FAILED. error in write: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
website, err)
|
||||
return false
|
||||
}
|
||||
@ -271,14 +248,14 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
||||
_, err = io.ReadFull(rc, buf)
|
||||
if err != nil {
|
||||
fwdr.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. error in read: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
log.F("[check] %s(%d) -> %s, FAILED. error in read: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
website, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if !bytes.Equal([]byte("HTTP"), buf) {
|
||||
fwdr.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. server response: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
log.F("[check] %s(%d) -> %s, FAILED. server response: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
website, buf)
|
||||
return false
|
||||
}
|
||||
@ -288,29 +265,29 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
||||
|
||||
if readTime > timeout {
|
||||
fwdr.Disable()
|
||||
log.F("[check] %s(%d) -> %s, DISABLED. check timeout: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
log.F("[check] %s(%d) -> %s, FAILED. check timeout: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
website, readTime)
|
||||
return false
|
||||
}
|
||||
|
||||
fwdr.Enable()
|
||||
log.F("[check] %s(%d) -> %s, ENABLED. connect time: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
log.F("[check] %s(%d) -> %s, SUCCEEDED. connect time: %s", fwdr.Addr(), fwdr.Priority(),
|
||||
website, readTime)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Round Robin
|
||||
// Round Robin.
|
||||
func (p *FwdrGroup) scheduleRR(dstAddr string) *Forwarder {
|
||||
return p.avail[atomic.AddUint32(&p.index, 1)%uint32(len(p.avail))]
|
||||
}
|
||||
|
||||
// High Availability
|
||||
// High Availability.
|
||||
func (p *FwdrGroup) scheduleHA(dstAddr string) *Forwarder {
|
||||
return p.avail[0]
|
||||
}
|
||||
|
||||
// Latency based High Availability
|
||||
// Latency based High Availability.
|
||||
func (p *FwdrGroup) scheduleLHA(dstAddr string) *Forwarder {
|
||||
fwdr := p.avail[0]
|
||||
lowest := fwdr.Latency()
|
||||
@ -323,7 +300,7 @@ func (p *FwdrGroup) scheduleLHA(dstAddr string) *Forwarder {
|
||||
return fwdr
|
||||
}
|
||||
|
||||
// Destination Hashing
|
||||
// Destination Hashing.
|
||||
func (p *FwdrGroup) scheduleDH(dstAddr string) *Forwarder {
|
||||
fnv1a := fnv.New32a()
|
||||
fnv1a.Write([]byte(dstAddr))
|
@ -9,7 +9,7 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// Proxy struct.
|
||||
// Proxy implements the proxy.Proxy interface with rule support.
|
||||
type Proxy struct {
|
||||
main *FwdrGroup
|
||||
all []*FwdrGroup
|
||||
@ -41,11 +41,14 @@ func NewProxy(mainForwarders []string, mainStrategy *StrategyConfig, rules []*Co
|
||||
}
|
||||
}
|
||||
|
||||
// if there's any forwarder defined in main config, make sure they will be accessed directly.
|
||||
if len(mainForwarders) > 0 {
|
||||
direct := NewFwdrGroup("backup", nil, mainStrategy)
|
||||
direct := NewFwdrGroup("", nil, mainStrategy)
|
||||
for _, f := range rd.main.fwdrs {
|
||||
// Note: the addr maybe ip address, but no matter here.
|
||||
rd.domainMap.Store(strings.ToLower(strings.Split(f.addr, ":")[0]), direct)
|
||||
host := strings.Split(f.addr, ":")[0]
|
||||
if ip := net.ParseIP(host); ip == nil {
|
||||
rd.domainMap.Store(strings.ToLower(host), direct)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,20 +57,18 @@ func NewProxy(mainForwarders []string, mainStrategy *StrategyConfig, rules []*Co
|
||||
|
||||
// Dial dials to targer addr and return a conn.
|
||||
func (p *Proxy) Dial(network, addr string) (net.Conn, proxy.Dialer, error) {
|
||||
return p.chooseProxy(addr).Dial(network, addr)
|
||||
return p.findDialer(addr).Dial(network, addr)
|
||||
}
|
||||
|
||||
// DialUDP connects to the given address via the proxy.
|
||||
func (p *Proxy) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
|
||||
return p.chooseProxy(addr).DialUDP(network, addr)
|
||||
return p.findDialer(addr).DialUDP(network, addr)
|
||||
}
|
||||
|
||||
// chooseProxy returns a proxy according to rule.
|
||||
func (p *Proxy) chooseProxy(dstAddr string) *FwdrGroup {
|
||||
// findDialer returns a dialer by dstAddr according to rule.
|
||||
func (p *Proxy) findDialer(dstAddr string) *FwdrGroup {
|
||||
host, _, err := net.SplitHostPort(dstAddr)
|
||||
if err != nil {
|
||||
// TODO: check here
|
||||
// logf("[rule] SplitHostPort ERROR: %s", err)
|
||||
return p.main
|
||||
}
|
||||
|
||||
@ -86,7 +87,6 @@ func (p *Proxy) chooseProxy(dstAddr string) *FwdrGroup {
|
||||
ret = value.(*FwdrGroup)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
@ -109,12 +109,18 @@ func (p *Proxy) chooseProxy(dstAddr string) *FwdrGroup {
|
||||
|
||||
// NextDialer returns next dialer according to rule.
|
||||
func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
|
||||
return p.chooseProxy(dstAddr).NextDialer(dstAddr)
|
||||
return p.findDialer(dstAddr).NextDialer(dstAddr)
|
||||
}
|
||||
|
||||
// Record records result while using the dialer from proxy.
|
||||
func (p *Proxy) Record(dialer proxy.Dialer, success bool) {
|
||||
OnRecord(dialer, success)
|
||||
if fwdr, ok := dialer.(*Forwarder); ok {
|
||||
if !success {
|
||||
fwdr.IncFailures()
|
||||
return
|
||||
}
|
||||
fwdr.Enable()
|
||||
}
|
||||
}
|
||||
|
||||
// AddDomainIP used to update ipMap rules according to domainMap rule.
|
||||
@ -125,18 +131,19 @@ func (p *Proxy) AddDomainIP(domain, ip string) error {
|
||||
i = strings.LastIndexByte(domain[:i], '.')
|
||||
if dialer, ok := p.domainMap.Load(domain[i+1:]); ok {
|
||||
p.ipMap.Store(ip, dialer)
|
||||
log.F("[rule] add ip=%s, based on rule: domain=%s & domain/ip: %s/%s\n", ip, domain[i+1:], domain, ip)
|
||||
log.F("[rule] add ip=%s, based on rule: domain=%s & domain/ip: %s/%s\n",
|
||||
ip, domain[i+1:], domain, ip)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check .
|
||||
// Check checks availability of forwarders inside proxy.
|
||||
func (p *Proxy) Check() {
|
||||
p.main.Check()
|
||||
|
||||
for _, fwdr := range p.all {
|
||||
fwdr.Check()
|
||||
for _, fwdrGroup := range p.all {
|
||||
fwdrGroup.Check()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user