From 10a5a5880a8a902a3d09a485eacbc02be9e7cbdd Mon Sep 17 00:00:00 2001 From: "W.C.A. Wijngaards" Date: Wed, 31 Aug 2022 10:11:25 +0200 Subject: [PATCH] - Patch from Vadim Fedorenko that adds MSG_DONTWAIT to receive operations, so that instruction reordering does not cause mistakenly blocking socket operations. --- dnstap/dtstream.c | 2 +- dnstap/unbound-dnstap-socket.c | 2 +- doc/Changelog | 3 +++ util/net_help.h | 5 +++++ util/netevent.c | 12 ++++++------ 5 files changed, 16 insertions(+), 8 deletions(-) diff --git a/dnstap/dtstream.c b/dnstap/dtstream.c index a1dd9703e..377ae9916 100644 --- a/dnstap/dtstream.c +++ b/dnstap/dtstream.c @@ -954,7 +954,7 @@ static int dtio_write_more(struct dt_io_thread* dtio) * -1: continue, >0: number of bytes read into buffer */ static ssize_t receive_bytes(struct dt_io_thread* dtio, void* buf, size_t len) { ssize_t r; - r = recv(dtio->fd, (void*)buf, len, 0); + r = recv(dtio->fd, (void*)buf, len, MSG_DONTWAIT); if(r == -1) { char* to = dtio->socket_path; if(!to) to = dtio->ip_str; diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 63292fbca..1cc450277 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -617,7 +617,7 @@ static void log_data_frame(uint8_t* pkt, size_t len) static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf, size_t len) { - ssize_t ret = recv(fd, buf, len, 0); + ssize_t ret = recv(fd, buf, len, MSG_DONTWAIT); if(ret == 0) { /* closed */ if(verbosity) log_info("dnstap client stream closed from %s", diff --git a/doc/Changelog b/doc/Changelog index ed3812c69..10d16e6eb 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,9 @@ 31 August 2022: Wouter - Fix to avoid process wide fcntl calls mixed with nonblocking operations after a blocked write. + - Patch from Vadim Fedorenko that adds MSG_DONTWAIT to receive + operations, so that instruction reordering does not cause mistakenly + blocking socket operations. 22 August 2022: Wouter - Fix #741: systemd socket activation fails on IPv6. diff --git a/util/net_help.h b/util/net_help.h index 4dd398460..fc23b2181 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -96,6 +96,11 @@ extern uint16_t EDNS_ADVERTISED_SIZE; /** return a random 16-bit number given a random source */ #define GET_RANDOM_ID(rnd) (((unsigned)ub_random(rnd)>>8) & 0xffff) +/** define MSG_DONTWAIT for unsupported platforms */ +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 +#endif + /** minimal responses when positive answer */ extern int MINIMAL_RESPONSES; diff --git a/util/netevent.c b/util/netevent.c index 5bc8d8bcd..6e2412f5a 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -701,7 +701,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) msg.msg_controllen = sizeof(ancil.buf); #endif /* S_SPLINT_S */ msg.msg_flags = 0; - rcv = recvmsg(fd, &msg, 0); + rcv = recvmsg(fd, &msg, MSG_DONTWAIT); if(rcv == -1) { if(errno != EAGAIN && errno != EINTR && udp_recv_needs_log(errno)) { @@ -781,7 +781,7 @@ comm_point_udp_callback(int fd, short event, void* arg) log_assert(fd != -1); log_assert(sldns_buffer_remaining(rep.c->buffer) > 0); rcv = recvfrom(fd, (void*)sldns_buffer_begin(rep.c->buffer), - sldns_buffer_remaining(rep.c->buffer), 0, + sldns_buffer_remaining(rep.c->buffer), MSG_DONTWAIT, (struct sockaddr*)&rep.addr, &rep.addrlen); if(rcv == -1) { #ifndef USE_WINSOCK @@ -1703,7 +1703,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok) if(c->tcp_byte_count < sizeof(uint16_t)) { /* read length bytes */ r = recv(fd,(void*)sldns_buffer_at(c->buffer,c->tcp_byte_count), - sizeof(uint16_t)-c->tcp_byte_count, 0); + sizeof(uint16_t)-c->tcp_byte_count, MSG_DONTWAIT); if(r == 0) { if(c->tcp_req_info) return tcp_req_info_handle_read_close(c->tcp_req_info); @@ -1794,7 +1794,7 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok) if(sldns_buffer_remaining(c->buffer) == 0) log_err("in comm_point_tcp_handle_read buffer_remaining is not > 0 as expected, continuing with (harmless) 0 length recv"); r = recv(fd, (void*)sldns_buffer_current(c->buffer), - sldns_buffer_remaining(c->buffer), 0); + sldns_buffer_remaining(c->buffer), MSG_DONTWAIT); if(r == 0) { if(c->tcp_req_info) return tcp_req_info_handle_read_close(c->tcp_req_info); @@ -2336,7 +2336,7 @@ http_read_more(int fd, struct comm_point* c) ssize_t r; log_assert(sldns_buffer_remaining(c->buffer) > 0); r = recv(fd, (void*)sldns_buffer_current(c->buffer), - sldns_buffer_remaining(c->buffer), 0); + sldns_buffer_remaining(c->buffer), MSG_DONTWAIT); if(r == 0) { return 0; } else if(r == -1) { @@ -2774,7 +2774,7 @@ ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf, } #endif /* HAVE_SSL */ - ret = recv(h2_session->c->fd, buf, len, 0); + ret = recv(h2_session->c->fd, buf, len, MSG_DONTWAIT); if(ret == 0) { return NGHTTP2_ERR_EOF; } else if(ret < 0) { -- 2.47.2