2013-06-26 11:18:32 +02:00
|
|
|
/*
|
2018-01-20 22:51:06 +01:00
|
|
|
* Copyright (c) 2013-2018 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
|
|
|
{
|
2016-01-04 22:40:14 +01:00
|
|
|
kore_debug("connection_cleanup()");
|
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);
|
|
|
|
|
2016-01-07 09:20:09 +01:00
|
|
|
#if !defined(KORE_NO_TLS)
|
2014-09-17 08:25:45 +02:00
|
|
|
c->ssl = NULL;
|
2016-01-07 09:20:09 +01:00
|
|
|
c->cert = NULL;
|
|
|
|
c->tls_reneg = 0;
|
|
|
|
#endif
|
2014-09-17 08:25:45 +02:00
|
|
|
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;
|
2014-09-17 08:25:45 +02:00
|
|
|
c->disconnect = NULL;
|
|
|
|
c->hdlr_extra = NULL;
|
|
|
|
c->proto = CONN_PROTO_UNKNOWN;
|
|
|
|
c->type = KORE_TYPE_CONNECTION;
|
|
|
|
c->idle_timer.start = 0;
|
|
|
|
c->idle_timer.length = KORE_IDLE_TIMER_MAX;
|
|
|
|
|
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;
|
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
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
kore_debug("kore_connection_accept(%p)", listener);
|
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
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
c->addrtype = listener->addrtype;
|
2013-07-27 20:56:15 +02:00
|
|
|
if (c->addrtype == AF_INET) {
|
|
|
|
len = sizeof(struct sockaddr_in);
|
2017-02-06 19:54:50 +01:00
|
|
|
s = (struct sockaddr *)&(c->addr.ipv4);
|
2013-07-27 20:56:15 +02:00
|
|
|
} else {
|
|
|
|
len = sizeof(struct sockaddr_in6);
|
2017-02-06 19:54:50 +01:00
|
|
|
s = (struct sockaddr *)&(c->addr.ipv6);
|
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
|
|
|
kore_debug("accept(): %s", errno_s);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2015-06-22 22:11:03 +02:00
|
|
|
if (!kore_connection_nonblock(c->fd, 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);
|
|
|
|
|
2015-05-25 15:42:34 +02:00
|
|
|
#if !defined(KORE_NO_TLS)
|
2017-02-11 21:33:09 +01:00
|
|
|
c->state = CONN_STATE_TLS_SHAKE;
|
|
|
|
c->write = net_write_tls;
|
|
|
|
c->read = net_read_tls;
|
2014-08-01 10:22:32 +02:00
|
|
|
#else
|
|
|
|
c->state = CONN_STATE_ESTABLISHED;
|
2014-09-17 08:25:45 +02:00
|
|
|
c->write = net_write;
|
|
|
|
c->read = net_read;
|
|
|
|
|
2015-11-27 16:22:50 +01:00
|
|
|
if (listener->connect != NULL) {
|
2017-01-12 23:38:51 +01:00
|
|
|
kore_runtime_connect(listener->connect, c);
|
2015-11-27 16:22:50 +01:00
|
|
|
} else {
|
|
|
|
#if !defined(KORE_NO_HTTP)
|
|
|
|
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);
|
|
|
|
#endif
|
|
|
|
}
|
2014-08-01 10:22:32 +02:00
|
|
|
#endif
|
|
|
|
|
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;
|
|
|
|
if (!(c->flags & CONN_IDLE_TIMER_ACT))
|
|
|
|
continue;
|
2018-04-09 14:20:26 +02:00
|
|
|
#if !defined(KORE_NO_HTTP)
|
2018-03-14 13:35:47 +01:00
|
|
|
if (!TAILQ_EMPTY(&c->http_requests))
|
|
|
|
continue;
|
2018-04-09 14:20:26 +02:00
|
|
|
#endif
|
2015-06-22 21:13:32 +02:00
|
|
|
kore_connection_check_idletimer(now, c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
kore_debug("preparing %p for disconnection", c);
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
kore_connection_handle(struct connection *c)
|
|
|
|
{
|
2015-05-25 15:42:34 +02:00
|
|
|
#if !defined(KORE_NO_TLS)
|
2013-06-26 11:18:32 +02:00
|
|
|
int r;
|
2015-11-27 16:22:50 +01:00
|
|
|
struct listener *listener;
|
2014-03-05 11:38:47 +01:00
|
|
|
char cn[X509_CN_LENGTH];
|
2014-08-01 10:22:32 +02:00
|
|
|
#endif
|
2013-06-26 11:18:32 +02:00
|
|
|
|
2014-06-29 14:15:40 +02:00
|
|
|
kore_debug("kore_connection_handle(%p) -> %d", c, c->state);
|
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) {
|
2015-05-25 15:42:34 +02:00
|
|
|
#if !defined(KORE_NO_TLS)
|
2017-02-11 21:33:09 +01:00
|
|
|
case CONN_STATE_TLS_SHAKE:
|
2018-07-11 09:44:29 +02:00
|
|
|
if (primary_dom->ssl_ctx == NULL) {
|
2018-07-11 09:52:05 +02:00
|
|
|
kore_log(LOG_NOTICE,
|
|
|
|
"TLS configuration for %s not yet complete",
|
|
|
|
primary_dom->domain);
|
2018-07-11 09:44:29 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
if (c->ssl == NULL) {
|
|
|
|
c->ssl = SSL_new(primary_dom->ssl_ctx);
|
|
|
|
if (c->ssl == NULL) {
|
|
|
|
kore_debug("SSL_new(): %s", ssl_errno_s);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
SSL_set_fd(c->ssl, c->fd);
|
2013-06-27 12:37:42 +02:00
|
|
|
SSL_set_accept_state(c->ssl);
|
2015-05-20 16:36:13 +02:00
|
|
|
SSL_set_app_data(c->ssl, c);
|
2013-06-26 11:18:32 +02:00
|
|
|
}
|
|
|
|
|
2016-12-05 14:44:58 +01:00
|
|
|
ERR_clear_error();
|
2013-06-26 11:18:32 +02:00
|
|
|
r = SSL_accept(c->ssl);
|
|
|
|
if (r <= 0) {
|
|
|
|
r = SSL_get_error(c->ssl, r);
|
|
|
|
switch (r) {
|
|
|
|
case SSL_ERROR_WANT_READ:
|
|
|
|
case SSL_ERROR_WANT_WRITE:
|
|
|
|
return (KORE_RESULT_OK);
|
|
|
|
default:
|
|
|
|
kore_debug("SSL_accept(): %s", ssl_errno_s);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-05 11:38:47 +01:00
|
|
|
if (SSL_get_verify_mode(c->ssl) & SSL_VERIFY_PEER) {
|
|
|
|
c->cert = SSL_get_peer_certificate(c->ssl);
|
|
|
|
if (c->cert == NULL) {
|
|
|
|
kore_log(LOG_NOTICE,
|
|
|
|
"no client certificate presented?");
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (X509_GET_CN(c->cert, cn, sizeof(cn)) == -1) {
|
|
|
|
kore_log(LOG_NOTICE,
|
|
|
|
"no CN found in client certificate");
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
2015-11-27 16:22:50 +01:00
|
|
|
} else {
|
|
|
|
c->cert = NULL;
|
2014-03-05 11:38:47 +01:00
|
|
|
}
|
|
|
|
|
2013-06-26 11:18:32 +02:00
|
|
|
r = SSL_get_verify_result(c->ssl);
|
|
|
|
if (r != X509_V_OK) {
|
2013-12-14 16:31:07 +01:00
|
|
|
kore_debug("SSL_get_verify_result(): %d, %s",
|
|
|
|
r, ssl_errno_s);
|
2013-06-26 11:18:32 +02:00
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
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);
|
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 */
|
2015-05-25 15:42:34 +02:00
|
|
|
#endif /* !KORE_NO_TLS */
|
2013-06-26 11:18:32 +02:00
|
|
|
case CONN_STATE_ESTABLISHED:
|
|
|
|
if (c->flags & CONN_READ_POSSIBLE) {
|
|
|
|
if (!net_recv_flush(c))
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c->flags & CONN_WRITE_POSSIBLE) {
|
|
|
|
if (!net_send_flush(c))
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CONN_STATE_DISCONNECTING:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
kore_debug("unknown state on %d (%d)", c->fd, c->state);
|
|
|
|
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
|
|
|
|
|
|
|
kore_debug("kore_connection_remove(%p)", c);
|
|
|
|
|
2015-05-25 15:42:34 +02:00
|
|
|
#if !defined(KORE_NO_TLS)
|
2014-01-29 22:48:51 +01:00
|
|
|
if (c->ssl != NULL) {
|
|
|
|
SSL_shutdown(c->ssl);
|
2013-06-26 11:18:32 +02:00
|
|
|
SSL_free(c->ssl);
|
2014-01-29 22:48:51 +01:00
|
|
|
}
|
|
|
|
|
2014-03-05 11:38:47 +01:00
|
|
|
if (c->cert != NULL)
|
|
|
|
X509_free(c->cert);
|
2014-08-01 10:22:32 +02:00
|
|
|
#endif
|
2014-03-05 11:38:47 +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;
|
|
|
|
net_remove_netbuf(&(c->send_queue), 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;
|
|
|
|
|
2013-07-01 12:08:51 +02:00
|
|
|
if (d >= c->idle_timer.length) {
|
2018-02-14 13:48:49 +01:00
|
|
|
kore_debug("%p idle for %" PRIu64 " ms, expiring", c, d);
|
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)
|
|
|
|
{
|
|
|
|
kore_debug("kore_connection_start_idletimer(%p)", c);
|
|
|
|
|
|
|
|
c->flags |= CONN_IDLE_TIMER_ACT;
|
|
|
|
c->idle_timer.start = kore_time_ms();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
kore_connection_stop_idletimer(struct connection *c)
|
|
|
|
{
|
|
|
|
kore_debug("kore_connection_stop_idletimer(%p)", 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;
|
|
|
|
|
|
|
|
kore_debug("kore_connection_nonblock(%d)", fd);
|
|
|
|
|
|
|
|
if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
|
|
|
|
kore_debug("fcntl(): F_GETFL %s", errno_s);
|
|
|
|
return (KORE_RESULT_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
flags |= O_NONBLOCK;
|
|
|
|
if (fcntl(fd, F_SETFL, flags) == -1) {
|
|
|
|
kore_debug("fcntl(): F_SETFL %s", errno_s);
|
|
|
|
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);
|
|
|
|
}
|