UNPKG

@cliz/inlets

Version:
93 lines (92 loc) 3.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const net = require("net"); const doreamon_1 = require("@zodash/doreamon"); const hmac = require("@zodash/hmac"); const constants_1 = require("../../common/constants"); const debug = require('debug')('inlets:client:tcp'); const logger = doreamon_1.default.logger.getLogger('client:tcp'); async function tcp(options) { const ip = getSocketIP(options.remoteHost, options.remotePort); let remote = null; const local = connect(options.localPort, options.localHost, 'local', { onClose() { remote === null || remote === void 0 ? void 0 : remote.destroy(); }, onConnect() { remote = connect(options.remotePort, options.remoteHost, 'remote'); const r = remote; remote.on('data', (data) => { if (r.isAuthenticated) return; const _ok = data.slice(0, constants_1.TUNNEL_TCP_OK_FLAG.length).toString(); const rest = data.slice(constants_1.TUNNEL_TCP_OK_FLAG.length); if (_ok !== constants_1.TUNNEL_TCP_OK_FLAG) { const error = data.slice(constants_1.TUNNEL_TCP_OK_FLAG.length, 32).toString(); logger.error(`[remote][${ip}] error: ${error}`); return; } logger.info(`[remote][${ip}] authenticated`); r.isAuthenticated = true; local.pipe(remote); remote.pipe(local); if (rest.length !== 0) { local.write(rest); } }); logger.info(`[remote][${ip}] authenticating`); const signedSecret = options.authType === 'credentials' ? options.clientSecret : options.token; const signature = hmac.hmacSHA256(options.id, signedSecret); const _data = [ constants_1.TUNNEL_TCP_FLAG, options.id, options.requestId, signature, ].join(''); remote.write(_data); }, }); } exports.default = tcp; function connect(port, host, name, options) { const ip = getSocketIP(host, port); const socket = net.connect(port, host, () => { var _a; logger.info(`[${name}][${ip}] socket connected`); (_a = options === null || options === void 0 ? void 0 : options.onConnect) === null || _a === void 0 ? void 0 : _a.call(options); }); onError(socket, name, ip); onClose(socket, name, ip, options === null || options === void 0 ? void 0 : options.onClose); onEnd(socket, name, ip); return socket; } function onError(socket, name, ip) { socket.on('error', (error) => { if (/ECONNREFUSED/.test(error.message)) { logger.error(`[${name}][${ip}] port is not available now`); return; } logger.error(`[${name}][${ip}] socket error:`, error); }); } function onClose(socket, name, ip, callback) { socket.on('close', (hadError) => { if (!hadError) { logger.info(`[${name}][${ip}] socket close normal`); } else { logger.error(`[${name}][${ip}] socket close error`); } callback === null || callback === void 0 ? void 0 : callback(); }); } function onEnd(socket, name, ip) { socket.on('end', () => { logger.info(`[${name}][${ip}] socket end`); }); } function getSocketIP(host, port) { return `${host}:${port}`; }