remove ips limit

refactoring errors
This commit is contained in:
afrokick 2019-04-01 15:41:09 +03:00
parent 5d40faf39e
commit 6f509b848c
7 changed files with 28 additions and 64 deletions

View File

@ -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',

View File

@ -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();

View File

@ -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'
}; };

View File

@ -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');

View File

@ -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;
} }

View File

@ -1,3 +0,0 @@
module.exports = {
INVALID_KEY: 'Invalid key provided'
};

View File

@ -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 }
}) })
); );