From: Mark Andrews Date: Tue, 26 Mar 2013 05:41:49 +0000 (+1100) Subject: check that sent packet arrives X-Git-Tag: v9.10.0a1~448^2~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d8c1e4eccf5bf88a3b4f8dc4a24391b5712bb3a3;p=thirdparty%2Fbind9.git check that sent packet arrives --- diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c index 4c51b6fe58e..38227c5e1ee 100644 --- a/lib/isc/unix/net.c +++ b/lib/isc/unix/net.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -450,6 +451,40 @@ cmsg_space(ISC_SOCKADDR_LEN_T len) { } #ifdef ISC_NET_BSD44MSGHDR +/* + * Make a fd non-blocking. + */ +static isc_result_t +make_nonblock(int fd) { + int ret; + int flags; + char strbuf[ISC_STRERRORSIZE]; +#ifdef USE_FIONBIO_IOCTL + int on = 1; + + ret = ioctl(fd, FIONBIO, (char *)&on); +#else + flags = fcntl(fd, F_GETFL, 0); + flags |= PORT_NONBLOCK; + ret = fcntl(fd, F_SETFL, flags); +#endif + + if (ret == -1) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, +#ifdef USE_FIONBIO_IOCTL + "ioctl(%d, FIONBIO, &on): %s", fd, +#else + "fcntl(%d, F_SETFL, %d): %s", fd, flags, +#endif + strbuf); + + return (ISC_R_UNEXPECTED); + } + + return (ISC_R_SUCCESS); +} + static isc_boolean_t cmsgsend(int s, int level, int type, struct addrinfo *res) { char strbuf[ISC_STRERRORSIZE]; @@ -463,6 +498,8 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { struct cmsghdr *cmsgp; int dscp = 46; struct iovec iovec = { (void *)&iovec, sizeof(iovec) }; + char buf[sizeof(iovec)]; + isc_result_t result; if (bind(s, res->ai_addr, res->ai_addrlen) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); @@ -523,6 +560,27 @@ cmsgsend(int s, int level, int type, struct addrinfo *res) { return (ISC_FALSE); } + /* + * Make sure the message actually got sent. + */ + result = make_nonblock(s); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + iovec.iov_base = buf; + iovec.iov_len = sizeof(len); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = (struct sockaddr *)&ss; + msg.msg_namelen = sizeof(ss); + msg.msg_iov = &iovec; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + if (recvmsg(s, &msg, 0) < 0) + return (ISC_FALSE); + return (ISC_TRUE); } #endif