内核打印的限速函数 net_ratelimit

net_ratelimit()函数是Linux内核中用于限制网络调试信息打印的机制,防止拒绝服务攻击。它限制每5秒最多打印10条信息,之后每隔5秒允许打印一次。该函数通过一个时间计数器实现,当计时器值达到阈值时允许打印,并在打印后减去相应的时间成本。若计时器未达到阈值,则禁止打印。
摘要由CSDN通过智能技术生成
  1. net_ratelimit()用于保护内核网络调试信息的打印, 当它返回(TRUE)时则可以打印调试信息,返回零则禁止信息打印. 它的特性为当"极快地"调用net_ratelimit()时,它最多只允许连续打印前10条信息, 后继信息每隔5秒允许打印一次.这样可防止攻击者使内核不断产生调试信息来使系统过载的拒绝服务攻击.2) net_ratelimit()定义了一个时间计数器变量(toks), 它随着系统时钟计数线性增长,但不超时50秒时钟计数(net_msg_burst). 当计时器的值大于或等于5秒时钟计数(net_msg_cost)时,则允许打印信息. 每允许打印一条信息, 计时器就减去5秒计数, 当计时器的值小于5秒时, 就不允许打印信息了.; net/core/utils.c:

int net_msg_cost = 5*HZ; /在拥塞时, 每条网络消息记录所间隔的时间/

int net_msg_burst = 105HZ; /连续记录网络突发消息的间隔(最多连续记录10条消息)/

/*

* This enforces a rate limit: not more than one kernel message

* every 5secs to make a denial-of-service attack impossible.

*

* All warning printk()s should be guarded by this function.

*/

int net_ratelimit(void)

{

static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;

static unsigned long toks = 105HZ; /50秒量程的计时器,每打印一条消息,计时器减5秒时间/

static unsigned long last_msg; /上一次调用net_ratelimit()的时戳/

static int missed; /两次net_ratelimit()调用之间所丢弃的信息数量/

unsigned long flags;

unsigned long now = jiffies; /取当前时戳/

spin_lock_irqsave(&ratelimit_lock, flags);

toks += now - last_msg;

/计时器加上两次net_ratelimit()调用的时间差,表现为计时时间的线性增长/

last_msg = now;

if (toks > net_msg_burst) /计时器累积时间超时50秒时/

toks = net_msg_burst;/* 设置计时上限*/

if (toks >= net_msg_cost) { /当计时大于或等于5秒时可以打印信息/

int lost = missed;

missed = 0;

toks -= net_msg_cost; /减去5秒时间/

spin_unlock_irqrestore(&ratelimit_lock, flags);

if (lost)

printk(KERN_WARNING “NET: %d messages suppressed.\n”, lost);

return 1;

}

missed++;

spin_unlock_irqrestore(&ratelimit_lock, flags);

return 0;

}

/linux 2.6内核直接调用__printk_ratelimit()/

int net_ratelimit(void)

{

return __printk_ratelimit(net_msg_cost, net_msg_burst);

}

kernel/printk.c

/*

* printk rate limiting, lifted from the networking subsystem.

*

* This enforces a rate limit: not more than one kernel message

* every printk_ratelimit_jiffies to make a denial-of-service

* attack impossible.

*/

int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)

{

static DEFINE_SPINLOCK(ratelimit_lock);

static unsigned long toks = 10 * 5 * HZ;

static unsigned long last_msg;

static int missed;

unsigned long flags;

unsigned long now = jiffies;

spin_lock_irqsave(&ratelimit_lock, flags);

toks += now - last_msg;

last_msg = now;

if (toks > (ratelimit_burst * ratelimit_jiffies))

toks = ratelimit_burst * ratelimit_jiffies;

if (toks >= ratelimit_jiffies) {

int lost = missed;

missed = 0;

toks -= ratelimit_jiffies;

spin_unlock_irqrestore(&ratelimit_lock, flags);

if (lost)

printk(KERN_WARNING “printk: %d messages suppressed.\n”, lost);

return 1;

}

missed++;

spin_unlock_irqrestore(&ratelimit_lock, flags);

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值