在Linux内核中,我发现系统调用getsockopt
最终调用sock->ops->getsockopt
(code here)。sock->ops
是一个名为proto_ops
的结构。这个结构包含许多函数指针,比如getsockopt
,我想知道它指向哪里-我没有找到启动这个结构的地方。
我正在使用IPv4和TCP进行系统调用,它可能有一些特定的实现函数要在这里调用。
任何洞察都会非常有帮助。提前谢谢!
最佳答案
对于IPv4套接字,ops将是inet_stream_ops
中定义的结构inet_dgram_ops
、inet_sockraw_ops
、net/ipv4/af_inet.c
之一(除非您正在使用类似SCTP的奇怪的东西,它在别处定义了自己的ops)。要查看这些指针是如何到达那里的,请查看同一个文件中的inet_create
,即called from __sock_create
as pf->create()
。
要查看指针是如何到达那里的,请注意inet_create
是名为create
的结构的inet_family_ops
成员,该结构是passed to sock_register()
,导致它被放置在net_families
数组中,该数组在创建套接字时被查询。
当您想了解不同的内核组件是如何连接的时,以register
命名的函数是一个很好的选择。
现在回到getsockopt
。如果您查看getsockopt
指针的实际位置,那么在所有3个inet_*_ops
结构中,它都指向sock_common_getsockopt
函数的getsockopt
。sock_common_getsockopt
中的net/core/sock.c
不是很有趣。它只是从astruct sock
中提取astruct socket
,然后调用sk->sk_prot->getsockopt
。所以接下来你会想知道那是从哪里来的。
它来自下一层。我将以TCP为例。
在net/ipv4/tcp_ipv4.c
中有一个struct proto tcp_prot
成员指向getsockopt
的函数。它实现tcp_getsockopt
选项本身,对于其他选项,它从另一个名为net/ipv4/tcp.c
的ops结构调用SOL_TCP
方法。这让我们回到getsockopt
的位置,这里icsk_af_ops
指向net/ipv4/tcp_ipv4.c
。struct inet_connection_sock_af_ops ipv4_specific
位于getsockopt
中,它在同一文件中调用ip_getsockopt
,这是实际处理ip_getsockopt
选项的地方。