Compare commits

..
3 Commits
39 changed files with 10628 additions and 287 deletions
+194
View File
@@ -0,0 +1,194 @@
# Main Thread CPU Offload Plan
## Problem Statement
The main `c_relay` thread consumes ~56% CPU while the DB worker threads (`db-read-1..4`, `db-write`) sit near 0%. All protocol handling, JSON parsing, event validation, subscription matching, and message queueing happens synchronously inside `nostr_relay_callback()` on the main libwebsockets event-loop thread.
## Current Architecture
```mermaid
flowchart TD
LWS[lws_service - main thread] --> CB[nostr_relay_callback]
CB --> PARSE[JSON parse - cJSON_Parse]
CB --> VALIDATE[Signature verify - nostr_validate_unified_request]
CB --> STORE[store_event - builds payload]
STORE --> SYNC_WRITE[thread_pool_execute_store_event_sync]
SYNC_WRITE --> |blocks main thread| DB_WRITE[db-write thread]
DB_WRITE --> |signal| SYNC_WRITE
CB --> REQ[handle_req_message - builds SQL]
REQ --> SYNC_READ[thread_pool_execute_req_sync]
SYNC_READ --> |blocks main thread| DB_READ[db-read-N thread]
DB_READ --> |signal| SYNC_READ
CB --> BROADCAST[broadcast_event_to_subscriptions]
BROADCAST --> QUEUE[queue_message per subscriber]
CB --> WRITEABLE[LWS_CALLBACK_SERVER_WRITEABLE]
WRITEABLE --> DRAIN[process_message_queue - lws_write]
```
### Why the main thread is hot
| Work item | Where | Cost |
|-----------|-------|------|
| JSON parsing | `cJSON_Parse` in `LWS_CALLBACK_RECEIVE` | Medium - per message |
| Signature verification | `nostr_validate_unified_request` - ed25519 crypto | **High** - per EVENT |
| SQL query building | `handle_req_message` filter-to-SQL loop | Low-Medium |
| Sync DB wait | `thread_pool_execute_*_sync` - pthread_cond_wait | Blocks but yields CPU |
| Result iteration + expiration check | Row loop in `handle_req_message` with `cJSON_Parse` per row | Medium-High for large result sets |
| Subscription matching | `broadcast_event_to_subscriptions` - filter matching | Medium - scales with subscriber count |
| Message serialization + queueing | `snprintf` + `queue_message_take_ownership` per subscriber | Medium |
| Config lookups | `get_config_int/bool` called repeatedly in hot paths | Low but frequent |
### Key constraint: libwebsockets is single-threaded
libwebsockets requires that **all `lws_write`, `lws_callback_on_writable`, and `lws_close_reason` calls happen from the service thread** (the thread running `lws_service`). This means we cannot directly write to WebSocket connections from worker threads. However, we **can** do computation on worker threads and post results back to the main thread for I/O.
## Offload Strategy
### Phase 1: Async EVENT Processing (Highest Impact)
Convert EVENT handling from synchronous to async. Currently the main thread does: parse → validate → store → broadcast, all blocking. Instead:
1. **Main thread**: Parse JSON (fast), extract event ID for dedup check, then submit a job to a new "event processing" worker thread
2. **Worker thread**: Signature verification (expensive crypto), store_event (already goes to DB thread), prepare broadcast payload
3. **Main thread callback**: Receive result via `wake_loop_cb` + `lws_cancel_service`, send OK response and broadcast to subscribers
```mermaid
flowchart TD
LWS[lws_service - main thread] --> RECEIVE[LWS_CALLBACK_RECEIVE]
RECEIVE --> PARSE[JSON parse + dedup check]
PARSE --> SUBMIT[Submit to event-worker queue]
SUBMIT --> LWS
WORKER[event-worker thread] --> VERIFY[Signature verification]
VERIFY --> STORE_DB[store_event via DB pool]
STORE_DB --> PREP[Prepare broadcast payload]
PREP --> RESULT_Q[Push result to completion queue]
RESULT_Q --> WAKE[lws_cancel_service]
LWS2[lws_service wakes] --> POLL[Poll completion queue]
POLL --> OK[Send OK response via queue_message]
POLL --> BCAST[broadcast_event_to_subscriptions]
```
**What this offloads**: ed25519 signature verification (~the most expensive per-event operation), event classification, tag serialization, and the synchronous DB store wait.
**What stays on main thread**: JSON parse (needed to extract event ID for dedup), OK response writing, broadcast fan-out (requires lws access).
### Phase 2: Async REQ Query Execution (Medium Impact)
Convert REQ handling from sync to async:
1. **Main thread**: Parse filters, build SQL, create subscription, submit query job
2. **DB reader thread**: Execute query (already happens, but currently blocks main thread via `_sync`)
3. **Main thread callback**: Iterate results, queue EVENT messages, send EOSE
This is simpler than Phase 1 because the thread pool already supports async submission via `thread_pool_submit_read` with a `result_cb`. The `_sync` wrappers just add a condvar wait on top. We need to:
- Use `thread_pool_submit_read` directly instead of `thread_pool_execute_req_sync`
- Store pending REQ context (sub_id, wsi, pss) so the callback can complete the work
- In the result callback, push results to a completion queue and call `lws_cancel_service`
- On the main thread, drain the completion queue and send EVENT + EOSE messages
### Phase 3: Reduce Per-Row Overhead in REQ Results (Low-Medium Impact)
Currently each row from a REQ query gets `cJSON_Parse` just to check NIP-40 expiration. This is wasteful:
- Option A: Add an `expiration` column to the events table so expiration filtering can be done in SQL
- Option B: Store expiration timestamp in a fast-parse format (extract during INSERT, store as integer column)
- Option C: Use string search on the raw JSON for the expiration tag instead of full parse
### Phase 4: Config Value Caching (Low Impact, Easy Win)
`get_config_int` and `get_config_bool` are called on every message in hot paths. These do SQLite queries. Cache config values in memory with a TTL or invalidation signal, so the main loop only refreshes them periodically (already done for `debug_level` every 60s — extend to all hot-path config values).
## Implementation Priority
| Phase | Impact | Risk | Complexity |
|-------|--------|------|------------|
| Phase 1: Async EVENT | **High** - removes crypto from main thread | Medium - async state management | Medium-High |
| Phase 2: Async REQ | **Medium** - unblocks main thread during queries | Low - infrastructure exists | Medium |
| Phase 3: Expiration optimization | **Low-Medium** - reduces per-row parse cost | Low | Low |
| Phase 4: Config caching | **Low** - reduces DB round-trips | Very Low | Low |
## Detailed Design: Phase 1 (Async EVENT Processing)
### New Components
#### Completion Queue (`src/completion_queue.h/.c`)
A thread-safe FIFO queue for posting results from worker threads back to the main thread:
```c
typedef struct {
int type; // COMPLETION_TYPE_EVENT_RESULT, COMPLETION_TYPE_REQ_RESULT, etc.
void* data; // Type-specific result data
struct lws* wsi; // Target WebSocket connection
void* pss; // Per-session data
} completion_item_t;
int completion_queue_init(void);
int completion_queue_push(completion_item_t* item);
completion_item_t* completion_queue_pop(void); // Non-blocking
void completion_queue_shutdown(void);
```
#### Event Worker Thread
A dedicated pthread that processes EVENT validation/storage:
```c
typedef struct {
cJSON* event; // Parsed event JSON - ownership transferred
cJSON* full_message; // Full message JSON for context
struct lws* wsi;
void* pss;
char sub_id[64]; // For response routing
} event_work_item_t;
```
#### Main Loop Integration
Add a completion queue drain step to the main event loop. After `lws_service` returns (either from timeout or `lws_cancel_service` wake), check the completion queue:
```c
while (g_server_running && !g_shutdown_flag) {
int result = lws_service(ws_context, 1000);
// NEW: Drain completion queue
completion_item_t* item;
while ((item = completion_queue_pop()) != NULL) {
process_completion(item); // Send OK, broadcast, etc.
free(item);
}
// ... existing periodic checks ...
}
```
### Changes to Existing Code
1. **`nostr_relay_callback` EVENT path**: After JSON parse and dedup check, instead of calling `nostr_validate_unified_request` + `store_event` + `broadcast_event_to_subscriptions` synchronously, submit an `event_work_item_t` to the event worker queue and return 0 immediately.
2. **`store_event`**: No changes needed — it already uses `thread_pool_execute_store_event_sync` which will run on the DB writer thread. The event worker thread will call it.
3. **`broadcast_event_to_subscriptions`**: No changes needed — it will be called from the main thread when processing the completion item, which is correct since it calls `queue_message_take_ownership` (requires lws thread).
### Thread Safety Considerations
- The `cJSON* event` object must be fully owned by the worker thread during processing. The main thread must not access it after submission.
- The `wsi` and `pss` pointers could become invalid if the client disconnects while the event is being processed. The completion handler must validate that the connection is still alive before sending the OK response.
- A generation counter or epoch on `pss` can detect stale references.
## What Cannot Be Offloaded
- **`lws_write` / `queue_message`**: Must happen on the lws service thread
- **`lws_callback_on_writable`**: Must happen on the lws service thread
- **`lws_close_reason`**: Must happen on the lws service thread
- **Subscription list iteration for broadcast**: Accesses `lws_wsi_user` which is lws-internal
These are fundamental libwebsockets constraints. The pattern is always: do computation off-thread, post result to completion queue, wake main thread, do I/O on main thread.
## Expected Impact
With Phase 1 alone, the main thread would no longer perform:
- ed25519 signature verification (~100-500μs per event depending on CPU)
- Synchronous DB store wait (~50-200μs per event)
- Event classification, tag serialization, JSON serialization for storage
This should reduce main-thread CPU by roughly 30-50% for EVENT-heavy workloads, shifting that work to the event worker thread and DB threads.
+1 -1
View File
@@ -1 +1 @@
513827
678119
+103 -10
View File
@@ -13,17 +13,58 @@
extern sqlite3* g_db;
extern char g_database_path[512];
// Optional per-thread connection override (used by thread pool workers)
static __thread sqlite3* g_thread_db = NULL;
static sqlite3* db_active_connection(void) {
return g_thread_db ? g_thread_db : g_db;
}
typedef struct db_stmt {
sqlite3_stmt* stmt;
} db_stmt_t;
int db_init(const char* connection_string) {
if (!connection_string || connection_string[0] == '\0') return DB_MISUSE;
if (g_db) return DB_OK;
int rc = sqlite3_open(connection_string, &g_db);
if (rc != SQLITE_OK) {
if (g_db) {
sqlite3_close(g_db);
g_db = NULL;
}
return DB_ERROR;
}
strncpy(g_database_path, connection_string, sizeof(g_database_path) - 1);
g_database_path[sizeof(g_database_path) - 1] = '\0';
return DB_OK;
}
void db_close(void) {
if (!g_db) return;
sqlite3_close(g_db);
g_db = NULL;
}
int db_set_thread_connection(void* connection) {
g_thread_db = (sqlite3*)connection;
return DB_OK;
}
void db_clear_thread_connection(void) {
g_thread_db = NULL;
}
int db_is_available(void) {
return g_db != NULL;
return db_active_connection() != NULL;
}
const char* db_last_error(void) {
if (!g_db) return "database not available";
return sqlite3_errmsg(g_db);
sqlite3* db = db_active_connection();
if (!db) return "database not available";
return sqlite3_errmsg(db);
}
const char* db_get_database_path(void) {
@@ -31,10 +72,11 @@ const char* db_get_database_path(void) {
}
int db_prepare(const char* sql, db_stmt_t** out_stmt) {
if (!g_db || !sql || !out_stmt) return DB_MISUSE;
sqlite3* db = db_active_connection();
if (!db || !sql || !out_stmt) return DB_MISUSE;
sqlite3_stmt* raw_stmt = NULL;
int rc = sqlite3_prepare_v2(g_db, sql, -1, &raw_stmt, NULL);
int rc = sqlite3_prepare_v2(db, sql, -1, &raw_stmt, NULL);
if (rc != SQLITE_OK) return rc;
db_stmt_t* wrapper = (db_stmt_t*)malloc(sizeof(db_stmt_t));
@@ -372,10 +414,11 @@ int db_count_active_whitelist_rules(void) {
}
int db_count_with_sql(const char* sql, const char** bind_params, int bind_param_count, int* out_count) {
if (!g_db || !sql || !out_count) return -1;
sqlite3* db = db_active_connection();
if (!db || !sql || !out_count) return -1;
sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
return -1;
}
@@ -882,11 +925,57 @@ int db_store_config_event(const cJSON* event) {
return (rc == SQLITE_DONE) ? 0 : -1;
}
static int db_insert_event_tags_json_with_db(sqlite3* db, const char* event_id, const char* tags_json) {
if (!db || !event_id || !tags_json) {
return -1;
}
cJSON* tags = cJSON_Parse(tags_json);
if (!tags || !cJSON_IsArray(tags)) {
if (tags) cJSON_Delete(tags);
return 0;
}
const char* sql = "INSERT INTO event_tags (event_id, tag_name, tag_value, tag_index) VALUES (?, ?, ?, ?)";
sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
cJSON_Delete(tags);
return -1;
}
int tag_index = 0;
cJSON* tag = NULL;
cJSON_ArrayForEach(tag, tags) {
if (cJSON_IsArray(tag) && cJSON_GetArraySize(tag) >= 2) {
cJSON* name = cJSON_GetArrayItem(tag, 0);
cJSON* value = cJSON_GetArrayItem(tag, 1);
if (cJSON_IsString(name) && cJSON_IsString(value)) {
sqlite3_reset(stmt);
sqlite3_clear_bindings(stmt);
sqlite3_bind_text(stmt, 1, event_id, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, cJSON_GetStringValue(name), -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, cJSON_GetStringValue(value), -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 4, tag_index);
if (sqlite3_step(stmt) != SQLITE_DONE) {
DEBUG_WARN("Failed to insert event tag for %s: %s", event_id, sqlite3_errmsg(db));
}
}
}
tag_index++;
}
sqlite3_finalize(stmt);
cJSON_Delete(tags);
return 0;
}
int db_insert_event_with_json(const char* id, const char* pubkey, long long created_at,
int kind, const char* event_type, const char* content,
const char* sig, const char* tags_json, const char* event_json,
int* out_step_rc, int* out_extended_errcode) {
if (!g_db || !id || !pubkey || !event_type || !content || !sig || !tags_json || !event_json) {
sqlite3* db = db_active_connection();
if (!db || !id || !pubkey || !event_type || !content || !sig || !tags_json || !event_json) {
return -1;
}
@@ -895,7 +984,7 @@ int db_insert_event_with_json(const char* id, const char* pubkey, long long crea
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
sqlite3_stmt* stmt = NULL;
if (sqlite3_prepare_v2(g_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) {
return -1;
}
@@ -910,9 +999,13 @@ int db_insert_event_with_json(const char* id, const char* pubkey, long long crea
sqlite3_bind_text(stmt, 9, event_json, -1, SQLITE_TRANSIENT);
int step_rc = sqlite3_step(stmt);
int extended_errcode = sqlite3_extended_errcode(g_db);
int extended_errcode = sqlite3_extended_errcode(db);
sqlite3_finalize(stmt);
if (step_rc == SQLITE_DONE) {
(void)db_insert_event_tags_json_with_db(db, id, tags_json);
}
if (out_step_rc) {
*out_step_rc = step_rc;
}
+6
View File
@@ -6,10 +6,16 @@
#include <cjson/cJSON.h>
// Generic helpers
int db_init(const char* connection_string);
void db_close(void);
int db_is_available(void);
const char* db_last_error(void);
const char* db_get_database_path(void);
// Per-thread connection override (used by thread pool workers)
int db_set_thread_connection(void* connection);
void db_clear_thread_connection(void);
// DB result codes (backend-agnostic)
#define DB_OK 0
#define DB_ERROR 1
+402 -148
View File
@@ -115,6 +115,12 @@ int process_admin_event_in_config(cJSON* event, char* error_message, size_t erro
// Forward declaration for NIP-45 COUNT message handling
int handle_count_message(const char* sub_id, cJSON* filters, struct lws *wsi, struct per_session_data *pss);
// Forward declaration for NOTICE message support
void send_notice_message(struct lws* wsi, struct per_session_data* pss, const char* message);
// Thread pool wake callback (called by worker threads)
static void wake_event_loop_from_thread_pool(void* ctx);
// Parameter binding helpers for SQL queries
static void add_bind_param(char*** params, int* count, int* capacity, const char* value) {
if (*count >= *capacity) {
@@ -131,11 +137,308 @@ static void free_bind_params(char** params, int count) {
free(params);
}
typedef struct req_async_state {
char sub_id[SUBSCRIPTION_ID_MAX_LENGTH];
struct lws* wsi_token;
pthread_mutex_t mutex;
int pending_jobs;
} req_async_state_t;
typedef struct req_async_submit_ctx {
req_async_state_t* state;
} req_async_submit_ctx_t;
typedef struct req_async_completion {
req_async_state_t* state;
thread_pool_status_t status;
thread_pool_req_result_t* req_result;
struct req_async_completion* next;
} req_async_completion_t;
static pthread_mutex_t g_req_async_completion_mutex = PTHREAD_MUTEX_INITIALIZER;
static req_async_completion_t* g_req_async_completion_head = NULL;
static req_async_completion_t* g_req_async_completion_tail = NULL;
static void free_req_payload_main(void* p) {
thread_pool_req_payload_t* payload = (thread_pool_req_payload_t*)p;
if (!payload) return;
free(payload->sql);
if (payload->bind_params) {
for (int i = 0; i < payload->bind_param_count; i++) {
free(payload->bind_params[i]);
}
free(payload->bind_params);
}
free(payload);
}
static req_async_state_t* req_async_state_create(const char* sub_id, struct lws* wsi) {
req_async_state_t* state = calloc(1, sizeof(*state));
if (!state) {
return NULL;
}
if (sub_id) {
strncpy(state->sub_id, sub_id, sizeof(state->sub_id) - 1);
state->sub_id[sizeof(state->sub_id) - 1] = '\0';
}
state->wsi_token = wsi;
pthread_mutex_init(&state->mutex, NULL);
return state;
}
static void req_async_state_free(req_async_state_t* state) {
if (!state) return;
pthread_mutex_destroy(&state->mutex);
free(state);
}
static void req_async_state_increment_pending(req_async_state_t* state) {
if (!state) return;
pthread_mutex_lock(&state->mutex);
state->pending_jobs++;
pthread_mutex_unlock(&state->mutex);
}
static int req_async_state_decrement_pending(req_async_state_t* state) {
if (!state) return 0;
pthread_mutex_lock(&state->mutex);
if (state->pending_jobs > 0) {
state->pending_jobs--;
}
int remaining = state->pending_jobs;
pthread_mutex_unlock(&state->mutex);
return remaining;
}
static void req_async_completion_push(req_async_completion_t* completion) {
if (!completion) return;
pthread_mutex_lock(&g_req_async_completion_mutex);
completion->next = NULL;
if (!g_req_async_completion_tail) {
g_req_async_completion_head = completion;
g_req_async_completion_tail = completion;
} else {
g_req_async_completion_tail->next = completion;
g_req_async_completion_tail = completion;
}
pthread_mutex_unlock(&g_req_async_completion_mutex);
}
static req_async_completion_t* req_async_completion_pop(void) {
pthread_mutex_lock(&g_req_async_completion_mutex);
req_async_completion_t* completion = g_req_async_completion_head;
if (completion) {
g_req_async_completion_head = completion->next;
if (!g_req_async_completion_head) {
g_req_async_completion_tail = NULL;
}
}
pthread_mutex_unlock(&g_req_async_completion_mutex);
return completion;
}
static int resolve_req_async_target(req_async_state_t* state, struct lws** out_wsi, struct per_session_data** out_pss) {
if (!state || !out_wsi || !out_pss) {
return 0;
}
*out_wsi = NULL;
*out_pss = NULL;
pthread_mutex_lock(&g_subscription_manager.subscriptions_lock);
subscription_t* sub = g_subscription_manager.active_subscriptions;
while (sub) {
if (sub->active && sub->wsi == state->wsi_token && strcmp(sub->id, state->sub_id) == 0) {
*out_wsi = sub->wsi;
break;
}
sub = sub->next;
}
pthread_mutex_unlock(&g_subscription_manager.subscriptions_lock);
if (!*out_wsi) {
return 0;
}
*out_pss = (struct per_session_data*)lws_wsi_user(*out_wsi);
return (*out_pss != NULL);
}
static void send_eose_message(struct lws* wsi, struct per_session_data* pss, const char* sub_id) {
if (!wsi || !pss || !sub_id) {
return;
}
cJSON* eose_response = cJSON_CreateArray();
if (!eose_response) {
return;
}
cJSON_AddItemToArray(eose_response, cJSON_CreateString("EOSE"));
cJSON_AddItemToArray(eose_response, cJSON_CreateString(sub_id));
char *eose_str = cJSON_Print(eose_response);
if (eose_str) {
size_t eose_len = strlen(eose_str);
DEBUG_TRACE("WS_FRAME_SEND: type=EOSE len=%zu data=%.100s%s",
eose_len,
eose_str,
eose_len > 100 ? "..." : "");
if (queue_message(wsi, pss, eose_str, eose_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue EOSE message");
}
free(eose_str);
}
cJSON_Delete(eose_response);
}
static void req_async_result_cb(const thread_pool_result_t* result, void* user_ctx) {
req_async_submit_ctx_t* ctx = (req_async_submit_ctx_t*)user_ctx;
if (!ctx || !ctx->state || !result) {
if (result && result->result_data) {
thread_pool_free_req_result((thread_pool_req_result_t*)result->result_data);
}
if (ctx) free(ctx);
return;
}
req_async_completion_t* completion = calloc(1, sizeof(*completion));
if (!completion) {
if (result->result_data) {
thread_pool_free_req_result((thread_pool_req_result_t*)result->result_data);
}
free(ctx);
return;
}
completion->state = ctx->state;
completion->status = result->status;
completion->req_result = (thread_pool_req_result_t*)result->result_data;
req_async_completion_push(completion);
wake_event_loop_from_thread_pool(NULL);
free(ctx);
}
static int submit_req_query_async(req_async_state_t* state, const char* sql, const char** bind_params, int bind_param_count) {
if (!state || !sql) {
return -1;
}
thread_pool_req_payload_t* payload = calloc(1, sizeof(*payload));
if (!payload) {
return -1;
}
payload->sql = strdup(sql);
payload->bind_param_count = bind_param_count;
if (!payload->sql) {
free_req_payload_main(payload);
return -1;
}
if (bind_param_count > 0) {
payload->bind_params = calloc((size_t)bind_param_count, sizeof(char*));
if (!payload->bind_params) {
free_req_payload_main(payload);
return -1;
}
for (int i = 0; i < bind_param_count; i++) {
const char* v = (bind_params && bind_params[i]) ? bind_params[i] : "";
payload->bind_params[i] = strdup(v);
if (!payload->bind_params[i]) {
free_req_payload_main(payload);
return -1;
}
}
}
req_async_submit_ctx_t* ctx = calloc(1, sizeof(*ctx));
if (!ctx) {
free_req_payload_main(payload);
return -1;
}
ctx->state = state;
thread_pool_job_t job;
memset(&job, 0, sizeof(job));
job.type = THREAD_POOL_JOB_REQ_QUERY;
job.payload = payload;
job.payload_size = sizeof(*payload);
job.payload_free = free_req_payload_main;
job.result_cb = req_async_result_cb;
job.result_cb_ctx = ctx;
req_async_state_increment_pending(state);
thread_pool_status_t submit_rc = thread_pool_submit_read(&job, NULL);
if (submit_rc != THREAD_POOL_STATUS_OK) {
req_async_state_decrement_pending(state);
free(ctx);
free_req_payload_main(payload);
return -1;
}
return 0;
}
void process_req_async_completions(void) {
req_async_completion_t* completion = NULL;
while ((completion = req_async_completion_pop()) != NULL) {
struct lws* target_wsi = NULL;
struct per_session_data* target_pss = NULL;
int has_target = resolve_req_async_target(completion->state, &target_wsi, &target_pss);
if (has_target && completion->status == THREAD_POOL_STATUS_OK && completion->req_result) {
for (int r = 0; r < completion->req_result->row_count; r++) {
const char* event_json_str = completion->req_result->event_json_rows[r];
if (!event_json_str) {
continue;
}
size_t sub_id_len = strlen(completion->state->sub_id);
size_t event_json_len = strlen(event_json_str);
size_t msg_len = 10 + sub_id_len + 3 + event_json_len + 1;
unsigned char* buf = malloc(LWS_PRE + msg_len + 1);
if (!buf) {
continue;
}
char* msg_ptr = (char*)(buf + LWS_PRE);
snprintf(msg_ptr, msg_len + 1, "[\"EVENT\",\"%s\",%s]", completion->state->sub_id, event_json_str);
size_t actual_len = strlen(msg_ptr);
if (queue_message_take_ownership(target_wsi, target_pss, buf, actual_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue async EVENT message for sub=%s", completion->state->sub_id);
}
}
} else if (has_target && completion->status != THREAD_POOL_STATUS_OK) {
send_notice_message(target_wsi, target_pss, "error: failed to execute subscription query");
}
int remaining = req_async_state_decrement_pending(completion->state);
if (remaining == 0) {
if (has_target) {
send_eose_message(target_wsi, target_pss, completion->state->sub_id);
}
req_async_state_free(completion->state);
}
if (completion->req_result) {
thread_pool_free_req_result(completion->req_result);
}
free(completion);
}
}
// Forward declaration for enhanced admin event authorization
int is_authorized_admin_event(cJSON* event, char* error_message, size_t error_size);
// Forward declaration for NOTICE message support
void send_notice_message(struct lws* wsi, struct per_session_data* pss, const char* message);
// Forward declarations for NIP-42 authentication functions
void send_nip42_auth_challenge(struct lws* wsi, struct per_session_data* pss);
@@ -164,8 +467,6 @@ int handle_nip11_http_request(struct lws* wsi, const char* accept_header);
// Forward declaration for WebSocket relay server
int start_websocket_relay(int port_override, int strict_port);
// Thread pool wake callback (called by worker threads)
static void wake_event_loop_from_thread_pool(void* ctx);
// Forward declarations for IP ban system
void ip_ban_init(void);
@@ -425,7 +726,7 @@ int init_database(const char* database_path_override) {
// Clean up stale WAL files before opening database
cleanup_stale_wal_files(db_path);
int rc = sqlite3_open(db_path, &g_db);
int rc = db_init(db_path);
if (rc != DB_OK) {
DEBUG_ERROR("Cannot open database");
DEBUG_TRACE("Exiting init_database() - failed to open database");
@@ -437,7 +738,7 @@ int init_database(const char* database_path_override) {
// Check config table row count immediately after database open
int row_count = 0;
if (db_get_config_row_count(&row_count) == 0) {
DEBUG_LOG("Config table row count immediately after sqlite3_open(): %d", row_count);
DEBUG_LOG("Config table row count immediately after db_init(): %d", row_count);
} else {
DEBUG_LOG("Config table count unavailable immediately after sqlite3_open() (table may not exist yet)");
}
@@ -600,8 +901,7 @@ void close_database() {
DEBUG_WARN("WAL checkpoint warning");
}
sqlite3_close(g_db);
g_db = NULL;
db_close();
DEBUG_LOG("Database connection closed");
}
@@ -675,12 +975,16 @@ int store_event_tags(const char* event_id, cJSON* tags) {
return db_store_event_tags_cjson(event_id, tags);
}
// Store event in database
int store_event(cJSON* event) {
// Core event storage path.
// Returns:
// 0 = inserted into DB
// 1 = handled without insert (duplicate or ephemeral)
// -1 = failure
int store_event_core(cJSON* event) {
if (!g_db || !event) {
return -1;
}
// Extract event fields
cJSON* id = cJSON_GetObjectItemCaseSensitive(event, "id");
cJSON* pubkey = cJSON_GetObjectItemCaseSensitive(event, "pubkey");
@@ -689,12 +993,12 @@ int store_event(cJSON* event) {
cJSON* content = cJSON_GetObjectItemCaseSensitive(event, "content");
cJSON* sig = cJSON_GetObjectItemCaseSensitive(event, "sig");
cJSON* tags = cJSON_GetObjectItemCaseSensitive(event, "tags");
if (!id || !pubkey || !created_at || !kind || !content || !sig) {
DEBUG_ERROR("Invalid event - missing required fields");
return -1;
}
// Classify event type
event_type_t type = classify_event_kind((int)cJSON_GetNumberValue(kind));
@@ -702,7 +1006,7 @@ int store_event(cJSON* event) {
if (type == EVENT_TYPE_EPHEMERAL) {
DEBUG_LOG("Ephemeral event (kind %d) - broadcasting only, not storing",
(int)cJSON_GetNumberValue(kind));
return 0; // Success - event was handled but not stored
return 1;
}
// Serialize tags to JSON (use empty array if no tags)
@@ -712,12 +1016,12 @@ int store_event(cJSON* event) {
} else {
tags_json = strdup("[]");
}
if (!tags_json) {
DEBUG_ERROR("Failed to serialize tags to JSON");
return -1;
}
// Serialize full event JSON for fast retrieval (use PrintUnformatted for compact storage)
char* event_json = cJSON_PrintUnformatted(event);
if (!event_json) {
@@ -725,7 +1029,7 @@ int store_event(cJSON* event) {
free(tags_json);
return -1;
}
thread_pool_store_event_payload_t payload;
memset(&payload, 0, sizeof(payload));
payload.id = (char*)cJSON_GetStringValue(id);
@@ -756,7 +1060,7 @@ int store_event(cJSON* event) {
DEBUG_ERROR("INSERT failed: rc=%d, extended_errcode=%d, msg=%s", rc, extended_errcode, err_msg);
}
}
if (rc != DB_DONE) {
if (rc == DB_CONSTRAINT) {
DEBUG_WARN("Event already exists in database");
@@ -782,7 +1086,7 @@ int store_event(cJSON* event) {
free(tags_json);
free(event_json);
return 0; // Not an error, just duplicate
return 1;
}
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Failed to insert event: %s", db_last_error());
@@ -794,13 +1098,18 @@ int store_event(cJSON* event) {
free(tags_json);
free(event_json);
return 0;
}
// Main-thread-only post-store follow-up actions.
void store_event_post_actions(cJSON* event) {
if (!event) {
return;
}
// Call monitoring hook after successful event storage
monitoring_on_event_stored();
// After successful event storage, insert denormalized tags
store_event_tags(cJSON_GetStringValue(id), tags);
// Check if this is a kind 3 event from the admin — trigger WoT sync
cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind");
cJSON* pubkey_obj = cJSON_GetObjectItemCaseSensitive(event, "pubkey");
@@ -816,7 +1125,17 @@ int store_event(cJSON* event) {
if (admin_pubkey) free((char*)admin_pubkey);
}
}
}
// Backward-compatible wrapper for synchronous call sites.
int store_event(cJSON* event) {
int core_rc = store_event_core(event);
if (core_rc < 0) {
return -1;
}
if (core_rc == 0) {
store_event_post_actions(event);
}
return 0;
}
@@ -1101,7 +1420,18 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
}
int events_sent = config_events_sent; // Start with synthetic config events
int submitted_jobs = 0;
int expiration_enabled = get_config_bool("expiration_enabled", 1);
int filter_responses = get_config_bool("expiration_filter", 1);
time_t query_now = time(NULL);
req_async_state_t* async_state = req_async_state_create(sub_id, wsi);
if (!async_state) {
DEBUG_ERROR("Failed to allocate async REQ state");
free_bind_params(bind_params, bind_param_count);
return events_sent;
}
// Process each filter in the array
for (int i = 0; i < cJSON_GetArraySize(filters); i++) {
cJSON* filter = cJSON_GetArrayItem(filters, i);
@@ -1125,13 +1455,26 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
// Build SQL query based on filter - exclude ephemeral events (kinds 20000-29999) from historical queries
// Select event_json for fast retrieval (no JSON reconstruction needed)
char sql[1024] = "SELECT event_json FROM events WHERE 1=1 AND (kind < 20000 OR kind >= 30000)";
char sql[1408] = "SELECT event_json FROM events WHERE 1=1 AND (kind < 20000 OR kind >= 30000)";
char* sql_ptr = sql + strlen(sql);
int remaining = sizeof(sql) - strlen(sql);
// Note: Expiration filtering will be done at application level
// after retrieving events to ensure compatibility with all SQLite versions
// Phase 3: push expiration filtering into SQL using indexed event_tags table.
if (expiration_enabled && filter_responses) {
snprintf(sql_ptr, remaining,
" AND NOT EXISTS (SELECT 1 FROM event_tags et_exp "
"WHERE et_exp.event_id = events.id "
"AND et_exp.tag_name = ? "
"AND CAST(et_exp.tag_value AS INTEGER) <= ?)");
sql_ptr += strlen(sql_ptr);
remaining = sizeof(sql) - strlen(sql);
add_bind_param(&bind_params, &bind_param_count, &bind_param_capacity, "expiration");
char now_buf[32];
snprintf(now_buf, sizeof(now_buf), "%lld", (long long)query_now);
add_bind_param(&bind_params, &bind_param_count, &bind_param_capacity, now_buf);
}
// Handle kinds filter
cJSON* kinds = cJSON_GetObjectItemCaseSensitive(filter, "kinds");
if (kinds && cJSON_IsArray(kinds)) {
@@ -1140,7 +1483,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
snprintf(sql_ptr, remaining, " AND kind IN (");
sql_ptr += strlen(sql_ptr);
remaining = sizeof(sql) - strlen(sql);
for (int k = 0; k < kind_count; k++) {
cJSON* kind = cJSON_GetArrayItem(kinds, k);
if (cJSON_IsNumber(kind)) {
@@ -1159,7 +1502,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
remaining = sizeof(sql) - strlen(sql);
}
}
// Handle authors filter
cJSON* authors = cJSON_GetObjectItemCaseSensitive(filter, "authors");
if (authors && cJSON_IsArray(authors)) {
@@ -1205,8 +1548,8 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
if (ids && cJSON_IsArray(ids)) {
int id_count = 0;
// Count valid ids
for (int i = 0; i < cJSON_GetArraySize(ids); i++) {
cJSON* id = cJSON_GetArrayItem(ids, i);
for (int j = 0; j < cJSON_GetArraySize(ids); j++) {
cJSON* id = cJSON_GetArrayItem(ids, j);
if (cJSON_IsString(id)) {
id_count++;
}
@@ -1216,8 +1559,8 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
sql_ptr += strlen(sql_ptr);
remaining = sizeof(sql) - strlen(sql);
for (int i = 0; i < id_count; i++) {
if (i > 0) {
for (int j = 0; j < id_count; j++) {
if (j > 0) {
snprintf(sql_ptr, remaining, ",");
sql_ptr++;
remaining--;
@@ -1231,8 +1574,8 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
remaining = sizeof(sql) - strlen(sql);
// Add id values to bind params
for (int i = 0; i < cJSON_GetArraySize(ids); i++) {
cJSON* id = cJSON_GetArrayItem(ids, i);
for (int j = 0; j < cJSON_GetArraySize(ids); j++) {
cJSON* id = cJSON_GetArrayItem(ids, j);
if (cJSON_IsString(id)) {
add_bind_param(&bind_params, &bind_param_count, &bind_param_capacity, cJSON_GetStringValue(id));
}
@@ -1251,8 +1594,8 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
if (cJSON_IsArray(filter_item)) {
int tag_value_count = 0;
// Count valid tag values
for (int i = 0; i < cJSON_GetArraySize(filter_item); i++) {
cJSON* tag_value = cJSON_GetArrayItem(filter_item, i);
for (int j = 0; j < cJSON_GetArraySize(filter_item); j++) {
cJSON* tag_value = cJSON_GetArrayItem(filter_item, j);
if (cJSON_IsString(tag_value)) {
tag_value_count++;
}
@@ -1263,8 +1606,8 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
sql_ptr += strlen(sql_ptr);
remaining = sizeof(sql) - strlen(sql);
for (int i = 0; i < tag_value_count; i++) {
if (i > 0) {
for (int j = 0; j < tag_value_count; j++) {
if (j > 0) {
snprintf(sql_ptr, remaining, ",");
sql_ptr++;
remaining--;
@@ -1279,8 +1622,8 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
// Add tag name and values to bind params
add_bind_param(&bind_params, &bind_param_count, &bind_param_capacity, tag_name);
for (int i = 0; i < cJSON_GetArraySize(filter_item); i++) {
cJSON* tag_value = cJSON_GetArrayItem(filter_item, i);
for (int j = 0; j < cJSON_GetArraySize(filter_item); j++) {
cJSON* tag_value = cJSON_GetArrayItem(filter_item, j);
if (cJSON_IsString(tag_value)) {
add_bind_param(&bind_params, &bind_param_count, &bind_param_capacity, cJSON_GetStringValue(tag_value));
}
@@ -1299,12 +1642,12 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
// Escape single quotes in search term for SQL safety
char escaped_search[256];
size_t escaped_len = 0;
for (size_t i = 0; search_term[i] && escaped_len < sizeof(escaped_search) - 1; i++) {
if (search_term[i] == '\'') {
for (size_t j = 0; search_term[j] && escaped_len < sizeof(escaped_search) - 1; j++) {
if (search_term[j] == '\'') {
escaped_search[escaped_len++] = '\'';
escaped_search[escaped_len++] = '\'';
} else {
escaped_search[escaped_len++] = search_term[i];
escaped_search[escaped_len++] = search_term[j];
}
}
escaped_search[escaped_len] = '\0';
@@ -1325,7 +1668,7 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
sql_ptr += strlen(sql_ptr);
remaining = sizeof(sql) - strlen(sql);
}
// Handle until filter
cJSON* until = cJSON_GetObjectItemCaseSensitive(filter, "until");
if (until && cJSON_IsNumber(until)) {
@@ -1333,12 +1676,12 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
sql_ptr += strlen(sql_ptr);
remaining = sizeof(sql) - strlen(sql);
}
// Add ordering and limit
snprintf(sql_ptr, remaining, " ORDER BY created_at DESC");
sql_ptr += strlen(sql_ptr);
remaining = sizeof(sql) - strlen(sql);
// Handle limit filter
cJSON* limit = cJSON_GetObjectItemCaseSensitive(filter, "limit");
if (limit && cJSON_IsNumber(limit)) {
@@ -1351,116 +1694,27 @@ int handle_req_message(const char* sub_id, cJSON* filters, struct lws *wsi, stru
snprintf(sql_ptr, remaining, " LIMIT 500");
}
// Start query timing
struct timespec query_start, query_end;
clock_gettime(CLOCK_MONOTONIC, &query_start);
// Execute query through db thread pool helper and send events
thread_pool_req_result_t* req_result = NULL;
if (thread_pool_execute_req_sync(sql, (const char**)bind_params, bind_param_count, 5000, &req_result) != 0 || !req_result) {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "Failed to execute subscription query: %s", db_last_error());
DEBUG_ERROR(error_msg);
// Log the failed query so we can see what SQL was generated
if (g_debug_level >= DEBUG_LEVEL_DEBUG) {
time_t now = time(NULL);
struct tm* tm_info = localtime(&now);
char timestamp[32];
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info);
fprintf(stderr, "[%s] [QUERY_FAILED] type=REQ sub=%s ip=%s error=%s sql=%s\n",
timestamp,
sub_id,
pss ? pss->client_ip : "N/A",
db_last_error(),
sql);
fflush(stderr);
}
// Submit async REQ query (results processed on lws thread via completion queue)
if (submit_req_query_async(async_state, sql, (const char**)bind_params, bind_param_count) != 0) {
DEBUG_ERROR("Failed to submit async REQ query for subscription %s", sub_id);
continue;
}
// Track query execution for abuse detection
submitted_jobs++;
if (pss) {
pss->db_queries_executed++;
}
// Cache config values outside the row loop (performance fix)
int expiration_enabled = get_config_bool("expiration_enabled", 1);
int filter_responses = get_config_bool("expiration_filter", 1);
int row_count = 0;
for (int r = 0; r < req_result->row_count; r++) {
const char* event_json_str = req_result->event_json_rows[r];
row_count++;
// Track rows returned for abuse detection
if (pss) {
pss->db_rows_returned++;
}
if (!event_json_str) {
DEBUG_ERROR("Event has NULL event_json field");
continue;
}
// Parse event JSON only for expiration check
cJSON* event = cJSON_Parse(event_json_str);
if (!event) {
DEBUG_ERROR("Failed to parse event_json from database");
continue;
}
// Check expiration filtering (NIP-40) at application level
// (expiration_enabled and filter_responses are cached outside the loop)
if (expiration_enabled && filter_responses) {
time_t current_time = time(NULL);
if (is_event_expired(event, current_time)) {
// Skip this expired event
cJSON_Delete(event);
continue;
}
}
// Build EVENT message using zero-copy path: allocate with LWS_PRE prefix,
// write directly, transfer ownership to queue — no memcpy.
// Format: ["EVENT","<sub_id>",<event_json>]
size_t sub_id_len = strlen(sub_id);
size_t event_json_len = strlen(event_json_str);
size_t msg_len = 10 + sub_id_len + 3 + event_json_len + 1;
unsigned char* buf = malloc(LWS_PRE + msg_len + 1);
if (buf) {
char* msg_ptr = (char*)(buf + LWS_PRE);
snprintf(msg_ptr, msg_len + 1, "[\"EVENT\",\"%s\",%s]", sub_id, event_json_str);
size_t actual_len = strlen(msg_ptr);
// queue_message_take_ownership takes buf ownership — no memcpy, no free needed here
if (queue_message_take_ownership(wsi, pss, buf, actual_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue EVENT message for sub=%s", sub_id);
// buf already freed by queue_message_take_ownership on failure
}
}
cJSON_Delete(event);
events_sent++;
}
thread_pool_free_req_result(req_result);
// Stop query timing and log
clock_gettime(CLOCK_MONOTONIC, &query_end);
long elapsed_us = (query_end.tv_sec - query_start.tv_sec) * 1000000L +
(query_end.tv_nsec - query_start.tv_nsec) / 1000L;
log_query_execution("REQ", sub_id, pss ? pss->client_ip : NULL,
sql, elapsed_us, row_count);
}
// Cleanup bind params
free_bind_params(bind_params, bind_param_count);
return events_sent;
if (submitted_jobs == 0) {
req_async_state_free(async_state);
return events_sent;
}
return HANDLE_REQ_ASYNC_PENDING;
}
/////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
@@ -2042,7 +2296,7 @@ int main(int argc, char* argv[]) {
ip_ban_load_from_db();
// Optional thread pool scaffold initialization (execution wiring is future work)
int thread_pool_enabled = get_config_bool("thread_pool_enabled", 0);
int thread_pool_enabled = get_config_bool("thread_pool_enabled", 1);
int thread_pool_initialized = 0;
if (thread_pool_enabled) {
thread_pool_config_t tp_cfg;
+20 -2
View File
@@ -13,8 +13,8 @@
// Using CRELAY_ prefix to avoid conflicts with nostr_core_lib VERSION macros
#define CRELAY_VERSION_MAJOR 2
#define CRELAY_VERSION_MINOR 1
#define CRELAY_VERSION_PATCH 1
#define CRELAY_VERSION "v2.1.1"
#define CRELAY_VERSION_PATCH 4
#define CRELAY_VERSION "v2.1.4"
// Relay metadata (authoritative source for NIP-11 information)
#define RELAY_NAME "C-Relay"
@@ -28,4 +28,22 @@
#define POSTING_POLICY ""
#define PAYMENTS_URL ""
// Forward declaration to avoid pulling cJSON headers into all includers.
typedef struct cJSON cJSON;
// Async REQ handler status used by websocket callback to defer EOSE until worker completion
#define HANDLE_REQ_ASYNC_PENDING (-2)
// Async EVENT storage split:
// - store_event_core(): worker-safe core DB write path
// returns 0 when inserted, 1 when handled without insert (duplicate/ephemeral), -1 on error
// - store_event_post_actions(): main-thread-only follow-up actions (monitoring/tags/WoT sync)
// - store_event(): legacy wrapper preserving original behavior for synchronous call sites
int store_event_core(cJSON* event);
void store_event_post_actions(cJSON* event);
int store_event(cJSON* event);
// Drains completed async REQ jobs and queues EVENT/EOSE on the lws service thread.
void process_req_async_completions(void);
#endif /* MAIN_H */
+22 -3
View File
@@ -129,6 +129,14 @@ typedef struct {
static nip42_challenge_manager_t g_challenge_manager = {0};
static int g_validator_initialized = 0;
typedef struct {
int has_active_whitelist_rules;
time_t last_refresh;
} auth_rules_fast_cache_t;
static auth_rules_fast_cache_t g_auth_rules_fast_cache = {0};
#define AUTH_RULES_CACHE_TTL_SEC 5
// Last rule violation details for status code mapping
struct {
char violation_type[100]; // "pubkey_blacklist", "hash_blacklist",
@@ -502,10 +510,10 @@ void nostr_request_result_free_file_data(nostr_request_result_t *result) {
/**
* Force cache refresh - cache no longer exists, function kept for compatibility
* Force cache refresh for auth rule fast cache.
*/
void nostr_request_validator_force_cache_refresh(void) {
// Cache no longer exists - direct database queries are used
g_auth_rules_fast_cache.last_refresh = 0;
}
/**
@@ -520,6 +528,17 @@ static int reload_auth_config(void) {
// Note: Blossom protocol validation removed - C-relay uses standard Nostr events only
static int has_active_whitelist_rules_cached(void) {
time_t now = time(NULL);
if (g_auth_rules_fast_cache.last_refresh == 0 ||
(now - g_auth_rules_fast_cache.last_refresh) >= AUTH_RULES_CACHE_TTL_SEC) {
g_auth_rules_fast_cache.has_active_whitelist_rules =
(db_count_active_whitelist_rules() > 0) ? 1 : 0;
g_auth_rules_fast_cache.last_refresh = now;
}
return g_auth_rules_fast_cache.has_active_whitelist_rules;
}
/**
* Check database authentication rules for the request
* Implements the 6-step rule evaluation engine from AUTH_API.md
@@ -553,7 +572,7 @@ int check_database_auth_rules(const char *pubkey, const char *operation __attrib
}
// Step 4: If any whitelist rules exist, deny by default
if (db_count_active_whitelist_rules() > 0) {
if (has_active_whitelist_rules_cached()) {
strcpy(g_last_rule_violation.violation_type, "whitelist_violation");
strcpy(g_last_rule_violation.reason,
"Public key not whitelisted for this operation");
+68 -2
View File
@@ -4,7 +4,10 @@
#include "debug.h"
#include "db_ops.h"
#include <sqlite3.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -37,6 +40,8 @@ typedef struct {
thread_pool_wake_loop_cb wake_loop_cb;
void* wake_loop_ctx;
char db_path[512];
pthread_mutex_t state_mutex;
} thread_pool_state_t;
@@ -193,6 +198,26 @@ static void wake_event_loop(void) {
}
}
static sqlite3* open_worker_connection(void) {
if (g_pool.db_path[0] == '\0') {
return NULL;
}
sqlite3* db = NULL;
int rc = sqlite3_open_v2(g_pool.db_path, &db, SQLITE_OPEN_READWRITE, NULL);
if (rc != SQLITE_OK) {
if (db) {
sqlite3_close(db);
}
return NULL;
}
sqlite3_exec(db, "PRAGMA journal_mode=WAL;", NULL, NULL, NULL);
sqlite3_busy_timeout(db, 5000);
return db;
}
static void complete_job_with_result(thread_pool_job_node_t* node,
thread_pool_status_t status,
const char* message,
@@ -374,24 +399,54 @@ static void execute_write_job(thread_pool_job_node_t* node) {
}
static void* reader_worker_main(void* arg) {
(void)arg;
int reader_index = (int)(intptr_t)arg;
char thread_name[16];
snprintf(thread_name, sizeof(thread_name), "db-read-%d", reader_index);
pthread_setname_np(pthread_self(), thread_name);
sqlite3* worker_db = open_worker_connection();
if (!worker_db) {
DEBUG_ERROR("Reader worker failed to open SQLite connection");
return NULL;
}
db_set_thread_connection(worker_db);
while (g_pool.running) {
thread_pool_job_node_t* node = queue_pop(&g_pool.read_q);
if (!node) break;
execute_read_job(node);
}
db_clear_thread_connection();
sqlite3_close(worker_db);
return NULL;
}
static void* writer_worker_main(void* arg) {
(void)arg;
pthread_setname_np(pthread_self(), "db-write");
sqlite3* worker_db = open_worker_connection();
if (!worker_db) {
DEBUG_ERROR("Writer worker failed to open SQLite connection");
return NULL;
}
db_set_thread_connection(worker_db);
while (g_pool.running) {
thread_pool_job_node_t* node = queue_pop(&g_pool.write_q);
if (!node) break;
execute_write_job(node);
}
db_clear_thread_connection();
sqlite3_close(worker_db);
return NULL;
}
@@ -417,10 +472,21 @@ int thread_pool_init(const thread_pool_config_t* config) {
g_pool.next_job_id = 1;
g_pool.wake_loop_cb = config->wake_loop_cb;
g_pool.wake_loop_ctx = config->wake_loop_ctx;
const char* db_path = (config->db_path && config->db_path[0] != '\0') ? config->db_path : db_get_database_path();
if (!db_path || db_path[0] == '\0') {
free(g_pool.readers);
g_pool.readers = NULL;
pthread_mutex_unlock(&g_pool.state_mutex);
return -1;
}
strncpy(g_pool.db_path, db_path, sizeof(g_pool.db_path) - 1);
g_pool.db_path[sizeof(g_pool.db_path) - 1] = '\0';
g_pool.running = 1;
for (int i = 0; i < g_pool.reader_count; i++) {
if (pthread_create(&g_pool.readers[i], NULL, reader_worker_main, NULL) != 0) {
if (pthread_create(&g_pool.readers[i], NULL, reader_worker_main, (void*)(intptr_t)(i + 1)) != 0) {
g_pool.running = 0;
pthread_cond_broadcast(&g_pool.read_q.cond);
pthread_cond_broadcast(&g_pool.write_q.cond);
+615 -59
View File
@@ -33,6 +33,8 @@
#include "thread_pool.h" // Thread pool scaffold
#include "db_ops.h" // DB abstraction wrappers
#include "main.h" // Async REQ completion integration
// Forward declarations for logging functions
// Forward declarations for configuration functions
@@ -196,7 +198,499 @@ static void check_idle_connections(int idle_timeout_sec) {
}
}
// Hot-path config cache (Phase 4): reduce per-message SQLite config lookups.
typedef struct {
time_t last_refresh;
int ttl_sec;
int nip70_protected_events_enabled;
int nip17_admin_enabled;
int wot_enabled;
int nip42_auth_timeout_sec;
int idle_connection_timeout_sec;
int max_connection_seconds;
int kind_1_status_posts_hours;
int debug_level;
} hot_config_cache_t;
static hot_config_cache_t g_hot_config = {
.last_refresh = 0,
.ttl_sec = 5,
.nip70_protected_events_enabled = 0,
.nip17_admin_enabled = 0,
.wot_enabled = 0,
.nip42_auth_timeout_sec = 10,
.idle_connection_timeout_sec = 30,
.max_connection_seconds = 86400,
.kind_1_status_posts_hours = 0,
.debug_level = -1,
};
static pthread_mutex_t g_hot_config_mutex = PTHREAD_MUTEX_INITIALIZER;
static void refresh_hot_config_if_needed(void) {
time_t now = time(NULL);
pthread_mutex_lock(&g_hot_config_mutex);
if (g_hot_config.last_refresh != 0 && (now - g_hot_config.last_refresh) < g_hot_config.ttl_sec) {
pthread_mutex_unlock(&g_hot_config_mutex);
return;
}
g_hot_config.nip70_protected_events_enabled = get_config_bool("nip70_protected_events_enabled", 0);
g_hot_config.nip17_admin_enabled = get_config_bool("nip17_admin_enabled", 0);
g_hot_config.wot_enabled = get_config_int("wot_enabled", 0);
g_hot_config.nip42_auth_timeout_sec = get_config_int("nip42_auth_timeout_sec", 10);
g_hot_config.idle_connection_timeout_sec = get_config_int("idle_connection_timeout_sec", 30);
g_hot_config.max_connection_seconds = get_config_int("max_connection_seconds", 86400);
g_hot_config.kind_1_status_posts_hours = get_config_int("kind_1_status_posts_hours", 0);
g_hot_config.debug_level = get_config_int("debug_level", -1);
g_hot_config.last_refresh = now;
pthread_mutex_unlock(&g_hot_config_mutex);
}
static int hot_cfg_nip70_protected_events_enabled(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.nip70_protected_events_enabled;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
static int hot_cfg_nip17_admin_enabled(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.nip17_admin_enabled;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
static int hot_cfg_wot_enabled(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.wot_enabled;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
static int hot_cfg_nip42_auth_timeout_sec(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.nip42_auth_timeout_sec;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
static int hot_cfg_idle_connection_timeout_sec(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.idle_connection_timeout_sec;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
static int hot_cfg_max_connection_seconds(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.max_connection_seconds;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
static int hot_cfg_kind_1_status_posts_hours(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.kind_1_status_posts_hours;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
static int hot_cfg_debug_level(void) {
refresh_hot_config_if_needed();
pthread_mutex_lock(&g_hot_config_mutex);
int v = g_hot_config.debug_level;
pthread_mutex_unlock(&g_hot_config_mutex);
return v;
}
// Async EVENT processing (Phase 1): offload signature validation + store_event from main lws thread.
typedef struct async_event_job {
char* event_json;
char event_id[65];
int event_kind;
struct lws* wsi;
struct per_session_data* pss_token;
struct async_event_job* next;
} async_event_job_t;
typedef struct async_event_completion {
struct lws* wsi;
struct per_session_data* pss_token;
char* event_json;
char event_id[65];
int success;
int should_broadcast;
int run_post_actions;
char error_message[512];
struct async_event_completion* next;
} async_event_completion_t;
static pthread_mutex_t g_async_event_job_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_async_event_job_cond = PTHREAD_COND_INITIALIZER;
static async_event_job_t* g_async_event_job_head = NULL;
static async_event_job_t* g_async_event_job_tail = NULL;
static pthread_mutex_t g_async_event_completion_mutex = PTHREAD_MUTEX_INITIALIZER;
static async_event_completion_t* g_async_event_completion_head = NULL;
static async_event_completion_t* g_async_event_completion_tail = NULL;
static pthread_t g_async_event_worker_thread;
static int g_async_event_worker_running = 0;
static void map_validation_error_message(int validation_result, char* out, size_t out_size) {
if (!out || out_size == 0) return;
switch (validation_result) {
case NOSTR_ERROR_INVALID_INPUT:
strncpy(out, "invalid: malformed event structure", out_size - 1);
break;
case NOSTR_ERROR_EVENT_INVALID_SIGNATURE:
strncpy(out, "invalid: signature verification failed", out_size - 1);
break;
case NOSTR_ERROR_EVENT_INVALID_ID:
strncpy(out, "invalid: event id verification failed", out_size - 1);
break;
case NOSTR_ERROR_EVENT_INVALID_PUBKEY:
strncpy(out, "invalid: invalid pubkey format", out_size - 1);
break;
case -103: // NOSTR_ERROR_EVENT_EXPIRED
strncpy(out, "rejected: event expired", out_size - 1);
break;
case -102: // NOSTR_ERROR_NIP42_DISABLED
strncpy(out, "auth-required: NIP-42 authentication required", out_size - 1);
break;
case -101: // NOSTR_ERROR_AUTH_REQUIRED
strncpy(out, "blocked: pubkey not authorized", out_size - 1);
break;
default:
strncpy(out, "error: validation failed", out_size - 1);
break;
}
out[out_size - 1] = '\0';
}
static void send_ok_response(struct lws* wsi,
struct per_session_data* pss,
const char* event_id,
int accepted,
const char* message) {
if (!wsi || !pss || !event_id) {
return;
}
cJSON* response = cJSON_CreateArray();
if (!response) {
return;
}
cJSON_AddItemToArray(response, cJSON_CreateString("OK"));
cJSON_AddItemToArray(response, cJSON_CreateString(event_id));
cJSON_AddItemToArray(response, cJSON_CreateBool(accepted ? 1 : 0));
cJSON_AddItemToArray(response, cJSON_CreateString(message ? message : ""));
char* response_str = cJSON_Print(response);
if (response_str) {
size_t response_len = strlen(response_str);
if (queue_message(wsi, pss, response_str, response_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue OK response message");
}
free(response_str);
}
cJSON_Delete(response);
}
static void async_event_completion_push(async_event_completion_t* completion) {
if (!completion) return;
pthread_mutex_lock(&g_async_event_completion_mutex);
completion->next = NULL;
if (!g_async_event_completion_tail) {
g_async_event_completion_head = completion;
g_async_event_completion_tail = completion;
} else {
g_async_event_completion_tail->next = completion;
g_async_event_completion_tail = completion;
}
pthread_mutex_unlock(&g_async_event_completion_mutex);
}
static async_event_completion_t* async_event_completion_pop(void) {
pthread_mutex_lock(&g_async_event_completion_mutex);
async_event_completion_t* completion = g_async_event_completion_head;
if (completion) {
g_async_event_completion_head = completion->next;
if (!g_async_event_completion_head) {
g_async_event_completion_tail = NULL;
}
}
pthread_mutex_unlock(&g_async_event_completion_mutex);
return completion;
}
static int event_is_async_eligible(cJSON* event, int* out_kind, char event_id_out[65]) {
if (!event || !out_kind || !event_id_out) {
return 0;
}
cJSON* id_obj = cJSON_GetObjectItemCaseSensitive(event, "id");
cJSON* kind_obj = cJSON_GetObjectItemCaseSensitive(event, "kind");
if (!id_obj || !cJSON_IsString(id_obj) || !kind_obj || !cJSON_IsNumber(kind_obj)) {
return 0;
}
const char* event_id = cJSON_GetStringValue(id_obj);
if (!event_id || strlen(event_id) >= 65) {
return 0;
}
int kind = (int)cJSON_GetNumberValue(kind_obj);
// Keep special/admin paths on main thread for existing behavior.
if (kind == 14 || kind == 1059 || kind == 23456) {
return 0;
}
strncpy(event_id_out, event_id, 64);
event_id_out[64] = '\0';
*out_kind = kind;
return 1;
}
static async_event_job_t* async_event_job_pop_blocking(void) {
pthread_mutex_lock(&g_async_event_job_mutex);
while (g_async_event_worker_running && !g_async_event_job_head) {
pthread_cond_wait(&g_async_event_job_cond, &g_async_event_job_mutex);
}
async_event_job_t* job = g_async_event_job_head;
if (job) {
g_async_event_job_head = job->next;
if (!g_async_event_job_head) {
g_async_event_job_tail = NULL;
}
}
pthread_mutex_unlock(&g_async_event_job_mutex);
return job;
}
static void* async_event_worker_main(void* arg) {
(void)arg;
pthread_setname_np(pthread_self(), "event-worker");
while (g_async_event_worker_running) {
async_event_job_t* job = async_event_job_pop_blocking();
if (!job) {
continue;
}
async_event_completion_t* completion = calloc(1, sizeof(*completion));
if (!completion) {
free(job->event_json);
free(job);
continue;
}
completion->wsi = job->wsi;
completion->pss_token = job->pss_token;
completion->event_json = job->event_json; // transfer ownership
strncpy(completion->event_id, job->event_id, sizeof(completion->event_id) - 1);
completion->event_id[sizeof(completion->event_id) - 1] = '\0';
int validation_result = nostr_validate_unified_request(completion->event_json, strlen(completion->event_json));
if (validation_result != NOSTR_SUCCESS) {
completion->success = 0;
completion->should_broadcast = 0;
map_validation_error_message(validation_result, completion->error_message, sizeof(completion->error_message));
} else {
cJSON* event_obj = cJSON_Parse(completion->event_json);
if (!event_obj || !cJSON_IsObject(event_obj)) {
completion->success = 0;
completion->should_broadcast = 0;
strncpy(completion->error_message, "error: failed to parse event", sizeof(completion->error_message) - 1);
completion->error_message[sizeof(completion->error_message) - 1] = '\0';
} else {
if (job->event_kind >= 20000 && job->event_kind < 30000) {
completion->success = 1;
completion->should_broadcast = 1;
completion->run_post_actions = 0;
} else {
int core_rc = store_event_core(event_obj);
if (core_rc < 0) {
completion->success = 0;
completion->should_broadcast = 0;
completion->run_post_actions = 0;
strncpy(completion->error_message, "error: failed to store event", sizeof(completion->error_message) - 1);
completion->error_message[sizeof(completion->error_message) - 1] = '\0';
} else {
completion->success = 1;
completion->should_broadcast = 1;
completion->run_post_actions = (core_rc == 0);
}
}
cJSON_Delete(event_obj);
}
}
async_event_completion_push(completion);
if (ws_context) {
lws_cancel_service(ws_context);
}
free(job);
}
return NULL;
}
static int start_async_event_worker(void) {
if (g_async_event_worker_running) {
return 0;
}
g_async_event_worker_running = 1;
if (pthread_create(&g_async_event_worker_thread, NULL, async_event_worker_main, NULL) != 0) {
g_async_event_worker_running = 0;
return -1;
}
return 0;
}
static void stop_async_event_worker(void) {
if (!g_async_event_worker_running) {
return;
}
pthread_mutex_lock(&g_async_event_job_mutex);
g_async_event_worker_running = 0;
pthread_cond_broadcast(&g_async_event_job_cond);
pthread_mutex_unlock(&g_async_event_job_mutex);
pthread_join(g_async_event_worker_thread, NULL);
pthread_mutex_lock(&g_async_event_job_mutex);
async_event_job_t* job = g_async_event_job_head;
while (job) {
async_event_job_t* next = job->next;
free(job->event_json);
free(job);
job = next;
}
g_async_event_job_head = g_async_event_job_tail = NULL;
pthread_mutex_unlock(&g_async_event_job_mutex);
async_event_completion_t* completion = NULL;
while ((completion = async_event_completion_pop()) != NULL) {
free(completion->event_json);
free(completion);
}
}
// Returns:
// 0 => accepted for async handling
// 1 => not eligible (safe to continue with special synchronous path)
// -1 => submit/allocation failure
// -2 => async worker unavailable (do not fall back to synchronous store on lws-main)
static int try_submit_async_event(cJSON* event, const char* event_json, struct lws* wsi, struct per_session_data* pss) {
if (!event || !event_json || !wsi || !pss) {
return 1;
}
if (!g_async_event_worker_running) {
return -2;
}
int event_kind = 0;
char event_id[65] = {0};
if (!event_is_async_eligible(event, &event_kind, event_id)) {
return 1;
}
async_event_job_t* job = calloc(1, sizeof(*job));
if (!job) {
return -1;
}
job->event_json = strdup(event_json);
if (!job->event_json) {
free(job);
return -1;
}
strncpy(job->event_id, event_id, sizeof(job->event_id) - 1);
job->event_id[sizeof(job->event_id) - 1] = '\0';
job->event_kind = event_kind;
job->wsi = wsi;
job->pss_token = pss;
pthread_mutex_lock(&g_async_event_job_mutex);
job->next = NULL;
if (!g_async_event_job_tail) {
g_async_event_job_head = job;
g_async_event_job_tail = job;
} else {
g_async_event_job_tail->next = job;
g_async_event_job_tail = job;
}
pthread_cond_signal(&g_async_event_job_cond);
pthread_mutex_unlock(&g_async_event_job_mutex);
return 0;
}
static void process_async_event_completions(void) {
async_event_completion_t* completion = NULL;
while ((completion = async_event_completion_pop()) != NULL) {
struct per_session_data* current_pss = (struct per_session_data*)lws_wsi_user(completion->wsi);
int target_alive = (current_pss && current_pss == completion->pss_token);
int needs_event_obj = completion->run_post_actions ||
(target_alive && completion->success && completion->should_broadcast);
if (completion->success && needs_event_obj) {
cJSON* event_obj = cJSON_Parse(completion->event_json);
if (event_obj && cJSON_IsObject(event_obj)) {
// Must run on main lws thread due config/monitoring DB access.
if (completion->run_post_actions) {
store_event_post_actions(event_obj);
}
if (target_alive && completion->should_broadcast) {
broadcast_event_to_subscriptions(event_obj);
}
cJSON_Delete(event_obj);
} else {
completion->success = 0;
strncpy(completion->error_message, "error: failed to process event", sizeof(completion->error_message) - 1);
completion->error_message[sizeof(completion->error_message) - 1] = '\0';
if (event_obj) {
cJSON_Delete(event_obj);
}
}
}
if (target_alive) {
send_ok_response(completion->wsi,
current_pss,
completion->event_id,
completion->success,
completion->success ? "" : completion->error_message);
}
free(completion->event_json);
free(completion);
}
}
// Message queue functions for proper libwebsockets pattern
@@ -664,7 +1158,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
// Initialize session activity tracking
pss->session_active = 0;
pss->idle_timeout_sec = get_config_int("idle_connection_timeout_sec", 30);
pss->idle_timeout_sec = hot_cfg_idle_connection_timeout_sec();
// Set idle timeout for ALL connections (not just auth-required)
// This catches bots that connect and do nothing
@@ -676,7 +1170,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
// Also set auth timeout if auth is required (separate concern)
if (pss->nip42_auth_required_events || pss->nip42_auth_required_subscriptions) {
int auth_timeout = get_config_int("nip42_auth_timeout_sec", 10);
int auth_timeout = hot_cfg_nip42_auth_timeout_sec();
// Use the shorter of the two timeouts
int effective_timeout = (pss->idle_timeout_sec > 0 && pss->idle_timeout_sec < auth_timeout)
? pss->idle_timeout_sec
@@ -842,7 +1336,27 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
}
}
// Call unified validator with JSON string
// Try async EVENT offload first (Phase 1).
int async_submit_rc = try_submit_async_event(event, event_json_str, wsi, pss);
if (async_submit_rc == 0) {
free(event_json_str);
cJSON_Delete(json);
return 0;
}
if (async_submit_rc < 0) {
cJSON* event_id = cJSON_GetObjectItemCaseSensitive(event, "id");
if (event_id && cJSON_IsString(event_id)) {
const char* async_err = (async_submit_rc == -2)
? "error: async event worker unavailable"
: "error: async event queue unavailable";
send_ok_response(wsi, pss, cJSON_GetStringValue(event_id), 0, async_err);
}
free(event_json_str);
cJSON_Delete(json);
return 0;
}
// Call unified validator with JSON string (sync path for special ineligible events)
size_t event_json_len = strlen(event_json_str);
int validation_result = nostr_validate_unified_request(event_json_str, event_json_len);
@@ -903,8 +1417,8 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
}
if (is_protected_event) {
// Check if protected events are enabled using config
int protected_events_enabled = get_config_bool("nip70_protected_events_enabled", 0);
// Check if protected events are enabled using hot-path cache
int protected_events_enabled = hot_cfg_nip70_protected_events_enabled();
if (!protected_events_enabled) {
// Protected events not supported
@@ -1012,7 +1526,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
// NIP-17 gift wrap events
// Admin DM processing is opt-in via nip17_admin_enabled config (default: off)
// to prevent expensive decryption on every incoming gift wrap event
int nip17_admin_enabled = get_config_bool("nip17_admin_enabled", 0);
int nip17_admin_enabled = hot_cfg_nip17_admin_enabled();
if (nip17_admin_enabled) {
char nip17_error[512] = {0};
cJSON* response_event = process_nip17_admin_message(event, nip17_error, sizeof(nip17_error), wsi);
@@ -1165,7 +1679,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
// Auth timeout: close connection if challenge was sent but client
// hasn't authenticated within nip42_auth_timeout_sec seconds
int auth_timeout = get_config_int("nip42_auth_timeout_sec", 10);
int auth_timeout = hot_cfg_nip42_auth_timeout_sec();
if (auth_timeout > 0 && pss->connection_established > 0) {
time_t connection_age = time(NULL) - pss->connection_established;
if (connection_age >= auth_timeout) {
@@ -1186,7 +1700,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
// WoT read restriction check (wot_enabled == 2)
// After NIP-42 auth, check if authenticated pubkey is in WoT whitelist
if (pss && pss->authenticated && get_config_int("wot_enabled", 0) == 2) {
if (pss && pss->authenticated && hot_cfg_wot_enabled() == 2) {
// Client is authenticated - check if their pubkey is in the WoT whitelist
extern int check_database_auth_rules(const char* pubkey, const char* operation, const char* resource_hash);
int wot_result = check_database_auth_rules(pss->authenticated_pubkey, "subscription", NULL);
@@ -1286,38 +1800,41 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
DEBUG_TRACE("REQ filters validated successfully");
DEBUG_TRACE("About to call handle_req_message for subscription %s", subscription_id);
handle_req_message(subscription_id, filters, wsi, pss);
int req_result = handle_req_message(subscription_id, filters, wsi, pss);
DEBUG_TRACE("handle_req_message completed for subscription %s", subscription_id);
// Clean up the filters array we created
cJSON_Delete(filters);
DEBUG_LOG("REQ subscription %s processed, sending EOSE", subscription_id);
// Async path will send EOSE from completion handler.
if (req_result != HANDLE_REQ_ASYNC_PENDING) {
DEBUG_LOG("REQ subscription %s processed, sending EOSE", subscription_id);
// Send EOSE (End of Stored Events)
cJSON* eose_response = cJSON_CreateArray();
if (eose_response) {
cJSON_AddItemToArray(eose_response, cJSON_CreateString("EOSE"));
cJSON_AddItemToArray(eose_response, cJSON_CreateString(subscription_id));
// Send EOSE (End of Stored Events)
cJSON* eose_response = cJSON_CreateArray();
if (eose_response) {
cJSON_AddItemToArray(eose_response, cJSON_CreateString("EOSE"));
cJSON_AddItemToArray(eose_response, cJSON_CreateString(subscription_id));
char *eose_str = cJSON_Print(eose_response);
if (eose_str) {
size_t eose_len = strlen(eose_str);
char *eose_str = cJSON_Print(eose_response);
if (eose_str) {
size_t eose_len = strlen(eose_str);
// DEBUG: Log WebSocket frame details before sending
DEBUG_TRACE("WS_FRAME_SEND: type=EOSE len=%zu data=%.100s%s",
eose_len,
eose_str,
eose_len > 100 ? "..." : "");
// DEBUG: Log WebSocket frame details before sending
DEBUG_TRACE("WS_FRAME_SEND: type=EOSE len=%zu data=%.100s%s",
eose_len,
eose_str,
eose_len > 100 ? "..." : "");
// Queue message for proper libwebsockets pattern
if (queue_message(wsi, pss, eose_str, eose_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue EOSE message");
// Queue message for proper libwebsockets pattern
if (queue_message(wsi, pss, eose_str, eose_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue EOSE message");
}
free(eose_str);
}
free(eose_str);
cJSON_Delete(eose_response);
}
cJSON_Delete(eose_response);
}
} else {
send_notice_message(wsi, pss, "error: missing or invalid subscription ID in REQ");
@@ -1629,7 +2146,29 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
}
}
// Call unified validator with JSON string
// Try async EVENT offload first (Phase 1).
int async_submit_rc = try_submit_async_event(event, event_json_str, wsi, pss);
if (async_submit_rc == 0) {
free(event_json_str);
cJSON_Delete(json);
free(message);
return 0;
}
if (async_submit_rc < 0) {
cJSON* event_id = cJSON_GetObjectItemCaseSensitive(event, "id");
if (event_id && cJSON_IsString(event_id)) {
const char* async_err = (async_submit_rc == -2)
? "error: async event worker unavailable"
: "error: async event queue unavailable";
send_ok_response(wsi, pss, cJSON_GetStringValue(event_id), 0, async_err);
}
free(event_json_str);
cJSON_Delete(json);
free(message);
return 0;
}
// Call unified validator with JSON string (sync path for special ineligible events)
size_t event_json_len = strlen(event_json_str);
int validation_result = nostr_validate_unified_request(event_json_str, event_json_len);
@@ -1691,8 +2230,8 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
}
if (is_protected_event) {
// Check if protected events are enabled using config
int protected_events_enabled = get_config_bool("nip70_protected_events_enabled", 0);
// Check if protected events are enabled using hot-path cache
int protected_events_enabled = hot_cfg_nip70_protected_events_enabled();
if (!protected_events_enabled) {
// Protected events not supported
@@ -1800,7 +2339,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
// NIP-17 gift wrap events
// Admin DM processing is opt-in via nip17_admin_enabled config (default: off)
// to prevent expensive decryption on every incoming gift wrap event
int nip17_admin_enabled = get_config_bool("nip17_admin_enabled", 0);
int nip17_admin_enabled = hot_cfg_nip17_admin_enabled();
if (nip17_admin_enabled) {
char nip17_error[512] = {0};
cJSON* response_event = process_nip17_admin_message(event, nip17_error, sizeof(nip17_error), wsi);
@@ -1955,7 +2494,7 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
// Auth timeout: close connection if challenge was sent but client
// hasn't authenticated within nip42_auth_timeout_sec seconds
int auth_timeout = get_config_int("nip42_auth_timeout_sec", 10);
int auth_timeout = hot_cfg_nip42_auth_timeout_sec();
if (auth_timeout > 0 && pss->connection_established > 0) {
time_t connection_age = time(NULL) - pss->connection_established;
if (connection_age >= auth_timeout) {
@@ -2058,38 +2597,41 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
DEBUG_TRACE("REQ filters validated successfully");
DEBUG_TRACE("About to call handle_req_message for subscription %s", subscription_id);
handle_req_message(subscription_id, filters, wsi, pss);
int req_result = handle_req_message(subscription_id, filters, wsi, pss);
DEBUG_TRACE("handle_req_message completed for subscription %s", subscription_id);
// Clean up the filters array we created
cJSON_Delete(filters);
DEBUG_LOG("REQ subscription %s processed, sending EOSE", subscription_id);
// Async path will send EOSE from completion handler.
if (req_result != HANDLE_REQ_ASYNC_PENDING) {
DEBUG_LOG("REQ subscription %s processed, sending EOSE", subscription_id);
// Send EOSE (End of Stored Events)
cJSON* eose_response = cJSON_CreateArray();
if (eose_response) {
cJSON_AddItemToArray(eose_response, cJSON_CreateString("EOSE"));
cJSON_AddItemToArray(eose_response, cJSON_CreateString(subscription_id));
// Send EOSE (End of Stored Events)
cJSON* eose_response = cJSON_CreateArray();
if (eose_response) {
cJSON_AddItemToArray(eose_response, cJSON_CreateString("EOSE"));
cJSON_AddItemToArray(eose_response, cJSON_CreateString(subscription_id));
char *eose_str = cJSON_Print(eose_response);
if (eose_str) {
size_t eose_len = strlen(eose_str);
char *eose_str = cJSON_Print(eose_response);
if (eose_str) {
size_t eose_len = strlen(eose_str);
// DEBUG: Log WebSocket frame details before sending
DEBUG_TRACE("WS_FRAME_SEND: type=EOSE len=%zu data=%.100s%s",
eose_len,
eose_str,
eose_len > 100 ? "..." : "");
// DEBUG: Log WebSocket frame details before sending
DEBUG_TRACE("WS_FRAME_SEND: type=EOSE len=%zu data=%.100s%s",
eose_len,
eose_str,
eose_len > 100 ? "..." : "");
// Queue message for proper libwebsockets pattern
if (queue_message(wsi, pss, eose_str, eose_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue EOSE message");
// Queue message for proper libwebsockets pattern
if (queue_message(wsi, pss, eose_str, eose_len, LWS_WRITE_TEXT) != 0) {
DEBUG_ERROR("Failed to queue EOSE message");
}
free(eose_str);
}
free(eose_str);
cJSON_Delete(eose_response);
}
cJSON_Delete(eose_response);
}
} else {
send_notice_message(wsi, pss, "error: missing or invalid subscription ID in REQ");
@@ -2638,6 +3180,12 @@ int start_websocket_relay(int port_override, int strict_port) {
// Static variable for connection age check timing
static time_t last_connection_age_check = 0;
if (start_async_event_worker() != 0) {
DEBUG_WARN("Async event worker failed to start; EVENT path will remain synchronous");
}
pthread_setname_np(pthread_self(), "lws-main");
// Main event loop with proper signal handling
while (g_server_running && !g_shutdown_flag) {
int result = lws_service(ws_context, 1000);
@@ -2647,9 +3195,15 @@ int start_websocket_relay(int port_override, int strict_port) {
break;
}
// Drain completed async REQ jobs and emit EVENT/EOSE on service thread.
process_req_async_completions();
// Drain completed async EVENT jobs and emit OK/broadcast on service thread.
process_async_event_completions();
// Check if it's time to post status update
time_t current_time = time(NULL);
int status_post_hours = get_config_int("kind_1_status_posts_hours", 0);
int status_post_hours = hot_cfg_kind_1_status_posts_hours();
if (status_post_hours > 0) {
int seconds_interval = status_post_hours * 3600; // Convert hours to seconds
@@ -2661,19 +3215,19 @@ int start_websocket_relay(int port_override, int strict_port) {
}
// Check connection age limits and run IP ban maintenance (every 60 seconds)
int max_connection_seconds = get_config_int("max_connection_seconds", 86400);
int max_connection_seconds = hot_cfg_max_connection_seconds();
if (current_time - last_connection_age_check >= 60) {
last_connection_age_check = current_time;
// Live debug level update: read from config table so it can be changed
// without restarting the relay (via config_set admin command or direct SQL)
int config_debug_level = get_config_int("debug_level", -1);
int config_debug_level = hot_cfg_debug_level();
if (config_debug_level >= 0 && config_debug_level != g_debug_level) {
DEBUG_WARN("Debug level changed: %d -> %d", g_debug_level, config_debug_level);
g_debug_level = config_debug_level;
}
// Check and close idle connections (no REQ/EVENT sent within timeout)
int idle_timeout_sec = get_config_int("idle_connection_timeout_sec", 30);
int idle_timeout_sec = hot_cfg_idle_connection_timeout_sec();
check_idle_connections(idle_timeout_sec);
if (max_connection_seconds > 0) {
@@ -2686,6 +3240,8 @@ int start_websocket_relay(int port_override, int strict_port) {
}
}
stop_async_event_worker();
lws_context_destroy(ws_context);
ws_context = NULL;
return 0;
-18
View File
@@ -1,18 +0,0 @@
2026-04-01 09:10:57 - ==========================================
2026-04-01 09:10:57 - C-Relay Comprehensive Test Suite Runner
2026-04-01 09:10:57 - ==========================================
2026-04-01 09:10:57 - Relay URL: ws://127.0.0.1:8888
2026-04-01 09:10:57 - Log file: test_results_20260401_091057.log
2026-04-01 09:10:57 - Report file: test_report_20260401_091057.html
2026-04-01 09:10:57 -
2026-04-01 09:10:57 - Checking relay status at ws://127.0.0.1:8888...
2026-04-01 09:10:57 - \033[0;32m✓ Relay HTTP endpoint is accessible\033[0m
2026-04-01 09:10:57 -
2026-04-01 09:10:57 - Starting comprehensive test execution...
2026-04-01 09:10:57 -
2026-04-01 09:10:57 - \033[0;34m=== SECURITY TEST SUITES ===\033[0m
2026-04-01 09:10:57 - ==========================================
2026-04-01 09:10:57 - Running Test Suite: SQL Injection Tests
2026-04-01 09:10:57 - Description: Comprehensive SQL injection vulnerability testing
2026-04-01 09:10:57 - ==========================================
2026-04-01 09:10:57 - \033[0;31mERROR: Test script sql_injection_tests.sh not found\033[0m
-18
View File
@@ -1,18 +0,0 @@
2026-04-01 09:32:38 - ==========================================
2026-04-01 09:32:38 - C-Relay Comprehensive Test Suite Runner
2026-04-01 09:32:38 - ==========================================
2026-04-01 09:32:38 - Relay URL: ws://127.0.0.1:8888
2026-04-01 09:32:38 - Log file: test_results_20260401_093238.log
2026-04-01 09:32:38 - Report file: test_report_20260401_093238.html
2026-04-01 09:32:38 -
2026-04-01 09:32:38 - Checking relay status at ws://127.0.0.1:8888...
2026-04-01 09:32:38 - \033[0;32m✓ Relay HTTP endpoint is accessible\033[0m
2026-04-01 09:32:38 -
2026-04-01 09:32:38 - Starting comprehensive test execution...
2026-04-01 09:32:38 -
2026-04-01 09:32:38 - \033[0;34m=== SECURITY TEST SUITES ===\033[0m
2026-04-01 09:32:38 - ==========================================
2026-04-01 09:32:38 - Running Test Suite: SQL Injection Tests
2026-04-01 09:32:38 - Description: Comprehensive SQL injection vulnerability testing
2026-04-01 09:32:38 - ==========================================
2026-04-01 09:32:38 - \033[0;31mERROR: Test script sql_injection_tests.sh not found\033[0m
+18
View File
@@ -0,0 +1,18 @@
2026-04-01 09:57:22 - ==========================================
2026-04-01 09:57:22 - C-Relay Comprehensive Test Suite Runner
2026-04-01 09:57:22 - ==========================================
2026-04-01 09:57:22 - Relay URL: ws://127.0.0.1:8888
2026-04-01 09:57:22 - Log file: test_results_20260401_095722.log
2026-04-01 09:57:22 - Report file: test_report_20260401_095722.html
2026-04-01 09:57:22 -
2026-04-01 09:57:22 - Checking relay status at ws://127.0.0.1:8888...
2026-04-01 09:57:22 - \033[0;32m✓ Relay HTTP endpoint is accessible\033[0m
2026-04-01 09:57:22 -
2026-04-01 09:57:22 - Starting comprehensive test execution...
2026-04-01 09:57:22 -
2026-04-01 09:57:22 - \033[0;34m=== SECURITY TEST SUITES ===\033[0m
2026-04-01 09:57:22 - ==========================================
2026-04-01 09:57:22 - Running Test Suite: SQL Injection Tests
2026-04-01 09:57:22 - Description: Comprehensive SQL injection vulnerability testing
2026-04-01 09:57:22 - ==========================================
2026-04-01 09:57:22 - \033[0;31mERROR: Test script sql_injection_tests.sh not found\033[0m
+18
View File
@@ -0,0 +1,18 @@
2026-04-01 11:01:47 - ==========================================
2026-04-01 11:01:47 - C-Relay Comprehensive Test Suite Runner
2026-04-01 11:01:47 - ==========================================
2026-04-01 11:01:47 - Relay URL: ws://127.0.0.1:8888
2026-04-01 11:01:47 - Log file: test_results_20260401_110147.log
2026-04-01 11:01:47 - Report file: test_report_20260401_110147.html
2026-04-01 11:01:47 -
2026-04-01 11:01:47 - Checking relay status at ws://127.0.0.1:8888...
2026-04-01 11:01:47 - \033[0;32m✓ Relay HTTP endpoint is accessible\033[0m
2026-04-01 11:01:47 -
2026-04-01 11:01:47 - Starting comprehensive test execution...
2026-04-01 11:01:47 -
2026-04-01 11:01:47 - \033[0;34m=== SECURITY TEST SUITES ===\033[0m
2026-04-01 11:01:47 - ==========================================
2026-04-01 11:01:47 - Running Test Suite: SQL Injection Tests
2026-04-01 11:01:47 - Description: Comprehensive SQL injection vulnerability testing
2026-04-01 11:01:47 - ==========================================
2026-04-01 11:01:47 - \033[0;31mERROR: Test script sql_injection_tests.sh not found\033[0m
+26 -26
View File
@@ -1,5 +1,5 @@
=== NIP-42 Authentication Test Started ===
2026-04-01 05:46:11 - Starting NIP-42 authentication tests
2026-04-01 10:00:44 - Starting NIP-42 authentication tests
[INFO] === Starting NIP-42 Authentication Tests ===
[INFO] Checking dependencies...
[WARNING] wscat not found. Some manual WebSocket tests will be skipped
@@ -7,7 +7,7 @@
[SUCCESS] Dependencies check complete
[INFO] Test 1: Checking NIP-42 support in relay info
[SUCCESS] NIP-42 is advertised in supported NIPs
2026-04-01 05:46:11 - Supported NIPs: 1,2,4,9,11,12,13,15,16,20,22,33,40,42,50,70
2026-04-01 10:00:44 - Supported NIPs: 1,2,4,9,11,12,13,15,16,20,22,33,40,42,50,70
[INFO] Test 2: Testing AUTH challenge generation
[WARNING] Could not extract admin private key from relay.log - using manual test approach
[INFO] Manual test: Connect to relay and send an event without auth to trigger challenge
@@ -15,8 +15,8 @@
[INFO] Generated test keypair: test_pubkey
[INFO] Attempting to publish event without authentication...
[INFO] Publishing test event to relay...
2026-04-01 05:46:12 - Event publish result: connecting to localhost:8888... ok.
{"kind":1,"id":"334754e42c2bd54bdf733fb2c9a28c1e0f33d2275ca2c70f26062187793b37fe","pubkey":"40d9f28055baeba6a9bcac1942a17370add58a95a46985f66c5c14d485573983","created_at":1775036772,"tags":[],"content":"NIP-42 test event - should require auth","sig":"6e81c7335d34a770c72566250ac363aa5a126383a1efe2effe5b4b7e84bf600c4d9531b26e9be188fe884e9bd32aa384d49739815c7fba4594174277b90cbf7d"}
2026-04-01 10:00:45 - Event publish result: connecting to localhost:8888... ok.
{"kind":1,"id":"28174ed72f9ef5484a6596db6c6be181d2ed10e46d8c22a9f7a267becbc9a47a","pubkey":"b5f9adc3b362c0e81569a46648a3996708d6b47754d36c617683f18e1f1daf6b","created_at":1775052045,"tags":[],"content":"NIP-42 test event - should require auth","sig":"0041347b233a21d6542a263634f52f8ca7e3b5ecf07bc37c86f390f1a7ab0bc2051306b14aa70edff020bd7311b259d03c2c35a035b285f9e19051a924546666"}
publishing to ws://localhost:8888... success.
[SUCCESS] Relay requested authentication as expected
[INFO] Test 4: Testing WebSocket AUTH message handling
@@ -26,50 +26,50 @@ publishing to ws://localhost:8888... success.
[WARNING] Could not retrieve configuration events
[INFO] Test 6: Testing NIP-42 performance and stability
[INFO] Testing multiple authentication attempts...
2026-04-01 05:46:13 - Attempt 1: .187311847s - connecting to localhost:8888... ok.
{"kind":1,"id":"470a74d32e1b739e6bfd275c0d03ab1508fb5908c0fa01523e4a3bdce6a95db3","pubkey":"59d792f5cfd57b3a284ce769b5d4b1e8a6eb231c63239cdad7f07d791433e79a","created_at":1775036773,"tags":[],"content":"Performance test event 1","sig":"0c30a125cb67d336413f006a5dfa422d788e177254e496b966854bf45183238d23f6575dba37dec6fa46b6f6b906a25afafcbbcaa7d0c15add89dd7fd1a80c22"}
2026-04-01 10:00:46 - Attempt 1: .195528002s - connecting to localhost:8888... ok.
{"kind":1,"id":"72526c57e50d721bfcdcca23856f2c5d3021c3100f0121538d9d829042e9b8b5","pubkey":"29af457d7eea750c11c836dfbeed3076fa0bf1f1b67a404ee4c25733d9b54238","created_at":1775052046,"tags":[],"content":"Performance test event 1","sig":"1a10db86a39aaf47bda6d0cca5f888691bae32bfd85df8c178dddbf24861503a491bfe4da8d66dfe3e5e0afec7bf8644e7eb69c9f051c601673ae13284f9ab31"}
publishing to ws://localhost:8888... success.
2026-04-01 05:46:13 - Attempt 2: .185565503s - connecting to localhost:8888... ok.
{"kind":1,"id":"e4f9db77d30d8e71ef01b16dcb1179d03462aaf368aae30120898f3758a9d0b9","pubkey":"59d792f5cfd57b3a284ce769b5d4b1e8a6eb231c63239cdad7f07d791433e79a","created_at":1775036773,"tags":[],"content":"Performance test event 2","sig":"24a8f38c2cb230d95120e60a246a1a03ac17d4d195d25f2ae0b2f674c3383287eca53cd7fc61bc3cdc58433a3d2c2108558f4f1a98dcfc02a97b4ec8c537cdde"}
2026-04-01 10:00:46 - Attempt 2: .185198180s - connecting to localhost:8888... ok.
{"kind":1,"id":"84eeb907205806bb88fc353bb83f1bf0149f3c93c18695306d8480d36752878b","pubkey":"29af457d7eea750c11c836dfbeed3076fa0bf1f1b67a404ee4c25733d9b54238","created_at":1775052046,"tags":[],"content":"Performance test event 2","sig":"e568dbca3113966f61e69eff05576d296fac42b5ff2ab7341778acc02cf6e9440b59bf651a8a2995d89180a62ec20ffc1143e211cf2960c5abaa358a82992ac6"}
publishing to ws://localhost:8888... success.
2026-04-01 05:46:14 - Attempt 3: .185110183s - connecting to localhost:8888... ok.
{"kind":1,"id":"4a85e466756452e90358fe5d98fa41bda93b6bc77cb079bb1616ca8873f4fca1","pubkey":"59d792f5cfd57b3a284ce769b5d4b1e8a6eb231c63239cdad7f07d791433e79a","created_at":1775036774,"tags":[],"content":"Performance test event 3","sig":"72ab716ff3b4786309fd4cef27ae8cd9df1e3c1746b5e49ba45c070cafcfb72a5b7ba045e7d798f23b5d82989526b4d3c818509f0eec639c8ad265be85a4728e"}
2026-04-01 10:00:47 - Attempt 3: .197159540s - connecting to localhost:8888... ok.
{"kind":1,"id":"0874716ba0b2a845d379e703226513f90db6228ce958369f4dce5aff3df64c5a","pubkey":"29af457d7eea750c11c836dfbeed3076fa0bf1f1b67a404ee4c25733d9b54238","created_at":1775052046,"tags":[],"content":"Performance test event 3","sig":"e74e885eb464998bddf655c24c95a18d7299908c63fb82a47f8d14af65992f90e73794a9f289b550bc1dec1c0298112d2b25941be7e26e3f17dd66b4c5dc742e"}
publishing to ws://localhost:8888... success.
2026-04-01 05:46:14 - Attempt 4: .185725746s - connecting to localhost:8888... ok.
{"kind":1,"id":"4c05b6359da88f85c0aa4c94a296a465f71bddaa10d849ed0923f972ac0628a9","pubkey":"59d792f5cfd57b3a284ce769b5d4b1e8a6eb231c63239cdad7f07d791433e79a","created_at":1775036774,"tags":[],"content":"Performance test event 4","sig":"3b0c8bd1f3d965a259a0ab228ea4c47defef3ad563ebce860ec65ab0ee341c5305c0988ac88651664d3090ce2ff282a0fe4913231448158c423a74b6e3b2a7a9"}
2026-04-01 10:00:47 - Attempt 4: .202520319s - connecting to localhost:8888... ok.
{"kind":1,"id":"5614d1b795cd028e096720418bb4dbc64870d442c6295b9bb2931564a332099a","pubkey":"29af457d7eea750c11c836dfbeed3076fa0bf1f1b67a404ee4c25733d9b54238","created_at":1775052047,"tags":[],"content":"Performance test event 4","sig":"1c0645a791ab9df573b152b782884bcb5ec2a18b8f4e1c18d7dc2175977b7d1d572674169ea1d2b3e3fa8d228de90f6cc281d56a3ef471ba4f9510e920ed586e"}
publishing to ws://localhost:8888... success.
2026-04-01 05:46:15 - Attempt 5: .184467365s - connecting to localhost:8888... ok.
{"kind":1,"id":"0902e868c5e7909f0143fde7738d5e8f4c42ea0ced2c69a404cfeb6cd686ceaa","pubkey":"59d792f5cfd57b3a284ce769b5d4b1e8a6eb231c63239cdad7f07d791433e79a","created_at":1775036774,"tags":[],"content":"Performance test event 5","sig":"a0754e774e5bc3514dc4cf04ec51cab077413251cfce480e80badccc7660bfe8d1eac87d43c6e332d936cc171d24e8318e1ef5df7425a8218e01af661f291c47"}
2026-04-01 10:00:47 - Attempt 5: .222530325s - connecting to localhost:8888... ok.
{"kind":1,"id":"9139f1eb39c31c43cb9f02e60a0f75a0f99f6c7d9693a69a225c8b3e530f774a","pubkey":"29af457d7eea750c11c836dfbeed3076fa0bf1f1b67a404ee4c25733d9b54238","created_at":1775052047,"tags":[],"content":"Performance test event 5","sig":"bd245a7629c33619c0ed426f631e0c2413adb4488c281bea09886ceb6407b40e247d42f82e374e2f53ee5281f0d8361661a4c613c6414c59d09e5bb23eeeb02d"}
publishing to ws://localhost:8888... success.
[SUCCESS] Performance test completed: 5/5 successful responses
[INFO] Test 7: Testing kind-specific NIP-42 authentication requirements
[INFO] Generated test keypair for kind-specific tests: test_pubkey
[INFO] Testing kind 1 event (regular note) - should work without authentication...
2026-04-01 05:46:15 - Kind 1 event result: connecting to localhost:8888... ok.
{"kind":1,"id":"a1d9545c4ac16c2ab1fae4d5d77cabd368d765533b6f6d1f4dbb3c7859696a5e","pubkey":"06ff6b7ca3c72cc7cebb9fe70ea76b6f79b6226c4dc5adc4ebcc59220c23c9bf","created_at":1775036775,"tags":[],"content":"Regular note - should not require auth","sig":"520796b21690bf03b20da28f30ffc84c9c198d0a908c07540f232f789c7a0327861e1f580d499be15b244bdf66c5c4b1cdf621bfdc5f60b1313d7f40036ffab8"}
2026-04-01 10:00:48 - Kind 1 event result: connecting to localhost:8888... ok.
{"kind":1,"id":"def386c66576a91f144a7321e9520a3ed46f9fecc56d9e79d32a162f249cace9","pubkey":"7c9b00749c966e50d18d4b807b44d4612bf9a8f67925fac3f00d21918b6e7f9c","created_at":1775052048,"tags":[],"content":"Regular note - should not require auth","sig":"7ee8fbf45e96d040df1a688e9bf028faaa49b81b26eeae6452b3a32cd9fd941c27b41734f14268d3deef14dbb19e514d29789211fffb27bfa9b73d20cddcc83e"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 1 event accepted without authentication (correct behavior)
[INFO] Testing kind 4 event (direct message) - should require authentication...
2026-04-01 05:46:25 - Kind 4 event result: connecting to localhost:8888... ok.
{"kind":4,"id":"c047f5a9fb6ff46828d0bb862e4bcc32120e50fc7804d651485e2cdbddaf993a","pubkey":"06ff6b7ca3c72cc7cebb9fe70ea76b6f79b6226c4dc5adc4ebcc59220c23c9bf","created_at":1775036775,"tags":[["p,test_pubkey"]],"content":"This is a direct message - should require auth","sig":"a7a027c302faf75e269d866a1b0137f2fbc02643d76435dc68707d2ba6560af95df709787f4a1a1bc7c1b9951615ad081a97cd7f694da94d5606d17100f0b0dc"}
2026-04-01 10:00:58 - Kind 4 event result: connecting to localhost:8888... ok.
{"kind":4,"id":"a2f2d176a835d17a0c9229c0ce3b1ba61a5eb81308e4a3b3446634f468721238","pubkey":"7c9b00749c966e50d18d4b807b44d4612bf9a8f67925fac3f00d21918b6e7f9c","created_at":1775052048,"tags":[["p,test_pubkey"]],"content":"This is a direct message - should require auth","sig":"441f9caba6ebcec6b6c55d13ffd9571f3fe441a54ddd0692f2868429a5087378d791c97289b8b990560dcf40f5c66e86ba6b41f1de78220a5f389c1f119bb887"}
publishing to ws://localhost:8888...
[SUCCESS] Kind 4 event requested authentication (correct behavior for DMs)
[INFO] Testing kind 14 event (chat message) - should require authentication...
2026-04-01 05:46:36 - Kind 14 event result: connecting to localhost:8888... ok.
{"kind":14,"id":"73e50afdaefdbb01ed021f8c888a87b00aa59e4d68c124101353fabcdfa59ae1","pubkey":"06ff6b7ca3c72cc7cebb9fe70ea76b6f79b6226c4dc5adc4ebcc59220c23c9bf","created_at":1775036786,"tags":[["p,test_pubkey"]],"content":"Chat message - should require auth","sig":"ec2c713e2add876856e6cb0d1d9790c43525c5139a0fe06fbee71898f1042173dc3af9187e6fbccfef7406c1af2f218631a1cdcb7ad73e34553cdf3aecc4f209"}
2026-04-01 10:01:09 - Kind 14 event result: connecting to localhost:8888... ok.
{"kind":14,"id":"e234a6faa63f95cd24f8596fbfac573730533bb0abcde47b4d341ff0acace657","pubkey":"7c9b00749c966e50d18d4b807b44d4612bf9a8f67925fac3f00d21918b6e7f9c","created_at":1775052059,"tags":[["p,test_pubkey"]],"content":"Chat message - should require auth","sig":"fd6ba0ddaa7e2379aa49c5cda6599d0a38264799b228a8e907b948bef645080603f7f910c587f6cfb1ef1bac946c47dc681fdab6abd248376cd552bcd535ef9e"}
publishing to ws://localhost:8888...
[SUCCESS] Kind 14 event requested authentication (correct behavior for DMs)
[INFO] Testing other event kinds - should work without authentication...
2026-04-01 05:46:36 - Kind 0 event result: connecting to localhost:8888... ok.
{"kind":0,"id":"51fe1630721cfa3472ba7c3af911a3164c788a48c6a678179c62be48ac3d1f1c","pubkey":"06ff6b7ca3c72cc7cebb9fe70ea76b6f79b6226c4dc5adc4ebcc59220c23c9bf","created_at":1775036796,"tags":[],"content":"Test event kind 0 - should not require auth","sig":"d72d827742fdc86daf1389c8dad40efc56c22b9744ad23547ea0b0a37598e5c18ccdac20b9ef2e6adf46d7683bff19f2cbc11fb00a252903efc1076c8f613b38"}
2026-04-01 10:01:09 - Kind 0 event result: connecting to localhost:8888... ok.
{"kind":0,"id":"d87b69e8a2c8f6d98229b55cde3f0fe1b70c6cafd080e4462209849338eafc76","pubkey":"7c9b00749c966e50d18d4b807b44d4612bf9a8f67925fac3f00d21918b6e7f9c","created_at":1775052069,"tags":[],"content":"Test event kind 0 - should not require auth","sig":"e3222bd4882c881d039e6790a6a8d9f8e20a71d0f9d5089e98604acaa4feff7c1b1b2d9b4171d640da3bba955408a9391a0fd52334cc4a4165fa932e5163f9dd"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 0 event accepted without authentication (correct)
2026-04-01 05:46:36 - Kind 3 event result: connecting to localhost:8888... ok.
{"kind":3,"id":"bf4155eb8b54bdd73a0b64365666caf886433634693cc3c4ab1d586187fc6bae","pubkey":"06ff6b7ca3c72cc7cebb9fe70ea76b6f79b6226c4dc5adc4ebcc59220c23c9bf","created_at":1775036796,"tags":[],"content":"Test event kind 3 - should not require auth","sig":"d27f654ccc9f95e76aacafcce7d42528545fa90b77d422a17301de6931883d8c00a0a84af56ab5d37a0f425140dbfc227458557f9050597beec42cacd0a15864"}
2026-04-01 10:01:09 - Kind 3 event result: connecting to localhost:8888... ok.
{"kind":3,"id":"ac0d45d7db2818bb5e674d4760711349928cf3d5dc8f1fc3717d9e7274e26fb0","pubkey":"7c9b00749c966e50d18d4b807b44d4612bf9a8f67925fac3f00d21918b6e7f9c","created_at":1775052069,"tags":[],"content":"Test event kind 3 - should not require auth","sig":"b65b317c81bc733ee2ff5921430b34d722e8d177147c5d1cddf14036573223582a3b7232810fc13169eb7a61ab3b99cd37ce13991673fce142d1ea10c702305e"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 3 event accepted without authentication (correct)
2026-04-01 05:46:37 - Kind 7 event result: connecting to localhost:8888... ok.
{"kind":7,"id":"658e0caf1c4b52062363849d55312070005124e8a10202df285078222e523132","pubkey":"06ff6b7ca3c72cc7cebb9fe70ea76b6f79b6226c4dc5adc4ebcc59220c23c9bf","created_at":1775036797,"tags":[],"content":"Test event kind 7 - should not require auth","sig":"50361b3aa6b85747befe20e50e317d8f905128930cec0263494434ec9029089d880ff23cdf071c5b63b8417eff216658f1229c0f0dc5174a9a16a6d5fe38fd4d"}
2026-04-01 10:01:10 - Kind 7 event result: connecting to localhost:8888... ok.
{"kind":7,"id":"ad7e77948a4742abfca2d63c5bb748f3db3940c85841f521b3b7d634bf09955a","pubkey":"7c9b00749c966e50d18d4b807b44d4612bf9a8f67925fac3f00d21918b6e7f9c","created_at":1775052070,"tags":[],"content":"Test event kind 7 - should not require auth","sig":"8a5e5a03956cec04d56934314a0876fccbd221546432aaccdbc249b5f9cedc221219abf6e2856b98675de205afaa0e91ea642933ec6724576a40db43d17aa758"}
publishing to ws://localhost:8888... success.
[SUCCESS] Kind 7 event accepted without authentication (correct)
[INFO] Kind-specific authentication test completed
+733
View File
@@ -0,0 +1,733 @@
2026-04-01 09:57:29 - ==========================================
2026-04-01 09:57:30 - C-Relay Comprehensive Test Suite Runner
2026-04-01 09:57:30 - ==========================================
2026-04-01 09:57:30 - Relay URL: ws://127.0.0.1:8888
2026-04-01 09:57:30 - Log file: test_results_20260401_095729.log
2026-04-01 09:57:30 - Report file: test_report_20260401_095729.html
2026-04-01 09:57:30 -
2026-04-01 09:57:30 - Checking relay status at ws://127.0.0.1:8888...
2026-04-01 09:57:30 - \033[0;32m✓ Relay HTTP endpoint is accessible\033[0m
2026-04-01 09:57:30 -
2026-04-01 09:57:30 - Starting comprehensive test execution...
2026-04-01 09:57:30 -
2026-04-01 09:57:30 - \033[0;34m=== SECURITY TEST SUITES ===\033[0m
2026-04-01 09:57:30 - ==========================================
2026-04-01 09:57:30 - Running Test Suite: SQL Injection Tests
2026-04-01 09:57:30 - Description: Comprehensive SQL injection vulnerability testing
2026-04-01 09:57:30 - ==========================================
==========================================
C-Relay SQL Injection Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - Valid query works
=== Authors Filter SQL Injection Tests ===
Testing Authors filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: #... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== IDs Filter SQL Injection Tests ===
Testing IDs filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: #... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Kinds Filter SQL Injection Tests ===
Testing Kinds filter with string injection... PASSED - SQL injection blocked (rejected with error)
Testing Kinds filter with negative value... PASSED - SQL injection blocked (rejected with error)
Testing Kinds filter with very large value... PASSED - SQL injection blocked (rejected with error)
=== Search Filter SQL Injection Tests ===
Testing Search filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Tag Filter SQL Injection Tests ===
Testing #e tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
=== Timestamp Filter SQL Injection Tests ===
Testing Since parameter injection... PASSED - SQL injection blocked (rejected with error)
Testing Until parameter injection... PASSED - SQL injection blocked (rejected with error)
=== Limit Parameter SQL Injection Tests ===
Testing Limit parameter injection... PASSED - SQL injection blocked (rejected with error)
Testing Limit with UNION... PASSED - SQL injection blocked (rejected with error)
=== Complex Multi-Filter SQL Injection Tests ===
Testing Multi-filter with authors injection... PASSED - SQL injection blocked (rejected with error)
Testing Multi-filter with search injection... PASSED - SQL injection blocked (rejected with error)
Testing Multi-filter with tag injection... PASSED - SQL injection blocked (query sanitized)
=== COUNT Message SQL Injection Tests ===
Testing COUNT with authors payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: */... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: */... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: #... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: #... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Edge Case SQL Injection Tests ===
Testing Empty string injection... PASSED - SQL injection blocked (rejected with error)
Testing Null byte injection... PASSED - SQL injection blocked (silently rejected)
Testing Unicode injection... PASSED - SQL injection blocked (rejected with error)
Testing Very long injection payload... PASSED - SQL injection blocked (rejected with error)
=== Subscription ID SQL Injection Tests ===
Testing Subscription ID injection... PASSED - SQL injection blocked (rejected with error)
Testing Subscription ID with quotes... PASSED - SQL injection blocked (silently rejected)
=== CLOSE Message SQL Injection Tests ===
Testing CLOSE with injection... PASSED - SQL injection blocked (rejected with error)
=== Test Results ===
Total tests: 318
Passed: 318
Failed: 0
✓ All SQL injection tests passed!
The relay appears to be protected against SQL injection attacks.
2026-04-01 09:57:36 - \033[0;32m✓ SQL Injection Tests PASSED\033[0m (Duration: 6s)
2026-04-01 09:57:36 - ==========================================
2026-04-01 09:57:36 - Running Test Suite: Filter Validation Tests
2026-04-01 09:57:36 - Description: Input validation for REQ and COUNT messages
2026-04-01 09:57:36 - ==========================================
=== C-Relay Filter Validation Tests ===
Testing against relay at ws://127.0.0.1:8888
Testing Valid REQ message... PASSED
Testing Valid COUNT message... PASSED
=== Testing Filter Array Validation ===
Testing Non-object filter... PASSED
Testing Too many filters... PASSED
=== Testing Authors Validation ===
Testing Invalid author type... PASSED
Testing Invalid author hex... PASSED
Testing Too many authors... PASSED
=== Testing IDs Validation ===
Testing Invalid ID type... PASSED
Testing Invalid ID hex... PASSED
Testing Too many IDs... PASSED
=== Testing Kinds Validation ===
Testing Invalid kind type... PASSED
Testing Negative kind... PASSED
Testing Too large kind... PASSED
Testing Too many kinds... PASSED
=== Testing Timestamp Validation ===
Testing Invalid since type... PASSED
Testing Negative since... PASSED
Testing Invalid until type... PASSED
Testing Negative until... PASSED
=== Testing Limit Validation ===
Testing Invalid limit type... PASSED
Testing Negative limit... PASSED
Testing Too large limit... PASSED
=== Testing Search Validation ===
Testing Invalid search type... PASSED
Testing Search too long... PASSED
Testing Search SQL injection... PASSED
=== Testing Tag Filter Validation ===
Testing Invalid tag filter type... PASSED
Testing Too many tag values... PASSED
Testing Tag value too long... PASSED
=== Testing Rate Limiting ===
Testing rate limiting with malformed requests... UNCERTAIN - Rate limiting may not have triggered (this could be normal)
=== Test Results ===
Total tests: 28
Passed: 28
Failed: 0
All tests passed!
2026-04-01 09:57:39 - \033[0;32m✓ Filter Validation Tests PASSED\033[0m (Duration: 3s)
2026-04-01 09:57:39 - ==========================================
2026-04-01 09:57:39 - Running Test Suite: Subscription Validation Tests
2026-04-01 09:57:39 - Description: Subscription ID and message validation
2026-04-01 09:57:39 - ==========================================
Testing subscription ID validation fixes...
Testing malformed subscription IDs...
Empty ID test: Connection failed (expected)
Long ID test: Connection failed (expected)
Invalid chars test: Connection failed (expected)
NULL ID test: Connection failed (expected)
Valid ID test: Failed
Testing CLOSE message validation...
CLOSE empty ID test: Connection failed (expected)
CLOSE valid ID test: Failed
Subscription validation tests completed.
2026-04-01 09:57:39 - \033[0;32m✓ Subscription Validation Tests PASSED\033[0m (Duration: 0s)
2026-04-01 09:57:39 - ==========================================
2026-04-01 09:57:39 - Running Test Suite: Memory Corruption Tests
2026-04-01 09:57:39 - Description: Buffer overflow and memory safety testing
2026-04-01 09:57:39 - ==========================================
==========================================
C-Relay Memory Corruption Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
Note: These tests may cause the relay to crash if vulnerabilities exist
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - No memory corruption detected
=== Subscription ID Memory Corruption Tests ===
Testing Empty subscription ID... UNCERTAIN - Expected error but got normal response
Testing Very long subscription ID (1KB)... UNCERTAIN - Expected error but got normal response
Testing Very long subscription ID (10KB)... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with null bytes... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with special chars... UNCERTAIN - Expected error but got normal response
Testing Unicode subscription ID... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with path traversal... UNCERTAIN - Expected error but got normal response
=== Filter Array Memory Corruption Tests ===
Testing Too many filters (50)... UNCERTAIN - Expected error but got normal response
=== Concurrent Access Memory Tests ===
Testing Concurrent subscription creation... ["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
["EVENT","concurrent_1775051860259483357",{"pubkey":"4f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa","created_at":1775051826,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"791ebcdcbe58fd5153b9a1f8f39907b0fcc4d86fc189e35fc9b6365031339b53","sig":"4164e20b9169a57c8086a0430b81af9bcabf69082c1d0d9d869673f2f5b0a350fb0ce882f2a19f08b613a0872edb69a0f8d1ccba0675bacff16c19b7282080e6"}]
PASSED - Concurrent access handled safely
Testing Concurrent CLOSE operations...
PASSED - Concurrent access handled safely
=== Malformed JSON Memory Tests ===
Testing Unclosed JSON object... UNCERTAIN - Expected error but got normal response
Testing Mismatched brackets... UNCERTAIN - Expected error but got normal response
Testing Extra closing brackets... UNCERTAIN - Expected error but got normal response
Testing Null bytes in JSON... UNCERTAIN - Expected error but got normal response
=== Large Message Memory Tests ===
Testing Very large filter array... UNCERTAIN - Expected error but got normal response
Testing Very long search term... UNCERTAIN - Expected error but got normal response
=== Test Results ===
Total tests: 17
Passed: 17
Failed: 0
✓ All memory corruption tests passed!
The relay appears to handle memory safely.
2026-04-01 09:57:40 - \033[0;32m✓ Memory Corruption Tests PASSED\033[0m (Duration: 1s)
2026-04-01 09:57:40 - ==========================================
2026-04-01 09:57:40 - Running Test Suite: Input Validation Tests
2026-04-01 09:57:40 - Description: Comprehensive input boundary testing
2026-04-01 09:57:40 - ==========================================
==========================================
C-Relay Input Validation Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - Input accepted correctly
=== Message Type Validation ===
Testing Invalid message type - string... PASSED - Invalid input properly rejected
Testing Invalid message type - number... PASSED - Invalid input properly rejected
Testing Invalid message type - null... PASSED - Invalid input properly rejected
Testing Invalid message type - object... PASSED - Invalid input properly rejected
Testing Empty message type... PASSED - Invalid input properly rejected
Testing Very long message type... PASSED - Invalid input properly rejected
=== Message Structure Validation ===
Testing Too few arguments... PASSED - Invalid input properly rejected
Testing Too many arguments... PASSED - Invalid input properly rejected
Testing Non-array message... PASSED - Invalid input properly rejected
Testing Empty array... PASSED - Invalid input properly rejected
Testing Nested arrays incorrectly... PASSED - Invalid input properly rejected
=== Subscription ID Boundary Tests ===
Testing Valid subscription ID... PASSED - Input accepted correctly
Testing Empty subscription ID... PASSED - Invalid input properly rejected
Testing Subscription ID with spaces... PASSED - Invalid input properly rejected
Testing Subscription ID with newlines... PASSED - Invalid input properly rejected
Testing Subscription ID with tabs... PASSED - Invalid input properly rejected
Testing Subscription ID with control chars... PASSED - Invalid input properly rejected
Testing Unicode subscription ID... PASSED - Invalid input properly rejected
Testing Very long subscription ID... PASSED - Invalid input properly rejected
=== Filter Object Validation ===
Testing Valid empty filter... PASSED - Input accepted correctly
Testing Non-object filter... PASSED - Invalid input properly rejected
Testing Null filter... PASSED - Invalid input properly rejected
Testing Array filter... PASSED - Invalid input properly rejected
Testing Filter with invalid keys... PASSED - Input accepted correctly
=== Authors Field Validation ===
Testing Valid authors array... PASSED - Input accepted correctly
Testing Empty authors array... PASSED - Input accepted correctly
Testing Non-array authors... PASSED - Invalid input properly rejected
Testing Invalid hex in authors... PASSED - Invalid input properly rejected
Testing Short pubkey in authors... PASSED - Invalid input properly rejected
=== IDs Field Validation ===
Testing Valid ids array... PASSED - Input accepted correctly
Testing Empty ids array... PASSED - Input accepted correctly
Testing Non-array ids... PASSED - Invalid input properly rejected
=== Kinds Field Validation ===
Testing Valid kinds array... PASSED - Input accepted correctly
Testing Empty kinds array... PASSED - Input accepted correctly
Testing Non-array kinds... PASSED - Invalid input properly rejected
Testing String in kinds... PASSED - Invalid input properly rejected
=== Timestamp Field Validation ===
Testing Valid since timestamp... PASSED - Input accepted correctly
Testing Valid until timestamp... PASSED - Input accepted correctly
Testing String since timestamp... PASSED - Invalid input properly rejected
Testing Negative timestamp... PASSED - Invalid input properly rejected
=== Limit Field Validation ===
Testing Valid limit... PASSED - Input accepted correctly
Testing Zero limit... PASSED - Input accepted correctly
Testing String limit... PASSED - Invalid input properly rejected
Testing Negative limit... PASSED - Invalid input properly rejected
=== Multiple Filters ===
Testing Two valid filters... PASSED - Input accepted correctly
Testing Many filters... PASSED - Input accepted correctly
=== Test Results ===
Total tests: 47
Passed: 47
Failed: 0
✓ All input validation tests passed!
The relay properly validates input.
2026-04-01 09:57:41 - \033[0;32m✓ Input Validation Tests PASSED\033[0m (Duration: 1s)
2026-04-01 09:57:41 -
2026-04-01 09:57:41 - \033[0;34m=== PERFORMANCE TEST SUITES ===\033[0m
2026-04-01 09:57:41 - ==========================================
2026-04-01 09:57:41 - Running Test Suite: Subscription Limit Tests
2026-04-01 09:57:41 - Description: Subscription limit enforcement testing
2026-04-01 09:57:41 - ==========================================
=== Subscription Limit Test ===
[INFO] Testing relay at: ws://127.0.0.1:8888
[INFO] Note: This test assumes default subscription limits (max 25 per client)
=== Test 1: Basic Connectivity ===
[INFO] Testing basic WebSocket connection...
[PASS] Basic connectivity works
=== Test 2: Subscription Limit Enforcement ===
[INFO] Testing subscription limits by creating multiple subscriptions...
[INFO] Creating multiple subscriptions within a single connection...
[INFO] Hit subscription limit at subscription 2
[PASS] Subscription limit enforcement working (limit hit after 1 subscriptions)
=== Test Complete ===
2026-04-01 09:57:42 - \033[0;32m✓ Subscription Limit Tests PASSED\033[0m (Duration: 1s)
2026-04-01 09:57:42 - ==========================================
2026-04-01 09:57:42 - Running Test Suite: Load Testing
2026-04-01 09:57:42 - Description: High concurrent connection testing
2026-04-01 09:57:42 - ==========================================
==========================================
C-Relay Load Testing Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
✓ Relay is accessible
==========================================
Load Test: Light Load Test
Description: Basic load test with moderate concurrent connections
Concurrent clients: 10
Messages per client: 5
==========================================
Launching 10 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 1s
Total connections attempted: 10
Successful connections: 10
Failed connections: 0
Connection success rate: 100%
Messages expected: 50
Messages sent: 50
Messages received: 100
✓ EXCELLENT: High connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Medium Load Test
Description: Moderate load test with higher concurrency
Concurrent clients: 25
Messages per client: 10
==========================================
Launching 25 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 4s
Total connections attempted: 35
Successful connections: 25
Failed connections: 0
Connection success rate: 71%
Messages expected: 250
Messages sent: 250
Messages received: 500
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Heavy Load Test
Description: Heavy load test with high concurrency
Concurrent clients: 50
Messages per client: 20
==========================================
Launching 50 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 15s
Total connections attempted: 85
Successful connections: 50
Failed connections: 0
Connection success rate: 58%
Messages expected: 1000
Messages sent: 1000
Messages received: 2000
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Stress Test
Description: Maximum load test to find breaking point
Concurrent clients: 100
Messages per client: 50
==========================================
Launching 100 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 64s
Total connections attempted: 185
Successful connections: 100
Failed connections: 0
Connection success rate: 54%
Messages expected: 5000
Messages sent: 5000
Messages received: 7500
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Testing Complete
==========================================
All load tests completed. Check individual test results above.
If any tests failed, the relay may need optimization or have resource limits.
2026-04-01 09:59:07 - \033[0;32m✓ Load Testing PASSED\033[0m (Duration: 85s)
2026-04-01 09:59:07 - ==========================================
2026-04-01 09:59:07 - Running Test Suite: Stress Testing
2026-04-01 09:59:07 - Description: Resource usage and stability testing
2026-04-01 09:59:07 - ==========================================
2026-04-01 09:59:07 - \033[0;31mERROR: Test script stress_tests.sh not found\033[0m
+733
View File
@@ -0,0 +1,733 @@
2026-04-01 11:02:00 - ==========================================
2026-04-01 11:02:00 - C-Relay Comprehensive Test Suite Runner
2026-04-01 11:02:00 - ==========================================
2026-04-01 11:02:00 - Relay URL: ws://127.0.0.1:8888
2026-04-01 11:02:00 - Log file: test_results_20260401_110200.log
2026-04-01 11:02:00 - Report file: test_report_20260401_110200.html
2026-04-01 11:02:00 -
2026-04-01 11:02:00 - Checking relay status at ws://127.0.0.1:8888...
2026-04-01 11:02:00 - \033[0;32m✓ Relay HTTP endpoint is accessible\033[0m
2026-04-01 11:02:00 -
2026-04-01 11:02:00 - Starting comprehensive test execution...
2026-04-01 11:02:00 -
2026-04-01 11:02:00 - \033[0;34m=== SECURITY TEST SUITES ===\033[0m
2026-04-01 11:02:00 - ==========================================
2026-04-01 11:02:00 - Running Test Suite: SQL Injection Tests
2026-04-01 11:02:00 - Description: Comprehensive SQL injection vulnerability testing
2026-04-01 11:02:00 - ==========================================
==========================================
C-Relay SQL Injection Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - Valid query works
=== Authors Filter SQL Injection Tests ===
Testing Authors filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: #... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== IDs Filter SQL Injection Tests ===
Testing IDs filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: #... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Kinds Filter SQL Injection Tests ===
Testing Kinds filter with string injection... PASSED - SQL injection blocked (rejected with error)
Testing Kinds filter with negative value... PASSED - SQL injection blocked (rejected with error)
Testing Kinds filter with very large value... PASSED - SQL injection blocked (rejected with error)
=== Search Filter SQL Injection Tests ===
Testing Search filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Tag Filter SQL Injection Tests ===
Testing #e tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
=== Timestamp Filter SQL Injection Tests ===
Testing Since parameter injection... PASSED - SQL injection blocked (rejected with error)
Testing Until parameter injection... PASSED - SQL injection blocked (rejected with error)
=== Limit Parameter SQL Injection Tests ===
Testing Limit parameter injection... PASSED - SQL injection blocked (rejected with error)
Testing Limit with UNION... PASSED - SQL injection blocked (rejected with error)
=== Complex Multi-Filter SQL Injection Tests ===
Testing Multi-filter with authors injection... PASSED - SQL injection blocked (rejected with error)
Testing Multi-filter with search injection... PASSED - SQL injection blocked (rejected with error)
Testing Multi-filter with tag injection... PASSED - SQL injection blocked (query sanitized)
=== COUNT Message SQL Injection Tests ===
Testing COUNT with authors payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: */... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: */... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: #... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: #... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Edge Case SQL Injection Tests ===
Testing Empty string injection... PASSED - SQL injection blocked (rejected with error)
Testing Null byte injection... PASSED - SQL injection blocked (silently rejected)
Testing Unicode injection... PASSED - SQL injection blocked (rejected with error)
Testing Very long injection payload... PASSED - SQL injection blocked (rejected with error)
=== Subscription ID SQL Injection Tests ===
Testing Subscription ID injection... PASSED - SQL injection blocked (rejected with error)
Testing Subscription ID with quotes... PASSED - SQL injection blocked (silently rejected)
=== CLOSE Message SQL Injection Tests ===
Testing CLOSE with injection... PASSED - SQL injection blocked (rejected with error)
=== Test Results ===
Total tests: 318
Passed: 318
Failed: 0
✓ All SQL injection tests passed!
The relay appears to be protected against SQL injection attacks.
2026-04-01 11:02:07 - \033[0;32m✓ SQL Injection Tests PASSED\033[0m (Duration: 7s)
2026-04-01 11:02:07 - ==========================================
2026-04-01 11:02:07 - Running Test Suite: Filter Validation Tests
2026-04-01 11:02:07 - Description: Input validation for REQ and COUNT messages
2026-04-01 11:02:07 - ==========================================
=== C-Relay Filter Validation Tests ===
Testing against relay at ws://127.0.0.1:8888
Testing Valid REQ message... PASSED
Testing Valid COUNT message... PASSED
=== Testing Filter Array Validation ===
Testing Non-object filter... PASSED
Testing Too many filters... PASSED
=== Testing Authors Validation ===
Testing Invalid author type... PASSED
Testing Invalid author hex... PASSED
Testing Too many authors... PASSED
=== Testing IDs Validation ===
Testing Invalid ID type... PASSED
Testing Invalid ID hex... PASSED
Testing Too many IDs... PASSED
=== Testing Kinds Validation ===
Testing Invalid kind type... PASSED
Testing Negative kind... PASSED
Testing Too large kind... PASSED
Testing Too many kinds... PASSED
=== Testing Timestamp Validation ===
Testing Invalid since type... PASSED
Testing Negative since... PASSED
Testing Invalid until type... PASSED
Testing Negative until... PASSED
=== Testing Limit Validation ===
Testing Invalid limit type... PASSED
Testing Negative limit... PASSED
Testing Too large limit... PASSED
=== Testing Search Validation ===
Testing Invalid search type... PASSED
Testing Search too long... PASSED
Testing Search SQL injection... PASSED
=== Testing Tag Filter Validation ===
Testing Invalid tag filter type... PASSED
Testing Too many tag values... PASSED
Testing Tag value too long... PASSED
=== Testing Rate Limiting ===
Testing rate limiting with malformed requests... UNCERTAIN - Rate limiting may not have triggered (this could be normal)
=== Test Results ===
Total tests: 28
Passed: 28
Failed: 0
All tests passed!
2026-04-01 11:02:10 - \033[0;32m✓ Filter Validation Tests PASSED\033[0m (Duration: 3s)
2026-04-01 11:02:10 - ==========================================
2026-04-01 11:02:10 - Running Test Suite: Subscription Validation Tests
2026-04-01 11:02:10 - Description: Subscription ID and message validation
2026-04-01 11:02:10 - ==========================================
Testing subscription ID validation fixes...
Testing malformed subscription IDs...
Empty ID test: Connection failed (expected)
Long ID test: Connection failed (expected)
Invalid chars test: Connection failed (expected)
NULL ID test: Connection failed (expected)
Valid ID test: Failed
Testing CLOSE message validation...
CLOSE empty ID test: Connection failed (expected)
CLOSE valid ID test: Failed
Subscription validation tests completed.
2026-04-01 11:02:10 - \033[0;32m✓ Subscription Validation Tests PASSED\033[0m (Duration: 0s)
2026-04-01 11:02:10 - ==========================================
2026-04-01 11:02:10 - Running Test Suite: Memory Corruption Tests
2026-04-01 11:02:10 - Description: Buffer overflow and memory safety testing
2026-04-01 11:02:10 - ==========================================
==========================================
C-Relay Memory Corruption Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
Note: These tests may cause the relay to crash if vulnerabilities exist
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - No memory corruption detected
=== Subscription ID Memory Corruption Tests ===
Testing Empty subscription ID... UNCERTAIN - Expected error but got normal response
Testing Very long subscription ID (1KB)... UNCERTAIN - Expected error but got normal response
Testing Very long subscription ID (10KB)... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with null bytes... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with special chars... UNCERTAIN - Expected error but got normal response
Testing Unicode subscription ID... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with path traversal... UNCERTAIN - Expected error but got normal response
=== Filter Array Memory Corruption Tests ===
Testing Too many filters (50)... UNCERTAIN - Expected error but got normal response
=== Concurrent Access Memory Tests ===
Testing Concurrent subscription creation... ["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
["EVENT","concurrent_1775055730660028379",{"pubkey":"26a8961265cc6db56d18b95fb54ad16a54259ab4342a2bd83e102846cb120e94","created_at":1775055645,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"f5ac528fb84b75bdef8050a56f0c2b4733389b2d97f91344811a7c3bf7e0bc4d","sig":"8c7480c64a4db80b643f60d4d6d38b5585bd6b10da3dbee0eab7b60796ee18826400162242c7056782a410de0b119860ba3210bffba78f0f6be466634e3b6940"}]
PASSED - Concurrent access handled safely
Testing Concurrent CLOSE operations...
PASSED - Concurrent access handled safely
=== Malformed JSON Memory Tests ===
Testing Unclosed JSON object... UNCERTAIN - Expected error but got normal response
Testing Mismatched brackets... UNCERTAIN - Expected error but got normal response
Testing Extra closing brackets... UNCERTAIN - Expected error but got normal response
Testing Null bytes in JSON... UNCERTAIN - Expected error but got normal response
=== Large Message Memory Tests ===
Testing Very large filter array... UNCERTAIN - Expected error but got normal response
Testing Very long search term... UNCERTAIN - Expected error but got normal response
=== Test Results ===
Total tests: 17
Passed: 17
Failed: 0
✓ All memory corruption tests passed!
The relay appears to handle memory safely.
2026-04-01 11:02:11 - \033[0;32m✓ Memory Corruption Tests PASSED\033[0m (Duration: 1s)
2026-04-01 11:02:11 - ==========================================
2026-04-01 11:02:11 - Running Test Suite: Input Validation Tests
2026-04-01 11:02:11 - Description: Comprehensive input boundary testing
2026-04-01 11:02:11 - ==========================================
==========================================
C-Relay Input Validation Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - Input accepted correctly
=== Message Type Validation ===
Testing Invalid message type - string... PASSED - Invalid input properly rejected
Testing Invalid message type - number... PASSED - Invalid input properly rejected
Testing Invalid message type - null... PASSED - Invalid input properly rejected
Testing Invalid message type - object... PASSED - Invalid input properly rejected
Testing Empty message type... PASSED - Invalid input properly rejected
Testing Very long message type... PASSED - Invalid input properly rejected
=== Message Structure Validation ===
Testing Too few arguments... PASSED - Invalid input properly rejected
Testing Too many arguments... PASSED - Invalid input properly rejected
Testing Non-array message... PASSED - Invalid input properly rejected
Testing Empty array... PASSED - Invalid input properly rejected
Testing Nested arrays incorrectly... PASSED - Invalid input properly rejected
=== Subscription ID Boundary Tests ===
Testing Valid subscription ID... PASSED - Input accepted correctly
Testing Empty subscription ID... PASSED - Invalid input properly rejected
Testing Subscription ID with spaces... PASSED - Invalid input properly rejected
Testing Subscription ID with newlines... PASSED - Invalid input properly rejected
Testing Subscription ID with tabs... PASSED - Invalid input properly rejected
Testing Subscription ID with control chars... PASSED - Invalid input properly rejected
Testing Unicode subscription ID... PASSED - Invalid input properly rejected
Testing Very long subscription ID... PASSED - Invalid input properly rejected
=== Filter Object Validation ===
Testing Valid empty filter... PASSED - Input accepted correctly
Testing Non-object filter... PASSED - Invalid input properly rejected
Testing Null filter... PASSED - Invalid input properly rejected
Testing Array filter... PASSED - Invalid input properly rejected
Testing Filter with invalid keys... PASSED - Input accepted correctly
=== Authors Field Validation ===
Testing Valid authors array... PASSED - Input accepted correctly
Testing Empty authors array... PASSED - Input accepted correctly
Testing Non-array authors... PASSED - Invalid input properly rejected
Testing Invalid hex in authors... PASSED - Invalid input properly rejected
Testing Short pubkey in authors... PASSED - Invalid input properly rejected
=== IDs Field Validation ===
Testing Valid ids array... PASSED - Input accepted correctly
Testing Empty ids array... PASSED - Input accepted correctly
Testing Non-array ids... PASSED - Invalid input properly rejected
=== Kinds Field Validation ===
Testing Valid kinds array... PASSED - Input accepted correctly
Testing Empty kinds array... PASSED - Input accepted correctly
Testing Non-array kinds... PASSED - Invalid input properly rejected
Testing String in kinds... PASSED - Invalid input properly rejected
=== Timestamp Field Validation ===
Testing Valid since timestamp... PASSED - Input accepted correctly
Testing Valid until timestamp... PASSED - Input accepted correctly
Testing String since timestamp... PASSED - Invalid input properly rejected
Testing Negative timestamp... PASSED - Invalid input properly rejected
=== Limit Field Validation ===
Testing Valid limit... PASSED - Input accepted correctly
Testing Zero limit... PASSED - Input accepted correctly
Testing String limit... PASSED - Invalid input properly rejected
Testing Negative limit... PASSED - Invalid input properly rejected
=== Multiple Filters ===
Testing Two valid filters... PASSED - Input accepted correctly
Testing Many filters... PASSED - Input accepted correctly
=== Test Results ===
Total tests: 47
Passed: 47
Failed: 0
✓ All input validation tests passed!
The relay properly validates input.
2026-04-01 11:02:12 - \033[0;32m✓ Input Validation Tests PASSED\033[0m (Duration: 1s)
2026-04-01 11:02:12 -
2026-04-01 11:02:12 - \033[0;34m=== PERFORMANCE TEST SUITES ===\033[0m
2026-04-01 11:02:12 - ==========================================
2026-04-01 11:02:12 - Running Test Suite: Subscription Limit Tests
2026-04-01 11:02:12 - Description: Subscription limit enforcement testing
2026-04-01 11:02:12 - ==========================================
=== Subscription Limit Test ===
[INFO] Testing relay at: ws://127.0.0.1:8888
[INFO] Note: This test assumes default subscription limits (max 25 per client)
=== Test 1: Basic Connectivity ===
[INFO] Testing basic WebSocket connection...
[PASS] Basic connectivity works
=== Test 2: Subscription Limit Enforcement ===
[INFO] Testing subscription limits by creating multiple subscriptions...
[INFO] Creating multiple subscriptions within a single connection...
[INFO] Hit subscription limit at subscription 2
[PASS] Subscription limit enforcement working (limit hit after 1 subscriptions)
=== Test Complete ===
2026-04-01 11:02:12 - \033[0;32m✓ Subscription Limit Tests PASSED\033[0m (Duration: 0s)
2026-04-01 11:02:12 - ==========================================
2026-04-01 11:02:12 - Running Test Suite: Load Testing
2026-04-01 11:02:12 - Description: High concurrent connection testing
2026-04-01 11:02:12 - ==========================================
==========================================
C-Relay Load Testing Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
✓ Relay is accessible
==========================================
Load Test: Light Load Test
Description: Basic load test with moderate concurrent connections
Concurrent clients: 10
Messages per client: 5
==========================================
Launching 10 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 1s
Total connections attempted: 10
Successful connections: 10
Failed connections: 0
Connection success rate: 100%
Messages expected: 50
Messages sent: 50
Messages received: 100
✓ EXCELLENT: High connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Medium Load Test
Description: Moderate load test with higher concurrency
Concurrent clients: 25
Messages per client: 10
==========================================
Launching 25 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 4s
Total connections attempted: 35
Successful connections: 25
Failed connections: 0
Connection success rate: 71%
Messages expected: 250
Messages sent: 250
Messages received: 500
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Heavy Load Test
Description: Heavy load test with high concurrency
Concurrent clients: 50
Messages per client: 20
==========================================
Launching 50 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 14s
Total connections attempted: 85
Successful connections: 50
Failed connections: 0
Connection success rate: 58%
Messages expected: 1000
Messages sent: 1000
Messages received: 2000
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Stress Test
Description: Maximum load test to find breaking point
Concurrent clients: 100
Messages per client: 50
==========================================
Launching 100 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 64s
Total connections attempted: 185
Successful connections: 100
Failed connections: 0
Connection success rate: 54%
Messages expected: 5000
Messages sent: 5000
Messages received: 7500
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Testing Complete
==========================================
All load tests completed. Check individual test results above.
If any tests failed, the relay may need optimization or have resource limits.
2026-04-01 11:03:37 - \033[0;32m✓ Load Testing PASSED\033[0m (Duration: 85s)
2026-04-01 11:03:37 - ==========================================
2026-04-01 11:03:37 - Running Test Suite: Stress Testing
2026-04-01 11:03:37 - Description: Resource usage and stability testing
2026-04-01 11:03:37 - ==========================================
2026-04-01 11:03:37 - \033[0;31mERROR: Test script stress_tests.sh not found\033[0m
+733
View File
@@ -0,0 +1,733 @@
2026-04-01 11:29:24 - ==========================================
2026-04-01 11:29:24 - C-Relay Comprehensive Test Suite Runner
2026-04-01 11:29:24 - ==========================================
2026-04-01 11:29:24 - Relay URL: ws://127.0.0.1:8888
2026-04-01 11:29:24 - Log file: test_results_20260401_112924.log
2026-04-01 11:29:24 - Report file: test_report_20260401_112924.html
2026-04-01 11:29:24 -
2026-04-01 11:29:24 - Checking relay status at ws://127.0.0.1:8888...
2026-04-01 11:29:25 - \033[0;32m✓ Relay HTTP endpoint is accessible\033[0m
2026-04-01 11:29:25 -
2026-04-01 11:29:25 - Starting comprehensive test execution...
2026-04-01 11:29:25 -
2026-04-01 11:29:25 - \033[0;34m=== SECURITY TEST SUITES ===\033[0m
2026-04-01 11:29:25 - ==========================================
2026-04-01 11:29:25 - Running Test Suite: SQL Injection Tests
2026-04-01 11:29:25 - Description: Comprehensive SQL injection vulnerability testing
2026-04-01 11:29:25 - ==========================================
==========================================
C-Relay SQL Injection Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - Valid query works
=== Authors Filter SQL Injection Tests ===
Testing Authors filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: #... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing Authors filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== IDs Filter SQL Injection Tests ===
Testing IDs filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: #... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing IDs filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Kinds Filter SQL Injection Tests ===
Testing Kinds filter with string injection... PASSED - SQL injection blocked (rejected with error)
Testing Kinds filter with negative value... PASSED - SQL injection blocked (rejected with error)
Testing Kinds filter with very large value... PASSED - SQL injection blocked (rejected with error)
=== Search Filter SQL Injection Tests ===
Testing Search filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: */... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing Search filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing Search filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Tag Filter SQL Injection Tests ===
Testing #e tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #e tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #p tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #t tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #r tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' OR 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: admin'--... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: /*... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: */... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: /**/... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: #... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND 1=1 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND 1=2 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (query sanitized)
Testing #d tag filter with payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (query sanitized)
=== Timestamp Filter SQL Injection Tests ===
Testing Since parameter injection... PASSED - SQL injection blocked (rejected with error)
Testing Until parameter injection... PASSED - SQL injection blocked (rejected with error)
=== Limit Parameter SQL Injection Tests ===
Testing Limit parameter injection... PASSED - SQL injection blocked (rejected with error)
Testing Limit with UNION... PASSED - SQL injection blocked (rejected with error)
=== Complex Multi-Filter SQL Injection Tests ===
Testing Multi-filter with authors injection... PASSED - SQL injection blocked (rejected with error)
Testing Multi-filter with search injection... PASSED - SQL injection blocked (rejected with error)
Testing Multi-filter with tag injection... PASSED - SQL injection blocked (query sanitized)
=== COUNT Message SQL Injection Tests ===
Testing COUNT with authors payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' OR '1'='1... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' OR '1'='1... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1; SELECT * FROM sqlite_master; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' OR 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: admin'--... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' UNION SELECT password FROM users --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND SLEEP(5) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=1 WAITFOR DELAY '0:0:5' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=CAST((SELECT version()) AS INT) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 1' AND 1=CONVERT(INT, (SELECT @@VERSION)) --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION SELECT 1,2,3 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' UNION ALL SELECT NULL,NULL,NULL --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; SELECT * FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DELETE FROM events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; UPDATE events SET content='hacked' WHERE 1=1; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: /*... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: */... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: */... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: /**/... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: #... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: #... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: 0x53514C5F494E4A454354494F4E... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: J1NSTCBJTkpFQ1RJT04gLS0=... PASSED - SQL injection blocked (query sanitized)
Testing COUNT with authors payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '))); DROP TABLE events; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ')) UNION SELECT NULL; --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND 1=1 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND 1=2 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: ' AND (SELECT COUNT(*) FROM events) > 0 --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; EXEC master..xp_cmdshell 'net user' --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with authors payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
Testing COUNT with search payload: '; DECLARE @host varchar(1024); SELECT @host=(SELECT TOP 1 master..sys.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa'); --... PASSED - SQL injection blocked (rejected with error)
=== Edge Case SQL Injection Tests ===
Testing Empty string injection... PASSED - SQL injection blocked (rejected with error)
Testing Null byte injection... PASSED - SQL injection blocked (silently rejected)
Testing Unicode injection... PASSED - SQL injection blocked (rejected with error)
Testing Very long injection payload... PASSED - SQL injection blocked (rejected with error)
=== Subscription ID SQL Injection Tests ===
Testing Subscription ID injection... PASSED - SQL injection blocked (rejected with error)
Testing Subscription ID with quotes... PASSED - SQL injection blocked (silently rejected)
=== CLOSE Message SQL Injection Tests ===
Testing CLOSE with injection... PASSED - SQL injection blocked (rejected with error)
=== Test Results ===
Total tests: 318
Passed: 318
Failed: 0
✓ All SQL injection tests passed!
The relay appears to be protected against SQL injection attacks.
2026-04-01 11:29:32 - \033[0;32m✓ SQL Injection Tests PASSED\033[0m (Duration: 7s)
2026-04-01 11:29:32 - ==========================================
2026-04-01 11:29:32 - Running Test Suite: Filter Validation Tests
2026-04-01 11:29:32 - Description: Input validation for REQ and COUNT messages
2026-04-01 11:29:32 - ==========================================
=== C-Relay Filter Validation Tests ===
Testing against relay at ws://127.0.0.1:8888
Testing Valid REQ message... PASSED
Testing Valid COUNT message... PASSED
=== Testing Filter Array Validation ===
Testing Non-object filter... PASSED
Testing Too many filters... PASSED
=== Testing Authors Validation ===
Testing Invalid author type... PASSED
Testing Invalid author hex... PASSED
Testing Too many authors... PASSED
=== Testing IDs Validation ===
Testing Invalid ID type... PASSED
Testing Invalid ID hex... PASSED
Testing Too many IDs... PASSED
=== Testing Kinds Validation ===
Testing Invalid kind type... PASSED
Testing Negative kind... PASSED
Testing Too large kind... PASSED
Testing Too many kinds... PASSED
=== Testing Timestamp Validation ===
Testing Invalid since type... PASSED
Testing Negative since... PASSED
Testing Invalid until type... PASSED
Testing Negative until... PASSED
=== Testing Limit Validation ===
Testing Invalid limit type... PASSED
Testing Negative limit... PASSED
Testing Too large limit... PASSED
=== Testing Search Validation ===
Testing Invalid search type... PASSED
Testing Search too long... PASSED
Testing Search SQL injection... PASSED
=== Testing Tag Filter Validation ===
Testing Invalid tag filter type... PASSED
Testing Too many tag values... PASSED
Testing Tag value too long... PASSED
=== Testing Rate Limiting ===
Testing rate limiting with malformed requests... UNCERTAIN - Rate limiting may not have triggered (this could be normal)
=== Test Results ===
Total tests: 28
Passed: 28
Failed: 0
All tests passed!
2026-04-01 11:29:35 - \033[0;32m✓ Filter Validation Tests PASSED\033[0m (Duration: 3s)
2026-04-01 11:29:35 - ==========================================
2026-04-01 11:29:35 - Running Test Suite: Subscription Validation Tests
2026-04-01 11:29:35 - Description: Subscription ID and message validation
2026-04-01 11:29:35 - ==========================================
Testing subscription ID validation fixes...
Testing malformed subscription IDs...
Empty ID test: Connection failed (expected)
Long ID test: Connection failed (expected)
Invalid chars test: Connection failed (expected)
NULL ID test: Connection failed (expected)
Valid ID test: Failed
Testing CLOSE message validation...
CLOSE empty ID test: Connection failed (expected)
CLOSE valid ID test: Failed
Subscription validation tests completed.
2026-04-01 11:29:35 - \033[0;32m✓ Subscription Validation Tests PASSED\033[0m (Duration: 0s)
2026-04-01 11:29:35 - ==========================================
2026-04-01 11:29:35 - Running Test Suite: Memory Corruption Tests
2026-04-01 11:29:35 - Description: Buffer overflow and memory safety testing
2026-04-01 11:29:35 - ==========================================
==========================================
C-Relay Memory Corruption Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
Note: These tests may cause the relay to crash if vulnerabilities exist
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - No memory corruption detected
=== Subscription ID Memory Corruption Tests ===
Testing Empty subscription ID... UNCERTAIN - Expected error but got normal response
Testing Very long subscription ID (1KB)... UNCERTAIN - Expected error but got normal response
Testing Very long subscription ID (10KB)... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with null bytes... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with special chars... UNCERTAIN - Expected error but got normal response
Testing Unicode subscription ID... UNCERTAIN - Expected error but got normal response
Testing Subscription ID with path traversal... UNCERTAIN - Expected error but got normal response
=== Filter Array Memory Corruption Tests ===
Testing Too many filters (50)... UNCERTAIN - Expected error but got normal response
=== Concurrent Access Memory Tests ===
Testing Concurrent subscription creation... ["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
["EVENT","concurrent_1775057376377657551",{"pubkey":"7b013abdf0cbc8f994e66018539fbcb750f3be118a70d8bdcf3b3e86dd2ebb40","created_at":1775057288,"kind":1,"tags":[],"content":"\nRelay Statistics\n━━━━━━━━━━━━━━━━━━━━\nDatabase Size 0.00 MB (4096 bytes)\nTotal Events 0\nActive Subscriptions 0\nOldest Event -\nNewest Event -\n\nEvent_Kind_Distribution:\n\nTime-based Statistics:\n0\tEvents in the last day\n0\tEvents in the last week\n0\tEvents in the last month\n\n\n","id":"210f21884a3581064f4d181bc10e4088b5161216ddc7088f5c39e570240687b3","sig":"a04a697e6b3a53a1df4e3d7d06da2483f07d45c97a939076bd8b28216425a854af5f7e463542adbed9b71af68d36d7e0296be0048c3156a51ed0defa685a5171"}]
PASSED - Concurrent access handled safely
Testing Concurrent CLOSE operations...
PASSED - Concurrent access handled safely
=== Malformed JSON Memory Tests ===
Testing Unclosed JSON object... UNCERTAIN - Expected error but got normal response
Testing Mismatched brackets... UNCERTAIN - Expected error but got normal response
Testing Extra closing brackets... UNCERTAIN - Expected error but got normal response
Testing Null bytes in JSON... UNCERTAIN - Expected error but got normal response
=== Large Message Memory Tests ===
Testing Very large filter array... UNCERTAIN - Expected error but got normal response
Testing Very long search term... UNCERTAIN - Expected error but got normal response
=== Test Results ===
Total tests: 17
Passed: 17
Failed: 0
✓ All memory corruption tests passed!
The relay appears to handle memory safely.
2026-04-01 11:29:36 - \033[0;32m✓ Memory Corruption Tests PASSED\033[0m (Duration: 1s)
2026-04-01 11:29:36 - ==========================================
2026-04-01 11:29:36 - Running Test Suite: Input Validation Tests
2026-04-01 11:29:36 - Description: Comprehensive input boundary testing
2026-04-01 11:29:36 - ==========================================
==========================================
C-Relay Input Validation Test Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
Testing Basic connectivity... PASSED - Input accepted correctly
=== Message Type Validation ===
Testing Invalid message type - string... PASSED - Invalid input properly rejected
Testing Invalid message type - number... PASSED - Invalid input properly rejected
Testing Invalid message type - null... PASSED - Invalid input properly rejected
Testing Invalid message type - object... PASSED - Invalid input properly rejected
Testing Empty message type... PASSED - Invalid input properly rejected
Testing Very long message type... PASSED - Invalid input properly rejected
=== Message Structure Validation ===
Testing Too few arguments... PASSED - Invalid input properly rejected
Testing Too many arguments... PASSED - Invalid input properly rejected
Testing Non-array message... PASSED - Invalid input properly rejected
Testing Empty array... PASSED - Invalid input properly rejected
Testing Nested arrays incorrectly... PASSED - Invalid input properly rejected
=== Subscription ID Boundary Tests ===
Testing Valid subscription ID... PASSED - Input accepted correctly
Testing Empty subscription ID... PASSED - Invalid input properly rejected
Testing Subscription ID with spaces... PASSED - Invalid input properly rejected
Testing Subscription ID with newlines... PASSED - Invalid input properly rejected
Testing Subscription ID with tabs... PASSED - Invalid input properly rejected
Testing Subscription ID with control chars... PASSED - Invalid input properly rejected
Testing Unicode subscription ID... PASSED - Invalid input properly rejected
Testing Very long subscription ID... PASSED - Invalid input properly rejected
=== Filter Object Validation ===
Testing Valid empty filter... PASSED - Input accepted correctly
Testing Non-object filter... PASSED - Invalid input properly rejected
Testing Null filter... PASSED - Invalid input properly rejected
Testing Array filter... PASSED - Invalid input properly rejected
Testing Filter with invalid keys... PASSED - Input accepted correctly
=== Authors Field Validation ===
Testing Valid authors array... PASSED - Input accepted correctly
Testing Empty authors array... PASSED - Input accepted correctly
Testing Non-array authors... PASSED - Invalid input properly rejected
Testing Invalid hex in authors... PASSED - Invalid input properly rejected
Testing Short pubkey in authors... PASSED - Invalid input properly rejected
=== IDs Field Validation ===
Testing Valid ids array... PASSED - Input accepted correctly
Testing Empty ids array... PASSED - Input accepted correctly
Testing Non-array ids... PASSED - Invalid input properly rejected
=== Kinds Field Validation ===
Testing Valid kinds array... PASSED - Input accepted correctly
Testing Empty kinds array... PASSED - Input accepted correctly
Testing Non-array kinds... PASSED - Invalid input properly rejected
Testing String in kinds... PASSED - Invalid input properly rejected
=== Timestamp Field Validation ===
Testing Valid since timestamp... PASSED - Input accepted correctly
Testing Valid until timestamp... PASSED - Input accepted correctly
Testing String since timestamp... PASSED - Invalid input properly rejected
Testing Negative timestamp... PASSED - Invalid input properly rejected
=== Limit Field Validation ===
Testing Valid limit... PASSED - Input accepted correctly
Testing Zero limit... PASSED - Input accepted correctly
Testing String limit... PASSED - Invalid input properly rejected
Testing Negative limit... PASSED - Invalid input properly rejected
=== Multiple Filters ===
Testing Two valid filters... PASSED - Input accepted correctly
Testing Many filters... PASSED - Input accepted correctly
=== Test Results ===
Total tests: 47
Passed: 47
Failed: 0
✓ All input validation tests passed!
The relay properly validates input.
2026-04-01 11:29:38 - \033[0;32m✓ Input Validation Tests PASSED\033[0m (Duration: 2s)
2026-04-01 11:29:38 -
2026-04-01 11:29:38 - \033[0;34m=== PERFORMANCE TEST SUITES ===\033[0m
2026-04-01 11:29:38 - ==========================================
2026-04-01 11:29:38 - Running Test Suite: Subscription Limit Tests
2026-04-01 11:29:38 - Description: Subscription limit enforcement testing
2026-04-01 11:29:38 - ==========================================
=== Subscription Limit Test ===
[INFO] Testing relay at: ws://127.0.0.1:8888
[INFO] Note: This test assumes default subscription limits (max 25 per client)
=== Test 1: Basic Connectivity ===
[INFO] Testing basic WebSocket connection...
[PASS] Basic connectivity works
=== Test 2: Subscription Limit Enforcement ===
[INFO] Testing subscription limits by creating multiple subscriptions...
[INFO] Creating multiple subscriptions within a single connection...
[INFO] Hit subscription limit at subscription 2
[PASS] Subscription limit enforcement working (limit hit after 1 subscriptions)
=== Test Complete ===
2026-04-01 11:29:38 - \033[0;32m✓ Subscription Limit Tests PASSED\033[0m (Duration: 0s)
2026-04-01 11:29:38 - ==========================================
2026-04-01 11:29:38 - Running Test Suite: Load Testing
2026-04-01 11:29:38 - Description: High concurrent connection testing
2026-04-01 11:29:38 - ==========================================
==========================================
C-Relay Load Testing Suite
==========================================
Testing against relay at ws://127.0.0.1:8888
=== Basic Connectivity Test ===
✓ Relay is accessible
==========================================
Load Test: Light Load Test
Description: Basic load test with moderate concurrent connections
Concurrent clients: 10
Messages per client: 5
==========================================
Launching 10 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 1s
Total connections attempted: 10
Successful connections: 10
Failed connections: 0
Connection success rate: 100%
Messages expected: 50
Messages sent: 50
Messages received: 100
✓ EXCELLENT: High connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Medium Load Test
Description: Moderate load test with higher concurrency
Concurrent clients: 25
Messages per client: 10
==========================================
Launching 25 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 4s
Total connections attempted: 35
Successful connections: 25
Failed connections: 0
Connection success rate: 71%
Messages expected: 250
Messages sent: 250
Messages received: 500
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Heavy Load Test
Description: Heavy load test with high concurrency
Concurrent clients: 50
Messages per client: 20
==========================================
Launching 50 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 14s
Total connections attempted: 85
Successful connections: 50
Failed connections: 0
Connection success rate: 58%
Messages expected: 1000
Messages sent: 1000
Messages received: 2000
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Test: Stress Test
Description: Maximum load test to find breaking point
Concurrent clients: 100
Messages per client: 50
==========================================
Launching 100 clients...
All clients completed. Processing results...
=== Load Test Results ===
Test duration: 64s
Total connections attempted: 185
Successful connections: 100
Failed connections: 0
Connection success rate: 54%
Messages expected: 5000
Messages sent: 5000
Messages received: 7500
✗ POOR: Low connection success rate
Checking relay responsiveness... ✓ Relay is still responsive
==========================================
Load Testing Complete
==========================================
All load tests completed. Check individual test results above.
If any tests failed, the relay may need optimization or have resource limits.
2026-04-01 11:31:03 - \033[0;32m✓ Load Testing PASSED\033[0m (Duration: 85s)
2026-04-01 11:31:03 - ==========================================
2026-04-01 11:31:03 - Running Test Suite: Stress Testing
2026-04-01 11:31:03 - Description: Resource usage and stability testing
2026-04-01 11:31:03 - ==========================================
2026-04-01 11:31:03 - \033[0;31mERROR: Test script stress_tests.sh not found\033[0m
+183
View File
@@ -0,0 +1,183 @@
#!/bin/bash
# Thread-level CPU profiler for c-relay on remote server
# - Samples per-thread CPU every N seconds using /proc/<pid>/task/*/stat deltas
# - Optionally runs perf record in parallel for callgraph data
# - Pulls artifacts locally and generates a summary report
set -euo pipefail
REMOTE_HOST="${REMOTE_HOST:-ubuntu@laantungir.com}"
DURATION="${DURATION:-600}" # seconds (default 10 minutes)
INTERVAL="${INTERVAL:-10}" # seconds between samples
OUTDIR_BASE="${OUTDIR_BASE:-thread_profile_runs}"
RUN_TS="$(date -u +%Y%m%d_%H%M%S)"
RUN_DIR="${OUTDIR_BASE}/${RUN_TS}"
LOCAL_CSV="${RUN_DIR}/thread_samples.csv"
LOCAL_REPORT="${RUN_DIR}/thread_summary.txt"
REMOTE_DIR="/tmp/c_relay_thread_profile_${RUN_TS}"
ENABLE_PERF="${ENABLE_PERF:-1}" # 1=run perf, 0=skip
mkdir -p "${RUN_DIR}"
echo "=========================================="
echo "C-Relay Thread CPU Profiler"
echo "=========================================="
echo "Remote host : ${REMOTE_HOST}"
echo "Duration : ${DURATION}s"
echo "Interval : ${INTERVAL}s"
echo "Run dir : ${RUN_DIR}"
echo "Perf record : ${ENABLE_PERF}"
echo ""
ssh "${REMOTE_HOST}" "bash -s" <<EOF
set -euo pipefail
REMOTE_DIR="${REMOTE_DIR}"
DURATION="${DURATION}"
INTERVAL="${INTERVAL}"
ENABLE_PERF="${ENABLE_PERF}"
mkdir -p "\${REMOTE_DIR}"
CSV_FILE="\${REMOTE_DIR}/thread_samples.csv"
PERF_FILE="\${REMOTE_DIR}/perf.data"
LOG_FILE="\${REMOTE_DIR}/run.log"
PID=\$(pgrep -f '/usr/local/bin/c_relay/c_relay|c_relay' | head -1 || true)
if [ -z "\${PID}" ]; then
echo "ERROR: c_relay process not found (checked by cmdline pattern)" | tee -a "\${LOG_FILE}"
exit 1
fi
echo "Profiling PID: \${PID}" | tee -a "\${LOG_FILE}"
CLK_TCK=\$(getconf CLK_TCK)
echo "CLK_TCK=\${CLK_TCK}" | tee -a "\${LOG_FILE}"
echo "timestamp,tid,thread_name,cpu_pct,delta_ticks,total_ticks" > "\${CSV_FILE}"
# Start perf in background (if enabled and available)
PERF_PID=""
if [ "\${ENABLE_PERF}" = "1" ]; then
if command -v perf >/dev/null 2>&1; then
if sudo -n true >/dev/null 2>&1; then
echo "Starting perf record in background..." | tee -a "\${LOG_FILE}"
sudo perf record -g -p "\${PID}" -o "\${PERF_FILE}" -- sleep "\${DURATION}" >/dev/null 2>&1 &
PERF_PID=\$!
PERF_OWNER="\$(id -un)"
echo "perf_pid=\${PERF_PID}" | tee -a "\${LOG_FILE}"
else
echo "Skipping perf: sudo -n not available" | tee -a "\${LOG_FILE}"
fi
else
echo "Skipping perf: command not found" | tee -a "\${LOG_FILE}"
fi
fi
# Capture previous totals by tid
declare -A PREV_TOTAL
capture_totals() {
local pid="\$1"
for statf in /proc/\${pid}/task/*/stat; do
[ -f "\${statf}" ] || continue
local tid
tid=\${statf%/stat}
tid=\${tid##*/}
local total
total=\$(awk '{print \$14+\$15}' "\${statf}" 2>/dev/null || echo 0)
PREV_TOTAL[\${tid}]="\${total}"
done
}
capture_totals "\${PID}"
START_TS=\$(date +%s)
END_TS=\$((START_TS + DURATION))
while [ \$(date +%s) -lt \${END_TS} ]; do
NOW=\$(date +%s)
for statf in /proc/\${PID}/task/*/stat; do
[ -f "\${statf}" ] || continue
tid=\${statf%/stat}
tid=\${tid##*/}
total=\$(awk '{print \$14+\$15}' "\${statf}" 2>/dev/null || echo 0)
prev=\${PREV_TOTAL[\${tid}]:-\${total}}
delta=\$((total - prev))
if [ \${delta} -lt 0 ]; then
delta=0
fi
PREV_TOTAL[\${tid}]="\${total}"
name_file="/proc/\${PID}/task/\${tid}/comm"
if [ -f "\${name_file}" ]; then
tname=\$(tr -d '\n' < "\${name_file}")
else
tname="unknown"
fi
cpu_pct=\$(awk -v d="\${delta}" -v hz="\${CLK_TCK}" -v iv="\${INTERVAL}" 'BEGIN { printf "%.2f", (d / hz) * 100.0 / iv }')
echo "\${NOW},\${tid},\${tname},\${cpu_pct},\${delta},\${total}" >> "\${CSV_FILE}"
done
sleep "\${INTERVAL}"
done
if [ -n "\${PERF_PID}" ]; then
wait "\${PERF_PID}" || true
if [ -f "\${PERF_FILE}" ]; then
sudo perf report --stdio -i "\${PERF_FILE}" --sort=comm,symbol --no-children -n > "\${REMOTE_DIR}/perf_report.txt" 2>/dev/null || true
sudo chown "\${PERF_OWNER}:\${PERF_OWNER}" "\${PERF_FILE}" "\${REMOTE_DIR}/perf_report.txt" 2>/dev/null || true
fi
fi
echo "Done. Artifacts in \${REMOTE_DIR}" | tee -a "\${LOG_FILE}"
EOF
echo "Fetching artifacts..."
scp -q "${REMOTE_HOST}:${REMOTE_DIR}/thread_samples.csv" "${LOCAL_CSV}"
scp -q "${REMOTE_HOST}:${REMOTE_DIR}/run.log" "${RUN_DIR}/run.log" || true
scp -q "${REMOTE_HOST}:${REMOTE_DIR}/perf.data" "${RUN_DIR}/perf.data" || true
scp -q "${REMOTE_HOST}:${REMOTE_DIR}/perf_report.txt" "${RUN_DIR}/perf_report.txt" || true
echo "Generating summary..."
{
echo "=========================================="
echo "Thread CPU Summary (avg + max over run)"
echo "=========================================="
echo "Run timestamp (UTC): ${RUN_TS}"
echo "Duration: ${DURATION}s, Interval: ${INTERVAL}s"
echo ""
awk -F, '
NR==1 {next}
{
key=$2"|"$3;
cpu=$4+0;
sum[key]+=cpu;
cnt[key]++;
if (cpu > max[key]) max[key]=cpu;
}
END {
printf("%-10s %-18s %12s %12s\n", "TID", "THREAD", "AVG_CPU%", "MAX_CPU%");
for (k in sum) {
split(k, a, "|");
avg=sum[k]/cnt[k];
printf("%-10s %-18s %12.2f %12.2f\n", a[1], a[2], avg, max[k]);
}
}
' "${LOCAL_CSV}" | sort -k3,3nr
} | tee "${LOCAL_REPORT}"
echo ""
echo "Completed. Files:"
echo " ${LOCAL_CSV}"
echo " ${LOCAL_REPORT}"
if [ -f "${RUN_DIR}/perf_report.txt" ]; then
echo " ${RUN_DIR}/perf_report.txt"
fi
echo ""
echo "Top 20 summary:"
head -n 22 "${LOCAL_REPORT}"
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
Profiling PID: 2040140
CLK_TCK=100
Starting perf record in background...
perf_pid=2040808
Done. Artifacts in /tmp/c_relay_thread_profile_20260401_154500
@@ -0,0 +1,421 @@
timestamp,tid,thread_name,cpu_pct,delta_ticks,total_ticks
1775058301,2040140",unknown,0.00,0,3950
1775058301,2040150",unknown,0.00,0,9
1775058301,2040151",unknown,0.00,0,8
1775058301,2040152",unknown,0.00,0,11
1775058301,2040153",unknown,0.00,0,11
1775058301,2040154",unknown,0.00,0,0
1775058301,2040155",unknown,0.00,0,0
1775058311,2040140",unknown,62.10,621,4571
1775058311,2040150",unknown,0.20,2,11
1775058311,2040151",unknown,0.10,1,9
1775058311,2040152",unknown,0.10,1,12
1775058311,2040153",unknown,0.00,0,11
1775058311,2040154",unknown,0.00,0,0
1775058311,2040155",unknown,0.00,0,0
1775058321,2040140",unknown,65.20,652,5223
1775058321,2040150",unknown,0.20,2,13
1775058321,2040151",unknown,0.20,2,11
1775058321,2040152",unknown,0.30,3,15
1775058321,2040153",unknown,0.20,2,13
1775058321,2040154",unknown,0.00,0,0
1775058321,2040155",unknown,0.00,0,0
1775058331,2040140",unknown,83.80,838,6061
1775058331,2040150",unknown,0.00,0,13
1775058331,2040151",unknown,0.00,0,11
1775058331,2040152",unknown,0.00,0,15
1775058331,2040153",unknown,0.00,0,13
1775058331,2040154",unknown,0.00,0,0
1775058331,2040155",unknown,0.00,0,0
1775058341,2040140",unknown,100.20,1002,7063
1775058341,2040150",unknown,0.00,0,13
1775058341,2040151",unknown,0.00,0,11
1775058341,2040152",unknown,0.00,0,15
1775058341,2040153",unknown,0.00,0,13
1775058341,2040154",unknown,0.00,0,0
1775058341,2040155",unknown,0.00,0,0
1775058351,2040140",unknown,100.30,1003,8066
1775058351,2040150",unknown,0.00,0,13
1775058351,2040151",unknown,0.00,0,11
1775058351,2040152",unknown,0.10,1,16
1775058351,2040153",unknown,0.00,0,13
1775058351,2040154",unknown,0.00,0,0
1775058351,2040155",unknown,0.00,0,0
1775058361,2040140",unknown,89.50,895,8961
1775058361,2040150",unknown,0.10,1,14
1775058361,2040151",unknown,0.00,0,11
1775058361,2040152",unknown,0.00,0,16
1775058361,2040153",unknown,0.00,0,13
1775058361,2040154",unknown,0.00,0,0
1775058361,2040155",unknown,0.00,0,0
1775058371,2040140",unknown,21.20,212,9173
1775058371,2040150",unknown,0.00,0,14
1775058371,2040151",unknown,0.00,0,11
1775058371,2040152",unknown,0.00,0,16
1775058371,2040153",unknown,0.00,0,13
1775058371,2040154",unknown,0.00,0,0
1775058371,2040155",unknown,0.00,0,0
1775058381,2040140",unknown,36.40,364,9537
1775058381,2040150",unknown,0.10,1,15
1775058381,2040151",unknown,0.10,1,12
1775058381,2040152",unknown,0.10,1,17
1775058381,2040153",unknown,0.00,0,13
1775058381,2040154",unknown,0.00,0,0
1775058381,2040155",unknown,0.00,0,0
1775058391,2040140",unknown,35.30,353,9890
1775058391,2040150",unknown,0.00,0,15
1775058391,2040151",unknown,0.00,0,12
1775058391,2040152",unknown,0.00,0,17
1775058391,2040153",unknown,0.00,0,13
1775058391,2040154",unknown,0.00,0,0
1775058391,2040155",unknown,0.00,0,0
1775058401,2040140",unknown,42.80,428,10318
1775058401,2040150",unknown,0.30,3,18
1775058401,2040151",unknown,0.20,2,14
1775058401,2040152",unknown,0.30,3,20
1775058401,2040153",unknown,0.30,3,16
1775058401,2040154",unknown,0.00,0,0
1775058401,2040155",unknown,0.00,0,0
1775058411,2040140",unknown,73.50,735,11053
1775058411,2040150",unknown,0.40,4,22
1775058411,2040151",unknown,0.20,2,16
1775058411,2040152",unknown,0.40,4,24
1775058411,2040153",unknown,0.20,2,18
1775058411,2040154",unknown,0.00,0,0
1775058411,2040155",unknown,0.00,0,0
1775058421,2040140",unknown,33.60,336,11389
1775058421,2040150",unknown,0.00,0,22
1775058421,2040151",unknown,0.00,0,16
1775058421,2040152",unknown,0.00,0,24
1775058421,2040153",unknown,0.10,1,19
1775058421,2040154",unknown,0.00,0,0
1775058421,2040155",unknown,0.00,0,0
1775058431,2040140",unknown,57.20,572,11961
1775058431,2040150",unknown,0.00,0,22
1775058431,2040151",unknown,0.10,1,17
1775058431,2040152",unknown,0.10,1,25
1775058431,2040153",unknown,0.00,0,19
1775058431,2040154",unknown,0.00,0,0
1775058431,2040155",unknown,0.00,0,0
1775058441,2040140",unknown,96.70,967,12928
1775058441,2040150",unknown,0.00,0,22
1775058441,2040151",unknown,0.00,0,17
1775058441,2040152",unknown,0.00,0,25
1775058441,2040153",unknown,0.00,0,19
1775058441,2040154",unknown,0.00,0,0
1775058441,2040155",unknown,0.00,0,0
1775058451,2040140",unknown,100.30,1003,13931
1775058451,2040150",unknown,0.10,1,23
1775058451,2040151",unknown,0.10,1,18
1775058451,2040152",unknown,0.10,1,26
1775058451,2040153",unknown,0.00,0,19
1775058451,2040154",unknown,0.00,0,0
1775058451,2040155",unknown,0.00,0,0
1775058461,2040140",unknown,98.40,984,14915
1775058461,2040150",unknown,0.10,1,24
1775058461,2040151",unknown,0.30,3,21
1775058461,2040152",unknown,0.10,1,27
1775058461,2040153",unknown,0.20,2,21
1775058461,2040154",unknown,0.00,0,0
1775058461,2040155",unknown,0.00,0,0
1775058471,2040140",unknown,62.90,629,15544
1775058471,2040150",unknown,0.00,0,24
1775058471,2040151",unknown,0.20,2,23
1775058471,2040152",unknown,0.00,0,27
1775058471,2040153",unknown,0.10,1,22
1775058471,2040154",unknown,0.00,0,0
1775058471,2040155",unknown,0.20,2,2
1775058481,2040140",unknown,83.20,832,16376
1775058481,2040150",unknown,0.20,2,26
1775058481,2040151",unknown,0.00,0,23
1775058481,2040152",unknown,0.20,2,29
1775058481,2040153",unknown,0.00,0,22
1775058481,2040154",unknown,0.00,0,0
1775058481,2040155",unknown,0.00,0,2
1775058491,2040140",unknown,100.30,1003,17379
1775058491,2040150",unknown,0.00,0,26
1775058491,2040151",unknown,0.00,0,23
1775058491,2040152",unknown,0.00,0,29
1775058491,2040153",unknown,0.00,0,22
1775058491,2040154",unknown,0.00,0,0
1775058491,2040155",unknown,0.00,0,2
1775058501,2040140",unknown,63.30,633,18012
1775058501,2040150",unknown,0.10,1,27
1775058501,2040151",unknown,0.10,1,24
1775058501,2040152",unknown,0.30,3,32
1775058501,2040153",unknown,0.20,2,24
1775058501,2040154",unknown,0.00,0,0
1775058501,2040155",unknown,0.00,0,2
1775058511,2040140",unknown,57.40,574,18586
1775058511,2040150",unknown,0.00,0,27
1775058511,2040151",unknown,0.10,1,25
1775058511,2040152",unknown,0.00,0,32
1775058511,2040153",unknown,0.00,0,24
1775058511,2040154",unknown,0.00,0,0
1775058511,2040155",unknown,0.00,0,2
1775058521,2040140",unknown,18.70,187,18773
1775058521,2040150",unknown,0.10,1,28
1775058521,2040151",unknown,0.00,0,25
1775058521,2040152",unknown,0.00,0,32
1775058521,2040153",unknown,0.00,0,24
1775058521,2040154",unknown,0.00,0,0
1775058521,2040155",unknown,0.00,0,2
1775058531,2040140",unknown,66.20,662,19435
1775058531,2040150",unknown,0.00,0,28
1775058531,2040151",unknown,0.10,1,26
1775058531,2040152",unknown,0.00,0,32
1775058531,2040153",unknown,0.00,0,24
1775058531,2040154",unknown,0.00,0,0
1775058531,2040155",unknown,0.00,0,2
1775058541,2040140",unknown,89.10,891,20326
1775058541,2040150",unknown,0.00,0,28
1775058541,2040151",unknown,0.00,0,26
1775058541,2040152",unknown,0.10,1,33
1775058541,2040153",unknown,0.00,0,24
1775058541,2040154",unknown,0.00,0,0
1775058541,2040155",unknown,0.00,0,2
1775058551,2040140",unknown,38.10,381,20707
1775058551,2040150",unknown,0.10,1,29
1775058551,2040151",unknown,0.00,0,26
1775058551,2040152",unknown,0.00,0,33
1775058551,2040153",unknown,0.00,0,24
1775058551,2040154",unknown,0.00,0,0
1775058551,2040155",unknown,0.00,0,2
1775058562,2040140",unknown,69.20,692,21399
1775058562,2040150",unknown,0.00,0,29
1775058562,2040151",unknown,0.20,2,28
1775058562,2040152",unknown,0.00,0,33
1775058562,2040153",unknown,0.10,1,25
1775058562,2040154",unknown,0.00,0,0
1775058562,2040155",unknown,0.00,0,2
1775058572,2040140",unknown,92.80,928,22327
1775058572,2040150",unknown,0.00,0,29
1775058572,2040151",unknown,0.00,0,28
1775058572,2040152",unknown,0.00,0,33
1775058572,2040153",unknown,0.00,0,25
1775058572,2040154",unknown,0.00,0,0
1775058572,2040155",unknown,0.00,0,2
1775058582,2040140",unknown,91.30,913,23240
1775058582,2040150",unknown,0.10,1,30
1775058582,2040151",unknown,0.00,0,28
1775058582,2040152",unknown,0.10,1,34
1775058582,2040153",unknown,0.00,0,25
1775058582,2040154",unknown,0.00,0,0
1775058582,2040155",unknown,0.00,0,2
1775058592,2040140",unknown,94.60,946,24186
1775058592,2040150",unknown,0.00,0,30
1775058592,2040151",unknown,0.00,0,28
1775058592,2040152",unknown,0.10,1,35
1775058592,2040153",unknown,0.10,1,26
1775058592,2040154",unknown,0.00,0,0
1775058592,2040155",unknown,0.00,0,2
1775058602,2040140",unknown,45.50,455,24641
1775058602,2040150",unknown,0.00,0,30
1775058602,2040151",unknown,0.00,0,28
1775058602,2040152",unknown,0.00,0,35
1775058602,2040153",unknown,0.00,0,26
1775058602,2040154",unknown,0.00,0,0
1775058602,2040155",unknown,0.00,0,2
1775058612,2040140",unknown,64.50,645,25286
1775058612,2040150",unknown,0.00,0,30
1775058612,2040151",unknown,0.10,1,29
1775058612,2040152",unknown,0.00,0,35
1775058612,2040153",unknown,0.10,1,27
1775058612,2040154",unknown,0.00,0,0
1775058612,2040155",unknown,0.00,0,2
1775058622,2040140",unknown,21.10,211,25497
1775058622,2040150",unknown,0.00,0,30
1775058622,2040151",unknown,0.00,0,29
1775058622,2040152",unknown,0.00,0,35
1775058622,2040153",unknown,0.00,0,27
1775058622,2040154",unknown,0.00,0,0
1775058622,2040155",unknown,0.00,0,2
1775058632,2040140",unknown,26.60,266,25763
1775058632,2040150",unknown,0.20,2,32
1775058632,2040151",unknown,0.10,1,30
1775058632,2040152",unknown,0.00,0,35
1775058632,2040153",unknown,0.00,0,27
1775058632,2040154",unknown,0.10,1,1
1775058632,2040155",unknown,0.00,0,2
1775058642,2040140",unknown,51.80,518,26281
1775058642,2040150",unknown,0.00,0,32
1775058642,2040151",unknown,0.10,1,31
1775058642,2040152",unknown,0.00,0,35
1775058642,2040153",unknown,0.00,0,27
1775058642,2040154",unknown,0.00,0,1
1775058642,2040155",unknown,0.00,0,2
1775058652,2040140",unknown,28.40,284,26565
1775058652,2040150",unknown,0.00,0,32
1775058652,2040151",unknown,0.10,1,32
1775058652,2040152",unknown,0.10,1,36
1775058652,2040153",unknown,0.20,2,29
1775058652,2040154",unknown,0.00,0,1
1775058652,2040155",unknown,0.00,0,2
1775058662,2040140",unknown,14.30,143,26708
1775058662,2040150",unknown,0.20,2,34
1775058662,2040151",unknown,0.10,1,33
1775058662,2040152",unknown,0.40,4,40
1775058662,2040153",unknown,0.30,3,32
1775058662,2040154",unknown,0.00,0,1
1775058662,2040155",unknown,0.00,0,2
1775058672,2040140",unknown,69.20,692,27400
1775058672,2040150",unknown,0.20,2,36
1775058672,2040151",unknown,0.00,0,33
1775058672,2040152",unknown,0.20,2,42
1775058672,2040153",unknown,0.10,1,33
1775058672,2040154",unknown,0.00,0,1
1775058672,2040155",unknown,0.00,0,2
1775058682,2040140",unknown,71.10,711,28111
1775058682,2040150",unknown,0.30,3,39
1775058682,2040151",unknown,0.20,2,35
1775058682,2040152",unknown,0.00,0,42
1775058682,2040153",unknown,0.10,1,34
1775058682,2040154",unknown,0.00,0,1
1775058682,2040155",unknown,0.00,0,2
1775058692,2040140",unknown,99.40,994,29105
1775058692,2040150",unknown,0.00,0,39
1775058692,2040151",unknown,0.00,0,35
1775058692,2040152",unknown,0.00,0,42
1775058692,2040153",unknown,0.00,0,34
1775058692,2040154",unknown,0.00,0,1
1775058692,2040155",unknown,0.00,0,2
1775058702,2040140",unknown,30.60,306,29411
1775058702,2040150",unknown,0.10,1,40
1775058702,2040151",unknown,0.10,1,36
1775058702,2040152",unknown,0.20,2,44
1775058702,2040153",unknown,0.20,2,36
1775058702,2040154",unknown,0.00,0,1
1775058702,2040155",unknown,0.00,0,2
1775058712,2040140",unknown,14.70,147,29558
1775058712,2040150",unknown,0.00,0,40
1775058712,2040151",unknown,0.00,0,36
1775058712,2040152",unknown,0.10,1,45
1775058712,2040153",unknown,0.00,0,36
1775058712,2040154",unknown,0.10,1,2
1775058712,2040155",unknown,0.00,0,2
1775058722,2040140",unknown,14.20,142,29700
1775058722,2040150",unknown,0.00,0,40
1775058722,2040151",unknown,0.10,1,37
1775058722,2040152",unknown,0.10,1,46
1775058722,2040153",unknown,0.00,0,36
1775058722,2040154",unknown,0.00,0,2
1775058722,2040155",unknown,0.00,0,2
1775058732,2040140",unknown,29.20,292,29992
1775058732,2040150",unknown,0.10,1,41
1775058732,2040151",unknown,0.00,0,37
1775058732,2040152",unknown,0.00,0,46
1775058732,2040153",unknown,0.00,0,36
1775058732,2040154",unknown,0.00,0,2
1775058732,2040155",unknown,0.00,0,2
1775058742,2040140",unknown,29.80,298,30290
1775058742,2040150",unknown,0.00,0,41
1775058742,2040151",unknown,0.00,0,37
1775058742,2040152",unknown,0.10,1,47
1775058742,2040153",unknown,0.00,0,36
1775058742,2040154",unknown,0.00,0,2
1775058742,2040155",unknown,0.00,0,2
1775058752,2040140",unknown,48.20,482,30772
1775058752,2040150",unknown,0.00,0,41
1775058752,2040151",unknown,0.00,0,37
1775058752,2040152",unknown,0.00,0,47
1775058752,2040153",unknown,0.10,1,37
1775058752,2040154",unknown,0.00,0,2
1775058752,2040155",unknown,0.00,0,2
1775058762,2040140",unknown,28.10,281,31053
1775058762,2040150",unknown,0.00,0,41
1775058762,2040151",unknown,0.00,0,37
1775058762,2040152",unknown,0.00,0,47
1775058762,2040153",unknown,0.00,0,37
1775058762,2040154",unknown,0.00,0,2
1775058762,2040155",unknown,0.00,0,2
1775058772,2040140",unknown,40.80,408,31461
1775058772,2040150",unknown,0.10,1,42
1775058772,2040151",unknown,0.10,1,38
1775058772,2040152",unknown,0.10,1,48
1775058772,2040153",unknown,0.10,1,38
1775058772,2040154",unknown,0.00,0,2
1775058772,2040155",unknown,0.00,0,2
1775058782,2040140",unknown,98.90,989,32450
1775058782,2040150",unknown,0.30,3,45
1775058782,2040151",unknown,0.00,0,38
1775058782,2040152",unknown,0.30,3,51
1775058782,2040153",unknown,0.10,1,39
1775058782,2040154",unknown,0.00,0,2
1775058782,2040155",unknown,0.10,1,3
1775058792,2040140",unknown,59.50,595,33045
1775058792,2040150",unknown,0.20,2,47
1775058792,2040151",unknown,0.10,1,39
1775058792,2040152",unknown,0.10,1,52
1775058792,2040153",unknown,0.10,1,40
1775058792,2040154",unknown,0.00,0,2
1775058792,2040155",unknown,0.00,0,3
1775058802,2040140",unknown,47.10,471,33516
1775058802,2040150",unknown,0.00,0,47
1775058802,2040151",unknown,0.00,0,39
1775058802,2040152",unknown,0.00,0,52
1775058802,2040153",unknown,0.10,1,41
1775058802,2040154",unknown,0.00,0,2
1775058802,2040155",unknown,0.10,1,4
1775058812,2040140",unknown,50.60,506,34022
1775058812,2040150",unknown,0.00,0,47
1775058812,2040151",unknown,0.00,0,39
1775058812,2040152",unknown,0.10,1,53
1775058812,2040153",unknown,0.00,0,41
1775058812,2040154",unknown,0.00,0,2
1775058812,2040155",unknown,0.10,1,5
1775058822,2040140",unknown,28.10,281,34303
1775058822,2040150",unknown,0.00,0,47
1775058822,2040151",unknown,0.00,0,39
1775058822,2040152",unknown,0.00,0,53
1775058822,2040153",unknown,0.00,0,41
1775058822,2040154",unknown,0.00,0,2
1775058822,2040155",unknown,0.00,0,5
1775058832,2040140",unknown,75.30,753,35056
1775058832,2040150",unknown,0.10,1,48
1775058832,2040151",unknown,0.10,1,40
1775058832,2040152",unknown,0.10,1,54
1775058832,2040153",unknown,0.10,1,42
1775058832,2040154",unknown,0.00,0,2
1775058832,2040155",unknown,0.00,0,5
1775058842,2040140",unknown,37.20,372,35428
1775058842,2040150",unknown,0.00,0,48
1775058842,2040151",unknown,0.00,0,40
1775058842,2040152",unknown,0.00,0,54
1775058842,2040153",unknown,0.00,0,42
1775058842,2040154",unknown,0.00,0,2
1775058842,2040155",unknown,0.00,0,5
1775058852,2040140",unknown,27.00,270,35698
1775058852,2040150",unknown,0.20,2,50
1775058852,2040151",unknown,0.20,2,42
1775058852,2040152",unknown,0.30,3,57
1775058852,2040153",unknown,0.20,2,44
1775058852,2040154",unknown,0.00,0,2
1775058852,2040155",unknown,0.00,0,5
1775058862,2040140",unknown,46.30,463,36161
1775058862,2040150",unknown,0.00,0,50
1775058862,2040151",unknown,0.10,1,43
1775058862,2040152",unknown,0.20,2,59
1775058862,2040153",unknown,0.00,0,44
1775058862,2040154",unknown,0.00,0,2
1775058862,2040155",unknown,0.00,0,5
1775058872,2040140",unknown,14.00,140,36301
1775058872,2040150",unknown,0.00,0,50
1775058872,2040151",unknown,0.00,0,43
1775058872,2040152",unknown,0.00,0,59
1775058872,2040153",unknown,0.00,0,44
1775058872,2040154",unknown,0.00,0,2
1775058872,2040155",unknown,0.00,0,5
1775058882,2040140",unknown,56.20,562,36863
1775058882,2040150",unknown,0.00,0,50
1775058882,2040151",unknown,0.10,1,44
1775058882,2040152",unknown,0.10,1,60
1775058882,2040153",unknown,0.00,0,44
1775058882,2040154",unknown,0.00,0,2
1775058882,2040155",unknown,0.00,0,5
1775058893,2040140",unknown,35.60,356,37219
1775058893,2040150",unknown,0.20,2,52
1775058893,2040151",unknown,0.10,1,45
1775058893,2040152",unknown,0.10,1,61
1775058893,2040153",unknown,0.10,1,45
1775058893,2040154",unknown,0.00,0,2
1775058893,2040155",unknown,0.00,0,5
Can't render this file because it contains an unexpected character in line 2 and column 19.
@@ -0,0 +1,14 @@
==========================================
Thread CPU Summary (avg + max over run)
==========================================
Run timestamp (UTC): 20260401_154500
Duration: 600s, Interval: 10s
2040140" unknown 55.45 100.30
2040152" unknown 0.08 0.40
2040150" unknown 0.07 0.40
2040151" unknown 0.06 0.30
2040153" unknown 0.06 0.30
2040155" unknown 0.01 0.20
2040154" unknown 0.00 0.10
TID THREAD AVG_CPU% MAX_CPU%
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
Profiling PID: 2040140
CLK_TCK=100
Starting perf record in background...
perf_pid=2046339
Done. Artifacts in /tmp/c_relay_thread_profile_20260401_155603
@@ -0,0 +1,372 @@
timestamp,tid,thread_name,cpu_pct,delta_ticks,total_ticks
1775058964,2040140,lws-main,0.00,0,42849
1775058964,2040150,db-read-1,0.00,0,58
1775058964,2040151,db-read-2,0.00,0,54
1775058964,2040152,db-read-3,0.10,1,68
1775058964,2040153,db-read-4,0.00,0,53
1775058964,2040154,db-write,0.00,0,2
1775058964,2040155,event-worker,0.00,0,5
1775058974,2040140,lws-main,59.30,593,43442
1775058974,2040150,db-read-1,0.00,0,58
1775058974,2040151,db-read-2,0.00,0,54
1775058974,2040152,db-read-3,0.10,1,69
1775058974,2040153,db-read-4,0.00,0,53
1775058974,2040154,db-write,0.00,0,2
1775058974,2040155,event-worker,0.00,0,5
1775058984,2040140,lws-main,67.40,674,44116
1775058984,2040150,db-read-1,0.00,0,58
1775058984,2040151,db-read-2,0.00,0,54
1775058984,2040152,db-read-3,0.00,0,69
1775058984,2040153,db-read-4,0.10,1,54
1775058984,2040154,db-write,0.00,0,2
1775058984,2040155,event-worker,0.00,0,5
1775058994,2040140,lws-main,98.70,987,45103
1775058994,2040150,db-read-1,0.10,1,59
1775058994,2040151,db-read-2,0.00,0,54
1775058994,2040152,db-read-3,0.00,0,69
1775058994,2040153,db-read-4,0.00,0,54
1775058994,2040154,db-write,0.00,0,2
1775058994,2040155,event-worker,0.00,0,5
1775059004,2040140,lws-main,71.00,710,45813
1775059004,2040150,db-read-1,0.00,0,59
1775059004,2040151,db-read-2,0.00,0,54
1775059004,2040152,db-read-3,0.10,1,70
1775059004,2040153,db-read-4,0.10,1,55
1775059004,2040154,db-write,0.00,0,2
1775059004,2040155,event-worker,0.00,0,5
1775059014,2040140,lws-main,14.70,147,45960
1775059014,2040150,db-read-1,0.10,1,60
1775059014,2040151,db-read-2,0.30,3,57
1775059014,2040152,db-read-3,0.10,1,71
1775059014,2040153,db-read-4,0.10,1,56
1775059014,2040154,db-write,0.00,0,2
1775059014,2040155,event-worker,0.00,0,5
1775059024,2040140,lws-main,47.70,477,46437
1775059024,2040150,db-read-1,0.00,0,60
1775059024,2040151,db-read-2,0.00,0,57
1775059024,2040152,db-read-3,0.00,0,71
1775059024,2040153,db-read-4,0.00,0,56
1775059024,2040154,db-write,0.00,0,2
1775059024,2040155,event-worker,0.00,0,5
1775059034,2040140,lws-main,99.50,995,47432
1775059034,2040150,db-read-1,0.10,1,61
1775059034,2040151,db-read-2,0.10,1,58
1775059034,2040152,db-read-3,0.10,1,72
1775059034,2040153,db-read-4,0.00,0,56
1775059034,2040154,db-write,0.10,1,3
1775059034,2040155,event-worker,0.00,0,5
1775059044,2040140,lws-main,88.50,885,48317
1775059044,2040150,db-read-1,0.20,2,63
1775059044,2040151,db-read-2,0.10,1,59
1775059044,2040152,db-read-3,0.10,1,73
1775059044,2040153,db-read-4,0.20,2,58
1775059044,2040154,db-write,0.00,0,3
1775059044,2040155,event-worker,0.00,0,5
1775059054,2040140,lws-main,67.70,677,48994
1775059054,2040150,db-read-1,0.00,0,63
1775059054,2040151,db-read-2,0.00,0,59
1775059054,2040152,db-read-3,0.00,0,73
1775059054,2040153,db-read-4,0.00,0,58
1775059054,2040154,db-write,0.00,0,3
1775059054,2040155,event-worker,0.00,0,5
1775059064,2040140,lws-main,53.10,531,49525
1775059064,2040150,db-read-1,0.40,4,67
1775059064,2040151,db-read-2,0.40,4,63
1775059064,2040152,db-read-3,0.20,2,75
1775059064,2040153,db-read-4,0.00,0,58
1775059064,2040154,db-write,0.00,0,3
1775059064,2040155,event-worker,0.00,0,5
1775059074,2040140,lws-main,61.60,616,50141
1775059074,2040150,db-read-1,0.30,3,70
1775059074,2040151,db-read-2,0.20,2,65
1775059074,2040152,db-read-3,0.10,1,76
1775059074,2040153,db-read-4,0.20,2,60
1775059074,2040154,db-write,0.00,0,3
1775059074,2040155,event-worker,0.00,0,5
1775059084,2040140,lws-main,96.20,962,51103
1775059084,2040150,db-read-1,0.00,0,70
1775059084,2040151,db-read-2,0.20,2,67
1775059084,2040152,db-read-3,0.40,4,80
1775059084,2040153,db-read-4,0.10,1,61
1775059084,2040154,db-write,0.10,1,4
1775059084,2040155,event-worker,0.00,0,5
1775059094,2040140,lws-main,53.60,536,51639
1775059094,2040150,db-read-1,0.10,1,71
1775059094,2040151,db-read-2,0.20,2,69
1775059094,2040152,db-read-3,0.00,0,80
1775059094,2040153,db-read-4,0.00,0,61
1775059094,2040154,db-write,0.00,0,4
1775059094,2040155,event-worker,0.00,0,5
1775059105,2040140,lws-main,51.40,514,52153
1775059105,2040150,db-read-1,0.10,1,72
1775059105,2040151,db-read-2,0.00,0,69
1775059105,2040152,db-read-3,0.00,0,80
1775059105,2040153,db-read-4,0.10,1,62
1775059105,2040154,db-write,0.00,0,4
1775059105,2040155,event-worker,0.00,0,5
1775059115,2040140,lws-main,78.50,785,52938
1775059115,2040150,db-read-1,0.00,0,72
1775059115,2040151,db-read-2,0.00,0,69
1775059115,2040152,db-read-3,0.00,0,80
1775059115,2040153,db-read-4,0.00,0,62
1775059115,2040154,db-write,0.00,0,4
1775059115,2040155,event-worker,0.00,0,5
1775059125,2040140,lws-main,40.70,407,53345
1775059125,2040150,db-read-1,0.00,0,72
1775059125,2040151,db-read-2,0.00,0,69
1775059125,2040152,db-read-3,0.10,1,81
1775059125,2040153,db-read-4,0.10,1,63
1775059125,2040154,db-write,0.00,0,4
1775059125,2040155,event-worker,0.00,0,5
1775059135,2040140,lws-main,41.00,410,53755
1775059135,2040150,db-read-1,0.00,0,72
1775059135,2040151,db-read-2,0.00,0,69
1775059135,2040152,db-read-3,0.00,0,81
1775059135,2040153,db-read-4,0.00,0,63
1775059135,2040154,db-write,0.00,0,4
1775059135,2040155,event-worker,0.00,0,5
1775059145,2040140,lws-main,58.70,587,54342
1775059145,2040150,db-read-1,0.00,0,72
1775059145,2040151,db-read-2,0.00,0,69
1775059145,2040152,db-read-3,0.00,0,81
1775059145,2040153,db-read-4,0.00,0,63
1775059145,2040154,db-write,0.00,0,4
1775059145,2040155,event-worker,0.00,0,5
1775059155,2040140,lws-main,28.40,284,54626
1775059155,2040150,db-read-1,0.20,2,74
1775059155,2040151,db-read-2,0.20,2,71
1775059155,2040152,db-read-3,0.10,1,82
1775059155,2040153,db-read-4,0.10,1,64
1775059155,2040154,db-write,0.00,0,4
1775059155,2040155,event-worker,0.00,0,5
1775059165,2040140,lws-main,89.80,898,55524
1775059165,2040150,db-read-1,0.30,3,77
1775059165,2040151,db-read-2,0.20,2,73
1775059165,2040152,db-read-3,0.30,3,85
1775059165,2040153,db-read-4,0.10,1,65
1775059165,2040154,db-write,0.00,0,4
1775059165,2040155,event-worker,0.00,0,5
1775059175,2040140,lws-main,100.20,1002,56526
1775059175,2040150,db-read-1,0.00,0,77
1775059175,2040151,db-read-2,0.00,0,73
1775059175,2040152,db-read-3,0.10,1,86
1775059175,2040153,db-read-4,0.20,2,67
1775059175,2040154,db-write,0.00,0,4
1775059175,2040155,event-worker,0.00,0,5
1775059185,2040140,lws-main,100.20,1002,57528
1775059185,2040150,db-read-1,0.20,2,79
1775059185,2040151,db-read-2,0.20,2,75
1775059185,2040152,db-read-3,0.10,1,87
1775059185,2040153,db-read-4,0.20,2,69
1775059185,2040154,db-write,0.00,0,4
1775059185,2040155,event-worker,0.00,0,5
1775059195,2040140,lws-main,75.70,757,58285
1775059195,2040150,db-read-1,0.20,2,81
1775059195,2040151,db-read-2,0.20,2,77
1775059195,2040152,db-read-3,0.20,2,89
1775059195,2040153,db-read-4,0.20,2,71
1775059195,2040154,db-write,0.00,0,4
1775059195,2040155,event-worker,0.00,0,5
1775059205,2040140,lws-main,77.70,777,59062
1775059205,2040150,db-read-1,0.20,2,83
1775059205,2040151,db-read-2,0.30,3,80
1775059205,2040152,db-read-3,0.50,5,94
1775059205,2040153,db-read-4,0.30,3,74
1775059205,2040154,db-write,0.00,0,4
1775059205,2040155,event-worker,0.10,1,6
1775059215,2040140,lws-main,99.60,996,60058
1775059215,2040150,db-read-1,0.40,4,87
1775059215,2040151,db-read-2,0.40,4,84
1775059215,2040152,db-read-3,0.10,1,95
1775059215,2040153,db-read-4,0.20,2,76
1775059215,2040154,db-write,0.00,0,4
1775059215,2040155,event-worker,0.00,0,6
1775059225,2040140,lws-main,100.30,1003,61061
1775059225,2040150,db-read-1,0.00,0,87
1775059225,2040151,db-read-2,0.10,1,85
1775059225,2040152,db-read-3,0.10,1,96
1775059225,2040153,db-read-4,0.20,2,78
1775059225,2040154,db-write,0.00,0,4
1775059225,2040155,event-worker,0.00,0,6
1775059235,2040140,lws-main,100.10,1001,62062
1775059235,2040150,db-read-1,0.10,1,88
1775059235,2040151,db-read-2,0.00,0,85
1775059235,2040152,db-read-3,0.00,0,96
1775059235,2040153,db-read-4,0.00,0,78
1775059235,2040154,db-write,0.00,0,4
1775059235,2040155,event-worker,0.00,0,6
1775059245,2040140,lws-main,98.10,981,63043
1775059245,2040150,db-read-1,0.10,1,89
1775059245,2040151,db-read-2,0.00,0,85
1775059245,2040152,db-read-3,0.20,2,98
1775059245,2040153,db-read-4,0.10,1,79
1775059245,2040154,db-write,0.00,0,4
1775059245,2040155,event-worker,0.00,0,6
1775059255,2040140,lws-main,54.10,541,63584
1775059255,2040150,db-read-1,0.20,2,91
1775059255,2040151,db-read-2,0.50,5,90
1775059255,2040152,db-read-3,0.50,5,103
1775059255,2040153,db-read-4,0.50,5,84
1775059255,2040154,db-write,0.00,0,4
1775059255,2040155,event-worker,0.00,0,6
1775059265,2040140,lws-main,82.80,828,64412
1775059265,2040150,db-read-1,0.00,0,91
1775059265,2040151,db-read-2,0.00,0,90
1775059265,2040152,db-read-3,0.00,0,103
1775059265,2040153,db-read-4,0.00,0,84
1775059265,2040154,db-write,0.00,0,4
1775059265,2040155,event-worker,0.00,0,6
1775059275,2040140,lws-main,99.90,999,65411
1775059275,2040150,db-read-1,0.10,1,92
1775059275,2040151,db-read-2,0.00,0,90
1775059275,2040152,db-read-3,0.00,0,103
1775059275,2040153,db-read-4,0.00,0,84
1775059275,2040154,db-write,0.00,0,4
1775059275,2040155,event-worker,0.00,0,6
1775059285,2040140,lws-main,58.30,583,65994
1775059285,2040150,db-read-1,0.00,0,92
1775059285,2040151,db-read-2,0.10,1,91
1775059285,2040152,db-read-3,0.10,1,104
1775059285,2040153,db-read-4,0.00,0,84
1775059285,2040154,db-write,0.00,0,4
1775059285,2040155,event-worker,0.00,0,6
1775059295,2040140,lws-main,42.60,426,66420
1775059295,2040150,db-read-1,0.30,3,95
1775059295,2040151,db-read-2,0.10,1,92
1775059295,2040152,db-read-3,0.10,1,105
1775059295,2040153,db-read-4,0.20,2,86
1775059295,2040154,db-write,0.00,0,4
1775059295,2040155,event-worker,0.00,0,6
1775059305,2040140,lws-main,16.20,162,66582
1775059305,2040150,db-read-1,0.20,2,97
1775059305,2040151,db-read-2,0.00,0,92
1775059305,2040152,db-read-3,0.10,1,106
1775059305,2040153,db-read-4,0.10,1,87
1775059305,2040154,db-write,0.00,0,4
1775059305,2040155,event-worker,0.00,0,6
1775059315,2040140,lws-main,100.30,1003,67585
1775059315,2040150,db-read-1,0.00,0,97
1775059315,2040151,db-read-2,0.00,0,92
1775059315,2040152,db-read-3,0.00,0,106
1775059315,2040153,db-read-4,0.00,0,87
1775059315,2040154,db-write,0.00,0,4
1775059315,2040155,event-worker,0.00,0,6
1775059325,2040140,lws-main,66.00,660,68245
1775059325,2040150,db-read-1,0.20,2,99
1775059325,2040151,db-read-2,0.50,5,97
1775059325,2040152,db-read-3,0.20,2,108
1775059325,2040153,db-read-4,0.20,2,89
1775059325,2040154,db-write,0.00,0,4
1775059325,2040155,event-worker,0.00,0,6
1775059335,2040140,lws-main,21.70,217,68462
1775059335,2040150,db-read-1,0.00,0,99
1775059335,2040151,db-read-2,0.00,0,97
1775059335,2040152,db-read-3,0.00,0,108
1775059335,2040153,db-read-4,0.00,0,89
1775059335,2040154,db-write,0.00,0,4
1775059335,2040155,event-worker,0.00,0,6
1775059345,2040140,lws-main,47.00,470,68932
1775059345,2040150,db-read-1,0.30,3,102
1775059345,2040151,db-read-2,0.30,3,100
1775059345,2040152,db-read-3,0.90,9,117
1775059345,2040153,db-read-4,0.20,2,91
1775059345,2040154,db-write,0.00,0,4
1775059345,2040155,event-worker,0.00,0,6
1775059355,2040140,lws-main,54.40,544,69476
1775059355,2040150,db-read-1,0.00,0,102
1775059355,2040151,db-read-2,0.00,0,100
1775059355,2040152,db-read-3,0.00,0,117
1775059355,2040153,db-read-4,0.00,0,91
1775059355,2040154,db-write,0.00,0,4
1775059355,2040155,event-worker,0.00,0,6
1775059365,2040140,lws-main,99.70,997,70473
1775059365,2040150,db-read-1,0.10,1,103
1775059365,2040151,db-read-2,0.10,1,101
1775059365,2040152,db-read-3,0.00,0,117
1775059365,2040153,db-read-4,0.00,0,91
1775059365,2040154,db-write,0.00,0,4
1775059365,2040155,event-worker,0.00,0,6
1775059375,2040140,lws-main,46.20,462,70935
1775059375,2040150,db-read-1,0.20,2,105
1775059375,2040151,db-read-2,0.10,1,102
1775059375,2040152,db-read-3,0.40,4,121
1775059375,2040153,db-read-4,0.20,2,93
1775059375,2040154,db-write,0.00,0,4
1775059375,2040155,event-worker,0.00,0,6
1775059385,2040140,lws-main,69.00,690,71625
1775059385,2040150,db-read-1,0.10,1,106
1775059385,2040151,db-read-2,0.00,0,102
1775059385,2040152,db-read-3,0.10,1,122
1775059385,2040153,db-read-4,0.10,1,94
1775059385,2040154,db-write,0.00,0,4
1775059385,2040155,event-worker,0.00,0,6
1775059395,2040140,lws-main,71.50,715,72340
1775059395,2040150,db-read-1,0.00,0,106
1775059395,2040151,db-read-2,0.20,2,104
1775059395,2040152,db-read-3,0.10,1,123
1775059395,2040153,db-read-4,0.30,3,97
1775059395,2040154,db-write,0.00,0,4
1775059395,2040155,event-worker,0.00,0,6
1775059405,2040140,lws-main,100.10,1001,73341
1775059405,2040150,db-read-1,0.20,2,108
1775059405,2040151,db-read-2,0.00,0,104
1775059405,2040152,db-read-3,0.00,0,123
1775059405,2040153,db-read-4,0.20,2,99
1775059405,2040154,db-write,0.00,0,4
1775059405,2040155,event-worker,0.00,0,6
1775059415,2040140,lws-main,100.20,1002,74343
1775059415,2040150,db-read-1,0.30,3,111
1775059415,2040151,db-read-2,0.20,2,106
1775059415,2040152,db-read-3,0.20,2,125
1775059415,2040153,db-read-4,0.30,3,102
1775059415,2040154,db-write,0.10,1,5
1775059415,2040155,event-worker,0.00,0,6
1775059425,2040140,lws-main,97.40,974,75317
1775059425,2040150,db-read-1,0.10,1,112
1775059425,2040151,db-read-2,0.10,1,107
1775059425,2040152,db-read-3,0.30,3,128
1775059425,2040153,db-read-4,0.10,1,103
1775059425,2040154,db-write,0.00,0,5
1775059425,2040155,event-worker,0.00,0,6
1775059435,2040140,lws-main,80.60,806,76123
1775059435,2040150,db-read-1,0.10,1,113
1775059435,2040151,db-read-2,0.20,2,109
1775059435,2040152,db-read-3,0.10,1,129
1775059435,2040153,db-read-4,0.10,1,104
1775059435,2040154,db-write,0.00,0,5
1775059435,2040155,event-worker,0.00,0,6
1775059445,2040140,lws-main,40.70,407,76530
1775059445,2040150,db-read-1,0.10,1,114
1775059445,2040151,db-read-2,0.00,0,109
1775059445,2040152,db-read-3,0.20,2,131
1775059445,2040153,db-read-4,0.10,1,105
1775059445,2040154,db-write,0.00,0,5
1775059445,2040155,event-worker,0.00,0,6
1775059456,2040140,lws-main,56.00,560,77090
1775059456,2040150,db-read-1,0.00,0,114
1775059456,2040151,db-read-2,0.20,2,111
1775059456,2040152,db-read-3,0.00,0,131
1775059456,2040153,db-read-4,0.10,1,106
1775059456,2040154,db-write,0.00,0,5
1775059456,2040155,event-worker,0.00,0,6
1775059466,2040140,lws-main,53.20,532,77622
1775059466,2040150,db-read-1,0.00,0,114
1775059466,2040151,db-read-2,0.00,0,111
1775059466,2040152,db-read-3,0.00,0,131
1775059466,2040153,db-read-4,0.00,0,106
1775059466,2040154,db-write,0.00,0,5
1775059466,2040155,event-worker,0.00,0,6
1775059476,2040140,lws-main,96.70,967,78589
1775059476,2040150,db-read-1,0.00,0,114
1775059476,2040151,db-read-2,0.00,0,111
1775059476,2040152,db-read-3,0.00,0,131
1775059476,2040153,db-read-4,0.00,0,106
1775059476,2040154,db-write,0.00,0,5
1775059476,2040155,event-worker,0.00,0,6
1775059486,2040140,lws-main,67.60,676,79265
1775059486,2040150,db-read-1,0.20,2,116
1775059486,2040151,db-read-2,0.00,0,111
1775059486,2040152,db-read-3,0.00,0,131
1775059486,2040153,db-read-4,0.00,0,106
1775059486,2040154,db-write,0.00,0,5
1775059486,2040155,event-worker,0.00,0,6
1 timestamp tid thread_name cpu_pct delta_ticks total_ticks
2 1775058964 2040140 lws-main 0.00 0 42849
3 1775058964 2040150 db-read-1 0.00 0 58
4 1775058964 2040151 db-read-2 0.00 0 54
5 1775058964 2040152 db-read-3 0.10 1 68
6 1775058964 2040153 db-read-4 0.00 0 53
7 1775058964 2040154 db-write 0.00 0 2
8 1775058964 2040155 event-worker 0.00 0 5
9 1775058974 2040140 lws-main 59.30 593 43442
10 1775058974 2040150 db-read-1 0.00 0 58
11 1775058974 2040151 db-read-2 0.00 0 54
12 1775058974 2040152 db-read-3 0.10 1 69
13 1775058974 2040153 db-read-4 0.00 0 53
14 1775058974 2040154 db-write 0.00 0 2
15 1775058974 2040155 event-worker 0.00 0 5
16 1775058984 2040140 lws-main 67.40 674 44116
17 1775058984 2040150 db-read-1 0.00 0 58
18 1775058984 2040151 db-read-2 0.00 0 54
19 1775058984 2040152 db-read-3 0.00 0 69
20 1775058984 2040153 db-read-4 0.10 1 54
21 1775058984 2040154 db-write 0.00 0 2
22 1775058984 2040155 event-worker 0.00 0 5
23 1775058994 2040140 lws-main 98.70 987 45103
24 1775058994 2040150 db-read-1 0.10 1 59
25 1775058994 2040151 db-read-2 0.00 0 54
26 1775058994 2040152 db-read-3 0.00 0 69
27 1775058994 2040153 db-read-4 0.00 0 54
28 1775058994 2040154 db-write 0.00 0 2
29 1775058994 2040155 event-worker 0.00 0 5
30 1775059004 2040140 lws-main 71.00 710 45813
31 1775059004 2040150 db-read-1 0.00 0 59
32 1775059004 2040151 db-read-2 0.00 0 54
33 1775059004 2040152 db-read-3 0.10 1 70
34 1775059004 2040153 db-read-4 0.10 1 55
35 1775059004 2040154 db-write 0.00 0 2
36 1775059004 2040155 event-worker 0.00 0 5
37 1775059014 2040140 lws-main 14.70 147 45960
38 1775059014 2040150 db-read-1 0.10 1 60
39 1775059014 2040151 db-read-2 0.30 3 57
40 1775059014 2040152 db-read-3 0.10 1 71
41 1775059014 2040153 db-read-4 0.10 1 56
42 1775059014 2040154 db-write 0.00 0 2
43 1775059014 2040155 event-worker 0.00 0 5
44 1775059024 2040140 lws-main 47.70 477 46437
45 1775059024 2040150 db-read-1 0.00 0 60
46 1775059024 2040151 db-read-2 0.00 0 57
47 1775059024 2040152 db-read-3 0.00 0 71
48 1775059024 2040153 db-read-4 0.00 0 56
49 1775059024 2040154 db-write 0.00 0 2
50 1775059024 2040155 event-worker 0.00 0 5
51 1775059034 2040140 lws-main 99.50 995 47432
52 1775059034 2040150 db-read-1 0.10 1 61
53 1775059034 2040151 db-read-2 0.10 1 58
54 1775059034 2040152 db-read-3 0.10 1 72
55 1775059034 2040153 db-read-4 0.00 0 56
56 1775059034 2040154 db-write 0.10 1 3
57 1775059034 2040155 event-worker 0.00 0 5
58 1775059044 2040140 lws-main 88.50 885 48317
59 1775059044 2040150 db-read-1 0.20 2 63
60 1775059044 2040151 db-read-2 0.10 1 59
61 1775059044 2040152 db-read-3 0.10 1 73
62 1775059044 2040153 db-read-4 0.20 2 58
63 1775059044 2040154 db-write 0.00 0 3
64 1775059044 2040155 event-worker 0.00 0 5
65 1775059054 2040140 lws-main 67.70 677 48994
66 1775059054 2040150 db-read-1 0.00 0 63
67 1775059054 2040151 db-read-2 0.00 0 59
68 1775059054 2040152 db-read-3 0.00 0 73
69 1775059054 2040153 db-read-4 0.00 0 58
70 1775059054 2040154 db-write 0.00 0 3
71 1775059054 2040155 event-worker 0.00 0 5
72 1775059064 2040140 lws-main 53.10 531 49525
73 1775059064 2040150 db-read-1 0.40 4 67
74 1775059064 2040151 db-read-2 0.40 4 63
75 1775059064 2040152 db-read-3 0.20 2 75
76 1775059064 2040153 db-read-4 0.00 0 58
77 1775059064 2040154 db-write 0.00 0 3
78 1775059064 2040155 event-worker 0.00 0 5
79 1775059074 2040140 lws-main 61.60 616 50141
80 1775059074 2040150 db-read-1 0.30 3 70
81 1775059074 2040151 db-read-2 0.20 2 65
82 1775059074 2040152 db-read-3 0.10 1 76
83 1775059074 2040153 db-read-4 0.20 2 60
84 1775059074 2040154 db-write 0.00 0 3
85 1775059074 2040155 event-worker 0.00 0 5
86 1775059084 2040140 lws-main 96.20 962 51103
87 1775059084 2040150 db-read-1 0.00 0 70
88 1775059084 2040151 db-read-2 0.20 2 67
89 1775059084 2040152 db-read-3 0.40 4 80
90 1775059084 2040153 db-read-4 0.10 1 61
91 1775059084 2040154 db-write 0.10 1 4
92 1775059084 2040155 event-worker 0.00 0 5
93 1775059094 2040140 lws-main 53.60 536 51639
94 1775059094 2040150 db-read-1 0.10 1 71
95 1775059094 2040151 db-read-2 0.20 2 69
96 1775059094 2040152 db-read-3 0.00 0 80
97 1775059094 2040153 db-read-4 0.00 0 61
98 1775059094 2040154 db-write 0.00 0 4
99 1775059094 2040155 event-worker 0.00 0 5
100 1775059105 2040140 lws-main 51.40 514 52153
101 1775059105 2040150 db-read-1 0.10 1 72
102 1775059105 2040151 db-read-2 0.00 0 69
103 1775059105 2040152 db-read-3 0.00 0 80
104 1775059105 2040153 db-read-4 0.10 1 62
105 1775059105 2040154 db-write 0.00 0 4
106 1775059105 2040155 event-worker 0.00 0 5
107 1775059115 2040140 lws-main 78.50 785 52938
108 1775059115 2040150 db-read-1 0.00 0 72
109 1775059115 2040151 db-read-2 0.00 0 69
110 1775059115 2040152 db-read-3 0.00 0 80
111 1775059115 2040153 db-read-4 0.00 0 62
112 1775059115 2040154 db-write 0.00 0 4
113 1775059115 2040155 event-worker 0.00 0 5
114 1775059125 2040140 lws-main 40.70 407 53345
115 1775059125 2040150 db-read-1 0.00 0 72
116 1775059125 2040151 db-read-2 0.00 0 69
117 1775059125 2040152 db-read-3 0.10 1 81
118 1775059125 2040153 db-read-4 0.10 1 63
119 1775059125 2040154 db-write 0.00 0 4
120 1775059125 2040155 event-worker 0.00 0 5
121 1775059135 2040140 lws-main 41.00 410 53755
122 1775059135 2040150 db-read-1 0.00 0 72
123 1775059135 2040151 db-read-2 0.00 0 69
124 1775059135 2040152 db-read-3 0.00 0 81
125 1775059135 2040153 db-read-4 0.00 0 63
126 1775059135 2040154 db-write 0.00 0 4
127 1775059135 2040155 event-worker 0.00 0 5
128 1775059145 2040140 lws-main 58.70 587 54342
129 1775059145 2040150 db-read-1 0.00 0 72
130 1775059145 2040151 db-read-2 0.00 0 69
131 1775059145 2040152 db-read-3 0.00 0 81
132 1775059145 2040153 db-read-4 0.00 0 63
133 1775059145 2040154 db-write 0.00 0 4
134 1775059145 2040155 event-worker 0.00 0 5
135 1775059155 2040140 lws-main 28.40 284 54626
136 1775059155 2040150 db-read-1 0.20 2 74
137 1775059155 2040151 db-read-2 0.20 2 71
138 1775059155 2040152 db-read-3 0.10 1 82
139 1775059155 2040153 db-read-4 0.10 1 64
140 1775059155 2040154 db-write 0.00 0 4
141 1775059155 2040155 event-worker 0.00 0 5
142 1775059165 2040140 lws-main 89.80 898 55524
143 1775059165 2040150 db-read-1 0.30 3 77
144 1775059165 2040151 db-read-2 0.20 2 73
145 1775059165 2040152 db-read-3 0.30 3 85
146 1775059165 2040153 db-read-4 0.10 1 65
147 1775059165 2040154 db-write 0.00 0 4
148 1775059165 2040155 event-worker 0.00 0 5
149 1775059175 2040140 lws-main 100.20 1002 56526
150 1775059175 2040150 db-read-1 0.00 0 77
151 1775059175 2040151 db-read-2 0.00 0 73
152 1775059175 2040152 db-read-3 0.10 1 86
153 1775059175 2040153 db-read-4 0.20 2 67
154 1775059175 2040154 db-write 0.00 0 4
155 1775059175 2040155 event-worker 0.00 0 5
156 1775059185 2040140 lws-main 100.20 1002 57528
157 1775059185 2040150 db-read-1 0.20 2 79
158 1775059185 2040151 db-read-2 0.20 2 75
159 1775059185 2040152 db-read-3 0.10 1 87
160 1775059185 2040153 db-read-4 0.20 2 69
161 1775059185 2040154 db-write 0.00 0 4
162 1775059185 2040155 event-worker 0.00 0 5
163 1775059195 2040140 lws-main 75.70 757 58285
164 1775059195 2040150 db-read-1 0.20 2 81
165 1775059195 2040151 db-read-2 0.20 2 77
166 1775059195 2040152 db-read-3 0.20 2 89
167 1775059195 2040153 db-read-4 0.20 2 71
168 1775059195 2040154 db-write 0.00 0 4
169 1775059195 2040155 event-worker 0.00 0 5
170 1775059205 2040140 lws-main 77.70 777 59062
171 1775059205 2040150 db-read-1 0.20 2 83
172 1775059205 2040151 db-read-2 0.30 3 80
173 1775059205 2040152 db-read-3 0.50 5 94
174 1775059205 2040153 db-read-4 0.30 3 74
175 1775059205 2040154 db-write 0.00 0 4
176 1775059205 2040155 event-worker 0.10 1 6
177 1775059215 2040140 lws-main 99.60 996 60058
178 1775059215 2040150 db-read-1 0.40 4 87
179 1775059215 2040151 db-read-2 0.40 4 84
180 1775059215 2040152 db-read-3 0.10 1 95
181 1775059215 2040153 db-read-4 0.20 2 76
182 1775059215 2040154 db-write 0.00 0 4
183 1775059215 2040155 event-worker 0.00 0 6
184 1775059225 2040140 lws-main 100.30 1003 61061
185 1775059225 2040150 db-read-1 0.00 0 87
186 1775059225 2040151 db-read-2 0.10 1 85
187 1775059225 2040152 db-read-3 0.10 1 96
188 1775059225 2040153 db-read-4 0.20 2 78
189 1775059225 2040154 db-write 0.00 0 4
190 1775059225 2040155 event-worker 0.00 0 6
191 1775059235 2040140 lws-main 100.10 1001 62062
192 1775059235 2040150 db-read-1 0.10 1 88
193 1775059235 2040151 db-read-2 0.00 0 85
194 1775059235 2040152 db-read-3 0.00 0 96
195 1775059235 2040153 db-read-4 0.00 0 78
196 1775059235 2040154 db-write 0.00 0 4
197 1775059235 2040155 event-worker 0.00 0 6
198 1775059245 2040140 lws-main 98.10 981 63043
199 1775059245 2040150 db-read-1 0.10 1 89
200 1775059245 2040151 db-read-2 0.00 0 85
201 1775059245 2040152 db-read-3 0.20 2 98
202 1775059245 2040153 db-read-4 0.10 1 79
203 1775059245 2040154 db-write 0.00 0 4
204 1775059245 2040155 event-worker 0.00 0 6
205 1775059255 2040140 lws-main 54.10 541 63584
206 1775059255 2040150 db-read-1 0.20 2 91
207 1775059255 2040151 db-read-2 0.50 5 90
208 1775059255 2040152 db-read-3 0.50 5 103
209 1775059255 2040153 db-read-4 0.50 5 84
210 1775059255 2040154 db-write 0.00 0 4
211 1775059255 2040155 event-worker 0.00 0 6
212 1775059265 2040140 lws-main 82.80 828 64412
213 1775059265 2040150 db-read-1 0.00 0 91
214 1775059265 2040151 db-read-2 0.00 0 90
215 1775059265 2040152 db-read-3 0.00 0 103
216 1775059265 2040153 db-read-4 0.00 0 84
217 1775059265 2040154 db-write 0.00 0 4
218 1775059265 2040155 event-worker 0.00 0 6
219 1775059275 2040140 lws-main 99.90 999 65411
220 1775059275 2040150 db-read-1 0.10 1 92
221 1775059275 2040151 db-read-2 0.00 0 90
222 1775059275 2040152 db-read-3 0.00 0 103
223 1775059275 2040153 db-read-4 0.00 0 84
224 1775059275 2040154 db-write 0.00 0 4
225 1775059275 2040155 event-worker 0.00 0 6
226 1775059285 2040140 lws-main 58.30 583 65994
227 1775059285 2040150 db-read-1 0.00 0 92
228 1775059285 2040151 db-read-2 0.10 1 91
229 1775059285 2040152 db-read-3 0.10 1 104
230 1775059285 2040153 db-read-4 0.00 0 84
231 1775059285 2040154 db-write 0.00 0 4
232 1775059285 2040155 event-worker 0.00 0 6
233 1775059295 2040140 lws-main 42.60 426 66420
234 1775059295 2040150 db-read-1 0.30 3 95
235 1775059295 2040151 db-read-2 0.10 1 92
236 1775059295 2040152 db-read-3 0.10 1 105
237 1775059295 2040153 db-read-4 0.20 2 86
238 1775059295 2040154 db-write 0.00 0 4
239 1775059295 2040155 event-worker 0.00 0 6
240 1775059305 2040140 lws-main 16.20 162 66582
241 1775059305 2040150 db-read-1 0.20 2 97
242 1775059305 2040151 db-read-2 0.00 0 92
243 1775059305 2040152 db-read-3 0.10 1 106
244 1775059305 2040153 db-read-4 0.10 1 87
245 1775059305 2040154 db-write 0.00 0 4
246 1775059305 2040155 event-worker 0.00 0 6
247 1775059315 2040140 lws-main 100.30 1003 67585
248 1775059315 2040150 db-read-1 0.00 0 97
249 1775059315 2040151 db-read-2 0.00 0 92
250 1775059315 2040152 db-read-3 0.00 0 106
251 1775059315 2040153 db-read-4 0.00 0 87
252 1775059315 2040154 db-write 0.00 0 4
253 1775059315 2040155 event-worker 0.00 0 6
254 1775059325 2040140 lws-main 66.00 660 68245
255 1775059325 2040150 db-read-1 0.20 2 99
256 1775059325 2040151 db-read-2 0.50 5 97
257 1775059325 2040152 db-read-3 0.20 2 108
258 1775059325 2040153 db-read-4 0.20 2 89
259 1775059325 2040154 db-write 0.00 0 4
260 1775059325 2040155 event-worker 0.00 0 6
261 1775059335 2040140 lws-main 21.70 217 68462
262 1775059335 2040150 db-read-1 0.00 0 99
263 1775059335 2040151 db-read-2 0.00 0 97
264 1775059335 2040152 db-read-3 0.00 0 108
265 1775059335 2040153 db-read-4 0.00 0 89
266 1775059335 2040154 db-write 0.00 0 4
267 1775059335 2040155 event-worker 0.00 0 6
268 1775059345 2040140 lws-main 47.00 470 68932
269 1775059345 2040150 db-read-1 0.30 3 102
270 1775059345 2040151 db-read-2 0.30 3 100
271 1775059345 2040152 db-read-3 0.90 9 117
272 1775059345 2040153 db-read-4 0.20 2 91
273 1775059345 2040154 db-write 0.00 0 4
274 1775059345 2040155 event-worker 0.00 0 6
275 1775059355 2040140 lws-main 54.40 544 69476
276 1775059355 2040150 db-read-1 0.00 0 102
277 1775059355 2040151 db-read-2 0.00 0 100
278 1775059355 2040152 db-read-3 0.00 0 117
279 1775059355 2040153 db-read-4 0.00 0 91
280 1775059355 2040154 db-write 0.00 0 4
281 1775059355 2040155 event-worker 0.00 0 6
282 1775059365 2040140 lws-main 99.70 997 70473
283 1775059365 2040150 db-read-1 0.10 1 103
284 1775059365 2040151 db-read-2 0.10 1 101
285 1775059365 2040152 db-read-3 0.00 0 117
286 1775059365 2040153 db-read-4 0.00 0 91
287 1775059365 2040154 db-write 0.00 0 4
288 1775059365 2040155 event-worker 0.00 0 6
289 1775059375 2040140 lws-main 46.20 462 70935
290 1775059375 2040150 db-read-1 0.20 2 105
291 1775059375 2040151 db-read-2 0.10 1 102
292 1775059375 2040152 db-read-3 0.40 4 121
293 1775059375 2040153 db-read-4 0.20 2 93
294 1775059375 2040154 db-write 0.00 0 4
295 1775059375 2040155 event-worker 0.00 0 6
296 1775059385 2040140 lws-main 69.00 690 71625
297 1775059385 2040150 db-read-1 0.10 1 106
298 1775059385 2040151 db-read-2 0.00 0 102
299 1775059385 2040152 db-read-3 0.10 1 122
300 1775059385 2040153 db-read-4 0.10 1 94
301 1775059385 2040154 db-write 0.00 0 4
302 1775059385 2040155 event-worker 0.00 0 6
303 1775059395 2040140 lws-main 71.50 715 72340
304 1775059395 2040150 db-read-1 0.00 0 106
305 1775059395 2040151 db-read-2 0.20 2 104
306 1775059395 2040152 db-read-3 0.10 1 123
307 1775059395 2040153 db-read-4 0.30 3 97
308 1775059395 2040154 db-write 0.00 0 4
309 1775059395 2040155 event-worker 0.00 0 6
310 1775059405 2040140 lws-main 100.10 1001 73341
311 1775059405 2040150 db-read-1 0.20 2 108
312 1775059405 2040151 db-read-2 0.00 0 104
313 1775059405 2040152 db-read-3 0.00 0 123
314 1775059405 2040153 db-read-4 0.20 2 99
315 1775059405 2040154 db-write 0.00 0 4
316 1775059405 2040155 event-worker 0.00 0 6
317 1775059415 2040140 lws-main 100.20 1002 74343
318 1775059415 2040150 db-read-1 0.30 3 111
319 1775059415 2040151 db-read-2 0.20 2 106
320 1775059415 2040152 db-read-3 0.20 2 125
321 1775059415 2040153 db-read-4 0.30 3 102
322 1775059415 2040154 db-write 0.10 1 5
323 1775059415 2040155 event-worker 0.00 0 6
324 1775059425 2040140 lws-main 97.40 974 75317
325 1775059425 2040150 db-read-1 0.10 1 112
326 1775059425 2040151 db-read-2 0.10 1 107
327 1775059425 2040152 db-read-3 0.30 3 128
328 1775059425 2040153 db-read-4 0.10 1 103
329 1775059425 2040154 db-write 0.00 0 5
330 1775059425 2040155 event-worker 0.00 0 6
331 1775059435 2040140 lws-main 80.60 806 76123
332 1775059435 2040150 db-read-1 0.10 1 113
333 1775059435 2040151 db-read-2 0.20 2 109
334 1775059435 2040152 db-read-3 0.10 1 129
335 1775059435 2040153 db-read-4 0.10 1 104
336 1775059435 2040154 db-write 0.00 0 5
337 1775059435 2040155 event-worker 0.00 0 6
338 1775059445 2040140 lws-main 40.70 407 76530
339 1775059445 2040150 db-read-1 0.10 1 114
340 1775059445 2040151 db-read-2 0.00 0 109
341 1775059445 2040152 db-read-3 0.20 2 131
342 1775059445 2040153 db-read-4 0.10 1 105
343 1775059445 2040154 db-write 0.00 0 5
344 1775059445 2040155 event-worker 0.00 0 6
345 1775059456 2040140 lws-main 56.00 560 77090
346 1775059456 2040150 db-read-1 0.00 0 114
347 1775059456 2040151 db-read-2 0.20 2 111
348 1775059456 2040152 db-read-3 0.00 0 131
349 1775059456 2040153 db-read-4 0.10 1 106
350 1775059456 2040154 db-write 0.00 0 5
351 1775059456 2040155 event-worker 0.00 0 6
352 1775059466 2040140 lws-main 53.20 532 77622
353 1775059466 2040150 db-read-1 0.00 0 114
354 1775059466 2040151 db-read-2 0.00 0 111
355 1775059466 2040152 db-read-3 0.00 0 131
356 1775059466 2040153 db-read-4 0.00 0 106
357 1775059466 2040154 db-write 0.00 0 5
358 1775059466 2040155 event-worker 0.00 0 6
359 1775059476 2040140 lws-main 96.70 967 78589
360 1775059476 2040150 db-read-1 0.00 0 114
361 1775059476 2040151 db-read-2 0.00 0 111
362 1775059476 2040152 db-read-3 0.00 0 131
363 1775059476 2040153 db-read-4 0.00 0 106
364 1775059476 2040154 db-write 0.00 0 5
365 1775059476 2040155 event-worker 0.00 0 6
366 1775059486 2040140 lws-main 67.60 676 79265
367 1775059486 2040150 db-read-1 0.20 2 116
368 1775059486 2040151 db-read-2 0.00 0 111
369 1775059486 2040152 db-read-3 0.00 0 131
370 1775059486 2040153 db-read-4 0.00 0 106
371 1775059486 2040154 db-write 0.00 0 5
372 1775059486 2040155 event-worker 0.00 0 6
@@ -0,0 +1,14 @@
==========================================
Thread CPU Summary (avg + max over run)
==========================================
Run timestamp (UTC): 20260401_155603
Duration: 600s, Interval: 10s
2040140 lws-main 68.71 100.30
2040152 db-read-3 0.12 0.90
2040150 db-read-1 0.11 0.40
2040151 db-read-2 0.11 0.50
2040153 db-read-4 0.10 0.50
2040154 db-write 0.01 0.10
2040155 event-worker 0.00 0.10
TID THREAD AVG_CPU% MAX_CPU%
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
Profiling PID: 2083904
CLK_TCK=100
Starting perf record in background...
perf_pid=2086924
Done. Artifacts in /tmp/c_relay_thread_profile_20260401_181751
@@ -0,0 +1,211 @@
timestamp,tid,thread_name,cpu_pct,delta_ticks,total_ticks
1775067472,2083904,lws-main,0.00,0,17710
1775067472,2083906,db-read-1,0.00,0,33
1775067472,2083907,db-read-2,0.00,0,29
1775067472,2083908,db-read-3,0.00,0,31
1775067472,2083909,db-read-4,0.00,0,41
1775067472,2083910,db-write,0.00,0,0
1775067472,2083911,event-worker,0.00,0,0
1775067482,2083904,lws-main,53.40,534,18244
1775067482,2083906,db-read-1,0.20,2,35
1775067482,2083907,db-read-2,0.00,0,29
1775067482,2083908,db-read-3,0.10,1,32
1775067482,2083909,db-read-4,0.00,0,41
1775067482,2083910,db-write,0.00,0,0
1775067482,2083911,event-worker,0.00,0,0
1775067492,2083904,lws-main,100.30,1003,19247
1775067492,2083906,db-read-1,0.00,0,35
1775067492,2083907,db-read-2,0.00,0,29
1775067492,2083908,db-read-3,0.00,0,32
1775067492,2083909,db-read-4,0.00,0,41
1775067492,2083910,db-write,0.00,0,0
1775067492,2083911,event-worker,0.00,0,0
1775067502,2083904,lws-main,100.30,1003,20250
1775067502,2083906,db-read-1,0.00,0,35
1775067502,2083907,db-read-2,0.00,0,29
1775067502,2083908,db-read-3,0.00,0,32
1775067502,2083909,db-read-4,0.00,0,41
1775067502,2083910,db-write,0.00,0,0
1775067502,2083911,event-worker,0.00,0,0
1775067512,2083904,lws-main,95.70,957,21207
1775067512,2083906,db-read-1,0.00,0,35
1775067512,2083907,db-read-2,0.10,1,30
1775067512,2083908,db-read-3,0.00,0,32
1775067512,2083909,db-read-4,0.00,0,41
1775067512,2083910,db-write,0.00,0,0
1775067512,2083911,event-worker,0.00,0,0
1775067522,2083904,lws-main,73.70,737,21944
1775067522,2083906,db-read-1,0.00,0,35
1775067522,2083907,db-read-2,0.00,0,30
1775067522,2083908,db-read-3,0.00,0,32
1775067522,2083909,db-read-4,0.00,0,41
1775067522,2083910,db-write,0.00,0,0
1775067522,2083911,event-worker,0.00,0,0
1775067532,2083904,lws-main,9.80,98,22042
1775067532,2083906,db-read-1,0.00,0,35
1775067532,2083907,db-read-2,0.00,0,30
1775067532,2083908,db-read-3,0.10,1,33
1775067532,2083909,db-read-4,0.10,1,42
1775067532,2083910,db-write,0.00,0,0
1775067532,2083911,event-worker,0.00,0,0
1775067542,2083904,lws-main,28.80,288,22330
1775067542,2083906,db-read-1,0.20,2,37
1775067542,2083907,db-read-2,0.40,4,34
1775067542,2083908,db-read-3,0.10,1,34
1775067542,2083909,db-read-4,0.20,2,44
1775067542,2083910,db-write,0.00,0,0
1775067542,2083911,event-worker,0.00,0,0
1775067552,2083904,lws-main,37.80,378,22708
1775067552,2083906,db-read-1,0.20,2,39
1775067552,2083907,db-read-2,0.20,2,36
1775067552,2083908,db-read-3,0.40,4,38
1775067552,2083909,db-read-4,0.10,1,45
1775067552,2083910,db-write,0.00,0,0
1775067552,2083911,event-worker,0.00,0,0
1775067563,2083904,lws-main,89.40,894,23602
1775067563,2083906,db-read-1,0.00,0,39
1775067563,2083907,db-read-2,0.10,1,37
1775067563,2083908,db-read-3,0.00,0,38
1775067563,2083909,db-read-4,0.10,1,46
1775067563,2083910,db-write,0.00,0,0
1775067563,2083911,event-worker,0.00,0,0
1775067573,2083904,lws-main,99.50,995,24597
1775067573,2083906,db-read-1,0.00,0,39
1775067573,2083907,db-read-2,0.00,0,37
1775067573,2083908,db-read-3,0.00,0,38
1775067573,2083909,db-read-4,0.00,0,46
1775067573,2083910,db-write,0.00,0,0
1775067573,2083911,event-worker,0.00,0,0
1775067583,2083904,lws-main,100.20,1002,25599
1775067583,2083906,db-read-1,0.00,0,39
1775067583,2083907,db-read-2,0.00,0,37
1775067583,2083908,db-read-3,0.00,0,38
1775067583,2083909,db-read-4,0.00,0,46
1775067583,2083910,db-write,0.00,0,0
1775067583,2083911,event-worker,0.00,0,0
1775067593,2083904,lws-main,100.20,1002,26601
1775067593,2083906,db-read-1,0.00,0,39
1775067593,2083907,db-read-2,0.00,0,37
1775067593,2083908,db-read-3,0.00,0,38
1775067593,2083909,db-read-4,0.00,0,46
1775067593,2083910,db-write,0.00,0,0
1775067593,2083911,event-worker,0.00,0,0
1775067603,2083904,lws-main,89.20,892,27493
1775067603,2083906,db-read-1,0.60,6,45
1775067603,2083907,db-read-2,0.20,2,39
1775067603,2083908,db-read-3,0.40,4,42
1775067603,2083909,db-read-4,0.60,6,52
1775067603,2083910,db-write,0.00,0,0
1775067603,2083911,event-worker,0.00,0,0
1775067613,2083904,lws-main,76.10,761,28254
1775067613,2083906,db-read-1,0.00,0,45
1775067613,2083907,db-read-2,0.00,0,39
1775067613,2083908,db-read-3,0.00,0,42
1775067613,2083909,db-read-4,0.00,0,52
1775067613,2083910,db-write,0.00,0,0
1775067613,2083911,event-worker,0.00,0,0
1775067623,2083904,lws-main,97.90,979,29233
1775067623,2083906,db-read-1,0.10,1,46
1775067623,2083907,db-read-2,0.20,2,41
1775067623,2083908,db-read-3,0.00,0,42
1775067623,2083909,db-read-4,0.00,0,52
1775067623,2083910,db-write,0.00,0,0
1775067623,2083911,event-worker,0.00,0,0
1775067633,2083904,lws-main,45.40,454,29687
1775067633,2083906,db-read-1,0.00,0,46
1775067633,2083907,db-read-2,0.00,0,41
1775067633,2083908,db-read-3,0.10,1,43
1775067633,2083909,db-read-4,0.00,0,52
1775067633,2083910,db-write,0.00,0,0
1775067633,2083911,event-worker,0.00,0,0
1775067643,2083904,lws-main,100.40,1004,30691
1775067643,2083906,db-read-1,0.00,0,46
1775067643,2083907,db-read-2,0.00,0,41
1775067643,2083908,db-read-3,0.00,0,43
1775067643,2083909,db-read-4,0.00,0,52
1775067643,2083910,db-write,0.00,0,0
1775067643,2083911,event-worker,0.00,0,0
1775067653,2083904,lws-main,100.20,1002,31693
1775067653,2083906,db-read-1,0.10,1,47
1775067653,2083907,db-read-2,0.00,0,41
1775067653,2083908,db-read-3,0.10,1,44
1775067653,2083909,db-read-4,0.10,1,53
1775067653,2083910,db-write,0.00,0,0
1775067653,2083911,event-worker,0.00,0,0
1775067663,2083904,lws-main,68.40,684,32377
1775067663,2083906,db-read-1,0.10,1,48
1775067663,2083907,db-read-2,0.20,2,43
1775067663,2083908,db-read-3,0.10,1,45
1775067663,2083909,db-read-4,0.10,1,54
1775067663,2083910,db-write,0.00,0,0
1775067663,2083911,event-worker,0.00,0,0
1775067673,2083904,lws-main,29.60,296,32673
1775067673,2083906,db-read-1,0.10,1,49
1775067673,2083907,db-read-2,0.10,1,44
1775067673,2083908,db-read-3,0.20,2,47
1775067673,2083909,db-read-4,0.20,2,56
1775067673,2083910,db-write,0.00,0,0
1775067673,2083911,event-worker,0.00,0,0
1775067683,2083904,lws-main,58.30,583,33256
1775067683,2083906,db-read-1,0.40,4,53
1775067683,2083907,db-read-2,0.40,4,48
1775067683,2083908,db-read-3,0.40,4,51
1775067683,2083909,db-read-4,0.60,6,62
1775067683,2083910,db-write,0.00,0,0
1775067683,2083911,event-worker,0.10,1,1
1775067693,2083904,lws-main,52.90,529,33785
1775067693,2083906,db-read-1,0.10,1,54
1775067693,2083907,db-read-2,0.20,2,50
1775067693,2083908,db-read-3,0.10,1,52
1775067693,2083909,db-read-4,0.10,1,63
1775067693,2083910,db-write,0.00,0,0
1775067693,2083911,event-worker,0.00,0,1
1775067703,2083904,lws-main,43.10,431,34216
1775067703,2083906,db-read-1,0.10,1,55
1775067703,2083907,db-read-2,0.00,0,50
1775067703,2083908,db-read-3,0.00,0,52
1775067703,2083909,db-read-4,0.10,1,64
1775067703,2083910,db-write,0.00,0,0
1775067703,2083911,event-worker,0.00,0,1
1775067713,2083904,lws-main,60.20,602,34818
1775067713,2083906,db-read-1,0.00,0,55
1775067713,2083907,db-read-2,0.00,0,50
1775067713,2083908,db-read-3,0.00,0,52
1775067713,2083909,db-read-4,0.00,0,64
1775067713,2083910,db-write,0.00,0,0
1775067713,2083911,event-worker,0.00,0,1
1775067723,2083904,lws-main,100.40,1004,35822
1775067723,2083906,db-read-1,0.00,0,55
1775067723,2083907,db-read-2,0.00,0,50
1775067723,2083908,db-read-3,0.00,0,52
1775067723,2083909,db-read-4,0.00,0,64
1775067723,2083910,db-write,0.00,0,0
1775067723,2083911,event-worker,0.00,0,1
1775067733,2083904,lws-main,100.20,1002,36824
1775067733,2083906,db-read-1,0.00,0,55
1775067733,2083907,db-read-2,0.00,0,50
1775067733,2083908,db-read-3,0.00,0,52
1775067733,2083909,db-read-4,0.00,0,64
1775067733,2083910,db-write,0.00,0,0
1775067733,2083911,event-worker,0.00,0,1
1775067743,2083904,lws-main,100.20,1002,37826
1775067743,2083906,db-read-1,0.00,0,55
1775067743,2083907,db-read-2,0.00,0,50
1775067743,2083908,db-read-3,0.20,2,54
1775067743,2083909,db-read-4,0.00,0,64
1775067743,2083910,db-write,0.00,0,0
1775067743,2083911,event-worker,0.00,0,1
1775067753,2083904,lws-main,93.70,937,38763
1775067753,2083906,db-read-1,0.20,2,57
1775067753,2083907,db-read-2,0.20,2,52
1775067753,2083908,db-read-3,0.10,1,55
1775067753,2083909,db-read-4,0.20,2,66
1775067753,2083910,db-write,0.10,1,1
1775067753,2083911,event-worker,0.00,0,1
1775067763,2083904,lws-main,100.10,1001,39764
1775067763,2083906,db-read-1,0.00,0,57
1775067763,2083907,db-read-2,0.00,0,52
1775067763,2083908,db-read-3,0.00,0,55
1775067763,2083909,db-read-4,0.00,0,66
1775067763,2083910,db-write,0.00,0,1
1775067763,2083911,event-worker,0.00,0,1
1 timestamp tid thread_name cpu_pct delta_ticks total_ticks
2 1775067472 2083904 lws-main 0.00 0 17710
3 1775067472 2083906 db-read-1 0.00 0 33
4 1775067472 2083907 db-read-2 0.00 0 29
5 1775067472 2083908 db-read-3 0.00 0 31
6 1775067472 2083909 db-read-4 0.00 0 41
7 1775067472 2083910 db-write 0.00 0 0
8 1775067472 2083911 event-worker 0.00 0 0
9 1775067482 2083904 lws-main 53.40 534 18244
10 1775067482 2083906 db-read-1 0.20 2 35
11 1775067482 2083907 db-read-2 0.00 0 29
12 1775067482 2083908 db-read-3 0.10 1 32
13 1775067482 2083909 db-read-4 0.00 0 41
14 1775067482 2083910 db-write 0.00 0 0
15 1775067482 2083911 event-worker 0.00 0 0
16 1775067492 2083904 lws-main 100.30 1003 19247
17 1775067492 2083906 db-read-1 0.00 0 35
18 1775067492 2083907 db-read-2 0.00 0 29
19 1775067492 2083908 db-read-3 0.00 0 32
20 1775067492 2083909 db-read-4 0.00 0 41
21 1775067492 2083910 db-write 0.00 0 0
22 1775067492 2083911 event-worker 0.00 0 0
23 1775067502 2083904 lws-main 100.30 1003 20250
24 1775067502 2083906 db-read-1 0.00 0 35
25 1775067502 2083907 db-read-2 0.00 0 29
26 1775067502 2083908 db-read-3 0.00 0 32
27 1775067502 2083909 db-read-4 0.00 0 41
28 1775067502 2083910 db-write 0.00 0 0
29 1775067502 2083911 event-worker 0.00 0 0
30 1775067512 2083904 lws-main 95.70 957 21207
31 1775067512 2083906 db-read-1 0.00 0 35
32 1775067512 2083907 db-read-2 0.10 1 30
33 1775067512 2083908 db-read-3 0.00 0 32
34 1775067512 2083909 db-read-4 0.00 0 41
35 1775067512 2083910 db-write 0.00 0 0
36 1775067512 2083911 event-worker 0.00 0 0
37 1775067522 2083904 lws-main 73.70 737 21944
38 1775067522 2083906 db-read-1 0.00 0 35
39 1775067522 2083907 db-read-2 0.00 0 30
40 1775067522 2083908 db-read-3 0.00 0 32
41 1775067522 2083909 db-read-4 0.00 0 41
42 1775067522 2083910 db-write 0.00 0 0
43 1775067522 2083911 event-worker 0.00 0 0
44 1775067532 2083904 lws-main 9.80 98 22042
45 1775067532 2083906 db-read-1 0.00 0 35
46 1775067532 2083907 db-read-2 0.00 0 30
47 1775067532 2083908 db-read-3 0.10 1 33
48 1775067532 2083909 db-read-4 0.10 1 42
49 1775067532 2083910 db-write 0.00 0 0
50 1775067532 2083911 event-worker 0.00 0 0
51 1775067542 2083904 lws-main 28.80 288 22330
52 1775067542 2083906 db-read-1 0.20 2 37
53 1775067542 2083907 db-read-2 0.40 4 34
54 1775067542 2083908 db-read-3 0.10 1 34
55 1775067542 2083909 db-read-4 0.20 2 44
56 1775067542 2083910 db-write 0.00 0 0
57 1775067542 2083911 event-worker 0.00 0 0
58 1775067552 2083904 lws-main 37.80 378 22708
59 1775067552 2083906 db-read-1 0.20 2 39
60 1775067552 2083907 db-read-2 0.20 2 36
61 1775067552 2083908 db-read-3 0.40 4 38
62 1775067552 2083909 db-read-4 0.10 1 45
63 1775067552 2083910 db-write 0.00 0 0
64 1775067552 2083911 event-worker 0.00 0 0
65 1775067563 2083904 lws-main 89.40 894 23602
66 1775067563 2083906 db-read-1 0.00 0 39
67 1775067563 2083907 db-read-2 0.10 1 37
68 1775067563 2083908 db-read-3 0.00 0 38
69 1775067563 2083909 db-read-4 0.10 1 46
70 1775067563 2083910 db-write 0.00 0 0
71 1775067563 2083911 event-worker 0.00 0 0
72 1775067573 2083904 lws-main 99.50 995 24597
73 1775067573 2083906 db-read-1 0.00 0 39
74 1775067573 2083907 db-read-2 0.00 0 37
75 1775067573 2083908 db-read-3 0.00 0 38
76 1775067573 2083909 db-read-4 0.00 0 46
77 1775067573 2083910 db-write 0.00 0 0
78 1775067573 2083911 event-worker 0.00 0 0
79 1775067583 2083904 lws-main 100.20 1002 25599
80 1775067583 2083906 db-read-1 0.00 0 39
81 1775067583 2083907 db-read-2 0.00 0 37
82 1775067583 2083908 db-read-3 0.00 0 38
83 1775067583 2083909 db-read-4 0.00 0 46
84 1775067583 2083910 db-write 0.00 0 0
85 1775067583 2083911 event-worker 0.00 0 0
86 1775067593 2083904 lws-main 100.20 1002 26601
87 1775067593 2083906 db-read-1 0.00 0 39
88 1775067593 2083907 db-read-2 0.00 0 37
89 1775067593 2083908 db-read-3 0.00 0 38
90 1775067593 2083909 db-read-4 0.00 0 46
91 1775067593 2083910 db-write 0.00 0 0
92 1775067593 2083911 event-worker 0.00 0 0
93 1775067603 2083904 lws-main 89.20 892 27493
94 1775067603 2083906 db-read-1 0.60 6 45
95 1775067603 2083907 db-read-2 0.20 2 39
96 1775067603 2083908 db-read-3 0.40 4 42
97 1775067603 2083909 db-read-4 0.60 6 52
98 1775067603 2083910 db-write 0.00 0 0
99 1775067603 2083911 event-worker 0.00 0 0
100 1775067613 2083904 lws-main 76.10 761 28254
101 1775067613 2083906 db-read-1 0.00 0 45
102 1775067613 2083907 db-read-2 0.00 0 39
103 1775067613 2083908 db-read-3 0.00 0 42
104 1775067613 2083909 db-read-4 0.00 0 52
105 1775067613 2083910 db-write 0.00 0 0
106 1775067613 2083911 event-worker 0.00 0 0
107 1775067623 2083904 lws-main 97.90 979 29233
108 1775067623 2083906 db-read-1 0.10 1 46
109 1775067623 2083907 db-read-2 0.20 2 41
110 1775067623 2083908 db-read-3 0.00 0 42
111 1775067623 2083909 db-read-4 0.00 0 52
112 1775067623 2083910 db-write 0.00 0 0
113 1775067623 2083911 event-worker 0.00 0 0
114 1775067633 2083904 lws-main 45.40 454 29687
115 1775067633 2083906 db-read-1 0.00 0 46
116 1775067633 2083907 db-read-2 0.00 0 41
117 1775067633 2083908 db-read-3 0.10 1 43
118 1775067633 2083909 db-read-4 0.00 0 52
119 1775067633 2083910 db-write 0.00 0 0
120 1775067633 2083911 event-worker 0.00 0 0
121 1775067643 2083904 lws-main 100.40 1004 30691
122 1775067643 2083906 db-read-1 0.00 0 46
123 1775067643 2083907 db-read-2 0.00 0 41
124 1775067643 2083908 db-read-3 0.00 0 43
125 1775067643 2083909 db-read-4 0.00 0 52
126 1775067643 2083910 db-write 0.00 0 0
127 1775067643 2083911 event-worker 0.00 0 0
128 1775067653 2083904 lws-main 100.20 1002 31693
129 1775067653 2083906 db-read-1 0.10 1 47
130 1775067653 2083907 db-read-2 0.00 0 41
131 1775067653 2083908 db-read-3 0.10 1 44
132 1775067653 2083909 db-read-4 0.10 1 53
133 1775067653 2083910 db-write 0.00 0 0
134 1775067653 2083911 event-worker 0.00 0 0
135 1775067663 2083904 lws-main 68.40 684 32377
136 1775067663 2083906 db-read-1 0.10 1 48
137 1775067663 2083907 db-read-2 0.20 2 43
138 1775067663 2083908 db-read-3 0.10 1 45
139 1775067663 2083909 db-read-4 0.10 1 54
140 1775067663 2083910 db-write 0.00 0 0
141 1775067663 2083911 event-worker 0.00 0 0
142 1775067673 2083904 lws-main 29.60 296 32673
143 1775067673 2083906 db-read-1 0.10 1 49
144 1775067673 2083907 db-read-2 0.10 1 44
145 1775067673 2083908 db-read-3 0.20 2 47
146 1775067673 2083909 db-read-4 0.20 2 56
147 1775067673 2083910 db-write 0.00 0 0
148 1775067673 2083911 event-worker 0.00 0 0
149 1775067683 2083904 lws-main 58.30 583 33256
150 1775067683 2083906 db-read-1 0.40 4 53
151 1775067683 2083907 db-read-2 0.40 4 48
152 1775067683 2083908 db-read-3 0.40 4 51
153 1775067683 2083909 db-read-4 0.60 6 62
154 1775067683 2083910 db-write 0.00 0 0
155 1775067683 2083911 event-worker 0.10 1 1
156 1775067693 2083904 lws-main 52.90 529 33785
157 1775067693 2083906 db-read-1 0.10 1 54
158 1775067693 2083907 db-read-2 0.20 2 50
159 1775067693 2083908 db-read-3 0.10 1 52
160 1775067693 2083909 db-read-4 0.10 1 63
161 1775067693 2083910 db-write 0.00 0 0
162 1775067693 2083911 event-worker 0.00 0 1
163 1775067703 2083904 lws-main 43.10 431 34216
164 1775067703 2083906 db-read-1 0.10 1 55
165 1775067703 2083907 db-read-2 0.00 0 50
166 1775067703 2083908 db-read-3 0.00 0 52
167 1775067703 2083909 db-read-4 0.10 1 64
168 1775067703 2083910 db-write 0.00 0 0
169 1775067703 2083911 event-worker 0.00 0 1
170 1775067713 2083904 lws-main 60.20 602 34818
171 1775067713 2083906 db-read-1 0.00 0 55
172 1775067713 2083907 db-read-2 0.00 0 50
173 1775067713 2083908 db-read-3 0.00 0 52
174 1775067713 2083909 db-read-4 0.00 0 64
175 1775067713 2083910 db-write 0.00 0 0
176 1775067713 2083911 event-worker 0.00 0 1
177 1775067723 2083904 lws-main 100.40 1004 35822
178 1775067723 2083906 db-read-1 0.00 0 55
179 1775067723 2083907 db-read-2 0.00 0 50
180 1775067723 2083908 db-read-3 0.00 0 52
181 1775067723 2083909 db-read-4 0.00 0 64
182 1775067723 2083910 db-write 0.00 0 0
183 1775067723 2083911 event-worker 0.00 0 1
184 1775067733 2083904 lws-main 100.20 1002 36824
185 1775067733 2083906 db-read-1 0.00 0 55
186 1775067733 2083907 db-read-2 0.00 0 50
187 1775067733 2083908 db-read-3 0.00 0 52
188 1775067733 2083909 db-read-4 0.00 0 64
189 1775067733 2083910 db-write 0.00 0 0
190 1775067733 2083911 event-worker 0.00 0 1
191 1775067743 2083904 lws-main 100.20 1002 37826
192 1775067743 2083906 db-read-1 0.00 0 55
193 1775067743 2083907 db-read-2 0.00 0 50
194 1775067743 2083908 db-read-3 0.20 2 54
195 1775067743 2083909 db-read-4 0.00 0 64
196 1775067743 2083910 db-write 0.00 0 0
197 1775067743 2083911 event-worker 0.00 0 1
198 1775067753 2083904 lws-main 93.70 937 38763
199 1775067753 2083906 db-read-1 0.20 2 57
200 1775067753 2083907 db-read-2 0.20 2 52
201 1775067753 2083908 db-read-3 0.10 1 55
202 1775067753 2083909 db-read-4 0.20 2 66
203 1775067753 2083910 db-write 0.10 1 1
204 1775067753 2083911 event-worker 0.00 0 1
205 1775067763 2083904 lws-main 100.10 1001 39764
206 1775067763 2083906 db-read-1 0.00 0 57
207 1775067763 2083907 db-read-2 0.00 0 52
208 1775067763 2083908 db-read-3 0.00 0 55
209 1775067763 2083909 db-read-4 0.00 0 66
210 1775067763 2083910 db-write 0.00 0 1
211 1775067763 2083911 event-worker 0.00 0 1
@@ -0,0 +1,14 @@
==========================================
Thread CPU Summary (avg + max over run)
==========================================
Run timestamp (UTC): 20260401_181751
Duration: 300s, Interval: 10s
2083904 lws-main 73.51 100.40
2083906 db-read-1 0.08 0.60
2083907 db-read-2 0.08 0.40
2083908 db-read-3 0.08 0.40
2083909 db-read-4 0.08 0.60
2083910 db-write 0.00 0.10
2083911 event-worker 0.00 0.10
TID THREAD AVG_CPU% MAX_CPU%
Binary file not shown.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,5 @@
Profiling PID: 2083904
CLK_TCK=100
Starting perf record in background...
perf_pid=2094527
Done. Artifacts in /tmp/c_relay_thread_profile_20260401_183846
@@ -0,0 +1,211 @@
timestamp,tid,thread_name,cpu_pct,delta_ticks,total_ticks
1775068727,2083904,lws-main,0.20,2,102303
1775068727,2083906,db-read-1,0.00,0,153
1775068727,2083907,db-read-2,0.00,0,145
1775068727,2083908,db-read-3,0.00,0,145
1775068727,2083909,db-read-4,0.00,0,160
1775068727,2083910,db-write,0.00,0,4
1775068727,2083911,event-worker,0.00,0,11
1775068737,2083904,lws-main,100.20,1002,103305
1775068737,2083906,db-read-1,0.00,0,153
1775068737,2083907,db-read-2,0.10,1,146
1775068737,2083908,db-read-3,0.00,0,145
1775068737,2083909,db-read-4,0.00,0,160
1775068737,2083910,db-write,0.00,0,4
1775068737,2083911,event-worker,0.00,0,11
1775068747,2083904,lws-main,100.30,1003,104308
1775068747,2083906,db-read-1,0.00,0,153
1775068747,2083907,db-read-2,0.00,0,146
1775068747,2083908,db-read-3,0.10,1,146
1775068747,2083909,db-read-4,0.10,1,161
1775068747,2083910,db-write,0.00,0,4
1775068747,2083911,event-worker,0.00,0,11
1775068757,2083904,lws-main,100.20,1002,105310
1775068757,2083906,db-read-1,0.00,0,153
1775068757,2083907,db-read-2,0.00,0,146
1775068757,2083908,db-read-3,0.00,0,146
1775068757,2083909,db-read-4,0.00,0,161
1775068757,2083910,db-write,0.00,0,4
1775068757,2083911,event-worker,0.00,0,11
1775068767,2083904,lws-main,100.20,1002,106312
1775068767,2083906,db-read-1,0.00,0,153
1775068767,2083907,db-read-2,0.00,0,146
1775068767,2083908,db-read-3,0.00,0,146
1775068767,2083909,db-read-4,0.00,0,161
1775068767,2083910,db-write,0.00,0,4
1775068767,2083911,event-worker,0.00,0,11
1775068777,2083904,lws-main,81.10,811,107123
1775068777,2083906,db-read-1,0.00,0,153
1775068777,2083907,db-read-2,0.00,0,146
1775068777,2083908,db-read-3,0.10,1,147
1775068777,2083909,db-read-4,0.00,0,161
1775068777,2083910,db-write,0.00,0,4
1775068777,2083911,event-worker,0.00,0,11
1775068787,2083904,lws-main,7.40,74,107197
1775068787,2083906,db-read-1,0.00,0,153
1775068787,2083907,db-read-2,0.00,0,146
1775068787,2083908,db-read-3,0.00,0,147
1775068787,2083909,db-read-4,0.00,0,161
1775068787,2083910,db-write,0.00,0,4
1775068787,2083911,event-worker,0.00,0,11
1775068797,2083904,lws-main,50.30,503,107700
1775068797,2083906,db-read-1,0.30,3,156
1775068797,2083907,db-read-2,0.30,3,149
1775068797,2083908,db-read-3,0.30,3,150
1775068797,2083909,db-read-4,0.20,2,163
1775068797,2083910,db-write,0.00,0,4
1775068797,2083911,event-worker,0.00,0,11
1775068807,2083904,lws-main,58.00,580,108280
1775068807,2083906,db-read-1,0.00,0,156
1775068807,2083907,db-read-2,0.00,0,149
1775068807,2083908,db-read-3,0.00,0,150
1775068807,2083909,db-read-4,0.00,0,163
1775068807,2083910,db-write,0.00,0,4
1775068807,2083911,event-worker,0.00,0,11
1775068818,2083904,lws-main,58.40,584,108864
1775068818,2083906,db-read-1,0.10,1,157
1775068818,2083907,db-read-2,0.10,1,150
1775068818,2083908,db-read-3,0.10,1,151
1775068818,2083909,db-read-4,0.30,3,166
1775068818,2083910,db-write,0.00,0,4
1775068818,2083911,event-worker,0.00,0,11
1775068828,2083904,lws-main,43.30,433,109297
1775068828,2083906,db-read-1,0.00,0,157
1775068828,2083907,db-read-2,0.00,0,150
1775068828,2083908,db-read-3,0.00,0,151
1775068828,2083909,db-read-4,0.20,2,168
1775068828,2083910,db-write,0.00,0,4
1775068828,2083911,event-worker,0.20,2,13
1775068838,2083904,lws-main,29.00,290,109587
1775068838,2083906,db-read-1,0.20,2,159
1775068838,2083907,db-read-2,0.00,0,150
1775068838,2083908,db-read-3,0.10,1,152
1775068838,2083909,db-read-4,0.00,0,168
1775068838,2083910,db-write,0.00,0,4
1775068838,2083911,event-worker,0.00,0,13
1775068848,2083904,lws-main,37.00,370,109957
1775068848,2083906,db-read-1,0.00,0,159
1775068848,2083907,db-read-2,0.10,1,151
1775068848,2083908,db-read-3,0.00,0,152
1775068848,2083909,db-read-4,0.00,0,168
1775068848,2083910,db-write,0.00,0,4
1775068848,2083911,event-worker,0.00,0,13
1775068858,2083904,lws-main,48.40,484,110441
1775068858,2083906,db-read-1,0.10,1,160
1775068858,2083907,db-read-2,0.10,1,152
1775068858,2083908,db-read-3,0.10,1,153
1775068858,2083909,db-read-4,0.20,2,170
1775068858,2083910,db-write,0.00,0,4
1775068858,2083911,event-worker,0.00,0,13
1775068868,2083904,lws-main,45.00,450,110891
1775068868,2083906,db-read-1,0.00,0,160
1775068868,2083907,db-read-2,0.10,1,153
1775068868,2083908,db-read-3,0.00,0,153
1775068868,2083909,db-read-4,0.00,0,170
1775068868,2083910,db-write,0.00,0,4
1775068868,2083911,event-worker,0.00,0,13
1775068878,2083904,lws-main,21.00,210,111101
1775068878,2083906,db-read-1,0.00,0,160
1775068878,2083907,db-read-2,0.00,0,153
1775068878,2083908,db-read-3,0.00,0,153
1775068878,2083909,db-read-4,0.00,0,170
1775068878,2083910,db-write,0.00,0,4
1775068878,2083911,event-worker,0.00,0,13
1775068888,2083904,lws-main,36.40,364,111465
1775068888,2083906,db-read-1,0.00,0,160
1775068888,2083907,db-read-2,0.30,3,156
1775068888,2083908,db-read-3,0.10,1,154
1775068888,2083909,db-read-4,0.00,0,170
1775068888,2083910,db-write,0.00,0,4
1775068888,2083911,event-worker,0.00,0,13
1775068898,2083904,lws-main,44.10,441,111906
1775068898,2083906,db-read-1,0.00,0,160
1775068898,2083907,db-read-2,0.00,0,156
1775068898,2083908,db-read-3,0.00,0,154
1775068898,2083909,db-read-4,0.00,0,170
1775068898,2083910,db-write,0.00,0,4
1775068898,2083911,event-worker,0.00,0,13
1775068908,2083904,lws-main,19.70,197,112103
1775068908,2083906,db-read-1,0.20,2,162
1775068908,2083907,db-read-2,0.10,1,157
1775068908,2083908,db-read-3,0.00,0,154
1775068908,2083909,db-read-4,0.10,1,171
1775068908,2083910,db-write,0.00,0,4
1775068908,2083911,event-worker,0.00,0,13
1775068918,2083904,lws-main,83.20,832,112935
1775068918,2083906,db-read-1,0.30,3,165
1775068918,2083907,db-read-2,0.30,3,160
1775068918,2083908,db-read-3,0.20,2,156
1775068918,2083909,db-read-4,0.20,2,173
1775068918,2083910,db-write,0.00,0,4
1775068918,2083911,event-worker,0.00,0,13
1775068928,2083904,lws-main,37.40,374,113309
1775068928,2083906,db-read-1,0.00,0,165
1775068928,2083907,db-read-2,0.00,0,160
1775068928,2083908,db-read-3,0.10,1,157
1775068928,2083909,db-read-4,0.00,0,173
1775068928,2083910,db-write,0.00,0,4
1775068928,2083911,event-worker,0.00,0,13
1775068938,2083904,lws-main,59.80,598,113907
1775068938,2083906,db-read-1,0.00,0,165
1775068938,2083907,db-read-2,0.00,0,160
1775068938,2083908,db-read-3,0.10,1,158
1775068938,2083909,db-read-4,0.00,0,173
1775068938,2083910,db-write,0.00,0,4
1775068938,2083911,event-worker,0.00,0,13
1775068948,2083904,lws-main,61.20,612,114519
1775068948,2083906,db-read-1,0.30,3,168
1775068948,2083907,db-read-2,0.20,2,162
1775068948,2083908,db-read-3,0.10,1,159
1775068948,2083909,db-read-4,0.40,4,177
1775068948,2083910,db-write,0.00,0,4
1775068948,2083911,event-worker,0.10,1,14
1775068958,2083904,lws-main,65.30,653,115172
1775068958,2083906,db-read-1,0.00,0,168
1775068958,2083907,db-read-2,0.10,1,163
1775068958,2083908,db-read-3,0.10,1,160
1775068958,2083909,db-read-4,0.20,2,179
1775068958,2083910,db-write,0.00,0,4
1775068958,2083911,event-worker,0.00,0,14
1775068968,2083904,lws-main,23.00,230,115402
1775068968,2083906,db-read-1,0.00,0,168
1775068968,2083907,db-read-2,0.00,0,163
1775068968,2083908,db-read-3,0.00,0,160
1775068968,2083909,db-read-4,0.00,0,179
1775068968,2083910,db-write,0.00,0,4
1775068968,2083911,event-worker,0.00,0,14
1775068978,2083904,lws-main,79.80,798,116200
1775068978,2083906,db-read-1,0.40,4,172
1775068978,2083907,db-read-2,0.10,1,164
1775068978,2083908,db-read-3,0.10,1,161
1775068978,2083909,db-read-4,0.20,2,181
1775068978,2083910,db-write,0.00,0,4
1775068978,2083911,event-worker,0.00,0,14
1775068988,2083904,lws-main,70.70,707,116907
1775068988,2083906,db-read-1,0.00,0,172
1775068988,2083907,db-read-2,0.00,0,164
1775068988,2083908,db-read-3,0.10,1,162
1775068988,2083909,db-read-4,0.00,0,181
1775068988,2083910,db-write,0.00,0,4
1775068988,2083911,event-worker,0.00,0,14
1775068998,2083904,lws-main,23.00,230,117137
1775068998,2083906,db-read-1,0.00,0,172
1775068998,2083907,db-read-2,0.00,0,164
1775068998,2083908,db-read-3,0.00,0,162
1775068998,2083909,db-read-4,0.00,0,181
1775068998,2083910,db-write,0.00,0,4
1775068998,2083911,event-worker,0.00,0,14
1775069008,2083904,lws-main,66.00,660,117797
1775069008,2083906,db-read-1,0.30,3,175
1775069008,2083907,db-read-2,0.40,4,168
1775069008,2083908,db-read-3,0.40,4,166
1775069008,2083909,db-read-4,0.30,3,184
1775069008,2083910,db-write,0.00,0,4
1775069008,2083911,event-worker,0.00,0,14
1775069018,2083904,lws-main,80.00,800,118597
1775069018,2083906,db-read-1,0.00,0,175
1775069018,2083907,db-read-2,0.00,0,168
1775069018,2083908,db-read-3,0.00,0,166
1775069018,2083909,db-read-4,0.00,0,184
1775069018,2083910,db-write,0.00,0,4
1775069018,2083911,event-worker,0.00,0,14
1 timestamp tid thread_name cpu_pct delta_ticks total_ticks
2 1775068727 2083904 lws-main 0.20 2 102303
3 1775068727 2083906 db-read-1 0.00 0 153
4 1775068727 2083907 db-read-2 0.00 0 145
5 1775068727 2083908 db-read-3 0.00 0 145
6 1775068727 2083909 db-read-4 0.00 0 160
7 1775068727 2083910 db-write 0.00 0 4
8 1775068727 2083911 event-worker 0.00 0 11
9 1775068737 2083904 lws-main 100.20 1002 103305
10 1775068737 2083906 db-read-1 0.00 0 153
11 1775068737 2083907 db-read-2 0.10 1 146
12 1775068737 2083908 db-read-3 0.00 0 145
13 1775068737 2083909 db-read-4 0.00 0 160
14 1775068737 2083910 db-write 0.00 0 4
15 1775068737 2083911 event-worker 0.00 0 11
16 1775068747 2083904 lws-main 100.30 1003 104308
17 1775068747 2083906 db-read-1 0.00 0 153
18 1775068747 2083907 db-read-2 0.00 0 146
19 1775068747 2083908 db-read-3 0.10 1 146
20 1775068747 2083909 db-read-4 0.10 1 161
21 1775068747 2083910 db-write 0.00 0 4
22 1775068747 2083911 event-worker 0.00 0 11
23 1775068757 2083904 lws-main 100.20 1002 105310
24 1775068757 2083906 db-read-1 0.00 0 153
25 1775068757 2083907 db-read-2 0.00 0 146
26 1775068757 2083908 db-read-3 0.00 0 146
27 1775068757 2083909 db-read-4 0.00 0 161
28 1775068757 2083910 db-write 0.00 0 4
29 1775068757 2083911 event-worker 0.00 0 11
30 1775068767 2083904 lws-main 100.20 1002 106312
31 1775068767 2083906 db-read-1 0.00 0 153
32 1775068767 2083907 db-read-2 0.00 0 146
33 1775068767 2083908 db-read-3 0.00 0 146
34 1775068767 2083909 db-read-4 0.00 0 161
35 1775068767 2083910 db-write 0.00 0 4
36 1775068767 2083911 event-worker 0.00 0 11
37 1775068777 2083904 lws-main 81.10 811 107123
38 1775068777 2083906 db-read-1 0.00 0 153
39 1775068777 2083907 db-read-2 0.00 0 146
40 1775068777 2083908 db-read-3 0.10 1 147
41 1775068777 2083909 db-read-4 0.00 0 161
42 1775068777 2083910 db-write 0.00 0 4
43 1775068777 2083911 event-worker 0.00 0 11
44 1775068787 2083904 lws-main 7.40 74 107197
45 1775068787 2083906 db-read-1 0.00 0 153
46 1775068787 2083907 db-read-2 0.00 0 146
47 1775068787 2083908 db-read-3 0.00 0 147
48 1775068787 2083909 db-read-4 0.00 0 161
49 1775068787 2083910 db-write 0.00 0 4
50 1775068787 2083911 event-worker 0.00 0 11
51 1775068797 2083904 lws-main 50.30 503 107700
52 1775068797 2083906 db-read-1 0.30 3 156
53 1775068797 2083907 db-read-2 0.30 3 149
54 1775068797 2083908 db-read-3 0.30 3 150
55 1775068797 2083909 db-read-4 0.20 2 163
56 1775068797 2083910 db-write 0.00 0 4
57 1775068797 2083911 event-worker 0.00 0 11
58 1775068807 2083904 lws-main 58.00 580 108280
59 1775068807 2083906 db-read-1 0.00 0 156
60 1775068807 2083907 db-read-2 0.00 0 149
61 1775068807 2083908 db-read-3 0.00 0 150
62 1775068807 2083909 db-read-4 0.00 0 163
63 1775068807 2083910 db-write 0.00 0 4
64 1775068807 2083911 event-worker 0.00 0 11
65 1775068818 2083904 lws-main 58.40 584 108864
66 1775068818 2083906 db-read-1 0.10 1 157
67 1775068818 2083907 db-read-2 0.10 1 150
68 1775068818 2083908 db-read-3 0.10 1 151
69 1775068818 2083909 db-read-4 0.30 3 166
70 1775068818 2083910 db-write 0.00 0 4
71 1775068818 2083911 event-worker 0.00 0 11
72 1775068828 2083904 lws-main 43.30 433 109297
73 1775068828 2083906 db-read-1 0.00 0 157
74 1775068828 2083907 db-read-2 0.00 0 150
75 1775068828 2083908 db-read-3 0.00 0 151
76 1775068828 2083909 db-read-4 0.20 2 168
77 1775068828 2083910 db-write 0.00 0 4
78 1775068828 2083911 event-worker 0.20 2 13
79 1775068838 2083904 lws-main 29.00 290 109587
80 1775068838 2083906 db-read-1 0.20 2 159
81 1775068838 2083907 db-read-2 0.00 0 150
82 1775068838 2083908 db-read-3 0.10 1 152
83 1775068838 2083909 db-read-4 0.00 0 168
84 1775068838 2083910 db-write 0.00 0 4
85 1775068838 2083911 event-worker 0.00 0 13
86 1775068848 2083904 lws-main 37.00 370 109957
87 1775068848 2083906 db-read-1 0.00 0 159
88 1775068848 2083907 db-read-2 0.10 1 151
89 1775068848 2083908 db-read-3 0.00 0 152
90 1775068848 2083909 db-read-4 0.00 0 168
91 1775068848 2083910 db-write 0.00 0 4
92 1775068848 2083911 event-worker 0.00 0 13
93 1775068858 2083904 lws-main 48.40 484 110441
94 1775068858 2083906 db-read-1 0.10 1 160
95 1775068858 2083907 db-read-2 0.10 1 152
96 1775068858 2083908 db-read-3 0.10 1 153
97 1775068858 2083909 db-read-4 0.20 2 170
98 1775068858 2083910 db-write 0.00 0 4
99 1775068858 2083911 event-worker 0.00 0 13
100 1775068868 2083904 lws-main 45.00 450 110891
101 1775068868 2083906 db-read-1 0.00 0 160
102 1775068868 2083907 db-read-2 0.10 1 153
103 1775068868 2083908 db-read-3 0.00 0 153
104 1775068868 2083909 db-read-4 0.00 0 170
105 1775068868 2083910 db-write 0.00 0 4
106 1775068868 2083911 event-worker 0.00 0 13
107 1775068878 2083904 lws-main 21.00 210 111101
108 1775068878 2083906 db-read-1 0.00 0 160
109 1775068878 2083907 db-read-2 0.00 0 153
110 1775068878 2083908 db-read-3 0.00 0 153
111 1775068878 2083909 db-read-4 0.00 0 170
112 1775068878 2083910 db-write 0.00 0 4
113 1775068878 2083911 event-worker 0.00 0 13
114 1775068888 2083904 lws-main 36.40 364 111465
115 1775068888 2083906 db-read-1 0.00 0 160
116 1775068888 2083907 db-read-2 0.30 3 156
117 1775068888 2083908 db-read-3 0.10 1 154
118 1775068888 2083909 db-read-4 0.00 0 170
119 1775068888 2083910 db-write 0.00 0 4
120 1775068888 2083911 event-worker 0.00 0 13
121 1775068898 2083904 lws-main 44.10 441 111906
122 1775068898 2083906 db-read-1 0.00 0 160
123 1775068898 2083907 db-read-2 0.00 0 156
124 1775068898 2083908 db-read-3 0.00 0 154
125 1775068898 2083909 db-read-4 0.00 0 170
126 1775068898 2083910 db-write 0.00 0 4
127 1775068898 2083911 event-worker 0.00 0 13
128 1775068908 2083904 lws-main 19.70 197 112103
129 1775068908 2083906 db-read-1 0.20 2 162
130 1775068908 2083907 db-read-2 0.10 1 157
131 1775068908 2083908 db-read-3 0.00 0 154
132 1775068908 2083909 db-read-4 0.10 1 171
133 1775068908 2083910 db-write 0.00 0 4
134 1775068908 2083911 event-worker 0.00 0 13
135 1775068918 2083904 lws-main 83.20 832 112935
136 1775068918 2083906 db-read-1 0.30 3 165
137 1775068918 2083907 db-read-2 0.30 3 160
138 1775068918 2083908 db-read-3 0.20 2 156
139 1775068918 2083909 db-read-4 0.20 2 173
140 1775068918 2083910 db-write 0.00 0 4
141 1775068918 2083911 event-worker 0.00 0 13
142 1775068928 2083904 lws-main 37.40 374 113309
143 1775068928 2083906 db-read-1 0.00 0 165
144 1775068928 2083907 db-read-2 0.00 0 160
145 1775068928 2083908 db-read-3 0.10 1 157
146 1775068928 2083909 db-read-4 0.00 0 173
147 1775068928 2083910 db-write 0.00 0 4
148 1775068928 2083911 event-worker 0.00 0 13
149 1775068938 2083904 lws-main 59.80 598 113907
150 1775068938 2083906 db-read-1 0.00 0 165
151 1775068938 2083907 db-read-2 0.00 0 160
152 1775068938 2083908 db-read-3 0.10 1 158
153 1775068938 2083909 db-read-4 0.00 0 173
154 1775068938 2083910 db-write 0.00 0 4
155 1775068938 2083911 event-worker 0.00 0 13
156 1775068948 2083904 lws-main 61.20 612 114519
157 1775068948 2083906 db-read-1 0.30 3 168
158 1775068948 2083907 db-read-2 0.20 2 162
159 1775068948 2083908 db-read-3 0.10 1 159
160 1775068948 2083909 db-read-4 0.40 4 177
161 1775068948 2083910 db-write 0.00 0 4
162 1775068948 2083911 event-worker 0.10 1 14
163 1775068958 2083904 lws-main 65.30 653 115172
164 1775068958 2083906 db-read-1 0.00 0 168
165 1775068958 2083907 db-read-2 0.10 1 163
166 1775068958 2083908 db-read-3 0.10 1 160
167 1775068958 2083909 db-read-4 0.20 2 179
168 1775068958 2083910 db-write 0.00 0 4
169 1775068958 2083911 event-worker 0.00 0 14
170 1775068968 2083904 lws-main 23.00 230 115402
171 1775068968 2083906 db-read-1 0.00 0 168
172 1775068968 2083907 db-read-2 0.00 0 163
173 1775068968 2083908 db-read-3 0.00 0 160
174 1775068968 2083909 db-read-4 0.00 0 179
175 1775068968 2083910 db-write 0.00 0 4
176 1775068968 2083911 event-worker 0.00 0 14
177 1775068978 2083904 lws-main 79.80 798 116200
178 1775068978 2083906 db-read-1 0.40 4 172
179 1775068978 2083907 db-read-2 0.10 1 164
180 1775068978 2083908 db-read-3 0.10 1 161
181 1775068978 2083909 db-read-4 0.20 2 181
182 1775068978 2083910 db-write 0.00 0 4
183 1775068978 2083911 event-worker 0.00 0 14
184 1775068988 2083904 lws-main 70.70 707 116907
185 1775068988 2083906 db-read-1 0.00 0 172
186 1775068988 2083907 db-read-2 0.00 0 164
187 1775068988 2083908 db-read-3 0.10 1 162
188 1775068988 2083909 db-read-4 0.00 0 181
189 1775068988 2083910 db-write 0.00 0 4
190 1775068988 2083911 event-worker 0.00 0 14
191 1775068998 2083904 lws-main 23.00 230 117137
192 1775068998 2083906 db-read-1 0.00 0 172
193 1775068998 2083907 db-read-2 0.00 0 164
194 1775068998 2083908 db-read-3 0.00 0 162
195 1775068998 2083909 db-read-4 0.00 0 181
196 1775068998 2083910 db-write 0.00 0 4
197 1775068998 2083911 event-worker 0.00 0 14
198 1775069008 2083904 lws-main 66.00 660 117797
199 1775069008 2083906 db-read-1 0.30 3 175
200 1775069008 2083907 db-read-2 0.40 4 168
201 1775069008 2083908 db-read-3 0.40 4 166
202 1775069008 2083909 db-read-4 0.30 3 184
203 1775069008 2083910 db-write 0.00 0 4
204 1775069008 2083911 event-worker 0.00 0 14
205 1775069018 2083904 lws-main 80.00 800 118597
206 1775069018 2083906 db-read-1 0.00 0 175
207 1775069018 2083907 db-read-2 0.00 0 168
208 1775069018 2083908 db-read-3 0.00 0 166
209 1775069018 2083909 db-read-4 0.00 0 184
210 1775069018 2083910 db-write 0.00 0 4
211 1775069018 2083911 event-worker 0.00 0 14
@@ -0,0 +1,14 @@
==========================================
Thread CPU Summary (avg + max over run)
==========================================
Run timestamp (UTC): 20260401_183846
Duration: 300s, Interval: 10s
2083904 lws-main 54.32 100.30
2083907 db-read-2 0.08 0.40
2083909 db-read-4 0.08 0.40
2083906 db-read-1 0.07 0.40
2083908 db-read-3 0.07 0.40
2083911 event-worker 0.01 0.20
2083910 db-write 0.00 0.00
TID THREAD AVG_CPU% MAX_CPU%