From bddb6ef78e0019007dcb782eba03ea274efc8bcd Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 2 Feb 2006 23:13:27 +0000 Subject: [PATCH] 1978. [port] Handle systems which have a broken recvmsg(). [RT #15742] --- CHANGES | 3 +++ config.h.in | 6 +++++- configure | 16 +++++++++++++++- configure.in | 13 ++++++++++++- lib/isc/unix/socket.c | 24 +++++++++++++++++++++++- 5 files changed, 58 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index b38f610883..4b9805e8c2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1978. [port] Handle systems which have a broken recvmsg(). + [RT #15742] + 1977. [bug] Silence noisy log message. [RT #15704] 1976. [bug] Handle systems with no IPv4 addresses. [RT #15695] diff --git a/config.h.in b/config.h.in index f2b22e1606..226611cd2c 100644 --- a/config.h.in +++ b/config.h.in @@ -16,7 +16,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: config.h.in,v 1.47.2.18 2006/01/04 04:27:30 marka Exp $ */ +/* $Id: config.h.in,v 1.47.2.20 2006/02/02 23:13:27 marka Exp $ */ /*** *** This file is not to be included by any public header files, because @@ -137,6 +137,10 @@ int sigwait(const unsigned int *set, int *sig); /* Define if threads need PTHREAD_SCOPE_SYSTEM */ #undef NEED_PTHREAD_SCOPE_SYSTEM +/* Define if recvmsg() does not meet all of the BSD socket API specifications. + */ +#undef BROKEN_RECVMSG + /* Define if you cannot bind() before connect() for TCP sockets. */ #undef BROKEN_TCP_BIND_BEFORE_CONNECT diff --git a/configure b/configure index e7a8e7ea6b..d58e402d54 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.in Revision: 1.294.2.57 . +# From configure.in Revision: 1.294.2.58 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59. # @@ -25812,6 +25812,20 @@ fi rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +# +# Some hosts need msg_namelen to match the size of the socket stucture. +# Some hosts don't set msg_namelen appropriately on return from recvmsg(). +# +case $host in +*os2*|*hp-mpeix*) + +cat >>confdefs.h <<\_ACEOF +#define BROKEN_RECVMSG 1 +_ACEOF + + ;; +esac + # # Microsoft has their own way of handling shared libraries that requires # additional qualifiers on extern variables. Unix systems don't need it. diff --git a/configure.in b/configure.in index 0497c7cc7e..0fd87385cb 100644 --- a/configure.in +++ b/configure.in @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -AC_REVISION($Revision: 1.294.2.57 $) +AC_REVISION($Revision: 1.294.2.58 $) AC_INIT(lib/dns/name.c) AC_PREREQ(2.13) @@ -1553,6 +1553,17 @@ AC_MSG_RESULT(cannot determine type of rlim_cur when cross compiling - assuming ]) AC_SUBST(ISC_PLATFORM_RLIMITTYPE) +# +# Some hosts need msg_namelen to match the size of the socket stucture. +# Some hosts don't set msg_namelen appropriately on return from recvmsg(). +# +case $host in +*os2*|*hp-mpeix*) + AC_DEFINE(BROKEN_RECVMSG, 1, + [Define if recvmsg() does not meet all of the BSD socket API specifications.]) + ;; +esac + # # Microsoft has their own way of handling shared libraries that requires # additional qualifiers on extern variables. Unix systems don't need it. diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index aa7b65b106..639ab9e798 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: socket.c,v 1.207.2.38 2005/11/03 23:41:23 marka Exp $ */ +/* $Id: socket.c,v 1.207.2.39 2006/02/02 23:10:21 marka Exp $ */ #include @@ -747,8 +747,26 @@ build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev, if (sock->type == isc_sockettype_udp) { memset(&dev->address, 0, sizeof(dev->address)); +#ifdef BROKEN_RECVMSG + if (sock->pf == AF_INET) { + msg->msg_name = (void *)&dev->address.type.sin; + msg->msg_namelen = sizeof(dev->address.type.sin6); + } else if (sock->pf == AF_INET6) { + msg->msg_name = (void *)&dev->address.type.sin6; + msg->msg_namelen = sizeof(dev->address.type.sin6); +#ifdef ISC_PLATFORM_HAVESYSUNH + } else if (sock->pf == AF_UNIX) { + msg->msg_name = (void *)&dev->address.type.sunix; + msg->msg_namelen = sizeof(dev->address.type.sunix); +#endif + } else { + msg->msg_name = (void *)&dev->address.type.sa; + msg->msg_namelen = sizeof(dev->address.type); + } +#else msg->msg_name = (void *)&dev->address.type.sa; msg->msg_namelen = sizeof(dev->address.type); +#endif #ifdef ISC_NET_RECVOVERFLOW /* If needed, steal one iovec for overflow detection. */ maxiov--; @@ -921,6 +939,10 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) { cc = recvmsg(sock->fd, &msghdr, 0); recv_errno = errno; +#if defined(ISC_SOCKET_DEBUG) + dump_msg(&msghdr); +#endif + if (cc < 0) { if (SOFT_ERROR(recv_errno)) return (DOIO_SOFT);