commit e6833a4892f048c147bccf4928f2ef11578dccb0
parent 548068d2a050cf3f0a9c7674657beda7b9d03930
Author: Joris Vink <joris@coders.se>
Date: Fri, 30 Mar 2018 13:45:29 +0200
Move header files to include/kore.
Mimics how the header files are installed on a system
as PREFIX/include/kore.
This is required for getting kodev to use the headers from the
kore_source option instead of requiring the kore headers to be
installed on the system even when building as a single_binary.
Diffstat:
15 files changed, 1616 insertions(+), 1616 deletions(-)
diff --git a/Makefile b/Makefile
@@ -19,7 +19,7 @@ FEATURES_INC=
CFLAGS+=-Wall -Werror -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+=-Wmissing-declarations -Wshadow -Wpointer-arith -Wcast-qual
-CFLAGS+=-Wsign-compare -Iincludes -std=c99 -pedantic
+CFLAGS+=-Wsign-compare -Iinclude/kore -std=c99 -pedantic
CFLAGS+=-DPREFIX='"$(PREFIX)"' -fstack-protector-all
LDFLAGS=-rdynamic -lssl -lcrypto
diff --git a/include/kore/http.h b/include/kore/http.h
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2013 Joris Vink <joris@coders.se>
+ *
+ * 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.
+ */
+
+#if !defined(KORE_NO_HTTP)
+
+#ifndef __H_HTTP_H
+#define __H_HTTP_H
+
+#include <sys/types.h>
+#include <sys/queue.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Keep the http_populate_get symbol around. */
+#define http_populate_get http_populate_qs
+
+#define HTTP_KEEPALIVE_TIME 20
+#define HTTP_HSTS_ENABLE 31536000
+#define HTTP_HEADER_MAX_LEN 4096
+#define HTTP_BODY_MAX_LEN 1024000
+#define HTTP_URI_LEN 2000
+#define HTTP_USERAGENT_LEN 256
+#define HTTP_REQ_HEADER_MAX 25
+#define HTTP_MAX_QUERY_ARGS 20
+#define HTTP_MAX_COOKIES 10
+#define HTTP_MAX_COOKIENAME 255
+#define HTTP_HEADER_BUFSIZE 1024
+#define HTTP_COOKIE_BUFSIZE 1024
+#define HTTP_DATE_MAXSIZE 255
+#define HTTP_REQUEST_LIMIT 1000
+#define HTTP_REQUEST_MS 10
+#define HTTP_BODY_DISK_PATH "tmp_files"
+#define HTTP_BODY_DISK_OFFLOAD 0
+#define HTTP_BODY_PATH_MAX 256
+#define HTTP_BOUNDARY_MAX 80
+
+#define HTTP_ARG_TYPE_RAW 0
+#define HTTP_ARG_TYPE_BYTE 1
+#define HTTP_ARG_TYPE_INT16 2
+#define HTTP_ARG_TYPE_UINT16 3
+#define HTTP_ARG_TYPE_INT32 4
+#define HTTP_ARG_TYPE_UINT32 5
+#define HTTP_ARG_TYPE_STRING 6
+#define HTTP_ARG_TYPE_INT64 7
+#define HTTP_ARG_TYPE_UINT64 8
+
+#define HTTP_STATE_ERROR 0
+#define HTTP_STATE_CONTINUE 1
+#define HTTP_STATE_COMPLETE 2
+#define HTTP_STATE_RETRY 3
+
+struct http_header {
+ char *header;
+ char *value;
+
+ TAILQ_ENTRY(http_header) list;
+};
+
+#define HTTP_COOKIE_HTTPONLY 0x0001
+#define HTTP_COOKIE_SECURE 0x0002
+
+struct http_cookie {
+ char *name;
+ char *value;
+ char *path;
+ char *domain;
+ u_int32_t maxage;
+ time_t expires;
+ u_int16_t flags;
+
+ TAILQ_ENTRY(http_cookie) list;
+};
+
+struct http_arg {
+ char *name;
+ char *s_value;
+
+ TAILQ_ENTRY(http_arg) list;
+};
+
+#define COPY_ARG_TYPE(v, t) \
+ do { \
+ *(t *)nout = v; \
+ } while (0)
+
+#define COPY_ARG_INT64(type, sign) \
+ do { \
+ int err; \
+ type nval; \
+ nval = (type)kore_strtonum64(q->s_value, sign, &err); \
+ if (err != KORE_RESULT_OK) \
+ return (KORE_RESULT_ERROR); \
+ COPY_ARG_TYPE(nval, type); \
+ } while (0)
+
+#define COPY_ARG_INT(min, max, type) \
+ do { \
+ int err; \
+ int64_t nval; \
+ nval = kore_strtonum(q->s_value, 10, min, max, &err); \
+ if (err != KORE_RESULT_OK) \
+ return (KORE_RESULT_ERROR); \
+ COPY_ARG_TYPE(nval, type); \
+ } while (0)
+
+#define COPY_AS_INTTYPE_64(type, sign) \
+ do { \
+ if (nout == NULL) \
+ return (KORE_RESULT_ERROR); \
+ COPY_ARG_INT64(type, sign); \
+ } while (0)
+
+#define COPY_AS_INTTYPE(min, max, type) \
+ do { \
+ if (nout == NULL) \
+ return (KORE_RESULT_ERROR); \
+ COPY_ARG_INT(min, max, type); \
+ } while (0)
+
+#define http_argument_type(r, n, so, no, t) \
+ http_argument_get(r, n, so, no, t)
+
+#define http_argument_get_string(r, n, o) \
+ http_argument_type(r, n, (void **)o, NULL, HTTP_ARG_TYPE_STRING)
+
+#define http_argument_get_byte(r, n, o) \
+ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_BYTE)
+
+#define http_argument_get_uint16(r, n, o) \
+ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT16)
+
+#define http_argument_get_int16(r, n, o) \
+ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT16)
+
+#define http_argument_get_uint32(r, n, o) \
+ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT32)
+
+#define http_argument_get_int32(r, n, o) \
+ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT32)
+
+#define http_argument_get_uint64(r, n, o) \
+ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT64)
+
+#define http_argument_get_int64(r, n, o) \
+ http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT64)
+
+
+struct http_file {
+ char *name;
+ char *filename;
+ size_t position;
+ size_t offset;
+ size_t length;
+ struct http_request *req;
+ TAILQ_ENTRY(http_file) list;
+};
+
+#define HTTP_METHOD_GET 0
+#define HTTP_METHOD_POST 1
+#define HTTP_METHOD_PUT 2
+#define HTTP_METHOD_DELETE 3
+#define HTTP_METHOD_HEAD 4
+#define HTTP_METHOD_OPTIONS 5
+#define HTTP_METHOD_PATCH 6
+
+#define HTTP_REQUEST_COMPLETE 0x0001
+#define HTTP_REQUEST_DELETE 0x0002
+#define HTTP_REQUEST_SLEEPING 0x0004
+#define HTTP_REQUEST_EXPECT_BODY 0x0020
+#define HTTP_REQUEST_RETAIN_EXTRA 0x0040
+#define HTTP_REQUEST_NO_CONTENT_LENGTH 0x0080
+#define HTTP_REQUEST_AUTHED 0x0100
+
+#define HTTP_VALIDATOR_IS_REQUEST 0x8000
+
+struct kore_task;
+
+struct http_request {
+ u_int8_t method;
+ u_int8_t fsm_state;
+ u_int16_t flags;
+ u_int16_t status;
+ u_int64_t ms;
+ u_int64_t start;
+ u_int64_t end;
+ u_int64_t total;
+ const char *path;
+ const char *host;
+ const char *agent;
+ struct connection *owner;
+ u_int8_t *headers;
+ struct kore_buf *http_body;
+ int http_body_fd;
+ char *http_body_path;
+ size_t http_body_length;
+ size_t http_body_offset;
+ size_t content_length;
+ void *hdlr_extra;
+ size_t state_len;
+ char *query_string;
+ struct kore_module_handle *hdlr;
+
+#if defined(KORE_USE_PYTHON)
+ void *py_coro;
+#endif
+
+ LIST_HEAD(, kore_task) tasks;
+ LIST_HEAD(, kore_pgsql) pgsqls;
+
+ TAILQ_HEAD(, http_cookie) req_cookies;
+ TAILQ_HEAD(, http_cookie) resp_cookies;
+ TAILQ_HEAD(, http_header) req_headers;
+ TAILQ_HEAD(, http_header) resp_headers;
+ TAILQ_HEAD(, http_arg) arguments;
+ TAILQ_HEAD(, http_file) files;
+ TAILQ_ENTRY(http_request) list;
+ TAILQ_ENTRY(http_request) olist;
+};
+
+struct http_state {
+ const char *name;
+ int (*cb)(struct http_request *);
+};
+
+extern size_t http_body_max;
+extern u_int16_t http_header_max;
+extern u_int32_t http_request_ms;
+extern u_int64_t http_hsts_enable;
+extern u_int16_t http_keepalive_time;
+extern u_int32_t http_request_limit;
+extern u_int32_t http_request_count;
+extern u_int64_t http_body_disk_offload;
+extern char *http_body_disk_path;
+
+void kore_accesslog(struct http_request *);
+
+void http_init(void);
+void http_cleanup(void);
+void http_server_version(const char *);
+void http_process(void);
+const char *http_status_text(int);
+const char *http_method_text(int);
+time_t http_date_to_time(char *);
+void http_request_free(struct http_request *);
+void http_request_sleep(struct http_request *);
+void http_request_wakeup(struct http_request *);
+void http_process_request(struct http_request *);
+int http_body_rewind(struct http_request *);
+ssize_t http_body_read(struct http_request *, void *, size_t);
+void http_response(struct http_request *, int, const void *, size_t);
+void http_serveable(struct http_request *, const void *,
+ size_t, const char *, const char *);
+void http_response_stream(struct http_request *, int, void *,
+ size_t, int (*cb)(struct netbuf *), void *);
+int http_request_header(struct http_request *,
+ const char *, const char **);
+void http_response_header(struct http_request *,
+ const char *, const char *);
+int http_state_run(struct http_state *, u_int8_t,
+ struct http_request *);
+int http_request_cookie(struct http_request *,
+ const char *, char **);
+void http_response_cookie(struct http_request *, const char *,
+ const char *, const char *, time_t, u_int32_t,
+ struct http_cookie **);
+
+void *http_state_get(struct http_request *);
+int http_state_exists(struct http_request *);
+void http_state_cleanup(struct http_request *);
+void *http_state_create(struct http_request *, size_t);
+
+int http_argument_urldecode(char *);
+int http_header_recv(struct netbuf *);
+void http_populate_qs(struct http_request *);
+void http_populate_post(struct http_request *);
+void http_populate_multipart_form(struct http_request *);
+void http_populate_cookies(struct http_request *);
+int http_argument_get(struct http_request *,
+ const char *, void **, void *, int);
+
+void http_file_rewind(struct http_file *);
+ssize_t http_file_read(struct http_file *, void *, size_t);
+struct http_file *http_file_lookup(struct http_request *, const char *);
+
+enum http_status_code {
+ HTTP_STATUS_CONTINUE = 100,
+ HTTP_STATUS_SWITCHING_PROTOCOLS = 101,
+ HTTP_STATUS_OK = 200,
+ HTTP_STATUS_CREATED = 201,
+ HTTP_STATUS_ACCEPTED = 202,
+ HTTP_STATUS_NON_AUTHORITATIVE = 203,
+ HTTP_STATUS_NO_CONTENT = 204,
+ HTTP_STATUS_RESET_CONTENT = 205,
+ HTTP_STATUS_PARTIAL_CONTENT = 206,
+ HTTP_STATUS_MULTIPLE_CHOICES = 300,
+ HTTP_STATUS_MOVED_PERMANENTLY = 301,
+ HTTP_STATUS_FOUND = 302,
+ HTTP_STATUS_SEE_OTHER = 303,
+ HTTP_STATUS_NOT_MODIFIED = 304,
+ HTTP_STATUS_USE_PROXY = 305,
+ HTTP_STATUS_TEMPORARY_REDIRECT = 307,
+ HTTP_STATUS_BAD_REQUEST = 400,
+ HTTP_STATUS_UNAUTHORIZED = 401,
+ HTTP_STATUS_PAYMENT_REQUIRED = 402,
+ HTTP_STATUS_FORBIDDEN = 403,
+ HTTP_STATUS_NOT_FOUND = 404,
+ HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
+ HTTP_STATUS_NOT_ACCEPTABLE = 406,
+ HTTP_STATUS_PROXY_AUTH_REQUIRED = 407,
+ HTTP_STATUS_REQUEST_TIMEOUT = 408,
+ HTTP_STATUS_CONFLICT = 409,
+ HTTP_STATUS_GONE = 410,
+ HTTP_STATUS_LENGTH_REQUIRED = 411,
+ HTTP_STATUS_PRECONDITION_FAILED = 412,
+ HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE = 413,
+ HTTP_STATUS_REQUEST_URI_TOO_LARGE = 414,
+ HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
+ HTTP_STATUS_REQUEST_RANGE_INVALID = 416,
+ HTTP_STATUS_EXPECTATION_FAILED = 417,
+ HTTP_STATUS_INTERNAL_ERROR = 500,
+ HTTP_STATUS_NOT_IMPLEMENTED = 501,
+ HTTP_STATUS_BAD_GATEWAY = 502,
+ HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
+ HTTP_STATUS_GATEWAY_TIMEOUT = 504,
+ HTTP_STATUS_BAD_VERSION = 505
+};
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !__H_HTTP_H */
+
+#endif /* ! KORE_NO_HTTP */
diff --git a/include/kore/jsonrpc.h b/include/kore/jsonrpc.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016 Raphaƫl Monrouzeau <raphael.monrouzeau@gmail.com>
+ *
+ * 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.
+ */
+
+#if !defined(KORE_NO_HTTP)
+
+#ifndef __H_JSONRPC_H
+#define __H_JSONRPC_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* JSON RPC request handling log entry. */
+struct jsonrpc_log
+{
+ char *msg;
+ struct jsonrpc_log *next, *prev;
+ int lvl;
+};
+
+/* JSON RPC request. */
+struct jsonrpc_request
+{
+ struct jsonrpc_log log;
+ struct kore_buf buf;
+ struct http_request *http;
+ yajl_gen gen;
+ yajl_val json;
+ yajl_val id;
+ char *method;
+ yajl_val params;
+ unsigned int flags;
+ int log_levels;
+};
+
+#define YAJL_GEN_CONST_STRING(CTX, STR) \
+ yajl_gen_string((CTX), (unsigned char *)(STR), sizeof (STR) - 1)
+
+#define YAJL_GEN_CONST_NUMBER(CTX, STR) \
+ yajl_gen_number((CTX), (unsigned char *)(STR), sizeof (STR) - 1)
+
+#define YAJL_GEN_KO(OPERATION) \
+ ((OPERATION) != yajl_gen_status_ok)
+
+enum jsonrpc_error_code
+{
+#define JSONRPC_PARSE_ERROR_MSG "Parse error"
+ JSONRPC_PARSE_ERROR = -32700,
+#define JSONRPC_INVALID_REQUEST_MSG "Invalid Request"
+ JSONRPC_INVALID_REQUEST = -32600,
+#define JSONRPC_METHOD_NOT_FOUND_MSG "Method not found"
+ JSONRPC_METHOD_NOT_FOUND = -32601,
+#define JSONRPC_INVALID_PARAMS_MSG "Invalid params"
+ JSONRPC_INVALID_PARAMS = -32602,
+#define JSONRPC_INTERNAL_ERROR_MSG "Internal error"
+ JSONRPC_INTERNAL_ERROR = -32603,
+#define JSONRPC_SERVER_ERROR_MSG "Server error"
+ JSONRPC_SERVER_ERROR = -32000,
+#define JSONRPC_LIMIT_REACHED_MSG "Limit reached"
+ JSONRPC_LIMIT_REACHED = -31997
+};
+
+void jsonrpc_log(struct jsonrpc_request *, int, const char *, ...);
+int jsonrpc_read_request(struct http_request *, struct jsonrpc_request *);
+void jsonrpc_destroy_request(struct jsonrpc_request *);
+int jsonrpc_error(struct jsonrpc_request *, int, const char *);
+int jsonrpc_result(struct jsonrpc_request *,
+ int (*)(struct jsonrpc_request *, void *), void *);
+#if defined(__cplusplus)
+}
+#endif
+#endif /* !__H_JSONRPC_H */
+
+#endif /* ! KORE_NO_HTTP */
diff --git a/include/kore/kore.h b/include/kore/kore.h
@@ -0,0 +1,716 @@
+/*
+ * Copyright (c) 2013-2018 Joris Vink <joris@coders.se>
+ *
+ * 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 <sys/types.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#if !defined(KORE_NO_TLS)
+#include <openssl/err.h>
+#include <openssl/dh.h>
+#include <openssl/ssl.h>
+#endif
+
+#include <errno.h>
+#include <regex.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__APPLE__)
+#undef daemon
+extern int daemon(int, int);
+#endif
+
+#define KORE_RESULT_ERROR 0
+#define KORE_RESULT_OK 1
+#define KORE_RESULT_RETRY 2
+
+#define KORE_VERSION_MAJOR 2
+#define KORE_VERSION_MINOR 1
+#define KORE_VERSION_PATCH 0
+#define KORE_VERSION_STATE "devel"
+
+#define KORE_TLS_VERSION_1_2 0
+#define KORE_TLS_VERSION_1_0 1
+#define KORE_TLS_VERSION_BOTH 2
+
+#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_DEFAULT_CIPHER_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA"
+
+#if defined(KORE_DEBUG)
+#define kore_debug(...) \
+ if (kore_debug) \
+ kore_debug_internal(__FILE__, __LINE__, __VA_ARGS__)
+#else
+#define kore_debug(...)
+#endif
+
+#define NETBUF_RECV 0
+#define NETBUF_SEND 1
+#define NETBUF_SEND_PAYLOAD_MAX 8192
+
+#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 X509_GET_CN(c, o, l) \
+ X509_NAME_get_text_by_NID(X509_get_subject_name(c), \
+ NID_commonName, o, l)
+
+#define X509_CN_LENGTH (ub_common_name + 1)
+
+/* XXX hackish. */
+#if !defined(KORE_NO_HTTP)
+struct http_request;
+#endif
+
+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;
+
+ void *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 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_READ_POSSIBLE 0x01
+#define CONN_WRITE_POSSIBLE 0x02
+#define CONN_WRITE_BLOCK 0x04
+#define CONN_IDLE_TIMER_ACT 0x10
+#define CONN_READ_BLOCK 0x20
+#define CONN_CLOSE_EMPTY 0x40
+#define CONN_WS_CLOSE_SENT 0x80
+
+#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_CONNECTION_PRUNE_DISCONNECT 0
+#define KORE_CONNECTION_PRUNE_ALL 1
+
+struct connection {
+ u_int8_t type;
+ int fd;
+ u_int8_t state;
+ u_int8_t proto;
+ void *owner;
+#if !defined(KORE_NO_TLS)
+ X509 *cert;
+ SSL *ssl;
+ int tls_reneg;
+#endif
+ u_int8_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 *);
+
+ u_int8_t addrtype;
+ union {
+ struct sockaddr_in ipv4;
+ struct sockaddr_in6 ipv6;
+ } 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)
+ 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
+
+struct kore_runtime {
+ int type;
+#if !defined(KORE_NO_HTTP)
+ int (*http_request)(void *, struct http_request *);
+ 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 (*connect)(void *, struct connection *);
+};
+
+struct kore_runtime_call {
+ void *addr;
+ struct kore_runtime *runtime;
+};
+
+extern struct kore_runtime kore_native_runtime;
+
+struct listener {
+ u_int8_t type;
+ u_int8_t addrtype;
+ int fd;
+ struct kore_runtime_call *connect;
+
+ union {
+ struct sockaddr_in ipv4;
+ struct sockaddr_in6 ipv6;
+ } addr;
+
+ LIST_ENTRY(listener) list;
+};
+
+LIST_HEAD(listener_head, listener);
+
+#if !defined(KORE_NO_HTTP)
+
+#define KORE_PARAMS_QUERY_STRING 0x0001
+
+struct kore_handler_params {
+ char *name;
+ int flags;
+ u_int8_t method;
+ struct kore_validator *validator;
+
+ TAILQ_ENTRY(kore_handler_params) list;
+};
+
+#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 0
+#define KORE_MODULE_PYTHON 1
+
+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;
+ time_t mtime;
+ struct kore_runtime_call *ocb;
+
+ struct kore_module_functions *fun;
+ struct kore_runtime *runtime;
+
+ TAILQ_ENTRY(kore_module) list;
+};
+
+struct kore_module_handle {
+ char *path;
+ char *func;
+ int type;
+ int errors;
+ regex_t rctx;
+ struct kore_domain *dom;
+ struct kore_runtime_call *rcall;
+#if !defined(KORE_NO_HTTP)
+ struct kore_auth *auth;
+ TAILQ_HEAD(, kore_handler_params) params;
+#endif
+ TAILQ_ENTRY(kore_module_handle) list;
+};
+
+struct kore_worker {
+ u_int8_t id;
+ u_int8_t cpu;
+ pid_t pid;
+ int pipe[2];
+ struct connection *msg[2];
+ u_int8_t has_lock;
+ u_int64_t time_locked;
+ struct kore_module_handle *active_hdlr;
+};
+
+struct kore_domain {
+ char *domain;
+ int accesslog;
+#if !defined(KORE_NO_TLS)
+ char *cafile;
+ char *crlfile;
+ char *certfile;
+ char *certkey;
+ SSL_CTX *ssl_ctx;
+#endif
+ TAILQ_HEAD(, kore_module_handle) handlers;
+ TAILQ_ENTRY(kore_domain) list;
+};
+
+TAILQ_HEAD(kore_domain_h, kore_domain);
+
+#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;
+};
+
+struct kore_pool_region {
+ void *start;
+ size_t length;
+ LIST_ENTRY(kore_pool_region) list;
+};
+
+struct kore_pool_entry {
+ u_int8_t state;
+ struct kore_pool_region *region;
+ LIST_ENTRY(kore_pool_entry) list;
+};
+
+struct kore_pool {
+ size_t elen;
+ size_t slen;
+ size_t elms;
+ size_t inuse;
+ volatile int lock;
+ char *name;
+
+ LIST_HEAD(, kore_pool_region) regions;
+ LIST_HEAD(, 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;
+};
+
+#define KORE_WORKER_KEYMGR 0
+
+/* Reserved message ids, registered on workers. */
+#define KORE_MSG_ACCESSLOG 1
+#define KORE_MSG_WEBSOCKET 2
+#define KORE_MSG_KEYMGR_REQ 3
+#define KORE_MSG_KEYMGR_RESP 4
+#define KORE_MSG_SHUTDOWN 5
+#define KORE_MSG_ENTROPY_REQ 6
+#define KORE_MSG_ENTROPY_RESP 7
+
+/* 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;
+ u_int32_t length;
+};
+
+#if !defined(KORE_NO_TLS)
+struct kore_keyreq {
+ int padding;
+ char domain[KORE_DOMAINNAME_LEN];
+ u_int8_t domain_len;
+ u_int16_t data_len;
+ u_int8_t data[];
+};
+#endif
+
+#if !defined(KORE_SINGLE_BINARY)
+extern char *config_file;
+#endif
+
+extern pid_t kore_pid;
+extern int foreground;
+extern int kore_debug;
+extern int skip_chroot;
+extern char *chroot_path;
+extern int skip_runas;
+extern char *runas_user;
+extern char *kore_pidfile;
+extern char *kore_tls_cipher_list;
+extern int tls_version;
+
+#if !defined(KORE_NO_TLS)
+extern DH *tls_dhparam;
+extern char *rand_file;
+#endif
+
+extern u_int8_t nlisteners;
+extern u_int16_t cpu_count;
+extern u_int8_t worker_count;
+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 listener_head listeners;
+extern struct kore_worker *worker;
+extern struct kore_domain_h domains;
+extern struct kore_domain *primary_dom;
+extern struct kore_pool nb_pool;
+
+void kore_signal(int);
+void kore_worker_wait(int);
+void kore_worker_init(void);
+void kore_worker_shutdown(void);
+void kore_worker_privdrop(void);
+void kore_worker_dispatch_signal(int);
+void kore_worker_spawn(u_int16_t, u_int16_t);
+void kore_worker_entry(struct kore_worker *);
+
+struct kore_worker *kore_worker_data(u_int8_t);
+
+void kore_platform_init(void);
+void kore_platform_event_init(void);
+void kore_platform_event_cleanup(void);
+void kore_platform_proctitle(char *);
+void kore_platform_disable_read(int);
+void kore_platform_enable_accept(void);
+void kore_platform_disable_accept(void);
+int kore_platform_event_wait(u_int64_t);
+void kore_platform_event_all(int, void *);
+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 *);
+
+void kore_accesslog_init(void);
+void kore_accesslog_worker_init(void);
+int kore_accesslog_write(const void *, u_int32_t);
+
+#if !defined(KORE_NO_HTTP)
+int kore_auth_run(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
+
+void kore_timer_init(void);
+u_int64_t kore_timer_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);
+
+int kore_sockopt(int, int, int);
+void kore_listener_cleanup(void);
+int kore_server_bind(const char *, const char *, const char *);
+#if !defined(KORE_NO_TLS)
+int kore_tls_sni_cb(SSL *, int *, void *);
+void kore_tls_info_callback(const SSL *, int, int);
+#endif
+
+void kore_connection_init(void);
+void kore_connection_cleanup(void);
+void kore_connection_prune(int);
+struct connection *kore_connection_new(void *);
+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 **);
+
+u_int64_t kore_time_ms(void);
+void kore_log_init(void);
+
+void *kore_malloc(size_t);
+void kore_parse_config(void);
+void *kore_calloc(size_t, size_t);
+void *kore_realloc(void *, size_t);
+void kore_free(void *);
+void kore_mem_init(void);
+void kore_mem_cleanup(void);
+void kore_mem_untag(void *);
+void *kore_mem_lookup(u_int32_t);
+void kore_mem_tag(void *, u_int32_t);
+void *kore_malloc_tagged(size_t, u_int32_t);
+
+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 *);
+
+time_t kore_date_to_time(char *);
+char *kore_time_to_date(time_t);
+char *kore_strdup(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(char *, const char, char **);
+int kore_snprintf(char *, size_t, int *, const char *, ...);
+long long kore_strtonum(const char *, int, long long, long long, int *);
+int kore_base64_encode(const void *, size_t, char **);
+int kore_base64_decode(const char *, u_int8_t **, size_t *);
+void *kore_mem_find(void *, size_t, void *, size_t);
+char *kore_text_trim(char *, size_t);
+char *kore_read_line(FILE *, char *, size_t);
+
+#if !defined(KORE_NO_HTTP)
+void kore_websocket_handshake(struct http_request *,
+ const char *, const char *, const char *);
+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
+
+void kore_msg_init(void);
+void kore_msg_worker_init(void);
+void kore_msg_parent_init(void);
+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 *, u_int32_t);
+int kore_msg_register(u_int8_t,
+ void (*cb)(struct kore_msg *, const void *));
+
+void kore_domain_init(void);
+void kore_domain_cleanup(void);
+int kore_domain_new(char *);
+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_tlsinit(struct kore_domain *);
+void kore_module_load(const char *, const char *, int);
+void kore_domain_callback(void (*cb)(struct kore_domain *));
+int kore_module_handler_new(const char *, const char *,
+ const char *, const char *, int);
+void kore_module_handler_free(struct kore_module_handle *);
+
+struct kore_runtime_call *kore_runtime_getcall(const char *);
+
+void kore_runtime_execute(struct kore_runtime_call *);
+int kore_runtime_onload(struct kore_runtime_call *, int);
+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 *);
+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
+
+struct kore_domain *kore_domain_lookup(const char *);
+struct kore_module_handle *kore_module_handler_find(const char *,
+ const char *);
+
+#if !defined(KORE_NO_HTTP)
+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
+
+void fatal(const char *, ...) __attribute__((noreturn));
+void kore_debug_internal(char *, int, const char *, ...);
+
+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);
+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_read_tls(struct connection *, size_t *);
+int net_write(struct connection *, size_t, size_t *);
+int net_write_tls(struct connection *, size_t, size_t *);
+void net_recv_reset(struct connection *, size_t,
+ int (*cb)(struct netbuf *));
+void net_remove_netbuf(struct netbuf_head *, 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 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 *, ...);
+void kore_buf_appendv(struct kore_buf *, const char *, va_list);
+void kore_buf_replace_string(struct kore_buf *, char *, void *, size_t);
+
+void kore_keymgr_run(void);
+void kore_keymgr_cleanup(void);
+
+void kore_parent_configure(void);
+void kore_worker_configure(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* !__H_KORE_H */
diff --git a/include/kore/pgsql.h b/include/kore/pgsql.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2014-2018 Joris Vink <joris@coders.se>
+ *
+ * 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_PGSQL
+#define _H_KORE_PGSQL
+
+#include <libpq-fe.h>
+
+#define KORE_PGSQL_FORMAT_TEXT 0
+#define KORE_PGSQL_FORMAT_BINARY 1
+
+#define KORE_PGSQL_SYNC 0x0001
+#define KORE_PGSQL_ASYNC 0x0002
+#define KORE_PGSQL_SCHEDULED 0x0004
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+struct pgsql_conn {
+ u_int8_t type;
+ u_int8_t flags;
+ char *name;
+
+ PGconn *db;
+ struct pgsql_job *job;
+ TAILQ_ENTRY(pgsql_conn) list;
+};
+
+struct pgsql_db {
+ char *name;
+ char *conn_string;
+ u_int16_t conn_max;
+ u_int16_t conn_count;
+
+ LIST_ENTRY(pgsql_db) rlist;
+};
+
+struct kore_pgsql {
+ u_int8_t state;
+ int flags;
+ char *error;
+ PGresult *result;
+ struct pgsql_conn *conn;
+
+ struct http_request *req;
+ void *arg;
+ void (*cb)(struct kore_pgsql *, void *);
+
+ LIST_ENTRY(kore_pgsql) rlist;
+};
+
+extern u_int16_t pgsql_conn_max;
+extern u_int32_t pgsql_queue_limit;
+
+void kore_pgsql_sys_init(void);
+void kore_pgsql_sys_cleanup(void);
+void kore_pgsql_init(struct kore_pgsql *);
+void kore_pgsql_bind_request(struct kore_pgsql *, struct http_request *);
+void kore_pgsql_bind_callback(struct kore_pgsql *,
+ void (*cb)(struct kore_pgsql *, void *), void *);
+int kore_pgsql_setup(struct kore_pgsql *, const char *, int);
+void kore_pgsql_handle(void *, int);
+void kore_pgsql_cleanup(struct kore_pgsql *);
+void kore_pgsql_continue(struct kore_pgsql *);
+int kore_pgsql_query(struct kore_pgsql *, const char *);
+int kore_pgsql_query_params(struct kore_pgsql *,
+ const char *, int, int, ...);
+int kore_pgsql_v_query_params(struct kore_pgsql *,
+ const char *, int, int, va_list);
+int kore_pgsql_register(const char *, const char *);
+int kore_pgsql_ntuples(struct kore_pgsql *);
+int kore_pgsql_nfields(struct kore_pgsql *);
+void kore_pgsql_logerror(struct kore_pgsql *);
+char *kore_pgsql_fieldname(struct kore_pgsql *, int);
+char *kore_pgsql_getvalue(struct kore_pgsql *, int, int);
+int kore_pgsql_getlength(struct kore_pgsql *, int, int);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#define KORE_PGSQL_STATE_INIT 1
+#define KORE_PGSQL_STATE_WAIT 2
+#define KORE_PGSQL_STATE_RESULT 3
+#define KORE_PGSQL_STATE_ERROR 4
+#define KORE_PGSQL_STATE_DONE 5
+#define KORE_PGSQL_STATE_COMPLETE 6
+
+#endif
diff --git a/include/kore/python_api.h b/include/kore/python_api.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Stanislav Yudin <stan@endlessinsomnia.com>
+ * Copyright (c) 2017-2018 Joris Vink <joris@coders.se>
+ *
+ * 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_PYTHON_H
+#define __H_PYTHON_H
+
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
+
+#include <Python.h>
+
+void kore_python_init(void);
+void kore_python_cleanup(void);
+void kore_python_path(const char *);
+
+PyObject *kore_python_callable(PyObject *, const char *);
+
+extern struct kore_module_functions kore_python_module;
+extern struct kore_runtime kore_python_runtime;
+
+#endif
diff --git a/include/kore/python_methods.h b/include/kore/python_methods.h
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2017-2018 Joris Vink <joris@coders.se>
+ *
+ * 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.
+ */
+
+static PyObject *python_kore_log(PyObject *, PyObject *);
+static PyObject *python_kore_fatal(PyObject *, PyObject *);
+static PyObject *python_kore_listen(PyObject *, PyObject *);
+
+#if defined(KORE_USE_PGSQL)
+static PyObject *python_kore_pgsql_register(PyObject *, PyObject *);
+#endif
+
+static PyObject *python_websocket_broadcast(PyObject *, PyObject *);
+
+#define METHOD(n, c, a) { n, (PyCFunction)c, a, NULL }
+#define GETTER(n, g) { n, (getter)g, NULL, NULL, NULL }
+#define SETTER(n, s) { n, NULL, (setter)g, NULL, NULL }
+#define GETSET(n, g, s) { n, (getter)g, (setter)s, NULL, NULL }
+
+static struct PyMethodDef pykore_methods[] = {
+ METHOD("log", python_kore_log, METH_VARARGS),
+ METHOD("fatal", python_kore_fatal, METH_VARARGS),
+ METHOD("listen", python_kore_listen, METH_VARARGS),
+ METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS),
+#if defined(KORE_USE_PGSQL)
+ METHOD("register_database", python_kore_pgsql_register, METH_VARARGS),
+#endif
+ { NULL, NULL, 0, NULL }
+};
+
+static struct PyModuleDef pykore_module = {
+ PyModuleDef_HEAD_INIT, "kore", NULL, -1, pykore_methods
+};
+
+struct pyconnection {
+ PyObject_HEAD
+ struct connection *c;
+};
+
+static PyObject *pyconnection_disconnect(struct pyconnection *, PyObject *);
+static PyObject *pyconnection_websocket_send(struct pyconnection *, PyObject *);
+
+static PyMethodDef pyconnection_methods[] = {
+ METHOD("disconnect", pyconnection_disconnect, METH_NOARGS),
+ METHOD("websocket_send", pyconnection_websocket_send, METH_VARARGS),
+ METHOD(NULL, NULL, -1),
+};
+
+static PyObject *pyconnection_get_fd(struct pyconnection *, void *);
+static PyObject *pyconnection_get_addr(struct pyconnection *, void *);
+
+static PyGetSetDef pyconnection_getset[] = {
+ GETTER("fd", pyconnection_get_fd),
+ GETTER("addr", pyconnection_get_addr),
+ GETTER(NULL, NULL),
+};
+
+static void pyconnection_dealloc(struct pyconnection *);
+
+static PyTypeObject pyconnection_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "kore.connection",
+ .tp_doc = "struct connection",
+ .tp_getset = pyconnection_getset,
+ .tp_methods = pyconnection_methods,
+ .tp_basicsize = sizeof(struct pyconnection),
+ .tp_dealloc = (destructor)pyconnection_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+
+struct pyhttp_request {
+ PyObject_HEAD
+ struct http_request *req;
+ PyObject *data;
+};
+
+struct pyhttp_file {
+ PyObject_HEAD
+ struct http_file *file;
+};
+
+static void pyhttp_dealloc(struct pyhttp_request *);
+static void pyhttp_file_dealloc(struct pyhttp_file *);
+
+#if defined(KORE_USE_PGSQL)
+static PyObject *pyhttp_pgsql(struct pyhttp_request *, PyObject *);
+#endif
+static PyObject *pyhttp_cookie(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_response(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_argument(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_body_read(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_file_lookup(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_populate_get(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_populate_post(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_populate_multi(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_populate_cookies(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_request_header(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_response_header(struct pyhttp_request *, PyObject *);
+static PyObject *pyhttp_websocket_handshake(struct pyhttp_request *,
+ PyObject *);
+
+static PyMethodDef pyhttp_request_methods[] = {
+#if defined(KORE_USE_PGSQL)
+ METHOD("pgsql", pyhttp_pgsql, METH_VARARGS),
+#endif
+ METHOD("cookie", pyhttp_cookie, METH_VARARGS),
+ METHOD("response", pyhttp_response, METH_VARARGS),
+ METHOD("argument", pyhttp_argument, METH_VARARGS),
+ METHOD("body_read", pyhttp_body_read, METH_VARARGS),
+ METHOD("file_lookup", pyhttp_file_lookup, METH_VARARGS),
+ METHOD("populate_get", pyhttp_populate_get, METH_NOARGS),
+ METHOD("populate_post", pyhttp_populate_post, METH_NOARGS),
+ METHOD("populate_multi", pyhttp_populate_multi, METH_NOARGS),
+ METHOD("populate_cookies", pyhttp_populate_cookies, METH_NOARGS),
+ METHOD("request_header", pyhttp_request_header, METH_VARARGS),
+ METHOD("response_header", pyhttp_response_header, METH_VARARGS),
+ METHOD("websocket_handshake", pyhttp_websocket_handshake, METH_VARARGS),
+ METHOD(NULL, NULL, -1)
+};
+
+static PyObject *pyhttp_get_host(struct pyhttp_request *, void *);
+static PyObject *pyhttp_get_path(struct pyhttp_request *, void *);
+static PyObject *pyhttp_get_body(struct pyhttp_request *, void *);
+static PyObject *pyhttp_get_agent(struct pyhttp_request *, void *);
+static PyObject *pyhttp_get_method(struct pyhttp_request *, void *);
+static PyObject *pyhttp_get_body_path(struct pyhttp_request *, void *);
+static PyObject *pyhttp_get_connection(struct pyhttp_request *, void *);
+
+static PyGetSetDef pyhttp_request_getset[] = {
+ GETTER("host", pyhttp_get_host),
+ GETTER("path", pyhttp_get_path),
+ GETTER("body", pyhttp_get_body),
+ GETTER("agent", pyhttp_get_agent),
+ GETTER("method", pyhttp_get_method),
+ GETTER("body_path", pyhttp_get_body_path),
+ GETTER("connection", pyhttp_get_connection),
+ GETTER(NULL, NULL)
+};
+
+static PyTypeObject pyhttp_request_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "kore.http_request",
+ .tp_doc = "struct http_request",
+ .tp_getset = pyhttp_request_getset,
+ .tp_methods = pyhttp_request_methods,
+ .tp_dealloc = (destructor)pyhttp_dealloc,
+ .tp_basicsize = sizeof(struct pyhttp_request),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+
+static PyObject *pyhttp_file_read(struct pyhttp_file *, PyObject *);
+
+static PyMethodDef pyhttp_file_methods[] = {
+ METHOD("read", pyhttp_file_read, METH_VARARGS),
+ METHOD(NULL, NULL, -1)
+};
+
+static PyObject *pyhttp_file_get_name(struct pyhttp_file *, void *);
+static PyObject *pyhttp_file_get_filename(struct pyhttp_file *, void *);
+
+static PyGetSetDef pyhttp_file_getset[] = {
+ GETTER("name", pyhttp_file_get_name),
+ GETTER("filename", pyhttp_file_get_filename),
+ GETTER(NULL, NULL)
+};
+
+static PyTypeObject pyhttp_file_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "kore.http_file",
+ .tp_doc = "struct http_file",
+ .tp_getset = pyhttp_file_getset,
+ .tp_methods = pyhttp_file_methods,
+ .tp_dealloc = (destructor)pyhttp_file_dealloc,
+ .tp_basicsize = sizeof(struct pyhttp_file),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+
+#if defined(KORE_USE_PGSQL)
+
+#define PYKORE_PGSQL_PREINIT 1
+#define PYKORE_PGSQL_INITIALIZE 2
+#define PYKORE_PGSQL_QUERY 3
+#define PYKORE_PGSQL_WAIT 4
+
+struct pykore_pgsql {
+ PyObject_HEAD
+ int state;
+ char *db;
+ char *query;
+ struct http_request *req;
+ PyObject *result;
+ struct kore_pgsql sql;
+};
+
+static void pykore_pgsql_dealloc(struct pykore_pgsql *);
+int pykore_pgsql_result(struct pykore_pgsql *);
+
+static PyObject *pykore_pgsql_await(PyObject *);
+static PyObject *pykore_pgsql_iternext(struct pykore_pgsql *);
+
+static PyAsyncMethods pykore_pgsql_async = {
+ (unaryfunc)pykore_pgsql_await,
+ NULL,
+ NULL
+};
+
+static PyTypeObject pykore_pgsql_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "kore.pgsql",
+ .tp_doc = "struct kore_pgsql",
+ .tp_as_async = &pykore_pgsql_async,
+ .tp_iternext = (iternextfunc)pykore_pgsql_iternext,
+ .tp_basicsize = sizeof(struct pykore_pgsql),
+ .tp_dealloc = (destructor)pykore_pgsql_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+};
+#endif
diff --git a/include/kore/tasks.h b/include/kore/tasks.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 Joris Vink <joris@coders.se>
+ *
+ * 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_TASKS
+#define __H_KORE_TASKS
+
+#include <pthread.h>
+
+#define KORE_TASK_STATE_CREATED 1
+#define KORE_TASK_STATE_RUNNING 2
+#define KORE_TASK_STATE_FINISHED 3
+#define KORE_TASK_STATE_ABORT 4
+
+#define KORE_TASK_THREADS 2
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if !defined(KORE_NO_HTTP)
+struct http_request;
+#endif
+
+struct kore_task {
+ u_int8_t type;
+ int state;
+ int result;
+ pthread_rwlock_t lock;
+
+#if !defined(KORE_NO_HTTP)
+ struct http_request *req;
+#endif
+
+ int fds[2];
+ int (*entry)(struct kore_task *);
+ void (*cb)(struct kore_task *);
+
+ struct kore_task_thread *thread;
+
+ TAILQ_ENTRY(kore_task) list;
+ LIST_ENTRY(kore_task) rlist;
+};
+
+struct kore_task_thread {
+ u_int8_t idx;
+ pthread_t tid;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+ TAILQ_HEAD(, kore_task) tasks;
+
+ TAILQ_ENTRY(kore_task_thread) list;
+};
+
+void kore_task_init(void);
+void kore_task_run(struct kore_task *);
+void kore_task_finish(struct kore_task *);
+void kore_task_destroy(struct kore_task *);
+int kore_task_finished(struct kore_task *);
+void kore_task_handle(struct kore_task *, int);
+
+#if !defined(KORE_NO_HTTP)
+void kore_task_bind_request(struct kore_task *,
+ struct http_request *);
+#endif
+void kore_task_bind_callback(struct kore_task *,
+ void (*cb)(struct kore_task *));
+void kore_task_create(struct kore_task *,
+ int (*entry)(struct kore_task *));
+
+u_int32_t kore_task_channel_read(struct kore_task *, void *, u_int32_t);
+void kore_task_channel_write(struct kore_task *, void *, u_int32_t);
+
+void kore_task_set_state(struct kore_task *, int);
+void kore_task_set_result(struct kore_task *, int);
+
+int kore_task_state(struct kore_task *);
+int kore_task_result(struct kore_task *);
+
+extern u_int16_t kore_task_threads;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/includes/http.h b/includes/http.h
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 2013 Joris Vink <joris@coders.se>
- *
- * 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.
- */
-
-#if !defined(KORE_NO_HTTP)
-
-#ifndef __H_HTTP_H
-#define __H_HTTP_H
-
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* Keep the http_populate_get symbol around. */
-#define http_populate_get http_populate_qs
-
-#define HTTP_KEEPALIVE_TIME 20
-#define HTTP_HSTS_ENABLE 31536000
-#define HTTP_HEADER_MAX_LEN 4096
-#define HTTP_BODY_MAX_LEN 1024000
-#define HTTP_URI_LEN 2000
-#define HTTP_USERAGENT_LEN 256
-#define HTTP_REQ_HEADER_MAX 25
-#define HTTP_MAX_QUERY_ARGS 20
-#define HTTP_MAX_COOKIES 10
-#define HTTP_MAX_COOKIENAME 255
-#define HTTP_HEADER_BUFSIZE 1024
-#define HTTP_COOKIE_BUFSIZE 1024
-#define HTTP_DATE_MAXSIZE 255
-#define HTTP_REQUEST_LIMIT 1000
-#define HTTP_REQUEST_MS 10
-#define HTTP_BODY_DISK_PATH "tmp_files"
-#define HTTP_BODY_DISK_OFFLOAD 0
-#define HTTP_BODY_PATH_MAX 256
-#define HTTP_BOUNDARY_MAX 80
-
-#define HTTP_ARG_TYPE_RAW 0
-#define HTTP_ARG_TYPE_BYTE 1
-#define HTTP_ARG_TYPE_INT16 2
-#define HTTP_ARG_TYPE_UINT16 3
-#define HTTP_ARG_TYPE_INT32 4
-#define HTTP_ARG_TYPE_UINT32 5
-#define HTTP_ARG_TYPE_STRING 6
-#define HTTP_ARG_TYPE_INT64 7
-#define HTTP_ARG_TYPE_UINT64 8
-
-#define HTTP_STATE_ERROR 0
-#define HTTP_STATE_CONTINUE 1
-#define HTTP_STATE_COMPLETE 2
-#define HTTP_STATE_RETRY 3
-
-struct http_header {
- char *header;
- char *value;
-
- TAILQ_ENTRY(http_header) list;
-};
-
-#define HTTP_COOKIE_HTTPONLY 0x0001
-#define HTTP_COOKIE_SECURE 0x0002
-
-struct http_cookie {
- char *name;
- char *value;
- char *path;
- char *domain;
- u_int32_t maxage;
- time_t expires;
- u_int16_t flags;
-
- TAILQ_ENTRY(http_cookie) list;
-};
-
-struct http_arg {
- char *name;
- char *s_value;
-
- TAILQ_ENTRY(http_arg) list;
-};
-
-#define COPY_ARG_TYPE(v, t) \
- do { \
- *(t *)nout = v; \
- } while (0)
-
-#define COPY_ARG_INT64(type, sign) \
- do { \
- int err; \
- type nval; \
- nval = (type)kore_strtonum64(q->s_value, sign, &err); \
- if (err != KORE_RESULT_OK) \
- return (KORE_RESULT_ERROR); \
- COPY_ARG_TYPE(nval, type); \
- } while (0)
-
-#define COPY_ARG_INT(min, max, type) \
- do { \
- int err; \
- int64_t nval; \
- nval = kore_strtonum(q->s_value, 10, min, max, &err); \
- if (err != KORE_RESULT_OK) \
- return (KORE_RESULT_ERROR); \
- COPY_ARG_TYPE(nval, type); \
- } while (0)
-
-#define COPY_AS_INTTYPE_64(type, sign) \
- do { \
- if (nout == NULL) \
- return (KORE_RESULT_ERROR); \
- COPY_ARG_INT64(type, sign); \
- } while (0)
-
-#define COPY_AS_INTTYPE(min, max, type) \
- do { \
- if (nout == NULL) \
- return (KORE_RESULT_ERROR); \
- COPY_ARG_INT(min, max, type); \
- } while (0)
-
-#define http_argument_type(r, n, so, no, t) \
- http_argument_get(r, n, so, no, t)
-
-#define http_argument_get_string(r, n, o) \
- http_argument_type(r, n, (void **)o, NULL, HTTP_ARG_TYPE_STRING)
-
-#define http_argument_get_byte(r, n, o) \
- http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_BYTE)
-
-#define http_argument_get_uint16(r, n, o) \
- http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT16)
-
-#define http_argument_get_int16(r, n, o) \
- http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT16)
-
-#define http_argument_get_uint32(r, n, o) \
- http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT32)
-
-#define http_argument_get_int32(r, n, o) \
- http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT32)
-
-#define http_argument_get_uint64(r, n, o) \
- http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_UINT64)
-
-#define http_argument_get_int64(r, n, o) \
- http_argument_type(r, n, NULL, o, HTTP_ARG_TYPE_INT64)
-
-
-struct http_file {
- char *name;
- char *filename;
- size_t position;
- size_t offset;
- size_t length;
- struct http_request *req;
- TAILQ_ENTRY(http_file) list;
-};
-
-#define HTTP_METHOD_GET 0
-#define HTTP_METHOD_POST 1
-#define HTTP_METHOD_PUT 2
-#define HTTP_METHOD_DELETE 3
-#define HTTP_METHOD_HEAD 4
-#define HTTP_METHOD_OPTIONS 5
-#define HTTP_METHOD_PATCH 6
-
-#define HTTP_REQUEST_COMPLETE 0x0001
-#define HTTP_REQUEST_DELETE 0x0002
-#define HTTP_REQUEST_SLEEPING 0x0004
-#define HTTP_REQUEST_EXPECT_BODY 0x0020
-#define HTTP_REQUEST_RETAIN_EXTRA 0x0040
-#define HTTP_REQUEST_NO_CONTENT_LENGTH 0x0080
-#define HTTP_REQUEST_AUTHED 0x0100
-
-#define HTTP_VALIDATOR_IS_REQUEST 0x8000
-
-struct kore_task;
-
-struct http_request {
- u_int8_t method;
- u_int8_t fsm_state;
- u_int16_t flags;
- u_int16_t status;
- u_int64_t ms;
- u_int64_t start;
- u_int64_t end;
- u_int64_t total;
- const char *path;
- const char *host;
- const char *agent;
- struct connection *owner;
- u_int8_t *headers;
- struct kore_buf *http_body;
- int http_body_fd;
- char *http_body_path;
- size_t http_body_length;
- size_t http_body_offset;
- size_t content_length;
- void *hdlr_extra;
- size_t state_len;
- char *query_string;
- struct kore_module_handle *hdlr;
-
-#if defined(KORE_USE_PYTHON)
- void *py_coro;
-#endif
-
- LIST_HEAD(, kore_task) tasks;
- LIST_HEAD(, kore_pgsql) pgsqls;
-
- TAILQ_HEAD(, http_cookie) req_cookies;
- TAILQ_HEAD(, http_cookie) resp_cookies;
- TAILQ_HEAD(, http_header) req_headers;
- TAILQ_HEAD(, http_header) resp_headers;
- TAILQ_HEAD(, http_arg) arguments;
- TAILQ_HEAD(, http_file) files;
- TAILQ_ENTRY(http_request) list;
- TAILQ_ENTRY(http_request) olist;
-};
-
-struct http_state {
- const char *name;
- int (*cb)(struct http_request *);
-};
-
-extern size_t http_body_max;
-extern u_int16_t http_header_max;
-extern u_int32_t http_request_ms;
-extern u_int64_t http_hsts_enable;
-extern u_int16_t http_keepalive_time;
-extern u_int32_t http_request_limit;
-extern u_int32_t http_request_count;
-extern u_int64_t http_body_disk_offload;
-extern char *http_body_disk_path;
-
-void kore_accesslog(struct http_request *);
-
-void http_init(void);
-void http_cleanup(void);
-void http_server_version(const char *);
-void http_process(void);
-const char *http_status_text(int);
-const char *http_method_text(int);
-time_t http_date_to_time(char *);
-void http_request_free(struct http_request *);
-void http_request_sleep(struct http_request *);
-void http_request_wakeup(struct http_request *);
-void http_process_request(struct http_request *);
-int http_body_rewind(struct http_request *);
-ssize_t http_body_read(struct http_request *, void *, size_t);
-void http_response(struct http_request *, int, const void *, size_t);
-void http_serveable(struct http_request *, const void *,
- size_t, const char *, const char *);
-void http_response_stream(struct http_request *, int, void *,
- size_t, int (*cb)(struct netbuf *), void *);
-int http_request_header(struct http_request *,
- const char *, const char **);
-void http_response_header(struct http_request *,
- const char *, const char *);
-int http_state_run(struct http_state *, u_int8_t,
- struct http_request *);
-int http_request_cookie(struct http_request *,
- const char *, char **);
-void http_response_cookie(struct http_request *, const char *,
- const char *, const char *, time_t, u_int32_t,
- struct http_cookie **);
-
-void *http_state_get(struct http_request *);
-int http_state_exists(struct http_request *);
-void http_state_cleanup(struct http_request *);
-void *http_state_create(struct http_request *, size_t);
-
-int http_argument_urldecode(char *);
-int http_header_recv(struct netbuf *);
-void http_populate_qs(struct http_request *);
-void http_populate_post(struct http_request *);
-void http_populate_multipart_form(struct http_request *);
-void http_populate_cookies(struct http_request *);
-int http_argument_get(struct http_request *,
- const char *, void **, void *, int);
-
-void http_file_rewind(struct http_file *);
-ssize_t http_file_read(struct http_file *, void *, size_t);
-struct http_file *http_file_lookup(struct http_request *, const char *);
-
-enum http_status_code {
- HTTP_STATUS_CONTINUE = 100,
- HTTP_STATUS_SWITCHING_PROTOCOLS = 101,
- HTTP_STATUS_OK = 200,
- HTTP_STATUS_CREATED = 201,
- HTTP_STATUS_ACCEPTED = 202,
- HTTP_STATUS_NON_AUTHORITATIVE = 203,
- HTTP_STATUS_NO_CONTENT = 204,
- HTTP_STATUS_RESET_CONTENT = 205,
- HTTP_STATUS_PARTIAL_CONTENT = 206,
- HTTP_STATUS_MULTIPLE_CHOICES = 300,
- HTTP_STATUS_MOVED_PERMANENTLY = 301,
- HTTP_STATUS_FOUND = 302,
- HTTP_STATUS_SEE_OTHER = 303,
- HTTP_STATUS_NOT_MODIFIED = 304,
- HTTP_STATUS_USE_PROXY = 305,
- HTTP_STATUS_TEMPORARY_REDIRECT = 307,
- HTTP_STATUS_BAD_REQUEST = 400,
- HTTP_STATUS_UNAUTHORIZED = 401,
- HTTP_STATUS_PAYMENT_REQUIRED = 402,
- HTTP_STATUS_FORBIDDEN = 403,
- HTTP_STATUS_NOT_FOUND = 404,
- HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
- HTTP_STATUS_NOT_ACCEPTABLE = 406,
- HTTP_STATUS_PROXY_AUTH_REQUIRED = 407,
- HTTP_STATUS_REQUEST_TIMEOUT = 408,
- HTTP_STATUS_CONFLICT = 409,
- HTTP_STATUS_GONE = 410,
- HTTP_STATUS_LENGTH_REQUIRED = 411,
- HTTP_STATUS_PRECONDITION_FAILED = 412,
- HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE = 413,
- HTTP_STATUS_REQUEST_URI_TOO_LARGE = 414,
- HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
- HTTP_STATUS_REQUEST_RANGE_INVALID = 416,
- HTTP_STATUS_EXPECTATION_FAILED = 417,
- HTTP_STATUS_INTERNAL_ERROR = 500,
- HTTP_STATUS_NOT_IMPLEMENTED = 501,
- HTTP_STATUS_BAD_GATEWAY = 502,
- HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
- HTTP_STATUS_GATEWAY_TIMEOUT = 504,
- HTTP_STATUS_BAD_VERSION = 505
-};
-#if defined(__cplusplus)
-}
-#endif
-#endif /* !__H_HTTP_H */
-
-#endif /* ! KORE_NO_HTTP */
diff --git a/includes/jsonrpc.h b/includes/jsonrpc.h
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2016 Raphaƫl Monrouzeau <raphael.monrouzeau@gmail.com>
- *
- * 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.
- */
-
-#if !defined(KORE_NO_HTTP)
-
-#ifndef __H_JSONRPC_H
-#define __H_JSONRPC_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/* JSON RPC request handling log entry. */
-struct jsonrpc_log
-{
- char *msg;
- struct jsonrpc_log *next, *prev;
- int lvl;
-};
-
-/* JSON RPC request. */
-struct jsonrpc_request
-{
- struct jsonrpc_log log;
- struct kore_buf buf;
- struct http_request *http;
- yajl_gen gen;
- yajl_val json;
- yajl_val id;
- char *method;
- yajl_val params;
- unsigned int flags;
- int log_levels;
-};
-
-#define YAJL_GEN_CONST_STRING(CTX, STR) \
- yajl_gen_string((CTX), (unsigned char *)(STR), sizeof (STR) - 1)
-
-#define YAJL_GEN_CONST_NUMBER(CTX, STR) \
- yajl_gen_number((CTX), (unsigned char *)(STR), sizeof (STR) - 1)
-
-#define YAJL_GEN_KO(OPERATION) \
- ((OPERATION) != yajl_gen_status_ok)
-
-enum jsonrpc_error_code
-{
-#define JSONRPC_PARSE_ERROR_MSG "Parse error"
- JSONRPC_PARSE_ERROR = -32700,
-#define JSONRPC_INVALID_REQUEST_MSG "Invalid Request"
- JSONRPC_INVALID_REQUEST = -32600,
-#define JSONRPC_METHOD_NOT_FOUND_MSG "Method not found"
- JSONRPC_METHOD_NOT_FOUND = -32601,
-#define JSONRPC_INVALID_PARAMS_MSG "Invalid params"
- JSONRPC_INVALID_PARAMS = -32602,
-#define JSONRPC_INTERNAL_ERROR_MSG "Internal error"
- JSONRPC_INTERNAL_ERROR = -32603,
-#define JSONRPC_SERVER_ERROR_MSG "Server error"
- JSONRPC_SERVER_ERROR = -32000,
-#define JSONRPC_LIMIT_REACHED_MSG "Limit reached"
- JSONRPC_LIMIT_REACHED = -31997
-};
-
-void jsonrpc_log(struct jsonrpc_request *, int, const char *, ...);
-int jsonrpc_read_request(struct http_request *, struct jsonrpc_request *);
-void jsonrpc_destroy_request(struct jsonrpc_request *);
-int jsonrpc_error(struct jsonrpc_request *, int, const char *);
-int jsonrpc_result(struct jsonrpc_request *,
- int (*)(struct jsonrpc_request *, void *), void *);
-#if defined(__cplusplus)
-}
-#endif
-#endif /* !__H_JSONRPC_H */
-
-#endif /* ! KORE_NO_HTTP */
diff --git a/includes/kore.h b/includes/kore.h
@@ -1,716 +0,0 @@
-/*
- * Copyright (c) 2013-2018 Joris Vink <joris@coders.se>
- *
- * 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 <sys/types.h>
-#include <sys/time.h>
-#include <sys/queue.h>
-
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#if !defined(KORE_NO_TLS)
-#include <openssl/err.h>
-#include <openssl/dh.h>
-#include <openssl/ssl.h>
-#endif
-
-#include <errno.h>
-#include <regex.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-#include <stdarg.h>
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if defined(__APPLE__)
-#undef daemon
-extern int daemon(int, int);
-#endif
-
-#define KORE_RESULT_ERROR 0
-#define KORE_RESULT_OK 1
-#define KORE_RESULT_RETRY 2
-
-#define KORE_VERSION_MAJOR 2
-#define KORE_VERSION_MINOR 1
-#define KORE_VERSION_PATCH 0
-#define KORE_VERSION_STATE "devel"
-
-#define KORE_TLS_VERSION_1_2 0
-#define KORE_TLS_VERSION_1_0 1
-#define KORE_TLS_VERSION_BOTH 2
-
-#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_DEFAULT_CIPHER_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!kRSA:!kDSA"
-
-#if defined(KORE_DEBUG)
-#define kore_debug(...) \
- if (kore_debug) \
- kore_debug_internal(__FILE__, __LINE__, __VA_ARGS__)
-#else
-#define kore_debug(...)
-#endif
-
-#define NETBUF_RECV 0
-#define NETBUF_SEND 1
-#define NETBUF_SEND_PAYLOAD_MAX 8192
-
-#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 X509_GET_CN(c, o, l) \
- X509_NAME_get_text_by_NID(X509_get_subject_name(c), \
- NID_commonName, o, l)
-
-#define X509_CN_LENGTH (ub_common_name + 1)
-
-/* XXX hackish. */
-#if !defined(KORE_NO_HTTP)
-struct http_request;
-#endif
-
-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;
-
- void *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 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_READ_POSSIBLE 0x01
-#define CONN_WRITE_POSSIBLE 0x02
-#define CONN_WRITE_BLOCK 0x04
-#define CONN_IDLE_TIMER_ACT 0x10
-#define CONN_READ_BLOCK 0x20
-#define CONN_CLOSE_EMPTY 0x40
-#define CONN_WS_CLOSE_SENT 0x80
-
-#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_CONNECTION_PRUNE_DISCONNECT 0
-#define KORE_CONNECTION_PRUNE_ALL 1
-
-struct connection {
- u_int8_t type;
- int fd;
- u_int8_t state;
- u_int8_t proto;
- void *owner;
-#if !defined(KORE_NO_TLS)
- X509 *cert;
- SSL *ssl;
- int tls_reneg;
-#endif
- u_int8_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 *);
-
- u_int8_t addrtype;
- union {
- struct sockaddr_in ipv4;
- struct sockaddr_in6 ipv6;
- } 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)
- 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
-
-struct kore_runtime {
- int type;
-#if !defined(KORE_NO_HTTP)
- int (*http_request)(void *, struct http_request *);
- 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 (*connect)(void *, struct connection *);
-};
-
-struct kore_runtime_call {
- void *addr;
- struct kore_runtime *runtime;
-};
-
-extern struct kore_runtime kore_native_runtime;
-
-struct listener {
- u_int8_t type;
- u_int8_t addrtype;
- int fd;
- struct kore_runtime_call *connect;
-
- union {
- struct sockaddr_in ipv4;
- struct sockaddr_in6 ipv6;
- } addr;
-
- LIST_ENTRY(listener) list;
-};
-
-LIST_HEAD(listener_head, listener);
-
-#if !defined(KORE_NO_HTTP)
-
-#define KORE_PARAMS_QUERY_STRING 0x0001
-
-struct kore_handler_params {
- char *name;
- int flags;
- u_int8_t method;
- struct kore_validator *validator;
-
- TAILQ_ENTRY(kore_handler_params) list;
-};
-
-#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 0
-#define KORE_MODULE_PYTHON 1
-
-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;
- time_t mtime;
- struct kore_runtime_call *ocb;
-
- struct kore_module_functions *fun;
- struct kore_runtime *runtime;
-
- TAILQ_ENTRY(kore_module) list;
-};
-
-struct kore_module_handle {
- char *path;
- char *func;
- int type;
- int errors;
- regex_t rctx;
- struct kore_domain *dom;
- struct kore_runtime_call *rcall;
-#if !defined(KORE_NO_HTTP)
- struct kore_auth *auth;
- TAILQ_HEAD(, kore_handler_params) params;
-#endif
- TAILQ_ENTRY(kore_module_handle) list;
-};
-
-struct kore_worker {
- u_int8_t id;
- u_int8_t cpu;
- pid_t pid;
- int pipe[2];
- struct connection *msg[2];
- u_int8_t has_lock;
- u_int64_t time_locked;
- struct kore_module_handle *active_hdlr;
-};
-
-struct kore_domain {
- char *domain;
- int accesslog;
-#if !defined(KORE_NO_TLS)
- char *cafile;
- char *crlfile;
- char *certfile;
- char *certkey;
- SSL_CTX *ssl_ctx;
-#endif
- TAILQ_HEAD(, kore_module_handle) handlers;
- TAILQ_ENTRY(kore_domain) list;
-};
-
-TAILQ_HEAD(kore_domain_h, kore_domain);
-
-#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;
-};
-
-struct kore_pool_region {
- void *start;
- size_t length;
- LIST_ENTRY(kore_pool_region) list;
-};
-
-struct kore_pool_entry {
- u_int8_t state;
- struct kore_pool_region *region;
- LIST_ENTRY(kore_pool_entry) list;
-};
-
-struct kore_pool {
- size_t elen;
- size_t slen;
- size_t elms;
- size_t inuse;
- volatile int lock;
- char *name;
-
- LIST_HEAD(, kore_pool_region) regions;
- LIST_HEAD(, 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;
-};
-
-#define KORE_WORKER_KEYMGR 0
-
-/* Reserved message ids, registered on workers. */
-#define KORE_MSG_ACCESSLOG 1
-#define KORE_MSG_WEBSOCKET 2
-#define KORE_MSG_KEYMGR_REQ 3
-#define KORE_MSG_KEYMGR_RESP 4
-#define KORE_MSG_SHUTDOWN 5
-#define KORE_MSG_ENTROPY_REQ 6
-#define KORE_MSG_ENTROPY_RESP 7
-
-/* 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;
- u_int32_t length;
-};
-
-#if !defined(KORE_NO_TLS)
-struct kore_keyreq {
- int padding;
- char domain[KORE_DOMAINNAME_LEN];
- u_int8_t domain_len;
- u_int16_t data_len;
- u_int8_t data[];
-};
-#endif
-
-#if !defined(KORE_SINGLE_BINARY)
-extern char *config_file;
-#endif
-
-extern pid_t kore_pid;
-extern int foreground;
-extern int kore_debug;
-extern int skip_chroot;
-extern char *chroot_path;
-extern int skip_runas;
-extern char *runas_user;
-extern char *kore_pidfile;
-extern char *kore_tls_cipher_list;
-extern int tls_version;
-
-#if !defined(KORE_NO_TLS)
-extern DH *tls_dhparam;
-extern char *rand_file;
-#endif
-
-extern u_int8_t nlisteners;
-extern u_int16_t cpu_count;
-extern u_int8_t worker_count;
-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 listener_head listeners;
-extern struct kore_worker *worker;
-extern struct kore_domain_h domains;
-extern struct kore_domain *primary_dom;
-extern struct kore_pool nb_pool;
-
-void kore_signal(int);
-void kore_worker_wait(int);
-void kore_worker_init(void);
-void kore_worker_shutdown(void);
-void kore_worker_privdrop(void);
-void kore_worker_dispatch_signal(int);
-void kore_worker_spawn(u_int16_t, u_int16_t);
-void kore_worker_entry(struct kore_worker *);
-
-struct kore_worker *kore_worker_data(u_int8_t);
-
-void kore_platform_init(void);
-void kore_platform_event_init(void);
-void kore_platform_event_cleanup(void);
-void kore_platform_proctitle(char *);
-void kore_platform_disable_read(int);
-void kore_platform_enable_accept(void);
-void kore_platform_disable_accept(void);
-int kore_platform_event_wait(u_int64_t);
-void kore_platform_event_all(int, void *);
-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 *);
-
-void kore_accesslog_init(void);
-void kore_accesslog_worker_init(void);
-int kore_accesslog_write(const void *, u_int32_t);
-
-#if !defined(KORE_NO_HTTP)
-int kore_auth_run(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
-
-void kore_timer_init(void);
-u_int64_t kore_timer_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);
-
-int kore_sockopt(int, int, int);
-void kore_listener_cleanup(void);
-int kore_server_bind(const char *, const char *, const char *);
-#if !defined(KORE_NO_TLS)
-int kore_tls_sni_cb(SSL *, int *, void *);
-void kore_tls_info_callback(const SSL *, int, int);
-#endif
-
-void kore_connection_init(void);
-void kore_connection_cleanup(void);
-void kore_connection_prune(int);
-struct connection *kore_connection_new(void *);
-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 **);
-
-u_int64_t kore_time_ms(void);
-void kore_log_init(void);
-
-void *kore_malloc(size_t);
-void kore_parse_config(void);
-void *kore_calloc(size_t, size_t);
-void *kore_realloc(void *, size_t);
-void kore_free(void *);
-void kore_mem_init(void);
-void kore_mem_cleanup(void);
-void kore_mem_untag(void *);
-void *kore_mem_lookup(u_int32_t);
-void kore_mem_tag(void *, u_int32_t);
-void *kore_malloc_tagged(size_t, u_int32_t);
-
-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 *);
-
-time_t kore_date_to_time(char *);
-char *kore_time_to_date(time_t);
-char *kore_strdup(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(char *, const char, char **);
-int kore_snprintf(char *, size_t, int *, const char *, ...);
-long long kore_strtonum(const char *, int, long long, long long, int *);
-int kore_base64_encode(const void *, size_t, char **);
-int kore_base64_decode(const char *, u_int8_t **, size_t *);
-void *kore_mem_find(void *, size_t, void *, size_t);
-char *kore_text_trim(char *, size_t);
-char *kore_read_line(FILE *, char *, size_t);
-
-#if !defined(KORE_NO_HTTP)
-void kore_websocket_handshake(struct http_request *,
- const char *, const char *, const char *);
-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
-
-void kore_msg_init(void);
-void kore_msg_worker_init(void);
-void kore_msg_parent_init(void);
-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 *, u_int32_t);
-int kore_msg_register(u_int8_t,
- void (*cb)(struct kore_msg *, const void *));
-
-void kore_domain_init(void);
-void kore_domain_cleanup(void);
-int kore_domain_new(char *);
-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_tlsinit(struct kore_domain *);
-void kore_module_load(const char *, const char *, int);
-void kore_domain_callback(void (*cb)(struct kore_domain *));
-int kore_module_handler_new(const char *, const char *,
- const char *, const char *, int);
-void kore_module_handler_free(struct kore_module_handle *);
-
-struct kore_runtime_call *kore_runtime_getcall(const char *);
-
-void kore_runtime_execute(struct kore_runtime_call *);
-int kore_runtime_onload(struct kore_runtime_call *, int);
-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 *);
-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
-
-struct kore_domain *kore_domain_lookup(const char *);
-struct kore_module_handle *kore_module_handler_find(const char *,
- const char *);
-
-#if !defined(KORE_NO_HTTP)
-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
-
-void fatal(const char *, ...) __attribute__((noreturn));
-void kore_debug_internal(char *, int, const char *, ...);
-
-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);
-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_read_tls(struct connection *, size_t *);
-int net_write(struct connection *, size_t, size_t *);
-int net_write_tls(struct connection *, size_t, size_t *);
-void net_recv_reset(struct connection *, size_t,
- int (*cb)(struct netbuf *));
-void net_remove_netbuf(struct netbuf_head *, 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 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 *, ...);
-void kore_buf_appendv(struct kore_buf *, const char *, va_list);
-void kore_buf_replace_string(struct kore_buf *, char *, void *, size_t);
-
-void kore_keymgr_run(void);
-void kore_keymgr_cleanup(void);
-
-void kore_parent_configure(void);
-void kore_worker_configure(void);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* !__H_KORE_H */
diff --git a/includes/pgsql.h b/includes/pgsql.h
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2014-2018 Joris Vink <joris@coders.se>
- *
- * 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_PGSQL
-#define _H_KORE_PGSQL
-
-#include <libpq-fe.h>
-
-#define KORE_PGSQL_FORMAT_TEXT 0
-#define KORE_PGSQL_FORMAT_BINARY 1
-
-#define KORE_PGSQL_SYNC 0x0001
-#define KORE_PGSQL_ASYNC 0x0002
-#define KORE_PGSQL_SCHEDULED 0x0004
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-struct pgsql_conn {
- u_int8_t type;
- u_int8_t flags;
- char *name;
-
- PGconn *db;
- struct pgsql_job *job;
- TAILQ_ENTRY(pgsql_conn) list;
-};
-
-struct pgsql_db {
- char *name;
- char *conn_string;
- u_int16_t conn_max;
- u_int16_t conn_count;
-
- LIST_ENTRY(pgsql_db) rlist;
-};
-
-struct kore_pgsql {
- u_int8_t state;
- int flags;
- char *error;
- PGresult *result;
- struct pgsql_conn *conn;
-
- struct http_request *req;
- void *arg;
- void (*cb)(struct kore_pgsql *, void *);
-
- LIST_ENTRY(kore_pgsql) rlist;
-};
-
-extern u_int16_t pgsql_conn_max;
-extern u_int32_t pgsql_queue_limit;
-
-void kore_pgsql_sys_init(void);
-void kore_pgsql_sys_cleanup(void);
-void kore_pgsql_init(struct kore_pgsql *);
-void kore_pgsql_bind_request(struct kore_pgsql *, struct http_request *);
-void kore_pgsql_bind_callback(struct kore_pgsql *,
- void (*cb)(struct kore_pgsql *, void *), void *);
-int kore_pgsql_setup(struct kore_pgsql *, const char *, int);
-void kore_pgsql_handle(void *, int);
-void kore_pgsql_cleanup(struct kore_pgsql *);
-void kore_pgsql_continue(struct kore_pgsql *);
-int kore_pgsql_query(struct kore_pgsql *, const char *);
-int kore_pgsql_query_params(struct kore_pgsql *,
- const char *, int, int, ...);
-int kore_pgsql_v_query_params(struct kore_pgsql *,
- const char *, int, int, va_list);
-int kore_pgsql_register(const char *, const char *);
-int kore_pgsql_ntuples(struct kore_pgsql *);
-int kore_pgsql_nfields(struct kore_pgsql *);
-void kore_pgsql_logerror(struct kore_pgsql *);
-char *kore_pgsql_fieldname(struct kore_pgsql *, int);
-char *kore_pgsql_getvalue(struct kore_pgsql *, int, int);
-int kore_pgsql_getlength(struct kore_pgsql *, int, int);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#define KORE_PGSQL_STATE_INIT 1
-#define KORE_PGSQL_STATE_WAIT 2
-#define KORE_PGSQL_STATE_RESULT 3
-#define KORE_PGSQL_STATE_ERROR 4
-#define KORE_PGSQL_STATE_DONE 5
-#define KORE_PGSQL_STATE_COMPLETE 6
-
-#endif
diff --git a/includes/python_api.h b/includes/python_api.h
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2016 Stanislav Yudin <stan@endlessinsomnia.com>
- * Copyright (c) 2017-2018 Joris Vink <joris@coders.se>
- *
- * 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_PYTHON_H
-#define __H_PYTHON_H
-
-#undef _POSIX_C_SOURCE
-#undef _XOPEN_SOURCE
-
-#include <Python.h>
-
-void kore_python_init(void);
-void kore_python_cleanup(void);
-void kore_python_path(const char *);
-
-PyObject *kore_python_callable(PyObject *, const char *);
-
-extern struct kore_module_functions kore_python_module;
-extern struct kore_runtime kore_python_runtime;
-
-#endif
diff --git a/includes/python_methods.h b/includes/python_methods.h
@@ -1,229 +0,0 @@
-/*
- * Copyright (c) 2017-2018 Joris Vink <joris@coders.se>
- *
- * 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.
- */
-
-static PyObject *python_kore_log(PyObject *, PyObject *);
-static PyObject *python_kore_fatal(PyObject *, PyObject *);
-static PyObject *python_kore_listen(PyObject *, PyObject *);
-
-#if defined(KORE_USE_PGSQL)
-static PyObject *python_kore_pgsql_register(PyObject *, PyObject *);
-#endif
-
-static PyObject *python_websocket_broadcast(PyObject *, PyObject *);
-
-#define METHOD(n, c, a) { n, (PyCFunction)c, a, NULL }
-#define GETTER(n, g) { n, (getter)g, NULL, NULL, NULL }
-#define SETTER(n, s) { n, NULL, (setter)g, NULL, NULL }
-#define GETSET(n, g, s) { n, (getter)g, (setter)s, NULL, NULL }
-
-static struct PyMethodDef pykore_methods[] = {
- METHOD("log", python_kore_log, METH_VARARGS),
- METHOD("fatal", python_kore_fatal, METH_VARARGS),
- METHOD("listen", python_kore_listen, METH_VARARGS),
- METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS),
-#if defined(KORE_USE_PGSQL)
- METHOD("register_database", python_kore_pgsql_register, METH_VARARGS),
-#endif
- { NULL, NULL, 0, NULL }
-};
-
-static struct PyModuleDef pykore_module = {
- PyModuleDef_HEAD_INIT, "kore", NULL, -1, pykore_methods
-};
-
-struct pyconnection {
- PyObject_HEAD
- struct connection *c;
-};
-
-static PyObject *pyconnection_disconnect(struct pyconnection *, PyObject *);
-static PyObject *pyconnection_websocket_send(struct pyconnection *, PyObject *);
-
-static PyMethodDef pyconnection_methods[] = {
- METHOD("disconnect", pyconnection_disconnect, METH_NOARGS),
- METHOD("websocket_send", pyconnection_websocket_send, METH_VARARGS),
- METHOD(NULL, NULL, -1),
-};
-
-static PyObject *pyconnection_get_fd(struct pyconnection *, void *);
-static PyObject *pyconnection_get_addr(struct pyconnection *, void *);
-
-static PyGetSetDef pyconnection_getset[] = {
- GETTER("fd", pyconnection_get_fd),
- GETTER("addr", pyconnection_get_addr),
- GETTER(NULL, NULL),
-};
-
-static void pyconnection_dealloc(struct pyconnection *);
-
-static PyTypeObject pyconnection_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "kore.connection",
- .tp_doc = "struct connection",
- .tp_getset = pyconnection_getset,
- .tp_methods = pyconnection_methods,
- .tp_basicsize = sizeof(struct pyconnection),
- .tp_dealloc = (destructor)pyconnection_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-};
-
-struct pyhttp_request {
- PyObject_HEAD
- struct http_request *req;
- PyObject *data;
-};
-
-struct pyhttp_file {
- PyObject_HEAD
- struct http_file *file;
-};
-
-static void pyhttp_dealloc(struct pyhttp_request *);
-static void pyhttp_file_dealloc(struct pyhttp_file *);
-
-#if defined(KORE_USE_PGSQL)
-static PyObject *pyhttp_pgsql(struct pyhttp_request *, PyObject *);
-#endif
-static PyObject *pyhttp_cookie(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_response(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_argument(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_body_read(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_file_lookup(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_populate_get(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_populate_post(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_populate_multi(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_populate_cookies(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_request_header(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_response_header(struct pyhttp_request *, PyObject *);
-static PyObject *pyhttp_websocket_handshake(struct pyhttp_request *,
- PyObject *);
-
-static PyMethodDef pyhttp_request_methods[] = {
-#if defined(KORE_USE_PGSQL)
- METHOD("pgsql", pyhttp_pgsql, METH_VARARGS),
-#endif
- METHOD("cookie", pyhttp_cookie, METH_VARARGS),
- METHOD("response", pyhttp_response, METH_VARARGS),
- METHOD("argument", pyhttp_argument, METH_VARARGS),
- METHOD("body_read", pyhttp_body_read, METH_VARARGS),
- METHOD("file_lookup", pyhttp_file_lookup, METH_VARARGS),
- METHOD("populate_get", pyhttp_populate_get, METH_NOARGS),
- METHOD("populate_post", pyhttp_populate_post, METH_NOARGS),
- METHOD("populate_multi", pyhttp_populate_multi, METH_NOARGS),
- METHOD("populate_cookies", pyhttp_populate_cookies, METH_NOARGS),
- METHOD("request_header", pyhttp_request_header, METH_VARARGS),
- METHOD("response_header", pyhttp_response_header, METH_VARARGS),
- METHOD("websocket_handshake", pyhttp_websocket_handshake, METH_VARARGS),
- METHOD(NULL, NULL, -1)
-};
-
-static PyObject *pyhttp_get_host(struct pyhttp_request *, void *);
-static PyObject *pyhttp_get_path(struct pyhttp_request *, void *);
-static PyObject *pyhttp_get_body(struct pyhttp_request *, void *);
-static PyObject *pyhttp_get_agent(struct pyhttp_request *, void *);
-static PyObject *pyhttp_get_method(struct pyhttp_request *, void *);
-static PyObject *pyhttp_get_body_path(struct pyhttp_request *, void *);
-static PyObject *pyhttp_get_connection(struct pyhttp_request *, void *);
-
-static PyGetSetDef pyhttp_request_getset[] = {
- GETTER("host", pyhttp_get_host),
- GETTER("path", pyhttp_get_path),
- GETTER("body", pyhttp_get_body),
- GETTER("agent", pyhttp_get_agent),
- GETTER("method", pyhttp_get_method),
- GETTER("body_path", pyhttp_get_body_path),
- GETTER("connection", pyhttp_get_connection),
- GETTER(NULL, NULL)
-};
-
-static PyTypeObject pyhttp_request_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "kore.http_request",
- .tp_doc = "struct http_request",
- .tp_getset = pyhttp_request_getset,
- .tp_methods = pyhttp_request_methods,
- .tp_dealloc = (destructor)pyhttp_dealloc,
- .tp_basicsize = sizeof(struct pyhttp_request),
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-};
-
-static PyObject *pyhttp_file_read(struct pyhttp_file *, PyObject *);
-
-static PyMethodDef pyhttp_file_methods[] = {
- METHOD("read", pyhttp_file_read, METH_VARARGS),
- METHOD(NULL, NULL, -1)
-};
-
-static PyObject *pyhttp_file_get_name(struct pyhttp_file *, void *);
-static PyObject *pyhttp_file_get_filename(struct pyhttp_file *, void *);
-
-static PyGetSetDef pyhttp_file_getset[] = {
- GETTER("name", pyhttp_file_get_name),
- GETTER("filename", pyhttp_file_get_filename),
- GETTER(NULL, NULL)
-};
-
-static PyTypeObject pyhttp_file_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "kore.http_file",
- .tp_doc = "struct http_file",
- .tp_getset = pyhttp_file_getset,
- .tp_methods = pyhttp_file_methods,
- .tp_dealloc = (destructor)pyhttp_file_dealloc,
- .tp_basicsize = sizeof(struct pyhttp_file),
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-};
-
-#if defined(KORE_USE_PGSQL)
-
-#define PYKORE_PGSQL_PREINIT 1
-#define PYKORE_PGSQL_INITIALIZE 2
-#define PYKORE_PGSQL_QUERY 3
-#define PYKORE_PGSQL_WAIT 4
-
-struct pykore_pgsql {
- PyObject_HEAD
- int state;
- char *db;
- char *query;
- struct http_request *req;
- PyObject *result;
- struct kore_pgsql sql;
-};
-
-static void pykore_pgsql_dealloc(struct pykore_pgsql *);
-int pykore_pgsql_result(struct pykore_pgsql *);
-
-static PyObject *pykore_pgsql_await(PyObject *);
-static PyObject *pykore_pgsql_iternext(struct pykore_pgsql *);
-
-static PyAsyncMethods pykore_pgsql_async = {
- (unaryfunc)pykore_pgsql_await,
- NULL,
- NULL
-};
-
-static PyTypeObject pykore_pgsql_type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "kore.pgsql",
- .tp_doc = "struct kore_pgsql",
- .tp_as_async = &pykore_pgsql_async,
- .tp_iternext = (iternextfunc)pykore_pgsql_iternext,
- .tp_basicsize = sizeof(struct pykore_pgsql),
- .tp_dealloc = (destructor)pykore_pgsql_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
-};
-#endif
diff --git a/includes/tasks.h b/includes/tasks.h
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2014 Joris Vink <joris@coders.se>
- *
- * 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_TASKS
-#define __H_KORE_TASKS
-
-#include <pthread.h>
-
-#define KORE_TASK_STATE_CREATED 1
-#define KORE_TASK_STATE_RUNNING 2
-#define KORE_TASK_STATE_FINISHED 3
-#define KORE_TASK_STATE_ABORT 4
-
-#define KORE_TASK_THREADS 2
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#if !defined(KORE_NO_HTTP)
-struct http_request;
-#endif
-
-struct kore_task {
- u_int8_t type;
- int state;
- int result;
- pthread_rwlock_t lock;
-
-#if !defined(KORE_NO_HTTP)
- struct http_request *req;
-#endif
-
- int fds[2];
- int (*entry)(struct kore_task *);
- void (*cb)(struct kore_task *);
-
- struct kore_task_thread *thread;
-
- TAILQ_ENTRY(kore_task) list;
- LIST_ENTRY(kore_task) rlist;
-};
-
-struct kore_task_thread {
- u_int8_t idx;
- pthread_t tid;
- pthread_mutex_t lock;
- pthread_cond_t cond;
- TAILQ_HEAD(, kore_task) tasks;
-
- TAILQ_ENTRY(kore_task_thread) list;
-};
-
-void kore_task_init(void);
-void kore_task_run(struct kore_task *);
-void kore_task_finish(struct kore_task *);
-void kore_task_destroy(struct kore_task *);
-int kore_task_finished(struct kore_task *);
-void kore_task_handle(struct kore_task *, int);
-
-#if !defined(KORE_NO_HTTP)
-void kore_task_bind_request(struct kore_task *,
- struct http_request *);
-#endif
-void kore_task_bind_callback(struct kore_task *,
- void (*cb)(struct kore_task *));
-void kore_task_create(struct kore_task *,
- int (*entry)(struct kore_task *));
-
-u_int32_t kore_task_channel_read(struct kore_task *, void *, u_int32_t);
-void kore_task_channel_write(struct kore_task *, void *, u_int32_t);
-
-void kore_task_set_state(struct kore_task *, int);
-void kore_task_set_result(struct kore_task *, int);
-
-int kore_task_state(struct kore_task *);
-int kore_task_result(struct kore_task *);
-
-extern u_int16_t kore_task_threads;
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif