2013-04-17 22:34:27 +02:00
|
|
|
/*
|
2016-01-04 12:58:51 +01:00
|
|
|
* Copyright (c) 2013-2016 Joris Vink <joris@coders.se>
|
2013-04-17 22:34:27 +02:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2015-05-20 16:36:13 +02:00
|
|
|
#include <sys/types.h>
|
2016-01-18 11:30:22 +01:00
|
|
|
#include <sys/stat.h>
|
|
|
|
|
2013-04-17 22:34:27 +02:00
|
|
|
#include <sys/socket.h>
|
2015-05-20 16:36:13 +02:00
|
|
|
#include <sys/resource.h>
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2016-01-22 12:08:13 +01:00
|
|
|
#include <stdio.h>
|
2013-07-27 20:56:15 +02:00
|
|
|
#include <netdb.h>
|
2013-05-03 00:04:06 +02:00
|
|
|
#include <signal.h>
|
2013-04-17 22:34:27 +02:00
|
|
|
|
|
|
|
#include "kore.h"
|
|
|
|
|
2016-01-18 11:30:22 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
|
|
|
#include "http.h"
|
|
|
|
#endif
|
|
|
|
|
2013-05-03 00:04:06 +02:00
|
|
|
volatile sig_atomic_t sig_recv;
|
2013-05-02 09:10:35 +02:00
|
|
|
|
2013-07-27 20:56:15 +02:00
|
|
|
struct listener_head listeners;
|
|
|
|
u_int8_t nlisteners;
|
2013-06-26 11:18:32 +02:00
|
|
|
pid_t kore_pid = -1;
|
2013-06-17 23:39:17 +02:00
|
|
|
u_int16_t cpu_count = 1;
|
2014-07-31 13:27:04 +02:00
|
|
|
int foreground = 0;
|
2013-06-05 08:55:07 +02:00
|
|
|
int kore_debug = 0;
|
2013-06-04 16:53:30 +02:00
|
|
|
u_int8_t worker_count = 0;
|
2015-05-18 21:34:39 +02:00
|
|
|
int skip_chroot = 0;
|
2013-06-05 09:47:08 +02:00
|
|
|
char *chroot_path = NULL;
|
2015-05-18 21:34:39 +02:00
|
|
|
int skip_runas = 0;
|
|
|
|
char *runas_user = NULL;
|
2015-04-09 15:29:44 +02:00
|
|
|
u_int32_t kore_socket_backlog = 5000;
|
2013-06-04 16:53:30 +02:00
|
|
|
char *kore_pidfile = KORE_PIDFILE_DEFAULT;
|
2015-05-06 10:59:43 +02:00
|
|
|
char *kore_tls_cipher_list = KORE_DEFAULT_CIPHER_LIST;
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
extern char *__progname;
|
|
|
|
|
2013-06-05 08:55:07 +02:00
|
|
|
static void usage(void);
|
2014-07-04 09:25:18 +02:00
|
|
|
static void version(void);
|
2013-06-26 11:18:32 +02:00
|
|
|
static void kore_server_start(void);
|
|
|
|
static void kore_write_kore_pid(void);
|
2013-06-24 11:32:45 +02:00
|
|
|
static void kore_server_sslstart(void);
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2013-06-05 08:55:07 +02:00
|
|
|
static void
|
|
|
|
usage(void)
|
|
|
|
{
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2014-08-01 13:59:47 +02:00
|
|
|
fprintf(stderr, "Usage: kore [options | command]\n");
|
2016-07-06 16:16:15 +02:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "Usage: %s [options]\n", __progname);
|
|
|
|
#endif
|
2014-08-01 13:59:47 +02:00
|
|
|
fprintf(stderr, "\n");
|
|
|
|
fprintf(stderr, "Available options:\n");
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
|
|
|
fprintf(stderr, "\t-c\tconfiguration to use\n");
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_DEBUG)
|
|
|
|
fprintf(stderr, "\t-d\trun with debug on)\n");
|
|
|
|
#endif
|
|
|
|
fprintf(stderr, "\t-f\tstart in foreground\n");
|
2014-08-03 17:11:02 +02:00
|
|
|
fprintf(stderr, "\t-h\tthis help text\n");
|
2015-05-28 22:20:43 +02:00
|
|
|
fprintf(stderr, "\t-n\tdo not chroot\n");
|
2016-07-06 16:16:15 +02:00
|
|
|
fprintf(stderr, "\t-r\tdo not drop privileges\n");
|
|
|
|
fprintf(stderr, "\t-v\tdisplay kore build information\n");
|
2014-08-01 13:59:47 +02:00
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2014-08-01 13:59:47 +02:00
|
|
|
kore_cli_usage(0);
|
2016-07-06 16:16:15 +02:00
|
|
|
#else
|
|
|
|
fprintf(stderr, "\nbuilt with https://kore.io\n");
|
|
|
|
exit(1);
|
|
|
|
#endif
|
2013-06-05 08:55:07 +02:00
|
|
|
}
|
|
|
|
|
2014-07-04 09:25:18 +02:00
|
|
|
static void
|
|
|
|
version(void)
|
|
|
|
{
|
2016-07-06 16:16:15 +02:00
|
|
|
printf("%d.%d.%d-%s ", KORE_VERSION_MAJOR, KORE_VERSION_MINOR,
|
2014-12-12 13:06:41 +01:00
|
|
|
KORE_VERSION_PATCH, KORE_VERSION_STATE);
|
2015-11-27 16:22:50 +01:00
|
|
|
#if defined(KORE_NO_TLS)
|
|
|
|
printf("no-tls ");
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_NO_HTTP)
|
|
|
|
printf("no-http ");
|
|
|
|
#endif
|
2014-07-04 09:25:18 +02:00
|
|
|
#if defined(KORE_USE_PGSQL)
|
|
|
|
printf("pgsql ");
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_TASKS)
|
|
|
|
printf("tasks ");
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
|
|
|
#if defined(KORE_DEBUG)
|
|
|
|
printf("debug ");
|
2016-07-06 16:16:15 +02:00
|
|
|
#endif
|
|
|
|
#if defined(KORE_SINGLE_BINARY)
|
|
|
|
printf("single ");
|
2014-07-04 09:25:18 +02:00
|
|
|
#endif
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2013-04-17 22:34:27 +02:00
|
|
|
int
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
{
|
2016-06-08 13:55:14 +02:00
|
|
|
int ch, flags;
|
2013-04-17 22:34:27 +02:00
|
|
|
|
2014-08-01 13:59:47 +02:00
|
|
|
flags = 0;
|
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2015-05-18 21:34:39 +02:00
|
|
|
while ((ch = getopt(argc, argv, "c:dfhnrv")) != -1) {
|
2016-07-06 16:16:15 +02:00
|
|
|
#else
|
|
|
|
while ((ch = getopt(argc, argv, "dfhnrv")) != -1) {
|
|
|
|
#endif
|
2014-08-01 13:59:47 +02:00
|
|
|
flags++;
|
2013-06-05 08:55:07 +02:00
|
|
|
switch (ch) {
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2013-06-05 08:55:07 +02:00
|
|
|
case 'c':
|
|
|
|
config_file = optarg;
|
|
|
|
break;
|
2016-07-06 16:16:15 +02:00
|
|
|
#endif
|
2013-07-15 10:13:36 +02:00
|
|
|
#if defined(KORE_DEBUG)
|
2016-07-06 16:16:15 +02:00
|
|
|
case 'd':
|
2013-06-05 08:55:07 +02:00
|
|
|
kore_debug = 1;
|
|
|
|
break;
|
2016-07-06 16:16:15 +02:00
|
|
|
#endif
|
2014-07-31 13:27:04 +02:00
|
|
|
case 'f':
|
|
|
|
foreground = 1;
|
|
|
|
break;
|
2014-08-01 13:59:47 +02:00
|
|
|
case 'h':
|
|
|
|
usage();
|
|
|
|
break;
|
2013-11-18 00:42:57 +01:00
|
|
|
case 'n':
|
|
|
|
skip_chroot = 1;
|
|
|
|
break;
|
2015-05-18 21:34:39 +02:00
|
|
|
case 'r':
|
|
|
|
skip_runas = 1;
|
|
|
|
break;
|
2014-07-04 09:25:18 +02:00
|
|
|
case 'v':
|
|
|
|
version();
|
|
|
|
break;
|
2013-06-05 08:55:07 +02:00
|
|
|
default:
|
|
|
|
usage();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
argc -= optind;
|
|
|
|
argv += optind;
|
|
|
|
|
2014-08-01 15:55:09 +02:00
|
|
|
kore_mem_init();
|
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2014-08-01 13:59:47 +02:00
|
|
|
if (argc > 0) {
|
|
|
|
if (flags)
|
|
|
|
fatal("You cannot specify kore flags and a command");
|
|
|
|
return (kore_cli_main(argc, argv));
|
|
|
|
}
|
2016-07-06 16:16:15 +02:00
|
|
|
#endif
|
2014-08-01 13:59:47 +02:00
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
kore_pid = getpid();
|
2013-07-27 20:56:15 +02:00
|
|
|
nlisteners = 0;
|
|
|
|
LIST_INIT(&listeners);
|
|
|
|
|
2013-07-15 10:13:36 +02:00
|
|
|
kore_log_init();
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2014-01-22 22:55:10 +01:00
|
|
|
kore_auth_init();
|
2015-11-27 16:22:50 +01:00
|
|
|
kore_validator_init();
|
|
|
|
#endif
|
2013-06-24 11:32:45 +02:00
|
|
|
kore_domain_init();
|
2013-12-15 01:11:56 +01:00
|
|
|
kore_module_init();
|
2013-06-24 11:32:45 +02:00
|
|
|
kore_server_sslstart();
|
2013-06-27 08:43:07 +02:00
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2014-07-31 17:15:51 +02:00
|
|
|
if (config_file == NULL)
|
|
|
|
usage();
|
2016-07-06 16:16:15 +02:00
|
|
|
#else
|
|
|
|
kore_module_load(NULL, NULL);
|
|
|
|
#endif
|
2014-07-31 17:15:51 +02:00
|
|
|
|
|
|
|
kore_parse_config();
|
2013-06-24 09:36:40 +02:00
|
|
|
kore_platform_init();
|
2015-11-27 16:22:50 +01:00
|
|
|
|
|
|
|
#if !defined(KORE_NO_HTTP)
|
2013-06-24 09:36:40 +02:00
|
|
|
kore_accesslog_init();
|
2016-01-18 11:30:22 +01:00
|
|
|
if (http_body_disk_offload > 0) {
|
|
|
|
if (mkdir(http_body_disk_path, 0700) == -1 && errno != EEXIST) {
|
|
|
|
printf("can't create http_body_disk_path '%s': %s\n",
|
|
|
|
http_body_disk_path, errno_s);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
}
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
2013-05-04 22:18:27 +02:00
|
|
|
|
2013-05-03 00:04:06 +02:00
|
|
|
sig_recv = 0;
|
|
|
|
signal(SIGHUP, kore_signal);
|
2013-06-05 09:47:08 +02:00
|
|
|
signal(SIGQUIT, kore_signal);
|
2016-01-31 16:48:17 +01:00
|
|
|
signal(SIGTERM, kore_signal);
|
2013-06-05 09:47:08 +02:00
|
|
|
|
2014-07-31 13:27:04 +02:00
|
|
|
if (foreground)
|
|
|
|
signal(SIGINT, kore_signal);
|
|
|
|
else
|
|
|
|
signal(SIGINT, SIG_IGN);
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
kore_server_start();
|
2013-05-03 00:04:06 +02:00
|
|
|
|
2013-06-04 23:24:47 +02:00
|
|
|
kore_log(LOG_NOTICE, "server shutting down");
|
2013-06-26 16:37:22 +02:00
|
|
|
kore_worker_shutdown();
|
2014-07-31 14:02:33 +02:00
|
|
|
|
|
|
|
if (!foreground)
|
|
|
|
unlink(kore_pidfile);
|
2013-07-27 20:56:15 +02:00
|
|
|
|
2016-06-08 13:55:14 +02:00
|
|
|
kore_listener_cleanup();
|
2013-06-26 16:37:22 +02:00
|
|
|
kore_log(LOG_NOTICE, "goodbye");
|
2016-06-08 13:55:14 +02:00
|
|
|
|
2013-04-17 22:34:27 +02:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
2015-05-25 15:42:34 +02:00
|
|
|
#if !defined(KORE_NO_TLS)
|
2013-06-24 11:32:45 +02:00
|
|
|
int
|
2016-06-09 13:52:37 +02:00
|
|
|
kore_tls_sni_cb(SSL *ssl, int *ad, void *arg)
|
2013-06-24 11:32:45 +02:00
|
|
|
{
|
|
|
|
struct kore_domain *dom;
|
|
|
|
const char *sname;
|
|
|
|
|
|
|
|
sname = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
2015-05-06 10:59:43 +02:00
|
|
|
kore_debug("kore_tls_sni_cb(): received host %s", sname);
|
2013-06-24 11:32:45 +02:00
|
|
|
|
|
|
|
if (sname != NULL && (dom = kore_domain_lookup(sname)) != NULL) {
|
|
|
|
kore_debug("kore_ssl_sni_cb(): Using %s CTX", sname);
|
|
|
|
SSL_set_SSL_CTX(ssl, dom->ssl_ctx);
|
2013-12-14 16:31:07 +01:00
|
|
|
|
|
|
|
if (dom->cafile != NULL) {
|
|
|
|
SSL_set_verify(ssl, SSL_VERIFY_PEER |
|
|
|
|
SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
|
|
|
} else {
|
|
|
|
SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
|
|
|
|
}
|
|
|
|
|
2013-06-24 11:32:45 +02:00
|
|
|
return (SSL_TLSEXT_ERR_OK);
|
2013-06-17 23:39:17 +02:00
|
|
|
}
|
|
|
|
|
2016-06-09 13:52:37 +02:00
|
|
|
return (SSL_TLSEXT_ERR_NOACK);
|
2013-06-24 11:32:45 +02:00
|
|
|
}
|
2015-05-20 16:36:13 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
kore_tls_info_callback(const SSL *ssl, int flags, int ret)
|
|
|
|
{
|
|
|
|
struct connection *c;
|
|
|
|
|
|
|
|
if (flags & SSL_CB_HANDSHAKE_START) {
|
|
|
|
if ((c = SSL_get_app_data(ssl)) == NULL)
|
|
|
|
fatal("no SSL_get_app_data");
|
|
|
|
c->tls_reneg++;
|
|
|
|
}
|
|
|
|
}
|
2014-08-01 10:22:32 +02:00
|
|
|
#endif
|
2013-06-17 23:39:17 +02:00
|
|
|
|
2013-07-27 20:56:15 +02:00
|
|
|
int
|
2015-11-27 16:22:50 +01:00
|
|
|
kore_server_bind(const char *ip, const char *port, const char *ccb)
|
2013-07-27 20:56:15 +02:00
|
|
|
{
|
|
|
|
struct listener *l;
|
|
|
|
int on, r;
|
2015-06-14 16:54:44 +02:00
|
|
|
struct addrinfo hints, *results;
|
2013-07-27 20:56:15 +02:00
|
|
|
|
|
|
|
kore_debug("kore_server_bind(%s, %s)", ip, port);
|
|
|
|
|
2015-06-14 16:54:44 +02:00
|
|
|
memset(&hints, 0, sizeof(hints));
|
|
|
|
hints.ai_family = AF_UNSPEC;
|
|
|
|
hints.ai_socktype = SOCK_STREAM;
|
|
|
|
hints.ai_protocol = IPPROTO_TCP;
|
|
|
|
hints.ai_flags = 0;
|
|
|
|
|
|
|
|
r = getaddrinfo(ip, port, &hints, &results);
|
2013-07-27 20:56:15 +02:00
|
|
|
if (r != 0)
|
|
|
|
fatal("getaddrinfo(%s): %s", ip, gai_strerror(r));
|
|
|
|
|
|
|
|
l = kore_malloc(sizeof(struct listener));
|
|
|
|
l->type = KORE_TYPE_LISTENER;
|
|
|
|
l->addrtype = results->ai_family;
|
|
|
|
|
|
|
|
if (l->addrtype != AF_INET && l->addrtype != AF_INET6)
|
|
|
|
fatal("getaddrinfo(): unknown address family %d", l->addrtype);
|
|
|
|
|
|
|
|
if ((l->fd = socket(results->ai_family, SOCK_STREAM, 0)) == -1) {
|
|
|
|
kore_mem_free(l);
|
|
|
|
freeaddrinfo(results);
|
|
|
|
kore_debug("socket(): %s", errno_s);
|
2015-04-26 21:09:46 +02:00
|
|
|
printf("failed to create socket: %s\n", errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2015-06-22 22:11:03 +02:00
|
|
|
if (!kore_connection_nonblock(l->fd, 1)) {
|
2013-07-27 20:56:15 +02:00
|
|
|
kore_mem_free(l);
|
|
|
|
freeaddrinfo(results);
|
2015-04-26 21:09:46 +02:00
|
|
|
printf("failed to make socket non blocking: %s\n", errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
on = 1;
|
|
|
|
if (setsockopt(l->fd, SOL_SOCKET,
|
|
|
|
SO_REUSEADDR, (const char *)&on, sizeof(on)) == -1) {
|
|
|
|
close(l->fd);
|
|
|
|
kore_mem_free(l);
|
|
|
|
freeaddrinfo(results);
|
|
|
|
kore_debug("setsockopt(): %s", errno_s);
|
2015-04-26 21:09:46 +02:00
|
|
|
printf("failed to set SO_REUSEADDR: %s\n", errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bind(l->fd, results->ai_addr, results->ai_addrlen) == -1) {
|
|
|
|
close(l->fd);
|
|
|
|
kore_mem_free(l);
|
|
|
|
freeaddrinfo(results);
|
|
|
|
kore_debug("bind(): %s", errno_s);
|
2015-04-26 21:09:46 +02:00
|
|
|
printf("failed to bind to %s port %s: %s\n", ip, port, errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
freeaddrinfo(results);
|
|
|
|
|
2015-04-09 15:29:44 +02:00
|
|
|
if (listen(l->fd, kore_socket_backlog) == -1) {
|
2013-07-27 20:56:15 +02:00
|
|
|
close(l->fd);
|
|
|
|
kore_mem_free(l);
|
|
|
|
kore_debug("listen(): %s", errno_s);
|
2015-04-26 21:09:46 +02:00
|
|
|
printf("failed to listen on socket: %s\n", errno_s);
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
if (ccb != NULL) {
|
2016-02-01 15:33:40 +01:00
|
|
|
*(void **)&(l->connect) = kore_module_getsym(ccb);
|
2015-11-27 16:22:50 +01:00
|
|
|
if (l->connect == NULL) {
|
|
|
|
printf("no such callback: '%s'\n", ccb);
|
|
|
|
close(l->fd);
|
|
|
|
kore_mem_free(l);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
l->connect = NULL;
|
|
|
|
}
|
|
|
|
|
2013-07-27 20:56:15 +02:00
|
|
|
nlisteners++;
|
|
|
|
LIST_INSERT_HEAD(&listeners, l, list);
|
|
|
|
|
2015-05-26 18:13:56 +02:00
|
|
|
if (foreground) {
|
|
|
|
#if !defined(KORE_NO_TLS)
|
2014-08-01 20:00:09 +02:00
|
|
|
kore_log(LOG_NOTICE, "running on https://%s:%s", ip, port);
|
2015-05-26 18:13:56 +02:00
|
|
|
#else
|
|
|
|
kore_log(LOG_NOTICE, "running on http://%s:%s", ip, port);
|
|
|
|
#endif
|
|
|
|
}
|
2014-08-01 20:00:09 +02:00
|
|
|
|
2013-07-27 20:56:15 +02:00
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
}
|
|
|
|
|
2016-06-08 13:55:14 +02:00
|
|
|
void
|
|
|
|
kore_listener_cleanup(void)
|
|
|
|
{
|
|
|
|
struct listener *l;
|
|
|
|
|
|
|
|
while (!LIST_EMPTY(&listeners)) {
|
|
|
|
l = LIST_FIRST(&listeners);
|
|
|
|
LIST_REMOVE(l, list);
|
|
|
|
close(l->fd);
|
|
|
|
kore_mem_free(l);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
void
|
|
|
|
kore_signal(int sig)
|
|
|
|
{
|
|
|
|
sig_recv = sig;
|
|
|
|
}
|
|
|
|
|
2013-06-24 11:32:45 +02:00
|
|
|
static void
|
|
|
|
kore_server_sslstart(void)
|
|
|
|
{
|
2015-05-25 15:42:34 +02:00
|
|
|
#if !defined(KORE_NO_TLS)
|
2013-06-24 11:32:45 +02:00
|
|
|
kore_debug("kore_server_sslstart()");
|
|
|
|
|
|
|
|
SSL_library_init();
|
|
|
|
SSL_load_error_strings();
|
2014-08-01 10:22:32 +02:00
|
|
|
#endif
|
2013-06-17 23:39:17 +02:00
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
static void
|
|
|
|
kore_server_start(void)
|
|
|
|
{
|
2015-06-22 21:13:32 +02:00
|
|
|
u_int32_t tmp;
|
2014-07-31 13:27:04 +02:00
|
|
|
int quit;
|
2013-09-02 08:52:16 +02:00
|
|
|
|
2014-07-31 13:27:04 +02:00
|
|
|
if (foreground == 0 && daemon(1, 1) == -1)
|
2013-06-26 11:18:32 +02:00
|
|
|
fatal("cannot daemon(): %s", errno_s);
|
|
|
|
|
|
|
|
kore_pid = getpid();
|
2014-07-31 14:02:33 +02:00
|
|
|
if (!foreground)
|
|
|
|
kore_write_kore_pid();
|
2013-06-26 11:18:32 +02:00
|
|
|
|
2016-07-06 16:16:15 +02:00
|
|
|
kore_log(LOG_NOTICE, "%s is starting up", __progname);
|
2014-07-04 09:14:05 +02:00
|
|
|
#if defined(KORE_USE_PGSQL)
|
|
|
|
kore_log(LOG_NOTICE, "pgsql built-in enabled");
|
|
|
|
#endif
|
|
|
|
#if defined(KORE_USE_TASKS)
|
|
|
|
kore_log(LOG_NOTICE, "tasks built-in enabled");
|
|
|
|
#endif
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
kore_platform_proctitle("kore [parent]");
|
2015-06-22 21:13:32 +02:00
|
|
|
kore_msg_init();
|
2013-06-26 11:18:32 +02:00
|
|
|
kore_worker_init();
|
|
|
|
|
2015-06-22 21:13:32 +02:00
|
|
|
/* Set worker_max_connections for kore_connection_init(). */
|
|
|
|
tmp = worker_max_connections;
|
|
|
|
worker_max_connections = worker_count;
|
|
|
|
|
|
|
|
net_init();
|
|
|
|
kore_connection_init();
|
|
|
|
kore_platform_event_init();
|
|
|
|
kore_msg_parent_init();
|
|
|
|
|
2014-07-31 13:27:04 +02:00
|
|
|
quit = 0;
|
2015-06-22 21:13:32 +02:00
|
|
|
worker_max_connections = tmp;
|
2014-07-31 13:27:04 +02:00
|
|
|
while (quit != 1) {
|
2013-06-26 16:37:22 +02:00
|
|
|
if (sig_recv != 0) {
|
2014-07-31 13:27:04 +02:00
|
|
|
switch (sig_recv) {
|
|
|
|
case SIGHUP:
|
2016-07-06 16:16:15 +02:00
|
|
|
#if !defined(KORE_SINGLE_BINARY)
|
2013-06-26 16:37:22 +02:00
|
|
|
kore_worker_dispatch_signal(sig_recv);
|
2014-07-31 13:27:04 +02:00
|
|
|
kore_module_reload(0);
|
2016-07-06 16:16:15 +02:00
|
|
|
#endif
|
2014-07-31 13:27:04 +02:00
|
|
|
break;
|
|
|
|
case SIGINT:
|
|
|
|
case SIGQUIT:
|
2016-01-31 16:48:17 +01:00
|
|
|
case SIGTERM:
|
2014-07-31 13:27:04 +02:00
|
|
|
quit = 1;
|
|
|
|
kore_worker_dispatch_signal(sig_recv);
|
|
|
|
continue;
|
|
|
|
default:
|
|
|
|
kore_log(LOG_NOTICE,
|
|
|
|
"no action taken for signal %d", sig_recv);
|
|
|
|
break;
|
2013-06-26 16:37:22 +02:00
|
|
|
}
|
2014-07-31 13:27:04 +02:00
|
|
|
|
2013-06-26 16:37:22 +02:00
|
|
|
sig_recv = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
kore_worker_wait(0);
|
2015-06-22 21:13:32 +02:00
|
|
|
kore_platform_event_wait(100);
|
|
|
|
kore_connection_prune(KORE_CONNECTION_PRUNE_DISCONNECT);
|
2013-06-26 16:37:22 +02:00
|
|
|
}
|
2015-12-29 20:39:39 +01:00
|
|
|
|
2016-01-04 22:40:14 +01:00
|
|
|
kore_platform_event_cleanup();
|
|
|
|
kore_connection_cleanup();
|
2016-02-01 20:02:02 +01:00
|
|
|
kore_domain_cleanup();
|
2016-01-04 22:40:14 +01:00
|
|
|
net_cleanup();
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
|
2013-06-17 23:39:17 +02:00
|
|
|
static void
|
2013-06-26 11:18:32 +02:00
|
|
|
kore_write_kore_pid(void)
|
2013-06-04 16:53:30 +02:00
|
|
|
{
|
|
|
|
FILE *fp;
|
|
|
|
|
|
|
|
if ((fp = fopen(kore_pidfile, "w+")) == NULL) {
|
2014-07-31 17:15:51 +02:00
|
|
|
printf("warning: couldn't write pid to %s (%s)\n",
|
|
|
|
kore_pidfile, errno_s);
|
2013-06-04 16:53:30 +02:00
|
|
|
} else {
|
2013-06-26 11:18:32 +02:00
|
|
|
fprintf(fp, "%d\n", kore_pid);
|
2013-06-04 16:53:30 +02:00
|
|
|
fclose(fp);
|
|
|
|
}
|
|
|
|
}
|