diff --git a/bin/goldilocks.js b/bin/goldilocks.js index 43f6627..d11f1a1 100755 --- a/bin/goldilocks.js +++ b/bin/goldilocks.js @@ -19,7 +19,7 @@ function run(config) { worker.send(config); }); } - console.log('config.tcp.ports', config.tcp.ports); + console.log('config.tcp.bind', config.tcp.bind); work(); } @@ -123,13 +123,13 @@ function readConfigAndRun(args) { var PromiseA = require('bluebird'); var tcpProm, dnsProm; - if (config.tcp.ports) { + if (config.tcp.bind) { tcpProm = PromiseA.resolve(); } else { tcpProm = new PromiseA(function (resolve, reject) { require('../lib/check-ports').checkTcpPorts(function (failed, bound) { - config.tcp.ports = Object.keys(bound); - if (config.tcp.ports.length) { + config.tcp.bind = Object.keys(bound); + if (config.tcp.bind.length) { resolve(); } else { reject(failed); diff --git a/lib/goldilocks.js b/lib/goldilocks.js index 6264845..bc5e6f1 100644 --- a/lib/goldilocks.js +++ b/lib/goldilocks.js @@ -242,6 +242,26 @@ module.exports.create = function (deps, config) { socket.send(msg, config.dns.proxy.port, config.dns.proxy.address || '127.0.0.1'); } + function createTcpForwarder(mod) { + var destination = mod.address.split(':'); + + return function (conn) { + var newConn = deps.net.createConnection({ + port: destination[1] + , host: destination[0] || '127.0.0.1' + + , remoteFamily: conn.remoteFamily + , remoteAddress: conn.remoteAddress + , remotePort: conn.remotePort + }, function () { + + }); + + newConn.pipe(conn); + conn.pipe(newConn); + }; + } + function approveDomains(opts, certs, cb) { // This is where you check your database and associated // email addresses with domains and agreements and such @@ -454,15 +474,59 @@ module.exports.create = function (deps, config) { }); }); - var listenPromises = config.tcp.ports.map(function (port) { - return listeners.tcp.add(port, netHandler); + var listenPromises = []; + var tcpPortMap = {}; + + if (config.tcp.bind) { + config.tcp.bind.forEach(function (port) { + tcpPortMap[port] = true; + }); + } + config.tcp.modules.forEach(function (mod) { + if (mod.name === 'forward') { + var forwarder = createTcpForwarder(mod); + mod.ports.forEach(function (port) { + if (!tcpPortMap[port]) { + console.log("forwarding port", port, "that wasn't specified in bind"); + } else { + delete tcpPortMap[port]; + } + listenPromises.push(listeners.tcp.add(port, forwarder)); + }); + } + else { + console.warn('unknown TCP module specified', mod); + } + }); + + // Even though these ports were specified in different places we treat any TCP + // connections we haven't been told to just forward exactly as is equal so that + // we can potentially use the same ports for different protocols. + function addPorts(bindList) { + if (!bindList) { + return; + } + if (Array.isArray(bindList)) { + bindList.forEach(function (port) { + tcpPortMap[port] = true; + }); + } + else { + tcpPortMap[bindList] = true; + } + } + addPorts(config.tls.bind); + addPorts(config.http.bind); + + Object.keys(tcpPortMap).forEach(function (port) { + listenPromises.push(listeners.tcp.add(port, netHandler)); }); if (config.dns.bind) { if (Array.isArray(config.dns.bind)) { - listenPromises = listenPromises.concat(config.dns.bind.map(function (port) { - return listeners.udp.add(port, dnsListener); - })); + config.dns.bind.map(function (port) { + listenPromises.push(listeners.udp.add(port, dnsListener)); + }); } else { listenPromises.push(listeners.udp.add(config.dns.bind, dnsListener)); }