kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

commit 46375303cb94e1b209216ab1bec90b0b01aba555
parent 5c18f4ac415b8b95b9bf5c94133a4bc44457ca30
Author: Joris Vink <joris@coders.se>
Date:   Fri, 27 Sep 2019 20:00:35 +0200

Allow multiple binds on new server directive.

Diffstat:
examples/async-curl/conf/async-curl.conf | 2+-
examples/cookies/conf/cookies.conf | 2+-
examples/cpp/conf/cpp.conf | 2+-
examples/generic/conf/generic.conf | 2+-
examples/headers/conf/headers.conf | 2+-
examples/integers/conf/integers.conf | 2+-
examples/json_yajl/conf/json_yajl.conf | 2+-
examples/jsonrpc/conf/jsonrpc.conf | 2+-
examples/memtag/conf/memtag.conf | 2+-
examples/messaging/conf/messaging.conf | 2+-
examples/nohttp/conf/nohttp.conf | 2+-
examples/parameters/conf/parameters.conf | 2+-
examples/pgsql-sync/conf/pgsql-sync.conf | 2+-
examples/pgsql/conf/pgsql.conf | 4++--
examples/pipe_task/conf/pipe_task.conf | 2+-
examples/python-async/conf/python-async.conf | 2+-
examples/python-pgsql/kore.conf | 2+-
examples/sse/conf/sse.conf | 2+-
examples/tasks/conf/tasks.conf | 2+-
examples/tls-proxy/conf/tls-proxy.conf | 2+-
examples/upload/conf/upload.conf | 2+-
examples/video_stream/conf/video_stream.conf | 2+-
examples/websocket/conf/websocket.conf | 2+-
include/kore/kore.h | 47++++++++++++++++++++++++++++++-----------------
include/kore/python_methods.h | 4++--
src/bsd.c | 31++++++++++++++++++++++---------
src/cli.c | 2+-
src/config.c | 77++++++++++++++++++++++++++++++++++-------------------------------------------
src/connection.c | 2+-
src/domain.c | 34+++++++++++++++++-----------------
src/filemap.c | 6++++--
src/fileref.c | 8++++----
src/keymgr.c | 20++++++++++----------
src/kore.c | 142++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
src/linux.c | 18+++++++++++++-----
src/module.c | 8++++----
src/net.c | 2+-
src/python.c | 30++++++++++++++++--------------
src/worker.c | 11++++++++---
39 files changed, 289 insertions(+), 201 deletions(-)

diff --git a/examples/async-curl/conf/async-curl.conf b/examples/async-curl/conf/async-curl.conf @@ -1,6 +1,6 @@ # ht configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/cookies/conf/cookies.conf b/examples/cookies/conf/cookies.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/cpp/conf/cpp.conf b/examples/cpp/conf/cpp.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/generic/conf/generic.conf b/examples/generic/conf/generic.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/headers/conf/headers.conf b/examples/headers/conf/headers.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/integers/conf/integers.conf b/examples/integers/conf/integers.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/json_yajl/conf/json_yajl.conf b/examples/json_yajl/conf/json_yajl.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/jsonrpc/conf/jsonrpc.conf b/examples/jsonrpc/conf/jsonrpc.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/memtag/conf/memtag.conf b/examples/memtag/conf/memtag.conf @@ -1,6 +1,6 @@ # memtag configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/messaging/conf/messaging.conf b/examples/messaging/conf/messaging.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/nohttp/conf/nohttp.conf b/examples/nohttp/conf/nohttp.conf @@ -2,7 +2,7 @@ load ./nohttp.so -listen tls { +server tls { bind 127.0.0.1 8888 connection_setup } diff --git a/examples/parameters/conf/parameters.conf b/examples/parameters/conf/parameters.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/pgsql-sync/conf/pgsql-sync.conf b/examples/pgsql-sync/conf/pgsql-sync.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/pgsql/conf/pgsql.conf b/examples/pgsql/conf/pgsql.conf @@ -2,11 +2,11 @@ load ./pgsql.so init -listen tls { +server tls { bind 127.0.0.1 8888 } -listen other { +server other { bind 127.0.0.1 8889 connection_new } diff --git a/examples/pipe_task/conf/pipe_task.conf b/examples/pipe_task/conf/pipe_task.conf @@ -1,6 +1,6 @@ # Kore pipe_task example -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/python-async/conf/python-async.conf b/examples/python-async/conf/python-async.conf @@ -1,6 +1,6 @@ # python-async configuration -listen notls { +server notls { tls no bind 127.0.0.1 8888 } diff --git a/examples/python-pgsql/kore.conf b/examples/python-pgsql/kore.conf @@ -1,6 +1,6 @@ # sql configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/sse/conf/sse.conf b/examples/sse/conf/sse.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/tasks/conf/tasks.conf b/examples/tasks/conf/tasks.conf @@ -1,6 +1,6 @@ # Kore config for tasks example -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/tls-proxy/conf/tls-proxy.conf b/examples/tls-proxy/conf/tls-proxy.conf @@ -8,7 +8,7 @@ tls_dhparam dh2048.pem # connection we receive we will call client_setup # so it can kick things in action. # -listen tls { +server tls { bind 127.0.0.1 8888 client_setup } diff --git a/examples/upload/conf/upload.conf b/examples/upload/conf/upload.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/video_stream/conf/video_stream.conf b/examples/video_stream/conf/video_stream.conf @@ -1,6 +1,6 @@ # Placeholder configuration -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/examples/websocket/conf/websocket.conf b/examples/websocket/conf/websocket.conf @@ -1,6 +1,6 @@ # Kore websocket example -listen tls { +server tls { bind 127.0.0.1 8888 } diff --git a/include/kore/kore.h b/include/kore/kore.h @@ -288,7 +288,7 @@ struct kore_domain { char *domain; struct kore_buf *logbuf; - struct listener *listener; + struct kore_server *server; char *cafile; char *crlfile; @@ -309,16 +309,24 @@ extern struct kore_runtime kore_native_runtime; struct listener { struct kore_event evt; int fd; - int tls; int family; + char *port; + char *host; + struct kore_server *server; struct kore_runtime_call *connect; + + LIST_ENTRY(listener) list; +}; + +struct kore_server { + int tls; char *name; struct kore_domain_h domains; - - LIST_ENTRY(listener) list; + LIST_HEAD(, listener) listeners; + LIST_ENTRY(kore_server) list; }; -LIST_HEAD(listener_head, listener); +LIST_HEAD(kore_server_list, kore_server); #if !defined(KORE_NO_HTTP) @@ -568,10 +576,10 @@ 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 *primary_dom; extern struct kore_pool nb_pool; +extern struct kore_domain *primary_dom; +extern struct kore_server_list kore_servers; void kore_signal(int); void kore_shutdown(void); @@ -636,18 +644,24 @@ void kore_timer_remove(struct kore_timer *); struct kore_timer *kore_timer_add(void (*cb)(void *, u_int64_t), u_int64_t, void *, int); -void kore_listener_cleanup(void); -void kore_listener_closeall(void); +void kore_server_closeall(void); +void kore_server_cleanup(void); +void kore_server_free(struct kore_server *); +void kore_server_finalize(struct kore_server *); + +struct kore_server *kore_server_create(const char *); +struct kore_server *kore_server_lookup(const char *); + void kore_listener_accept(void *, int); -struct listener *kore_listener_create(const char *); struct listener *kore_listener_lookup(const char *); void kore_listener_free(struct listener *); +struct listener *kore_listener_create(struct kore_server *); int kore_listener_init(struct listener *, int, const char *); int kore_sockopt(int, int, int); -int kore_server_bind_unix(struct listener *, +int kore_server_bind_unix(struct kore_server *, const char *, const char *); -int kore_server_bind(struct listener *, +int kore_server_bind(struct kore_server *, const char *, const char *, const char *); int kore_tls_sni_cb(SSL *, int *, void *); @@ -745,7 +759,7 @@ extern char *kore_filemap_index; void kore_fileref_init(void); struct kore_fileref *kore_fileref_get(const char *, int); -struct kore_fileref *kore_fileref_create(struct connection *, +struct kore_fileref *kore_fileref_create(struct kore_server *, const char *, int, off_t, struct timespec *); void kore_fileref_release(struct kore_fileref *); @@ -764,7 +778,7 @@ void *kore_module_getsym(const char *, struct kore_runtime **); void kore_domain_load_crl(void); void kore_domain_keymgr_init(void); void kore_domain_callback(void (*cb)(struct kore_domain *)); -int kore_domain_attach(struct listener *, struct kore_domain *); +int kore_domain_attach(struct kore_domain *, struct kore_server *); void kore_domain_tlsinit(struct kore_domain *, const void *, size_t); void kore_domain_crl_add(struct kore_domain *, const void *, size_t); #if !defined(KORE_NO_HTTP) @@ -795,9 +809,8 @@ void kore_runtime_wsmessage(struct kore_runtime_call *, struct connection *, u_int8_t, const void *, size_t); #endif -struct kore_domain *kore_domain_byid(u_int16_t); -struct kore_domain *kore_domain_lookup(struct listener *, - const char *); +struct kore_domain *kore_domain_byid(u_int16_t); +struct kore_domain *kore_domain_lookup(struct kore_server *, const char *); #if !defined(KORE_NO_HTTP) void kore_validator_init(void); diff --git a/include/kore/python_methods.h b/include/kore/python_methods.h @@ -56,7 +56,7 @@ static PyObject *python_kore_socket_wrap(PyObject *, PyObject *); static PyObject *python_kore_domain(PyObject *, PyObject *, PyObject *); static PyObject *python_kore_gather(PyObject *, PyObject *, PyObject *); -static PyObject *python_kore_listen(PyObject *, PyObject *, +static PyObject *python_kore_server(PyObject *, PyObject *, PyObject *); #if defined(KORE_USE_PGSQL) @@ -97,7 +97,7 @@ static struct PyMethodDef pykore_methods[] = { METHOD("prerequest", python_kore_prerequest, METH_VARARGS), METHOD("task_create", python_kore_task_create, METH_VARARGS), METHOD("socket_wrap", python_kore_socket_wrap, METH_VARARGS), - METHOD("listen", python_kore_listen, METH_VARARGS | METH_KEYWORDS), + METHOD("server", python_kore_server, METH_VARARGS | METH_KEYWORDS), METHOD("gather", python_kore_gather, METH_VARARGS | METH_KEYWORDS), METHOD("domain", python_kore_domain, METH_VARARGS | METH_KEYWORDS), METHOD("websocket_broadcast", python_websocket_broadcast, METH_VARARGS), diff --git a/src/bsd.c b/src/bsd.c @@ -79,6 +79,7 @@ void kore_platform_event_init(void) { struct listener *l; + struct kore_server *srv; if (kfd != -1) close(kfd); @@ -93,11 +94,13 @@ kore_platform_event_init(void) /* Hack to check if we're running under the parent or not. */ if (worker != NULL) { - LIST_FOREACH(l, &listeners, list) { - if (l->fd == -1) - continue; - kore_platform_event_schedule(l->fd, - EVFILT_READ, EV_ADD | EV_DISABLE, l); + LIST_FOREACH(srv, &kore_servers, list) { + LIST_FOREACH(l, &srv->listeners, list) { + if (l->fd == -1) + continue; + kore_platform_event_schedule(l->fd, + EVFILT_READ, EV_ADD | EV_DISABLE, l); + } } } } @@ -184,18 +187,28 @@ void kore_platform_enable_accept(void) { struct listener *l; + struct kore_server *srv; - LIST_FOREACH(l, &listeners, list) - kore_platform_event_schedule(l->fd, EVFILT_READ, EV_ENABLE, l); + LIST_FOREACH(srv, &kore_servers, list) { + LIST_FOREACH(l, &srv->listeners, list) { + kore_platform_event_schedule(l->fd, + EVFILT_READ, EV_ENABLE, l); + } + } } void kore_platform_disable_accept(void) { struct listener *l; + struct kore_server *srv; - LIST_FOREACH(l, &listeners, list) - kore_platform_event_schedule(l->fd, EVFILT_READ, EV_DISABLE, l); + LIST_FOREACH(srv, &kore_servers, list) { + LIST_FOREACH(l, &srv->listeners, list) { + kore_platform_event_schedule(l->fd, + EVFILT_READ, EV_DISABLE, l); + } + } } void diff --git a/src/cli.c b/src/cli.c @@ -273,7 +273,7 @@ static const char *src_data = static const char *config_data = "# %s configuration\n" "\n" - "listen tls {\n" + "server tls {\n" "\tbind 127.0.0.1 8888\n" "}\n" "\n" diff --git a/src/config.c b/src/config.c @@ -58,7 +58,7 @@ static int configure_file(char *); #endif static int configure_tls(char *); -static int configure_listen(char *); +static int configure_server(char *); static int configure_include(char *); static int configure_bind(char *); static int configure_bind_unix(char *); @@ -147,7 +147,7 @@ static struct { int (*configure)(char *); } config_directives[] = { { "tls", configure_tls }, - { "listen", configure_listen }, + { "server", configure_server }, { "include", configure_include }, { "bind", configure_bind }, { "unix", configure_bind_unix }, @@ -256,7 +256,7 @@ static struct kore_module_handle *current_handler = NULL; extern const char *__progname; static struct kore_domain *current_domain = NULL; -static struct listener *current_listener = NULL; +static struct kore_server *current_server = NULL; void kore_parse_config(void) @@ -351,9 +351,10 @@ kore_parse_config_file(FILE *fp) continue; } - if (!strcmp(p, "}") && current_listener != NULL) { + if (!strcmp(p, "}") && current_server != NULL) { lineno++; - current_listener = NULL; + kore_server_finalize(current_server); + current_server = NULL; continue; } @@ -379,12 +380,12 @@ kore_parse_config_file(FILE *fp) #endif if (!strcmp(p, "}") && current_domain != NULL) { - if (current_domain->listener == NULL) { - fatal("domain '%s' not attached to listener", + if (current_domain->server == NULL) { + fatal("domain '%s' not attached to server", current_domain->domain); } - if (current_domain->listener->tls == 1 && + if (current_domain->server->tls == 1 && (current_domain->certfile == NULL || current_domain->certkey == NULL)) { fatal("incomplete TLS setup for '%s'", @@ -481,34 +482,34 @@ configure_include(char *path) } static int -configure_listen(char *options) +configure_server(char *options) { - struct listener *l; + struct kore_server *srv; char *argv[3]; - if (current_listener != NULL) { - printf("nested listener contexts are not allowed\n"); + if (current_server != NULL) { + printf("nested server contexts are not allowed\n"); return (KORE_RESULT_ERROR); } kore_split_string(options, " ", argv, 3); if (argv[0] == NULL || argv[1] == NULL) { - printf("invalid listener context\n"); + printf("invalid server context\n"); return (KORE_RESULT_ERROR); } if (strcmp(argv[1], "{")) { - printf("listener context not opened correctly\n"); + printf("server context not opened correctly\n"); return (KORE_RESULT_ERROR); } - if ((l = kore_listener_lookup(argv[0])) != NULL) { - printf("a listener with name '%s' already exists\n", l->name); + if ((srv = kore_server_lookup(argv[0])) != NULL) { + printf("a server with name '%s' already exists\n", srv->name); return (KORE_RESULT_ERROR); } - current_listener = kore_listener_create(argv[0]); + current_server = kore_server_create(argv[0]); return (KORE_RESULT_OK); } @@ -516,15 +517,15 @@ configure_listen(char *options) static int configure_tls(char *yesno) { - if (current_listener == NULL) { - printf("bind directive not inside a listener context\n"); + if (current_server == NULL) { + printf("bind directive not inside a server context\n"); return (KORE_RESULT_ERROR); } if (!strcmp(yesno, "no")) { - current_listener->tls = 0; + current_server->tls = 0; } else if (!strcmp(yesno, "yes")) { - current_listener->tls = 1; + current_server->tls = 1; } else { printf("invalid '%s' for yes|no tls option\n", yesno); return (KORE_RESULT_ERROR); @@ -538,13 +539,8 @@ configure_bind(char *options) { char *argv[4]; - if (current_listener == NULL) { - printf("bind directive not inside a listener context\n"); - return (KORE_RESULT_ERROR); - } - - if (current_listener->fd != -1) { - printf("listener '%s' already bound\n", current_listener->name); + if (current_server == NULL) { + printf("bind directive not inside a server context\n"); return (KORE_RESULT_ERROR); } @@ -552,7 +548,7 @@ configure_bind(char *options) if (argv[0] == NULL || argv[1] == NULL) return (KORE_RESULT_ERROR); - return (kore_server_bind(current_listener, argv[0], argv[1], argv[2])); + return (kore_server_bind(current_server, argv[0], argv[1], argv[2])); } static int @@ -560,13 +556,8 @@ configure_bind_unix(char *options) { char *argv[3]; - if (current_listener == NULL) { - printf("bind_unix directive not inside a listener context\n"); - return (KORE_RESULT_ERROR); - } - - if (current_listener->fd != -1) { - printf("listener '%s' already bound\n", current_listener->name); + if (current_server == NULL) { + printf("bind_unix directive not inside a server context\n"); return (KORE_RESULT_ERROR); } @@ -574,7 +565,7 @@ configure_bind_unix(char *options) if (argv[0] == NULL) return (KORE_RESULT_ERROR); - return (kore_server_bind_unix(current_listener, argv[0], argv[1])); + return (kore_server_bind_unix(current_server, argv[0], argv[1])); } static int @@ -848,25 +839,25 @@ configure_domain(char *options) static int configure_attach(char *name) { - struct listener *l; + struct kore_server *srv; if (current_domain == NULL) { printf("attach not specified in domain context\n"); return (KORE_RESULT_ERROR); } - if (current_domain->listener != NULL) { - printf("domain '%s' already attached to listener\n", + if (current_domain->server != NULL) { + printf("domain '%s' already attached to server\n", current_domain->domain); return (KORE_RESULT_ERROR); } - if ((l = kore_listener_lookup(name)) == NULL) { - printf("listener '%s' does not exist\n", name); + if ((srv = kore_server_lookup(name)) == NULL) { + printf("server '%s' does not exist\n", name); return (KORE_RESULT_ERROR); } - if (!kore_domain_attach(l, current_domain)) { + if (!kore_domain_attach(current_domain, srv)) { printf("failed to attach '%s' to '%s'\n", current_domain->domain, name); return (KORE_RESULT_ERROR); diff --git a/src/connection.c b/src/connection.c @@ -144,7 +144,7 @@ kore_connection_accept(struct listener *listener, struct connection **out) c->handle = kore_connection_handle; TAILQ_INSERT_TAIL(&connections, c, list); - if (listener->tls) { + if (listener->server->tls) { c->state = CONN_STATE_TLS_SHAKE; c->write = net_write_tls; c->read = net_read_tls; diff --git a/src/domain.c b/src/domain.c @@ -199,20 +199,20 @@ kore_domain_new(const char *domain) } int -kore_domain_attach(struct listener *l, struct kore_domain *dom) +kore_domain_attach(struct kore_domain *dom, struct kore_server *server) { struct kore_domain *d; - if (dom->listener != NULL) + if (dom->server != NULL) return (KORE_RESULT_ERROR); - TAILQ_FOREACH(d, &l->domains, list) { + TAILQ_FOREACH(d, &server->domains, list) { if (!strcmp(d->domain, dom->domain)) return (KORE_RESULT_ERROR); } - dom->listener = l; - TAILQ_INSERT_TAIL(&l->domains, dom, list); + dom->server = server; + TAILQ_INSERT_TAIL(&server->domains, dom, list); return (KORE_RESULT_OK); } @@ -229,7 +229,7 @@ kore_domain_free(struct kore_domain *dom) if (primary_dom == dom) primary_dom = NULL; - TAILQ_REMOVE(&dom->listener->domains, dom, list); + TAILQ_REMOVE(&dom->server->domains, dom, list); if (dom->domain != NULL) kore_free(dom->domain); @@ -472,22 +472,22 @@ kore_domain_crl_add(struct kore_domain *dom, const void *pem, size_t pemlen) void kore_domain_callback(void (*cb)(struct kore_domain *)) { - struct listener *l; + struct kore_server *srv; struct kore_domain *dom; - LIST_FOREACH(l, &listeners, list) { - TAILQ_FOREACH(dom, &l->domains, list) { + LIST_FOREACH(srv, &kore_servers, list) { + TAILQ_FOREACH(dom, &srv->domains, list) { cb(dom); } } } struct kore_domain * -kore_domain_lookup(struct listener *l, const char *domain) +kore_domain_lookup(struct kore_server *srv, const char *domain) { struct kore_domain *dom; - TAILQ_FOREACH(dom, &l->domains, list) { + TAILQ_FOREACH(dom, &srv->domains, list) { if (!strcmp(dom->domain, domain)) return (dom); if (!fnmatch(dom->domain, domain, FNM_CASEFOLD)) @@ -500,14 +500,14 @@ kore_domain_lookup(struct listener *l, const char *domain) struct kore_domain * kore_domain_byid(u_int16_t id) { - struct listener *l; + struct kore_server *srv; struct kore_domain *dom; if (id < KORE_DOMAIN_CACHE) return (cached[id]); - LIST_FOREACH(l, &listeners, list) { - TAILQ_FOREACH(dom, &l->domains, list) { + LIST_FOREACH(srv, &kore_servers, list) { + TAILQ_FOREACH(dom, &srv->domains, list) { if (dom->id == id) return (dom); } @@ -523,11 +523,11 @@ kore_domain_byid(u_int16_t id) void kore_domain_closelogs(void) { - struct listener *l; + struct kore_server *srv; struct kore_domain *dom; - LIST_FOREACH(l, &listeners, list) { - TAILQ_FOREACH(dom, &l->domains, list) { + LIST_FOREACH(srv, &kore_servers, list) { + TAILQ_FOREACH(dom, &srv->domains, list) { if (dom->accesslog != -1) { (void)close(dom->accesslog); /* diff --git a/src/filemap.c b/src/filemap.c @@ -179,6 +179,7 @@ filemap_serve(struct http_request *req, struct filemap_entry *map) struct stat st; struct connection *c; struct kore_fileref *ref; + struct kore_server *srv; const char *path; int len, fd, index; char fpath[PATH_MAX], rpath[PATH_MAX]; @@ -226,8 +227,9 @@ lookup: } c = req->owner; + srv = c->owner->server; - if ((ref = kore_fileref_get(rpath, c->owner->tls)) == NULL) { + if ((ref = kore_fileref_get(rpath, srv->tls)) == NULL) { if ((fd = open(fpath, O_RDONLY | O_NOFOLLOW)) == -1) { switch (errno) { case ENOENT: @@ -274,7 +276,7 @@ lookup: } /* kore_fileref_create() takes ownership of the fd. */ - ref = kore_fileref_create(c, fpath, fd, + ref = kore_fileref_create(srv, fpath, fd, st.st_size, &st.st_mtim); if (ref == NULL) { http_response(req, diff --git a/src/fileref.c b/src/fileref.c @@ -45,14 +45,14 @@ kore_fileref_init(void) } struct kore_fileref * -kore_fileref_create(struct connection *c, const char *path, int fd, +kore_fileref_create(struct kore_server *srv, const char *path, int fd, off_t size, struct timespec *ts) { struct kore_fileref *ref; fileref_timer_prime(); - if ((ref = kore_fileref_get(path, c->owner->tls)) != NULL) + if ((ref = kore_fileref_get(path, srv->tls)) != NULL) return (ref); ref = kore_pool_get(&ref_pool); @@ -60,7 +60,7 @@ kore_fileref_create(struct connection *c, const char *path, int fd, ref->cnt = 1; ref->flags = 0; ref->size = size; - ref->ontls = c->owner->tls; + ref->ontls = srv->tls; ref->path = kore_strdup(path); ref->mtime_sec = ts->tv_sec; ref->mtime = ((u_int64_t)(ts->tv_sec * 1000 + (ts->tv_nsec / 1000000))); @@ -78,7 +78,7 @@ kore_fileref_create(struct connection *c, const char *path, int fd, fatal("net_send_file: madvise: %s", errno_s); close(fd); #else - if (c->owner->tls == 0) { + if (srv->tls == 0) { ref->fd = fd; } else { if ((uintmax_t)size> SIZE_MAX) { diff --git a/src/keymgr.c b/src/keymgr.c @@ -133,7 +133,7 @@ kore_keymgr_run(void) quit = 0; - kore_listener_closeall(); + kore_server_closeall(); kore_module_cleanup(); net_init(); @@ -230,7 +230,7 @@ kore_keymgr_cleanup(int final) static void keymgr_reload(void) { - struct listener *l; + struct kore_server *srv; struct kore_domain *dom; if (!kore_quiet) @@ -242,10 +242,10 @@ keymgr_reload(void) kore_domain_callback(keymgr_load_privatekey); /* can't use kore_domain_callback() due to dst parameter. */ - LIST_FOREACH(l, &listeners, list) { - if (l->tls == 0) + LIST_FOREACH(srv, &kore_servers, list) { + if (srv->tls == 0) continue; - TAILQ_FOREACH(dom, &l->domains, list) + TAILQ_FOREACH(dom, &srv->domains, list) keymgr_submit_certificates(dom, KORE_MSG_WORKER_ALL); } } @@ -417,7 +417,7 @@ keymgr_load_privatekey(struct kore_domain *dom) FILE *fp; struct key *key; - if (dom->listener->tls == 0) + if (dom->server->tls == 0) return; if ((fp = fopen(dom->certkey, "r")) == NULL) @@ -437,13 +437,13 @@ keymgr_load_privatekey(struct kore_domain *dom) static void keymgr_certificate_request(struct kore_msg *msg, const void *data) { - struct listener *l; + struct kore_server *srv; struct kore_domain *dom; - LIST_FOREACH(l, &listeners, list) { - if (l->tls == 0) + LIST_FOREACH(srv, &kore_servers, list) { + if (srv->tls == 0) continue; - TAILQ_FOREACH(dom, &l->domains, list) + TAILQ_FOREACH(dom, &srv->domains, list) keymgr_submit_certificates(dom, msg->src); } } diff --git a/src/kore.c b/src/kore.c @@ -46,7 +46,7 @@ #endif volatile sig_atomic_t sig_recv; -struct listener_head listeners; +struct kore_server_list kore_servers; u_int8_t nlisteners; int kore_argc = 0; pid_t kore_pid = -1; @@ -239,7 +239,7 @@ main(int argc, char *argv[]) kore_pid = getpid(); nlisteners = 0; - LIST_INIT(&listeners); + LIST_INIT(&kore_servers); kore_platform_init(); kore_log_init(); @@ -322,7 +322,7 @@ main(int argc, char *argv[]) if (unlink(kore_pidfile) == -1 && errno != ENOENT) kore_log(LOG_NOTICE, "failed to remove pidfile (%s)", errno_s); - kore_listener_cleanup(); + kore_server_cleanup(); if (!kore_quiet) kore_log(LOG_NOTICE, "goodbye"); @@ -349,8 +349,10 @@ kore_tls_sni_cb(SSL *ssl, int *ad, void *arg) sname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); kore_debug("kore_tls_sni_cb(): received host %s", sname); + printf("looking for %s in %s\n", sname, c->owner->server->name); + if (sname != NULL && - (dom = kore_domain_lookup(c->owner, sname)) != NULL) { + (dom = kore_domain_lookup(c->owner->server, sname)) != NULL) { if (dom->ssl_ctx == NULL) { kore_log(LOG_NOTICE, "TLS configuration for %s not complete", @@ -391,11 +393,11 @@ kore_tls_info_callback(const SSL *ssl, int flags, int ret) } int -kore_server_bind(struct listener *l, const char *ip, const char *port, +kore_server_bind(struct kore_server *srv, const char *ip, const char *port, const char *ccb) { int r; - const char *proto; + struct listener *l; struct addrinfo hints, *results; kore_debug("kore_server_bind(%s, %s, %s)", l->name, ip, port); @@ -410,6 +412,10 @@ kore_server_bind(struct listener *l, const char *ip, const char *port, if (r != 0) fatal("getaddrinfo(%s): %s", ip, gai_strerror(r)); + l = kore_listener_create(srv); + l->host = kore_strdup(ip); + l->port = kore_strdup(port); + if (kore_listener_init(l, results->ai_family, ccb) == -1) { freeaddrinfo(results); kore_listener_free(l); @@ -431,21 +437,14 @@ kore_server_bind(struct listener *l, const char *ip, const char *port, return (KORE_RESULT_ERROR); } - if (foreground && !kore_quiet) { - if (l->tls) - proto = "https"; - else - proto = "http"; - - kore_log(LOG_NOTICE, "running on %s://%s:%s", proto, ip, port); - } - return (KORE_RESULT_OK); } int -kore_server_bind_unix(struct listener *l, const char *path, const char *ccb) +kore_server_bind_unix(struct kore_server *srv, const char *path, + const char *ccb) { + struct listener *l; int len; struct sockaddr_un sun; socklen_t socklen; @@ -467,6 +466,9 @@ kore_server_bind_unix(struct listener *l, const char *path, const char *ccb) socklen = sizeof(sun); #endif + l = kore_listener_create(srv); + l->host = kore_strdup(path); + if (kore_listener_init(l, AF_UNIX, ccb) == -1) { kore_listener_free(l); return (KORE_RESULT_ERROR); @@ -484,42 +486,78 @@ kore_server_bind_unix(struct listener *l, const char *path, const char *ccb) return (KORE_RESULT_ERROR); } - if (foreground && !kore_quiet) - kore_log(LOG_NOTICE, "running on %s", path); - return (KORE_RESULT_OK); } +struct kore_server * +kore_server_create(const char *name) +{ + struct kore_server *srv; + + srv = kore_calloc(1, sizeof(struct kore_server)); + srv->name = kore_strdup(name); + srv->tls = 1; + + TAILQ_INIT(&srv->domains); + LIST_INIT(&srv->listeners); + + LIST_INSERT_HEAD(&kore_servers, srv, list); + + return (srv); +} + +void +kore_server_finalize(struct kore_server *srv) +{ + struct listener *l; + const char *proto; + + if (kore_quiet) + return; + + LIST_FOREACH(l, &srv->listeners, list) { + if (srv->tls) + proto = "https"; + else + proto = "http"; + + if (l->family == AF_UNIX) { + kore_log(LOG_NOTICE, "%s serving %s on %s", + srv->name, proto, l->host); + } else { + kore_log(LOG_NOTICE, "%s serving %s on %s:%s", + srv->name, proto, l->host, l->port); + } + } +} + struct listener * -kore_listener_create(const char *name) +kore_listener_create(struct kore_server *server) { struct listener *l; l = kore_calloc(1, sizeof(struct listener)); nlisteners++; - LIST_INSERT_HEAD(&listeners, l, list); + LIST_INSERT_HEAD(&server->listeners, l, list); - l->fd = -1; - l->tls = 1; - l->name = kore_strdup(name); + l->server = server; + l->fd = -1; l->evt.type = KORE_TYPE_LISTENER; l->evt.handle = kore_listener_accept; - TAILQ_INIT(&l->domains); - return (l); } -struct listener * -kore_listener_lookup(const char *name) +struct kore_server * +kore_server_lookup(const char *name) { - struct listener *l; + struct kore_server *srv; - LIST_FOREACH(l, &listeners, list) { - if (!strcmp(l->name, name)) - return (l); + LIST_FOREACH(srv, &kore_servers, list) { + if (!strcmp(srv->name, name)) + return (srv); } return (NULL); @@ -576,19 +614,34 @@ kore_listener_init(struct listener *l, int family, const char *ccb) } void -kore_listener_free(struct listener *l) +kore_server_free(struct kore_server *srv) { + struct listener *l; struct kore_domain *dom; - while ((dom = TAILQ_FIRST(&l->domains)) != NULL) + LIST_REMOVE(srv, list); + + while ((dom = TAILQ_FIRST(&srv->domains)) != NULL) kore_domain_free(dom); + while ((l = LIST_FIRST(&srv->listeners)) != NULL) + kore_listener_free(l); + + kore_free(srv->name); + kore_free(srv); +} + +void +kore_listener_free(struct listener *l) +{ LIST_REMOVE(l, list); - kore_free(l->name); if (l->fd != -1) close(l->fd); + kore_free(l->host); + kore_free(l->port); + kore_free(l); } @@ -673,23 +726,24 @@ kore_signal_setup(void) } void -kore_listener_closeall(void) +kore_server_closeall(void) { struct listener *l; + struct kore_server *srv; - LIST_FOREACH(l, &listeners, list) - l->fd = -1; + LIST_FOREACH(srv, &kore_servers, list) { + LIST_FOREACH(l, &srv->listeners, list) + l->fd = -1; + } } void -kore_listener_cleanup(void) +kore_server_cleanup(void) { - struct listener *l; + struct kore_server *srv; - while (!LIST_EMPTY(&listeners)) { - l = LIST_FIRST(&listeners); - kore_listener_free(l); - } + while ((srv = LIST_FIRST(&kore_servers)) != NULL) + kore_server_free(srv); } void diff --git a/src/linux.c b/src/linux.c @@ -191,23 +191,31 @@ void kore_platform_enable_accept(void) { struct listener *l; + struct kore_server *srv; kore_debug("kore_platform_enable_accept()"); - LIST_FOREACH(l, &listeners, list) - kore_platform_event_schedule(l->fd, EPOLLIN, 0, l); + LIST_FOREACH(srv, &kore_servers, list) { + LIST_FOREACH(l, &srv->listeners, list) + kore_platform_event_schedule(l->fd, EPOLLIN, 0, l); + } } void kore_platform_disable_accept(void) { struct listener *l; + struct kore_server *srv; kore_debug("kore_platform_disable_accept()"); - LIST_FOREACH(l, &listeners, list) { - if (epoll_ctl(efd, EPOLL_CTL_DEL, l->fd, NULL) == -1) - fatal("kore_platform_disable_accept: %s", errno_s); + LIST_FOREACH(srv, &kore_servers, list) { + LIST_FOREACH(l, &srv->listeners, list) { + if (epoll_ctl(efd, EPOLL_CTL_DEL, l->fd, NULL) == -1) { + fatal("kore_platform_disable_accept: %s", + errno_s); + } + } } } diff --git a/src/module.c b/src/module.c @@ -136,7 +136,7 @@ kore_module_reload(int cbs) struct stat st; int ret; #if !defined(KORE_NO_HTTP) - struct listener *l; + struct kore_server *srv; struct kore_domain *dom; struct kore_module_handle *hdlr; #endif @@ -183,8 +183,8 @@ kore_module_reload(int cbs) } #if !defined(KORE_NO_HTTP) - LIST_FOREACH(l, &listeners, list) { - TAILQ_FOREACH(dom, &l->domains, list) { + LIST_FOREACH(srv, &kore_servers, list) { + TAILQ_FOREACH(dom, &srv->domains, list) { TAILQ_FOREACH(hdlr, &(dom->handlers), list) { kore_free(hdlr->rcall); hdlr->rcall = kore_runtime_getcall(hdlr->func); @@ -293,7 +293,7 @@ kore_module_handler_find(struct http_request *req, const char *domain, c = req->owner; - if ((dom = kore_domain_lookup(c->owner, domain)) == NULL) + if ((dom = kore_domain_lookup(c->owner->server, domain)) == NULL) return (NULL); TAILQ_FOREACH(hdlr, &(dom->handlers), list) { diff --git a/src/net.c b/src/net.c @@ -156,7 +156,7 @@ net_send_fileref(struct connection *c, struct kore_fileref *ref) nb->flags = NETBUF_IS_FILEREF; #if defined(KORE_USE_PLATFORM_SENDFILE) - if (c->owner->tls == 0) { + if (c->owner->server->tls == 0) { nb->fd_off = 0; nb->fd_len = ref->size; } else { diff --git a/src/python.c b/src/python.c @@ -1349,9 +1349,9 @@ python_kore_time(PyObject *self, PyObject *args) } static PyObject * -python_kore_listen(PyObject *self, PyObject *args, PyObject *kwargs) +python_kore_server(PyObject *self, PyObject *args, PyObject *kwargs) { - struct listener *l; + struct kore_server *srv; const char *name, *ip, *port, *path; if (!PyArg_ParseTuple(args, "s", &name)) @@ -1376,30 +1376,32 @@ python_kore_listen(PyObject *self, PyObject *args, PyObject *kwargs) return (NULL); } - l = kore_listener_create(name); - python_bool_from_dict(kwargs, "tls", &l->tls); + srv = kore_server_create(name); + python_bool_from_dict(kwargs, "tls", &srv->tls); if (ip != NULL) { if ((port = python_string_from_dict(kwargs, "port")) == NULL) { - kore_listener_free(l); + kore_server_free(srv); PyErr_SetString(PyExc_RuntimeError, "missing or invalid 'port' keyword"); return (NULL); } - if (!kore_server_bind(l, ip, port, NULL)) { + if (!kore_server_bind(srv, ip, port, NULL)) { PyErr_Format(PyExc_RuntimeError, "failed to bind to '%s:%s'", ip, port); return (NULL); } } else { - if (!kore_server_bind_unix(l, path, NULL)) { + if (!kore_server_bind_unix(srv, path, NULL)) { PyErr_Format(PyExc_RuntimeError, "failed to bind to '%s'", path); return (NULL); } } + kore_server_finalize(srv); + Py_RETURN_NONE; } @@ -1578,7 +1580,7 @@ python_kore_tracer(PyObject *self, PyObject *args) static PyObject * python_kore_domain(PyObject *self, PyObject *args, PyObject *kwargs) { - struct listener *l; + struct kore_server *srv; long depth; const char *name; struct pydomain *domain; @@ -1604,13 +1606,13 @@ python_kore_domain(PyObject *self, PyObject *args, PyObject *kwargs) return (NULL); } - if ((l = kore_listener_lookup(attach)) == NULL) { + if ((srv = kore_server_lookup(attach)) == NULL) { PyErr_Format(PyExc_RuntimeError, - "listener '%s' does not exist", attach); + "server '%s' does not exist", attach); return (NULL); } - if (l->tls) { + if (srv->tls) { key = python_string_from_dict(kwargs, "key"); cert = python_string_from_dict(kwargs, "cert"); @@ -1633,7 +1635,7 @@ python_kore_domain(PyObject *self, PyObject *args, PyObject *kwargs) kore_log(LOG_INFO, "ignoring tls settings for '%s'", name); } - if (kore_domain_lookup(l, name) != NULL) { + if (kore_domain_lookup(srv, name) != NULL) { PyErr_SetString(PyExc_RuntimeError, "domain exists"); return (NULL); } @@ -1644,10 +1646,10 @@ python_kore_domain(PyObject *self, PyObject *args, PyObject *kwargs) if ((domain->config = kore_domain_new(name)) == NULL) fatal("failed to create new domain configuration"); - if (!kore_domain_attach(l, domain->config)) + if (!kore_domain_attach(domain->config, srv)) fatal("failed to attach domain configuration"); - if (l->tls) { + if (srv->tls) { domain->config->certkey = kore_strdup(key); domain->config->certfile = kore_strdup(cert); diff --git a/src/worker.c b/src/worker.c @@ -475,6 +475,8 @@ kore_worker_entry(struct kore_worker *kw) kore_free(rcall); } + kore_server_cleanup(); + kore_platform_event_cleanup(); kore_connection_cleanup(); kore_domain_cleanup(); @@ -739,7 +741,7 @@ static int worker_keymgr_response_verify(struct kore_msg *msg, const void *data, struct kore_domain **out) { - struct listener *l; + struct kore_server *srv; struct kore_domain *dom; const struct kore_x509_msg *req; @@ -763,10 +765,13 @@ worker_keymgr_response_verify(struct kore_msg *msg, const void *data, return (KORE_RESULT_ERROR); } - LIST_FOREACH(l, &listeners, list) { + LIST_FOREACH(srv, &kore_servers, list) { dom = NULL; - TAILQ_FOREACH(dom, &l->domains, list) { + if (srv->tls == 0) + continue; + + TAILQ_FOREACH(dom, &srv->domains, list) { if (!strncmp(dom->domain, req->domain, req->domain_len)) break; }