This is my first post here in quite a while!
Some background...
Over Christmas break I've devised a more generalized design for tunsl. It is based on BSD's netgraph.
tunsl has been re-interpreted as a series of "filters", each with very simple tasks. A filter is an interface that has: send, attach, detach, control, and shutdown functions. These functions are hung in a struct. filter also has linked lists for input and output consumers. Additionally a filter is one way. Filters can only send to locally attached filters either by broadcasting or by traversing the output consumer linked list and invoking selected filter send functions (one can send to input consumers...but that disrupts the conceptual "flow" of data).
To alleviate confusion:
An input consumer is a filter that accepts input
An output consumer is a filter that generates output
The advantages of this construct are:
1) tunsl's operations are reduced into simple tasks
2) tunsl is incredibly extensible...filters can be attached anywhere in the filter network...they are like legos
tunsl itself, is a set of 4 filters, composed of logic and cryptographic pairs of input/output filters (remember, they are 1 way). The logic and crypto pairs are attached to each other.
A network filter is attached to the logic pair. The interface filter is attached to the crypto pair.
A network filter is a filter that inputs/outputs to the peer-to-peer network over any supported medium (e.g. tcp, udp, bluetooth, etc...)
An interface filter is a filter that inputs/outputs to programs (e.g. tun, SOCKS5, etc...). This allows programs to transparently access the peer-to-peer network over a variety of different mediums, protocols, and so forth.
So my question...
I want to separate network and interface filters from tunsl's core. There are variety of ways this can be achieved. Here are a few ways this could be achieved...but whats the best way or whats better?
Think of each filter/subsystem as a shared object (or DLL). Load these at runtime determined by command line flags or config file. Now we need to provide subsystem/filter specific information by either
1) Create one tunsl config file with nests for logical separation...pass the configuration parser context to each loaded module so that it can get its configurations.
2) Hardwire a configuration file path for each module and allow them to aquire their own configurations upon load
3) Create a tunslcfg utility, synonymous to ifconfig and use a script to load settings through tunslcfg.
I like 1 or 3 personally...but whats the best way? I like 1 because it allows one to consolidate all settings to one file and if someone wanted to use an alternative configuration file, they could do so by having tunsl open an alternative file (e.g. like a -c flag). I like 3 because UNIX configures network interfaces in this manner...but it would require a lot more work.