STTNet 0.7.0
Loading...
Searching...
No Matches
stt::security::ConnectionLimiter Class Reference

统一的连接与请求安全裁决器(IP 级 + fd 级,多策略限流 + 黑名单)。 More...

#include <sttnet.h>

Public Member Functions

 ConnectionLimiter (const int &maxConn=20, const int &idleTimeout=60)
 构造函数。
 
void setConnectStrategy (const RateLimitType &type)
 设置“连接速率限流”所使用的策略。
 
void setRequestStrategy (const RateLimitType &type)
 设置“IP 级请求限流”所使用的策略。
 
void setPathStrategy (const RateLimitType &type)
 设置“path 级请求限流”所使用的策略。
 
void setPathLimit (const std::string &path, const int &times, const int &secs)
 设置某个路径的额外限流规则(path 级)。
 
DefenseDecision allowConnect (const std::string &ip, const int &fd, const int &times, const int &secs)
 对新建立的连接进行安全裁决(IP 级)。
 
DefenseDecision allowRequest (const std::string &ip, const int &fd, const std::string_view &path, const int &times, const int &secs)
 对已建立连接的一次请求进行安全裁决。
 
void clearIP (const std::string &ip, const int &fd)
 在连接断开时回收对应 fd 的状态。
 
bool connectionDetect (const std::string &ip, const int &fd)
 检测并清理僵尸连接(fd 级)。
 
void banIP (const std::string &ip, int banSeconds, const std::string &reasonCN, const std::string &reasonEN)
 立即将指定 IP 加入黑名单(直接封禁)。
 
void unbanIP (const std::string &ip)
 手动解除某个 IP 的黑名单。
 
bool isBanned (const std::string &ip) const
 判断某ip是否被封禁
 

Detailed Description

统一的连接与请求安全裁决器(IP 级 + fd 级,多策略限流 + 黑名单)。

ConnectionLimiter 是一个“安全门(Security Gate)”, 所有连接建立与请求处理在进入业务逻辑前,都必须经过该类的裁决。

本类不直接执行业务行为(如 close / send / sleep), 而是返回一个 DefenseDecision 结果,由外层统一执行。


设计概览

本类实现的是一个分层防御模型:

  • IP 级防御:
    • 并发连接数限制(maxConnections)
    • 建连速率限制(connectRate)
    • IP 风险评分(badScore)
    • 临时黑名单(blacklist,带 TTL)
  • fd 级防御:
    • 请求速率限制(requestRate)
    • path 级额外限流(pathRate)
    • 连接活动时间记录(lastActivity)

防御裁决语义

allowConnect / allowRequest 的返回值为 DefenseDecision

  • ALLOW (0):
    • 允许继续处理
  • DROP (1):
    • 无视本次请求(不回应、不处理)
    • 主要用于 request 阶段的轻度防御
  • CLOSE (2):
    • 立即断开连接
    • 可伴随 IP 风险升级或临时封禁
Note
  • connect 阶段由于 TCP 连接已建立,通常只使用 ALLOW / CLOSE
  • DROP 主要用于 request 阶段(fd 已存在时)

策略与限流

本类支持多种限流策略(见 RateLimitType):

  • Cooldown
  • FixedWindow
  • SlidingWindow
  • TokenBucket

不同维度使用不同策略:

  • 建连速率:connectStrategy(默认 Cooldown)
  • fd 级请求速率:requestStrategy(默认 SlidingWindow)
  • path 级请求速率:pathStrategy(默认 SlidingWindow)

线程安全

Warning
本类本身不包含锁:
  • table / pathConfig / blacklist 的并发安全 需由上层保证(如事件循环线程、外部互斥锁等)。

生命周期说明

  • allowConnect:
    • 判断 IP 是否允许进入应用层
    • 在 ALLOW 时登记 fd
  • allowRequest:
    • 对已登记 fd 进行请求裁决
  • clearIP:
    • 在连接关闭时调用,回收 fd 与并发计数
  • connectionDetect:
    • 用于检测并清理长时间无活动的僵尸连接

Constructor & Destructor Documentation

◆ ConnectionLimiter()

stt::security::ConnectionLimiter::ConnectionLimiter ( const int & maxConn = 20,
const int & idleTimeout = 60 )
inline

构造函数。

Parameters
maxConn同一 IP 允许的最大并发连接数(activeConnections 上限)。
idleTimeout连接僵尸检测超时时间(秒)。若 < 0 表示不做僵尸检测。

Member Function Documentation

◆ allowConnect()

DefenseDecision stt::security::ConnectionLimiter::allowConnect ( const std::string & ip,
const int & fd,
const int & times,
const int & secs )

对新建立的连接进行安全裁决(IP 级)。

Parameters
ip对端 IP 地址。
fd新 accept 得到的文件描述符。
times在 secs 秒内允许的最大建连次数。
secs建连速率统计窗口(秒)。
Returns
DefenseDecision
  • ALLOW:允许该连接进入应用层(fd 将被登记)
  • CLOSE:拒绝并应立即断开连接
Note
  • connect 阶段通常不使用 DROP
  • 若命中黑名单或高风险状态,将直接返回 CLOSE

◆ allowRequest()

DefenseDecision stt::security::ConnectionLimiter::allowRequest ( const std::string & ip,
const int & fd,
const std::string_view & path,
const int & times,
const int & secs )

对已建立连接的一次请求进行安全裁决。

Parameters
ip对端 IP 地址。
fd当前请求对应的文件描述符。
path请求路径(用于 path 级限流)。
timesfd 级请求速率上限。
secs请求速率统计窗口(秒)。
Returns
DefenseDecision
  • ALLOW:正常处理请求
  • DROP:无视本次请求(不回应)
  • CLOSE:断开连接

◆ banIP()

void stt::security::ConnectionLimiter::banIP ( const std::string & ip,
int banSeconds,
const std::string & reasonCN,
const std::string & reasonEN )

立即将指定 IP 加入黑名单(直接封禁)。

该接口用于在检测到“明确恶意行为”时,绕过评分与渐进惩罚, 直接对 IP 进行封禁(写入黑名单)。

封禁语义说明:

  • 若 IP 当前不在黑名单中:直接加入;
  • 若 IP 已在黑名单中:刷新(覆盖)封禁到期时间;
  • 若 banSeconds < 0:表示永久封禁(使用 time_point::max)。
Parameters
ip需要封禁的 IP 地址。
banSeconds封禁时长(秒):
  • > 0 :封禁 banSeconds 秒(短期封禁)
  • = 0 :不做任何操作
  • < 0 :永久封禁
reasonCN封禁原因(中文,用于日志)。
reasonEN封禁原因(英文,用于日志)。
Note
  • 本函数 不会 立即断开已有连接; 外层逻辑应在返回 CLOSE 后自行 close(fd)。
  • 使用 steady_clock,不受系统时间调整影响。
  • 该接口是安全裁决的“终态动作”,应谨慎调用。
  • 若 IP 已被封禁且原到期时间晚于本次封禁时间, 将保留更长的封禁(不会缩短)。

◆ clearIP()

void stt::security::ConnectionLimiter::clearIP ( const std::string & ip,
const int & fd )

在连接断开时回收对应 fd 的状态。

Parameters
ip对端 IP 地址。
fd已关闭的文件描述符。
Note
  • 必须在 close(fd) 后调用
  • 用于维护 activeConnections 与内部状态一致性

◆ connectionDetect()

bool stt::security::ConnectionLimiter::connectionDetect ( const std::string & ip,
const int & fd )

检测并清理僵尸连接(fd 级)。

Parameters
ip对端 IP 地址。
fd待检测的文件描述符。
Returns
true 该连接被判定为僵尸并已清理
false 未超时或不存在
Note
  • “活动”指 allowConnect / allowRequest 更新 lastActivity
  • 建议由外部定时器触发调用,避免热路径扫描

◆ isBanned()

bool stt::security::ConnectionLimiter::isBanned ( const std::string & ip) const

判断某ip是否被封禁

◆ setConnectStrategy()

void stt::security::ConnectionLimiter::setConnectStrategy ( const RateLimitType & type)

设置“连接速率限流”所使用的策略。

Parameters
type策略类型,见 RateLimitType 说明。
Note
不调用本函数时,默认策略为 RateLimitType::Cooldown

◆ setPathLimit()

void stt::security::ConnectionLimiter::setPathLimit ( const std::string & path,
const int & times,
const int & secs )

设置某个路径的额外限流规则(path 级)。

Parameters
path需要额外限流的路径,例如 "/login"、"/register"。
times在 secs 秒内允许的最大请求次数。
secs统计窗口长度(秒)。
Note
setPathLimit 配置的是 额外规则:
  • allowRequest 调用时传入的 (times, secs) 仍然会作为 IP 级规则先执行;
  • 若 path 命中此配置,则再执行 path 级规则;
  • 两者为 AND 关系:任何一层失败即拒绝。

◆ setPathStrategy()

void stt::security::ConnectionLimiter::setPathStrategy ( const RateLimitType & type)

设置“path 级请求限流”所使用的策略。

Parameters
type策略类型,见 RateLimitType 说明。
Note
不调用本函数时,默认策略为 RateLimitType::SlidingWindow

◆ setRequestStrategy()

void stt::security::ConnectionLimiter::setRequestStrategy ( const RateLimitType & type)

设置“IP 级请求限流”所使用的策略。

Parameters
type策略类型,见 RateLimitType 说明。
Note
不调用本函数时,默认策略为 RateLimitType::SlidingWindow

◆ unbanIP()

void stt::security::ConnectionLimiter::unbanIP ( const std::string & ip)

手动解除某个 IP 的黑名单。


The documentation for this class was generated from the following file: