fix(server): 付费会话「活跃即续期」——根治 macOS 常驻隧道一天多掉线
根因:付费连接凭证硬编码 24h TTL(paidCredentialTTL),而客户端只在 _connect() (用户/看门狗前台重连)才重签,服务端从不因流量续期。macOS sysext(root)隧道独立于 GUI app 常驻,用户关窗后 Dart 看门狗根本不运行 → 凭证 24h 到期、下次 agent 重注册 用「未过期」快照整表覆盖并重渲染 sing-box → REALITY 会话被剔除、永久黑洞。该逻辑 四端共用同一份 Dart,故为全端共性(macOS 最易现形)。 修法(方案 A,服务端、与客户端生命周期无关,一改修四端): - ReportUsage 收到某 dp_uuid 有流量,若属付费套餐(!AdGate)即把其凭证 expires_at 顶到 now+PaidCredentialTTL。活跃会话永不过期;免费凭证 TTL 编码日额度、绝不续期 (否则击穿日限)。每报按 user 缓存一次 entitlement 查询。 - 新增 NodeStore.RenewCredential(纯 UPDATE,WHERE expires_at>now 不复活已过期会话)。 - 24h 提为 nodes.PaidCredentialTTL 单一真相源,httpapi 引用它消除漂移。 - 纯 DB 续期,无需再 push agent(现有 REALITY 用户仍在,只要 DB 行不过期,下次 重注册快照仍含它)。可移植 SQL(? 占位 + Go 端算时间,无 MySQL 专属构造)。 测试:handler 层付费续期/免费不续期(mock);store 层真 SQLite 续期/不复活已过期。 go test ./... 全绿、go vet 干净。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FEVUXAbFT6bF1Qw27RHWoD
This commit is contained in:
@@ -21,7 +21,9 @@ import (
|
||||
|
||||
const (
|
||||
// paidCredentialTTL is the default connect credential lifetime for paid users.
|
||||
paidCredentialTTL = 24 * time.Hour
|
||||
// Single source in the nodes package: ReportUsage 的「活跃即续期」用同一常量续期,
|
||||
// 两处 24h 不会漂移。
|
||||
paidCredentialTTL = nodes.PaidCredentialTTL
|
||||
// freeCredentialTTL is the per-minute TTL for free users (per remaining minutes).
|
||||
freeMinuteTTL = time.Minute
|
||||
// deviceStaleWindow: connect 设备上限 backstop 只数近此窗口活跃的设备(与 devices 侧一致)。
|
||||
|
||||
Reference in New Issue
Block a user