var net = require('net'),
    util = require('util');

module.exports = module.exports.createServer = function (options) {
  return new FailoverProxy(options);
};

var FailoverProxy = module.exports.FailoverProxy = function (options) {
  var self = this;

  self.hosts = options.hosts.slice(0);

  net.Server.call(this, self._requestHandler.bind(self));
};
util.inherits(FailoverProxy, net.Server);

FailoverProxy.prototype._requestHandler = function (socket) {
  var self = this,
      buffer = '';

  function doProxy(host) {
    var connected = false,
        connectQueue = [],
        outgoing;

    function deferToConnect(f, c, args) {
      connectQueue.push([f, c, args]);
    }

    function onIncomingData(chunk) {
      if (!connected) {
        deferToConnect(outgoing.write, outgoing, [chunk]);
      }
      else {
        outgoing.write(chunk);
      }
    }

    function onIncomingEnd() {
      if (connected) {
        outgoing.end();
      }
      else {
        deferToConnect(outgoing.end, outgoing, []);
      }
    }

    function onOutgoingConnected() {
      connectQueue.forEach(function (action) {
        action[0].apply(action[1], action[2]);
      });
      connectQueue.length = 0;

      connected = true;
    }

    function onOutgoingData(chunk) {
      if (socket.write(chunk) === false) {
        outgoing.pause();
      }
    }

    function onOutgoingEnd() {
      socket.end();
    }

    function onOutgoingError(err) {
      var badHost = self.hosts.shift();
      self.hosts.push(badHost);

      self.emit('cycle', badHost, self.hosts[0]);

      doProxy(self.hosts[0]);
    }

    socket.on('data', onIncomingData);
    socket.on('end', onIncomingEnd);

    outgoing = net.connect(host, onOutgoingConnected);

    outgoing.on('data', onOutgoingData);
    outgoing.on('end', onOutgoingEnd);
    outgoing.on('error', onOutgoingError);
  }

  doProxy(self.hosts[0]);
};

@@ -1027,32 +1027,157 @@
 %0A      %7D%0A    %7D%0A%0A
+    function onIncomingDrain() %7B%0A      if (outgoing.readable && outgoing.resume) %7B%0A        outgoing.resume();%0A      %7D%0A    %7D%0A%0A
     function onO
@@ -1193,24 +1193,24 @@
 nnected() %7B%0A
-
       connec
@@ -1736,24 +1736,143 @@
 0%5D);%0A    %7D%0A%0A
+    function onOutgoingDrain() %7B%0A      if (socket.readable && socket.resume) %7B%0A        socket.resume();%0A      %7D%0A    %7D%0A%0A
     socket.o
@@ -1934,16 +1934,57 @@
 ingEnd);
+%0A    socket.on('drain', onIncomingDrain);
 %0A%0A    ou
@@ -2109,24 +2109,24 @@
 tgoingEnd);%0A
-
     outgoing
@@ -2156,16 +2156,59 @@
 Error);%0A
+    outgoing.on('drain', onOutgoingDrain);%0A
   %7D%0A%0A  d

Add `drain` handlers