// WebSocket protocol structures and constants for C-Relay // This header defines structures shared between main.c and websockets.c #ifndef WEBSOCKETS_H #define WEBSOCKETS_H #include #include #include #include "../nostr_core_lib/cjson/cJSON.h" #include "config.h" // For CLIENT_IP_MAX_LENGTH and MAX_SUBSCRIPTIONS_PER_CLIENT // Constants #define CHALLENGE_MAX_LENGTH 128 #define AUTHENTICATED_PUBKEY_MAX_LENGTH 65 // 64 hex + null // Rate limiting constants for malformed requests #define MAX_MALFORMED_REQUESTS_PER_HOUR 10 #define MALFORMED_REQUEST_BLOCK_DURATION 3600 // 1 hour in seconds #define RATE_LIMIT_CLEANUP_INTERVAL 300 // 5 minutes // Filter validation constants #define MAX_FILTERS_PER_REQUEST 10 #define MAX_AUTHORS_PER_FILTER 1000 #define MAX_IDS_PER_FILTER 1000 #define MAX_KINDS_PER_FILTER 500 #define MAX_TAG_VALUES_PER_FILTER 1000 #define MAX_KIND_VALUE 65535 #define MAX_TIMESTAMP_VALUE 2147483647 // Max 32-bit signed int #define MAX_LIMIT_VALUE 5000 #define MAX_SEARCH_LENGTH 256 #define MAX_TAG_VALUE_LENGTH 1024 // Message queue node for proper libwebsockets pattern struct message_queue_node { unsigned char* data; // Message data (with LWS_PRE space) size_t length; // Message length (without LWS_PRE) enum lws_write_protocol type; // LWS_WRITE_TEXT, etc. struct message_queue_node* next; // Next node in queue }; // Enhanced per-session data with subscription management, NIP-42 authentication, and rate limiting struct per_session_data { int authenticated; struct subscription* subscriptions; // Head of this session's subscription list pthread_mutex_t session_lock; // Per-session thread safety char client_ip[CLIENT_IP_MAX_LENGTH]; // Client IP for logging int subscription_count; // Number of subscriptions for this session time_t connection_established; // When WebSocket connection was established // NIP-42 Authentication State char authenticated_pubkey[65]; // Authenticated public key (64 hex + null) char active_challenge[65]; // Current challenge for this session (64 hex + null) time_t challenge_created; // When challenge was created time_t challenge_expires; // Challenge expiration time int nip42_auth_required_events; // Whether NIP-42 auth is required for EVENT submission int nip42_auth_required_subscriptions; // Whether NIP-42 auth is required for REQ operations int auth_challenge_sent; // Whether challenge has been sent (0/1) // Rate limiting for subscription attempts int failed_subscription_attempts; // Count of failed subscription attempts time_t last_failed_attempt; // Timestamp of last failed attempt time_t rate_limit_until; // Time until rate limiting expires int consecutive_failures; // Consecutive failed attempts for backoff // Rate limiting for malformed requests int malformed_request_count; // Count of malformed requests in current hour time_t malformed_request_window_start; // Start of current hour window time_t malformed_request_blocked_until; // Time until blocked for malformed requests // Message queue for proper libwebsockets pattern (replaces single buffer) struct message_queue_node* message_queue_head; // Head of message queue struct message_queue_node* message_queue_tail; // Tail of message queue int message_queue_count; // Number of messages in queue int writeable_requested; // Flag: 1 if writeable callback requested // Message reassembly for handling fragmented WebSocket messages char* reassembly_buffer; // Buffer for accumulating message fragments (NULL when not reassembling) size_t reassembly_size; // Current size of accumulated data size_t reassembly_capacity; // Allocated capacity of reassembly buffer int reassembly_active; // Flag: 1 if currently reassembling a message }; // NIP-11 HTTP session data structure for managing buffer lifetime struct nip11_session_data { int type; // 0 for NIP-11 char* json_buffer; size_t json_length; int headers_sent; int body_sent; }; // Function declarations int start_websocket_relay(int port_override, int strict_port); // Message queue functions for proper libwebsockets pattern int queue_message(struct lws* wsi, struct per_session_data* pss, const char* message, size_t length, enum lws_write_protocol type); int process_message_queue(struct lws* wsi, struct per_session_data* pss); // Auth rules checking function from request_validator.c int check_database_auth_rules(const char *pubkey, const char *operation, const char *resource_hash); #endif // WEBSOCKETS_H