kk Blog —— 通用基础

date [-d @int|str] [+%s|"+%F %T"]

tcp连接建立过程

一、server

1. 接收syn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
tcp_v4_do_rcv {
	nsk = tcp_v4_hnd_req(sk, skb);

	nsk == sk


	tcp_rcv_state_process {
		icsk->icsk_af_ops->conn_request(sk, skb)
		tcp_v4_conn_request {
			__tcp_v4_send_synack {

				2. 发送syn/ack
			}
		}
	}
}
2. 接收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
38
39
40
41
42
43
44
45
tcp_v4_do_rcv {
	nsk = tcp_v4_hnd_req(sk, skb) {
		req = inet_csk_search_req
		nsk = tcp_check_req {
			tcp_v4_syn_recv_sock {
				tcp_create_openreq_child {
					inet_csk_clone {

						newsk->sk_state = TCP_SYN_RECV;

					}
				}
			}
		}
	}

	nsk != sk {
		tcp_child_process {
			tcp_rcv_state_process {

				if (!tcp_validate_incoming(sk, skb, th, 0))
					return 0;

				/* step 5: check the ACK field */
				if (th->ack) {
					int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0;

					switch (sk->sk_state) {
						case TCP_SYN_RECV:

						tcp_set_state(sk, TCP_ESTABLISHED);

					}

					case TCP_ESTABLISHED:
						tcp_data_queue(sk, skb);
						queued = 1;
						break;
					}
				}

			}
		}
	}
}

二、client

1. 发送syn
1
2
3
4
5
6
7
8
9
10
tcp_v4_connect {

	tcp_set_state(sk, TCP_SYN_SENT);

	tcp_connect {
		__tcp_add_write_queue_tail
		tcp_transmit_skb
		inet_csk_reset_xmit_timer
	}
}
2. 接收syn/ack
1
2
3
4
5
6
7
8
9
10
11
12
tcp_v4_do_rcv {
	sk->sk_state == TCP_SYN_SENT

	tcp_rcv_state_process {
		queued = tcp_rcv_synsent_state_process(sk, skb, th, len) {

			tcp_set_state(sk, TCP_ESTABLISHED);

			tcp_send_ack(sk); // 发送ack
		}
	}
}