Skip to content

sargon/ddhcpd

Repository files navigation

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:

  <command> <action> <ip-addr> <hwaddr>

Currently <action> is one of the following keywords:

  - `lease`
    A new lease was handed out to the client indicated.

  - `release`
    The indicated lease has been released back into the address pool.

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 <number> 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