---
title: HDDEMUX
section: 1
author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
date: 2017 May
---


NAME
====

hddemux - demultiplexes incoming TCP connections between HTTP and DNS

SYNOPSIS
========
 
hddemux

DESCRIPTION
===========

hddemux takes a set of listening stream-based file descriptors (see
sd_listen_fds(3)) and accepts new connections on them.

When a new connection comes in, it decides from the first few octets
whether the connection is HTTP/1.x or DNS.  If it thinks it's
HTTP/1.x, it splices the connection to the HTTP_TARGET.  If it thinks
it's DNS, it splices the connection to the DNS_TARGET.

ENVIRONMENT VARIABLES
=====================

HTTP_TARGET and DNS_TARGET should be either a DNS name or an IP address,
optionally followed by a colon and a port number.  If either variable
is unset, it will default to "localhost".

If the port number is not specified, HTTP_TARGET defaults to TCP port
80, and DNS_TARGET defaults to TCP port 53.

If HDDEMUX_DEBUG is set to a non-empty string, then it will send a lot
of verbose debugging info to stderr.

IDLE_TIMEOUT is used to set the number of milliseconds that hddemux
will permit a session to be in an open state with no traffic passing
before it tries to close both sides.  The default is 600000 (10
minutes).  Set this variable to 0 to never try to do this kind of
cleanup.

SIGNALS
=======

When hddemux receives SIGUSR1, it dumps an overview of the current
state of the demuxer (configuration, outstanding established streams,
etc) to stderr.

EXAMPLES
========

For systemd, you need a .socket unit file:

    #/lib/systemd/hddemux.socket
    [Unit]
    Description=HTTP/1.x and DNS demuxer socket
    Documentation=man:hddemux(1)

    [Socket]
    ListenStream=/run/hddemux/socket

    [Install]
    WantedBy=sockets.target

and a .service unit file:

    #/lib/systemd/hddemux.service
    [Unit]
    Description=HTTP/1.x and DNS demuxer service
    Documentation=man:hddemux(1)
    Requires=hddemux.socket
    
    [Service]
    Type=notify
    ExecStart=/usr/bin/hddemux
    WorkingDirectory=/run/hddemux/workdir
    User=hddemux
    Group=hddemux
    
    [Install]
    Also=hddemux.socket

Configuration can be done by overriding the .service file (e.g. with
Service.Environment= entries).  See the "edit" documentation in
systemctl(1) and the "Overriding vendor settings" section of
systemd.unit(5).


CONSTRAINTS
===========

hddemux is designed to demultiplex HTTP/1.x from stream-based DNS.
Trying to demultiplex other protocols (including HTTP/2 or later) is
not advised.  Please see draft-dkg-dprive-demux-dns-http for more
information and analysis.

WARNING
=======

Note that this effectively acts as a stream redirector once the
client's first flight has been processed.  It does this with no
attempt to defend against stream redirection loops, so be careful not
to redirect it to itself or it will eat all of your memory in infinite
recursion.

SEE ALSO
========

sd_listen_fds(3), systemctl(1), systemd.unit(5),
https://datatracker.ietf.org/doc/draft-dkg-dprive-demux-dns-http/
