【问题标题】:Stuck on closing socket while interposing JVM through LD_PRELOAD通过 LD_PRELOAD 插入 JVM 时卡在关闭套接字
【发布时间】:2012-05-03 18:18:01
【问题描述】:

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

【问题讨论】:

  • @AhmedJolani 冷静下来,伙计...,保持礼貌是个好主意,主要是这会有所帮助。
  • 只是出于好奇:是否也勾上了shutdown()
  • @alk 这个问题太模棱两可了。
  • 所以你还需要连接到dup*()
  • 跟踪说明文件描述符 11 的来源是什么?

标签: c sockets


【解决方案1】:

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


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

如果您是LD_PRELOADing 的进程分叉了子进程,他们也将使用您的钩子,使用与父进程相同的描述符集,以及他们所有的兄弟姐妹和孩子都会这样做。

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


dup2(int fdOld, int fdNew) 在复制 fdOld 之前关闭 fdNew。但是你不能把电话挂到close(),我想:-(。

【讨论】:

  • 目前我正在使用一个简单的 Java 程序,它不会分叉子代。
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 2012-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多