0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux bind的核心执行函数

麦辣鸡腿堡 来源:技术简说 作者:董旭 2023-07-31 10:51 次阅读

bind的核心执行函数

bind系统调用的核心函数调用流程如下:

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

中间的流程暂且不看,本文主要分析最重要的函数:inet_csk_get_port,从该函数出发了解本地绑定端口如何管理。

以下是原函数,通过下文章节逐步分段分析

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
    +关注

    关注

    87

    文章

    11222

    浏览量

    208886
  • 函数
    +关注

    关注

    3

    文章

    4304

    浏览量

    62416
  • 系统
    +关注

    关注

    1

    文章

    1006

    浏览量

    21310
收藏 人收藏

    评论

    相关推荐

    Linux源码分析bind系统调用

    众所周知,一个Server端Socket的建立,需要socket、bind、listen、accept四个步骤。
    的头像 发表于 10-16 11:08 3229次阅读
    从<b class='flag-5'>Linux</b>源码分析<b class='flag-5'>bind</b>系统调用

    linux中的busybox,是否带有bind和ifenslave?

    想问下,飞凌提供的linux中的busybox,是否带有bind和ifenslave?如果没有有什么办法可以添加?
    发表于 01-11 06:53

    Bind源代码包安装

    先到官方下载Bind的安装包 wgetftp://ftp.isc.org/isc/bind9/9.6.0-P1/bind-9.6.0-P1.tar.gz tar xzvf
    发表于 04-04 20:30 23次下载

    linux c函数库参考手册_徐千洋

    书中整理了超过400个Linux常用的函数,每个函数以整齐划一的体例列出了函数名称、相关函数、使用的表头文件、
    发表于 11-29 17:12 0次下载

    Linux C函数手册

    Linux C函数库参考,一本linux学习的参考备查手册
    发表于 11-03 17:33 0次下载

    linux_C函数库中文手册

    linux_C函数库中文手册linux_C函数库中文手册
    发表于 03-20 10:42 14次下载

    Linux C函数参考手册

    Linux C函数参考手册
    发表于 10-25 15:32 6次下载
    <b class='flag-5'>Linux</b> C<b class='flag-5'>函数</b>参考手册

    Linux教程之Linux C函数参考教程免费下载

    本文档的主要内容详细介绍的是Linux教程之Linux C函数参考教程免费下载。
    发表于 03-20 08:00 4次下载
    <b class='flag-5'>Linux</b>教程之<b class='flag-5'>Linux</b> C<b class='flag-5'>函数</b>参考教程免费下载

    Linux下进程的创建、执行和终止

     许多操作系统提供的都是产生进程的机制,也就是说,首先在新的地址空间里创建进程、读入可执行文件,后再开始执行Linux中进程的创建很特别,它把上述步骤分解到两个单独的函数中去
    发表于 06-11 09:21 606次阅读

    如何使用Arduino millis函数执行多任务处理

    在本教程中,我们将学习Arduino 如何使用 Arduino millis 函数执行多任务处理。通常在 Arduino 中使用delay()函数执行LED 闪烁等周期性任务,但此
    的头像 发表于 09-06 14:41 1.3w次阅读
    如何使用Arduino millis<b class='flag-5'>函数</b><b class='flag-5'>执行</b>多任务处理

    什么是bind?你真的熟悉bind吗?

    bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被指定 bind()的第一个参数,而其余参数将作为新
    的头像 发表于 07-13 09:56 2673次阅读

    bind系统调用背后的端口管理复用

    bind系统调用进行分析,主要是了解一下bind背后,Linux内核是如何进行端口绑定、如何管理本地众多的端口号。 先直观感受bind系统调用背后的端口管理、端口复用 # inclu
    的头像 发表于 07-31 10:45 519次阅读
    <b class='flag-5'>bind</b>系统调用背后的端口管理复用

    Linux内核分析 端口哈希桶

    是用来封装各种协议的绑定哈希表,具体定义如下所示,这个结构体在[Linux内核角度分析服务器Listen细节中介绍过,具体地,struct inet_bind_hashbcket是bind相关的哈希桶
    的头像 发表于 07-31 11:03 730次阅读
    <b class='flag-5'>Linux</b>内核分析 端口哈希桶

    Linux内核分析 bind端口选择

    端口选择 继续看inet_csk_get_port函数: 在端口选择前, 先确定当前该socket的“属性”,即是否可以端口复用,是否在TCP_LISTEN状态,以便后面插入到桶队列时设置
    的头像 发表于 07-31 11:08 909次阅读

    SCP固件执行步骤和模块间通信

    SCP固件执行步骤 运行前阶段:按固定顺序排列的5个阶段 • 模块初始化:框架使用模块配置数据调用的模块的.init()函数。 • 元素初始化:带有元素配置数据的框架调用的模块
    的头像 发表于 11-02 17:02 922次阅读
    SCP固件<b class='flag-5'>执行</b>步骤和模块间通信