Skip to content

Commit

Permalink
feat: add tcp server
Browse files Browse the repository at this point in the history
Add tcp server.
Use UUID module insteal of int.
  • Loading branch information
purpose233 committed May 14, 2019
1 parent 3ce84dd commit b34c6a8
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 54 deletions.
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
3 changes: 1 addition & 2 deletions src/common/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ export const SocketType = {
};

export const EventType = {
FROM_REMOTE: 'remote',
FROM_TUNNEL: 'tunnel'
RECEIVE_REMOTE_CONNECTION: 'remote'
};

export const TunnelServerInfoType = {
Expand Down
102 changes: 59 additions & 43 deletions src/tcpServer.js
Original file line number Diff line number Diff line change
@@ -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);
}
};
13 changes: 5 additions & 8 deletions src/tunnelServer.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit b34c6a8

Please sign in to comment.