haraka-plugin-limit
Advanced tools
Comparing version 1.0.0 to 1.0.1
{ | ||
"env": { | ||
"node": true, | ||
"mocha": true, | ||
"es6": true | ||
}, | ||
"extends": "eslint:recommended", | ||
"installedESLint": true, | ||
"root": true, | ||
"plugins": [ | ||
"haraka" | ||
], | ||
"extends": ["eslint:recommended", "plugin:haraka/recommended"], | ||
"rules": { | ||
"comma-dangle": [2, "only-multiline"], | ||
"dot-notation": 2, | ||
"indent": [2, 4, {"SwitchCase": 1}], | ||
"one-var": [2, "never"], | ||
"no-trailing-spaces": [2, { "skipBlankLines": false }], | ||
"keyword-spacing": [2, { | ||
"before": true, | ||
"after": true | ||
}], | ||
"no-delete-var": 2, | ||
"no-empty": ["error", { "allowEmptyCatch": true }], | ||
"no-label-var": 2, | ||
"no-shadow": 2, | ||
"no-unused-vars": [ 1, { "args": "none" }], | ||
"no-console": 0 | ||
} | ||
} |
241
index.js
@@ -16,5 +16,5 @@ 'use strict'; | ||
if (plugin.cfg.concurrency) { | ||
plugin.register_hook('connect_init', 'incr_concurrency'); | ||
plugin.register_hook('connect_init', 'conn_concur_incr'); | ||
plugin.register_hook('connect', 'check_concurrency'); | ||
plugin.register_hook('disconnect', 'decr_concurrency'); | ||
plugin.register_hook('disconnect', 'conn_concur_decr'); | ||
} | ||
@@ -36,16 +36,25 @@ | ||
plugin.register_hook('connect', 'rate_rcpt_host'); | ||
plugin.register_hook('connect', 'rate_conn'); | ||
if (plugin.cfg.rate_conn) { | ||
plugin.register_hook('connect_init', 'rate_conn_incr'); | ||
plugin.register_hook('connect', 'rate_conn_enforce'); | ||
} | ||
if (plugin.cfg.rate_rcpt_host) { | ||
plugin.register_hook('connect', 'rate_rcpt_host_enforce'); | ||
plugin.register_hook('rcpt', 'rate_rcpt_host_incr'); | ||
} | ||
if (plugin.cfg.rate_rcpt_sender) { | ||
plugin.register_hook('rcpt', 'rate_rcpt_sender'); | ||
} | ||
if (plugin.cfg.rate_rcpt_null) { | ||
plugin.register_hook('rcpt', 'rate_rcpt_null'); | ||
} | ||
if (plugin.cfg.rate_rcpt) { | ||
plugin.register_hook('rcpt', 'rate_rcpt'); | ||
} | ||
['rcpt', 'rcpt_ok'].forEach(function (h) { | ||
plugin.register_hook(h, 'rate_rcpt_sender'); | ||
plugin.register_hook(h, 'rate_rcpt_null'); | ||
plugin.register_hook(h, 'rate_rcpt'); | ||
}); | ||
if (plugin.cfg.outbound.enabled) { | ||
plugin.register_hook('send_email', 'increment_outbound_limit'); | ||
plugin.register_hook('delivered', 'decrement_outbound_limit'); | ||
plugin.register_hook('deferred', 'decrement_outbound_limit'); | ||
plugin.register_hook('bounce', 'decrement_outbound_limit'); | ||
plugin.register_hook('send_email', 'outbound_increment'); | ||
plugin.register_hook('delivered', 'outbound_decrement'); | ||
plugin.register_hook('deferred', 'outbound_decrement'); | ||
plugin.register_hook('bounce', 'outbound_decrement'); | ||
} | ||
@@ -76,3 +85,3 @@ }; | ||
exports.max_unrecognized_commands = function(next, connection, cmd) { | ||
exports.max_unrecognized_commands = function (next, connection, cmd) { | ||
var plugin = this; | ||
@@ -91,3 +100,3 @@ if (!plugin.cfg.unrecognized_commands) return next(); | ||
connection.results.add(plugin, {fail: 'unrec_cmds.max'}); | ||
connection.results.add(plugin, { fail: 'unrec_cmds.max' }); | ||
plugin.penalize(connection, true, 'Too many unrecognized commands', next); | ||
@@ -113,3 +122,3 @@ }; | ||
var max = plugin.get_recipient_limit(connection); | ||
var max = plugin.get_limit('recipients', connection); | ||
if (!max || isNaN(max)) return next(); | ||
@@ -125,13 +134,10 @@ | ||
exports.get_recipient_limit = function (connection) { | ||
exports.get_history_limit = function (type, connection) { | ||
var plugin = this; | ||
if (connection.relaying && plugin.cfg.recipients.max_relaying) { | ||
return plugin.cfg.recipients.max_relaying; | ||
} | ||
var history_cfg = type + '_history'; | ||
if (!plugin.cfg[history_cfg]) return; | ||
var history_plugin = plugin.cfg.concurrency.history; | ||
if (!history_plugin) { | ||
return plugin.cfg.recipients.max; | ||
} | ||
var history_plugin = plugin.cfg[history_cfg].plugin; | ||
if (!history_plugin) return; | ||
@@ -142,9 +148,9 @@ var results = connection.results.get(history_plugin); | ||
' disabling history due to misconfiguration'); | ||
delete plugin.cfg.recipients.history; | ||
return plugin.cfg.recipients.max; | ||
delete plugin.cfg[history_cfg]; | ||
return; | ||
} | ||
if (results.history === undefined) { | ||
connection.logerror(plugin, 'no history from : ' + history_plugin); | ||
return plugin.cfg.recipients.max; | ||
connection.logdebug(plugin, 'no history from : ' + history_plugin); | ||
return; | ||
} | ||
@@ -154,18 +160,36 @@ | ||
connection.logdebug(plugin, 'history: ' + history); | ||
if (isNaN(history)) { history = 0; } | ||
if (isNaN(history)) return; | ||
if (history > 0) return plugin.cfg.recipients.history_good || 50; | ||
if (history < 0) return plugin.cfg.recipients.history_bad || 2; | ||
return plugin.cfg.recipients.history_none || 15; | ||
if (history > 0) return plugin.cfg[history_cfg].good; | ||
if (history < 0) return plugin.cfg[history_cfg].bad; | ||
return plugin.cfg[history_cfg].none; | ||
}; | ||
exports.incr_concurrency = function (next, connection) { | ||
exports.get_limit = function (type, connection) { | ||
var plugin = this; | ||
if (type === 'recipients') { | ||
if (connection.relaying && plugin.cfg.recipients.max_relaying) { | ||
return plugin.cfg.recipients.max_relaying; | ||
} | ||
} | ||
if (plugin.cfg[type + '_history']) { | ||
var history = plugin.get_history_limit(type, connection); | ||
if (history) return history; | ||
} | ||
return plugin.cfg[type].max || plugin.cfg[type].default; | ||
}; | ||
exports.conn_concur_incr = function (next, connection) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
if (!plugin.cfg.concurrency) return next(); | ||
var dbkey = plugin.get_key(connection); | ||
var dbkey = plugin.get_concurrency_key(connection); | ||
plugin.db.incr(dbkey, function (err, count) { | ||
if (err) { | ||
connection.results.add(plugin, { err: 'incr_concurrency:' + err }); | ||
connection.results.add(plugin, { err: 'conn_concur_incr:' + err }); | ||
return next(); | ||
@@ -175,3 +199,3 @@ } | ||
if (isNaN(count)) { | ||
connection.results.add(plugin, {err: 'incr_concurrency got isNaN'}); | ||
connection.results.add(plugin, {err: 'conn_concur_incr got isNaN'}); | ||
return next(); | ||
@@ -190,3 +214,3 @@ } | ||
plugin.db.expire(dbkey, 120); // 2 minute lifetime | ||
plugin.db.expire(dbkey, 3 * 60); // 3 minute lifetime | ||
next(); | ||
@@ -196,3 +220,3 @@ }); | ||
exports.get_key = function (connection) { | ||
exports.get_concurrency_key = function (connection) { | ||
return 'concurrency|' + connection.remote.ip; | ||
@@ -204,3 +228,3 @@ }; | ||
var max = plugin.get_concurrency_limit(connection); | ||
var max = plugin.get_limit('concurrency', connection); | ||
if (!max || isNaN(max)) { | ||
@@ -226,32 +250,2 @@ connection.results.add(plugin, {err: "concurrency: no limit?!"}); | ||
exports.get_concurrency_limit = function (connection) { | ||
var plugin = this; | ||
var history_plugin = plugin.cfg.concurrency.history; | ||
if (!history_plugin) { | ||
return plugin.cfg.concurrency.max; | ||
} | ||
var results = connection.results.get(history_plugin); | ||
if (!results) { | ||
connection.logerror(plugin, 'no ' + history_plugin + ' results,' + | ||
' disabling history due to misconfiguration'); | ||
delete plugin.cfg.concurrency.history; | ||
return plugin.cfg.concurrency.max; | ||
} | ||
if (results.history === undefined) { | ||
connection.loginfo(plugin, 'no IP history from : ' + history_plugin); | ||
return plugin.cfg.concurrency.max; | ||
} | ||
var history = parseFloat(results.history); | ||
connection.logdebug(plugin, 'history: ' + history); | ||
if (isNaN(history)) { history = 0; } | ||
if (history < 0) { return plugin.cfg.concurrency.history_bad || 1; } | ||
if (history > 0) { return plugin.cfg.concurrency.history_good || 5; } | ||
return plugin.cfg.concurrency.history_none || 3; | ||
}; | ||
exports.penalize = function (connection, disconnect, msg, next) { | ||
@@ -274,9 +268,10 @@ var plugin = this; | ||
exports.decr_concurrency = function (next, connection) { | ||
exports.conn_concur_decr = function (next, connection) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
if (!plugin.cfg.concurrency) return next(); | ||
var dbkey = plugin.get_key(connection); | ||
var dbkey = plugin.get_concurrency_key(connection); | ||
plugin.db.incrby(dbkey, -1, function (err, concurrent) { | ||
if (err) connection.results.add(plugin, { err: 'decr_concurrency:' + err }) | ||
if (err) connection.results.add(plugin, { err: 'conn_concur_decr:' + err }) | ||
return next(); | ||
@@ -286,3 +281,3 @@ }); | ||
exports.lookup_host_key = function (type, remote, cb) { | ||
exports.get_host_key = function (type, connection, cb) { | ||
var plugin = this; | ||
@@ -294,3 +289,3 @@ if (!plugin.cfg[type]) { | ||
try { | ||
var ip = ipaddr.parse(remote.ip); | ||
var ip = ipaddr.parse(connection.remote.ip); | ||
if (ip.kind === 'ipv6') { | ||
@@ -317,4 +312,4 @@ ip = ipaddr.toNormalizedString(); | ||
// rDNS | ||
if (remote.host) { | ||
var rdns_array = remote.host.toLowerCase().split('.'); | ||
if (connection.remote.host) { | ||
var rdns_array = connection.remote.host.toLowerCase().split('.'); | ||
while (rdns_array.length) { | ||
@@ -329,2 +324,7 @@ var part2 = rdns_array.join('.'); | ||
if (plugin.cfg[type + '_history']) { | ||
var history = plugin.get_history_limit(type, connection); | ||
if (history) return cb(null, ip, history); | ||
} | ||
// Custom Default | ||
@@ -402,4 +402,4 @@ if (plugin.cfg[type].default) { | ||
var match = /^([\d]+)/.exec(value); | ||
if (!match) return; | ||
return match[1]; | ||
if (!match) return 0; | ||
return parseInt(match[1], 10); | ||
} | ||
@@ -417,2 +417,3 @@ | ||
if (!key || !value) return cb(); | ||
if (!plugin.db) return cb(); | ||
@@ -432,12 +433,26 @@ var limit = getLimit(value); | ||
if (newval === 1) plugin.db.expire(key, ttl); | ||
cb(err, parseInt(newval) > parseInt(limit)); // boolean true/false | ||
cb(err, parseInt(newval, 10) > limit); // boolean true/false | ||
}); | ||
}; | ||
exports.rate_rcpt_host = function (next, connection) { | ||
exports.rate_rcpt_host_incr = function (next, connection) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
if (!plugin.cfg.rate_rcpt_host) return next(); | ||
plugin.get_host_key('rate_rcpt_host', connection, function (err, key, value) { | ||
if (!key || !value) return next(); | ||
plugin.lookup_host_key('rate_rcpt_host', connection.remote, function (err, key, value) { | ||
key = 'rate_rcpt_host:' + key; | ||
plugin.db.incr(key, function (err2, newval) { | ||
if (newval === 1) plugin.db.expire(key, getTTL(value)); | ||
next(); | ||
}); | ||
}); | ||
}; | ||
exports.rate_rcpt_host_enforce = function (next, connection) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
plugin.get_host_key('rate_rcpt_host', connection, function (err, key, value) { | ||
if (err) { | ||
@@ -451,3 +466,3 @@ connection.results.add(plugin, { err: 'rate_rcpt_host:' + err }); | ||
var match = /^(\d+)/.exec(value); | ||
var limit = match[0]; | ||
var limit = parseInt(match[0], 10); | ||
if (!limit) return next(); | ||
@@ -463,8 +478,9 @@ | ||
connection.results.add(plugin, { | ||
rate_rcpt_host: key + ':' + result + '/' + limit | ||
rate_rcpt_host: key + ':' + result + ':' + value | ||
}); | ||
if (result <= limit) return next(); | ||
connection.results.add(plugin, { fail: 'rate_rcpt_host' }); | ||
plugin.penalize(connection, false, 'connection rate limit exceeded', next); | ||
plugin.penalize(connection, false, 'recipient rate limit exceeded', next); | ||
}); | ||
@@ -474,6 +490,23 @@ }); | ||
exports.rate_conn = function (next, connection) { | ||
exports.rate_conn_incr = function (next, connection) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
plugin.lookup_host_key('rate_conn', connection.remote, function (err, key, value) { | ||
plugin.get_host_key('rate_conn', connection, function (err, key, value) { | ||
if (!key || !value) return next(); | ||
key = 'rate_conn:' + key; | ||
plugin.db.hincrby(key, + new Date(), 1, function (err2, newval) { | ||
// extend key expiration on every new connection | ||
plugin.db.expire(key, getTTL(value) * 2); | ||
next(); | ||
}); | ||
}); | ||
} | ||
exports.rate_conn_enforce = function (next, connection) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
plugin.get_host_key('rate_conn', connection, function (err, key, value) { | ||
if (err) { | ||
@@ -484,8 +517,6 @@ connection.results.add(plugin, { err: 'rate_conn:' + err }); | ||
if (value === 0) return next(); // limits disabled for host | ||
if (!key || !value) return next(); | ||
var limit = getLimit(value); | ||
var ttl = getTTL(value); | ||
if (!limit || ! ttl) { | ||
if (!limit) { | ||
connection.results.add(plugin, { err: 'rate_conn:syntax:' + value }); | ||
@@ -495,3 +526,3 @@ return next(); | ||
plugin.db.incr('rate_conn:' + key, function (err2, newval) { | ||
plugin.db.hgetall('rate_conn:' + key, function (err2, tstamps) { | ||
if (err2) { | ||
@@ -502,7 +533,14 @@ connection.results.add(plugin, { err: 'rate_conn:' + err }); | ||
if (newval === 1) plugin.db.expire('rate_conn:' + key, ttl); | ||
var d = new Date(); | ||
d.setMinutes(d.getMinutes() - (getTTL(value) / 60)); | ||
var periodStartTs = + d; // date as integer | ||
connection.results.add(plugin, { rate_conn: newval + '/' + limit}); | ||
var connections_in_ttl_period = 0; | ||
Object.keys(tstamps).forEach(function (ts) { | ||
if (parseInt(ts, 10) < periodStartTs) return; // older than ttl | ||
connections_in_ttl_period = connections_in_ttl_period + parseInt(tstamps[ts], 10); | ||
}) | ||
connection.results.add(plugin, { rate_conn: connections_in_ttl_period + ':' + value}); | ||
if (parseInt(newval) <= parseInt(limit)) return next(); | ||
if (connections_in_ttl_period <= limit) return next(); | ||
@@ -592,8 +630,9 @@ connection.results.add(plugin, { fail: 'rate_conn' }); | ||
exports.increment_outbound_limit = function (next, hmail) { | ||
exports.outbound_increment = function (next, hmail) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
plugin.db.hincrby(getOutKey(hmail), 'TOTAL', 1, function (err, count) { | ||
if (err) { | ||
plugin.logerror("increment_outbound_limit: " + err); | ||
plugin.logerror("outbound_increment: " + err); | ||
return next(); // just deliver | ||
@@ -614,5 +653,7 @@ } | ||
exports.decrement_outbound_limit = function (next, hmail) { | ||
this.db.hincrby(getOutKey(hmail), 'TOTAL', -1); | ||
exports.outbound_decrement = function (next, hmail) { | ||
var plugin = this; | ||
if (!plugin.db) return next(); | ||
plugin.db.hincrby(getOutKey(hmail), 'TOTAL', -1); | ||
return next(); | ||
} | ||
} |
{ | ||
"name": "haraka-plugin-limit", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "enforce various types of limits on remote MTAs", | ||
@@ -16,5 +16,6 @@ "main": "limit.js", | ||
"devDependencies": { | ||
"address-rfc2821": "^1.0.1", | ||
"address-rfc2821": "*", | ||
"eslint": "^3.14.1", | ||
"haraka-test-fixtures": "^1.0.13", | ||
"eslint-plugin-haraka": "*", | ||
"haraka-test-fixtures": "*", | ||
"nodeunit": "^0.10.2" | ||
@@ -21,0 +22,0 @@ }, |
@@ -218,2 +218,12 @@ # limit | ||
## CAUTION | ||
Applying strict connection and rate limits is an effective way to reduce spam delivery. It's also an effective way to inflict a stampeding herd on your mail server. When spam/malware is delivered by MTAs that have queue retries, if you disconnect early (which the rate limits do) with a 400 series code (a sane default), the remote is likely to try again. And again. And again. And again. This can cause an obscene rise in the number of connections your mail server handles. Plan a strategy for handling that. | ||
## Strategies | ||
- Don't enforce limits early. I use karma and wait until DATA before disconnecting. By then, the score of the connection is determinate and I can return a 500 series code telling the remote not to try again. | ||
- enforce rate limits with your firewall instead | ||
### TODO | ||
@@ -220,0 +230,0 @@ |
'use strict'; | ||
var path = require('path'); | ||
var fixtures = require('haraka-test-fixtures'); | ||
@@ -7,2 +8,3 @@ | ||
this.plugin = new fixtures.plugin('index'); | ||
this.plugin.config = this.plugin.config.module_config(path.resolve('test')); | ||
done(); | ||
@@ -12,8 +14,9 @@ }; | ||
var default_config = { | ||
main: {}, | ||
main: { tarpit_delay: 0 }, | ||
outbound: { enabled: false }, | ||
redis: { db: 4, host: '127.0.0.1', port: '6379' }, | ||
concurrency: { plugin: 'karma', good: 10, bad: 1, none: 2 }, | ||
recipients: {}, | ||
unrecognized_commands: {}, | ||
errors: {}, | ||
redis: { db: 4, host: '127.0.0.1', port: '6379' }, | ||
concurrency: { }, | ||
rate_conn: { '127': 0, default: 5 }, | ||
@@ -23,4 +26,3 @@ rate_rcpt_host: { '127': 0, default: '50/5m' }, | ||
rate_rcpt: { '127': 0, default: '50/5m' }, | ||
rate_rcpt_null: { default: 1 }, | ||
outbound: { enabled: false } | ||
rate_rcpt_null: { default: 1 } | ||
}; | ||
@@ -32,3 +34,3 @@ | ||
test.expect(1); | ||
// gotta inhert b/c config loader merges in defaults from redis.ini | ||
// gotta inherit b/c config loader merges in defaults from redis.ini | ||
this.plugin.inherits('haraka-plugin-redis'); | ||
@@ -45,2 +47,3 @@ this.plugin.load_limit_ini(); | ||
}, | ||
}; |
'use strict'; | ||
var path = require('path'); | ||
var constants = require('haraka-constants'); | ||
@@ -9,7 +11,5 @@ var fixtures = require('haraka-test-fixtures'); | ||
this.plugin = new fixtures.plugin('index'); | ||
this.plugin.config = this.plugin.config.module_config(path.resolve('test')); | ||
this.plugin.cfg = { main: {} }; | ||
this.connection = new fixtures.connection.createConnection(); | ||
this.connection.results = new fixtures.result_store(this.connection); | ||
this.connection.transaction = new fixtures.transaction.createTransaction(); | ||
@@ -21,28 +21,2 @@ | ||
exports.inheritance = { | ||
setUp : function (done) { | ||
this.plugin = new fixtures.plugin('index'); | ||
done(); | ||
}, | ||
'inherits redis': function (test) { | ||
test.expect(1); | ||
this.plugin.inherits('haraka-plugin-redis'); | ||
test.equal(typeof this.plugin.load_redis_ini, 'function'); | ||
test.done(); | ||
}, | ||
'can call parent functions': function (test) { | ||
test.expect(1); | ||
this.plugin.inherits('haraka-plugin-redis'); | ||
this.plugin.load_redis_ini(); | ||
test.ok(this.plugin.redisCfg); // loaded config | ||
test.done(); | ||
}, | ||
'register': function (test) { | ||
test.expect(1); | ||
this.plugin.register(); | ||
test.ok(this.plugin.cfg); // loaded config | ||
test.done(); | ||
}, | ||
}; | ||
exports.max_errors = { | ||
@@ -49,0 +23,0 @@ setUp : _set_up, |
@@ -20,7 +20,7 @@ 'use strict'; | ||
exports.increment_outbound_limit = { | ||
exports.outbound_increment = { | ||
setUp : _set_up, | ||
'no limit, no delay': function (test) { | ||
test.expect(2); | ||
this.plugin.increment_outbound_limit(function (code, msg) { | ||
this.plugin.outbound_increment(function (code, msg) { | ||
test.equal(code, undefined); | ||
@@ -37,3 +37,3 @@ test.equal(msg, undefined); | ||
self.plugin.db.hset('outbound-rate:slow.test.com', 'TOTAL', 4, function () { | ||
self.plugin.increment_outbound_limit(function (code, delay) { | ||
self.plugin.outbound_increment(function (code, delay) { | ||
test.equal(code, constants.delay); | ||
@@ -40,0 +40,0 @@ test.equal(delay, 30); |
'use strict'; | ||
var path = require('path'); | ||
var Address = require('address-rfc2821').Address; | ||
@@ -7,3 +9,3 @@ var constants = require('haraka-constants'); | ||
exports.lookup_host_key = { | ||
exports.get_host_key = { | ||
setUp : function (done) { | ||
@@ -20,3 +22,3 @@ this.plugin = new fixtures.plugin('rate_limit'); | ||
test.expect(3); | ||
this.plugin.lookup_host_key('rate_conn', this.connection.remote, function (err, ip, limit) { | ||
this.plugin.get_host_key('rate_conn', this.connection, function (err, ip, limit) { | ||
test.equal(err, undefined); | ||
@@ -30,3 +32,3 @@ test.equal(ip, '1.2.3.4'); | ||
test.expect(3); | ||
this.plugin.lookup_host_key('rate_rcpt_host', this.connection.remote, function (err, ip, limit) { | ||
this.plugin.get_host_key('rate_rcpt_host', this.connection, function (err, ip, limit) { | ||
test.equal(err, undefined); | ||
@@ -110,2 +112,4 @@ test.equal(ip, '1.2.3.4'); | ||
this.plugin = new fixtures.plugin('rate_limit'); | ||
this.plugin.config = this.plugin.config.module_config(path.resolve('test')); | ||
this.connection = new fixtures.connection.createConnection(); | ||
@@ -124,21 +128,49 @@ this.connection.remote.ip = '1.2.3.4'; | ||
test.expect(3); | ||
this.plugin.rate_conn(function (code, msg) { | ||
var plugin = this.plugin; | ||
var connection = this.connection; | ||
var rc = this.connection.results.get(this.plugin.name); | ||
test.ok(rc.rate_conn); | ||
plugin.rate_conn_incr(function () { | ||
plugin.rate_conn_enforce(function (code, msg) { | ||
var rc = connection.results.get(plugin.name); | ||
test.ok(rc.rate_conn); | ||
var match = /([\d]+)\/([\d]+)$/.exec(rc.rate_conn); // 1/5 | ||
var match = /([\d]+):(.*)$/.exec(rc.rate_conn); // 1/5 | ||
if (parseInt(match[1]) <= parseInt(match[2])) { | ||
test.equal(code, undefined); | ||
test.equal(msg, undefined); | ||
} | ||
else { | ||
test.equal(code, constants.DENYSOFTDISCONNECT); | ||
test.equal(msg, 'connection rate limit exceeded'); | ||
} | ||
test.done(); | ||
}.bind(this), | ||
this.connection); | ||
if (parseInt(match[1]) <= parseInt(match[2])) { | ||
test.equal(code, undefined); | ||
test.equal(msg, undefined); | ||
} | ||
else { | ||
test.equal(code, constants.DENYSOFTDISCONNECT); | ||
test.equal(msg, 'connection rate limit exceeded'); | ||
} | ||
test.done(); | ||
}.bind(this), | ||
connection); | ||
}, connection); | ||
}, | ||
'defined limit' : function (test) { | ||
test.expect(3); | ||
var plugin = this.plugin; | ||
var connection = this.connection; | ||
plugin.cfg.rate_conn['1.2.3.4'] = '1/5m'; | ||
plugin.rate_conn_incr(function () { | ||
plugin.rate_conn_enforce(function (code, msg) { | ||
var rc = connection.results.get(plugin.name); | ||
test.ok(rc.rate_conn); | ||
var match = /^([\d]+):(.*)$/.exec(rc.rate_conn); // 1/5m | ||
if (parseInt(match[1]) <= parseInt(match[2])) { | ||
test.equal(code, undefined); | ||
test.equal(msg, undefined); | ||
} | ||
else { | ||
test.equal(code, constants.DENYSOFTDISCONNECT); | ||
test.equal(msg, 'connection rate limit exceeded'); | ||
} | ||
test.done(); | ||
}.bind(this), | ||
connection); | ||
}, connection); | ||
}, | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49706
18
945
247
5