I am trying to build a simple TCP and UDP proxies. No problem with the TCP proxy, however the UDP is a little more complex to handle. The classic proxy scenario would be like this.
- Listen for incoming packets from clients
- When packet is received send it to destination (server)
- Listen for possible response packets from server
- Send response packets back to the clients
Ok this should be simple. But when trying to implement this using Synapse or Indy I have a problem. when I receive a packet from a client, I make an internal UDP client, to forward the packet to the destination. Then I have to listen to the possible responses from the destination. Now the question is what is the best implementation for this? There is no single request / response like in TCP. Destination can response with multiple answers over time, or does not respond at all. If I continue to listen for response over one client packet, then I will miss other future packets from this or other clients.
I am looking for a good design to this problem. Here is a sample communication for the reference. Note the multiple responses from the destination at one point
- 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 开发者_StackOverflow中文版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
EDIT:
For the record. Maybe the UDP proxy is just to messy to implement, for it to be usable. This is a strong probability, while theoretically it is certainly doable. But I will try just for the fun of it. If I get a stable working solution, then even better. Otherwise I will learn something new and admit defeat.
In no way I am trying to be stubborn and going with my head through the wall. I am still hoping somebody has a good idea :)
It's not just proxies that have this problem with UDP - network devices such as stateful firewalls and NAT devices run into it too.
The typical way that it's dealt with is to have a timeout. Once no UDP traffic between the proxied client and server has been observed for the length of the timeout, the "connection" is torn down. When traffic is seen, the timeout is reset.
Also, having one current proxied connection shouldn't prevent another one from being opened simultaneously - your proxy should be able to handle that.
A typical UDP client-server communication might look like this:
- Client sends UDP packet to port 1000
- Server receives packet and sends back response to port 1001 (or port 1000!)
Your proxy should simply listen to packets on both port 1000 and 1001. When a packet gets in on port 1000, send it to port 1000 on the server. When a packet arrives on port 1001, it's from the server and needs to be sent on port 1001 to the appropriate client. This is pretty much where the fun ends. UDP offers nothing in terms of session or connection management: It all depends on the specific UDP protocol you're trying to proxy. If you received UDP packets from 2 different clients, and you receive a "response" packet from the server, there's nothing in UDP itself to tell you where to forward that packet. Protocols built on top of UDP might or might not have some way of maintaining state.
A generic solution is not possible, you get to read the RFCs, and you get to implement specific helpers for each and every UDP protocol you want to support.
精彩评论