重新规划网关与节点的交互协议,实现统一命令位的识别和处理
This commit is contained in:
82
server/fwd/user.go
Normal file
82
server/fwd/user.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package fwd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"net"
|
||||
"proxy-server/pkg/utils"
|
||||
"proxy-server/server/core"
|
||||
"proxy-server/server/env"
|
||||
"proxy-server/server/fwd/dispatcher"
|
||||
"proxy-server/server/fwd/metrics"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (s *Service) listenUser(port uint16, ctrl net.Conn) error {
|
||||
dspt, err := dispatcher.New(port, time.Duration(env.AppUserTimeout)*time.Second)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer dspt.Close()
|
||||
|
||||
go func() {
|
||||
err := dspt.Run()
|
||||
if err != nil {
|
||||
slog.Error("代理服务运行失败", "err", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// 处理连接
|
||||
for {
|
||||
select {
|
||||
case <-s.ctx.Done():
|
||||
return nil
|
||||
case user := <-dspt.Conn:
|
||||
metrics.TimerAuth.Store(user.Conn, time.Now())
|
||||
s.userConnWg.Add(1)
|
||||
go func() {
|
||||
defer s.userConnWg.Done()
|
||||
err := s.processUserConn(user, ctrl)
|
||||
if err != nil {
|
||||
slog.Error("处理用户连接失败", "err", err)
|
||||
utils.Close(user)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) processUserConn(user *core.Conn, ctrl net.Conn) (err error) {
|
||||
|
||||
// 发送代理命令
|
||||
err = s.sendProxy(ctrl, user.Tag, user.Dest.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 保存用户连接
|
||||
s.userConnMap.Store(hex.EncodeToString(user.Tag[:]), user)
|
||||
|
||||
// 如果限定时间内没有建立数据通道,则关闭连接
|
||||
var timeout, cancel = context.WithTimeout(context.Background(), time.Duration(env.AppDataTimeout)*time.Second)
|
||||
defer cancel()
|
||||
|
||||
select {
|
||||
case <-timeout.Done():
|
||||
err = timeout.Err()
|
||||
case <-s.ctx.Done():
|
||||
err = s.ctx.Err()
|
||||
}
|
||||
|
||||
_, ok := s.userConnMap.LoadAndDelete(hex.EncodeToString(user.Tag[:]))
|
||||
if ok {
|
||||
utils.Close(user)
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
slog.Error("用户连接超时", "tag", hex.EncodeToString(user.Tag[:]), "addr", user.RemoteAddr().String())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user