typedef int (*funcptr)();

An engineers technical notebook

Using DJB's daemontools and netcat to bounce a request around

Lately I have been moving the data from one server to another server, located halfway across the globe, and I needed some way to forward all incoming requests from the old server to the new server. This had to be done so that DNS could take its time to update while everything was now already being served from the new location.

What I ended up doing was using daemontools along with netcat to pipe the request around the world. Here are the steps I took in doing so:

mkdir /usr/local/redirect/
cd /usr/local/redirect/
mkdir smtp smtp/env
cd smtp

Put the following in a file named run:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#!/bin/sh
exec 2>&1 \
envdir ./env \
sh -c '
    case "$REMOTENAME" in h) H=;; p) H=p;; *) H=H;; esac
    case "$REMOTEINFO" in r) R=;; [0-9]*) R="t$REMOTEINFO";; *) R=R;; esac
    exec \
    /usr/local/bin/tcpserver \
        -vDU"$H$R" \
        ${LOCALNAME+"-l$LOCALNAME"} \
        ${BACKLOG+"-b$BACKLOG"} \
        ${CONCURRENCY+"-c$CONCURRENCY"} \
        -- "${IP-0}" "${PORT}" \
        /usr/bin/nc "${REMOTEHOST}" "${REMOTEPORT}"
'

Make it executable:

chmod +x run

Then we need to set up a few environment variables:

cd env
echo "example.net" > REMOTEHOST
echo "25" > REMOTEPORT
echo "25" > PORT
echo `hostname` > LOCALNAME
echo "200" > CONCURRENCY

I made REMOTEPORT and PORT be separate on purpose, in one case I now had more IP's than before, so instead of having SSL running on a separate port it was running on the default port, and I needed a clean way to forward that.

Now just add it to your services folder as a symlink and it will automatically be started, from there it will do it's job! I also suggest adding some simple logging, or discarding all off the output from tcpserver.