免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1490 | 回复: 0
打印 上一主题 下一主题

内核打印的限速函数 net_ratelimit() [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-02 10:54 |只看该作者 |倒序浏览

                                                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 = 10*5*HZ; /*连续记录网络突发消息的间隔(最多连续记录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 = 10*5*HZ; /*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;
}


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/33173/showart_1161828.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP