From b34c6a89c5bfec446e93b09b2a2b31001f780158 Mon Sep 17 00:00:00 2001 From: purpose233 Date: Tue, 14 May 2019 17:41:51 +0800 Subject: [PATCH] feat: add tcp server Add tcp server. Use UUID module insteal of int. --- package-lock.json | 5 +++ package.json | 3 +- src/common/config.js | 3 +- src/tcpServer.js | 102 +++++++++++++++++++++++++------------------ src/tunnelServer.js | 13 +++--- 5 files changed, 72 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6309e74..ef5aa20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,11 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" } } } diff --git a/package.json b/package.json index 2a011d1..3c1fef5 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "dependencies": { "commander": "^2.20.0", "lodash": "^4.17.11", - "text-encoding": "^0.7.0" + "text-encoding": "^0.7.0", + "uuid": "^3.3.2" } } diff --git a/src/common/config.js b/src/common/config.js index 94e62cc..18bb446 100644 --- a/src/common/config.js +++ b/src/common/config.js @@ -4,8 +4,7 @@ export const SocketType = { }; export const EventType = { - FROM_REMOTE: 'remote', - FROM_TUNNEL: 'tunnel' + RECEIVE_REMOTE_CONNECTION: 'remote' }; export const TunnelServerInfoType = { diff --git a/src/tcpServer.js b/src/tcpServer.js index 929a846..4d811a7 100644 --- a/src/tcpServer.js +++ b/src/tcpServer.js @@ -1,55 +1,71 @@ const Net = require('net'); -const TextEncoding = require('text-encoding'); import {handleSocketError} from './common/socket'; +import {EventType, SocketType} from './common/config'; -const decoder = new TextEncoding.TextDecoder('utf-8'); -const createRemoteServer = () => { +// const createRemoteServer = () => { +// const remoteServer = Net.createServer(function (socket) { +// handleSocketError(socket); +// +// const socketId = UUID++; +// remoteSockets[socketId] = socket; +// socket.on('close', () => { +// delete remoteSockets[socketId]; +// }); +// socket.pause(); +// const info = {type: 'createTunnel', uuid: socketId}; +// mainClientSocket.write(JSON.stringify(info)); +// }); +// +// remoteServer.listen(RemoteServerPort, '127.0.0.1'); +// }; +// +// export const initTcpProxyServer = (proxies, bindPort) => { +// let UUID = 0; +// let mainClientSocket = null; +// +// const remoteSockets = {}; +// const tunnelSockets = {}; +// +// const tunnelServer = Net.createServer((socket) => { +// let isPiping = false; +// handleSocketError(socket); +// // data: {type: 'main'|'tunnel', uuid: int, remotePort: int} +// socket.on('data', (data) => { +// if (isPiping) { return; } +// console.log('Tunnel receive data: ' + data); +// const info = JSON.parse(decoder.decode(data)); +// const uuid = info.uuid; +// if (info.type === 'main') { +// mainClientSocket = socket; +// } else if (info.type === 'tunnel') { +// tunnelSockets[uuid] = socket; +// socket.on('close', () => { +// delete tunnelSockets[uuid]; +// }); +// remoteSockets[uuid].pipe(socket).pipe(remoteSockets[uuid]); +// remoteSockets[uuid].resume(); +// isPiping = true; +// } +// }); +// }); +// +// tunnelServer.listen(TunnelServerPort, '127.0.0.1'); +// }; + +const createRemoteServer = (eventEmitter, listenPort) => { const remoteServer = Net.createServer(function (socket) { handleSocketError(socket); - const socketId = UUID++; - remoteSockets[socketId] = socket; - socket.on('close', () => { - delete remoteSockets[socketId]; - }); - socket.pause(); - const info = {type: 'createTunnel', uuid: socketId}; - mainClientSocket.write(JSON.stringify(info)); + eventEmitter.emit(EventType.RECEIVE_REMOTE_CONNECTION, + SocketType.TCP, socket, listenPort); }); - remoteServer.listen(RemoteServerPort, '127.0.0.1'); + remoteServer.listen(listenPort, '127.0.0.1'); }; -export const initTcpProxyServer = (proxies, bindPort) => { - let UUID = 0; - let mainClientSocket = null; - - const remoteSockets = {}; - const tunnelSockets = {}; - - const tunnelServer = Net.createServer((socket) => { - let isPiping = false; - handleSocketError(socket); - // data: {type: 'main'|'tunnel', uuid: int, remotePort: int} - socket.on('data', (data) => { - if (isPiping) { return; } - console.log('Tunnel receive data: ' + data); - const info = JSON.parse(decoder.decode(data)); - const uuid = info.uuid; - if (info.type === 'main') { - mainClientSocket = socket; - } else if (info.type === 'tunnel') { - tunnelSockets[uuid] = socket; - socket.on('close', () => { - delete tunnelSockets[uuid]; - }); - remoteSockets[uuid].pipe(socket).pipe(remoteSockets[uuid]); - remoteSockets[uuid].resume(); - isPiping = true; - } - }); - }); - - tunnelServer.listen(TunnelServerPort, '127.0.0.1'); +export const createTcpProxies = (eventEmitter, proxies) => { + for (let proxy of proxies) { + createRemoteServer(eventEmitter, proxy.listenPort); + } }; diff --git a/src/tunnelServer.js b/src/tunnelServer.js index fd91b91..401a9b0 100644 --- a/src/tunnelServer.js +++ b/src/tunnelServer.js @@ -1,4 +1,5 @@ const Net = require('net'); +const uuidv4 = require('uuid/v4'); import {handleSocketError, parseMsgWithMetaData, sendMetaData, sendWithMetaData} from './common/socket'; import {logSocketData} from './common/log'; @@ -20,12 +21,8 @@ const pipeRemoteAndTunnelSocket = (remoteSocket, tunnelSocket, uuid, srcPort) => }); }; -export const createTunnelServer = (bindPort, eventEmitter) => { - // TODO: note that the amount of tunnelSocket might reach the limit, - // and UUID might be too large. - - // TODO: maybe use separated UUID for tcp and udp. - let UUID = 0; +export const createTunnelServer = (eventEmitter, bindPort) => { + // TODO: note that the amount of tunnelSocket might reach the limit. let tcpControlSocket = null; let udpControlSocket = null; @@ -71,11 +68,11 @@ export const createTunnelServer = (bindPort, eventEmitter) => { }); }); - eventEmitter.on(EventType.FROM_REMOTE, (socketType, src, srcPort) => { + eventEmitter.on(EventType.RECEIVE_REMOTE_CONNECTION, (socketType, src, srcPort) => { // When socket type is TCP, src is socket object. // else src is address object. if (socketType === SocketType.TCP) { - const socketId = UUID++; + const socketId = uuidv4(); const remoteSocket = src; remoteTcpSocketInfos[socketId] = { port: srcPort,