Files
2024-04-22 23:14:36 +08:00

193 lines
3.4 KiB
Go

package entrypoint
import (
"errors"
"sync"
"github.com/go-gost/core/logger"
"github.com/go-gost/gost.plus/config"
"github.com/go-gost/gost.plus/tunnel"
)
const (
TCPEntryPoint = "tcp"
UDPEntryPoint = "udp"
)
var (
ErrEntryPointClosed = errors.New("entrypoint closed")
)
type EntryPoint = tunnel.Tunnel
type entryPointList struct {
list []EntryPoint
mux sync.RWMutex
}
var (
entryPoints entryPointList
)
func Count() int {
entryPoints.mux.RLock()
defer entryPoints.mux.RUnlock()
return len(entryPoints.list)
}
func Add(s EntryPoint) {
entryPoints.mux.Lock()
defer entryPoints.mux.Unlock()
entryPoints.list = append(entryPoints.list, s)
}
func Set(s EntryPoint) {
if s == nil {
return
}
old := Get(s.ID())
if old == nil {
return
}
s.Favorite(old.IsFavorite())
entryPoints.mux.Lock()
defer entryPoints.mux.Unlock()
for i, ep := range entryPoints.list {
if ep != nil && ep.ID() == s.ID() {
entryPoints.list[i] = s
}
}
}
func GetIndex(index int) EntryPoint {
entryPoints.mux.RLock()
defer entryPoints.mux.RUnlock()
if index < 0 || index >= len(entryPoints.list) {
return nil
}
return entryPoints.list[index]
}
func Get(id string) EntryPoint {
entryPoints.mux.RLock()
defer entryPoints.mux.RUnlock()
for _, s := range entryPoints.list {
if s != nil && s.ID() == id {
return s
}
}
return nil
}
func Delete(id string) {
entryPoints.mux.Lock()
defer entryPoints.mux.Unlock()
for i, s := range entryPoints.list {
if s != nil && s.ID() == id {
s.Close()
entryPoints.list[i] = nil
return
}
}
}
func LoadConfig() {
for _, cfg := range config.Get().EntryPoints {
if cfg == nil {
continue
}
ep := createEntryPoint(cfg.Type, tunnel.Options{
ID: cfg.ID,
Name: cfg.Name,
Endpoint: cfg.Endpoint,
Hostname: cfg.Hostname,
Username: cfg.Username,
Password: cfg.Password,
EnableTLS: cfg.EnableTLS,
Keepalive: cfg.Keepalive,
TTL: cfg.TTL,
CreatedAt: cfg.CreatedAt,
Stats: cfg.Stats,
})
if ep == nil {
continue
}
if cfg.Closed {
ep.Close()
} else {
ep.Run()
}
ep.Favorite(cfg.Favorite)
Add(ep)
}
}
func SaveConfig() error {
cfg := config.Get()
cfg.EntryPoints = nil
for i := 0; i < Count(); i++ {
ep := GetIndex(i)
if ep == nil {
continue
}
opts := ep.Options()
cfg.EntryPoints = append(cfg.EntryPoints, &config.Tunnel{
ID: ep.ID(),
Name: ep.Name(),
Type: ep.Type(),
Endpoint: ep.Entrypoint(),
Hostname: opts.Hostname,
Username: opts.Username,
Password: opts.Password,
EnableTLS: opts.EnableTLS,
Favorite: ep.IsFavorite(),
Closed: ep.IsClosed(),
CreatedAt: opts.CreatedAt,
Stats: ep.Stats(),
})
}
config.Set(cfg)
if err := cfg.Write(); err != nil {
logger.Default().Error(err)
return err
}
return nil
}
func createEntryPoint(st string, opts tunnel.Options) (ep EntryPoint) {
options := []tunnel.Option{
tunnel.IDOption(opts.ID),
tunnel.NameOption(opts.Name),
tunnel.EndpointOption(opts.Endpoint),
tunnel.HostnameOption(opts.Hostname),
tunnel.UsernameOption(opts.Username),
tunnel.PasswordOption(opts.Password),
tunnel.EnableTLSOption(opts.EnableTLS),
tunnel.CreatedAtOption(opts.CreatedAt),
}
switch st {
case TCPEntryPoint:
ep = NewTCPEntryPoint(options...)
case UDPEntryPoint:
ep = NewUDPEntryPoint(options...)
default:
return nil
}
ep.SetStats(opts.Stats)
return
}