【问题标题】:UDP and port randomisationUDP 和端口随机化
【发布时间】:2012-03-02 13:17:43
【问题描述】:

我目前正在编写一个允许客户端登录的 UDP 应用程序。之后,他们的端点被存储在一个列表中。

private void socket_Callback(IAsyncResult result_)
{
    EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
    socket.EndReceiveFrom(result_, ref remote);

    if (!listOfEndPoints.Contains(remote))
    {
        // registration process

        // add it to list
        listOfEndPoints.Add(remote)
    }
    else
    {
        // process packet
    }
}

但是,有时客户端的 NAT 会为每个数据包分配不同的外部端点。如果注册数据包的源端点是 12.34.56.78:1000,则该端点被添加到列表中。然而,如果同一个客户端发送另一个数据包,NAT 将为其分配一个不同的端口,因此其源端点将是 12.34.56.78:1001。 这导致服务器假设客户端未注册并尝试将数据包作为注册处理。不用说这行不通。

解决此问题的一种方法是向客户端发送一个 ID(不过,如果它不是超级神秘的话,它很容易被伪造)。但是,客户端必须将它添加到它发送到服务器的每个数据包中。 所以那样做不会很有效。

还有其他方法可以判断数据包与注册数据包来自同一个客户端吗?

【问题讨论】:

    标签: c# sockets udp nat


    【解决方案1】:

    您绝对应该使用 UDP 数据包的源 IP 地址和端口将其与逻辑连接相关联。您应该在每个数据包中包含连接的 ID,如果您收到相同逻辑连接的新 IP 和端口,则更新您响应的 IP 和端口。如果连接劫持是一个问题,您可能需要实现某种形式的安全性,例如数据报中的安全校验和。

    TCP 为您处理将数据包与连接相关联。使用 UDP,您必须自己将数据报与逻辑会话相关联。我不知道你为什么认为“那样做不会很有效”。

    UDP 的一个折衷方案是,如果您需要 TCP 提供的任何东西,您必须自己编写代码。

    顺便说一句,我从未见过端口以这种方式转移。您确定客户端代码没有损坏,可能为它发送的每个数据报打开一个新套接字。

    【讨论】:

    • 谢谢!如果这是我的代码中的错误,为什么我不应该使用数据包的端点?那么这对每个客户来说不是独一无二的吗?安全校验和是什么样的?我正在考虑在注册时向客户发送一个随机数。然后客户端会将 md5(packetdata XOR checksum) 添加到数据包中。然后服务器将检查校验和的正确性。这就是你的意思吗?
    • @haiyyu:不使用端点数据的原因是因为对方的IP地址可能会改变。使用 TCP,可以理解网络需要将数据包与会话相关联,并且 NAT 设备知道要保留 IP。使用 UDP,他们不会。是的,这就是我的意思。当然,最佳解决方案取决于您的要求。
    猜你喜欢
    • 2012-02-09
    • 1970-01-01
    • 2012-08-04
    • 2010-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多