bind的核心執(zhí)行函數(shù)
bind系統(tǒng)調(diào)用的核心函數(shù)調(diào)用流程如下:
SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen)
|
sock- >ops- >bind(sock,
(struct sockaddr *)
&address, addrlen);
|
inet_bind
|
inet_csk_get_port
中間的流程暫且不看,本文主要分析最重要的函數(shù):inet_csk_get_port,從該函數(shù)出發(fā)了解本地綁定端口如何管理。
以下是原函數(shù),通過下文章節(jié)逐步分段分析
int inet_csk_get_port(struct sock *sk, unsigned short snum)
{
bool reuse = sk- >sk_reuse && sk- >sk_state != TCP_LISTEN;
struct inet_hashinfo *hinfo = sk- >sk_prot- >h.hashinfo;
int ret = 1, port = snum;
struct inet_bind_hashbucket *head;
struct net *net = sock_net(sk);
struct inet_bind_bucket *tb = NULL;
kuid_t uid = sock_i_uid(sk);
if (!port) {
head = inet_csk_find_open_port(sk, &tb, &port);
if (!head)
return ret;
if (!tb)
goto tb_not_found;
goto success;
}
head = &hinfo- >bhash[inet_bhashfn(net, port,
hinfo- >bhash_size)];
spin_lock_bh(&head- >lock);
inet_bind_bucket_for_each(tb, &head- >chain)
if (net_eq(ib_net(tb), net) && tb- >port == port)
goto tb_found;
tb_not_found:
tb = inet_bind_bucket_create(hinfo- >bind_bucket_cachep,
net, head, port);
if (!tb)
goto fail_unlock;
tb_found:
if (!hlist_empty(&tb- >owners)) {
if (sk- >sk_reuse == SK_FORCE_REUSE)
goto success;
if ((tb- >fastreuse > 0 && reuse) ||
sk_reuseport_match(tb, sk))
goto success;
if (inet_csk_bind_conflict(sk, tb, true, true))
goto fail_unlock;
}
success:
if (hlist_empty(&tb- >owners)) {
tb- >fastreuse = reuse;
if (sk- >sk_reuseport) {
tb- >fastreuseport = FASTREUSEPORT_ANY;
tb- >fastuid = uid;
tb- >fast_rcv_saddr = sk- >sk_rcv_saddr;
tb- >fast_ipv6_only = ipv6_only_sock(sk);
tb- >fast_sk_family = sk- >sk_family;
#if IS_ENABLED(CONFIG_IPV6)
tb- >fast_v6_rcv_saddr = sk- >sk_v6_rcv_saddr;
#endif
} else {
tb- >fastreuseport = 0;
}
} else {
if (!reuse)
tb- >fastreuse = 0;
if (sk- >sk_reuseport) {
if (!sk_reuseport_match(tb, sk)) {
tb- >fastreuseport = FASTREUSEPORT_STRICT;
tb- >fastuid = uid;
tb- >fast_rcv_saddr = sk- >sk_rcv_saddr;
tb- >fast_ipv6_only = ipv6_only_sock(sk);
tb- >fast_sk_family = sk- >sk_family;
#if IS_ENABLED(CONFIG_IPV6)
tb- >fast_v6_rcv_saddr = sk- >sk_v6_rcv_saddr;
#endif
}
} else {
tb- >fastreuseport = 0;
}
}
if (!inet_csk(sk)- >icsk_bind_hash)
inet_bind_hash(sk, tb, port);
WARN_ON(inet_csk(sk)- >icsk_bind_hash != tb);
ret = 0;
fail_unlock:
spin_unlock_bh(&head- >lock);
return ret;
}
-
Linux
+關(guān)注
關(guān)注
87文章
11345瀏覽量
210409 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4346瀏覽量
62978 -
系統(tǒng)
+關(guān)注
關(guān)注
1文章
1019瀏覽量
21431
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
linux中的busybox,是否帶有bind和ifenslave?
Bind源代碼包安裝
linux c函數(shù)庫參考手冊(cè)_徐千洋
Linux教程之Linux C函數(shù)參考教程免費(fèi)下載
![<b class='flag-5'>Linux</b>教程之<b class='flag-5'>Linux</b> C<b class='flag-5'>函數(shù)</b>參考教程免費(fèi)下載](https://file.elecfans.com/web1/M00/8A/88/o4YBAFyRk0qASN6VAAYgz4K0vHA536.png)
Linux下進(jìn)程的創(chuàng)建、執(zhí)行和終止
如何使用Arduino millis函數(shù)執(zhí)行多任務(wù)處理
![如何使用Arduino millis<b class='flag-5'>函數(shù)</b><b class='flag-5'>執(zhí)行</b>多任務(wù)處理](https://file.elecfans.com/web2/M00/67/C8/pYYBAGMW60iAYtxhAABWB9UQiL8404.png)
什么是bind?你真的熟悉bind嗎?
bind系統(tǒng)調(diào)用背后的端口管理復(fù)用
![<b class='flag-5'>bind</b>系統(tǒng)調(diào)用背后的端口管理復(fù)用](https://file1.elecfans.com/web2/M00/8E/6B/wKgZomTHIB2AVtO2AAAfP5q_nsk559.jpg)
Linux內(nèi)核分析 端口哈希桶
![<b class='flag-5'>Linux</b>內(nèi)核分析 端口哈希桶](https://file1.elecfans.com/web2/M00/8E/6B/wKgZomTHIB2AVtO2AAAfP5q_nsk559.jpg)
Linux內(nèi)核分析 bind端口選擇
SCP固件執(zhí)行步驟和模塊間通信
![SCP固件<b class='flag-5'>執(zhí)行</b>步驟和模塊間通信](https://file1.elecfans.com/web2/M00/AD/EB/wKgZomVDYz-AUM4dAAI_K0SohKc889.jpg)
評(píng)論