From 73cfda12bb7235fd99dc2d72521211ef6f78b014 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 28 Oct 2010 11:42:22 -0700 Subject: [PATCH] Abstract out a Server.prototype.pause method --- benchmark/idle_server.js | 2 +- lib/net.js | 39 ++++++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/benchmark/idle_server.js b/benchmark/idle_server.js index 17d11a1..a4c70d7 100644 --- a/benchmark/idle_server.js +++ b/benchmark/idle_server.js @@ -11,7 +11,7 @@ server = net.Server(function (socket) { }); -server.maxConnections = 128; +//server.maxConnections = 128; server.listen(9000); diff --git a/lib/net.js b/lib/net.js index fcb0750..ca5dade 100644 --- a/lib/net.js +++ b/lib/net.js @@ -960,7 +960,7 @@ function Server (/* [ options, ] listener */) { // Just in case we don't have a dummy fd. getDummyFD(); - if (self._acceptTimer) { + if (self._pauseTimer) { // Somehow the watcher got started again. Need to wait until // the timer finishes. self.watcher.stop(); @@ -1022,6 +1022,28 @@ exports.createServer = function () { }; +// Just stop trying to accepting connections for a while. +// Useful for throttling against DoS attacks. +Server.prototype.pause = function (msecs) { + // We're already paused. + if (this._pauseTimer) return; + + var self = this; + msecs = msecs || 1000; + + this.watcher.stop(); + + // Wait a second before accepting more. + this._pauseTimer = setTimeout(function () { + // Our fd should still be there. If someone calls server.close() then + // the pauseTimer should be cleared. + assert(parseInt(self.fd) >= 0); + self._pauseTimer = null; + self.watcher.start(); + }, msecs); +}; + + Server.prototype._rejectPending = function () { var self = this; var acceptCount = 0; @@ -1034,14 +1056,7 @@ Server.prototype._rejectPending = function () { // Don't become DoS'd by incoming requests if (++acceptCount > 50) { - assert(!this._acceptTimer); - this.watcher.stop(); - // Wait a second before accepting more. - this._acceptTimer = setTimeout(function () { - assert(parseInt(self.fd) >= 0); - self._acceptTimer = null; - self.watcher.start(); - }, 1000); + this.pause(); return; } } @@ -1174,6 +1189,11 @@ Server.prototype.close = function () { close(self.fd); self.fd = null; + if (self._pauseTimer) { + clearTimeout(self._pauseTimer); + self._pauseTimer = null; + } + if (self.type === "unix") { fs.unlink(self.path, function () { self.emit("close"); @@ -1183,6 +1203,7 @@ Server.prototype.close = function () { } }; + var dummyFD = null; var lastEMFILEWarning = 0; // Ensures to have at least on free file-descriptor free. -- 2.7.4