/* * Copyright (c) 2013-2022 Joris Vink * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __H_KORE_H #define __H_KORE_H #if defined(__APPLE__) #define daemon portability_is_king #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__cplusplus) extern "C" { #endif #if defined(__APPLE__) #undef daemon extern int daemon(int, int); #define st_mtim st_mtimespec #endif #if !defined(KORE_NO_SENDFILE) #if defined(__MACH__) || defined(__FreeBSD_version) || defined(__linux__) #define KORE_USE_PLATFORM_SENDFILE 1 #endif #endif #if defined(__OpenBSD__) #define KORE_USE_PLATFORM_PLEDGE 1 #endif #if defined(TLS_BACKEND_OPENSSL) #include #include typedef X509 KORE_X509; typedef SSL KORE_TLS; typedef SSL_CTX KORE_TLS_CTX; typedef X509_NAME KORE_X509_NAMES; typedef EVP_PKEY KORE_PRIVATE_KEY; #else typedef void KORE_X509; typedef void KORE_TLS; typedef void KORE_TLS_CTX; typedef void KORE_X509_NAMES; typedef void KORE_PRIVATE_KEY; #endif #define KORE_RSAKEY_BITS 4096 /* Kore quit reasons. */ #define KORE_QUIT_NONE -1 #define KORE_QUIT_NORMAL 0 #define KORE_QUIT_FATAL 1 #define KORE_RESULT_ERROR 0 #define KORE_RESULT_OK 1 #define KORE_RESULT_RETRY 2 #define KORE_TLS_VERSION_1_3 0 #define KORE_TLS_VERSION_1_2 1 #define KORE_TLS_VERSION_BOTH 2 #define KORE_BASE64_RAW 0x0001 #define KORE_WAIT_INFINITE (u_int64_t)-1 #define KORE_RESEED_TIME (1800 * 1000) #define errno_s strerror(errno) #define ssl_errno_s ERR_error_string(ERR_get_error(), NULL) #define KORE_DOMAINNAME_LEN 255 #define KORE_PIDFILE_DEFAULT "kore.pid" #define KORE_DHPARAM_PATH PREFIX "/share/kore/ffdhe4096.pem" #define KORE_DEFAULT_CIPHER_LIST "AEAD-AES256-GCM-SHA384:AEAD-CHACHA20-POLY1305-SHA256:AEAD-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256" #define NETBUF_RECV 0 #define NETBUF_SEND 1 #define NETBUF_SEND_PAYLOAD_MAX 8192 #define SENDFILE_PAYLOAD_MAX (1024 * 1024 * 10) #define NETBUF_LAST_CHAIN 0 #define NETBUF_BEFORE_CHAIN 1 #define NETBUF_CALL_CB_ALWAYS 0x01 #define NETBUF_FORCE_REMOVE 0x02 #define NETBUF_MUST_RESEND 0x04 #define NETBUF_IS_STREAM 0x10 #define NETBUF_IS_FILEREF 0x20 #define KORE_X509_COMMON_NAME_ONLY 0x0001 #define KORE_PEM_CERT_CHAIN 1 #define KORE_DER_CERT_DATA 2 /* XXX hackish. */ #if !defined(KORE_NO_HTTP) struct http_request; struct http_redirect; #endif #define KORE_FILEREF_SOFT_REMOVED 0x1000 struct kore_fileref { int cnt; int flags; int ontls; off_t size; char *path; u_int64_t mtime; time_t mtime_sec; u_int64_t expiration; void *base; int fd; TAILQ_ENTRY(kore_fileref) list; }; struct netbuf { u_int8_t *buf; size_t s_off; size_t b_len; size_t m_len; u_int8_t type; u_int8_t flags; struct kore_fileref *file_ref; off_t fd_off; off_t fd_len; struct connection *owner; void *extra; int (*cb)(struct netbuf *); TAILQ_ENTRY(netbuf) list; }; TAILQ_HEAD(netbuf_head, netbuf); #define KORE_TYPE_LISTENER 1 #define KORE_TYPE_CONNECTION 2 #define KORE_TYPE_PGSQL_CONN 3 #define KORE_TYPE_TASK 4 #define KORE_TYPE_PYSOCKET 5 #define KORE_TYPE_CURL_HANDLE 6 #define CONN_STATE_UNKNOWN 0 #define CONN_STATE_TLS_SHAKE 1 #define CONN_STATE_ESTABLISHED 2 #define CONN_STATE_DISCONNECTING 3 #define CONN_PROTO_UNKNOWN 0 #define CONN_PROTO_HTTP 1 #define CONN_PROTO_WEBSOCKET 2 #define CONN_PROTO_MSG 3 #define CONN_PROTO_ACME_ALPN 200 #define KORE_EVENT_READ 0x01 #define KORE_EVENT_WRITE 0x02 #define KORE_EVENT_ERROR 0x04 #define CONN_IDLE_TIMER_ACT 0x0001 #define CONN_CLOSE_EMPTY 0x0002 #define CONN_WS_CLOSE_SENT 0x0004 #define CONN_IS_BUSY 0x0008 #define CONN_LOG_TLS_FAILURE 0x0020 #define CONN_TLS_ALPN_ACME_SEEN 0x0040 #define CONN_TLS_SNI_SEEN 0x0080 #define KORE_IDLE_TIMER_MAX 5000 #define WEBSOCKET_OP_CONT 0x00 #define WEBSOCKET_OP_TEXT 0x01 #define WEBSOCKET_OP_BINARY 0x02 #define WEBSOCKET_OP_CLOSE 0x08 #define WEBSOCKET_OP_PING 0x09 #define WEBSOCKET_OP_PONG 0x0a #define WEBSOCKET_BROADCAST_LOCAL 1 #define WEBSOCKET_BROADCAST_GLOBAL 2 #define KORE_TIMER_ONESHOT 0x01 #define KORE_TIMER_FLAGS (KORE_TIMER_ONESHOT) #define KORE_CONNECTION_PRUNE_DISCONNECT 0 #define KORE_CONNECTION_PRUNE_ALL 1 struct kore_event { int type; int flags; void (*handle)(void *, int); } __attribute__((packed)); struct connection { struct kore_event evt; int fd; u_int8_t state; u_int8_t proto; struct listener *owner; KORE_TLS *tls; KORE_X509 *tls_cert; char *tls_sni; int tls_reneg; u_int16_t flags; void *hdlr_extra; int (*handle)(struct connection *); void (*disconnect)(struct connection *); int (*read)(struct connection *, size_t *); int (*write)(struct connection *, size_t, size_t *); int family; union { struct sockaddr_in ipv4; struct sockaddr_in6 ipv6; struct sockaddr_un sun; } addr; struct { u_int64_t length; u_int64_t start; } idle_timer; struct netbuf_head send_queue; struct netbuf *snb; struct netbuf *rnb; #if !defined(KORE_NO_HTTP) u_int64_t http_start; u_int64_t http_timeout; struct kore_runtime_call *ws_connect; struct kore_runtime_call *ws_message; struct kore_runtime_call *ws_disconnect; TAILQ_HEAD(, http_request) http_requests; #endif TAILQ_ENTRY(connection) list; }; TAILQ_HEAD(connection_list, connection); extern struct connection_list connections; extern struct connection_list disconnected; #define KORE_RUNTIME_NATIVE 0 #define KORE_RUNTIME_PYTHON 1 #define KORE_RUNTIME_LUA 2 struct kore_runtime { int type; int (*resolve)(const char *, const struct stat *); #if !defined(KORE_NO_HTTP) int (*http_request)(void *, struct http_request *); void (*http_request_free)(void *, struct http_request *); void (*http_body_chunk)(void *, struct http_request *, const void *, size_t); int (*validator)(void *, struct http_request *, const void *); void (*wsconnect)(void *, struct connection *); void (*wsdisconnect)(void *, struct connection *); void (*wsmessage)(void *, struct connection *, u_int8_t, const void *, size_t); #endif void (*execute)(void *); int (*onload)(void *, int); void (*signal)(void *, int); void (*connect)(void *, struct connection *); void (*configure)(void *, int, char **); }; struct kore_runtime_call { void *addr; struct kore_runtime *runtime; }; #if !defined(KORE_NO_HTTP) struct kore_route_params { char *name; int flags; u_int8_t method; struct kore_validator *validator; TAILQ_ENTRY(kore_route_params) list; }; struct kore_route { char *path; char *func; int type; int errors; int methods; regex_t rctx; struct kore_domain *dom; struct kore_auth *auth; struct kore_runtime_call *rcall; struct kore_runtime_call *on_free; struct kore_runtime_call *on_headers; struct kore_runtime_call *on_body_chunk; TAILQ_HEAD(, kore_route_params) params; TAILQ_ENTRY(kore_route) list; }; #endif struct kore_domain { u_int16_t id; int logerr; u_int64_t logwarn; int accesslog; char *domain; struct kore_buf *logbuf; struct kore_server *server; #if defined(KORE_USE_ACME) int acme; int acme_challenge; void *acme_cert; size_t acme_cert_len; #endif char *cafile; char *crlfile; char *certfile; char *certkey; KORE_TLS_CTX *tls_ctx; int x509_verify_depth; #if !defined(KORE_NO_HTTP) TAILQ_HEAD(, kore_route) routes; TAILQ_HEAD(, http_redirect) redirects; #endif TAILQ_ENTRY(kore_domain) list; }; TAILQ_HEAD(kore_domain_h, kore_domain); extern struct kore_runtime kore_native_runtime; struct listener { struct kore_event evt; int fd; int family; char *port; char *host; struct kore_server *server; struct kore_runtime_call *connect; LIST_ENTRY(listener) list; }; struct kore_server { int tls; char *name; struct kore_domain_h domains; LIST_HEAD(, listener) listeners; LIST_ENTRY(kore_server) list; }; LIST_HEAD(kore_server_list, kore_server); #if !defined(KORE_NO_HTTP) #define KORE_PARAMS_QUERY_STRING 0x0001 #define KORE_AUTH_TYPE_COOKIE 1 #define KORE_AUTH_TYPE_HEADER 2 #define KORE_AUTH_TYPE_REQUEST 3 struct kore_auth { u_int8_t type; char *name; char *value; char *redirect; struct kore_validator *validator; TAILQ_ENTRY(kore_auth) list; }; #define HANDLER_TYPE_STATIC 1 #define HANDLER_TYPE_DYNAMIC 2 #endif /* !KORE_NO_HTTP */ #define KORE_MODULE_LOAD 1 #define KORE_MODULE_UNLOAD 2 #define KORE_MODULE_NATIVE KORE_RUNTIME_NATIVE #define KORE_MODULE_PYTHON KORE_RUNTIME_PYTHON #define KORE_MODULE_LUA KORE_RUNTIME_LUA struct kore_module; struct kore_module_functions { void (*free)(struct kore_module *); void (*reload)(struct kore_module *); int (*callback)(struct kore_module *, int); void (*load)(struct kore_module *); void *(*getsym)(struct kore_module *, const char *); }; struct kore_module { void *handle; char *path; char *onload; int type; struct kore_runtime_call *ocb; struct kore_module_functions *fun; struct kore_runtime *runtime; TAILQ_ENTRY(kore_module) list; }; /* * The workers get a 128KB log buffer per worker, and parent will fetch their * logs when it reached at least 75% of that or if its been > 1 second since * it was last synced. */ #define KORE_ACCESSLOG_BUFLEN 131072U #define KORE_ACCESSLOG_SYNC 98304U struct kore_alog_header { u_int16_t domain; u_int16_t loglen; } __attribute__((packed)); struct kore_privsep { char *root; char *runas; int skip_runas; int skip_chroot; }; struct kore_worker { u_int16_t id; u_int16_t cpu; int ready; int running; #if defined(__linux__) int tracing; #endif pid_t pid; int pipe[2]; struct connection *msg[2]; u_int8_t has_lock; int restarted; u_int64_t time_locked; struct kore_route *active_route; struct kore_privsep *ps; /* Used by the workers to store accesslogs. */ struct { int lock; size_t offset; char buf[KORE_ACCESSLOG_BUFLEN]; } lb; }; #if !defined(KORE_NO_HTTP) #define KORE_VALIDATOR_TYPE_REGEX 1 #define KORE_VALIDATOR_TYPE_FUNCTION 2 struct kore_validator { u_int8_t type; char *name; char *arg; regex_t rctx; struct kore_runtime_call *rcall; TAILQ_ENTRY(kore_validator) list; }; #endif /* !KORE_NO_HTTP */ #define KORE_BUF_OWNER_API 0x0001 struct kore_buf { u_int8_t *data; int flags; size_t length; size_t offset; }; #define KORE_JSON_TYPE_OBJECT 0x0001 #define KORE_JSON_TYPE_ARRAY 0x0002 #define KORE_JSON_TYPE_STRING 0x0004 #define KORE_JSON_TYPE_NUMBER 0x0008 #define KORE_JSON_TYPE_LITERAL 0x0010 #define KORE_JSON_TYPE_INTEGER 0x0020 #define KORE_JSON_TYPE_INTEGER_U64 0x0040 #define KORE_JSON_FALSE 0 #define KORE_JSON_TRUE 1 #define KORE_JSON_NULL 2 #define KORE_JSON_DEPTH_MAX 10 #define KORE_JSON_ERR_NONE 0 #define KORE_JSON_ERR_INVALID_OBJECT 1 #define KORE_JSON_ERR_INVALID_ARRAY 2 #define KORE_JSON_ERR_INVALID_STRING 3 #define KORE_JSON_ERR_INVALID_NUMBER 4 #define KORE_JSON_ERR_INVALID_LITERAL 5 #define KORE_JSON_ERR_DEPTH 6 #define KORE_JSON_ERR_EOF 7 #define KORE_JSON_ERR_INVALID_JSON 8 #define KORE_JSON_ERR_INVALID_SEARCH 9 #define KORE_JSON_ERR_NOT_FOUND 10 #define KORE_JSON_ERR_TYPE_MISMATCH 11 #define KORE_JSON_ERR_LAST KORE_JSON_ERR_TYPE_MISMATCH #define kore_json_find_object(j, p) \ kore_json_find(j, p, KORE_JSON_TYPE_OBJECT) #define kore_json_find_array(j, p) \ kore_json_find(j, p, KORE_JSON_TYPE_ARRAY) #define kore_json_find_string(j, p) \ kore_json_find(j, p, KORE_JSON_TYPE_STRING) #define kore_json_find_number(j, p) \ kore_json_find(j, p, KORE_JSON_TYPE_NUMBER) #define kore_json_find_integer(j, p) \ kore_json_find(j, p, KORE_JSON_TYPE_INTEGER) #define kore_json_find_integer_u64(j, p) \ kore_json_find(j, p, KORE_JSON_TYPE_INTEGER_U64) #define kore_json_find_literal(j, p) \ kore_json_find(j, p, KORE_JSON_TYPE_LITERAL) #define kore_json_create_object(o, n) \ kore_json_create_item(o, n, KORE_JSON_TYPE_OBJECT) #define kore_json_create_array(o, n) \ kore_json_create_item(o, n, KORE_JSON_TYPE_ARRAY) #define kore_json_create_string(o, n, v) \ kore_json_create_item(o, n, KORE_JSON_TYPE_STRING, v) #define kore_json_create_number(o, n, v) \ kore_json_create_item(o, n, KORE_JSON_TYPE_NUMBER, (double)v) #define kore_json_create_integer(o, n, v) \ kore_json_create_item(o, n, KORE_JSON_TYPE_INTEGER, (int64_t)v) #define kore_json_create_integer_u64(o, n, v) \ kore_json_create_item(o, n, KORE_JSON_TYPE_INTEGER_U64, (u_int64_t)v) #define kore_json_create_literal(o, n, v) \ kore_json_create_item(o, n, KORE_JSON_TYPE_LITERAL, v) struct kore_json { const u_int8_t *data; int depth; size_t length; size_t offset; struct kore_buf tmpbuf; struct kore_json_item *root; }; struct kore_json_item { u_int32_t type; char *name; struct kore_json_item *parent; union { TAILQ_HEAD(, kore_json_item) items; char *string; double number; int literal; int64_t integer; u_int64_t u64; } data; int (*parse)(struct kore_json *, struct kore_json_item *); TAILQ_ENTRY(kore_json_item) list; }; struct kore_pool_entry { u_int8_t state; void *uptr; void *canary; struct kore_pool_entry *nextfree; }; struct kore_pool { size_t memsz; size_t growth; size_t pagesz; size_t elmlen; size_t uselen; u_int64_t canary; volatile int lock; char *name; struct kore_pool_entry *freelist; }; struct kore_timer { u_int64_t nextrun; u_int64_t interval; int flags; void *arg; void (*cb)(void *, u_int64_t); TAILQ_ENTRY(kore_timer) list; }; /* * Keymgr process is worker index 0, but id 2000. * Acme process is worker index 1, but id 2001. */ #define KORE_WORKER_KEYMGR_IDX 0 #define KORE_WORKER_ACME_IDX 1 #define KORE_WORKER_BASE 2 #define KORE_WORKER_KEYMGR 2000 #define KORE_WORKER_ACME 2001 #define KORE_WORKER_MAX UCHAR_MAX #define KORE_WORKER_POLICY_RESTART 1 #define KORE_WORKER_POLICY_TERMINATE 2 /* Reserved message ids, registered on workers. */ #define KORE_MSG_WEBSOCKET 1 #define KORE_MSG_KEYMGR_REQ 2 #define KORE_MSG_KEYMGR_RESP 3 #define KORE_MSG_SHUTDOWN 4 #define KORE_MSG_ENTROPY_REQ 5 #define KORE_MSG_ENTROPY_RESP 6 #define KORE_MSG_CERTIFICATE 7 #define KORE_MSG_CERTIFICATE_REQ 8 #define KORE_MSG_CRL 9 #define KORE_MSG_ACCEPT_AVAILABLE 10 #define KORE_PYTHON_SEND_OBJ 11 #define KORE_MSG_WORKER_LOG 12 #define KORE_MSG_FATALX 13 #define KORE_MSG_ACME_BASE 100 /* messages for applications should start at 201. */ #define KORE_MSG_APP_BASE 200 /* Predefined message targets. */ #define KORE_MSG_PARENT 1000 #define KORE_MSG_WORKER_ALL 1001 struct kore_msg { u_int8_t id; u_int16_t src; u_int16_t dst; size_t length; }; struct kore_keyreq { int padding; char domain[KORE_DOMAINNAME_LEN + 1]; size_t data_len; u_int8_t data[]; }; struct kore_x509_msg { char domain[KORE_DOMAINNAME_LEN + 1]; size_t data_len; u_int8_t data[]; }; #if !defined(KORE_SINGLE_BINARY) extern char *config_file; #endif extern pid_t kore_pid; extern int kore_quit; extern int kore_quiet; extern int skip_chroot; extern int skip_runas; extern int kore_mem_guard; extern int kore_foreground; extern char *kore_pidfile; extern volatile sig_atomic_t sig_recv; extern char *kore_rand_file; extern int kore_keymgr_active; extern struct kore_privsep worker_privsep; extern struct kore_privsep keymgr_privsep; extern struct kore_privsep acme_privsep; extern u_int8_t nlisteners; extern u_int16_t cpu_count; extern u_int8_t worker_count; extern const char *kore_version; extern const char *kore_build_date; extern int worker_policy; extern u_int8_t worker_set_affinity; extern u_int32_t worker_rlimit_nofiles; extern u_int32_t worker_max_connections; extern u_int32_t worker_active_connections; extern u_int32_t worker_accept_threshold; extern u_int64_t kore_websocket_maxframe; extern u_int64_t kore_websocket_timeout; extern u_int32_t kore_socket_backlog; extern struct kore_worker *worker; extern struct kore_pool nb_pool; extern struct kore_domain *primary_dom; extern struct kore_server_list kore_servers; /* kore.c */ void kore_signal(int); void kore_shutdown(void); void kore_signal_trap(int); void kore_signal_setup(void); void kore_proctitle(const char *); void kore_default_getopt(int, char **); void kore_server_closeall(void); void kore_server_cleanup(void); void kore_server_free(struct kore_server *); void kore_server_finalize(struct kore_server *); void kore_hooks_set(const char *, const char *, const char *); struct kore_server *kore_server_create(const char *); struct kore_server *kore_server_lookup(const char *); void kore_listener_accept(void *, int); struct listener *kore_listener_lookup(const char *); void kore_listener_free(struct listener *); struct listener *kore_listener_create(struct kore_server *); int kore_listener_init(struct listener *, int, const char *); int kore_sockopt(int, int, int); int kore_server_bind_unix(struct kore_server *, const char *, const char *); int kore_server_bind(struct kore_server *, const char *, const char *, const char *); /* worker.c */ void kore_worker_reap(void); int kore_worker_init(void); void kore_worker_privsep(void); void kore_worker_started(void); void kore_worker_make_busy(void); void kore_worker_shutdown(void); void kore_worker_dispatch_signal(int); int kore_worker_spawn(u_int16_t, u_int16_t, u_int16_t); int kore_worker_keymgr_response_verify(struct kore_msg *, const void *, struct kore_domain **); void kore_worker_entry(struct kore_worker *) __attribute__((noreturn)); struct kore_worker *kore_worker_data(u_int8_t); struct kore_worker *kore_worker_data_byid(u_int16_t); /* platform code (linux.c, bsd.c) */ void kore_platform_init(void); void kore_platform_sandbox(void); void kore_platform_event_init(void); void kore_platform_event_cleanup(void); void kore_platform_disable_read(int); void kore_platform_disable_write(int); void kore_platform_enable_accept(void); void kore_platform_disable_accept(void); void kore_platform_event_wait(u_int64_t); void kore_platform_event_all(int, void *); void kore_platform_event_level_all(int, void *); void kore_platform_event_level_read(int, void *); void kore_platform_proctitle(const char *); void kore_platform_schedule_read(int, void *); void kore_platform_schedule_write(int, void *); void kore_platform_event_schedule(int, int, int, void *); void kore_platform_worker_setcpu(struct kore_worker *); u_int32_t kore_platform_random_uint32(void); #if defined(KORE_USE_PLATFORM_SENDFILE) int kore_platform_sendfile(struct connection *, struct netbuf *); #endif #if defined(KORE_USE_PLATFORM_PLEDGE) void kore_platform_pledge(void); void kore_platform_add_pledge(const char *); #endif /* tls variants. */ #define KORE_X509_NAME_COMMON_NAME 1 void kore_tls_init(void); void kore_tls_cleanup(void); void kore_tls_dh_check(void); int kore_tls_supported(void); void kore_tls_version_set(int); void kore_tls_keymgr_init(void); void kore_tls_log_version(void); int kore_tls_dh_load(const char *); void kore_tls_seed(const void *, size_t); int kore_tls_ciphersuite_set(const char *); int kore_tls_read(struct connection *, size_t *); void kore_tls_domain_cleanup(struct kore_domain *); int kore_tls_connection_accept(struct connection *); void kore_tls_connection_cleanup(struct connection *); int kore_tls_write(struct connection *, size_t, size_t *); void kore_tls_domain_crl(struct kore_domain *, const void *, size_t); void kore_tls_domain_setup(struct kore_domain *, int, const void *, size_t); KORE_PRIVATE_KEY *kore_tls_rsakey_load(const char *); KORE_PRIVATE_KEY *kore_tls_rsakey_generate(const char *); int kore_tls_x509_data(struct connection *, u_int8_t **, size_t *); KORE_X509_NAMES *kore_tls_x509_issuer_name(struct connection *); KORE_X509_NAMES *kore_tls_x509_subject_name(struct connection *); int kore_tls_x509name_foreach(KORE_X509_NAMES *, int, void *, int (*)(void *, int, int, const char *, const void *, size_t, int)); /* accesslog.c */ void kore_accesslog_init(u_int16_t); void kore_accesslog_worker_init(void); void kore_accesslog_run(void *, u_int64_t); void kore_accesslog_gather(void *, u_int64_t, int); #if !defined(KORE_NO_HTTP) /* auth.c */ int kore_auth_run(struct http_request *, struct kore_auth *); int kore_auth_cookie(struct http_request *, struct kore_auth *); int kore_auth_header(struct http_request *, struct kore_auth *); int kore_auth_request(struct http_request *, struct kore_auth *); void kore_auth_init(void); int kore_auth_new(const char *); struct kore_auth *kore_auth_lookup(const char *); #endif /* timer.c */ void kore_timer_init(void); void kore_timer_run(u_int64_t); u_int64_t kore_timer_next_run(u_int64_t); void kore_timer_remove(struct kore_timer *); struct kore_timer *kore_timer_add(void (*cb)(void *, u_int64_t), u_int64_t, void *, int); /* connection.c */ void kore_connection_init(void); void kore_connection_cleanup(void); void kore_connection_prune(int); struct connection *kore_connection_new(void *); void kore_connection_event(void *, int); int kore_connection_nonblock(int, int); void kore_connection_check_timeout(u_int64_t); int kore_connection_handle(struct connection *); void kore_connection_remove(struct connection *); void kore_connection_disconnect(struct connection *); void kore_connection_start_idletimer(struct connection *); void kore_connection_stop_idletimer(struct connection *); void kore_connection_check_idletimer(u_int64_t, struct connection *); int kore_connection_accept(struct listener *, struct connection **); void kore_connection_log(struct connection *, const char *, ...) __attribute__((format (printf, 2, 3))); const char *kore_connection_ip(struct connection *); void kore_log_init(void); void kore_log_file(const char *); /* config.c */ void kore_parse_config(void); void kore_parse_config_file(FILE *); int kore_configure_setting(const char *, char *); /* mem.c */ void *kore_malloc(size_t); void *kore_mmap_region(size_t); void *kore_calloc(size_t, size_t); void *kore_realloc(void *, size_t); void kore_free(void *); void kore_mem_init(void); void kore_free_zero(void *); void kore_mem_cleanup(void); void kore_mem_untag(void *); void *kore_mem_lookup(u_int32_t); void kore_mem_zero(void *, size_t); void kore_mem_tag(void *, u_int32_t); void *kore_malloc_tagged(size_t, u_int32_t); /* pool.c */ void *kore_pool_get(struct kore_pool *); void kore_pool_put(struct kore_pool *, void *); void kore_pool_init(struct kore_pool *, const char *, size_t, size_t); void kore_pool_cleanup(struct kore_pool *); /* utils.c */ void fatal(const char *, ...) __attribute__((noreturn)) __attribute__((format (printf, 1, 2))); void fatalx(const char *, ...) __attribute__((noreturn)) __attribute__((format (printf, 1, 2))); u_int64_t kore_time_ms(void); char *kore_time_to_date(time_t); char *kore_strdup(const char *); time_t kore_date_to_time(const char *); void kore_log(int, const char *, ...) __attribute__((format (printf, 2, 3))); u_int64_t kore_strtonum64(const char *, int, int *); size_t kore_strlcpy(char *, const char *, const size_t); void kore_server_disconnect(struct connection *); int kore_split_string(char *, const char *, char **, size_t); void kore_strip_chars(const char *, const char, char **); int kore_snprintf(char *, size_t, int *, const char *, ...) __attribute__((format (printf, 4, 5))); long long kore_strtonum(const char *, int, long long, long long, int *); double kore_strtodouble(const char *, long double, long double, int *); int kore_base64_encode(const void *, size_t, char **); int kore_base64_decode(const char *, u_int8_t **, size_t *); int kore_base64url_encode(const void *, size_t, char **, int); int kore_base64url_decode(const char *, u_int8_t **, size_t *, int); int kore_x509_issuer_name(struct connection *, char **, int); int kore_x509_subject_name(struct connection *, char **, int); void *kore_mem_find(void *, size_t, const void *, size_t); char *kore_text_trim(char *, size_t); char *kore_read_line(FILE *, char *, size_t); #if !defined(KORE_NO_HTTP) /* websocket.c */ void kore_websocket_handshake(struct http_request *, const char *, const char *, const char *); int kore_websocket_send_clean(struct netbuf *); void kore_websocket_send(struct connection *, u_int8_t, const void *, size_t); void kore_websocket_broadcast(struct connection *, u_int8_t, const void *, size_t, int); #endif /* msg.c */ void kore_msg_init(void); void kore_msg_worker_init(void); void kore_msg_parent_init(void); void kore_msg_unregister(u_int8_t); void kore_msg_parent_add(struct kore_worker *); void kore_msg_parent_remove(struct kore_worker *); void kore_msg_send(u_int16_t, u_int8_t, const void *, size_t); int kore_msg_register(u_int8_t, void (*cb)(struct kore_msg *, const void *)); #if !defined(KORE_NO_HTTP) /* filemap.c */ void kore_filemap_init(void); void kore_filemap_resolve_paths(void); extern char *kore_filemap_ext; extern char *kore_filemap_index; struct kore_route *kore_filemap_create(struct kore_domain *, const char *, const char *, const char *); #endif /* fileref.c */ void kore_fileref_init(void); struct kore_fileref *kore_fileref_get(const char *, int); struct kore_fileref *kore_fileref_create(struct kore_server *, const char *, int, off_t, struct timespec *); void kore_fileref_release(struct kore_fileref *); /* domain.c */ struct kore_domain *kore_domain_new(const char *); struct kore_domain *kore_domain_byid(u_int16_t); struct kore_domain *kore_domain_lookup(struct kore_server *, const char *); void kore_domain_init(void); void kore_domain_cleanup(void); void kore_domain_free(struct kore_domain *); void kore_module_init(void); void kore_module_cleanup(void); void kore_module_reload(int); void kore_module_onload(void); int kore_module_loaded(void); void kore_domain_closelogs(void); void *kore_module_getsym(const char *, struct kore_runtime **); void kore_domain_load_crl(void); void kore_domain_keymgr_init(void); void kore_domain_callback(void (*cb)(struct kore_domain *)); int kore_domain_attach(struct kore_domain *, struct kore_server *); #if !defined(KORE_NO_HTTP) /* route.c */ void kore_route_reload(void); void kore_route_free(struct kore_route *); void kore_route_callback(struct kore_route *, const char *); struct kore_route *kore_route_create(struct kore_domain *, const char *, int); int kore_route_lookup(struct http_request *, struct kore_domain *, int, struct kore_route **); #endif /* runtime.c */ size_t kore_runtime_count(void); struct kore_runtime_call *kore_runtime_getcall(const char *); struct kore_module *kore_module_load(const char *, const char *, int); void kore_runtime_execute(struct kore_runtime_call *); int kore_runtime_onload(struct kore_runtime_call *, int); void kore_runtime_signal(struct kore_runtime_call *, int); void kore_runtime_resolve(const char *, const struct stat *); void kore_runtime_configure(struct kore_runtime_call *, int, char **); void kore_runtime_connect(struct kore_runtime_call *, struct connection *); #if !defined(KORE_NO_HTTP) int kore_runtime_http_request(struct kore_runtime_call *, struct http_request *); void kore_runtime_http_request_free(struct kore_runtime_call *, struct http_request *); void kore_runtime_http_body_chunk(struct kore_runtime_call *, struct http_request *, const void *, size_t); int kore_runtime_validator(struct kore_runtime_call *, struct http_request *, const void *); void kore_runtime_wsconnect(struct kore_runtime_call *, struct connection *); void kore_runtime_wsdisconnect(struct kore_runtime_call *, struct connection *); void kore_runtime_wsmessage(struct kore_runtime_call *, struct connection *, u_int8_t, const void *, size_t); #endif #if !defined(KORE_NO_HTTP) /* validator.c */ void kore_validator_init(void); void kore_validator_reload(void); int kore_validator_add(const char *, u_int8_t, const char *); int kore_validator_run(struct http_request *, const char *, char *); int kore_validator_check(struct http_request *, struct kore_validator *, const void *); struct kore_validator *kore_validator_lookup(const char *); #endif const char *kore_worker_name(int); /* net.c */ u_int16_t net_read16(u_int8_t *); u_int32_t net_read32(u_int8_t *); u_int64_t net_read64(u_int8_t *); void net_write16(u_int8_t *, u_int16_t); void net_write32(u_int8_t *, u_int32_t); void net_write64(u_int8_t *, u_int64_t); void net_init(void); void net_cleanup(void); struct netbuf *net_netbuf_get(void); int net_send(struct connection *); int net_send_flush(struct connection *); int net_recv_flush(struct connection *); int net_read(struct connection *, size_t *); int net_write(struct connection *, size_t, size_t *); void net_recv_reset(struct connection *, size_t, int (*cb)(struct netbuf *)); void net_remove_netbuf(struct connection *, struct netbuf *); void net_recv_queue(struct connection *, size_t, int, int (*cb)(struct netbuf *)); void net_recv_expand(struct connection *c, size_t, int (*cb)(struct netbuf *)); void net_send_queue(struct connection *, const void *, size_t); void net_send_stream(struct connection *, void *, size_t, int (*cb)(struct netbuf *), struct netbuf **); void net_send_fileref(struct connection *, struct kore_fileref *); /* buf.c */ void kore_buf_free(struct kore_buf *); struct kore_buf *kore_buf_alloc(size_t); void kore_buf_init(struct kore_buf *, size_t); void kore_buf_append(struct kore_buf *, const void *, size_t); u_int8_t *kore_buf_release(struct kore_buf *, size_t *); void kore_buf_reset(struct kore_buf *); void kore_buf_cleanup(struct kore_buf *); char *kore_buf_stringify(struct kore_buf *, size_t *); void kore_buf_appendf(struct kore_buf *, const char *, ...) __attribute__((format (printf, 2, 3))); void kore_buf_appendv(struct kore_buf *, const char *, va_list) __attribute__((format (printf, 2, 0))); void kore_buf_replace_string(struct kore_buf *, const char *, const void *, size_t); /* json.c */ int kore_json_errno(void); int kore_json_parse(struct kore_json *); void kore_json_cleanup(struct kore_json *); void kore_json_item_free(struct kore_json_item *); void kore_json_init(struct kore_json *, const void *, size_t); void kore_json_item_tobuf(struct kore_json_item *, struct kore_buf *); void kore_json_item_attach(struct kore_json_item *, struct kore_json_item *); const char *kore_json_strerror(void); struct kore_json_item *kore_json_find(struct kore_json_item *, const char *, u_int32_t); struct kore_json_item *kore_json_create_item(struct kore_json_item *, const char *, u_int32_t, ...); /* keymgr.c */ void kore_keymgr_run(void); void kore_keymgr_cleanup(int); #if defined(__cplusplus) } #endif #endif /* !__H_KORE_H */