mirror of
https://github.com/nadoo/glider.git
synced 2025-02-23 01:15:41 +08:00
general: use builtin dns when it enabled. (#184)
This commit is contained in:
parent
89114e678b
commit
84b00d6db6
3
conf.go
3
conf.go
@ -10,7 +10,6 @@ import (
|
||||
|
||||
"github.com/nadoo/glider/dns"
|
||||
"github.com/nadoo/glider/rule"
|
||||
"github.com/nadoo/glider/strategy"
|
||||
)
|
||||
|
||||
var flag = conflag.New()
|
||||
@ -21,7 +20,7 @@ var conf struct {
|
||||
Listen []string
|
||||
|
||||
Forward []string
|
||||
StrategyConfig strategy.Config
|
||||
StrategyConfig rule.StrategyConfig
|
||||
|
||||
RuleFile []string
|
||||
RulesDir string
|
||||
|
4
go.mod
4
go.mod
@ -10,8 +10,8 @@ require (
|
||||
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-20200909081042-eff7692f9009 // indirect
|
||||
golang.org/x/tools v0.0.0-20200913032122-97363e29fc9b // indirect
|
||||
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860 // indirect
|
||||
golang.org/x/tools v0.0.0-20200923053713-ba800b16d873 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
)
|
||||
|
||||
|
8
go.sum
8
go.sum
@ -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-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/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/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-20200913032122-97363e29fc9b h1:3/5GThpuWHBq2GFcurHBWuWlzdbln+Er+cyzGqQAPOs=
|
||||
golang.org/x/tools v0.0.0-20200913032122-97363e29fc9b/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
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/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=
|
||||
|
17
main.go
17
main.go
@ -1,18 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
stdlog "log"
|
||||
"net"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/nadoo/glider/common/log"
|
||||
"github.com/nadoo/glider/dns"
|
||||
"github.com/nadoo/glider/ipset"
|
||||
"github.com/nadoo/glider/proxy"
|
||||
"github.com/nadoo/glider/rule"
|
||||
"github.com/nadoo/glider/strategy"
|
||||
|
||||
// comment out the protocol you don't need to make the compiled binary smaller.
|
||||
_ "github.com/nadoo/glider/proxy/http"
|
||||
@ -34,7 +36,7 @@ import (
|
||||
_ "github.com/nadoo/glider/proxy/ws"
|
||||
)
|
||||
|
||||
var version = "0.10.4"
|
||||
var version = "0.11.0"
|
||||
|
||||
func main() {
|
||||
// read configs
|
||||
@ -48,7 +50,7 @@ func main() {
|
||||
}
|
||||
|
||||
// global rule proxy
|
||||
p := rule.NewProxy(conf.rules, strategy.NewProxy("default", conf.Forward, &conf.StrategyConfig))
|
||||
p := rule.NewProxy(conf.Forward, &conf.StrategyConfig, conf.rules)
|
||||
|
||||
// ipset manager
|
||||
ipsetM, _ := ipset.NewManager(conf.rules)
|
||||
@ -69,6 +71,15 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// custom resolver
|
||||
net.DefaultResolver = &net.Resolver{
|
||||
PreferGo: true,
|
||||
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
d := net.Dialer{Timeout: time.Second * 3}
|
||||
return d.DialContext(ctx, "udp", conf.DNS)
|
||||
},
|
||||
}
|
||||
|
||||
// add a handler to update proxy rules when a domain resolved
|
||||
d.AddHandler(p.AddDomainIP)
|
||||
if ipsetM != nil {
|
||||
|
@ -37,12 +37,12 @@ type UDPDialer interface {
|
||||
type DialerCreator func(s string, dialer Dialer) (Dialer, error)
|
||||
|
||||
var (
|
||||
dialerMap = make(map[string]DialerCreator)
|
||||
dialerCreators = make(map[string]DialerCreator)
|
||||
)
|
||||
|
||||
// RegisterDialer is used to register a dialer.
|
||||
func RegisterDialer(name string, c DialerCreator) {
|
||||
dialerMap[name] = c
|
||||
dialerCreators[name] = c
|
||||
}
|
||||
|
||||
// DialerFromURL calls the registered creator to create dialers.
|
||||
@ -58,7 +58,7 @@ func DialerFromURL(s string, dialer Dialer) (Dialer, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, ok := dialerMap[strings.ToLower(u.Scheme)]
|
||||
c, ok := dialerCreators[strings.ToLower(u.Scheme)]
|
||||
if ok {
|
||||
return c(s, dialer)
|
||||
}
|
||||
|
@ -22,12 +22,12 @@ type Server interface {
|
||||
type ServerCreator func(s string, proxy Proxy) (Server, error)
|
||||
|
||||
var (
|
||||
serverMap = make(map[string]ServerCreator)
|
||||
serverCreators = make(map[string]ServerCreator)
|
||||
)
|
||||
|
||||
// RegisterServer is used to register a proxy server
|
||||
func RegisterServer(name string, c ServerCreator) {
|
||||
serverMap[name] = c
|
||||
serverCreators[name] = c
|
||||
}
|
||||
|
||||
// ServerFromURL calls the registered creator to create proxy servers
|
||||
@ -47,7 +47,7 @@ func ServerFromURL(s string, p Proxy) (Server, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, ok := serverMap[strings.ToLower(u.Scheme)]
|
||||
c, ok := serverCreators[strings.ToLower(u.Scheme)]
|
||||
if ok {
|
||||
return c(s, p)
|
||||
}
|
||||
|
@ -7,8 +7,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/nadoo/conflag"
|
||||
|
||||
"github.com/nadoo/glider/strategy"
|
||||
)
|
||||
|
||||
// Config of rule dialer.
|
||||
@ -16,7 +14,7 @@ type Config struct {
|
||||
Name string
|
||||
|
||||
Forward []string
|
||||
StrategyConfig strategy.Config
|
||||
StrategyConfig StrategyConfig
|
||||
|
||||
DNSServers []string
|
||||
IPSet string
|
||||
|
@ -1,4 +1,4 @@
|
||||
package strategy
|
||||
package rule
|
||||
|
||||
import (
|
||||
"net"
|
60
rule/rule.go
60
rule/rule.go
@ -7,77 +7,83 @@ import (
|
||||
|
||||
"github.com/nadoo/glider/common/log"
|
||||
"github.com/nadoo/glider/proxy"
|
||||
"github.com/nadoo/glider/strategy"
|
||||
)
|
||||
|
||||
// Proxy struct.
|
||||
type Proxy struct {
|
||||
proxy *strategy.Proxy
|
||||
proxies []*strategy.Proxy
|
||||
|
||||
main *FwdrGroup
|
||||
all []*FwdrGroup
|
||||
domainMap sync.Map
|
||||
ipMap sync.Map
|
||||
cidrMap sync.Map
|
||||
}
|
||||
|
||||
// NewProxy returns a new rule proxy.
|
||||
func NewProxy(rules []*Config, proxy *strategy.Proxy) *Proxy {
|
||||
rd := &Proxy{proxy: proxy}
|
||||
func NewProxy(mainForwarders []string, mainStrategy *StrategyConfig, rules []*Config) *Proxy {
|
||||
rd := &Proxy{main: NewFwdrGroup("main", mainForwarders, mainStrategy)}
|
||||
|
||||
for _, r := range rules {
|
||||
sd := strategy.NewProxy(r.Name, r.Forward, &r.StrategyConfig)
|
||||
rd.proxies = append(rd.proxies, sd)
|
||||
group := NewFwdrGroup(r.Name, r.Forward, &r.StrategyConfig)
|
||||
rd.all = append(rd.all, group)
|
||||
|
||||
for _, domain := range r.Domain {
|
||||
rd.domainMap.Store(strings.ToLower(domain), sd)
|
||||
rd.domainMap.Store(strings.ToLower(domain), group)
|
||||
}
|
||||
|
||||
for _, ip := range r.IP {
|
||||
rd.ipMap.Store(ip, sd)
|
||||
rd.ipMap.Store(ip, group)
|
||||
}
|
||||
|
||||
for _, s := range r.CIDR {
|
||||
if _, cidr, err := net.ParseCIDR(s); err == nil {
|
||||
rd.cidrMap.Store(cidr, sd)
|
||||
rd.cidrMap.Store(cidr, group)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(mainForwarders) > 0 {
|
||||
direct := NewFwdrGroup("backup", 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)
|
||||
}
|
||||
}
|
||||
|
||||
return rd
|
||||
}
|
||||
|
||||
// Dial dials to targer addr and return a conn.
|
||||
func (p *Proxy) Dial(network, addr string) (net.Conn, proxy.Dialer, error) {
|
||||
return p.nextProxy(addr).Dial(network, addr)
|
||||
return p.chooseProxy(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.nextProxy(addr).DialUDP(network, addr)
|
||||
return p.chooseProxy(addr).DialUDP(network, addr)
|
||||
}
|
||||
|
||||
// nextProxy return next proxy according to rule.
|
||||
func (p *Proxy) nextProxy(dstAddr string) *strategy.Proxy {
|
||||
// chooseProxy returns a proxy according to rule.
|
||||
func (p *Proxy) chooseProxy(dstAddr string) *FwdrGroup {
|
||||
host, _, err := net.SplitHostPort(dstAddr)
|
||||
if err != nil {
|
||||
// TODO: check here
|
||||
// logf("[rule] SplitHostPort ERROR: %s", err)
|
||||
return p.proxy
|
||||
return p.main
|
||||
}
|
||||
|
||||
// find ip
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
// check ip
|
||||
if proxy, ok := p.ipMap.Load(ip.String()); ok {
|
||||
return proxy.(*strategy.Proxy)
|
||||
return proxy.(*FwdrGroup)
|
||||
}
|
||||
|
||||
var ret *strategy.Proxy
|
||||
var ret *FwdrGroup
|
||||
// check cidr
|
||||
p.cidrMap.Range(func(key, value interface{}) bool {
|
||||
cidr := key.(*net.IPNet)
|
||||
if cidr.Contains(ip) {
|
||||
ret = value.(*strategy.Proxy)
|
||||
ret = value.(*FwdrGroup)
|
||||
return false
|
||||
}
|
||||
|
||||
@ -94,21 +100,21 @@ func (p *Proxy) nextProxy(dstAddr string) *strategy.Proxy {
|
||||
for i := len(host); i != -1; {
|
||||
i = strings.LastIndexByte(host[:i], '.')
|
||||
if proxy, ok := p.domainMap.Load(host[i+1:]); ok {
|
||||
return proxy.(*strategy.Proxy)
|
||||
return proxy.(*FwdrGroup)
|
||||
}
|
||||
}
|
||||
|
||||
return p.proxy
|
||||
return p.main
|
||||
}
|
||||
|
||||
// NextDialer return next dialer according to rule.
|
||||
// NextDialer returns next dialer according to rule.
|
||||
func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
|
||||
return p.nextProxy(dstAddr).NextDialer(dstAddr)
|
||||
return p.chooseProxy(dstAddr).NextDialer(dstAddr)
|
||||
}
|
||||
|
||||
// Record records result while using the dialer from proxy.
|
||||
func (p *Proxy) Record(dialer proxy.Dialer, success bool) {
|
||||
strategy.OnRecord(dialer, success)
|
||||
OnRecord(dialer, success)
|
||||
}
|
||||
|
||||
// AddDomainIP used to update ipMap rules according to domainMap rule.
|
||||
@ -128,9 +134,9 @@ func (p *Proxy) AddDomainIP(domain, ip string) error {
|
||||
|
||||
// Check .
|
||||
func (p *Proxy) Check() {
|
||||
p.proxy.Check()
|
||||
p.main.Check()
|
||||
|
||||
for _, d := range p.proxies {
|
||||
d.Check()
|
||||
for _, fwdr := range p.all {
|
||||
fwdr.Check()
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package strategy
|
||||
package rule
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -15,8 +15,8 @@ import (
|
||||
"github.com/nadoo/glider/proxy"
|
||||
)
|
||||
|
||||
// Config is strategy config struct.
|
||||
type Config struct {
|
||||
// StrategyConfig is strategy config struct.
|
||||
type StrategyConfig struct {
|
||||
Strategy string
|
||||
CheckWebSite string
|
||||
CheckInterval int
|
||||
@ -35,9 +35,9 @@ func (p priSlice) Len() int { return len(p) }
|
||||
func (p priSlice) Less(i, j int) bool { return p[i].Priority() > p[j].Priority() }
|
||||
func (p priSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
|
||||
|
||||
// Proxy is base proxy struct.
|
||||
type Proxy struct {
|
||||
config *Config
|
||||
// FwdrGroup is a forwarder group.
|
||||
type FwdrGroup struct {
|
||||
config *StrategyConfig
|
||||
fwdrs priSlice
|
||||
avail []*Forwarder // available forwarders
|
||||
mu sync.RWMutex
|
||||
@ -46,8 +46,8 @@ type Proxy struct {
|
||||
next func(addr string) *Forwarder
|
||||
}
|
||||
|
||||
// NewProxy returns a new strategy proxy.
|
||||
func NewProxy(name string, s []string, c *Config) *Proxy {
|
||||
// NewFwdrGroup returns a new forward group.
|
||||
func NewFwdrGroup(name string, s []string, c *StrategyConfig) *FwdrGroup {
|
||||
var fwdrs []*Forwarder
|
||||
for _, chain := range s {
|
||||
fwdr, err := ForwarderFromURL(chain, c.IntFace,
|
||||
@ -66,12 +66,12 @@ func NewProxy(name string, s []string, c *Config) *Proxy {
|
||||
c.Strategy = "rr"
|
||||
}
|
||||
|
||||
return newProxy(name, fwdrs, c)
|
||||
return newFwdrGroup(name, fwdrs, c)
|
||||
}
|
||||
|
||||
// newProxy returns a new Proxy.
|
||||
func newProxy(name string, fwdrs []*Forwarder, c *Config) *Proxy {
|
||||
p := &Proxy{fwdrs: fwdrs, config: c}
|
||||
// newFwdrGroup returns a new Proxy.
|
||||
func newFwdrGroup(name string, fwdrs []*Forwarder, c *StrategyConfig) *FwdrGroup {
|
||||
p := &FwdrGroup{fwdrs: fwdrs, config: c}
|
||||
sort.Sort(p.fwdrs)
|
||||
|
||||
p.init()
|
||||
@ -106,19 +106,19 @@ func newProxy(name string, fwdrs []*Forwarder, c *Config) *Proxy {
|
||||
}
|
||||
|
||||
// Dial connects to the address addr on the network net.
|
||||
func (p *Proxy) Dial(network, addr string) (net.Conn, proxy.Dialer, error) {
|
||||
func (p *FwdrGroup) Dial(network, addr string) (net.Conn, proxy.Dialer, error) {
|
||||
nd := p.NextDialer(addr)
|
||||
c, err := nd.Dial(network, addr)
|
||||
return c, nd, err
|
||||
}
|
||||
|
||||
// DialUDP connects to the given address.
|
||||
func (p *Proxy) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
|
||||
func (p *FwdrGroup) DialUDP(network, addr string) (pc net.PacketConn, writeTo net.Addr, err error) {
|
||||
return p.NextDialer(addr).DialUDP(network, addr)
|
||||
}
|
||||
|
||||
// NextDialer returns the next dialer.
|
||||
func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
|
||||
func (p *FwdrGroup) NextDialer(dstAddr string) proxy.Dialer {
|
||||
p.mu.RLock()
|
||||
defer p.mu.RUnlock()
|
||||
|
||||
@ -130,7 +130,7 @@ func (p *Proxy) NextDialer(dstAddr string) proxy.Dialer {
|
||||
}
|
||||
|
||||
// Record records result while using the dialer from proxy.
|
||||
func (p *Proxy) Record(dialer proxy.Dialer, success bool) {
|
||||
func (p *FwdrGroup) Record(dialer proxy.Dialer, success bool) {
|
||||
OnRecord(dialer, success)
|
||||
}
|
||||
|
||||
@ -146,13 +146,13 @@ func OnRecord(dialer proxy.Dialer, success bool) {
|
||||
}
|
||||
|
||||
// Priority returns the active priority of dialer.
|
||||
func (p *Proxy) Priority() uint32 { return atomic.LoadUint32(&p.priority) }
|
||||
func (p *FwdrGroup) Priority() uint32 { return atomic.LoadUint32(&p.priority) }
|
||||
|
||||
// SetPriority sets the active priority of daler.
|
||||
func (p *Proxy) SetPriority(pri uint32) { atomic.StoreUint32(&p.priority, pri) }
|
||||
func (p *FwdrGroup) SetPriority(pri uint32) { atomic.StoreUint32(&p.priority, pri) }
|
||||
|
||||
// init traverse d.fwdrs and init the available forwarder slice.
|
||||
func (p *Proxy) init() {
|
||||
func (p *FwdrGroup) init() {
|
||||
for _, f := range p.fwdrs {
|
||||
if f.Enabled() {
|
||||
p.SetPriority(f.Priority())
|
||||
@ -175,7 +175,7 @@ func (p *Proxy) init() {
|
||||
}
|
||||
|
||||
// onStatusChanged will be called when fwdr's status changed.
|
||||
func (p *Proxy) onStatusChanged(fwdr *Forwarder) {
|
||||
func (p *FwdrGroup) onStatusChanged(fwdr *Forwarder) {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
|
||||
@ -202,7 +202,7 @@ func (p *Proxy) onStatusChanged(fwdr *Forwarder) {
|
||||
}
|
||||
|
||||
// Check implements the Checker interface.
|
||||
func (p *Proxy) Check() {
|
||||
func (p *FwdrGroup) Check() {
|
||||
// no need to check when there's only 1 forwarder
|
||||
if len(p.fwdrs) > 1 {
|
||||
for i := 0; i < len(p.fwdrs); i++ {
|
||||
@ -211,7 +211,7 @@ func (p *Proxy) Check() {
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Proxy) check(f *Forwarder) {
|
||||
func (p *FwdrGroup) check(f *Forwarder) {
|
||||
wait := uint8(0)
|
||||
buf := make([]byte, 4)
|
||||
intval := time.Duration(p.config.CheckInterval) * time.Second
|
||||
@ -301,17 +301,17 @@ func checkWebSite(fwdr *Forwarder, website string, timeout time.Duration, buf []
|
||||
}
|
||||
|
||||
// Round Robin
|
||||
func (p *Proxy) scheduleRR(dstAddr string) *Forwarder {
|
||||
func (p *FwdrGroup) scheduleRR(dstAddr string) *Forwarder {
|
||||
return p.avail[atomic.AddUint32(&p.index, 1)%uint32(len(p.avail))]
|
||||
}
|
||||
|
||||
// High Availability
|
||||
func (p *Proxy) scheduleHA(dstAddr string) *Forwarder {
|
||||
func (p *FwdrGroup) scheduleHA(dstAddr string) *Forwarder {
|
||||
return p.avail[0]
|
||||
}
|
||||
|
||||
// Latency based High Availability
|
||||
func (p *Proxy) scheduleLHA(dstAddr string) *Forwarder {
|
||||
func (p *FwdrGroup) scheduleLHA(dstAddr string) *Forwarder {
|
||||
fwdr := p.avail[0]
|
||||
lowest := fwdr.Latency()
|
||||
for _, f := range p.avail {
|
||||
@ -324,7 +324,7 @@ func (p *Proxy) scheduleLHA(dstAddr string) *Forwarder {
|
||||
}
|
||||
|
||||
// Destination Hashing
|
||||
func (p *Proxy) scheduleDH(dstAddr string) *Forwarder {
|
||||
func (p *FwdrGroup) scheduleDH(dstAddr string) *Forwarder {
|
||||
fnv1a := fnv.New32a()
|
||||
fnv1a.Write([]byte(dstAddr))
|
||||
return p.avail[fnv1a.Sum32()%uint32(len(p.avail))]
|
Loading…
Reference in New Issue
Block a user