ratelimit

package
v0.1.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2026 License: GPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package ratelimit wraps connections with a token-bucket rate limiter.

XrayR 的 RateWriter(xray buf.Writer/MultiBuffer 适配器)在此重写为包装 sing N.ExtendedConn / N.PacketConn 的令牌桶限速。sing 无内置限速器,故自实现: 在 Read/ReadBuffer/Write/WriteBuffer(以及 UDP 的 ReadPacket/WritePacket)取得 本次传输字节数 n 后,调用 *rate.Limiter.WaitN(ctx, n) 阻塞到令牌可用。

bucket 的 burst/limit 由 limiter.GetUserBucket 给出(已是 int(limit) bytes/s), 本包只负责按 bucket 限流,不做 Mbps→bytes/s 换算。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AutoLimiter

type AutoLimiter struct {
	// contains filtered or unexported fields
}

AutoLimiter 是动态限速状态机,移植自 XrayR service/controller 的 AutoSpeedLimitConfig + warnedUsers/limitedUsers 逻辑(controller.go limitUser / userInfoMonitor 动态限速段,v0.9.4)。

它是纯状态机:只维护每 key 的告警计数与限速到期时间,不直接触碰 limiter/stats。由 Integrate 阶段在 Controller 周期任务里驱动——每周期 读 billing/stats 拿到本周期用户增量 (up,down),喂给 Check 判定是否施限; 施限走 limiter.UpdateInboundLimiter(把 limitTo 写进 UserInfo.SpeedLimit), 到期释放的 key 由 Release 给出、同样走 limiter 恢复原速。

语义对齐 XrayR:

  • 阈值:单周期 up 或 down 超过 limit*1e6*period/8 字节即视为超速。
  • WarnTimes==0:一超速立即施限。
  • WarnTimes>0:需连续超速,告警计数严格大于 WarnTimes 才施限 (即第 WarnTimes+1 次连续超速触发);任一周期未超速则计数清零。
  • 已处于限速中的 key 再次超速不重复施限(沿用 !ok 守卫)。
  • 施限时长:end = 施加时刻 + LimitDuration*60 秒;Release 在 now>end 时(严格大于,对齐 XrayR)释放。

func NewAutoLimiter

func NewAutoLimiter(limit, warnTimes, limitSpeed, limitDuration int) *AutoLimiter

NewAutoLimiter 构造动态限速状态机。参数单位对齐 XrayR AutoSpeedLimitConfig: limit/limitSpeed 为 Mbps,limitDuration 为分钟,warnTimes 为连续超速容忍次数。 limit<=0 时状态机停用(Check 恒返回未施限)。

func (*AutoLimiter) Check

func (a *AutoLimiter) Check(key string, up, down int64, period int) (limitTo int, limited bool)

Check 对单个用户做单周期超速判定。up/down 为本周期(period 秒)内的字节增量 (通常来自 billing/stats 的一次 reset 读值)。

返回 (limitTo, limited):limited 为 true 表示本次判定触发了新的限速,limitTo 为应施加的限速值,单位 bytes/s(LimitSpeed*1e6/8,对齐 XrayR 写入 UserInfo.SpeedLimit 的口径)。limited 为 false 时 limitTo 为 0——包括未超速、 仍在告警累计中、以及已处于限速中再次超速这几种不产生新动作的情形。

func (*AutoLimiter) Release

func (a *AutoLimiter) Release(now int64) (releasedKeys []string)

Release 释放所有到期(now > end)的限速用户,返回被释放的 key 列表,供调用方 走 limiter 恢复原速。now 为当前 Unix 秒(由调用方传入,便于测试与统一时钟)。

type Manager

type Manager struct{}

Manager 是限速包装工厂,无状态。

func (*Manager) Wrap

func (m *Manager) Wrap(bucket *rate.Limiter, conn net.Conn) net.Conn

Wrap 用 bucket 包装 conn:Read/Write(含 Buffer 零拷贝路径)前后按字节数 WaitN。 bucket 为 nil 时原样返回 conn(无限速)。

func (*Manager) WrapPacket

func (m *Manager) WrapPacket(bucket *rate.Limiter, conn N.PacketConn) N.PacketConn

WrapPacket 用 bucket 包装 UDP PacketConn:ReadPacket/WritePacket 按字节数 WaitN。 bucket 为 nil 时原样返回 conn(无限速)。

type RateConn

type RateConn struct {
	N.ExtendedConn
	// contains filtered or unexported fields
}

RateConn 包装 N.ExtendedConn,在每次读写按实际字节数向令牌桶取令牌。

func (*RateConn) Read

func (c *RateConn) Read(p []byte) (n int, err error)

func (*RateConn) ReadBuffer

func (c *RateConn) ReadBuffer(buffer *buf.Buffer) error

func (*RateConn) Upstream

func (c *RateConn) Upstream() any

Upstream 供 sing 的解包链识别底层连接。

func (*RateConn) Write

func (c *RateConn) Write(p []byte) (n int, err error)

func (*RateConn) WriteBuffer

func (c *RateConn) WriteBuffer(buffer *buf.Buffer) error

type RatePacketConn

type RatePacketConn struct {
	N.PacketConn
	// contains filtered or unexported fields
}

RatePacketConn 包装 N.PacketConn,对 UDP 收发按字节数向令牌桶取令牌。

func (*RatePacketConn) ReadPacket

func (c *RatePacketConn) ReadPacket(buffer *buf.Buffer) (destination M.Socksaddr, err error)

func (*RatePacketConn) Upstream

func (c *RatePacketConn) Upstream() any

Upstream 供 sing 的解包链识别底层连接。

func (*RatePacketConn) WritePacket

func (c *RatePacketConn) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL