From: Wouter Wijngaards Date: Mon, 15 Feb 2016 09:54:52 +0000 (+0000) Subject: - wait for sendto to drain socket buffers when they are full. X-Git-Tag: release-1.5.8~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9eeb489243cf2368df52adffeb86507a4f335a6d;p=thirdparty%2Funbound.git - wait for sendto to drain socket buffers when they are full. git-svn-id: file:///svn/unbound/trunk@3624 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 2ad8ae409..b290fbe40 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,5 +1,6 @@ 15 February 2016: Wouter - ip-transparent option for FreeBSD with IP_BINDANY socket option. + - wait for sendto to drain socket buffers when they are full. 9 February 2016: Wouter - Test for type OPENPGPKEY. diff --git a/util/netevent.c b/util/netevent.c index d7ab218aa..b827e6540 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -400,6 +400,31 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, sent = sendto(c->fd, (void*)sldns_buffer_begin(packet), sldns_buffer_remaining(packet), 0, addr, addrlen); + if(sent == -1) { + /* try again and block, waiting for IO to complete, + * we want to send the answer, and we will wait for + * the ethernet interface buffer to have space. */ +#ifndef USE_WINSOCK + if(errno == EAGAIN || +# ifdef EWOULDBLOCK + errno == EWOULDBLOCK || +# endif + errno == ENOBUFS) { +#else + if(WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAENOBUFS || + WSAGetLastError() == WSAEWOULDBLOCK) { +#endif + int e; + fd_set_block(c->fd); + sent = sendto(c->fd, (void*)sldns_buffer_begin(packet), + sldns_buffer_remaining(packet), 0, + addr, addrlen); + e = errno; + fd_set_nonblock(c->fd); + errno = e; + } + } if(sent == -1) { if(!udp_send_errno_needs_log(addr, addrlen)) return 0; @@ -553,6 +578,29 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, if(verbosity >= VERB_ALGO) p_ancil("send_udp over interface", r); sent = sendmsg(c->fd, &msg, 0); + if(sent == -1) { + /* try again and block, waiting for IO to complete, + * we want to send the answer, and we will wait for + * the ethernet interface buffer to have space. */ +#ifndef USE_WINSOCK + if(errno == EAGAIN || +# ifdef EWOULDBLOCK + errno == EWOULDBLOCK || +# endif + errno == ENOBUFS) { +#else + if(WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAENOBUFS || + WSAGetLastError() == WSAEWOULDBLOCK) { +#endif + int e; + fd_set_block(c->fd); + sent = sendmsg(c->fd, &msg, 0); + e = errno; + fd_set_nonblock(c->fd); + errno = e; + } + } if(sent == -1) { if(!udp_send_errno_needs_log(addr, addrlen)) return 0;