端口哈希桶
在inet_csk_get_port函數中的變量聲名中有如下幾個結構體:
struct inet_hashinfo *hinfo = sk- >sk_prot- >h.hashinfo;
struct inet_bind_hashbucket *head;
struct inet_bind_bucket *tb = NULL;
其中strcut inet_hashinfo是用來封裝各種協議的綁定哈希表,具體定義如下所示,這個結構體在[Linux內核角度分析服務器Listen細節中介紹過,具體地,struct inet_bind_hashbcket是bind相關的哈希桶,bhash_size是bind哈希桶的大小。
struct inet_hashinfo {
struct inet_ehash_bucket *ehash;
spinlock_t *ehash_locks;
unsigned int ehash_mask;
unsigned int ehash_locks_mask;
struct inet_bind_hashbucket *bhash;
unsigned int bhash_size;
struct inet_listen_hashbucket listening_hash[INET_LHTABLE_SIZE]
____cacheline_aligned_in_smp;
};
struct inet_bind_hashbcket哈希桶的具體定義如下,其中chain代表著各個桶的哈希隊列,用來鏈接具有同一哈希值的哈希元素
struct inet_bind_hashbucket {
spinlock_t lock;
struct hlist_head chain;
};
具體每個桶結構是struct inet_bind_bucket:
struct inet_bind_bucket {
possible_net_t ib_net;
unsigned short port;
signed char fastreuse;
signed char fastreuseport;
kuid_t fastuid;
#if IS_ENABLED(CONFIG_IPV6)
struct in6_addr fast_v6_rcv_saddr;
#endif
__be32 fast_rcv_saddr;
unsigned short fast_sk_family;
bool fast_ipv6_only;
struct hlist_node node;
struct hlist_head owners;
};
初次看到這幾個結構體可能比較亂,下面用圖進行描述:
由上圖所示,每個綁定的端口號經過哈希計算都會掛在相應的chain鏈表上,chain鏈表上是一個個的桶結構,同一個chain上的節點具有相同的哈希值(通過端口號計算),桶結構inet_bind_bucket包含對應的端口號port、owners等信息,owners對應:該端口號對應的tcp_sock實例,如果該port支持復用,那么owners可能掛著多個tcp_sock節點。
在struct inet_bind_bucket中有一個關鍵的成員:signed char fastreuse
為了避免每次都遍歷 inet_bind_bucket 的 owners 字段 來獲知是否所有的 sock 都設置了 sk_reuse 字段,并且不是在 TCP_LISTEN 狀態。在 inet_bind_bucket 結構體中設置了 fastreuse 字段。如果 owners 沒有元素,那么這 個字段為真。此后每次添加一個新的 sock 到 owners 中的時候,如果它設置了 sk_reuse 并且不在 TCP_LISTEN 狀態,就維持 fastreuse 為真,否則設置它為假。
-
內核
+關注
關注
3文章
1382瀏覽量
40425 -
Linux
+關注
關注
87文章
11345瀏覽量
210399
發布評論請先 登錄
相關推薦
Android內核分析
基于Linux 2.6內核Makefile分析
![基于<b class='flag-5'>Linux</b> 2.6<b class='flag-5'>內核</b>Makefile<b class='flag-5'>分析</b>](https://file.elecfans.com/web2/M00/49/C9/pYYBAGKhvF-AaNxuAAAWx5Gmzlo629.jpg)
評論