add reload and plugin support for hop
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/hop"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/metadata"
|
||||
"github.com/go-gost/core/selector"
|
||||
@ -38,7 +39,7 @@ type chainNamer interface {
|
||||
|
||||
type Chain struct {
|
||||
name string
|
||||
hops []chain.Hop
|
||||
hops []hop.Hop
|
||||
marker selector.Marker
|
||||
metadata metadata.Metadata
|
||||
logger logger.Logger
|
||||
@ -60,7 +61,7 @@ func NewChain(name string, opts ...ChainOption) *Chain {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Chain) AddHop(hop chain.Hop) {
|
||||
func (c *Chain) AddHop(hop hop.Hop) {
|
||||
c.hops = append(c.hops, hop)
|
||||
}
|
||||
|
||||
@ -84,8 +85,8 @@ func (c *Chain) Route(ctx context.Context, network, address string) chain.Route
|
||||
}
|
||||
|
||||
rt := NewRoute(ChainRouteOption(c))
|
||||
for _, hop := range c.hops {
|
||||
node := hop.Select(ctx, chain.AddrSelectOption(address))
|
||||
for _, h := range c.hops {
|
||||
node := h.Select(ctx, hop.AddrSelectOption(address))
|
||||
if node == nil {
|
||||
return rt
|
||||
}
|
||||
|
138
chain/hop.go
138
chain/hop.go
@ -1,138 +0,0 @@
|
||||
package chain
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/go-gost/core/bypass"
|
||||
"github.com/go-gost/core/chain"
|
||||
"github.com/go-gost/core/logger"
|
||||
"github.com/go-gost/core/selector"
|
||||
)
|
||||
|
||||
type HopOptions struct {
|
||||
bypass bypass.Bypass
|
||||
selector selector.Selector[*chain.Node]
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
type HopOption func(*HopOptions)
|
||||
|
||||
func BypassHopOption(bp bypass.Bypass) HopOption {
|
||||
return func(o *HopOptions) {
|
||||
o.bypass = bp
|
||||
}
|
||||
}
|
||||
|
||||
func SelectorHopOption(s selector.Selector[*chain.Node]) HopOption {
|
||||
return func(o *HopOptions) {
|
||||
o.selector = s
|
||||
}
|
||||
}
|
||||
|
||||
func LoggerHopOption(logger logger.Logger) HopOption {
|
||||
return func(opts *HopOptions) {
|
||||
opts.logger = logger
|
||||
}
|
||||
}
|
||||
|
||||
type chainHop struct {
|
||||
nodes []*chain.Node
|
||||
options HopOptions
|
||||
}
|
||||
|
||||
func NewChainHop(nodes []*chain.Node, opts ...HopOption) chain.Hop {
|
||||
var options HopOptions
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(&options)
|
||||
}
|
||||
}
|
||||
|
||||
hop := &chainHop{
|
||||
nodes: nodes,
|
||||
options: options,
|
||||
}
|
||||
|
||||
return hop
|
||||
}
|
||||
|
||||
func (p *chainHop) Nodes() []*chain.Node {
|
||||
return p.nodes
|
||||
}
|
||||
|
||||
func (p *chainHop) Select(ctx context.Context, opts ...chain.SelectOption) *chain.Node {
|
||||
var options chain.SelectOptions
|
||||
for _, opt := range opts {
|
||||
opt(&options)
|
||||
}
|
||||
|
||||
if p == nil || len(p.nodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// hop level bypass
|
||||
if p.options.bypass != nil &&
|
||||
p.options.bypass.Contains(ctx, options.Addr) {
|
||||
return nil
|
||||
}
|
||||
|
||||
filters := p.nodes
|
||||
if host := options.Host; host != "" {
|
||||
filters = nil
|
||||
if v, _, _ := net.SplitHostPort(host); v != "" {
|
||||
host = v
|
||||
}
|
||||
var nodes []*chain.Node
|
||||
for _, node := range p.nodes {
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
vhost := node.Options().Host
|
||||
if vhost == "" {
|
||||
nodes = append(nodes, node)
|
||||
continue
|
||||
}
|
||||
if vhost == host ||
|
||||
vhost[0] == '.' && strings.HasSuffix(host, vhost[1:]) {
|
||||
filters = append(filters, node)
|
||||
}
|
||||
}
|
||||
if len(filters) == 0 {
|
||||
filters = nodes
|
||||
}
|
||||
} else if protocol := options.Protocol; protocol != "" {
|
||||
filters = nil
|
||||
for _, node := range p.nodes {
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
if node.Options().Protocol == protocol {
|
||||
filters = append(filters, node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var nodes []*chain.Node
|
||||
for _, node := range filters {
|
||||
if node == nil {
|
||||
continue
|
||||
}
|
||||
// node level bypass
|
||||
if node.Options().Bypass != nil &&
|
||||
node.Options().Bypass.Contains(ctx, options.Addr) {
|
||||
continue
|
||||
}
|
||||
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if s := p.options.selector; s != nil {
|
||||
return s.Select(ctx, nodes...)
|
||||
}
|
||||
return nodes[0]
|
||||
}
|
Reference in New Issue
Block a user