1) net_ratelimit()用于保护内核网络调试信息的打印, 当它返回(TRUE)时则可以打印调试信息,
返回零
则禁止信息打印. 它的特性为当"极快地"调用net_ratelimit()时,
它最多只允许连续打印前10条信息,
后继信息每隔5秒允许打印一次.
这样可防止攻击者使内核不断产生调试信息来使系统过载的拒绝服务攻击.
2) net_ratelimit()定义了一个时间计数器变量(toks), 它随着系统时钟计数线性增长,
但不超时50秒时
钟计数(net_msg_burst). 当计时器的值大于或等于5秒时钟计数(net_msg_cost)时,
则允许打印信息. 每
允许打印一条信息, 计时器就减去5秒计数, 当计时器的值小于5秒时, 就不允许打印信息了.
/*
int net_msg_cost = 5*HZ;
int net_msg_burst = 10;
int net_ratelimit(void)
{
return __printk_ratelimit(net_msg_cost, net_msg_burst);
}
*/
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; //计时器加上两次net_ratelimit()调用的时间差,表现为计时时间的线性增长
last_msg = now;
if (toks > (ratelimit_burst * ratelimit_jiffies)) //计时器累积时间超时50秒时
toks = ratelimit_burst * ratelimit_jiffies; //设置计时上限
if (toks >= ratelimit_jiffies) { //当计时大于或等于5秒时可以打印信息
int lost = missed;
missed = 0;
toks -= ratelimit_jiffies; //减去5秒时间
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;
}
可以参考:
阅读(4229) | 评论(0) | 转发(2) |