For my next masochistic spare time project, I'm trying to implement a basic anonymity protocol using UDP tunnels over which other traffic can flow. I want to use UDP because it gives high throughput and prevents timeout meltdowns that are possible with TCP over TCP.
Each user in the anonymous network becomes a node and becomes part of other user's tunnels. Each node has to be able to handle multiple tunnels, and thus identify incoming and outgoing packets as belonging to a specific tunnel.
What is the best way to determine which tunnel a packet belongs without needing to look at the actual packet data (so just the header, or connection, if possible)? Is there a connection-oriented version of UDP?
My understanding of UDP is this- it is connectionless, and the packet header just says what the source/destination address and sources are.
I can think of several ways to take advantage of this info:
- Spoof the packet's source port to hold a 16-bit connection ID associated with an IP address (so on each machine, the connection table is the concatenation of source or target IP + connection ID. This requires fooling around with raw sockets and may be less portable between systems. I don't know what the overhead of constructing UDP packets and examining them on the other side is.
- Use the source port on the UDP packet for a unique connection ID, but the port field is 16-bit, so that's not really practical for a global ID. I'd prefer to be able to have the application be able to use arbitrary ports, and only need a single port.
- Use a protocol like UDT built on top of UDP- it's still fast (1/4-1/3 of the speed of UDP supposedly), checks reliability, has congestion control, and has connections. Seems complicated though, and I'd prefer not to have to rely on a proprietary (if open source) library. Ultimately I need to do stream encryption on top of this, so that'll be yet more slowdown.
(1) seems preferable if it adds minimal overhead. I'd really prefer to use only a single, arbitrary port and not have any extra stuff on top of UDP besides a way to identify a packet as being part of a given tunnel.
EDIT: One possibility to reduce overhead would be listening on a UDP socket and sending via raw socket, but that doesn't address the main problem.
EDIT2: How does Skype or another streaming service that is centrally routed work? Do they use their own protocol?
EDIT3: Re Xaxxon's answer, I plan on exposing the anonymous network to userspace programs with a tun interface. This will allow me to run any traffic I want over the system- ssh, ftp, etc. I'd prefer not to mess with packet headers corresponding to these higher layer protocols.
Each user in the anonymous network becomes a node and becomes part of other user's tunnels
-- this means the network is not anonymous, only the traffic communication is anonymous. (That is, it'll be pretty easy to tell when someone is on the network, although you won't know what they are saying) – cegfault