UNPKG

@cliz/inlets

Version:
71 lines (70 loc) 2.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.forward = void 0; const cli_1 = require("@cliz/cli"); const doreamon_1 = require("@zodash/doreamon"); const net = require("net"); const debug = require('debug')('inlets:forward'); async function forward(options) { var _a; const logger = doreamon_1.default.logger.getLogger('forward'); const servers = (_a = options === null || options === void 0 ? void 0 : options.servers) !== null && _a !== void 0 ? _a : []; logger.info(`total servers: ${servers.length}`); const portUsed = {}; for (const server of servers) { if (portUsed[server.localPort]) { logger.error(`forward error: port(${server.localPort}) used internal`); continue; } portUsed[server.localPort] = true; try { await serve(server); } catch (error) { logger.error('forward error:', error); } } } exports.forward = forward; async function serve(options) { const { localHost = '127.0.0.1', localPort, remoteHost, remotePort, } = options; const logger = doreamon_1.default.logger.getLogger(`${localHost}:${localPort}:${remoteHost}:${remotePort}`); if (!await cli_1.api.network.isPortAvailable(localPort)) { throw new Error(`port(${localPort}) is used`); } const connect = async () => { try { const server = net.createServer(socket => { const clientIP = socket.remoteAddress; logger.info(`client(${clientIP}) connected`); const remoteSocket = net.connect(remotePort, remoteHost); socket.on('error', (error) => { logger.error('local socket error:', error); }); socket.on('close', (had_error) => { logger.info('local socket close, has error ? ', had_error); }); remoteSocket.on('error', (error) => { logger.error('remote socket error:', error); }); remoteSocket.pipe(socket); socket.pipe(remoteSocket); }); server.on('error', (error) => { logger.error('tcp server error:', error); }); server.on('close', (error) => { logger.error('tcp server close:', error); }); server.listen(localPort, localHost, () => { logger.info('start success'); }); } catch (error) { await doreamon_1.default.delay(1000); logger.info('reconnect:', error); await connect(); } }; await connect(); }