remove ips limit
refactoring errors
This commit is contained in:
parent
5d40faf39e
commit
6f509b848c
@ -34,11 +34,6 @@ module.exports = convict({
|
|||||||
format: String,
|
format: String,
|
||||||
default: '/myapp'
|
default: '/myapp'
|
||||||
},
|
},
|
||||||
ip_limit: {
|
|
||||||
doc: 'Max connections per ip',
|
|
||||||
format: 'duration',
|
|
||||||
default: 100
|
|
||||||
},
|
|
||||||
concurrent_limit: {
|
concurrent_limit: {
|
||||||
doc: 'Max connections',
|
doc: 'Max connections',
|
||||||
format: 'duration',
|
format: 'duration',
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
const config = require('../../../../config');
|
const config = require('../../../../config');
|
||||||
const realm = require('../../../services/realm');
|
const realm = require('../../../services/realm');
|
||||||
|
const { Errors } = require('../../../enums');
|
||||||
|
|
||||||
module.exports = (req, res, next) => {
|
module.exports = (req, res, next) => {
|
||||||
const { id, token, key } = req.params;
|
const { id, token, key } = req.params;
|
||||||
|
|
||||||
const sendAuthError = () => res.sendStatus(401);
|
|
||||||
|
|
||||||
if (key !== config.get('key')) {
|
if (key !== config.get('key')) {
|
||||||
return sendAuthError();
|
return res.status(401).send(Errors.INVALID_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!id) {
|
if (!id) {
|
||||||
@ -17,11 +16,11 @@ module.exports = (req, res, next) => {
|
|||||||
const client = realm.getClientById(id);
|
const client = realm.getClientById(id);
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
return sendAuthError();
|
return res.sendStatus(401);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client.getToken() && token !== client.getToken()) {
|
if (client.getToken() && token !== client.getToken()) {
|
||||||
return sendAuthError();
|
return res.status(401).send(Errors.INVALID_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
12
src/enums.js
12
src/enums.js
@ -1,10 +1,18 @@
|
|||||||
module.exports.Errors = {};
|
module.exports.Errors = {
|
||||||
|
INVALID_KEY: 'Invalid key provided',
|
||||||
|
INVALID_TOKEN: 'Invalid token provided',
|
||||||
|
INVALID_WS_PARAMETERS: 'No id, token, or key supplied to websocket server',
|
||||||
|
CONNECTION_LIMIT_EXCEED: 'Server has reached its concurrent user limit'
|
||||||
|
};
|
||||||
|
|
||||||
module.exports.MessageType = {
|
module.exports.MessageType = {
|
||||||
|
OPEN: 'OPEN',
|
||||||
LEAVE: 'LEAVE',
|
LEAVE: 'LEAVE',
|
||||||
CANDIDATE: 'CANDIDATE',
|
CANDIDATE: 'CANDIDATE',
|
||||||
OFFER: 'OFFER',
|
OFFER: 'OFFER',
|
||||||
ANSWER: 'ANSWER',
|
ANSWER: 'ANSWER',
|
||||||
EXPIRE: 'EXPIRE',
|
EXPIRE: 'EXPIRE',
|
||||||
HEARTBEAT: 'HEARTBEAT'
|
HEARTBEAT: 'HEARTBEAT',
|
||||||
|
ID_TAKEN: 'ID-TAKEN',
|
||||||
|
ERROR: 'ERROR'
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,10 @@ const messageHandler = require('./messageHandler');
|
|||||||
const realm = require('./services/realm');
|
const realm = require('./services/realm');
|
||||||
const { MessageType } = require('./enums');
|
const { MessageType } = require('./enums');
|
||||||
|
|
||||||
|
process.on('uncaughtException', (e) => {
|
||||||
|
logger.error('Error: ' + e);
|
||||||
|
});
|
||||||
|
|
||||||
// parse config
|
// parse config
|
||||||
let path = config.get('path');
|
let path = config.get('path');
|
||||||
const port = config.get('port');
|
const port = config.get('port');
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
class Client {
|
class Client {
|
||||||
constructor ({ id, token, ip }) {
|
constructor ({ id, token }) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.token = token;
|
this.token = token;
|
||||||
this.ip = ip;
|
|
||||||
this.socket = null;
|
this.socket = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,10 +13,6 @@ class Client {
|
|||||||
return this.token;
|
return this.token;
|
||||||
}
|
}
|
||||||
|
|
||||||
getIp () {
|
|
||||||
return this.ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSocket (socket) {
|
setSocket (socket) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
INVALID_KEY: 'Invalid key provided'
|
|
||||||
};
|
|
@ -2,7 +2,7 @@ const WSS = require('ws').Server;
|
|||||||
const url = require('url');
|
const url = require('url');
|
||||||
const EventEmitter = require('events');
|
const EventEmitter = require('events');
|
||||||
const logger = require('../logger');
|
const logger = require('../logger');
|
||||||
|
const { MessageType, Errors } = require('../../enums');
|
||||||
const config = require('../../../config');
|
const config = require('../../../config');
|
||||||
const realm = require('../realm');
|
const realm = require('../realm');
|
||||||
const Client = require('../../models/client');
|
const Client = require('../../models/client');
|
||||||
@ -12,8 +12,6 @@ class WebSocketServer extends EventEmitter {
|
|||||||
super();
|
super();
|
||||||
this.setMaxListeners(0);
|
this.setMaxListeners(0);
|
||||||
|
|
||||||
this._ips = {};
|
|
||||||
|
|
||||||
let path = config.get('path');
|
let path = config.get('path');
|
||||||
path = path + (path[path.length - 1] !== '/' ? '/' : '') + 'peerjs';
|
path = path + (path[path.length - 1] !== '/' ? '/' : '') + 'peerjs';
|
||||||
|
|
||||||
@ -33,11 +31,11 @@ class WebSocketServer extends EventEmitter {
|
|||||||
const { id, token, key } = query;
|
const { id, token, key } = query;
|
||||||
|
|
||||||
if (!id || !token || !key) {
|
if (!id || !token || !key) {
|
||||||
return this._sendErrorAndClose(socket, 'No id, token, or key supplied to websocket server');
|
return this._sendErrorAndClose(socket, Errors.INVALID_WS_PARAMETERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key !== config.get('key')) {
|
if (key !== config.get('key')) {
|
||||||
return this._sendErrorAndClose(socket, 'Invalid key provided');
|
return this._sendErrorAndClose(socket, Errors.INVALID_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
const client = realm.getClientById(id);
|
const client = realm.getClientById(id);
|
||||||
@ -46,7 +44,7 @@ class WebSocketServer extends EventEmitter {
|
|||||||
if (token !== client.getToken()) {
|
if (token !== client.getToken()) {
|
||||||
// ID-taken, invalid token
|
// ID-taken, invalid token
|
||||||
socket.send(JSON.stringify({
|
socket.send(JSON.stringify({
|
||||||
type: 'ID-TAKEN',
|
type: MessageType.ID_TAKEN,
|
||||||
payload: { msg: 'ID is taken' }
|
payload: { msg: 'ID is taken' }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -66,59 +64,27 @@ class WebSocketServer extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_registerClient ({ socket, id, token }) {
|
_registerClient ({ socket, id, token }) {
|
||||||
const ip = socket.remoteAddress;
|
|
||||||
|
|
||||||
if (!this._ips[ip]) {
|
|
||||||
this._ips[ip] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check concurrent limit
|
// Check concurrent limit
|
||||||
const clientsCount = realm.getClientsIds().length;
|
const clientsCount = realm.getClientsIds().length;
|
||||||
|
|
||||||
if (clientsCount >= config.get('concurrent_limit')) {
|
if (clientsCount >= config.get('concurrent_limit')) {
|
||||||
return this._sendErrorAndClose(socket, 'Server has reached its concurrent user limit');
|
return this._sendErrorAndClose(socket, Errors.CONNECTION_LIMIT_EXCEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
const connectionsPerIP = this._ips[ip];
|
const newClient = new Client({ id, token });
|
||||||
|
|
||||||
if (connectionsPerIP >= config.get('ip_limit')) {
|
|
||||||
return this._sendErrorAndClose(socket, `${ip} has reached its concurrent user limit`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const oldClient = realm.getClientById(id);
|
|
||||||
|
|
||||||
if (oldClient) {
|
|
||||||
return this._sendErrorAndClose(socket, `${id} already registered`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const newClient = new Client({ id, token, ip });
|
|
||||||
realm.setClient(newClient, id);
|
realm.setClient(newClient, id);
|
||||||
socket.send(JSON.stringify({ type: 'OPEN' }));
|
socket.send(JSON.stringify({ type: MessageType.OPEN }));
|
||||||
this._ips[ip]++;
|
|
||||||
this._configureWS(socket, newClient);
|
this._configureWS(socket, newClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
_configureWS (socket, client) {
|
_configureWS (socket, client) {
|
||||||
if (client.socket && socket !== client.socket) {
|
|
||||||
// TODO remove old ip, add new ip
|
|
||||||
}
|
|
||||||
|
|
||||||
client.setSocket(socket);
|
client.setSocket(socket);
|
||||||
|
|
||||||
// Cleanup after a socket closes.
|
// Cleanup after a socket closes.
|
||||||
socket.on('close', () => {
|
socket.on('close', () => {
|
||||||
logger.info('Socket closed:', client.getId());
|
logger.info('Socket closed:', client.getId());
|
||||||
|
|
||||||
const ip = socket.remoteAddress;
|
|
||||||
|
|
||||||
if (this._ips[ip]) {
|
|
||||||
this._ips[ip]--;
|
|
||||||
|
|
||||||
if (this._ips[ip] === 0) {
|
|
||||||
delete this._ips[ip];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (client.socket === socket) {
|
if (client.socket === socket) {
|
||||||
realm.removeClientById(client.getId());
|
realm.removeClientById(client.getId());
|
||||||
this.emit('close', client);
|
this.emit('close', client);
|
||||||
@ -145,7 +111,7 @@ class WebSocketServer extends EventEmitter {
|
|||||||
_sendErrorAndClose (socket, msg) {
|
_sendErrorAndClose (socket, msg) {
|
||||||
socket.send(
|
socket.send(
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
type: 'ERROR',
|
type: MessageType.ERROR,
|
||||||
payload: { msg }
|
payload: { msg }
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user