add chain hop

This commit is contained in:
ginuerzh
2022-09-20 11:48:30 +08:00
parent 50d443049f
commit 41ff9835a6
8 changed files with 293 additions and 527 deletions

View File

@ -1,8 +1,6 @@
package chain
import (
"context"
"github.com/go-gost/core/bypass"
"github.com/go-gost/core/hosts"
"github.com/go-gost/core/metadata"
@ -10,48 +8,76 @@ import (
"github.com/go-gost/core/selector"
)
type Node struct {
Name string
Addr string
transport *Transport
bypass bypass.Bypass
resolver resolver.Resolver
hostMapper hosts.HostMapper
marker selector.Marker
metadata metadata.Metadata
type NodeOptions struct {
Transport *Transport
Bypass bypass.Bypass
Resolver resolver.Resolver
HostMapper hosts.HostMapper
Metadata metadata.Metadata
}
func NewNode(name, addr string) *Node {
return &Node{
Name: name,
Addr: addr,
marker: selector.NewFailMarker(),
type NodeOption func(*NodeOptions)
func TransportNodeOption(tr *Transport) NodeOption {
return func(o *NodeOptions) {
o.Transport = tr
}
}
func (node *Node) WithTransport(tr *Transport) *Node {
node.transport = tr
return node
func BypassNodeOption(bp bypass.Bypass) NodeOption {
return func(o *NodeOptions) {
o.Bypass = bp
}
}
func (node *Node) WithBypass(bypass bypass.Bypass) *Node {
node.bypass = bypass
return node
func ResoloverNodeOption(resolver resolver.Resolver) NodeOption {
return func(o *NodeOptions) {
o.Resolver = resolver
}
}
func (node *Node) WithResolver(reslv resolver.Resolver) *Node {
node.resolver = reslv
return node
func HostMapperNodeOption(m hosts.HostMapper) NodeOption {
return func(o *NodeOptions) {
o.HostMapper = m
}
}
func (node *Node) WithHostMapper(m hosts.HostMapper) *Node {
node.hostMapper = m
return node
func MetadataNodeOption(md metadata.Metadata) NodeOption {
return func(o *NodeOptions) {
o.Metadata = md
}
}
func (node *Node) WithMetadata(md metadata.Metadata) *Node {
node.metadata = md
return node
type Node struct {
Name string
Addr string
marker selector.Marker
options NodeOptions
}
func NewNode(name string, addr string, opts ...NodeOption) *Node {
var options NodeOptions
for _, opt := range opts {
if opt != nil {
opt(&options)
}
}
return &Node{
Name: name,
Addr: addr,
marker: selector.NewFailMarker(),
options: options,
}
}
func (node *Node) Options() *NodeOptions {
return &node.options
}
// Metadata implements metadadta.Metadatable interface.
func (node *Node) Metadata() metadata.Metadata {
return node.options.Metadata
}
// Marker implements selector.Markable interface.
@ -59,65 +85,8 @@ func (node *Node) Marker() selector.Marker {
return node.marker
}
// Metadata implements metadadta.Metadatable interface.
func (node *Node) Metadata() metadata.Metadata {
return node.metadata
}
func (node *Node) Copy() *Node {
n := &Node{}
*n = *node
return n
}
type NodeGroup struct {
nodes []*Node
selector selector.Selector[*Node]
bypass bypass.Bypass
}
func NewNodeGroup(nodes ...*Node) *NodeGroup {
return &NodeGroup{
nodes: nodes,
}
}
func (g *NodeGroup) AddNode(node *Node) {
g.nodes = append(g.nodes, node)
}
func (g *NodeGroup) Nodes() []*Node {
return g.nodes
}
func (g *NodeGroup) WithSelector(selector selector.Selector[*Node]) *NodeGroup {
g.selector = selector
return g
}
func (g *NodeGroup) WithBypass(bypass bypass.Bypass) *NodeGroup {
g.bypass = bypass
return g
}
func (g *NodeGroup) FilterAddr(addr string) *NodeGroup {
var nodes []*Node
for _, node := range g.nodes {
if node.bypass == nil || !node.bypass.Contains(addr) {
nodes = append(nodes, node)
}
}
return &NodeGroup{
nodes: nodes,
selector: g.selector,
bypass: g.bypass,
}
}
func (g *NodeGroup) Next(ctx context.Context) *Node {
if g == nil || len(g.nodes) == 0 {
return nil
}
return g.selector.Select(ctx, g.nodes...)
}