端口哈希桶
在inet_csk_get_port函數(shù)中的變量聲名中有如下幾個結(jié)構(gòu)體:
struct inet_hashinfo *hinfo = sk- >sk_prot- >h.hashinfo;
struct inet_bind_hashbucket *head;
struct inet_bind_bucket *tb = NULL;
其中strcut inet_hashinfo是用來封裝各種協(xié)議的綁定哈希表,具體定義如下所示,這個結(jié)構(gòu)體在[Linux內(nèi)核角度分析服務(wù)器Listen細(xì)節(jié)中介紹過,具體地,struct inet_bind_hashbcket是bind相關(guān)的哈希桶,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;
};
具體每個桶結(jié)構(gòu)是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;
};
初次看到這幾個結(jié)構(gòu)體可能比較亂,下面用圖進(jìn)行描述:
由上圖所示,每個綁定的端口號經(jīng)過哈希計算都會掛在相應(yīng)的chain鏈表上,chain鏈表上是一個個的桶結(jié)構(gòu),同一個chain上的節(jié)點(diǎn)具有相同的哈希值(通過端口號計算),桶結(jié)構(gòu)inet_bind_bucket包含對應(yīng)的端口號port、owners等信息,owners對應(yīng):該端口號對應(yīng)的tcp_sock實(shí)例,如果該port支持復(fù)用,那么owners可能掛著多個tcp_sock節(jié)點(diǎn)。
在struct inet_bind_bucket中有一個關(guān)鍵的成員:signed char fastreuse
為了避免每次都遍歷 inet_bind_bucket 的 owners 字段 來獲知是否所有的 sock 都設(shè)置了 sk_reuse 字段,并且不是在 TCP_LISTEN 狀態(tài)。在 inet_bind_bucket 結(jié)構(gòu)體中設(shè)置了 fastreuse 字段。如果 owners 沒有元素,那么這 個字段為真。此后每次添加一個新的 sock 到 owners 中的時候,如果它設(shè)置了 sk_reuse 并且不在 TCP_LISTEN 狀態(tài),就維持 fastreuse 為真,否則設(shè)置它為假。
-
內(nèi)核
+關(guān)注
關(guān)注
3文章
1372瀏覽量
40293 -
Linux
+關(guān)注
關(guān)注
87文章
11304瀏覽量
209535
發(fā)布評論請先 登錄
相關(guān)推薦
評論