2013-06-26 11:18:32 +02:00
|
|
|
/*
|
2022-01-31 22:02:06 +01:00
|
|
|
* Copyright (c) 2013-2022 Joris Vink <joris@coders.se>
|
2013-06-26 11:18:32 +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.
|
|
|
|
*/
|
|
|
|
|
2013-07-10 10:37:37 +02:00
|
|
|
#include <sys/param.h>
|
2013-06-26 11:18:32 +02:00
|
|
|
#include <sys/socket.h>
|
|
|
|
|
2013-10-26 00:48:09 +02:00
|
|
|
#include <netinet/tcp.h>
|
|
|
|
|
2018-02-14 13:48:49 +01:00
|
|
|
#include <inttypes.h>
|
2013-06-26 11:18:32 +02:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
#include "kore.h"
|
|
|
|
#include "http.h"
|
|
|
|
|
2013-07-15 10:13:36 +02:00
|
|
|
struct kore_pool connection_pool;
|
2015-06-22 21:13:32 +02:00
|
|
|
struct connection_list connections;
|
|
|
|
struct connection_list disconnected;
|
2013-07-15 10:13:36 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
kore_connection_init(void)
|
|
|
|
{
|
2018-02-14 13:48:49 +01:00
|
|
|
u_int32_t elm;
|
|
|
|
|
2015-06-22 21:13:32 +02:00
|
|
|
TAILQ_INIT(&connections);
|
|
|
|
TAILQ_INIT(&disconnected);
|
|
|
|
|
2018-02-14 13:48:49 +01:00
|
|
|
/* Add some overhead so we don't rollover for internal items. */
|
|
|
|
elm = worker_max_connections + 10;
|
|
|
|
|
2013-07-15 10:13:36 +02:00
|
|
|
kore_pool_init(&connection_pool, "connection_pool",
|
2018-02-14 13:48:49 +01:00
|
|
|
sizeof(struct connection), elm);
|
2013-07-15 10:13:36 +02:00
|
|
|
}
|
|
|
|
|
2015-12-29 20:39:39 +01:00
|
|
|
void
|
2016-01-04 22:40:14 +01:00
|
|
|
kore_connection_cleanup(void)
|
2015-12-29 20:39:39 +01:00
|
|
|
{
|
|
|
|
/* Drop all connections */
|
|
|
|
kore_connection_prune(KORE_CONNECTION_PRUNE_ALL);
|
2016-01-04 22:40:14 +01:00
|
|
|
kore_pool_cleanup(&connection_pool);
|
2015-12-29 20:39:39 +01:00
|
|
|
}
|
|
|
|
|
2014-09-17 08:25:45 +02:00
|
|
|
struct connection *
|
|
|
|
kore_connection_new(void *owner)
|
|
|
|
{
|
|
|
|
struct connection *c;
|
|
|
|
|
|
|
|
c = kore_pool_get(&connection_pool);
|
|
|
|
|
|
|
|
c->flags = 0;
|
2014-10-22 21:16:49 +02:00
|
|
|
c->rnb = NULL;
|
|
|
|
c->snb = NULL;
|
2014-09-17 08:25:45 +02:00
|
|
|
c->owner = owner;
|
2015-12-01 20:55:00 +01:00
|
|
|
c->handle = NULL;
|
2022-02-18 10:20:28 +01:00
|
|
|
|
|
|
|
c->tls = NULL;
|
|
|
|
c->tls_cert = NULL;
|
2019-11-19 11:09:24 +01:00
|
|
|
c->tls_reneg = 0;
|
|
|
|
c->tls_sni = NULL;
|
2022-02-18 10:20:28 +01:00
|
|
|
|
2014-09-17 08:25:45 +02:00
|
|
|
c->disconnect = NULL;
|
|
|
|
c->hdlr_extra = NULL;
|
|
|
|
c->proto = CONN_PROTO_UNKNOWN;
|
|
|
|
c->idle_timer.start = 0;
|
|
|
|
c->idle_timer.length = KORE_IDLE_TIMER_MAX;
|
|
|
|
|
2018-10-09 19:34:40 +02:00
|
|
|
c->evt.type = KORE_TYPE_CONNECTION;
|
|
|
|
c->evt.handle = kore_connection_event;
|
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2017-01-29 22:57:34 +01:00
|
|
|
c->ws_connect = NULL;
|
|
|
|
c->ws_message = NULL;
|
|
|
|
c->ws_disconnect = NULL;
|
2019-04-11 20:51:49 +02:00
|
|
|
c->http_start = kore_time_ms();
|
|
|
|
c->http_timeout = http_header_timeout * 1000;
|
2014-09-17 08:25:45 +02:00
|
|
|
TAILQ_INIT(&(c->http_requests));
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
TAILQ_INIT(&(c->send_queue));
|
2014-09-17 08:25:45 +02:00
|
|
|
|
|
|
|
return (c);
|
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
int
|
2015-11-27 16:22:50 +01:00
|
|
|
kore_connection_accept(struct listener *listener, struct connection **out)
|
2013-06-26 11:18:32 +02:00
|
|
|
{
|
|
|
|
struct connection *c;
|
2017-02-06 19:54:50 +01:00
|
|
|
struct sockaddr *s;
|
2013-07-27 20:56:15 +02:00
|
|
|
socklen_t len;
|
2013-06-26 11:18:32 +02:00
|
|
|
|
|
|
|
*out = NULL;
|
2015-11-27 16:22:50 +01:00
|
|
|
c = kore_connection_new(listener);
|
2013-07-27 20:56:15 +02:00
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
c->family = listener->family;
|
|
|
|
|
|
|
|
switch (c->family) {
|
|
|
|
case AF_INET:
|
2013-07-27 20:56:15 +02:00
|
|
|
len = sizeof(struct sockaddr_in);
|
2017-02-06 19:54:50 +01:00
|
|
|
s = (struct sockaddr *)&(c->addr.ipv4);
|
2018-10-07 20:49:16 +02:00
|
|
|
break;
|
|
|
|
case AF_INET6:
|
2013-07-27 20:56:15 +02:00
|
|
|
len = sizeof(struct sockaddr_in6);
|
2017-02-06 19:54:50 +01:00
|
|
|
s = (struct sockaddr *)&(c->addr.ipv6);
|
2018-10-07 20:49:16 +02:00
|
|
|
break;
|
|
|
|
case AF_UNIX:
|
|
|
|
len = sizeof(struct sockaddr_un);
|
2018-10-07 21:03:12 +02:00
|
|
|
s = (struct sockaddr *)&(c->addr.sun);
|
2018-10-07 20:49:16 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fatal("unknown family type %d", c->family);
|
2013-07-27 20:56:15 +02:00
|
|
|
}
|
|
|
|
|
2017-02-06 19:54:50 +01:00
|
|
|
if ((c->fd = accept(listener->fd, s, &len)) == -1) {
|
2013-07-15 10:13:36 +02:00
|
|
|
kore_pool_put(&connection_pool, c);
|
2013-06-26 11:18:32 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2018-10-07 20:49:16 +02:00
|
|
|
if (!kore_connection_nonblock(c->fd, listener->family != AF_UNIX)) {
|
2018-10-26 19:19:47 +02:00
|
|
|
close(c->fd);
|
|
|
|
kore_pool_put(&connection_pool, c);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fcntl(c->fd, F_SETFD, FD_CLOEXEC) == -1) {
|
2013-06-26 11:18:32 +02:00
|
|
|
close(c->fd);
|
2013-07-15 10:13:36 +02:00
|
|
|
kore_pool_put(&connection_pool, c);
|
2013-06-26 11:18:32 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2015-12-01 20:55:00 +01:00
|
|
|
c->handle = kore_connection_handle;
|
2015-11-27 16:22:50 +01:00
|
|
|
TAILQ_INSERT_TAIL(&connections, c, list);
|
|
|
|
|
2019-09-27 20:00:35 +02:00
|
|
|
if (listener->server->tls) {
|
2019-09-27 12:22:35 +02:00
|
|
|
c->state = CONN_STATE_TLS_SHAKE;
|
2022-02-17 13:45:28 +01:00
|
|
|
c->write = kore_tls_write;
|
|
|
|
c->read = kore_tls_read;
|
2015-11-27 16:22:50 +01:00
|
|
|
} else {
|
2019-09-27 12:22:35 +02:00
|
|
|
c->state = CONN_STATE_ESTABLISHED;
|
|
|
|
c->write = net_write;
|
|
|
|
c->read = net_read;
|
|
|
|
|
|
|
|
if (listener->connect != NULL) {
|
|
|
|
kore_runtime_connect(listener->connect, c);
|
|
|
|
} else {
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2019-09-27 12:22:35 +02:00
|
|
|
c->proto = CONN_PROTO_HTTP;
|
|
|
|
if (http_keepalive_time != 0) {
|
|
|
|
c->idle_timer.length =
|
|
|
|
http_keepalive_time * 1000;
|
|
|
|
}
|
|
|
|
net_recv_queue(c, http_header_max,
|
|
|
|
NETBUF_CALL_CB_ALWAYS, http_header_recv);
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
2019-09-27 12:22:35 +02:00
|
|
|
}
|
2015-11-27 16:22:50 +01:00
|
|
|
}
|
2014-08-01 10:22:32 +02:00
|
|
|
|
2013-07-01 12:08:51 +02:00
|
|
|
kore_connection_start_idletimer(c);
|
2016-10-06 16:50:02 +02:00
|
|
|
worker_active_connections++;
|
2013-06-26 11:18:32 +02:00
|
|
|
|
|
|
|
*out = c;
|
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
}
|
|
|
|
|
2015-06-22 21:13:32 +02:00
|
|
|
void
|
2018-02-14 13:48:49 +01:00
|
|
|
kore_connection_check_timeout(u_int64_t now)
|
2015-06-22 21:13:32 +02:00
|
|
|
{
|
2018-02-14 13:48:49 +01:00
|
|
|
struct connection *c, *next;
|
2015-06-22 21:13:32 +02:00
|
|
|
|
2018-02-14 13:48:49 +01:00
|
|
|
for (c = TAILQ_FIRST(&connections); c != NULL; c = next) {
|
|
|
|
next = TAILQ_NEXT(c, list);
|
2015-06-22 21:13:32 +02:00
|
|
|
if (c->proto == CONN_PROTO_MSG)
|
|
|
|
continue;
|
2018-04-09 14:20:26 +02:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2019-11-04 07:23:21 +01:00
|
|
|
if (c->state == CONN_STATE_ESTABLISHED &&
|
|
|
|
c->proto == CONN_PROTO_HTTP) {
|
2019-11-03 22:28:48 +01:00
|
|
|
if (!http_check_timeout(c, now))
|
|
|
|
continue;
|
|
|
|
if (!TAILQ_EMPTY(&c->http_requests))
|
|
|
|
continue;
|
|
|
|
}
|
2018-04-09 14:20:26 +02:00
|
|
|
#endif
|
2019-04-11 20:51:49 +02:00
|
|
|
if (c->flags & CONN_IDLE_TIMER_ACT)
|
|
|
|
kore_connection_check_idletimer(now, c);
|
2015-06-22 21:13:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_connection_prune(int all)
|
|
|
|
{
|
|
|
|
struct connection *c, *cnext;
|
|
|
|
|
|
|
|
if (all) {
|
2017-02-07 22:44:20 +01:00
|
|
|
for (c = TAILQ_FIRST(&connections); c != NULL; c = cnext) {
|
|
|
|
cnext = TAILQ_NEXT(c, list);
|
2015-06-22 21:13:32 +02:00
|
|
|
net_send_flush(c);
|
|
|
|
kore_connection_disconnect(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-07 22:44:20 +01:00
|
|
|
for (c = TAILQ_FIRST(&disconnected); c != NULL; c = cnext) {
|
|
|
|
cnext = TAILQ_NEXT(c, list);
|
2015-06-22 21:13:32 +02:00
|
|
|
TAILQ_REMOVE(&disconnected, c, list);
|
|
|
|
kore_connection_remove(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
void
|
|
|
|
kore_connection_disconnect(struct connection *c)
|
|
|
|
{
|
|
|
|
if (c->state != CONN_STATE_DISCONNECTING) {
|
|
|
|
c->state = CONN_STATE_DISCONNECTING;
|
2014-09-17 08:25:45 +02:00
|
|
|
if (c->disconnect)
|
|
|
|
c->disconnect(c);
|
|
|
|
|
2015-06-22 21:13:32 +02:00
|
|
|
TAILQ_REMOVE(&connections, c, list);
|
|
|
|
TAILQ_INSERT_TAIL(&disconnected, c, list);
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-09 19:34:40 +02:00
|
|
|
void
|
|
|
|
kore_connection_event(void *arg, int error)
|
|
|
|
{
|
|
|
|
struct connection *c = arg;
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
kore_connection_disconnect(c);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!c->handle(c))
|
|
|
|
kore_connection_disconnect(c);
|
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
int
|
|
|
|
kore_connection_handle(struct connection *c)
|
|
|
|
{
|
2015-11-27 16:22:50 +01:00
|
|
|
struct listener *listener;
|
2013-06-26 11:18:32 +02:00
|
|
|
|
2013-07-13 20:19:01 +02:00
|
|
|
kore_connection_stop_idletimer(c);
|
2013-07-01 12:08:51 +02:00
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
switch (c->state) {
|
2017-02-11 21:33:09 +01:00
|
|
|
case CONN_STATE_TLS_SHAKE:
|
2022-03-21 12:23:38 +01:00
|
|
|
switch (kore_tls_connection_accept(c)) {
|
|
|
|
case KORE_RESULT_OK:
|
|
|
|
break;
|
|
|
|
case KORE_RESULT_RETRY:
|
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
default:
|
2021-12-11 21:59:41 +01:00
|
|
|
return (KORE_RESULT_ERROR);
|
2022-03-21 12:23:38 +01:00
|
|
|
}
|
2014-03-05 11:38:47 +01:00
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
if (c->owner != NULL) {
|
|
|
|
listener = (struct listener *)c->owner;
|
|
|
|
if (listener->connect != NULL) {
|
2017-01-12 23:38:51 +01:00
|
|
|
kore_runtime_connect(listener->connect, c);
|
2019-02-08 15:40:00 +01:00
|
|
|
kore_connection_start_idletimer(c);
|
2015-12-01 20:55:00 +01:00
|
|
|
return (KORE_RESULT_OK);
|
2013-10-15 11:10:45 +02:00
|
|
|
}
|
2015-11-27 16:22:50 +01:00
|
|
|
}
|
2013-10-15 11:10:45 +02:00
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
|
|
|
c->proto = CONN_PROTO_HTTP;
|
|
|
|
if (http_keepalive_time != 0) {
|
|
|
|
c->idle_timer.length =
|
|
|
|
http_keepalive_time * 1000;
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
net_recv_queue(c, http_header_max,
|
|
|
|
NETBUF_CALL_CB_ALWAYS, http_header_recv);
|
|
|
|
#endif
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
c->state = CONN_STATE_ESTABLISHED;
|
|
|
|
/* FALLTHROUGH */
|
|
|
|
case CONN_STATE_ESTABLISHED:
|
2018-10-09 19:34:40 +02:00
|
|
|
if (c->evt.flags & KORE_EVENT_READ) {
|
2013-06-26 11:18:32 +02:00
|
|
|
if (!net_recv_flush(c))
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2018-10-09 19:34:40 +02:00
|
|
|
if (c->evt.flags & KORE_EVENT_WRITE) {
|
2013-06-26 11:18:32 +02:00
|
|
|
if (!net_send_flush(c))
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CONN_STATE_DISCONNECTING:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-07-13 20:19:01 +02:00
|
|
|
kore_connection_start_idletimer(c);
|
2013-07-01 12:08:51 +02:00
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_connection_remove(struct connection *c)
|
|
|
|
{
|
|
|
|
struct netbuf *nb, *next;
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2014-06-29 20:20:13 +02:00
|
|
|
struct http_request *req, *rnext;
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
2013-06-26 11:18:32 +02:00
|
|
|
|
2022-02-17 13:45:28 +01:00
|
|
|
kore_tls_connection_cleanup(c);
|
2019-11-19 11:09:24 +01:00
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
close(c->fd);
|
2013-08-14 16:09:09 +02:00
|
|
|
|
|
|
|
if (c->hdlr_extra != NULL)
|
2016-07-12 13:54:14 +02:00
|
|
|
kore_free(c->hdlr_extra);
|
2013-06-26 16:37:22 +02:00
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2017-02-07 22:44:20 +01:00
|
|
|
for (req = TAILQ_FIRST(&(c->http_requests));
|
|
|
|
req != NULL; req = rnext) {
|
|
|
|
rnext = TAILQ_NEXT(req, olist);
|
2014-07-27 21:01:14 +02:00
|
|
|
TAILQ_REMOVE(&(c->http_requests), req, olist);
|
2016-12-26 20:08:53 +01:00
|
|
|
req->owner = NULL;
|
2013-09-09 10:59:56 +02:00
|
|
|
req->flags |= HTTP_REQUEST_DELETE;
|
2014-07-04 16:51:19 +02:00
|
|
|
http_request_wakeup(req);
|
2014-06-29 20:20:13 +02:00
|
|
|
}
|
2017-01-29 22:57:34 +01:00
|
|
|
|
|
|
|
kore_free(c->ws_connect);
|
|
|
|
kore_free(c->ws_message);
|
|
|
|
kore_free(c->ws_disconnect);
|
2015-11-27 16:22:50 +01:00
|
|
|
#endif
|
2013-09-09 10:59:56 +02:00
|
|
|
|
2017-02-07 22:44:20 +01:00
|
|
|
for (nb = TAILQ_FIRST(&(c->send_queue)); nb != NULL; nb = next) {
|
|
|
|
next = TAILQ_NEXT(nb, list);
|
2018-06-28 13:27:44 +02:00
|
|
|
nb->flags &= ~NETBUF_MUST_RESEND;
|
2018-12-22 09:25:00 +01:00
|
|
|
net_remove_netbuf(c, nb);
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
|
2014-10-22 21:16:49 +02:00
|
|
|
if (c->rnb != NULL) {
|
2016-07-12 13:54:14 +02:00
|
|
|
kore_free(c->rnb->buf);
|
2014-10-22 21:16:49 +02:00
|
|
|
kore_pool_put(&nb_pool, c->rnb);
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
|
2013-07-15 10:13:36 +02:00
|
|
|
kore_pool_put(&connection_pool, c);
|
2016-10-06 16:50:02 +02:00
|
|
|
worker_active_connections--;
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
|
2013-07-01 12:08:51 +02:00
|
|
|
void
|
|
|
|
kore_connection_check_idletimer(u_int64_t now, struct connection *c)
|
|
|
|
{
|
|
|
|
u_int64_t d;
|
|
|
|
|
2018-02-14 13:48:49 +01:00
|
|
|
if (now > c->idle_timer.start)
|
|
|
|
d = now - c->idle_timer.start;
|
|
|
|
else
|
|
|
|
d = 0;
|
|
|
|
|
2022-08-18 15:20:55 +02:00
|
|
|
if (d >= c->idle_timer.length)
|
2015-11-27 16:22:50 +01:00
|
|
|
kore_connection_disconnect(c);
|
2013-07-01 12:08:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_connection_start_idletimer(struct connection *c)
|
|
|
|
{
|
|
|
|
c->flags |= CONN_IDLE_TIMER_ACT;
|
|
|
|
c->idle_timer.start = kore_time_ms();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_connection_stop_idletimer(struct connection *c)
|
|
|
|
{
|
|
|
|
c->flags &= ~CONN_IDLE_TIMER_ACT;
|
|
|
|
c->idle_timer.start = 0;
|
|
|
|
}
|
|
|
|
|
2013-06-26 16:37:22 +02:00
|
|
|
int
|
2015-06-22 22:11:03 +02:00
|
|
|
kore_connection_nonblock(int fd, int nodelay)
|
2013-06-26 11:18:32 +02:00
|
|
|
{
|
|
|
|
int flags;
|
|
|
|
|
2022-08-18 15:20:55 +02:00
|
|
|
if ((flags = fcntl(fd, F_GETFL, 0)) == -1)
|
2013-06-26 11:18:32 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
|
|
|
|
flags |= O_NONBLOCK;
|
2022-08-18 15:20:55 +02:00
|
|
|
if (fcntl(fd, F_SETFL, flags) == -1)
|
2013-06-26 11:18:32 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
|
2015-06-22 22:11:03 +02:00
|
|
|
if (nodelay) {
|
2017-02-22 22:23:30 +01:00
|
|
|
if (!kore_sockopt(fd, IPPROTO_TCP, TCP_NODELAY)) {
|
2015-06-22 22:11:03 +02:00
|
|
|
kore_log(LOG_NOTICE,
|
|
|
|
"failed to set TCP_NODELAY on %d", fd);
|
|
|
|
}
|
2013-10-26 00:48:09 +02:00
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
}
|
2022-09-05 10:59:06 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
kore_connection_log(struct connection *c, const char *fmt, ...)
|
|
|
|
{
|
|
|
|
struct kore_buf buf;
|
|
|
|
va_list args;
|
|
|
|
char *ptr;
|
|
|
|
|
|
|
|
kore_buf_init(&buf, 128);
|
|
|
|
kore_buf_appendf(&buf, "ip=[%s] msg=[", kore_connection_ip(c));
|
|
|
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
kore_buf_appendv(&buf, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
kore_buf_appendf(&buf, "]");
|
|
|
|
|
|
|
|
ptr = kore_buf_stringify(&buf, NULL);
|
|
|
|
kore_log(LOG_NOTICE, "%s", ptr);
|
|
|
|
kore_free(ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
kore_connection_ip(struct connection *c)
|
|
|
|
{
|
|
|
|
static char addr[INET6_ADDRSTRLEN];
|
|
|
|
|
|
|
|
memset(addr, 0, sizeof(addr));
|
|
|
|
|
|
|
|
switch (c->family) {
|
|
|
|
case AF_INET:
|
|
|
|
if (inet_ntop(c->family,
|
|
|
|
&(c->addr.ipv4.sin_addr), addr, sizeof(addr)) == NULL)
|
|
|
|
fatal("inet_ntop: %s", errno_s);
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
|
|
if (inet_ntop(c->family,
|
|
|
|
&(c->addr.ipv6.sin6_addr), addr, sizeof(addr)) == NULL)
|
|
|
|
fatal("inet_ntop: %s", errno_s);
|
|
|
|
break;
|
|
|
|
case AF_UNIX:
|
|
|
|
(void)kore_strlcpy(addr, "unix-socket", sizeof(addr));
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
fatal("unknown family %d", c->family);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (addr);
|
|
|
|
}
|