linux内核学习笔记------对端信息块

本文介绍了Linux内核中的对端信息块,主要用于防止IP数据包分片攻击和TCP连接验证。对端信息块由inet_peer结构体表示,组织成AVL树,并通过inet_getpeer进行创建和查询。当引用计数为0时,对端信息块会被移到未使用链表,清理工作可通过同步或异步(定时器)方式进行。

首先,什么是对端信息块?

在linux内核源码剖析——tcp/ip实现这本书中是真么介绍的:对端信息块主要用于组装ip数据包时防止分片攻击,在建立tcp连接时检测连接请求段是否有效以及其序列号是否回绕

在linux内核中是通过inet_peer结构体描述的:

struct inet_peer
{
	/* group together avl_left,avl_right,v4daddr to speedup lookups */
	/*
	 * avl_left、avl_right、avl_height用来将对端信息
	 * 块组成AVL树。AVL树的根为peer_root。
	 */
	struct inet_peer	*avl_left, *avl_right;
	/*
	 * 对端的IP地址。
	 */
	__be32			v4daddr;	/* peer's address */
	__u16			avl_height;
	/*
	 * 一个单调递增值,用来设置IP分片首部中
	 * 的id域。根据对端地址初始化为随机值。
	 */
	__u16			ip_id_count;	/* IP ID for the next packet */
	/*
	 * 用来链接到inet_peer_unused_head链表上。该
	 * 链表上的对端信息块都是当前闲置的,
	 * 可回收的。
	 */
	struct list_head	unused;
	/*
	 * 记录该对端信息块引用计数为0的时间。
	 * 当闲置的时间超出指定的时间时,
	 * 就会被回收。
	 */
	__u32			dtime;		/* the time of last use of not
						 * referenced entries */
	/*
	 * 引用计数器,标识当前被使用的次数。
	 * 当引用计数为0,表示该对端信息块
	 * 没有被使用。
	 */
	atomic_t		refcnt;
	/*
	 * 递增ID,对端发送分片的计数器。
	 * 参见ipq结构中的rid成员。
	 */
	atomic_t		rid;		/* Frag reception counter */
	/*
	 * TCP中,记录最后一个ACK段到达的
	 * 时间。参见tcp_options_received结构中
	 * 的ts_recent成员。
	 */
	__u32			tcp_ts;
	/*
	 * TCP中,记录接收到的段中的时间戳,
	 * 设置ts_recent的时间。参见tcp_options_received
	 * 结构中的ts_recent_stamp成员。
	 */
	unsigned long		tcp_ts_stamp;
};
代码中都有注释,其中注释来自于:
http://blog.youkuaiyun.com/justlinux2010

对端信息块主要是以ip地址为关键字,peer_root为根,组织成AVL树。

对端信息块的创建和查询都是通过inet_getpeer来完成的,如果查询到了,自然会返回查询到的结果,但是如果查询到的结果在没有使用的对端信息块的链表(没用使用的对端信息块会被组织到一个链表中,也就是ient_peer_unused_head)中,会将它从其中删除,如果没有找到结果,会根据参数create来判断是否创建。

对端信息块的删除其实只是减小对端信息块的引用计数,如果减到0,就会把该对端信息块添加到inet_peer_unused_head中。真正删除对端信息块是通过cleanup_once这个函数。

清除对端信息块有两种方式-----同步和异步;同步的方式其实就是在inet_geetpeer中:

	if (peer_total >= inet_peer_threshold)
		/* Remove one less-recently-used entry. */
		cleanup_once(0);
如果peer_total大于inet_peer_threadhold就会调用cleanup_once删除。peer_total在每次创建对端信息块的时候就会增加,而inet_peer_threadhold是一个系统参数。

而异步方式也就是所谓的定时器实现的,也就是调用peer_check_expire,初始时间是通过inet_initpeers中设置。

static void peer_check_expire(unsigned long dummy)
{
	unsigned long now = jiffies;
	int ttl;

        	/*
	 * 根据当前对端信息块数计算本次垃圾回收
	 * 的对端信息块生存期阈值。当前对端信息
	 * 块数大于inet_peer_threshold时,使用inet_peer_minttl
	 * 作为本次垃圾回收的对端信息块生存期
	 * 阈值,否则根据inet_peer_maxttl来计算本次垃圾
	 * 回收的对端信息块生存期阈值。
	 */
	if (peer_total >= inet_peer_threshold)
		ttl = inet_peer_minttl;
	else
		ttl = inet_peer_maxttl
				- (inet_peer_maxttl - inet_peer_minttl) / HZ *
					peer_total / inet_peer_threshold * HZ;

	while (!cleanup_once(ttl)) {
		if (jiffies != now)
			break;
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值