1
0
mirror of https://git.kore.io/kore.git synced 2024-11-15 22:46:21 +01:00

allow kore to bind to unix sockets via bind_unix.

This commit is contained in:
Joris Vink 2018-10-07 20:49:16 +02:00
parent f87624a459
commit 442bdef79b
6 changed files with 158 additions and 64 deletions

View File

@ -24,6 +24,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@ -214,10 +215,11 @@ struct connection {
int (*read)(struct connection *, size_t *);
int (*write)(struct connection *, size_t, size_t *);
u_int8_t addrtype;
int family;
union {
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
struct sockaddr_un unix;
} addr;
struct {
@ -271,15 +273,10 @@ extern struct kore_runtime kore_native_runtime;
struct listener {
u_int8_t type;
u_int8_t addrtype;
int fd;
int family;
struct kore_runtime_call *connect;
union {
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
} addr;
LIST_ENTRY(listener) list;
};
@ -593,6 +590,9 @@ struct kore_timer *kore_timer_add(void (*cb)(void *, u_int64_t),
int kore_sockopt(int, int, int);
void kore_listener_cleanup(void);
void kore_listener_free(struct listener *);
struct listener *kore_listener_alloc(int, const char *);
int kore_server_bind_unix(const char *, const char *);
int kore_server_bind(const char *, const char *, const char *);
#if !defined(KORE_NO_TLS)
int kore_tls_sni_cb(SSL *, int *, void *);

View File

@ -26,7 +26,7 @@ struct kore_log_packet {
u_int8_t method;
int status;
size_t length;
u_int8_t addrtype;
int family;
u_int8_t addr[sizeof(struct in6_addr)];
char host[KORE_DOMAINNAME_LEN];
char path[HTTP_URI_LEN];
@ -102,9 +102,13 @@ kore_accesslog_write(const void *data, u_int32_t len)
cn = logpacket.cn;
#endif
if (inet_ntop(logpacket.addrtype, &(logpacket.addr),
addr, sizeof(addr)) == NULL)
(void)kore_strlcpy(addr, "-", sizeof(addr));
if (logpacket.family != AF_UNIX) {
if (inet_ntop(logpacket.family, &(logpacket.addr),
addr, sizeof(addr)) == NULL)
(void)kore_strlcpy(addr, "-", sizeof(addr));
} else {
(void)kore_strlcpy(addr, "unix-socket", sizeof(addr));
}
time(&now);
tm = localtime(&now);
@ -140,15 +144,21 @@ kore_accesslog(struct http_request *req)
{
struct kore_log_packet logpacket;
logpacket.addrtype = req->owner->addrtype;
if (logpacket.addrtype == AF_INET) {
logpacket.family = req->owner->family;
switch (logpacket.family) {
case AF_INET:
memcpy(logpacket.addr,
&(req->owner->addr.ipv4.sin_addr),
sizeof(req->owner->addr.ipv4.sin_addr));
} else {
break;
case AF_INET6:
memcpy(logpacket.addr,
&(req->owner->addr.ipv6.sin6_addr),
sizeof(req->owner->addr.ipv6.sin6_addr));
break;
default:
break;
}
logpacket.status = req->status;

View File

@ -52,6 +52,7 @@ extern u_int32_t asset_len_builtin_kore_conf;
static int configure_include(char *);
static int configure_bind(char *);
static int configure_bind_unix(char *);
static int configure_domain(char *);
static int configure_root(char *);
static int configure_runas(char *);
@ -130,6 +131,7 @@ static struct {
} config_names[] = {
{ "include", configure_include },
{ "bind", configure_bind },
{ "bind_unix", configure_bind_unix },
{ "load", configure_load },
#if defined(KORE_USE_PYTHON)
{ "python_path", configure_python_path },
@ -374,6 +376,18 @@ configure_bind(char *options)
return (kore_server_bind(argv[0], argv[1], argv[2]));
}
static int
configure_bind_unix(char *options)
{
char *argv[3];
kore_split_string(options, " ", argv, 3);
if (argv[0] == NULL)
return (KORE_RESULT_ERROR);
return (kore_server_bind_unix(argv[0], argv[1]));
}
static int
configure_load(char *options)
{

View File

@ -102,13 +102,23 @@ kore_connection_accept(struct listener *listener, struct connection **out)
*out = NULL;
c = kore_connection_new(listener);
c->addrtype = listener->addrtype;
if (c->addrtype == AF_INET) {
c->family = listener->family;
switch (c->family) {
case AF_INET:
len = sizeof(struct sockaddr_in);
s = (struct sockaddr *)&(c->addr.ipv4);
} else {
break;
case AF_INET6:
len = sizeof(struct sockaddr_in6);
s = (struct sockaddr *)&(c->addr.ipv6);
break;
case AF_UNIX:
len = sizeof(struct sockaddr_un);
s = (struct sockaddr *)&(c->addr.unix);
break;
default:
fatal("unknown family type %d", c->family);
}
if ((c->fd = accept(listener->fd, s, &len)) == -1) {
@ -117,7 +127,7 @@ kore_connection_accept(struct listener *listener, struct connection **out)
return (KORE_RESULT_ERROR);
}
if (!kore_connection_nonblock(c->fd, 1)) {
if (!kore_connection_nonblock(c->fd, listener->family != AF_UNIX)) {
close(c->fd);
kore_pool_put(&connection_pool, c);
return (KORE_RESULT_ERROR);

View File

@ -1398,7 +1398,7 @@ http_request_new(struct connection *c, const char *host,
hp = NULL;
switch (c->addrtype) {
switch (c->family) {
case AF_INET6:
if (*host == '[') {
if ((hp = strrchr(host, ']')) == NULL) {

View File

@ -16,6 +16,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <sys/resource.h>
@ -299,37 +300,13 @@ kore_server_bind(const char *ip, const char *port, const char *ccb)
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_free(l);
freeaddrinfo(results);
kore_log(LOG_ERR, "socket(): %s", errno_s);
return (KORE_RESULT_ERROR);
}
if (!kore_connection_nonblock(l->fd, 1)) {
kore_free(l);
freeaddrinfo(results);
kore_log(LOG_ERR, "kore_connection_nonblock(): %s", errno_s);
return (KORE_RESULT_ERROR);
}
if (!kore_sockopt(l->fd, SOL_SOCKET, SO_REUSEADDR)) {
close(l->fd);
kore_free(l);
if ((l = kore_listener_alloc(results->ai_family, ccb)) == NULL) {
freeaddrinfo(results);
return (KORE_RESULT_ERROR);
}
if (bind(l->fd, results->ai_addr, results->ai_addrlen) == -1) {
close(l->fd);
kore_free(l);
kore_listener_free(l);
freeaddrinfo(results);
kore_log(LOG_ERR, "bind(): %s", errno_s);
return (KORE_RESULT_ERROR);
@ -338,26 +315,11 @@ kore_server_bind(const char *ip, const char *port, const char *ccb)
freeaddrinfo(results);
if (listen(l->fd, kore_socket_backlog) == -1) {
close(l->fd);
kore_free(l);
kore_listener_free(l);
kore_log(LOG_ERR, "listen(): %s", errno_s);
return (KORE_RESULT_ERROR);
}
if (ccb != NULL) {
if ((l->connect = kore_runtime_getcall(ccb)) == NULL) {
kore_log(LOG_ERR, "no such callback: '%s'", ccb);
close(l->fd);
kore_free(l);
return (KORE_RESULT_ERROR);
}
} else {
l->connect = NULL;
}
nlisteners++;
LIST_INSERT_HEAD(&listeners, l, list);
if (foreground) {
#if !defined(KORE_NO_TLS)
kore_log(LOG_NOTICE, "running on https://%s:%s", ip, port);
@ -369,6 +331,106 @@ kore_server_bind(const char *ip, const char *port, const char *ccb)
return (KORE_RESULT_OK);
}
int
kore_server_bind_unix(const char *path, const char *ccb)
{
struct listener *l;
struct sockaddr_un sun;
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
if (kore_strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >=
sizeof(sun.sun_path)) {
kore_log(LOG_ERR, "unix socket path '%s' too long", path);
return (KORE_RESULT_ERROR);
}
if ((l = kore_listener_alloc(AF_UNIX, ccb)) == NULL)
return (KORE_RESULT_ERROR);
if (bind(l->fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
kore_log(LOG_ERR, "bind: %s", errno_s);
kore_listener_free(l);
return (KORE_RESULT_ERROR);
}
if (listen(l->fd, kore_socket_backlog) == -1) {
kore_log(LOG_ERR, "listen(): %s", errno_s);
kore_listener_free(l);
return (KORE_RESULT_ERROR);
}
if (foreground)
kore_log(LOG_NOTICE, "running on %s", path);
return (KORE_RESULT_OK);
}
struct listener *
kore_listener_alloc(int family, const char *ccb)
{
struct listener *l;
switch (family) {
case AF_INET:
case AF_INET6:
case AF_UNIX:
break;
default:
fatal("unknown address family %d", family);
}
l = kore_calloc(1, sizeof(struct listener));
l->fd = -1;
l->family = family;
l->type = KORE_TYPE_LISTENER;
if ((l->fd = socket(family, SOCK_STREAM, 0)) == -1) {
kore_listener_free(l);
kore_log(LOG_ERR, "socket(): %s", errno_s);
return (NULL);
}
if (!kore_connection_nonblock(l->fd, 1)) {
kore_listener_free(l);
kore_log(LOG_ERR, "kore_connection_nonblock(): %s", errno_s);
return (NULL);
}
if (!kore_sockopt(l->fd, SOL_SOCKET, SO_REUSEADDR)) {
kore_listener_free(l);
return (NULL);
}
if (ccb != NULL) {
if ((l->connect = kore_runtime_getcall(ccb)) == NULL) {
kore_log(LOG_ERR, "no such callback: '%s'", ccb);
kore_listener_free(l);
return (NULL);
}
} else {
l->connect = NULL;
}
nlisteners++;
LIST_INSERT_HEAD(&listeners, l, list);
return (l);
}
void
kore_listener_free(struct listener *l)
{
LIST_REMOVE(l, list);
if (l->fd != -1)
close(l->fd);
kore_free(l);
}
int
kore_sockopt(int fd, int what, int opt)
{
@ -421,9 +483,7 @@ kore_listener_cleanup(void)
while (!LIST_EMPTY(&listeners)) {
l = LIST_FIRST(&listeners);
LIST_REMOVE(l, list);
close(l->fd);
kore_free(l);
kore_listener_free(l);
}
}