TCP連線建立系列 連線請求塊

2021-06-19 10:14:42 字數 4825 閱讀 9274

連線請求塊(request_sock)之於tcp三次握手,就如同網路資料報(sk_buff)之於網路協議棧,都是核心的資料結構。

核心版本:3.6

author:zhangskd @ csdn blog

連線請求塊的儲存佇列:包括全連線佇列、半連線佇列。

/**

* @icsk_accept_queue: fifo of established children

*/struct inet_connection_sock ;

/* struct request_sock_queue - queue of request_sock

* @rskq_accept_head: fifo head of established children

* @rskq_accept_tail: fifo tail of established children

* @syn_wait_lock: serializer

* @rskq_defer_accept: user waits for some data after accept()

*/struct request_sock_queue ;

連線請求塊(request_sock)儲存在兩個佇列中:

(1) 處於syn_recv狀態,即半連線佇列

儲存在icsk->icsk_accept_queue.listen_opt中,這個listen_sock例項在listen()後建立。

當客戶端的ack到達時,連線請求塊會被移動到established狀態的連線請求塊佇列中。

注意,半連線佇列是在listen()時建立的。

(2) 處於established狀態,即全連線佇列

儲存在icsk->icsk_accept_queue.rskq_accept_head和icsk->icsk_accept_queue.rskq_accept_tail

所指定的fifo佇列中。此佇列的連線請求塊等待accept()的獲取。

listen_sock用於儲存syn_recv狀態的連線請求塊,它的例項在listen()時建立。

/* struct listen_sock - listen state

* * @max_qlen_log - log_2 of maximal queued syns/requsts

*/struct listen_sock ;

最基本表示。

/* struct request_sock - mini sock to represent a connection request */

struct request_sock ;

inet層表示。

struct inet_request_sock ;
tcp層表示為tcp_request_sock。

struct tcp_request_sock ;
request_sock_ops為處理連線請求塊的函式指標表,對於tcp,它的例項為tcp_request_sock_ops。

struct request_sock_ops ;
對於tcp,它的例項為tcp_request_sock_ops。

struct request_sock_ops tcp_request_sock_ops__read_mostly = ;
(1)分配

從快取塊中分配乙個request_sock例項,並指定此例項的操作函式集。

static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops)

return req;}

static inline struct request_sock *reqsk_alloc(const struct request_sock_ops *ops)

(2)釋放

釋放乙個request_sock例項。

static inline void reqsk_free(struct request_sock *req)

/* ipv4 request_sock destructor. */

static void tcp_v4_reqsk_destructor(struct request_sock *req)

static inline void __reqsk_free(struct request_sock *req)

(3)初始化

初始化連線請求塊,包括request_sock、inet_request_sock、tcp_request_sock。

static inline void tcp_openreq_init(struct request_sock *req, 

struct tcp_options_received *rx_opt, struct sk_buff *skb)

(4)入佇列

把連線請求塊鏈入半連線佇列中。

void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, unsigned long timeout)

設定連線請求塊的超時時間、按照hash值把它鏈入半連線佇列。

static inline void reqsk_queue_hash_req(struct request_sock_queue *queue, u32 hash,

struct request_sock *req, unsigned long timeout)

static inline void inet_csk_reqsk_queue_added(struct sock *sk, const unsigned long timeout)

static inline int reqsk_queue_added(struct request_sock_queue *queue)

void inet_csk_reset_keepalive_timer(struct sock *sk, unsigned long len)

根據目的ip、目的埠和隨機數,計算出該連線請求塊的hash值。

static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport, const u32 rnd, 

const u32 synq_hsize)

static inline u32 jhash_2words(u32 a, u32 b, u32 initval)

static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval)

/* an arbitrary initial parameter */

#define jhash_initval 0xdeadbeef

/* __jhash_final - final mixing of 3 32-bit values (a, b, c) into c */

#define __jhash_final(a, b, c) \

/*** rol32 - rotate a 32-bit value left

* @word: value to rotate

* @shift: bits to roll

*/static inline __u32 rol32(__u32 word, unsigned int shift)

(5) 出佇列

把連線請求塊從半連線佇列中刪除。 

static inline void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req,

struct request_sock **prev)

static inline void inet_csk_reqsk_queue_unlink(struct sock *sk, struct request_sock *req,

struct request_sock **prev)

把連線請求塊從半連線佇列中刪除。

static inline void reqsk_queue_unlink(struct request_sock_queue *queue, struct request_sock *req,

struct request_sock **prev_req)

static inline void inet_csk_reqsk_queue_removed(struct sock *sk, struct request_sock *req)

更新未重傳過的連線請求塊數、更新半連線佇列長度。

static inline int reqsk_queue_removed(struct request_sock_queue *queue, struct request_sock *req)

TCP建立連線

3 月,跳不動了?對tcp 面向連線 特性的學習研究。什麼是面向連線?tcp為什麼要進行面向連線的通訊?tcp 連線建立的過程是怎樣的?建立連線的通訊過程 打 是面向連線的通訊 a 呼叫 b b 接受並且此時 a 還沒有結束通話,連線建立成功,a b 雙方正常通訊。如果 b 不接受呼叫,連線無法建立...

TCP建立連線與釋放連線

tcp建立連線與釋放連線 tcp建立連線與釋放連線 最近複習準備 計算機網路 考試,感覺tcp協議建立連線與釋放連線這兩個過程比較重要,所以把自己理解的部分寫下來。1.建立連線 三次握手 1 客戶端傳送乙個syn包給伺服器,然後等待應答。2 伺服器端回應給客戶端乙個ack 1 syn 1的tcp資料...

TCP建立連線與釋放連線

tcp建立連線與釋放連線 最近複習準備 計算機網路 考試,感覺tcp協議建立連線與釋放連線這兩個過程比較重要,所以把自己理解的部分寫下來。1.建立連線 三次握手 1 客戶端傳送乙個syn包給伺服器,然後等待應答。2 伺服器端回應給客戶端乙個ack 1 syn 1的tcp資料段。3 客戶必須再次回應伺...