111
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 29s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 48s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 37s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 59s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 36s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 57s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 38s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m6s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 35s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m0s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 52s
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 29s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 48s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 37s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 59s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 36s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 57s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 38s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m6s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 50s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 35s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m0s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 52s
This commit is contained in:
103
pkg/plugin/api.go
Normal file
103
pkg/plugin/api.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// 核心接口定义 - 按职责分离
|
||||
// =============================================================================
|
||||
|
||||
// Dialer 网络拨号接口(已在 types.go 中定义,此处为文档说明)
|
||||
// type Dialer interface {
|
||||
// Dial(network, address string) (net.Conn, error)
|
||||
// }
|
||||
|
||||
// PortManager 端口管理接口(仅服务端可用)
|
||||
type PortManager interface {
|
||||
// ReservePort 预留端口,返回错误如果端口已被占用
|
||||
ReservePort(port int) error
|
||||
// ReleasePort 释放端口
|
||||
ReleasePort(port int)
|
||||
// IsPortAvailable 检查端口是否可用
|
||||
IsPortAvailable(port int) bool
|
||||
}
|
||||
|
||||
// RuleManager 代理规则管理接口(仅服务端可用)
|
||||
type RuleManager interface {
|
||||
// CreateRule 创建代理规则
|
||||
CreateRule(rule *RuleConfig) error
|
||||
// DeleteRule 删除代理规则
|
||||
DeleteRule(clientID, ruleName string) error
|
||||
// GetRules 获取客户端的代理规则
|
||||
GetRules(clientID string) ([]RuleConfig, error)
|
||||
// UpdateRule 更新代理规则
|
||||
UpdateRule(clientID string, rule *RuleConfig) error
|
||||
}
|
||||
|
||||
// ClientManager 客户端管理接口(仅服务端可用)
|
||||
type ClientManager interface {
|
||||
// GetClientList 获取所有客户端列表
|
||||
GetClientList() ([]ClientInfo, error)
|
||||
// IsClientOnline 检查客户端是否在线
|
||||
IsClientOnline(clientID string) bool
|
||||
}
|
||||
|
||||
// Logger 日志接口
|
||||
type Logger interface {
|
||||
// Log 记录日志
|
||||
Log(level LogLevel, format string, args ...interface{})
|
||||
}
|
||||
|
||||
// ConfigStore 配置存储接口
|
||||
type ConfigStore interface {
|
||||
// GetConfig 获取配置值
|
||||
GetConfig(key string) string
|
||||
// SetConfig 设置配置值
|
||||
SetConfig(key, value string)
|
||||
}
|
||||
|
||||
// EventBus 事件总线接口
|
||||
type EventBus interface {
|
||||
// OnEvent 订阅事件
|
||||
OnEvent(eventType EventType, handler EventHandler)
|
||||
// EmitEvent 发送事件
|
||||
EmitEvent(event *Event)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 组合接口
|
||||
// =============================================================================
|
||||
|
||||
// PluginAPI 插件 API 主接口,组合所有子接口
|
||||
// 插件可以通过此接口访问 GoTunnel 的功能
|
||||
type PluginAPI interface {
|
||||
// 网络操作
|
||||
Dial(network, address string) (net.Conn, error)
|
||||
DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
|
||||
Listen(network, address string) (net.Listener, error)
|
||||
|
||||
// 端口管理(服务端)
|
||||
PortManager
|
||||
|
||||
// 规则管理(服务端)
|
||||
RuleManager
|
||||
|
||||
// 客户端管理(服务端)
|
||||
ClientManager
|
||||
|
||||
// 日志
|
||||
Logger
|
||||
|
||||
// 配置
|
||||
ConfigStore
|
||||
|
||||
// 事件
|
||||
EventBus
|
||||
|
||||
// 上下文
|
||||
GetContext() *Context
|
||||
GetClientID() string
|
||||
GetServerInfo() *ServerInfo
|
||||
}
|
||||
90
pkg/plugin/base.go
Normal file
90
pkg/plugin/base.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// 基础实现 - 提取公共代码
|
||||
// =============================================================================
|
||||
|
||||
// baseAPI 包含服务端和客户端共享的基础功能
|
||||
type baseAPI struct {
|
||||
pluginName string
|
||||
config map[string]string
|
||||
configMu sync.RWMutex
|
||||
|
||||
eventHandlers map[EventType][]EventHandler
|
||||
eventMu sync.RWMutex
|
||||
}
|
||||
|
||||
// newBaseAPI 创建基础 API
|
||||
func newBaseAPI(pluginName string, config map[string]string) *baseAPI {
|
||||
cfg := config
|
||||
if cfg == nil {
|
||||
cfg = make(map[string]string)
|
||||
}
|
||||
return &baseAPI{
|
||||
pluginName: pluginName,
|
||||
config: cfg,
|
||||
eventHandlers: make(map[EventType][]EventHandler),
|
||||
}
|
||||
}
|
||||
|
||||
// Log 记录日志
|
||||
func (b *baseAPI) Log(level LogLevel, format string, args ...interface{}) {
|
||||
prefix := fmt.Sprintf("[Plugin:%s] ", b.pluginName)
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
log.Printf("%s%s", prefix, msg)
|
||||
}
|
||||
|
||||
// GetConfig 获取配置值
|
||||
func (b *baseAPI) GetConfig(key string) string {
|
||||
b.configMu.RLock()
|
||||
defer b.configMu.RUnlock()
|
||||
return b.config[key]
|
||||
}
|
||||
|
||||
// SetConfig 设置配置值
|
||||
func (b *baseAPI) SetConfig(key, value string) {
|
||||
b.configMu.Lock()
|
||||
defer b.configMu.Unlock()
|
||||
b.config[key] = value
|
||||
}
|
||||
|
||||
// OnEvent 订阅事件
|
||||
func (b *baseAPI) OnEvent(eventType EventType, handler EventHandler) {
|
||||
b.eventMu.Lock()
|
||||
defer b.eventMu.Unlock()
|
||||
b.eventHandlers[eventType] = append(b.eventHandlers[eventType], handler)
|
||||
}
|
||||
|
||||
// EmitEvent 发送事件(复制切片避免竞态条件)
|
||||
func (b *baseAPI) EmitEvent(event *Event) {
|
||||
b.eventMu.RLock()
|
||||
handlers := make([]EventHandler, len(b.eventHandlers[event.Type]))
|
||||
copy(handlers, b.eventHandlers[event.Type])
|
||||
b.eventMu.RUnlock()
|
||||
|
||||
for _, handler := range handlers {
|
||||
go handler(event)
|
||||
}
|
||||
}
|
||||
|
||||
// getPluginName 获取插件名称
|
||||
func (b *baseAPI) getPluginName() string {
|
||||
return b.pluginName
|
||||
}
|
||||
|
||||
// getConfigMap 获取配置副本
|
||||
func (b *baseAPI) getConfigMap() map[string]string {
|
||||
b.configMu.RLock()
|
||||
defer b.configMu.RUnlock()
|
||||
result := make(map[string]string, len(b.config))
|
||||
for k, v := range b.config {
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -50,6 +50,9 @@ func (p *SOCKS5Plugin) Metadata() plugin.PluginMetadata {
|
||||
Capabilities: []string{
|
||||
"dial", "read", "write", "close",
|
||||
},
|
||||
RuleSchema: &plugin.RuleSchema{
|
||||
NeedsLocalAddr: false, // SOCKS5 不需要本地地址
|
||||
},
|
||||
ConfigSchema: []plugin.ConfigField{
|
||||
{
|
||||
Key: "auth",
|
||||
|
||||
@@ -34,6 +34,18 @@ func (p *VNCPlugin) Metadata() plugin.PluginMetadata {
|
||||
Capabilities: []string{
|
||||
"dial", "read", "write", "close",
|
||||
},
|
||||
RuleSchema: &plugin.RuleSchema{
|
||||
NeedsLocalAddr: false,
|
||||
ExtraFields: []plugin.ConfigField{
|
||||
{
|
||||
Key: "vnc_addr",
|
||||
Label: "VNC 地址",
|
||||
Type: plugin.ConfigFieldString,
|
||||
Default: "127.0.0.1:5900",
|
||||
Description: "客户端本地 VNC 服务地址",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
161
pkg/plugin/client_api.go
Normal file
161
pkg/plugin/client_api.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// 客户端 API 实现
|
||||
// =============================================================================
|
||||
|
||||
// ClientAPI 客户端 PluginAPI 实现
|
||||
type ClientAPI struct {
|
||||
*baseAPI
|
||||
clientID string
|
||||
dialer Dialer
|
||||
}
|
||||
|
||||
// ClientAPIOption 客户端 API 配置选项
|
||||
type ClientAPIOption struct {
|
||||
PluginName string
|
||||
ClientID string
|
||||
Config map[string]string
|
||||
Dialer Dialer
|
||||
}
|
||||
|
||||
// NewClientAPI 创建客户端 API
|
||||
func NewClientAPI(opt ClientAPIOption) *ClientAPI {
|
||||
return &ClientAPI{
|
||||
baseAPI: newBaseAPI(opt.PluginName, opt.Config),
|
||||
clientID: opt.ClientID,
|
||||
dialer: opt.Dialer,
|
||||
}
|
||||
}
|
||||
|
||||
// --- 网络操作 ---
|
||||
|
||||
// Dial 通过隧道建立连接
|
||||
func (c *ClientAPI) Dial(network, address string) (net.Conn, error) {
|
||||
if c.dialer == nil {
|
||||
return nil, ErrNotConnected
|
||||
}
|
||||
return c.dialer.Dial(network, address)
|
||||
}
|
||||
|
||||
// DialTimeout 带超时的连接(使用 context 避免 goroutine 泄漏)
|
||||
func (c *ClientAPI) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
||||
if c.dialer == nil {
|
||||
return nil, ErrNotConnected
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||
defer cancel()
|
||||
|
||||
type result struct {
|
||||
conn net.Conn
|
||||
err error
|
||||
}
|
||||
ch := make(chan result, 1)
|
||||
|
||||
go func() {
|
||||
conn, err := c.dialer.Dial(network, address)
|
||||
select {
|
||||
case ch <- result{conn, err}:
|
||||
case <-ctx.Done():
|
||||
if conn != nil {
|
||||
conn.Close()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
case r := <-ch:
|
||||
return r.conn, r.err
|
||||
case <-ctx.Done():
|
||||
return nil, fmt.Errorf("dial timeout")
|
||||
}
|
||||
}
|
||||
|
||||
// Listen 客户端不支持监听
|
||||
func (c *ClientAPI) Listen(network, address string) (net.Listener, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// --- 端口管理(客户端不支持)---
|
||||
|
||||
// ReservePort 客户端不支持
|
||||
func (c *ClientAPI) ReservePort(port int) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
// ReleasePort 客户端不支持
|
||||
func (c *ClientAPI) ReleasePort(port int) {}
|
||||
|
||||
// IsPortAvailable 检查本地端口是否可用
|
||||
func (c *ClientAPI) IsPortAvailable(port int) bool {
|
||||
ln, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
ln.Close()
|
||||
return true
|
||||
}
|
||||
|
||||
// --- 规则管理(客户端不支持)---
|
||||
|
||||
// CreateRule 客户端不支持
|
||||
func (c *ClientAPI) CreateRule(rule *RuleConfig) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
// DeleteRule 客户端不支持
|
||||
func (c *ClientAPI) DeleteRule(clientID, ruleName string) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
// GetRules 客户端不支持
|
||||
func (c *ClientAPI) GetRules(clientID string) ([]RuleConfig, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// UpdateRule 客户端不支持
|
||||
func (c *ClientAPI) UpdateRule(clientID string, rule *RuleConfig) error {
|
||||
return ErrNotSupported
|
||||
}
|
||||
|
||||
// --- 客户端管理 ---
|
||||
|
||||
// GetClientID 获取当前客户端 ID
|
||||
func (c *ClientAPI) GetClientID() string {
|
||||
return c.clientID
|
||||
}
|
||||
|
||||
// GetClientList 客户端不支持
|
||||
func (c *ClientAPI) GetClientList() ([]ClientInfo, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// IsClientOnline 客户端不支持
|
||||
func (c *ClientAPI) IsClientOnline(clientID string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// --- 上下文 ---
|
||||
|
||||
// GetContext 获取当前上下文
|
||||
func (c *ClientAPI) GetContext() *Context {
|
||||
return &Context{
|
||||
PluginName: c.getPluginName(),
|
||||
Side: SideClient,
|
||||
ClientID: c.clientID,
|
||||
Config: c.getConfigMap(),
|
||||
}
|
||||
}
|
||||
|
||||
// GetServerInfo 客户端不支持
|
||||
func (c *ClientAPI) GetServerInfo() *ServerInfo {
|
||||
return nil
|
||||
}
|
||||
180
pkg/plugin/server_api.go
Normal file
180
pkg/plugin/server_api.go
Normal file
@@ -0,0 +1,180 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// 服务端依赖接口(依赖注入)
|
||||
// =============================================================================
|
||||
|
||||
// PortStore 端口存储接口
|
||||
type PortStore interface {
|
||||
Reserve(port int, owner string) error
|
||||
Release(port int)
|
||||
IsAvailable(port int) bool
|
||||
}
|
||||
|
||||
// RuleStore 规则存储接口
|
||||
type RuleStore interface {
|
||||
GetAll(clientID string) ([]RuleConfig, error)
|
||||
Create(clientID string, rule *RuleConfig) error
|
||||
Update(clientID string, rule *RuleConfig) error
|
||||
Delete(clientID, ruleName string) error
|
||||
}
|
||||
|
||||
// ClientStore 客户端存储接口
|
||||
type ClientStore interface {
|
||||
GetAll() ([]ClientInfo, error)
|
||||
IsOnline(clientID string) bool
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// 服务端 API 实现
|
||||
// =============================================================================
|
||||
|
||||
// ServerAPI 服务端 PluginAPI 实现
|
||||
type ServerAPI struct {
|
||||
*baseAPI
|
||||
portStore PortStore
|
||||
ruleStore RuleStore
|
||||
clientStore ClientStore
|
||||
serverInfo *ServerInfo
|
||||
}
|
||||
|
||||
// ServerAPIOption 服务端 API 配置选项
|
||||
type ServerAPIOption struct {
|
||||
PluginName string
|
||||
Config map[string]string
|
||||
PortStore PortStore
|
||||
RuleStore RuleStore
|
||||
ClientStore ClientStore
|
||||
ServerInfo *ServerInfo
|
||||
}
|
||||
|
||||
// NewServerAPI 创建服务端 API
|
||||
func NewServerAPI(opt ServerAPIOption) *ServerAPI {
|
||||
return &ServerAPI{
|
||||
baseAPI: newBaseAPI(opt.PluginName, opt.Config),
|
||||
portStore: opt.PortStore,
|
||||
ruleStore: opt.RuleStore,
|
||||
clientStore: opt.ClientStore,
|
||||
serverInfo: opt.ServerInfo,
|
||||
}
|
||||
}
|
||||
|
||||
// --- 网络操作 ---
|
||||
|
||||
// Dial 服务端不支持隧道拨号
|
||||
func (s *ServerAPI) Dial(network, address string) (net.Conn, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// DialTimeout 服务端不支持隧道拨号
|
||||
func (s *ServerAPI) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
|
||||
// Listen 在指定地址监听
|
||||
func (s *ServerAPI) Listen(network, address string) (net.Listener, error) {
|
||||
return net.Listen(network, address)
|
||||
}
|
||||
|
||||
// --- 端口管理 ---
|
||||
|
||||
// ReservePort 预留端口
|
||||
func (s *ServerAPI) ReservePort(port int) error {
|
||||
if s.portStore == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.portStore.Reserve(port, s.getPluginName())
|
||||
}
|
||||
|
||||
// ReleasePort 释放端口
|
||||
func (s *ServerAPI) ReleasePort(port int) {
|
||||
if s.portStore != nil {
|
||||
s.portStore.Release(port)
|
||||
}
|
||||
}
|
||||
|
||||
// IsPortAvailable 检查端口是否可用
|
||||
func (s *ServerAPI) IsPortAvailable(port int) bool {
|
||||
if s.portStore == nil {
|
||||
return false
|
||||
}
|
||||
return s.portStore.IsAvailable(port)
|
||||
}
|
||||
|
||||
// --- 规则管理 ---
|
||||
|
||||
// CreateRule 创建代理规则
|
||||
func (s *ServerAPI) CreateRule(rule *RuleConfig) error {
|
||||
if s.ruleStore == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.ruleStore.Create(rule.ClientID, rule)
|
||||
}
|
||||
|
||||
// DeleteRule 删除代理规则
|
||||
func (s *ServerAPI) DeleteRule(clientID, ruleName string) error {
|
||||
if s.ruleStore == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.ruleStore.Delete(clientID, ruleName)
|
||||
}
|
||||
|
||||
// GetRules 获取客户端的代理规则
|
||||
func (s *ServerAPI) GetRules(clientID string) ([]RuleConfig, error) {
|
||||
if s.ruleStore == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
return s.ruleStore.GetAll(clientID)
|
||||
}
|
||||
|
||||
// UpdateRule 更新代理规则
|
||||
func (s *ServerAPI) UpdateRule(clientID string, rule *RuleConfig) error {
|
||||
if s.ruleStore == nil {
|
||||
return ErrNotSupported
|
||||
}
|
||||
return s.ruleStore.Update(clientID, rule)
|
||||
}
|
||||
|
||||
// --- 客户端管理 ---
|
||||
|
||||
// GetClientID 服务端返回空
|
||||
func (s *ServerAPI) GetClientID() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetClientList 获取所有客户端列表
|
||||
func (s *ServerAPI) GetClientList() ([]ClientInfo, error) {
|
||||
if s.clientStore == nil {
|
||||
return nil, ErrNotSupported
|
||||
}
|
||||
return s.clientStore.GetAll()
|
||||
}
|
||||
|
||||
// IsClientOnline 检查客户端是否在线
|
||||
func (s *ServerAPI) IsClientOnline(clientID string) bool {
|
||||
if s.clientStore == nil {
|
||||
return false
|
||||
}
|
||||
return s.clientStore.IsOnline(clientID)
|
||||
}
|
||||
|
||||
// --- 上下文 ---
|
||||
|
||||
// GetContext 获取当前上下文
|
||||
func (s *ServerAPI) GetContext() *Context {
|
||||
return &Context{
|
||||
PluginName: s.getPluginName(),
|
||||
Side: SideServer,
|
||||
Config: s.getConfigMap(),
|
||||
}
|
||||
}
|
||||
|
||||
// GetServerInfo 获取服务端信息
|
||||
func (s *ServerAPI) GetServerInfo() *ServerInfo {
|
||||
return s.serverInfo
|
||||
}
|
||||
@@ -45,6 +45,12 @@ type ConfigField struct {
|
||||
Description string `json:"description,omitempty"` // 字段描述
|
||||
}
|
||||
|
||||
// RuleSchema 规则表单模式定义
|
||||
type RuleSchema struct {
|
||||
NeedsLocalAddr bool `json:"needs_local_addr"` // 是否需要本地地址
|
||||
ExtraFields []ConfigField `json:"extra_fields,omitempty"` // 额外字段
|
||||
}
|
||||
|
||||
// PluginMetadata 描述一个 plugin
|
||||
type PluginMetadata struct {
|
||||
Name string `json:"name"` // 唯一标识符 (如 "socks5")
|
||||
@@ -57,7 +63,8 @@ type PluginMetadata struct {
|
||||
Checksum string `json:"checksum,omitempty"` // WASM 二进制的 SHA256
|
||||
Size int64 `json:"size,omitempty"` // WASM 二进制大小
|
||||
Capabilities []string `json:"capabilities,omitempty"` // 所需 host functions
|
||||
ConfigSchema []ConfigField `json:"config_schema,omitempty"`// 配置模式定义
|
||||
ConfigSchema []ConfigField `json:"config_schema,omitempty"`// 插件配置模式
|
||||
RuleSchema *RuleSchema `json:"rule_schema,omitempty"` // 规则表单模式
|
||||
}
|
||||
|
||||
// PluginInfo 组合元数据和运行时状态
|
||||
@@ -90,6 +97,15 @@ type ProxyHandler interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
// ExtendedProxyHandler 扩展的代理处理器接口
|
||||
// 支持 PluginAPI 的插件应实现此接口
|
||||
type ExtendedProxyHandler interface {
|
||||
ProxyHandler
|
||||
|
||||
// SetAPI 设置 PluginAPI,允许插件调用系统功能
|
||||
SetAPI(api PluginAPI)
|
||||
}
|
||||
|
||||
// LogLevel 日志级别
|
||||
type LogLevel uint8
|
||||
|
||||
@@ -100,6 +116,101 @@ const (
|
||||
LogError
|
||||
)
|
||||
|
||||
// =============================================================================
|
||||
// API 相关类型
|
||||
// =============================================================================
|
||||
|
||||
// Side 运行侧
|
||||
type Side string
|
||||
|
||||
const (
|
||||
SideServer Side = "server"
|
||||
SideClient Side = "client"
|
||||
)
|
||||
|
||||
// Context 插件运行上下文
|
||||
type Context struct {
|
||||
PluginName string
|
||||
Side Side
|
||||
ClientID string
|
||||
Config map[string]string
|
||||
}
|
||||
|
||||
// ServerInfo 服务端信息
|
||||
type ServerInfo struct {
|
||||
BindAddr string
|
||||
BindPort int
|
||||
Version string
|
||||
}
|
||||
|
||||
// RuleConfig 代理规则配置
|
||||
type RuleConfig struct {
|
||||
ClientID string `json:"client_id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
LocalIP string `json:"local_ip"`
|
||||
LocalPort int `json:"local_port"`
|
||||
RemotePort int `json:"remote_port"`
|
||||
Enabled bool `json:"enabled"`
|
||||
PluginName string `json:"plugin_name,omitempty"`
|
||||
PluginConfig map[string]string `json:"plugin_config,omitempty"`
|
||||
}
|
||||
|
||||
// ClientInfo 客户端信息
|
||||
type ClientInfo struct {
|
||||
ID string `json:"id"`
|
||||
Nickname string `json:"nickname"`
|
||||
Online bool `json:"online"`
|
||||
LastPing string `json:"last_ping,omitempty"`
|
||||
}
|
||||
|
||||
// EventType 事件类型
|
||||
type EventType string
|
||||
|
||||
const (
|
||||
EventClientConnect EventType = "client_connect"
|
||||
EventClientDisconnect EventType = "client_disconnect"
|
||||
EventRuleCreated EventType = "rule_created"
|
||||
EventRuleDeleted EventType = "rule_deleted"
|
||||
EventProxyConnect EventType = "proxy_connect"
|
||||
EventProxyDisconnect EventType = "proxy_disconnect"
|
||||
)
|
||||
|
||||
// Event 事件
|
||||
type Event struct {
|
||||
Type EventType `json:"type"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
}
|
||||
|
||||
// EventHandler 事件处理函数
|
||||
type EventHandler func(event *Event)
|
||||
|
||||
// =============================================================================
|
||||
// 错误定义
|
||||
// =============================================================================
|
||||
|
||||
// APIError API 错误
|
||||
type APIError struct {
|
||||
Code int
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *APIError) Error() string {
|
||||
return e.Message
|
||||
}
|
||||
|
||||
// 常见 API 错误
|
||||
var (
|
||||
ErrNotSupported = &APIError{Code: 1, Message: "operation not supported"}
|
||||
ErrClientNotFound = &APIError{Code: 2, Message: "client not found"}
|
||||
ErrPortOccupied = &APIError{Code: 3, Message: "port already occupied"}
|
||||
ErrRuleNotFound = &APIError{Code: 4, Message: "rule not found"}
|
||||
ErrRuleExists = &APIError{Code: 5, Message: "rule already exists"}
|
||||
ErrNotConnected = &APIError{Code: 6, Message: "not connected"}
|
||||
ErrInvalidConfig = &APIError{Code: 7, Message: "invalid configuration"}
|
||||
)
|
||||
|
||||
// ConnHandle WASM 连接句柄
|
||||
type ConnHandle uint32
|
||||
|
||||
|
||||
Reference in New Issue
Block a user