連線請求塊(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 客戶必須再次回應伺...