To be consistent with my other postings, I've decided to dedicate a topic of its own to the actual p2p tunneler instead of appending it the
P2P VLAN post. This (tunsl) is a working prototype of a p2p tunneler.
tunsl is composed of 9 inter working components:
fdman - The file descriptor manager
timer - The timer manager, it cooperates with fdman ... fdman varies its timeout value to select() with information from timer.
tunman - The tunnel manager, it gives the application a high level interface to doing simple operations like setting the tunnel's IP address, reading from tunnel, and etc.
sudp - This does secure UDP communications over DSS/DH with Blowfish
conf - This is the configurations parser
It uses these data structures:
hash - A generalized hash table (heavily used)
stack - A generalized stack (used with conf)
list - A generlized linked list (used with timer)
And finally, the main component, the meat and the guts
tunsl - This is the route manager ... it does everything from seek out routes to DSS/DH with Blowfish over routes.
The real thing would have more components to manage the protocol and communications with the daemon.
The purpose of this prototype is to get a feel for how to write this odd program ... its not everyday you're walking down the street and instantly want to write a p2p tunneler. It's also meant to be used for testing purposes both stability and security-wise. I think it could be useful to have a decentralized virtualized LAN, as long as one peer exists, the network exists. No matter which peer you connect to, you are part of the same logical network as they are.
So, just to give you a general idea of how this works. The tunsl component is the focal point of this program, it is the literally the engine. It makes use of both sudp and tunman for communications. tunsl listens on sudp for various events, but in the prototype all that is emphasized is connect/disconnect and read events. On connect and disconnect, tunsl creates and destroys peer structures that are hung in sudpcon.arg for later use. On read, tunsl hands the data over to a protocol handler. The protocol handler does any forwarding necessary and also handles data addressed to us. tunsl additionally listens on tunman for packets read from the tunnel and each packet read, it calls a function that tries to send the packet ... that is, it looks for a route if none exist, or it uses a random existing route.
So, I did some testing last night between 4 machines: LIGHTBULB, BLENDER, BOTTLE and DOORKNOB.
LIGHTBULB connected to BLENDER
BOTTLE connected to BLENDER
DOORKNOB connected to BLENDER and BOTTLE
I pinged each of these machines by their virtual IP from every other machine (and in some cases, all at the same time). I had even ssh'd from LIGHTBULB to BOTTLE. The routing scheme works quite well surprisingly (see Protocol Description post in P2P VLAN).
Here is a screenshot of transactions:
So, some problems I discovered:
a) This network, although it
emulates an IP LAN,
cannot be bridged or NAT'd to a real IP network. The reason is, each route must be encrypted ... nodes communicating from outside of the network simply cannot do this.
b) The Blowfish cipher has a chaining effect on the data ... the original intent was to allow the OS to handle lossage, but I have to deal with this too. Encrypted data
cannot go missing and
cannot arrive out of order ... but that doesn't mean tunsl isn't ill equipped to handle this scenario, like the sudp library, it will reset the cryptographic parameters to their initial state.
c) There is no checking on the packet level ... you can have a packet of random garbage addressed to a destination on P2P level (this can be fixed)
Any comments on solutions to the above are welcome
So here is the source, it is designed for FreeBSD 6.x branch of OS but it
might work on 5.x. Additionally, you will need OpenSSL 0.9.7 or above to use it.
http://nslay.36bit.com/tunsl.tar.gz