在通过LD_PRELOAD插入JVM时关闭套接字

时间:2012-05-03 18:18:01

标签: c sockets

我通过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()上没有正确显示。奇怪!

1 个答案:

答案 0 :(得分:0)

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


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

如果您LD_PRELOAD的过程让孩子们离开,那么他们也会使用与父母一样的描述符,而他们的兄弟姐妹和孩子都会使用你的钩子。

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


dup2(int fdOld, int fdNew)在制作fdNew副本之前关闭fdOld。但你不能将调用挂钩close(),我想: - (。