重命名客户端相关术语为节点;移动 utils 包到根路径;优化网关对节点各种连接状态的处理,并在节点断联后统一清理资源
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user