/Hydra-DHCP

Hydra, a high performance and resilient Erlang DHCP server.

Primary LanguageErlangMIT LicenseMIT

Hydra-DHCP

Hydra, a high performance and resilient DHCP server is a research project towards a distributed and scalable DHCP service in Erlang/OTP for next generations IPAM scenarios.

This is the source code of an Erlang/OTP application designed to function as a DHCP (Dynamic Host Configuration Protocol) service featuring scalability and resilence thanks to the great OTP framework capabilities.

This is work in progress, yet a rebarized "shell" is provided from day one to manage the entire OTP application as a command-line Unix program, so for the most part you only need to follow the install instructions to get a single standalone "hdcp-server" escript bundle.

As Aug'14 this project is on hold so updates will make their way on a very slow fashion.

Project status

Build Status

The repository is registered on Travis-ci, so a green status means all software compile and unit tests (if any) went fine.

We will provide a stable release on reaching v 1.0.

  • Escript fronted :

    • Command-line parsing , and complete statup and shutdoen of the bundle OTP application.
  • Cross module get-opt :

    • Gathering of options specs across all bundled modules.
  • Main OTP tree :

    • Simple (non distributed) applicaction startup with config data provided from escript frontend.
  • Console server :

  • Table master :

    • Simple inheritance from process deaths, and service of ETS table identifiers to any process.
  • UDP Driver :

    • UDP port configurable via command-line.
    • Iface and server ID configuration in progress.
  • Middleman DHCP encoder / decoder:

  • DORA Cache manager :

    • Helps middlemen processes to figure out which FSM is managing client state, and also spawn new FSM on request.
  • DORA DHCP State machine :

    • Manages entire DHCP server state machine for every client. FSM can stop storing data into a suitable pool server (which also presist lease info to a DETS file).
  • Address Pool Servers :

    • 'Simple pool type' this type manages a simple range of IP's, and a list of options using a ETS table and a DETS table to persist lease information. Simple format suitable for file:consult() usage:

      • Pool name {name, "Universidad"}
      • A range of IP's {range, {192,168,1,2}, {192,168,1,253}}
      • A list of Options
        • {lease_time, 3600}
        • {renewal_time, 1800}
        • {rebinding_time, 3000}
        • {subnet_mask, {255, 255, 255, 0}}
        • {broadcast_address, {192, 168, 1, 255}}
        • {dns_server, {192, 168, 1, 1}}
        • {domain_name, "uah.es"}
        • {router, {192, 168, 1, 254}}
    • Init functions mostly finished ( file parse, load and state/tables population)

Brief Project roadmap

  • Basic DHCP service

    • Simple file based data backend and SQL storage backend.
    • DHCP Fingerprinting
  • High Performance DHCP Service

    • Hydra mode: Serving a pool of UDP ports (on suitable platforms with iptables like capabilities)
  • Distributed DHCP service

    • Master/Slave HA schemes.
    • Multimaster HA (Mnesia)

Basic application architecture

                                   [Top Supervisor]
                                          |
      --------------------------------------------------------------------------------------------
     |                        |                      |                        |                   |
[Supervisor]            [Supervisor]           [Supervisor]             [Supervisor]         [Supervisor]
     |                        |                 |    |                        |                   |
     |                        |    Pid?         |    |                        |               [Console]
     |                        |     --->[FSM cache] [*]                       |                   |
[UDP_SRV_SRV]                 |    |                 |                        |              [Table Heir]
     |                  [MIDDLEMAN_SRV]          [DORA_FSM]             [ADDR_POOL_SRV]
     |                        |                      |                        |
      --UDP binaries--> [MIDDLEMAN_SRV]          [DORA_FSM]             [ADDR_POOL_SRV]
                              |                      |                        |
                              |                  [DORA_FSM]             [ADDR_POOL_SRV]
                              |                      |                        |
                               --Erlang Terms--> [DORA_FSM]             [ADDR_POOL_SRV]
                                                     |                        |
                                                     |                        |
                                                      --Erlang Terms--> [ADDR_POOL_SRV]

[*] Simple_one_for_one Supervisor

1. UDP_DRV_SRV
	- One per UDP port served (currently on UDP port), dispatch UDP messages between network hosts and erlang processes.
2. MIDDLEMAN_SRV
	- At least one per core, transform UDP message into erlang terms and viceversa, and talks (async) to DORA finite state machines.
3. DORA_FSM
	- One per active client, manage the entire DHCP exchange state machine (a.k.a DORA) and talks (sync) to pool servers
	 to get leases.
4. ADDR_POOL_SRV
	- One per addr pool configured, manages client leases and pool policies.

5. Miscelaneous servers.
	- Console service: frontend offering services to print all the various structures on the application.
	- Table heir:  Responsible for ets tables used across the various workers.

SYSTEM REQUIREMENTS

1. Base Operating System
	- Unix-like compatible operating systems
		- Currently tested on Mac OS X 10.8.5 (development platform)

2. Erlang environment
	- Currently tested on Erlang R16B03-1

INSTALL

1. Get Erlang/OTP.
2. Get rebar.
	$ git clone git://github.com/rebar/rebar.git
	$ cd rebar
	$ ./bootstrap
	Recompile: src/getopt
	...
	Recompile: src/rebar_utils
	==> rebar (compile)

	move the result rebar file to somewhere in yout $PATH

3. Clone this repository.

4. Build the application.

	- cd Hydra-DHCP
	- rebar clean
	- rebar compile
	- rebar escriptize

5. Run the server

	bash-3.2$ ./dhcp_server --help

	Hydra, a high performance and resilent Erlang DHCP server.
	Copyright: 2014 Angel J. Alvarez Miguel
	Version: 0.1

	Usage: ./dhcp_server [-D <pool_dir>] [-P <procs>] [-V] [-v] [-d <debug>] [-?] [-M <middleman_pool_factor>] [-U <udp_port>]

	-D, --pooldir		Pool data directory.
	-P, --cores			Number of workers (default 2*core).
	-V, --version		Show software version.
	-v, --verbose		Show all actions performed.
	-d, --debug			Show debug info.
	-?, --help			Show this help.
	-M, --middleman		Use 1, 2 or 4 middlemen (packet processors) per core
	-U, --udp			UDP listening port.

	Remember you need root privileges to open port 67, instead you can try something like this:

	$ ./dhcp_server --udp 2000

	so you dont need to be root... do you? 

	$ sudo ./dhcp_service

	Once the server start, you should see something like this

	bash-3.2$ ./dhcp_server --timeout 10 --udp 9000

	Hydra, a high performance and resilent Erlang DHCP server.
	Copyright: 2014 Angel J. Alvarez Miguel
	Version: 0.1

	top_sup: Init, I got 5 children to spawn..
	misc_sup: Init..
	[console_srv]: Init... 
	[ets_master_srv]: Init..
	[addr_pool_sup] Initiating, got 2 address pools to setup
	[addr_pool_srv_1]: Initiating pool from file ./data/pool2.dat..
	[addr_pool_srv_1]: Creating ETS pool named 'Universidad2'..
	[ets_master_srv]: Pid {<0.38.0>,#Ref<0.0.0.90>} asked for 'Universidad2', we sent not_found..
	[addr_pool_srv_1]: Creating DETS leases table named 'Universidad2.leases'..
	[addr_pool_srv_1]: Populating pool from {10,10,0,2} to {10,10,1,253}..
	[addr_pool_srv_1]: option: {lease_time,3600}
	[addr_pool_srv_1]: option: {renewal_time,1800}
	[addr_pool_srv_1]: option: {rebinding_time,3000}
	[addr_pool_srv_1]: option: {subnet_mask,{255,255,254,0}}
	[addr_pool_srv_1]: option: {dns_server,{192,168,1,1}}
	[addr_pool_srv_1]: option: {domain_name,"uah.es"}
	[addr_pool_srv_1]: option: {router,{10,10,1,254}}
	[addr_pool_srv_1]: Transferring client leases to ETS pool.
	[addr_pool_srv_2]: Initiating pool from file ./data/pool1.dat..
	[addr_pool_srv_2]: Creating ETS pool named 'Universidad'..
	[ets_master_srv]: Pid {<0.44.0>,#Ref<0.0.0.129>} asked for 'Universidad', we sent not_found..
	[addr_pool_srv_2]: Creating DETS leases table named 'Universidad.leases'..
	[addr_pool_srv_2]: Populating pool from {192,168,1,2} to {192,168,1,253}..
	[addr_pool_srv_2]: option: {lease_time,3600}
	[addr_pool_srv_2]: option: {renewal_time,1800}
	[addr_pool_srv_2]: option: {rebinding_time,3000}
	[addr_pool_srv_2]: option: {subnet_mask,{255,255,255,0}}
	[addr_pool_srv_2]: option: {broadcast_address,{192,168,1,255}}
	[addr_pool_srv_2]: option: {dns_server,{192,168,1,1}}
	[addr_pool_srv_2]: option: {domain_name,"uah.es"}
	[addr_pool_srv_2]: option: {router,{192,168,1,254}}
	[addr_pool_srv_2]: Transferring client leases to ETS pool.
	dora_cache_sup: Init..
	dora_cache_srv: Init..
	[dora_dyn_sup]: Init..
	[middleman_sup]: Init.. I got 4 children to spawn
	[middleman_srv_1]: Init..
	[middleman_srv_2]: Init..
	[middleman_srv_3]: Init..
	[middleman_srv_4]: Init..
	network_sup: Init..
	udp_driver_srv: Init..
	udp_driver_srv: I got 4 middleman pids..
	udp_driver_srv: Opening UPD port 9000..
	Application started...

	[MAIN] Application Timeout
	Application stopped...

Authors

  • Angel J. Alvarez Miguel

References

  • "Erlang Programming", Cesarini, Thompson, 2009, O’Reilly.
  • "The DHCP Handbook 2nd Ed.", Droms n Lemon, 2003, Sams.
  • "IP ADDRESS MANAGEMENT Principles and Practice", Rooney, 2011, IEEE Press.
  • RFC 2131, 6361