端口哈希桶
在inet_csk_get_port函數(shù)中的變量聲名中有如下幾個結構體:
struct inet_hashinfo *hinfo = sk- >sk_prot- >h.hashinfo;
struct inet_bind_hashbucket *head;
struct inet_bind_bucket *tb = NULL;
其中strcut inet_hashinfo是用來封裝各種協(xié)議的綁定哈希表,具體定義如下所示,這個結構體在[Linux內核角度分析服務器Listen細節(jié)中介紹過,具體地,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上的節(jié)點具有相同的哈希值(通過端口號計算),桶結構inet_bind_bucket包含對應的端口號port、owners等信息,owners對應:該端口號對應的tcp_sock實例,如果該port支持復用,那么owners可能掛著多個tcp_sock節(jié)點。
在struct inet_bind_bucket中有一個關鍵的成員:signed char fastreuse
為了避免每次都遍歷 inet_bind_bucket 的 owners 字段 來獲知是否所有的 sock 都設置了 sk_reuse 字段,并且不是在 TCP_LISTEN 狀態(tài)。在 inet_bind_bucket 結構體中設置了 fastreuse 字段。如果 owners 沒有元素,那么這 個字段為真。此后每次添加一個新的 sock 到 owners 中的時候,如果它設置了 sk_reuse 并且不在 TCP_LISTEN 狀態(tài),就維持 fastreuse 為真,否則設置它為假。
-
內核
+關注
關注
4文章
1467瀏覽量
42867 -
Linux
+關注
關注
88文章
11756瀏覽量
219000
發(fā)布評論請先 登錄
Linux的內核教程
Android內核分析
基于Linux 2.6內核Makefile分析
Linux內核分析 端口哈希桶
評論