【问题标题】:derive socket fd from 'struct sock'从'struct sock'派生socket fd
【发布时间】:2017-10-15 19:15:16
【问题描述】:

有没有办法从内核中的struct sock 类型的对象获取套接字 fd?快速查看struct sock 内部并不能帮助找到看起来像套接字描述符的东西。基本上我需要socket() syscall 返回的内容,它不是存储在“sock”中吗?

我需要在数据包到达 IP 堆栈之前获取fd

谢谢。

【问题讨论】:

  • fd 编号仅存在于每个进程的基础上,因此不清楚在内核中请求 fd 时需要什么。
  • @Martin,感谢您的评论。基本上,当我有 'struct sock' 对象时,我希望能够知道它对应于用户空间中的哪个fd
  • 我的意思是,您可能需要以其他方式开始。获取特定进程的文件描述符表,遍历它并检查是否有一些记录指向有问题的套接字。一个或多个用户空间任务中的更多 fd 可以引用同一个套接字。 (抱歉,目前没有详细回答具体怎么做,因为我需要检查一些细节,现在没有时间,如果没有人会更快回答,也许稍后。)

标签: sockets networking linux-kernel system-calls


【解决方案1】:

对于每个进程,都有一个文件描述符表,它将文件描述符映射到struct file 对象。您可以使用iterate_fd() 函数迭代此表。

对于任何struct file,您可以使用sock_from_file() 函数确定它对应的struct sock 对象。

总共:

/*
 * Callback for iterate_fd().
 *
 * If given file corresponds to the given socket, return fd + 1.
 * Otherwise return 0.
 *
 * Note, that returning 0 is needed for continue the search.
 */
static int check_file_is_sock(void* s, struct file* f, int fd)
{
    int err;
    struct sock* real_sock = sock_from_file(f, &err);
    if(real_sock == s)
        return fd + 1;
    else
        return 0;
}
// Return file descriptor for given socket in given process.
int get_fd_for_sock(struct sock* s, struct task* p)
{
    int search_res;
    task_lock(p);
    // This returns either (fd + 1) or 0 if not found.
    search_res = iterate_fd(p->files, 0, &check_file_is_sock, s);
    task_unlock(p);

    if(search_res)
        return search_res - 1;
    else
        return -1; // Not found
}

【讨论】:

  • 请注意,完全有可能没有进程打开了套接字,有多个进程打开了套接字,甚至有多个进程打开了同一个套接字。跨度>
  • @Tsyvarev,感谢您的回答。你建议的代码只能在进程上下文中工作,我对吗?否则我将如何获得'task_struct'指针?我需要在数据包到达 IP 堆栈之前获取 fd
  • 这不必是一个进程上下文。您可以在之前的某个时间点存储task_struct,并在此处使用它。或者遍历所有任务以找到一个,其中包含给定的sock 对象。在任何情况下,您都需要task_struct 对象,因为没有它,文件描述符是没有意义的。正是在对您的问题和我的回答的评论中说明了这一点。
  • @Tsyvarev,在__netif_receive_skb_core() -> sch_handle_ingress() 代码路径中,我在哪里可以获得对task_struct 的引用?此时只有skb 可用,有可能通过skb->sk 到达file
猜你喜欢
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 2023-01-19
  • 2011-09-21
  • 2015-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多