fix(node,agent): 转发链路两处慢失败补超时——①节点转发握手(告知目标+等agent回执)新增 HandshakeTimeout 默认5s, agent会话半死时观看端不再无限挂起到点即断、握手成功即清除不约束数据阶段; ②agent 拨内网目标新增 DialTimeout 默认5s(Agent 可配), 目标离线且防火墙丢包时不再裸 Dial 吊20s+, 到点回执失败观看端立即断开; 附 e2e 红绿双向证明(半死agent/黑洞拨号 两场景撤修复必红)
This commit is contained in:
+10
-8
@@ -24,25 +24,27 @@ const loginTimeout = 10 * time.Second
|
||||
|
||||
// Node 穿透节点
|
||||
type Node struct {
|
||||
JwtSecret string // agent 登录 JWT 校验密钥(HS256 系)
|
||||
BindTunnel string // 隧道监听绑定地址(默认 0.0.0.0)
|
||||
SweepInterval time.Duration // TTL 清扫间隔(默认 30s)
|
||||
JwtSecret string // agent 登录 JWT 校验密钥(HS256 系)
|
||||
BindTunnel string // 隧道监听绑定地址(默认 0.0.0.0)
|
||||
SweepInterval time.Duration // TTL 清扫间隔(默认 30s)
|
||||
HandshakeTimeout time.Duration // 单条观看连接的 agent 拨号应答上限(默认 5s; 超时立即断开观看端, 数据阶段不受限)
|
||||
|
||||
listener net.Listener
|
||||
|
||||
mu sync.Mutex
|
||||
stopped bool
|
||||
sessions map[*Session]struct{} // 该节点上的全部 agent 会话(一个 agent 多隧道=多会话)
|
||||
sessions map[*Session]struct{} // 该节点上的全部 agent 会话(一个 agent 多隧道=多会话)
|
||||
tunnels map[string]*TunnelServer // tunnelId -> 隧道
|
||||
}
|
||||
|
||||
// New 创建节点
|
||||
func New() *Node {
|
||||
return &Node{
|
||||
BindTunnel: "0.0.0.0",
|
||||
SweepInterval: 30 * time.Second,
|
||||
sessions: make(map[*Session]struct{}),
|
||||
tunnels: make(map[string]*TunnelServer),
|
||||
BindTunnel: "0.0.0.0",
|
||||
SweepInterval: 30 * time.Second,
|
||||
HandshakeTimeout: 5 * time.Second,
|
||||
sessions: make(map[*Session]struct{}),
|
||||
tunnels: make(map[string]*TunnelServer),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,11 @@ func (t *TunnelServer) handleConn(conn net.Conn) {
|
||||
}
|
||||
defer stream.Close()
|
||||
|
||||
// 转发握手(告知目标+等 agent 回执)限时: agent 会话半死/目标拨号不回时
|
||||
// 观看端不再无限挂起, 到点立即断开让观看端快速失败可重试
|
||||
if hs := t.session.node.HandshakeTimeout; hs > 0 {
|
||||
_ = stream.SetDeadline(time.Now().Add(hs))
|
||||
}
|
||||
tf := agent.NewFrame(agent.FrameVersion, agent.CmdTarget, 0)
|
||||
if err := tf.Marshal(t.tunnel); err != nil {
|
||||
return
|
||||
@@ -67,8 +72,10 @@ func (t *TunnelServer) handleConn(conn net.Conn) {
|
||||
}
|
||||
rf, err := agent.ReadFrame(stream)
|
||||
if err != nil {
|
||||
slog.Warn("节点 agent拨号应答失败", "id", t.tunnel.Id, "err", err.Error())
|
||||
return
|
||||
}
|
||||
_ = stream.SetDeadline(time.Time{}) // 数据阶段不受握手超时约束
|
||||
ret := agent.Ret{}
|
||||
if err := rf.Unmarshal(&ret); err != nil || ret.Code != 0 {
|
||||
slog.Warn("节点 agent拨号失败", "id", t.tunnel.Id, "msg", ret.Msg)
|
||||
|
||||
Reference in New Issue
Block a user