124 lines
3.8 KiB
Go
124 lines
3.8 KiB
Go
// Package core 定义 VPN 协议统一抽象接口与运行时管理器。
|
|
// 所有协议(内置或自定义插件)只需实现 Protocol 接口即可接入平台。
|
|
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"vpn-platform/backend/internal/model"
|
|
)
|
|
|
|
// Status 专线运行状态
|
|
type Status struct {
|
|
Running bool `json:"running"`
|
|
State string `json:"state"` // running / stopped / error / undeployed
|
|
Detail string `json:"detail"`
|
|
RxBytes int64 `json:"rx_bytes"`
|
|
TxBytes int64 `json:"tx_bytes"`
|
|
// Peers 为协议可选的对端实时状态。WireGuard 等多对端协议使用它向
|
|
// 管理端返回逐 Peer 的握手时间、端点和内核计数器,不能用隧道总流量冒充。
|
|
Peers []PeerStatus `json:"peers,omitempty"`
|
|
UpdatedAt int64 `json:"updated_at"`
|
|
}
|
|
|
|
// PeerStatus 是多对端协议的真实运行时数据。RxBytes/TxBytes 来自协议
|
|
// 进程或内核的累计计数器;服务重启后计数器可能从零重新开始。
|
|
type PeerStatus struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name,omitempty"`
|
|
PublicKey string `json:"public_key"`
|
|
Endpoint string `json:"endpoint,omitempty"`
|
|
AllowedIPs string `json:"allowed_ips,omitempty"`
|
|
LatestHandshakeAt int64 `json:"latest_handshake_at,omitempty"`
|
|
Connected bool `json:"connected"`
|
|
RxBytes int64 `json:"rx_bytes"`
|
|
TxBytes int64 `json:"tx_bytes"`
|
|
}
|
|
|
|
// Protocol 统一协议接口 —— 自定义协议按此契约实现即可热插拔接入
|
|
type Protocol interface {
|
|
// Name 协议标识,如 wireguard / ipsec / frp
|
|
Name() string
|
|
// DisplayName 展示名
|
|
DisplayName() string
|
|
// Validate 创建前校验参数,返回规范化后的配置
|
|
Validate(cfg map[string]interface{}) (map[string]interface{}, error)
|
|
// Create 生成服务端配置并落盘(不启动)
|
|
Create(t *model.Tunnel) error
|
|
// Start 启动实例
|
|
Start(t *model.Tunnel) error
|
|
// Stop 停止实例
|
|
Stop(t *model.Tunnel) error
|
|
// Status 查询运行状态与流量
|
|
Status(t *model.Tunnel) (Status, error)
|
|
// GenerateClientConfig 生成客户端配置(用于下载 / 二维码)
|
|
GenerateClientConfig(t *model.Tunnel) (string, error)
|
|
// Delete 清理实例配置与运行时资源
|
|
Delete(t *model.Tunnel) error
|
|
// Available 检测系统依赖是否就绪(wg / strongswan / frps 等)
|
|
Available() (bool, string)
|
|
}
|
|
|
|
// Manager 协议注册中心 + 实例状态缓存
|
|
type Manager struct {
|
|
mu sync.RWMutex
|
|
protocols map[string]Protocol
|
|
statuses map[uint]Status
|
|
}
|
|
|
|
func NewManager() *Manager {
|
|
return &Manager{protocols: map[string]Protocol{}, statuses: map[uint]Status{}}
|
|
}
|
|
|
|
// Register 注册协议实现(内置协议与自定义插件共用入口)
|
|
func (m *Manager) Register(p Protocol) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
m.protocols[p.Name()] = p
|
|
}
|
|
|
|
// Get 获取协议实现
|
|
func (m *Manager) Get(name string) (Protocol, error) {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
p, ok := m.protocols[name]
|
|
if !ok {
|
|
return nil, fmt.Errorf("不支持的协议类型: %s", name)
|
|
}
|
|
return p, nil
|
|
}
|
|
|
|
// List 列出全部已注册协议
|
|
func (m *Manager) List() []Protocol {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
out := make([]Protocol, 0, len(m.protocols))
|
|
for _, p := range m.protocols {
|
|
out = append(out, p)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// SetStatus 更新实例状态缓存(monitor 写入)
|
|
func (m *Manager) SetStatus(tunnelID uint, s Status) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
m.statuses[tunnelID] = s
|
|
}
|
|
|
|
// GetStatus 读取实例状态缓存
|
|
func (m *Manager) GetStatus(tunnelID uint) (Status, bool) {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
s, ok := m.statuses[tunnelID]
|
|
return s, ok
|
|
}
|
|
|
|
// RemoveStatus 删除状态缓存
|
|
func (m *Manager) RemoveStatus(tunnelID uint) {
|
|
m.mu.Lock()
|
|
defer m.mu.Unlock()
|
|
delete(m.statuses, tunnelID)
|
|
}
|