Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UDP/ DTLS #14

Open
G0ne opened this issue Jul 16, 2021 · 7 comments
Open

UDP/ DTLS #14

G0ne opened this issue Jul 16, 2021 · 7 comments
Labels
enhancement New feature or request

Comments

@G0ne
Copy link

G0ne commented Jul 16, 2021

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(:

@SapphicCode SapphicCode added the enhancement New feature or request label Jul 19, 2021
@SapphicCode
Copy link
Owner

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.

@G0ne
Copy link
Author

G0ne commented Jul 19, 2021

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

@zekker6
Copy link

zekker6 commented Jul 28, 2021

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.

@G0ne
Copy link
Author

G0ne commented Jul 28, 2021

@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

@SapphicCode
Copy link
Owner

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.

@zekker6
Copy link

zekker6 commented Jul 29, 2021

@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

@G0ne
Copy link
Author

G0ne commented Jul 29, 2021

@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!(:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants