protoplex icon indicating copy to clipboard operation
protoplex copied to clipboard

UDP/ DTLS

Open G0ne opened this issue 4 years ago • 7 comments

This is the best and simple application protocol multiplexer on internet. The only thing is missing in my opinion is a udp/ dtls support. This implementation would make this tool even more perfect than its actual state! If you want to add this, since the tool will be then capable of handle tcp and udp/ dtls connections, the ability to bind the server on multiple ports simultaneously ( for example --tcpbind x.x.x.x:yyyy --udpbind x.x.x.x:yyyy ) would be the icing on the cake(:

G0ne avatar Jul 16 '21 09:07 G0ne

It'd be a nice idea for the roadmap, but TCP is what lets us keep track of proxied connections. We'd effectively have to build a UDP state machine.

I'll definitely keep it in mind when I get around to it.

SapphicCode avatar Jul 19 '21 13:07 SapphicCode

Awesome! I'm glad you liked the idea!(: I will wait for it like someone that waits for the last episode of his favorite tv show ahah

G0ne avatar Jul 19 '21 15:07 G0ne

Hello Guys I've implemented UDP proxying for my own purposes(Wireguard connection for now), @SapphicCode if you are interested in merging it please let me know and I'll create a PR. You can have a look at my implementation here - https://github.com/zekker6/protoplex . Feedback is much appreciated.

Binding different addresses for TCP and UDP is not implemented yet but that will be easy to add.

zekker6 avatar Jul 28 '21 09:07 zekker6

@zekker6 amazing!(: The only issue is that the UDP server sends the data to all the clients connected. See the following example with the string "bbbbbbbbb"

image

2 ncat udp clients -> protoplex UDP server -> socat UDP to TCP -> ncat TCP server The string "SEZI3t097GZSHEOI" was used for protoplex to handle this test

G0ne avatar Jul 28 '21 17:07 G0ne

Yeah, that's... a bit of a problem, hence why I mentioned state tracking. You need to keep track of your clients individually otherwise this happens.

For now I'd suggest just iptables / any other app on the UDP port (TCP and UDP can occupy the same port on different sockets), that way you don't interfere with multiple clients and you get statekeeping by the respective application.

SapphicCode avatar Jul 28 '21 19:07 SapphicCode

@G0ne I'm afraid there is an issue you've found is caused by test scenario(probably socat UDP to TCP part). There is state tracking implemented based on saving client address(IP + port) as key.

I've tried to reproduce this by using following configuration: client1 -> protoplex -> server and client2 -> protoplex -> server. Client source:

package main
 
import (
    "log"
    "net"
)
 
func main() {
    addr, _ := net.ResolveUDPAddr("udp", "localhost:8443")
 
    con, _ := net.DialUDP("udp", nil, addr)
 
    log.Println(con)
 
    _, e := con.Write([]byte{0x01, 0x00, 0x00, 0x00})
    log.Println(e)
 
    buf := make([]byte, 1000)
    for {
        con.ReadFromUDP(buf)
        log.Println(string(buf))
    }
}

Server source:



package main
 
import (
	"log"
	"net"
	"time"
)
 
func main() {
	addr, _ := net.ResolveUDPAddr("udp", "localhost:8444")
 
	con, _ := net.ListenUDP("udp", addr)
 
	log.Println(con)
 
	buf := make([]byte, 1000)
	for {
		_, client, err := con.ReadFromUDP(buf)
		log.Println(client.String(), err)
 
		go func(client *net.UDPAddr) {
			for {
				_, e := con.WriteToUDP([]byte(client.String()), client)
				log.Println(e)
				time.Sleep(1 * time.Second)
			}
 
		}(client)
	}
}

Server only accepts connection and sends client ip back every second.

Test result showed the following:

# client1
2021/07/29 09:05:17 127.0.0.1:41693
2021/07/29 09:05:18 127.0.0.1:41693
2021/07/29 09:05:19 127.0.0.1:41693
2021/07/29 09:05:20 127.0.0.1:41693
2021/07/29 09:05:21 127.0.0.1:41693
2021/07/29 09:05:22 127.0.0.1:41693
2021/07/29 09:05:23 127.0.0.1:41693
2021/07/29 09:05:24 127.0.0.1:41693
 
#client2
2021/07/29 09:05:15 127.0.0.1:35598
2021/07/29 09:05:16 127.0.0.1:35598
2021/07/29 09:05:17 127.0.0.1:35598
2021/07/29 09:05:18 127.0.0.1:35598
2021/07/29 09:05:19 127.0.0.1:35598
2021/07/29 09:05:20 127.0.0.1:35598
2021/07/29 09:05:21 127.0.0.1:35598
2021/07/29 09:05:22 127.0.0.1:35598
2021/07/29 09:05:23 127.0.0.1:35598
2021/07/29 09:05:24 127.0.0.1:35598

zekker6 avatar Jul 29 '21 06:07 zekker6

@zekker6 you are right, it works! After some investigations the problem was not socat, but ncat server. I had to forward the incoming traffic to different ports ( rather than just listen ) to make it work

Your implementation works like a charm with this my last test!(:

G0ne avatar Jul 29 '21 08:07 G0ne