Delphi UDP代理实现

Delphi UDP代理实现,delphi,proxy,udp,pascal,synapse,Delphi,Proxy,Udp,Pascal,Synapse,我正在尝试构建一个简单的TCP和UDP代理。TCP代理没有问题,但是UDP处理起来有点复杂。经典的代理场景是这样的 侦听来自客户端的传入数据包 收到数据包后,将其发送到目的地(服务器) 侦听来自服务器的可能响应数据包 将响应数据包发送回客户端 好的,这应该很简单。但当我试图用Synapse或Indy来实现这一点时,我遇到了一个问题。当我从客户机接收到数据包时,我创建一个内部UDP客户机,将数据包转发到目的地。然后我必须倾听目的地可能的反应。现在的问题是,这方面的最佳实现是什么?没有像TCP中那样

我正在尝试构建一个简单的TCP和UDP代理。TCP代理没有问题,但是UDP处理起来有点复杂。经典的代理场景是这样的

  • 侦听来自客户端的传入数据包
  • 收到数据包后,将其发送到目的地(服务器)
  • 侦听来自服务器的可能响应数据包
  • 将响应数据包发送回客户端
  • 好的,这应该很简单。但当我试图用Synapse或Indy来实现这一点时,我遇到了一个问题。当我从客户机接收到数据包时,我创建一个内部UDP客户机,将数据包转发到目的地。然后我必须倾听目的地可能的反应。现在的问题是,这方面的最佳实现是什么?没有像TCP中那样的单一请求/响应。目的地可以随时间以多个答案响应,或者根本不响应。如果我继续在一个客户端数据包上侦听响应,那么我将错过来自该客户端或其他客户端的其他未来数据包

    我正在寻找一个好的设计来解决这个问题。下面是一个通信示例,供参考。注意在一个点上来自目的地的多个响应

    - bind UDP port 40222 on interface 0.0.0.0
    - ready
    - add 127.0.0.1:4569
    
    127.0.0.1:4569 -> 192.168.90.10:4569
    c3 ef 00 00 00 00 00 03 00 00 06 01 0b 02 00 02   ................
    02 0a 37 30 30 35 35 35 31 32 31 32 04 0d 4e 6f   ..7005551212..No
    74 20 41 76 61 69 6c 61 62 6c 65 09 04 00 00 00   t Available.....
    08 08 04 00 00 00 08 06 06 31 36 31 34 30 31 01   .........161401.
    08 34 31 33 31 33 39 34 37 0d 08 34 31 33 31 33   .41313947..41313
    39 34 37                                          947
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    a9 e7 43 ef 00 00 00 09 00 01 06 08 0e 02 00 03   ..C.............
    0f 09 34 31 38 32 32 31 37 38 33 06 06 31 36 31   ..418221783..161
    34 30 31                                          401
    
    127.0.0.1:4569 -> 192.168.90.10:4569
    c3 ef 29 e7 00 00 00 4f 01 01 06 09 10 20 39 36   ..)....O..... 96
    64 66 37 31 32 38 61 62 35 39 39 37 65 36 37 36   df7128ab5997e676
    65 62 38 63 61 30 33 39 38 66 33 34 30 65         eb8ca0398f340e
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    a9 e7 43 ef 00 00 00 56 01 02 06 07 09 04 00 00   ..C....V........
    00 08                                             ..
    
    127.0.0.1:4569 -> 192.168.90.10:4569
    c3 ef 29 e7 00 00 00 56 02 02 06 04               ..)....V....
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    a9 e7 43 ef 00 00 02 85 02 02 04 0e               ..C.........
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    a9 e7 43 ef 00 00 02 96 03 02 02 08 54 54 54 54   ..C.........TTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54               TTTTTTTTTTTT
    
    127.0.0.1:4569 -> 192.168.90.10:4569
    c3 ef 29 e7 00 00 02 96 02 04 06 04               ..).........
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    29 e7 02 aa 54 54 54 54 54 54 54 54 54 54 54 54   )...TTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54                                       TTTT
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    29 e7 02 be 54 54 54 54 54 54 54 54 54 54 54 54   )...TTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54                                       TTTT
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    29 e7 02 d2 54 54 54 54 54 54 54 54 54 54 54 54   )...TTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54                                       TTTT
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    29 e7 02 e6 54 54 54 54 54 54 54 54 54 54 54 54   )...TTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54                                       TTTT
    
    192.168.90.10:4569 -> 127.0.0.1:4569
    29 e7 02 fa 54 54 54 54 54 54 54 54 54 54 54 54   )...TTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54 54 54 54 54 54 54 54 54 54 54 54 54   TTTTTTTTTTTTTTTT
    54 54 54 54                                       TTTT
    
    编辑:

    记录在案。也许UDP代理实现起来太麻烦了,因为它是可用的。这是一个很强的可能性,而理论上它肯定是可行的。但我会尝试只是为了好玩。如果我得到一个稳定的工作解决方案,那就更好了。否则我会学到新东西,承认失败


    我决不是在试图变得固执,让我的头撞到墙上去。我仍然希望有人有一个好主意:)

    典型的UDP客户机-服务器通信可能如下所示:

    • 客户端将UDP数据包发送到端口1000
    • 服务器接收数据包并将响应发送回端口1001(或端口1000!)
    您的代理应该只监听端口1000和1001上的数据包。当数据包从端口1000进入时,将其发送到服务器上的端口1000。当数据包到达端口1001时,它来自服务器,需要在端口1001上发送到相应的客户端。这几乎就是乐趣的终点。UDP在会话或连接管理方面不提供任何功能:它完全取决于您尝试代理的特定UDP协议。如果您从两个不同的客户端接收到UDP数据包,并且从服务器接收到一个“响应”数据包,那么UDP本身并没有告诉您将该数据包转发到哪里。建立在UDP之上的协议可能有也可能没有某种方式来维护状态


    通用解决方案是不可能的,您需要阅读RFC,并且需要为您想要支持的每个UDP协议实现特定的帮助程序。

    UDP存在此问题的不仅仅是代理,还有网络设备,例如有状态防火墙和NAT设备

    处理它的典型方式是超时。一旦在超时期间未观察到代理客户端和服务器之间的UDP通信,则“连接”将被中断。当看到流量时,将重置超时


    此外,拥有一个当前代理连接不应阻止同时打开另一个代理连接-您的代理应该能够处理该问题。

    它认为通用解决方案是可能的。我可以有一个客户端池,每个客户端将绑定到不同的内部端口。但问题是我可能会耗尽端口或绑定到已连接的端口。是的,UDP应该很简单,但它使代理实现成为地狱。现在我知道了为什么SSH隧道只支持TCP.:)我希望有人有一个聪明而简单的解决方案:)假设您决定绑定到端口6000-6099以处理100个不同的客户端。当两个客户端都更喜欢发送到端口1000时,您如何说服客户端1发送到6000,客户端2发送到6001,因为这是通过UDP实现的协议的RFC中的一个?如果您有一个应用程序要代理,您可以启动代理并监听端口6000。应用程序连接到端口6000上的本地主机。对于代理接收到的每个数据包,它会在新端口上创建一个UDP客户端,并将数据发送到Destination。然后它会在一段时间内监听响应。您始终有一个用于侦听的本地端口和一个IP/端口目标。如果您需要更多,可以在不同的端口上启动更多代理。我已经测试过这样的解决方案,所以我知道这是可能的。不,我不能使用这个,因为我想在两个这样的代理之间进行加密:)是的,我得出了完全相同的结论:)每个新数据包都有一个新的内部客户端。然后在一定时间内监听响应,然后释放客户端。但自由端口的数量可能会有问题。这正是我说通用解决方案不可能的原因。我很幸运/不幸地处理了大量的SIP通信,这就是UDP,Linux iptables for NAT:iptables可以处理它,但是它有一个针对SIP协议的特定conntrack模块!我并不是说如果iptables的人不这么做,这是不可能的,但这是一个好迹象,这将是困难的。@Cosmin Prund,是的,我确信这是困难的。但这让我更感兴趣:)我问题中显示的数据包属于IAX协议。这是Asterisk VOIP支持的除SIP之外的另一个协议。这就是为什么我想试着去做。如果我失败了,就不会有任何伤害。@Runner,不管怎样,IAX更容易NAT而不是SIP,可能更容易代理。玩得高兴请注意,TCP也不是请求/响应协议。你可以发送一些东西,但也得不到任何回应。这可能是您调试代理时使用的应用程序级协议,即请求/响应协议。是的,我同意,但如果您没有得到任何反馈,那么您就知道没有响应。与UDP不同的是,在UDP中,您可以获得向后的“响应”