v1.2.17 - Add nip42_auth_timeout_sec (default 10s): close unauthenticated connections after timeout to prevent connection accumulation

This commit is contained in:
Your Name
2026-02-23 15:22:18 -04:00
parent 0de491382e
commit 361912ec85
4 changed files with 47 additions and 2 deletions
+9
View File
@@ -952,6 +952,15 @@ static int validate_config_field(const char* key, const char* value, char* error
return 0;
}
// NIP-42 auth timeout
if (strcmp(key, "nip42_auth_timeout_sec") == 0) {
if (!is_valid_positive_integer(value) && strcmp(value, "0") != 0) {
snprintf(error_msg, error_size, "invalid nip42_auth_timeout_sec '%s' (must be non-negative integer)", value);
return -1;
}
return 0;
}
// SQLite performance tuning
if (strcmp(key, "sqlite_mmap_size") == 0) {
if (!is_valid_positive_integer(value) && strcmp(value, "0") != 0) {
+5
View File
@@ -83,6 +83,11 @@ static const struct {
// IP-based rate limiting or access control (which would require firewall protection anyway)
{"trust_proxy_headers", "true"},
// NIP-42 Authentication Timeout
// Seconds after connection before unauthenticated clients are disconnected (0 = disabled)
// Prevents unauthenticated connections from accumulating under heavy load
{"nip42_auth_timeout_sec", "10"},
// SQLite Performance Tuning
// mmap_size: bytes of database file to memory-map (0 = disabled, 268435456 = 256MB recommended)
// Eliminates pread64 syscall overhead for database reads — significant CPU savings under load
+2 -2
View File
@@ -13,8 +13,8 @@
// Using CRELAY_ prefix to avoid conflicts with nostr_core_lib VERSION macros
#define CRELAY_VERSION_MAJOR 1
#define CRELAY_VERSION_MINOR 2
#define CRELAY_VERSION_PATCH 16
#define CRELAY_VERSION "v1.2.16"
#define CRELAY_VERSION_PATCH 17
#define CRELAY_VERSION "v1.2.17"
// Relay metadata (authoritative source for NIP-11 information)
#define RELAY_NAME "C-Relay"
+31
View File
@@ -1011,6 +1011,21 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
} else {
send_notice_message(wsi, pss, "NIP-42 authentication required for subscriptions");
DEBUG_WARN("REQ rejected: NIP-42 authentication required");
// 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);
if (auth_timeout > 0 && pss->connection_established > 0) {
time_t connection_age = time(NULL) - pss->connection_established;
if (connection_age >= auth_timeout) {
DEBUG_LOG("Closing unauthenticated connection from %s after %ld seconds (timeout=%d)",
pss->client_ip, connection_age, auth_timeout);
lws_close_reason(wsi, LWS_CLOSE_STATUS_POLICY_VIOLATION,
(unsigned char*)"Authentication timeout", 22);
cJSON_Delete(json);
return -1;
}
}
}
cJSON_Delete(json);
// Note: complete_message points to reassembly_buffer, which is managed separately
@@ -1768,6 +1783,22 @@ static int nostr_relay_callback(struct lws *wsi, enum lws_callback_reasons reaso
} else {
send_notice_message(wsi, pss, "NIP-42 authentication required for subscriptions");
DEBUG_WARN("REQ rejected: NIP-42 authentication required");
// 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);
if (auth_timeout > 0 && pss->connection_established > 0) {
time_t connection_age = time(NULL) - pss->connection_established;
if (connection_age >= auth_timeout) {
DEBUG_LOG("Closing unauthenticated connection from %s after %ld seconds (timeout=%d)",
pss->client_ip, connection_age, auth_timeout);
lws_close_reason(wsi, LWS_CLOSE_STATUS_POLICY_VIOLATION,
(unsigned char*)"Authentication timeout", 22);
cJSON_Delete(json);
free(message);
return -1;
}
}
}
cJSON_Delete(json);
free(message);