Module agora.common.BanManager

Contains code to support temporarily banning from communicating with specific addressses which may belong to badly-behaving nodes.

Example

class UnitBanMan : BanManager
{
    TimePoint time;
    this (ManagedDatabase db) { super(Config(10, 1.days), null, db); }
    protected override TimePoint getCurTime () const { return this.time; }
}

const node1 = Address("agora://node-1");
const node2 = Address("agora://node-2");
const whitelistNode = Address("agora://whitelist-node");

auto db = new ManagedDatabase(":memory:");
auto banman = new UnitBanMan(db);
banman.whitelist(whitelistNode);
assert(db.execute("select url from whitelisted where url = ?", whitelistNode)
    .oneValue!string == whitelistNode.toString());
foreach (idx; 0 .. 9)
{
    banman.onFailedRequest(node1);
    banman.onFailedRequest(whitelistNode);
    assert(banman.url_failures[node1].fail_count == idx + 1);
    assert(!banman.isBanned(node1));
}

banman.onFailedRequest(node1);
assert(banman.url_failures[node1].fail_count == 0);  // reset counter on ban
assert(banman.isBanned(node1));
assert(banman.url_failures[node1].banned_until == 86400);  // banned until "next day"
assert(db.execute("select until from banned where url = ?", node1).oneValue!ulong == 86400);

banman.onFailedRequest(whitelistNode);
assert(!banman.isBanned(whitelistNode));

// stop counting failed requests during the ban
banman.onFailedRequest(node1);
assert(banman.url_failures[node1].fail_count == 0);

banman.time = 86401;  // "next day"
assert(!banman.isBanned(node1));

// banUntil
banman.banUntil(node1, TimePoint(86500));
banman.time = 86499;
assert(banman.isBanned(node1));
banman.time = 86500;
assert(!banman.isBanned(node1));

// banFor
banman.banFor(node1, 10.seconds);
banman.time = 86509;
assert(banman.isBanned(node1));
banman.time++;
assert(!banman.isBanned(node1));

banman.time = 0;
banman.ban(node2);  // use default ban time
assert(banman.url_failures[node2].banned_until == 86400);

// test loading from db
auto banman2 = new UnitBanMan(db);
assert(banman2.isBanned(node2));
assert(banman2.isWhitelisted(whitelistNode));

// unwhitelist
banman.unwhitelist(whitelistNode);
assert(!banman.isWhitelisted(whitelistNode));

Classes

NameDescription
BanManager