add reload and plugin support for hop

This commit is contained in:
ginuerzh
2023-09-28 21:04:15 +08:00
parent ddc3c9392e
commit ea585fc25d
88 changed files with 2208 additions and 1538 deletions

View File

@ -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
}

View File

@ -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]
}