0

我通过 LD_PRELOAD 变量插入 JVM。

基本上,我想建立一个虚拟路由表(VRT)。在调用 bind() 时,我将 IP 地址和端口参数修改为我的选择(我保存在 VRT 中)。此外,我将套接字描述符(bind() 的第一个参数)添加到链接列表中。(直到这个阶段,socket 的 sin_family 类型为 AF_INET6)。

现在当套接字关闭时(close()),我想删除虚拟路由表条目。因此,我检查我们试图关闭的套接字描述符是否存储在链接列表中。如果是,则说明它的记录存在于VRT中,所以我应该在关闭套接字之前删除VRT条目。我面临的问题是,在这个阶段,同一个套接字描述符的 sin_family 值为 1(我不知道它代表什么)而不是 10(AF_INET6,bind() 期间的值)。此外,我在这个阶段尝试打印套接字描述符的 IP 地址和端口,但它是垃圾。

我不知道我错过了什么。

更新:我的代码没有问题。由于 JVM 的以下行为(我通过 strace 跟踪)而出现异常

9722  socket(PF_INET6, SOCK_STREAM, IPPROTO_IP) = 12
...(receive messages)...
9722  dup2(11, 12)                      = 12 (?!?)
9722  close(12)                         = 0

JVM 在我们的套接字上复制了另一个文件描述符,因此它的 sin_family 在 close() 上没有正确显示。奇怪的!

4

1 回答 1

0

sin_family == 1AF_UNIX,即管道或域名套接字。


你确定它真的是“相同”的套接字描述符吗?你怎么识别它?它的整数值仅对进程是唯一的。

如果你的进程LD_PRELOAD派生出子进程,他们也将使用你的钩子,使用与父进程相同的描述符集,以及他们所有的兄弟姐妹和孩子都会这样做。

因此,要解决这种歧义getpid(),请在挂钩bind()代码中使用 PID,并将 PID 添加到您为此套接字存储的密钥中。


dup2(int fdOld, int fdNew)fdNew将其复制为fdOld. 但我想你不能把close()它挂起来,我想:-(。

于 2012-05-03T18:48:00.323 回答