From: Vladimír Čunát Date: Thu, 6 Jun 2024 12:27:43 +0000 (+0200) Subject: daemon: drop user-space buffering for sockets X-Git-Tag: v6.0.8^2~1^2~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7de51d25cdf07684453cc32b11ee82b079aaacd3;p=thirdparty%2Fknot-resolver.git daemon: drop user-space buffering for sockets --- diff --git a/daemon/session2.c b/daemon/session2.c index 09a4b362f..67d1c32db 100644 --- a/daemon/session2.c +++ b/daemon/session2.c @@ -1380,6 +1380,15 @@ static void session2_transport_pushv_ensure_long_lived( *iovcnt = 1; } +/// Count the total size of an iovec[] in bytes. +static inline size_t iovec_sum(const struct iovec iov[], const int iovcnt) +{ + size_t result = 0; + for (int i = 0; i < iovcnt; ++i) + result += iov[i].iov_len; + return result; +} + static int session2_transport_pushv(struct session2 *s, struct iovec *iov, int iovcnt, bool iov_short_lived, @@ -1433,7 +1442,7 @@ static int session2_transport_pushv(struct session2 *s, } else { int ret = uv_udp_try_send((uv_udp_t*)handle, (uv_buf_t *)iov, iovcnt, comm->comm_addr); - if (ret == UV_EAGAIN) { + if (false && ret == UV_EAGAIN) { // XXX: see uv_try_write() below uv_udp_send_t *req = malloc(sizeof(*req)); req->data = ctx; session2_transport_pushv_ensure_long_lived( @@ -1451,7 +1460,12 @@ static int session2_transport_pushv(struct session2 *s, } } else if (handle->type == UV_TCP) { int ret = uv_try_write((uv_stream_t *)handle, (uv_buf_t *)iov, iovcnt); - if (ret == UV_EAGAIN) { + // XXX: queueing disabled for now if the OS can't accept the data. + // Typically that happens when OS buffers are full. + // We were missing any handling of partial write success, too. + if (ret == UV_EAGAIN || (ret >= 0 && ret != iovec_sum(iov, iovcnt))) + ret = kr_error(ENOBUFS); + if (false && ret == UV_EAGAIN) { uv_write_t *req = malloc(sizeof(*req)); req->data = ctx; session2_transport_pushv_ensure_long_lived( @@ -1464,7 +1478,7 @@ static int session2_transport_pushv(struct session2 *s, } else { session2_transport_pushv_finished(ret, ctx); } - return ret; + return ret; // TODO: check again that errors ensure connection closure #if ENABLE_XDP } else if (handle->type == UV_POLL) { xdp_handle_data_t *xhd = handle->data; diff --git a/daemon/tls.c b/daemon/tls.c index c77c5c2b3..96f036f96 100644 --- a/daemon/tls.c +++ b/daemon/tls.c @@ -1184,6 +1184,9 @@ static ssize_t pl_tls_submit(gnutls_session_t tls_session, if (payload.type == PROTOLAYER_PAYLOAD_WIRE_BUF) payload = protolayer_payload_as_buffer(&payload); + // TODO: the handling of positive gnutls_record_send() is weird/confusing, + // but it seems caught later when checking gnutls_record_uncork() + if (payload.type == PROTOLAYER_PAYLOAD_BUFFER) { ssize_t count = gnutls_record_send(tls_session, payload.buffer.buf, payload.buffer.len);