【问题标题】:See socket options on existing sockets created by other apps?查看其他应用程序创建的现有套接字上的套接字选项?
【发布时间】:2009-10-24 13:46:18
【问题描述】:

我想测试是否已在现有套接字上设置了特定的套接字选项。即,您可以在其中看到的几乎所有内容:

#!/usr/bin/env python
'''See possible TCP socket options'''

import socket

sockettypelist = [x for x in dir(socket) if x.startswith('SO_')]
sockettypelist.sort()
for sockettype in sockettypelist:
    print sockettype

任何人都知道我如何查看现有 套接字上的选项,即由其他进程创建的那些?唉,我读过的关于 Python 套接字编程的几乎所有文档都是关于制作新套接字的。

【问题讨论】:

  • 您能否更准确地了解您想要实现的确切(即什么应用程序,以及您为什么想了解套接字选项)?如前所述,我不认为你想要什么是可能的 - 在 python 或其他方式中。
  • 当然。我希望能够测试第三方应用程序是否正确设置,例如,keepalive,以避免在未设置时在我的环境中出现已知问题。我没有访问第三方应用程序的源代码。
  • 开始回答我自己的问题:一些研究表明 Linux netstat 中的 '-o' 'timers' 选项还显示了进程上的套接字选项。跟踪这表明有关套接字选项的信息保存在 Linux 上 /proc/net/tcp 的最后一个字段中。我正在调查 Python procfs 模块是否可以处理这个问题,或者我需要创建自己的模块...
  • Hrm 似乎 /proc/net/tcp 不包含所有套接字选项(至少不是我感兴趣的 NODELAY) - 请参阅 lkml.indiana.edu/hypermail/linux/kernel/0409.1/2166.html 。是时候在别处继续搜索了……
  • 相关:stackoverflow.com/questions/8014151/… - 有办法做到这一点(但不是在 Python 中)。

标签: linux sockets setsockopt systemtap


【解决方案1】:

不幸的是,nailer 的答案仅捕获 SOL_TCP 级别的套接字选项,而没有捕获 SOL_SOCKET 级别的选项(如 SO_KEEPALIVE)。

一些发行版附带一些示例以及 systemtap。其中之一是 pfiles.stp,您可以使用它从正在运行的进程的套接字中获取套接字选项。文件中的示例:

$ ./pfiles.stp `pgrep udevd`
   787: udevd
  Current rlimit: 32 file descriptors
   0: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   1: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   2: S_IFCHR mode:0666 dev:0,15 ino:396 uid:0 gid:0 rdev:1,3
      O_RDWR|O_LARGEFILE 
      /dev/null
   3: S_IFDIR mode:0600 dev:0,9 ino:1 uid:0 gid:0 rdev:0,0
      O_RDONLY 
      inotify
   4: S_IFSOCK mode:0777 dev:0,4 ino:2353 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2353]
      SO_PASSCRED,SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(111616)
        sockname: AF_UNIX
   5: S_IFSOCK mode:0777 dev:0,4 ino:2354 uid:0 gid:0 rdev:0,0
      O_RDWR 
      socket:[2354]
      SO_TYPE(2),SO_SNDBUF(111616),SO_RCVBUF(33554432)
        ulocks: rcv
   6: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_RDONLY|O_NONBLOCK 
      pipe:[2355]
   7: S_IFIFO mode:0600 dev:0,6 ino:2355 uid:0 gid:0 rdev:0,0
      O_WRONLY|O_NONBLOCK 
      pipe:[2355]

【讨论】:

    【解决方案2】:

    这在 Python 中是不可能的。

    Linux 内核在 /procfs 中没有提供报告 TCP 套接字状态的机制(与 BSD 和其他类 Unix 操作系统不同)。由于内核不公开这些信息,我们无法通过 python-linux-procfs 模块或类似模块看到它。

    lsof FAQ item 3.14.1:

    问。 “为什么 lsof 不报告我的方言的套接字选项、套接字状态以及 TCP 标志和值?”。

    A. '套接字选项、套接字状态和 TCP 标志和值不能通过 /proc 文件系统获得。'

    不过 SystemTap 的 Network tapset 提供了一个 tcp.setsockopt 断点,可以用来拦截进程设置的套接字选项,但是这将在 stap 而不是 python 中处理。

    我创建了所需的 Tapset 如下:

    # Show sockets setting options
    
    # Return enabled or disabled based on value of optval
    function getstatus(optlen)
    {
        if ( optlen == 1 )
            return "enabling"
        else
            return "disabling"
    }
    
    probe begin
    {
        print ("\nChecking for apps making socket calls\n")
    }
    
    # See apps setting a socket option 
    probe tcp.setsockopt
    {
        status = getstatus(user_int($optval))
        printf ("  App '%s' (PID %d) is %s socket option %s... ", execname(), pid(), status, optstr)
    }
    
    # Check setting the socket option worked
    probe tcp.setsockopt.return
    {
        if ( ret == 0 )
            printf ("success")
        else
            printf ("failed")
        printf ("\n")    
    }
    
    
    probe end
    {
        print ("\nClosing down\n")
    }
    

    【讨论】:

      【解决方案3】:

      socket 库确实是用来创建新的socket 并对其进行操作的。出于明显的安全原因,在其他进程中创建的套接字不可见:您不希望任何随机应用程序改变您管理自己的套接字的方式,或者更糟糕的是从您的套接字读取数据。所以套接字是系统对象,由句柄引用,具有(在体面的操作系统上)适用于它们的访问权限。这就是为什么您不能列出由其他进程创建的现有套接字的原因。

      最终,您可能会找到一种方法来检索套接字句柄(应该有一种方法,我记得在 Windows 上看到过一种列出系统句柄的方法),但这仍然非常特定于您的操作系统,因此可能不可用在 python 中,您可能仍然无权在这些套接字上执行任何操作。

      现在,如果您只是想知道特定应用程序如何实现特定功能,还有其他方法:最明显的是安装代理或防火墙(我记得我的 Kerio WinRoute 防火墙列出了套接字选项),或者只是向 stackoverflow 询问如何实现这一壮举。

      【讨论】:

      • 了解 re: 安全性,但希望 root/SYSTEM 用户能够看到所有进程上设置的选项。我的目的是诊断其他应用程序。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-22
      • 1970-01-01
      • 1970-01-01
      • 2014-10-28
      相关资源
      最近更新 更多