重命名客户端相关术语为节点;移动 utils 包到根路径;优化网关对节点各种连接状态的处理,并在节点断联后统一清理资源

This commit is contained in:
2025-05-17 10:00:28 +08:00
parent 20ac7dbd91
commit 84e01d3b50
14 changed files with 150 additions and 129 deletions

View File

@@ -12,8 +12,9 @@ import (
"proxy-server/gateway/app"
"proxy-server/gateway/env"
"proxy-server/gateway/report"
"proxy-server/pkg/utils"
"proxy-server/utils"
"strconv"
"syscall"
)
type CtrlCmdType int
@@ -80,6 +81,21 @@ func (s *Service) listenCtrl() error {
}
func (s *Service) processCtrlConn(ctx context.Context, conn net.Conn) (err error) {
defer func() {
_, portStr, err := net.SplitHostPort(conn.LocalAddr().String())
if err != nil {
slog.Error("获取控制通道端口失败", "err", err)
return
}
port, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
slog.Error("解析控制通道端口失败", "err", err)
return
}
app.DelEdge(uint16(port))
}()
reader := bufio.NewReader(conn)
for {
// 循环等待直到服务关闭
@@ -90,12 +106,21 @@ func (s *Service) processCtrlConn(ctx context.Context, conn net.Conn) (err error
}
// 读取命令
cmdByte, err := reader.ReadByte()
cmd, err := reader.ReadByte()
if errors.Is(err, syscall.WSAECONNRESET) {
slog.Debug("节点重置了控制通道连接(WSAECONNRESET)")
return nil
}
if errors.Is(err, io.EOF) {
slog.Debug("节点关闭了控制通道")
return nil
}
if err != nil {
return fmt.Errorf("读取节点命令失败: %w", err)
}
var cmd = CtrlCmdType(cmdByte)
switch cmd {
// 处理节点命令
switch CtrlCmdType(cmd) {
// 连接建立命令
case CtrlCmdOpen:
@@ -132,15 +157,11 @@ func (s *Service) processCtrlConn(ctx context.Context, conn net.Conn) (err error
}
}
func (s *Service) onPing(conn net.Conn) (err error) {
return s.sendPong(conn)
}
func (s *Service) onOpen(conn net.Conn, client int32) (err error) {
func (s *Service) onOpen(writer io.Writer, edge int32) (err error) {
// open 命令全局只执行一次
_, ok := app.Clients.Load(client)
_, ok := app.Edges.Load(edge)
if ok {
return fmt.Errorf("节点 ID %d 已经连接", client)
return fmt.Errorf("节点 ID %d 已经连接", edge)
}
// 分配端口
@@ -151,8 +172,7 @@ func (s *Service) onOpen(conn net.Conn, client int32) (err error) {
var _, ok = app.Assigns.Load(i)
if !ok {
port = i
app.Assigns.Store(i, client)
app.Clients.Store(client, i)
app.AddEdge(edge, port)
break
}
}
@@ -161,62 +181,46 @@ func (s *Service) onOpen(conn net.Conn, client int32) (err error) {
}
// 报告端口分配
if err = report.Assigned(client, port); err != nil {
if err = report.Assigned(edge, port); err != nil {
return fmt.Errorf("报告端口分配失败: %w", err)
}
// 响应客户端
if err = s.sendPong(conn); err != nil {
return fmt.Errorf("响应客户端失败: %w", err)
// 响应节点
if err = s.sendPong(writer); err != nil {
return fmt.Errorf("响应节点失败: %w", err)
}
// 启动转发服务
s.fwdLesWg.Add(1)
go func() {
defer s.fwdLesWg.Done()
slog.Info("监听转发端口", "port", port, "client", client)
err = s.listenUser(port, conn)
slog.Info("监听转发端口", "port", port, "edge", edge)
err = s.listenUser(port, writer)
if err != nil {
slog.Error("监听转发端口失败", "port", port, "client", client, "err", err)
slog.Error("监听转发端口失败", "port", port, "edge", edge, "err", err)
}
}()
return nil
}
func (s *Service) onClose(conn net.Conn) (err error) {
_, portStr, err := net.SplitHostPort(conn.LocalAddr().String())
if err != nil {
return err
}
port, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
return err
}
id, _ := app.Assigns.LoadAndDelete(uint16(port))
app.Clients.Delete(id)
app.Assigns.Delete(uint16(port))
app.Permits.Delete(uint16(port))
err = s.sendPong(conn)
if err != nil {
return err
}
return nil
func (s *Service) onPing(writer io.Writer) (err error) {
return s.sendPong(writer)
}
func (s *Service) sendPong(conn net.Conn) (err error) {
_, err = conn.Write([]byte{byte(CtrlCmdPong)})
func (s *Service) onClose(writer io.Writer) (err error) {
return s.sendPong(writer)
}
func (s *Service) sendPong(writer io.Writer) (err error) {
_, err = writer.Write([]byte{byte(CtrlCmdPong)})
if err != nil {
return fmt.Errorf("响应客户端失败: %w", err)
return fmt.Errorf("响应节点失败: %w", err)
}
return nil
}
func (s *Service) sendProxy(conn net.Conn, tag [16]byte, addr string) (err error) {
func (s *Service) sendProxy(writer io.Writer, tag [16]byte, addr string) (err error) {
if len(addr) > 65535 {
return fmt.Errorf("代理地址过长: %s", addr)
}
@@ -227,7 +231,7 @@ func (s *Service) sendProxy(conn net.Conn, tag [16]byte, addr string) (err error
binary.BigEndian.PutUint16(buf[17:], uint16(len(addr)))
copy(buf[19:], addr)
_, err = conn.Write(buf)
_, err = writer.Write(buf)
if err != nil {
return fmt.Errorf("发送代理命令失败: %w", err)
}