mirror of
https://github.com/p4gefau1t/trojan-go.git
synced 2024-04-21 12:21:34 +00:00
109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
package proxy
|
|
|
|
import (
|
|
"context"
|
|
"github.com/p4gefau1t/trojan-go/log"
|
|
"github.com/p4gefau1t/trojan-go/tunnel"
|
|
)
|
|
|
|
type Node struct {
|
|
Name string
|
|
Next map[string]*Node
|
|
IsEndpoint bool
|
|
context.Context
|
|
tunnel.Server
|
|
}
|
|
|
|
func (n *Node) BuildNext(name string) *Node {
|
|
if next, found := n.Next[name]; found {
|
|
return next
|
|
}
|
|
t, err := tunnel.GetTunnel(name)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
s, err := t.NewServer(n.Context, n.Server)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
newNode := &Node{
|
|
Name: name,
|
|
Next: make(map[string]*Node),
|
|
Context: n.Context,
|
|
Server: s,
|
|
}
|
|
n.Next[name] = newNode
|
|
return newNode
|
|
}
|
|
|
|
func FindAllEndpoints(root *Node) []tunnel.Server {
|
|
list := make([]tunnel.Server, 0)
|
|
if root.IsEndpoint || len(root.Next) == 0 {
|
|
list = append(list, root.Server)
|
|
}
|
|
for _, next := range root.Next {
|
|
list = append(list, FindAllEndpoints(next)...)
|
|
}
|
|
return list
|
|
}
|
|
|
|
func buildServerStacksTree(ctx context.Context, current *Node, parent *Node) ([]tunnel.Server, error) {
|
|
t, err := tunnel.GetTunnel(current.Name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
current.Server, err = t.NewServer(ctx, parent)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
leaves := make([]tunnel.Server, 0)
|
|
for _, child := range current.Next {
|
|
subTreeLeaves, err := buildServerStacksTree(ctx, child, current)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
leaves = append(leaves, subTreeLeaves...)
|
|
}
|
|
// current node is a leave node
|
|
if len(leaves) == 0 || current.IsEndpoint {
|
|
leaves = append(leaves, current)
|
|
}
|
|
return leaves, nil
|
|
}
|
|
|
|
func CreateServersStacksTree(ctx context.Context, root *Node) ([]tunnel.Server, error) {
|
|
return buildServerStacksTree(ctx, root, nil)
|
|
}
|
|
|
|
// CreateClientStack create client tunnel stacks from lists
|
|
func CreateClientStack(ctx context.Context, clientStack []string) (tunnel.Client, error) {
|
|
var client tunnel.Client
|
|
for _, name := range clientStack {
|
|
t, err := tunnel.GetTunnel(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
client, err = t.NewClient(ctx, client)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return client, nil
|
|
}
|
|
|
|
// CreateServerStack create server tunnel stack from list
|
|
func CreateServerStack(ctx context.Context, serverStack []string) (tunnel.Server, error) {
|
|
var server tunnel.Server
|
|
for _, name := range serverStack {
|
|
t, err := tunnel.GetTunnel(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
server, err = t.NewServer(ctx, server)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return server, nil
|
|
}
|