【问题标题】:Determining who opened a TCP session确定谁打开了 TCP 会话
【发布时间】:2014-01-24 02:48:27
【问题描述】:

给定一个已建立的 TCP 会话的本地 IP 和端口,我能否找出哪一方发送了初始 SYN?也就是说,这个连接是主动打开还是被动打开?我需要在 Linux 上的 C/C++ 中工作的东西。一个 hacky 方法可能是 socket()/listen() 并抓住 EADDRINUSE 但我希望有更清洁的东西。一旦会话建立,我什至不确定内核是否会跟踪它。

编辑:我也不想调用 netstat(甚至 ss),因为打开了许多套接字,两者都太慢了。这段代码会经常被调用。

【问题讨论】:

  • 有趣的问题(+1)
  • 这里的目的是什么?
  • @EJP: 识别给定流是来自这台机器还是来自远程机器。
  • (tomshardware.com/forum/… 上的类似讨论 - 在建立连接期间没有嗅探/记录就没有解决方案)

标签: c++ c linux sockets network-programming


【解决方案1】:

客户端总是通过发送SYN(到服务器)来建立活动连接。因此,给定一个本地 IP 和端口号,使用以下命令检查它是否是侦听套接字:

netstat --listening | grep given_ip:given_port

如果这里没有列出,那么它是一个客户端套接字,因此启动一个SYN。如果它在那里,那么它就是一个监听套接字,因此它收到了一个SYN。

对应的代码如下:

system("netstat --listening | grep given_ip:given_port > tmp.txt");
int fd = open("tmp.txt", O_RDONLY);
char buf[100] ;
if(read(fd,buf,100)>0)
    printf("The socket has received a SYN!");
else
    printf("The socket has sent a SYN!");

编辑:

如果你觉得netstat扫描整个端口的速度很差,那么要达到快速的唯一方法就是打开一个raw socket并设置它接收所有TCP数据包。

只处理那些包含SYN 的数据包。现在,将source address:port 和destination address:port 存储到两个表中。一个是SYN 的发送者,一个是接收者。

现在,当您获得端口和 IP 地址后,在目前存储的数据上创建一个scan。您也可以使用C++ 中的STL map 来获得更快的结果。

由于可能有很多请求,map 可能会很快被填满,从而导致查找速度变慢。我建议您也处理FIN 数据包,并在此基础上从表中删除相应的条目。

【讨论】:

  • 谢谢。我希望除了 netstat 之外的其他东西,因为当您打开数千个套接字时它会很慢。我会用这个更新问题。
  • 当侦听套接字的 TCP 服务器接受客户端连接时,accept 调用返回一个单独的套接字/端口,该套接字/端口本身并不处于侦听状态 - 这是一个点对点连接:不是关于找出该状态下的套接字是由服务器接受还是传出客户端连接创建的问题? netstat --listening 对此无济于事。
  • @TonyD accept() 确实返回了一个新的套接字,但没有返回一个新的port。见this
  • Tony:是的,问题是关于已建立的连接,因此寻找监听套接字并不完全正确。不过,我不需要一个确切的答案——如果一个套接字正在侦听我正在查看的端口,那么它大部分时间都足够接近。羞耻找到一个监听套接字是如此昂贵:(
  • @nitish712:不幸的是,以这种方式跟踪的流量太多。我正在寻找一个非常便宜的解决方案。
猜你喜欢
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
相关资源
最近更新 更多