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:
parent
f87624a459
commit
442bdef79b
@ -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 *);
|
||||
|
@ -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;
|
||||
|
14
src/config.c
14
src/config.c
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
150
src/kore.c
150
src/kore.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user