C++ Winsock API如何在接受连接之前获取连接客户端IP?

Posted

技术标签:

【中文标题】C++ Winsock API如何在接受连接之前获取连接客户端IP?【英文标题】:C++ Winsock API how to get connecting client IP before accepting the connection? 【发布时间】:2009-04-04 00:54:27 【问题描述】:

我正在使用 Winsock API(不是 CAsyncSocket)来创建一个侦听传入连接的套接字。

当有人尝试连接时,我如何才能在接受连接之前获取他们的 IP 地址?我试图让它只接受来自某些 IP 地址的连接。

谢谢

【问题讨论】:

【参考方案1】:

SO_CONDITIONAL_ACCEPT 套接字选项。 Here

另外,很确定它在 XP 和 Server 2003 中可用,而不仅仅是 Vista。

【讨论】:

是的,但是:[虽然它会隐藏一个监听套接字,]“启用 SO_CONDITIONAL_ACCEPT 的缺点通常超过了这个限制,”[因为应用程序,而不是 TCP/IP 堆栈,必须处理 DoS SYN 攻击本身。]【参考方案2】:

我不想接受连接以检查远程 IP 地址的两个原因:

1)。客户端会看到此端口上有一个侦听套接字。如果我决定拒绝客户端连接,我不希望他们知道这个端口上有一个套接字正在侦听。

2)。这种技术效率不高,需要更多的 CPU、RAM 和网络使用;所以在拒绝服务攻击的情况下是不好的。

【讨论】:

【参考方案3】:

使用 ATM 时,CONNECT ACK 数据包将来自最近的交换机,而不是最终客户端。因此,您必须在套接字上调用 accept(),然后查看地址(基于传递的 addr_family),然后关闭套接字。当它到达请求者时,它可能会失败。

我不确定您认为这会占用多少资源,但接受连接处于非常低的水平,并且不会成为真正的问题。删除它们很容易。

如果您受到 DoS 攻击,您的代码可以在预设的时间内退出侦听,因此如果您非常担心,攻击者只会失败。

客户端是否知道有一个套接字正在侦听真的很重要吗?尝试使用 telnet 连接到端口 137 上的本地主机,看看 Windows 中的文件共享断开连接的速度有多快......(如果你启用了它,并且我记得正确的端口号......呵呵......)

但是,在 SOCKET 级别,您将无法做您想做的事。您正在谈论深入到 TCP 级别,并查看传入的连接请求,并在那里处理它们。

这是可以做到的,但是您正在谈论一个内核驱动程序来做到这一点。我不确定您是否可以在用户模式下执行此操作。

如果您需要内核帮助,请告诉我。我也许可以给你一些例子或指导。

只有我自己的两分钱,而且恕我直言......

【讨论】:

【参考方案4】:

接受连接,查看IP,如果不允许,关闭连接

编辑

我假设您在谈论 TCP 连接。当您侦听端口并且连接来自客户端时,API 将执行 TCP 3 次握手,并且客户端将知道正在侦听此端口。

我不确定是否有办法阻止发送任何数据包(即接受连接),以便您可以先查看 IP 地址然后再决定。

我能想到的唯一方法是在网络层根据源IP进行包过滤(例如使用防火墙)。

【讨论】:

以上是关于C++ Winsock API如何在接受连接之前获取连接客户端IP?的主要内容,如果未能解决你的问题,请参考以下文章

Winsock - 为啥 ZNC(和 IRC 保镖)不接受我的 winsock 连接?

在接受连接 C++ 之前获取套接字的 IP 地址

Winsock - 停止接受新连接但与现有连接保持通信

C++ winsock服务器中非阻塞模式与异步套接字的区别

使用winsock设置主机名?

用WinSock API接收UDP消息时,可不可以设置接收Buffer?如何设置