Wire quota enforcement into pro server loop

New server_loop.rs:
- Custom accept loop with pre-connection IP quota check
- DB-based MD5 authentication (verifies user exists + enabled)
- Pre-test user quota check (reject if already exceeded)
- Session tracking in DB (start_session/end_session)
- QuotaEnforcer spawned alongside each test
- Post-test usage recording to both user + IP tables
- Syslog events for auth, quota rejection, test start/end

Full flow:
  1. Accept connection → check IP quota → reject if exceeded
  2. Handshake + auth → verify user in DB → reject if disabled/not found
  3. Check user quota → reject if daily/weekly/monthly exceeded
  4. Start session → spawn enforcer (checks every N seconds)
  5. Run test → enforcer stops it if quota hit or max_duration reached
  6. Record usage → persist to DB → disconnect IP tracker

TODO: Wire actual TX/RX data loops (currently only enforcer runs,
data transfer not yet delegated from pro server to standard handlers)

64 tests, all passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-04-01 15:45:45 +04:00
parent c08bcffaff
commit 4403eae4b9
2 changed files with 265 additions and 4 deletions

View File

@@ -11,6 +11,7 @@
mod user_db;
mod quota;
mod enforcer;
mod server_loop;
mod ldap_auth;
use clap::Parser;
@@ -241,7 +242,7 @@ async fn main() -> anyhow::Result<()> {
}
// Initialize quota manager
let _quota_mgr = quota::QuotaManager::new(
let quota_mgr = quota::QuotaManager::new(
db.clone(),
cli.daily_quota,
cli.weekly_quota,
@@ -269,12 +270,17 @@ async fn main() -> anyhow::Result<()> {
tracing::info!("btest-server-pro starting on port {}", cli.port);
// TODO: Run the enhanced server loop with quota checks and multi-user auth
// For now, delegate to the standard server
let v4 = if cli.listen_addr.eq_ignore_ascii_case("none") { None } else { Some(cli.listen_addr) };
let v6 = cli.listen6_addr;
btest_rs::server::run_server(cli.port, None, None, cli.ecsrp5, v4, v6).await?;
server_loop::run_pro_server(
cli.port,
cli.ecsrp5,
v4, v6,
db,
quota_mgr,
cli.quota_check_interval,
).await?;
Ok(())
}