add server status
This commit is contained in:
2
local.js
2
local.js
@@ -2,7 +2,7 @@ const TCPRelay = require('./tcprelay').TCPRelay;
|
|||||||
const local = require('commander');
|
const local = require('commander');
|
||||||
|
|
||||||
local
|
local
|
||||||
.version('0.1.3')
|
.version('0.1.4')
|
||||||
.option('-m --method [method]', 'encryption method, default: aes-256-cfb')
|
.option('-m --method [method]', 'encryption method, default: aes-256-cfb')
|
||||||
.option('-k --password [password]', 'password')
|
.option('-k --password [password]', 'password')
|
||||||
.option('-s --server-address [address]', 'server address')
|
.option('-s --server-address [address]', 'server address')
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "shadowsocks-over-websocket",
|
"name": "shadowsocks-over-websocket",
|
||||||
"version": "0.1.3",
|
"version": "0.1.4",
|
||||||
"description": "A fast tunnel proxy that helps you bypass firewalls",
|
"description": "A fast tunnel proxy that helps you bypass firewalls",
|
||||||
"main": "tcprelay.js",
|
"main": "tcprelay.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const TCPRelay = require('./tcprelay').TCPRelay;
|
|||||||
const server = require('commander');
|
const server = require('commander');
|
||||||
|
|
||||||
server
|
server
|
||||||
.version('0.1.3')
|
.version('0.1.4')
|
||||||
.option('-m --method [method]', 'encryption method, default: aes-256-cfb')
|
.option('-m --method [method]', 'encryption method, default: aes-256-cfb')
|
||||||
.option('-k --password [password]', 'password')
|
.option('-k --password [password]', 'password')
|
||||||
.option('-s --server-address [address]', 'server address')
|
.option('-s --server-address [address]', 'server address')
|
||||||
|
|||||||
33
tcprelay.js
33
tcprelay.js
@@ -61,7 +61,12 @@ const STAGE = {
|
|||||||
5: 'STAGE_STREAM'
|
5: 'STAGE_STREAM'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SERVER_STATUS_INIT = 0;
|
||||||
|
const SERVER_STATUS_RUNNING = 1;
|
||||||
|
const SERVER_STATUS_STOPPED = 2;
|
||||||
|
|
||||||
var globalConnectionId = 1;
|
var globalConnectionId = 1;
|
||||||
|
var connections = {};
|
||||||
|
|
||||||
function parseAddressHeader(data, offset) {
|
function parseAddressHeader(data, offset) {
|
||||||
var addressType = data.readUInt8(offset);
|
var addressType = data.readUInt8(offset);
|
||||||
@@ -88,10 +93,10 @@ function parseAddressHeader(data, offset) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// client <=> local <=> server <=> target
|
|
||||||
function TCPRelay(config, isLocal, logLevel) {
|
function TCPRelay(config, isLocal, logLevel) {
|
||||||
this.isLocal = isLocal;
|
this.isLocal = isLocal;
|
||||||
this.server = null;
|
this.server = null;
|
||||||
|
this.status = SERVER_STATUS_INIT;
|
||||||
this.config = require('./config.json');
|
this.config = require('./config.json');
|
||||||
if (config) {
|
if (config) {
|
||||||
this.config = Object.assign(this.config, config);
|
this.config = Object.assign(this.config, config);
|
||||||
@@ -112,17 +117,29 @@ TCPRelay.prototype.bootstrap = function() {
|
|||||||
|
|
||||||
TCPRelay.prototype.stop = function() {
|
TCPRelay.prototype.stop = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var connId = null;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
if (self.server) {
|
if (self.server) {
|
||||||
self.server.close(function() {
|
self.server.close(function() {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (connId in connections) {
|
||||||
|
if (connections[connId]) {
|
||||||
|
self.isLocal ? connections[connId].destroy() : connections[connId].terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TCPRelay.prototype.getStatus = function() {
|
||||||
|
return this.status;
|
||||||
|
};
|
||||||
|
|
||||||
TCPRelay.prototype.init = function() {
|
TCPRelay.prototype.init = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
@@ -139,6 +156,10 @@ TCPRelay.prototype.init = function() {
|
|||||||
server.on('connection', function(connection) {
|
server.on('connection', function(connection) {
|
||||||
return self.handleConnectionByLocal(connection);
|
return self.handleConnectionByLocal(connection);
|
||||||
});
|
});
|
||||||
|
server.on('close', function() {
|
||||||
|
self.logger.info('server is closed');
|
||||||
|
self.status = SERVER_STATUS_STOPPED;
|
||||||
|
});
|
||||||
server.listen(port, address);
|
server.listen(port, address);
|
||||||
} else {
|
} else {
|
||||||
server = self.server = new WebSocket.Server({
|
server = self.server = new WebSocket.Server({
|
||||||
@@ -153,10 +174,12 @@ TCPRelay.prototype.init = function() {
|
|||||||
}
|
}
|
||||||
server.on('error', function(error) {
|
server.on('error', function(error) {
|
||||||
self.logger.error('an error of', self.getServerName(), 'occured', error);
|
self.logger.error('an error of', self.getServerName(), 'occured', error);
|
||||||
|
self.status = SERVER_STATUS_STOPPED;
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
server.on('listening', function() {
|
server.on('listening', function() {
|
||||||
self.logger.info(self.getServerName(), 'is listening on', address + ':' + port);
|
self.logger.info(self.getServerName(), 'is listening on', address + ':' + port);
|
||||||
|
self.status = SERVER_STATUS_RUNNING;
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -181,6 +204,7 @@ TCPRelay.prototype.handleConnectionByServer = function(connection) {
|
|||||||
var dataCache = [];
|
var dataCache = [];
|
||||||
|
|
||||||
logger.info(`[${connectionId}]: accept connection from local`);
|
logger.info(`[${connectionId}]: accept connection from local`);
|
||||||
|
connections[connectionId] = connection;
|
||||||
connection.on('message', function(data) {
|
connection.on('message', function(data) {
|
||||||
data = encryptor.decrypt(data);
|
data = encryptor.decrypt(data);
|
||||||
logger.info(`[${connectionId}]: read data[length = ${data.length}] from local connection at stage[${STAGE[stage]}]`);
|
logger.info(`[${connectionId}]: read data[length = ${data.length}] from local connection at stage[${STAGE[stage]}]`);
|
||||||
@@ -258,10 +282,13 @@ TCPRelay.prototype.handleConnectionByServer = function(connection) {
|
|||||||
});
|
});
|
||||||
connection.on('close', function(hadError) {
|
connection.on('close', function(hadError) {
|
||||||
logger.info(`[${connectionId}]: close event[had error = ${hadError}] of connection has been triggered`);
|
logger.info(`[${connectionId}]: close event[had error = ${hadError}] of connection has been triggered`);
|
||||||
|
connections[connectionId] = null;
|
||||||
|
targetConnection && targetConnection.destroy();
|
||||||
});
|
});
|
||||||
connection.on('error', function(error) {
|
connection.on('error', function(error) {
|
||||||
logger.error(`[${connectionId}]: an error of connection occured`, error);
|
logger.error(`[${connectionId}]: an error of connection occured`, error);
|
||||||
connection.terminate();
|
connection.terminate();
|
||||||
|
connections[connectionId] = null;
|
||||||
targetConnection && targetConnection.end();
|
targetConnection && targetConnection.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -286,6 +313,7 @@ TCPRelay.prototype.handleConnectionByLocal = function(connection) {
|
|||||||
var dataCache = [];
|
var dataCache = [];
|
||||||
|
|
||||||
logger.info(`[${connectionId}]: accept connection from client`);
|
logger.info(`[${connectionId}]: accept connection from client`);
|
||||||
|
connections[connectionId] = connection;
|
||||||
connection.setKeepAlive(true, 10000);
|
connection.setKeepAlive(true, 10000);
|
||||||
connection.on('data', function(data) {
|
connection.on('data', function(data) {
|
||||||
logger.info(`[${connectionId}]: read data[length = ${data.length}] from client connection at stage[${STAGE[stage]}]`);
|
logger.info(`[${connectionId}]: read data[length = ${data.length}] from client connection at stage[${STAGE[stage]}]`);
|
||||||
@@ -389,12 +417,15 @@ TCPRelay.prototype.handleConnectionByLocal = function(connection) {
|
|||||||
logger.info(`[${connectionId}]: close event[had error = ${hadError}] of client connection has been triggered`);
|
logger.info(`[${connectionId}]: close event[had error = ${hadError}] of client connection has been triggered`);
|
||||||
stage = STAGE_DESTROYED;
|
stage = STAGE_DESTROYED;
|
||||||
canWriteToLocalConnection = false;
|
canWriteToLocalConnection = false;
|
||||||
|
connections[connectionId] = null;
|
||||||
|
serverConnection && serverConnection.terminate();
|
||||||
});
|
});
|
||||||
connection.on('error', function(error) {
|
connection.on('error', function(error) {
|
||||||
logger.error(`[${connectionId}]: an error of client connection occured`, error);
|
logger.error(`[${connectionId}]: an error of client connection occured`, error);
|
||||||
stage = STAGE_DESTROYED;
|
stage = STAGE_DESTROYED;
|
||||||
connection.destroy();
|
connection.destroy();
|
||||||
canWriteToLocalConnection = false;
|
canWriteToLocalConnection = false;
|
||||||
|
connections[connectionId] = null;
|
||||||
serverConnection && serverConnection.close();
|
serverConnection && serverConnection.close();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user