kk Blog —— 通用基础


date [-d @int|str] [+%s|"+%F %T"]
netstat -ltunp
sar -n DEV 1

TCP_NEW_SYN_RECV fix bug

https://github.com/torvalds/linux/commit/5e0724d027f0548511a2165a209572d48fe7a4c8

TCP_NEW_SYN_RECV 漏了上面patch

把 syn_recv 状态的req也放进 sk 队列.

在收到第三个ack 的时候执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
tcp_check_req() {
	...
	child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, req, &own_req, 0);

	return inet_csk_complete_hashdance(sk, child, req, own_req);
}


tcp_v4_syn_recv_sock() {
	...
	// __inet_hash_nolisten(newsk, NULL); // 3.10.0
	__inet_hash_nolisten(newsk, NULL, req_to_sk(req_unhash), own_req); // fix
}

__inet_hash_nolisten() {
	...
	spin_lock(lock);
	if (osk) {
		*own_req = sk_nulls_del_node_init_rcu(osk);
	}
	spin_unlock(lock);
	...
}

inet_csk_complete_hashdance() {
	if (own_req) {
		inet_csk_reqsk_queue_drop(sk, req);
		reqsk_queue_removed(&inet_csk(sk)->icsk_accept_queue, req);
		if (inet_csk_reqsk_queue_add(sk, req, child))
			return child;
	}

	/* Too bad, another child took ownership of the request, undo. */
	bh_unlock_sock(child);
	sock_put(child);
	return NULL;
}

3.10.0 的代码 syn_recv_sock() -> __inet_hash_nolisten(newsk, NULL); 直接把newsk加到队列, 不考虑req。

就有可能出现BUG: 一个req创建了2个newsk, 在inet_csk_complete_hashdance的时候, 2个newsk都执行了inet_csk_reqsk_queue_drop. 导致req被多次释放

所以在splock内只让一个线程创建成功newsk, 用own_req标记

kernel, net

« PerformanceObserver监测网页性能 邮件SPF防伪 »