v1.1.7 - Add per-connection database query tracking for abuse detection

Implemented comprehensive database query tracking to identify clients causing
high CPU usage through excessive database queries. The relay now tracks and
displays query statistics per WebSocket connection in the admin UI.

Features Added:
- Track db_queries_executed and db_rows_returned per connection
- Calculate query rate (queries/minute) and row rate (rows/minute)
- Display stats in admin UI grouped by IP address and WebSocket
- Show: IP, Subscriptions, Queries, Rows, Query Rate, Duration

Implementation:
- Added tracking fields to per_session_data structure
- Increment counters in handle_req_message() and handle_count_message()
- Extract stats from pss in query_subscription_details()
- Updated admin UI to display IP address and query metrics

Use Case:
Admins can now identify abusive clients by monitoring:
- High query rates (>50 queries/min indicates polling abuse)
- High row counts (>10K rows/min indicates broad filter abuse)
- Query patterns (high queries + low rows = targeted, high both = crawler)

This enables informed decisions about which IPs to blacklist based on
actual resource consumption rather than just connection count.
This commit is contained in:
Your Name
2026-02-01 16:26:37 -04:00
parent 4cc2d2376e
commit c0051b22be
8 changed files with 80 additions and 9 deletions

View File

@@ -391,6 +391,11 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
memset(pss, 0, sizeof(*pss));
pthread_mutex_init(&pss->session_lock, NULL);
// Initialize database query tracking
pss->db_queries_executed = 0;
pss->db_rows_returned = 0;
pss->query_tracking_start = time(NULL);
// Get real client IP address
char client_ip[CLIENT_IP_MAX_LENGTH];
memset(client_ip, 0, sizeof(client_ip));
@@ -2429,7 +2434,7 @@ int process_dm_stats_command(cJSON* dm_event, char* error_message, size_t error_
// Handle NIP-45 COUNT message
int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, struct per_session_data *pss) {
(void)pss; // Suppress unused parameter warning
// pss is now used for query tracking, so remove unused warning suppression
if (!cJSON_IsArray(filters)) {
DEBUG_ERROR("COUNT filters is not an array");