# Funkensturm: a versatile DNS proxy


# What's a DNS proxy?
A proxy is something this sits between a client and a server and does something
with the data flowing through it. So a DNS proxy does this for DNS packets.

# How does Funkensturm work?
_Funkensturm_ consists out of 3 configuration parts:

1. A setup function for the initial setup.
2. Match/Modify function(s) &mdash; This function checks the packet for configured
properties. If there is match `true` is returned.
3. Action function(s) &mdash; Taking the truth value from 2. (and the packet) as input, it
does something with it. 

With this setup you can change incoming packets before they are send through to the
server. And you can change packet coming from the server that are send back to the 
client.

<img src="/images/2011/funkensturm2.png"/>

The image above shows the architecture and the stages of _Funkensturm_. The number shows 
the stage were you can influence the packet.

1. A packet comes in (`IN` gets set), you can modify it at your heart's content. In the
example `config_delay` the delaying happens here;
2. Action function is called, often it will forward the packet to a server. You can for instance
broadcast packets to multiple servers, that would typically happen here;
3. Reply packets; they go through the match/modify function again (`OUT` gets set). Only the
modification is important. On the fly signing happens here for instance. The example `config_sign` shows
how to do that;
4. The packet gets send back to the client. If any of the above
   functions returns a `nil` packet, nothing
is send back.

The match/modify functions are chained (ala Unix pipes), the input packet to the function[N+1] is
the output packet from function[N]. They are also chained in the logical sense of the word:

    outcome = true AND funcion[N] AND/OR function[N+1]

`outcome` is given to the action function(s), so they can decide what to do to packets
that match the criteria and those that don't.

The match/modify functions are re-used on the way back, so you have a last change to
change the packet before it is send to the client. If this stage is reached a packet
is *always* send back, unless it is `nil`.

# Configuring Funkensturm
I contemplated a "simple" configuration syntax, which would then be translated to
Go code. But making a flexible and simple syntax is hard and there will always
be stuff you can not express using this syntax. In the end this will lead to 
a complex language which still won't fulfill *all* your needs.

Therefor I opted
to configure _Funkensturm_ directly with Go. I.e. you have to recompile
_Funkensturm_ for new configuration to take effect. Luckily with Go this takes
about half a second. This has advantages (you don't need to learn a complex config language) and
disadvantages (you'll have to learn Go syntax (your life will never be
the same.)<sup>you're millage may vary.</sup>

I'm playing with the idea of interpreted Go code (`exp/eval` package) to make this
more dynamic, but this will *not* happen any time soon.

In upcoming posts I will detail some proxy configurations and show actual code.

# Current status
Code works, but needs to be cleaned up. I expect this too happen in the coming days or weeks - at the most.
The code is included as an example in the [Go DNS package](https://github.com/miekg/godns) and can be
compiled if you have the [Go language](http://www.golang.org) installed. See the directory `_example/funkensturm`
for the code and examples.

# The name
Why _Funkensturm_? I just wanted a cool sounding German name for this
project, like Stacheldraht, but different. Thanks to Twitter and
`@__sporkbomb` it became the name.

