feat: disconnect passive server after timeout

If no client connects within 30 seconds of requesting, close the server.
This prevents multiple servers from being created and never closing.
This commit is contained in:
Tyler Stewart
2019-07-19 16:27:24 -06:00
parent 16dbc7895c
commit b1fe56826c

View File

@@ -6,6 +6,8 @@ const Promise = require('bluebird');
const Connector = require('./base'); const Connector = require('./base');
const errors = require('../errors'); const errors = require('../errors');
const CONNECT_TIMEOUT = 30 * 1000;
class Passive extends Connector { class Passive extends Connector {
constructor(connection) { constructor(connection) {
super(connection); super(connection);
@@ -30,6 +32,9 @@ class Passive extends Connector {
this.closeServer(); this.closeServer();
return this.server.getNextPasvPort() return this.server.getNextPasvPort()
.then((port) => { .then((port) => {
this.dataSocket = null;
let idleServerTimeout;
const connectionHandler = (socket) => { const connectionHandler = (socket) => {
if (!ip.isEqual(this.connection.commandSocket.remoteAddress, socket.remoteAddress)) { if (!ip.isEqual(this.connection.commandSocket.remoteAddress, socket.remoteAddress)) {
this.log.error({ this.log.error({
@@ -41,6 +46,8 @@ class Passive extends Connector {
return this.connection.reply(550, 'Remote addresses do not match') return this.connection.reply(550, 'Remote addresses do not match')
.finally(() => this.connection.close()); .finally(() => this.connection.close());
} }
clearTimeout(idleServerTimeout);
this.log.trace({port, remoteAddress: socket.remoteAddress}, 'Passive connection fulfilled.'); this.log.trace({port, remoteAddress: socket.remoteAddress}, 'Passive connection fulfilled.');
this.dataSocket = socket; this.dataSocket = socket;
@@ -52,8 +59,6 @@ class Passive extends Connector {
} }
}; };
this.dataSocket = null;
const serverOptions = Object.assign({}, this.connection.secure ? this.server.options.tls : {}, {pauseOnConnect: true}); const serverOptions = Object.assign({}, this.connection.secure ? this.server.options.tls : {}, {pauseOnConnect: true});
this.dataServer = (this.connection.secure ? tls : net).createServer(serverOptions, connectionHandler); this.dataServer = (this.connection.secure ? tls : net).createServer(serverOptions, connectionHandler);
this.dataServer.maxConnections = 1; this.dataServer.maxConnections = 1;
@@ -74,6 +79,8 @@ class Passive extends Connector {
this.dataServer.listen(port, this.server.url.hostname, (err) => { this.dataServer.listen(port, this.server.url.hostname, (err) => {
if (err) reject(err); if (err) reject(err);
else { else {
idleServerTimeout = setTimeout(() => this.closeServer(), CONNECT_TIMEOUT);
this.log.debug({port}, 'Passive connection listening'); this.log.debug({port}, 'Passive connection listening');
resolve(this.dataServer); resolve(this.dataServer);
} }