// Subscription system structures and functions for C-Relay // This header defines subscription management functionality #ifndef SUBSCRIPTIONS_H #define SUBSCRIPTIONS_H #include #include #include #include "../nostr_core_lib/cjson/cJSON.h" #include "config.h" // For CLIENT_IP_MAX_LENGTH // Forward declaration for libwebsockets struct struct lws; // Constants #define SUBSCRIPTION_ID_MAX_LENGTH 64 #define MAX_FILTERS_PER_SUBSCRIPTION 10 #define MAX_TOTAL_SUBSCRIPTIONS 5000 // Forward declarations for typedefs typedef struct subscription_filter subscription_filter_t; typedef struct subscription subscription_t; typedef struct subscription_manager subscription_manager_t; // Subscription filter structure struct subscription_filter { // Filter criteria (all optional) cJSON* kinds; // Array of event kinds [1,2,3] cJSON* authors; // Array of author pubkeys cJSON* ids; // Array of event IDs long since; // Unix timestamp (0 = not set) long until; // Unix timestamp (0 = not set) int limit; // Result limit (0 = no limit) cJSON* tag_filters; // Object with tag filters: {"#e": ["id1"], "#p": ["pubkey1"]} // Linked list for multiple filters per subscription struct subscription_filter* next; }; // Active subscription structure struct subscription { char id[SUBSCRIPTION_ID_MAX_LENGTH]; // Subscription ID struct lws* wsi; // WebSocket connection handle subscription_filter_t* filters; // Linked list of filters (OR'd together) time_t created_at; // When subscription was created int events_sent; // Counter for sent events int active; // 1 = active, 0 = closed // Client info for logging char client_ip[CLIENT_IP_MAX_LENGTH]; // Client IP address // Linked list pointers struct subscription* next; // Next subscription globally struct subscription* session_next; // Next subscription for this session }; // Global subscription manager struct subscription_manager { subscription_t* active_subscriptions; // Head of global subscription list pthread_mutex_t subscriptions_lock; // Global thread safety int total_subscriptions; // Current count // Configuration int max_subscriptions_per_client; // Default: 20 int max_total_subscriptions; // Default: 5000 // Statistics uint64_t total_created; // Lifetime subscription count uint64_t total_events_broadcast; // Lifetime event broadcast count }; // Function declarations subscription_filter_t* create_subscription_filter(cJSON* filter_json); void free_subscription_filter(subscription_filter_t* filter); subscription_t* create_subscription(const char* sub_id, struct lws* wsi, cJSON* filters_array, const char* client_ip); void free_subscription(subscription_t* sub); int add_subscription_to_manager(subscription_t* sub); int remove_subscription_from_manager(const char* sub_id, struct lws* wsi); int event_matches_filter(cJSON* event, subscription_filter_t* filter); int event_matches_subscription(cJSON* event, subscription_t* subscription); int broadcast_event_to_subscriptions(cJSON* event); // Database logging functions void log_subscription_created(const subscription_t* sub); void log_subscription_closed(const char* sub_id, const char* client_ip, const char* reason); void log_subscription_disconnected(const char* client_ip); void log_event_broadcast(const char* event_id, const char* sub_id, const char* client_ip); void update_subscription_events_sent(const char* sub_id, int events_sent); #endif // SUBSCRIPTIONS_H