根据文档:
rpcbind[3] 实用程序将 RPC 服务映射到它们侦听的端口。 RPC 进程在启动时通知 rpcbind,注册它们正在侦听的端口以及它们期望服务的 RPC 程序号。然后,客户端系统使用特定的 RPC 程序编号联系服务器上的 rpcbind。 rpcbind 服务将客户端重定向到正确的端口号,以便它可以与请求的服务进行通信
为了测试这一点,我设置了 NFS 服务器和客户端并监控它们之间的流量。从我看到的情况来看,客户端已经知道服务器上的 NFS 服务正在侦听端口 2049。
那么rcpbind什么时候发挥作用呢?当我rpcinfo
在服务器上执行此操作时,我得到以下信息:
100003 2 udp 0.0.0.0.8.1 nfs superuser
100003 3 udp 0.0.0.0.8.1 nfs superuser
100003 2 udp6 ::.8.1 nfs superuser
100003 3 udp6 ::.8.1 nfs superuser
100003 2 tcp 0.0.0.0.8.1 nfs superuser
100003 3 tcp 0.0.0.0.8.1 nfs superuser
100003 2 tcp6 ::.8.1 nfs superuser
100003 3 tcp6 ::.8.1 nfs superuser
0.0.0.0.8.1
在这种情况下意味着什么?这如何转换为端口 2049?
答案1
rpcbind
是 BIND 的近似模拟,或者实际上是任何 DNS 服务器。如果我没记错的话,当您使用rpcgen
.
当客户端在特定主机上注册给定接口时(通常通过调用clnt_create()
),存根代码会rpcbind
在该主机上询问一个问题,例如“协议号 X 正在侦听哪个 UDP 或 TCP 端口?”rpcbind
与大多数其他 ONC 服务不同,它侦听 TCP 和 UDP 端口 111,因此给定主机名或 IP 地址,程序只需询问rpcbind
该主机或 IP 地址。rpcbind
如果服务器已在该主机上注册,则使用适当的端口号进行响应。该注册是由服务器进程在调用 时完成的svc_create()
。
在您的示例中,100003 是 NFS 的协议号。某些进程已向 注册rpcbind
,并给出其协议号 (100003) 以及它们已获取的任何 TCP 或 UDP 端口。正确rpcbind
地给出该端口号(在您的例子中为 2049),以供任何对它的调用“我应该为协议号 100003 使用哪个端口”。
现在我们进入了更奇怪的领域。 “0.0.0.0.8.1”位于输出的“地址”列中rpcinfo
。由于这是 NFS 服务器进程的“通用地址”,我敢打赌“0.0.0.0”前缀是服务器bind()
在获取端口号时在系统调用中使用的 IP 地址(在本例中为 INADDR_ANY)。我不确定“8.1”后缀是什么,但从rpcinfo
输出来看,它与 NFS 服务器(基本上是一个内核线程)有关。