linux内核tcp syn seq读取

2024-01-03 19:17:18

一?书上讲tcp?连接初始seq是随机取的,这里分析一下流程。

二?代码流程梳理

want_cookie?不在本文讨论范围,洪泛攻击的情况这里就不做分析了。

linux内核通过tcp_conn_request?完成握手动作。

初始syn的seq分为两种情况。

2.1?复用之前的timewait端口连接的最后一次的序列号。

__u32?isn?=?TCP_SKB_CB(skb)->tcp_tw_isn;

这样在接受连接一端,就会判断seq是符合递增的逻辑的,不会拒绝这次syn请求。

2.2?之前没有过连接的端口

isn?=?af_ops->init_seq(skb);

.init_seq??=???tcp_v4_init_seq,

分析一下tcp_v4_init_seq?函数。

static?u32?tcp_v4_init_seq(const?struct?sk_buff?*skb)

{

????return?secure_tcp_seq(ip_hdr(skb)->daddr,

??????????????????ip_hdr(skb)->saddr,

??????????????????tcp_hdr(skb)->dest,

??????????????????tcp_hdr(skb)->source);

}

tcp_v4_init_seq?参数是链接四元组

u32?secure_tcp_seq(__be32?saddr,?__be32?daddr,

???????????__be16?sport,?__be16?dport)

{

????u32?hash;

????net_secret_init();?//?获取随机数,用随机数生成密钥,存入net_secret

????hash?=?siphash_3u32((__force?u32)saddr,?(__force?u32)daddr,

????????????????(__force?u32)sport?<<?16?|?(__force?u32)dport,

????????????????&net_secret);//全局变量?net_secret?

//通过net_secret?得到一个hash值

????return?seq_scale(hash);?

}

static?u32?seq_scale(u32?seq)

{

????/*

?????*??As?close?as?possible?to?RFC?793,?which

?????*??suggests?using?a?250?kHz?clock.

?????*??Further?reading?shows?this?assumes?2?Mb/s?networks.

?????*??For?10?Mb/s?Ethernet,?a?1?MHz?clock?is?appropriate.

?????*??For?10?Gb/s?Ethernet,?a?1?GHz?clock?should?be?ok,?but

?????*??we?also?need?to?limit?the?resolution?so?that?the?u32?seq

?????*??overlaps?less?than?one?time?per?MSL?(2?minutes).

?????*??Choosing?a?clock?of?64?ns?period?is?OK.?(period?of?274?s)

?????*/

????return?seq?+?(ktime_get_real_ns()?>>?6);

}

尽可能接近RFC?793

*建议使用250?kHz时钟。

*进一步的阅读表明,这是假设2?Mb/s的网络。

*对于10?Mb/s以太网,1?MHz时钟是合适的。

*对于10?Gb/s以太网,1?GHz时钟应该可以,但是

*我们还需要限制分辨率,以便u32-seq

*每个MSL重叠少于一次(2分钟)。

*选择64?ns周期的时钟是可以的。(274?s周期)

通过上面的seq_scale?生成最终的随机数seq

文章来源:https://blog.csdn.net/fantasy_ARM9/article/details/135366881
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。