sargon / ddhcpd

A distributed DHCP Daemon
GNU General Public License v3.0
31 stars 12 forks source link

A Distributed DHCP Daemon

In self managed networks with decentralized client realms a central DHCP server is not available. DDHCPD allows every realm to have its own server; preserving roaming features for the client, by maintaining a common consens on DHCP leases.

The implementation is flexible, meaning we do not prevent you from doing stupid stuff, but also allow you maximal adaption.

Usage: ddhcp [-h] [-d|-D] [-L] [-c CLT-IFACE|-S] [-i SRV-IFACE] [-t TENTATIVE-TIMEOUT] [-B BLOCK-TIMEOUT]

-h                     This usage information.
-c CLT-IFACE           Interface on which requests from clients are handled
-i SRV-IFACE           Interface on which different servers communicate
-S                     no client interface
-t TENTATIVE           Time required for a block to be claimed
-N NETWORK/CIDR        Network to announce and manage blocks in
-o CODE:LEN:P1. .. .Pn DHCP Option with code, len and #len chars in decimal
-b BLKSIZEPOW          Block size as power of two
-B TIMEOUT             Block claim timeout
-s SPARELEASES         Amount of spare leases (max: 256)
-L                     Deactivate learning phase
-d                     Run in background and daemonize
-D                     Run in foreground and log to console (default)
-C CTRL_PATH           Path to control socket
-H COMMAND             Hook to call on events
-V                     Print build revision
-v                     Increase verbosity, may be specified multiple times

Build

To build a production binary of DDHCPD run.

make clean all

To increase the default logging output additional CFLAGS can be provided:

CFLAGS="-D LOG_LEVEL_DEFAULT=5" make clean all

Additionally setting DEBUG=1 activates debug symbols:

DEBUG=1 CFLAGS="-D LOG_LEVEL_DEFAULT=5" make clean all

To reduce the binary size to the minimum run:

CFLAGS="-D LOG_LEVEL_LIMIT=0" make clean all

To collect statistics build with

CFLAGS="-D DDHCPD_STATISTICS" make clean all

Depending on the chosen variant the binary size may variate between 30KiB and 1MiB.

Running

On a gluon node the command may look this:

ddhcpd -o "3:4:10.116.254.254" -o "1:4:255.255.128.0" -o "28:4:10.116.254.255" -N 10.116.224.0/20 -b 2 -s 1 -c br-client -i bat0

We are able to register DHCP options during startup but also during runtime. Using the ddhcpdctl binary, to e.g. add the standard gateway:

ddhcpdctl -o "3:4:10.116.254.253"

or a dedicated timeserver

ddhcpdctl -o "42:4:10.116.254.252"

Configured options can be removed with:

ddhcpdctl -r "42"

Be careful with this: as expressed above we do not save you from shooting yourself into your foot.

Hook

If you want to react to events, you can register an executable (binary or script) via the '-H' switch. On every event that executable will be called given a list of arguments:

Currently is one of the following keywords:

Upcoming versions of DDHCPD may introduce further action keywords.

Network analyzing

You can count the nodes in your network wich an active ddhcpd with

# ddhcpdctl -b | tail -n+10 | sed -e 's/\t\+/ /g' | cut -d ' ' -f 3 | sort -u | wc -l

Testing

The network-test script sets up a set of virtual interfaces which are composed of server and client interface pairs. Those are called srvX for daemons and cltX for clients inside of the main network namespace and server0 and client0 in the ''daemons'' network namespaces. All srvX interfaces are bridged in br-srv; enabling all daemons to communicate bidirectional.

Inside of the daemon's network namespace the client0 interface has the address 10.0.0.1/20. An IPv4 address is needed here, because the DHCP part of DDHCPD binds on this interface. It is the same address in every daemon namespace and since cltX interfaces are not bridged this is no problem. On the server0 interface we need no IPv4 address, because d2d communication is handled via IPv6 multicast/unicast on the local link.

You can setup a basic DDHCPD network testing environment by calling

# ./network-test net-init <number>

which creates a virtual network for of DDHCPD instances. You will need to have sufficient privileges to create network namespaces. Or in short: use sudo and check the network-test script upfront.

To start the (n-1)-th instance of DDHCPD in your test environment, use

# ./network-test srv-start <n> ./ddhcpd -t 3

The above also reduces the tentative timeout from 12 to 3 seconds to speed up testing.

After starting multiple instances, we generate DHCP requests against specific instances of DDHCPD by starting DHCP clients pointed to the cltX interfaces, i.e.

# dhclient -sf /dev/null -d -v clt0

for the first DDHCPD instance. To create multiple parallel running clients with different mac addresses, do:

# ./network-test clt-start <n>

To unconfigure the setup call:

# ./network-test net-stop

A simple testing routine incorporating all the above:

# ./network-test test

Gluon Packages

A maintained gluon integration can be found at:

https://github.com/sargon/gluon-sargon/tree/master