实现节点下线功能,优化控制通道和数据通道的连接处理

This commit is contained in:
2025-05-16 16:59:33 +08:00
parent 8a6a4833d4
commit 22f3c37478
7 changed files with 136 additions and 120 deletions

View File

@@ -2,6 +2,7 @@ package fwd
import (
"bufio"
"errors"
"fmt"
"github.com/google/uuid"
"io"
@@ -14,8 +15,6 @@ import (
"strconv"
"sync"
"time"
"errors"
)
func (s *Service) listenData() error {
@@ -29,29 +28,41 @@ func (s *Service) listenData() error {
}
defer utils.Close(ls)
// 异步等待连接
var connCh = make(chan net.Conn)
go func() {
<-s.ctx.Done()
utils.Close(ls)
for {
conn, err := ls.Accept()
if errors.Is(err, net.ErrClosed) {
slog.Debug("数据通道监听关闭")
return
}
if err != nil {
slog.Error("接受数据通道连接失败", "err", err)
return
}
select {
case connCh <- conn:
case <-s.ctx.Done():
utils.Close(conn)
return
}
}
}()
// 处理连接
for {
conn, err := ls.Accept()
if err != nil {
return fmt.Errorf("监听数据通道失败: %w", err)
}
select {
case <-s.ctx.Done():
utils.Close(conn)
return nil
default:
case conn := <-connCh:
s.dataConnWg.Add(1)
go func() {
defer s.dataConnWg.Done()
defer utils.Close(conn)
err := s.processDataConn(conn)
if err != nil {
slog.Error("建立数据通道失败失败", "err", err)
slog.Error("处理数据通道连接失败", "err", err)
}
}()
}
@@ -89,6 +100,7 @@ func (s *Service) processDataConn(client net.Conn) error {
userPipeReader, userPipeWriter := io.Pipe()
defer utils.Close(userPipeWriter)
teeUser := io.TeeReader(user, userPipeWriter)
go func() {
err := analysisAndLog(user, userPipeReader)
@@ -115,38 +127,40 @@ func (s *Service) processDataConn(client net.Conn) error {
}()
select {
case <-s.ctx.Done():
return nil
case <-utils.WgWait(&wg):
proxy := time.Now()
start, startOk := metrics.TimerStart.Load(user.Conn)
auth, authOk := metrics.TimerAuth.Load(user.Conn)
var authDuration time.Duration
if startOk && authOk {
authDuration = auth.(time.Time).Sub(start.(time.Time))
}
var dataDuration time.Duration
if authOk {
dataDuration = data.Sub(auth.(time.Time))
}
proxyDuration := proxy.Sub(data)
var totalDuration time.Duration
if startOk {
totalDuration = proxy.Sub(start.(time.Time))
}
debug.ConsumingCh <- debug.Consuming{
Auth: authDuration,
Data: dataDuration,
Proxy: proxyDuration,
Total: totalDuration,
}
return nil
}
proxy := time.Now()
start, startOk := metrics.TimerStart.Load(user.Conn)
auth, authOk := metrics.TimerAuth.Load(user.Conn)
var authDuration time.Duration
if startOk && authOk {
authDuration = auth.(time.Time).Sub(start.(time.Time))
}
var dataDuration time.Duration
if authOk {
dataDuration = data.Sub(auth.(time.Time))
}
proxyDuration := proxy.Sub(data)
var totalDuration time.Duration
if startOk {
totalDuration = proxy.Sub(start.(time.Time))
}
debug.ConsumingCh <- debug.Consuming{
Auth: authDuration,
Data: dataDuration,
Proxy: proxyDuration,
Total: totalDuration,
}
return nil
}