'use strict'; var net = require('net'); var tls = require('tls'); function listenForConns(emitter, opts) { function pipeConn(c, out) { var sclient = tls.connect({ servername: opts.remoteAddr, host: opts.remoteAddr, port: opts.remotePort , rejectUnauthorized: opts.rejectUnauthorized }, function () { console.info('[connect] ' + sclient.localAddress.replace('::1', 'localhost') + ":" + sclient.localPort + " => " + opts.remoteAddr + ":" + opts.remotePort); c.pipe(sclient); sclient.pipe(out || c); }); sclient.on('error', function (err) { console.error('[error] (remote) ' + err.toString()); }); c.on('error', function (err) { console.error('[error] (local) ' + err.toString()); }); if (out) { out.on('error', function (err) { console.error('[error] (local) ' + err.toString()); }); } } if ('-' === opts.localAddress || '|' === opts.localAddress) { pipeConn(opts.stdin, opts.stdout); return; } var server = net.createServer(pipeConn); server.on('error', function (err) { console.error('[error] ' + err.toString()); }); server.listen({ host: opts.localAddress , port: opts.localPort }, function () { opts.localPort = this.address().port; opts.server = this; emitter.emit('listening', opts); }); } function testConn(opts) { var emitter = new (require('events').EventEmitter)(); // Test connection first var tlsOpts = { host: opts.remoteAddr, port: opts.remotePort , rejectUnauthorized: opts.rejectUnauthorized }; if (opts.servername) { tlsOpts.servername = opts.servername; } else if (/^[\w\.\-]+\.[a-z]{2,}$/i.test(opts.remoteAddr)) { tlsOpts.servername = opts.remoteAddr.toLowerCase(); } if (opts.alpn) { tlsOpts.ALPNProtocols = [ 'http', 'h2' ]; } var tlsSock = tls.connect(tlsOpts, function () { setTimeout(function () { tlsSock.end(); listenForConns(emitter, opts); }, 200); }); tlsSock.on('error', function (err) { console.warn("[warn] '" + opts.remoteAddr + ":" + opts.remotePort + "' may not be accepting connections: ", err.toString(), '\n'); listenForConns(emitter, opts); }); return emitter; } module.exports = testConn;