summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bind/lib/isc/unix/socket.c
diff options
context:
space:
mode:
authorjakob <jakob@openbsd.org>2007-12-09 13:37:00 +0000
committerjakob <jakob@openbsd.org>2007-12-09 13:37:00 +0000
commit75290b878677166fb160137e559260952e86a7d9 (patch)
tree41bf2b12cf0f7ceff8a71597d4791d0618a9a4b8 /usr.sbin/bind/lib/isc/unix/socket.c
parentNuke evil common, spotted by martin@ (diff)
downloadwireguard-openbsd-75290b878677166fb160137e559260952e86a7d9.tar.xz
wireguard-openbsd-75290b878677166fb160137e559260952e86a7d9.zip
resolve conflicts
Diffstat (limited to 'usr.sbin/bind/lib/isc/unix/socket.c')
-rw-r--r--usr.sbin/bind/lib/isc/unix/socket.c390
1 files changed, 339 insertions, 51 deletions
diff --git a/usr.sbin/bind/lib/isc/unix/socket.c b/usr.sbin/bind/lib/isc/unix/socket.c
index 128f39467ea..97822cef4e2 100644
--- a/usr.sbin/bind/lib/isc/unix/socket.c
+++ b/usr.sbin/bind/lib/isc/unix/socket.c
@@ -1,8 +1,8 @@
/*
- * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
- * Permission to use, copy, modify, and distribute this software for any
+ * Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
@@ -15,13 +15,19 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: socket.c,v 1.207.2.19.2.26 2006/05/19 02:53:36 marka Exp $ */
+/* $ISC: socket.c,v 1.237.18.29 2007/08/28 07:20:06 tbox Exp $ */
+
+/*! \file */
#include <config.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
+#ifdef ISC_PLATFORM_HAVESYSUNH
+#include <sys/un.h>
+#endif
#include <sys/time.h>
#include <sys/uio.h>
@@ -42,6 +48,7 @@
#include <isc/msgs.h>
#include <isc/mutex.h>
#include <isc/net.h>
+#include <isc/once.h>
#include <isc/platform.h>
#include <isc/print.h>
#include <isc/privsep.h>
@@ -58,7 +65,7 @@
#include "socket_p.h"
#endif /* ISC_PLATFORM_USETHREADS */
-/*
+/*%
* Some systems define the socket length argument as an int, some as size_t,
* some as socklen_t. This is here so it can be easily changed if needed.
*/
@@ -66,7 +73,12 @@
#define ISC_SOCKADDR_LEN_T unsigned int
#endif
-/*
+
+#if defined(SO_BSDCOMPAT) && defined(__linux__)
+#include <sys/utsname.h>
+#endif
+
+/*%
* Define what the possible "soft" errors can be. These are non-fatal returns
* of various network related functions, like recv() and so on.
*
@@ -81,7 +93,7 @@
#define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x)
-/*
+/*!<
* DLVL(90) -- Function entry/exit and other tracing.
* DLVL(70) -- Socket "correctness" -- including returning of events, etc.
* DLVL(60) -- Socket data send/receive
@@ -105,7 +117,7 @@ typedef isc_event_t intev_t;
#define SOCKET_MAGIC ISC_MAGIC('I', 'O', 'i', 'o')
#define VALID_SOCKET(t) ISC_MAGIC_VALID(t, SOCKET_MAGIC)
-/*
+/*!
* IPv6 control information. If the socket is an IPv6 socket we want
* to collect the destination address and interface so the client can
* set them on outgoing packets.
@@ -116,7 +128,7 @@ typedef isc_event_t intev_t;
#endif
#endif
-/*
+/*%
* NetBSD and FreeBSD can timestamp packets. XXXMLG Should we have
* a setsockopt() like interface to request timestamps, and if the OS
* doesn't do it for us, call gettimeofday() on every UDP receive?
@@ -127,7 +139,12 @@ typedef isc_event_t intev_t;
#endif
#endif
-/*
+/*%
+ * The size to raise the recieve buffer to (from BIND 8).
+ */
+#define RCVBUFSIZE (32*1024)
+
+/*%
* The number of times a send operation is repeated if the result is EINTR.
*/
#define NRETRIES 10
@@ -241,9 +258,9 @@ static void build_msghdr_recv(isc_socket_t *, isc_socketevent_t *,
#define SELECT_POKE_SHUTDOWN (-1)
#define SELECT_POKE_NOTHING (-2)
#define SELECT_POKE_READ (-3)
-#define SELECT_POKE_ACCEPT (-3) /* Same as _READ */
+#define SELECT_POKE_ACCEPT (-3) /*%< Same as _READ */
#define SELECT_POKE_WRITE (-4)
-#define SELECT_POKE_CONNECT (-4) /* Same as _WRITE */
+#define SELECT_POKE_CONNECT (-4) /*%< Same as _WRITE */
#define SELECT_POKE_CLOSE (-5)
#define SOCK_DEAD(s) ((s)->references == 0)
@@ -873,6 +890,15 @@ set_dev_address(isc_sockaddr_t *address, isc_socket_t *sock,
}
}
+static void
+destroy_socketevent(isc_event_t *event) {
+ isc_socketevent_t *ev = (isc_socketevent_t *)event;
+
+ INSIST(ISC_LIST_EMPTY(ev->bufferlist));
+
+ (ev->destroy)(event);
+}
+
static isc_socketevent_t *
allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
isc_taskaction_t action, const void *arg)
@@ -894,6 +920,8 @@ allocate_socketevent(isc_socket_t *sock, isc_eventtype_t eventtype,
ev->n = 0;
ev->offset = 0;
ev->attributes = 0;
+ ev->destroy = ev->ev_destroy;
+ ev->ev_destroy = destroy_socketevent;
return (ev);
}
@@ -1228,7 +1256,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
isc_socket_t **socketp)
{
isc_socket_t *sock;
- isc_result_t ret;
+ isc_result_t result;
ISC_SOCKADDR_LEN_T cmsgbuflen;
sock = isc_mem_get(manager->mctx, sizeof(*sock));
@@ -1236,7 +1264,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
if (sock == NULL)
return (ISC_R_NOMEMORY);
- ret = ISC_R_UNEXPECTED;
+ result = ISC_R_UNEXPECTED;
sock->magic = 0;
sock->references = 0;
@@ -1296,13 +1324,9 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
/*
* initialize the lock
*/
- if (isc_mutex_init(&sock->lock) != ISC_R_SUCCESS) {
+ result = isc_mutex_init(&sock->lock);
+ if (result != ISC_R_SUCCESS) {
sock->magic = 0;
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mutex_init() %s",
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
- ret = ISC_R_UNEXPECTED;
goto error;
}
@@ -1330,7 +1354,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
sock->sendcmsgbuflen);
isc_mem_put(manager->mctx, sock, sizeof(*sock));
- return (ret);
+ return (result);
}
/*
@@ -1371,7 +1395,45 @@ free_socket(isc_socket_t **socketp) {
*socketp = NULL;
}
+#ifdef SO_BSDCOMPAT
/*
+ * This really should not be necessary to do. Having to workout
+ * which kernel version we are on at run time so that we don't cause
+ * the kernel to issue a warning about us using a deprecated socket option.
+ * Such warnings should *never* be on by default in production kernels.
+ *
+ * We can't do this a build time because executables are moved between
+ * machines and hence kernels.
+ *
+ * We can't just not set SO_BSDCOMAT because some kernels require it.
+ */
+
+static isc_once_t bsdcompat_once = ISC_ONCE_INIT;
+isc_boolean_t bsdcompat = ISC_TRUE;
+
+static void
+clear_bsdcompat(void) {
+#ifdef __linux__
+ struct utsname buf;
+ char *endp;
+ long int major;
+ long int minor;
+
+ uname(&buf); /* Can only fail if buf is bad in Linux. */
+
+ /* Paranoia in parsing can be increased, but we trust uname(). */
+ major = strtol(buf.release, &endp, 10);
+ if (*endp == '.') {
+ minor = strtol(endp+1, &endp, 10);
+ if ((major > 2) || ((major == 2) && (minor >= 4))) {
+ bsdcompat = ISC_FALSE;
+ }
+ }
+#endif /* __linux __ */
+}
+#endif
+
+/*%
* Create a new 'type' socket managed by 'manager'. Events
* will be posted to 'task' and when dispatched 'action' will be
* called with 'arg' as the arg value. The new socket is returned
@@ -1382,21 +1444,27 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
isc_socket_t **socketp)
{
isc_socket_t *sock = NULL;
- isc_result_t ret;
+ isc_result_t result;
#if defined(USE_CMSG) || defined(SO_BSDCOMPAT)
int on = 1;
#endif
+#if defined(SO_RCVBUF)
+ ISC_SOCKADDR_LEN_T optlen;
+ int size;
+#endif
char strbuf[ISC_STRERRORSIZE];
const char *err = "socket";
+ int try = 0;
REQUIRE(VALID_MANAGER(manager));
REQUIRE(socketp != NULL && *socketp == NULL);
- ret = allocate_socket(manager, type, &sock);
- if (ret != ISC_R_SUCCESS)
- return (ret);
+ result = allocate_socket(manager, type, &sock);
+ if (result != ISC_R_SUCCESS)
+ return (result);
sock->pf = pf;
+ again:
switch (type) {
case isc_sockettype_udp:
sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
@@ -1404,7 +1472,12 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
case isc_sockettype_tcp:
sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);
break;
+ case isc_sockettype_unix:
+ sock->fd = socket(pf, SOCK_STREAM, 0);
+ break;
}
+ if (sock->fd == -1 && errno == EINTR && try++ < 42)
+ goto again;
#ifdef F_DUPFD
/*
@@ -1471,7 +1544,10 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#ifdef SO_BSDCOMPAT
- if (setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT,
+ RUNTIME_CHECK(isc_once_do(&bsdcompat_once,
+ clear_bsdcompat) == ISC_R_SUCCESS);
+ if (type != isc_sockettype_unix && bsdcompat &&
+ setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT,
(void *)&on, sizeof(on)) < 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -1484,9 +1560,10 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#endif
-#if defined(USE_CMSG)
+#if defined(USE_CMSG) || defined(SO_RCVBUF)
if (type == isc_sockettype_udp) {
+#if defined(USE_CMSG)
#if defined(SO_TIMESTAMP)
if (setsockopt(sock->fd, SOL_SOCKET, SO_TIMESTAMP,
(void *)&on, sizeof(on)) < 0
@@ -1516,7 +1593,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
#ifdef IPV6_RECVPKTINFO
- /* 2292bis */
+ /* RFC 3542 */
if ((pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
(void *)&on, sizeof(on)) < 0)) {
@@ -1531,7 +1608,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
strbuf);
}
#else
- /* 2292 */
+ /* RFC 2292 */
if ((pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
(void *)&on, sizeof(on)) < 0)) {
@@ -1547,7 +1624,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#endif /* IPV6_RECVPKTINFO */
#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */
-#ifdef IPV6_USE_MIN_MTU /*2292bis, not too common yet*/
+#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/
/* use minimum MTU */
if (pf == AF_INET6) {
(void)setsockopt(sock->fd, IPPROTO_IPV6,
@@ -1556,9 +1633,30 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
}
#endif
#endif /* ISC_PLATFORM_HAVEIPV6 */
-
+#endif /* defined(USE_CMSG) */
+
+#if defined(SO_RCVBUF)
+ optlen = sizeof(size);
+ if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF,
+ (void *)&size, &optlen) >= 0 &&
+ size < RCVBUFSIZE) {
+ size = RCVBUFSIZE;
+ if (setsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF,
+ (void *)&size, sizeof(size)) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "setsockopt(%d, SO_RCVBUF, %d) %s: %s",
+ sock->fd, size,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ }
+ }
+#endif
}
-#endif /* USE_CMSG */
+#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */
sock->references = 1;
*socketp = sock;
@@ -2319,6 +2417,7 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
#ifdef ISC_PLATFORM_USETHREADS
char strbuf[ISC_STRERRORSIZE];
#endif
+ isc_result_t result;
REQUIRE(managerp != NULL && *managerp == NULL);
@@ -2338,13 +2437,10 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
manager->mctx = NULL;
memset(manager->fds, 0, sizeof(manager->fds));
ISC_LIST_INIT(manager->socklist);
- if (isc_mutex_init(&manager->lock) != ISC_R_SUCCESS) {
+ result = isc_mutex_init(&manager->lock);
+ if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, manager, sizeof(*manager));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "isc_mutex_init() %s",
- isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED, "failed"));
- return (ISC_R_UNEXPECTED);
+ return (result);
}
#ifdef ISC_PLATFORM_USETHREADS
if (isc_condition_init(&manager->shutdown_ok) != ISC_R_SUCCESS) {
@@ -2887,6 +2983,190 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
return (socket_send(sock, event, task, address, pktinfo, flags));
}
+void
+isc_socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active) {
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ int s;
+ struct stat sb;
+ char strbuf[ISC_STRERRORSIZE];
+
+ if (sockaddr->type.sa.sa_family != AF_UNIX)
+ return;
+
+#ifndef S_ISSOCK
+#if defined(S_IFMT) && defined(S_IFSOCK)
+#define S_ISSOCK(mode) ((mode & S_IFMT)==S_IFSOCK)
+#elif defined(_S_IFMT) && defined(S_IFSOCK)
+#define S_ISSOCK(mode) ((mode & _S_IFMT)==S_IFSOCK)
+#endif
+#endif
+
+#ifndef S_ISFIFO
+#if defined(S_IFMT) && defined(S_IFIFO)
+#define S_ISFIFO(mode) ((mode & S_IFMT)==S_IFIFO)
+#elif defined(_S_IFMT) && defined(S_IFIFO)
+#define S_ISFIFO(mode) ((mode & _S_IFMT)==S_IFIFO)
+#endif
+#endif
+
+#if !defined(S_ISFIFO) && !defined(S_ISSOCK)
+#error You need to define S_ISFIFO and S_ISSOCK as appropriate for your platform. See <sys/stat.h>.
+#endif
+
+#ifndef S_ISFIFO
+#define S_ISFIFO(mode) 0
+#endif
+
+#ifndef S_ISSOCK
+#define S_ISSOCK(mode) 0
+#endif
+
+ if (active) {
+ if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_cleanunix: stat(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ return;
+ }
+ if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_cleanunix: %s: not a socket",
+ sockaddr->type.sunix.sun_path);
+ return;
+ }
+ if (unlink(sockaddr->type.sunix.sun_path) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_cleanunix: unlink(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ }
+ return;
+ }
+
+ s = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (s < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: socket(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ return;
+ }
+
+ if (stat(sockaddr->type.sunix.sun_path, &sb) < 0) {
+ switch (errno) {
+ case ENOENT: /* We exited cleanly last time */
+ break;
+ default:
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: stat(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ break;
+ }
+ goto cleanup;
+ }
+
+ if (!(S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode))) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: %s: not a socket",
+ sockaddr->type.sunix.sun_path);
+ goto cleanup;
+ }
+
+ if (connect(s, (struct sockaddr *)&sockaddr->type.sunix,
+ sizeof(sockaddr->type.sunix)) < 0) {
+ switch (errno) {
+ case ECONNREFUSED:
+ case ECONNRESET:
+ if (unlink(sockaddr->type.sunix.sun_path) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET,
+ ISC_LOG_WARNING,
+ "isc_socket_cleanunix: "
+ "unlink(%s): %s",
+ sockaddr->type.sunix.sun_path,
+ strbuf);
+ }
+ break;
+ default:
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "isc_socket_cleanunix: connect(%s): %s",
+ sockaddr->type.sunix.sun_path, strbuf);
+ break;
+ }
+ }
+ cleanup:
+ close(s);
+#else
+ UNUSED(sockaddr);
+ UNUSED(active);
+#endif
+}
+
+isc_result_t
+isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group)
+{
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ isc_result_t result = ISC_R_SUCCESS;
+ char strbuf[ISC_STRERRORSIZE];
+ char path[sizeof(sockaddr->type.sunix.sun_path)];
+#ifdef NEED_SECURE_DIRECTORY
+ char *slash;
+#endif
+
+ REQUIRE(sockaddr->type.sa.sa_family == AF_UNIX);
+ INSIST(strlen(sockaddr->type.sunix.sun_path) < sizeof(path));
+ strcpy(path, sockaddr->type.sunix.sun_path);
+
+#ifdef NEED_SECURE_DIRECTORY
+ slash = strrchr(path, '/');
+ if (slash != NULL) {
+ if (slash != path)
+ *slash = '\0';
+ else
+ strcpy(path, "/");
+ } else
+ strcpy(path, ".");
+#endif
+
+ if (chmod(path, perm) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_permunix: chmod(%s, %d): %s",
+ path, perm, strbuf);
+ result = ISC_R_FAILURE;
+ }
+ if (chown(path, owner, group) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "isc_socket_permunix: chown(%s, %d, %d): %s",
+ path, owner, group,
+ strbuf);
+ result = ISC_R_FAILURE;
+ }
+ return (result);
+#else
+ UNUSED(sockaddr);
+ UNUSED(perm);
+ UNUSED(owner);
+ UNUSED(group);
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
+
isc_result_t
isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
char strbuf[ISC_STRERRORSIZE];
@@ -2903,6 +3183,10 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
/*
* Only set SO_REUSEADDR when we want a specific port.
*/
+#ifdef AF_UNIX
+ if (sock->pf == AF_UNIX)
+ goto bind_socket;
+#endif
if (isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
sizeof(on)) < 0) {
@@ -2915,6 +3199,9 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
if ((privsep ?
isc_priv_bind(sock->fd, &sockaddr->type.sa, sockaddr->length) :
bind(sock->fd, &sockaddr->type.sa, sockaddr->length)) < 0) {
+#ifdef AF_UNIX
+ bind_socket:
+#endif
UNLOCK(&sock->lock);
switch (errno) {
case EACCES:
@@ -2996,7 +3283,8 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
REQUIRE(!sock->listener);
REQUIRE(sock->bound);
- REQUIRE(sock->type == isc_sockettype_tcp);
+ REQUIRE(sock->type == isc_sockettype_tcp ||
+ sock->type == isc_sockettype_unix);
if (backlog == 0)
backlog = SOMAXCONN;
@@ -3027,7 +3315,7 @@ isc_socket_accept(isc_socket_t *sock,
isc_socketmgr_t *manager;
isc_task_t *ntask = NULL;
isc_socket_t *nsock;
- isc_result_t ret;
+ isc_result_t result;
isc_boolean_t do_poke = ISC_FALSE;
REQUIRE(VALID_SOCKET(sock));
@@ -3052,11 +3340,11 @@ isc_socket_accept(isc_socket_t *sock,
}
ISC_LINK_INIT(dev, ev_link);
- ret = allocate_socket(manager, sock->type, &nsock);
- if (ret != ISC_R_SUCCESS) {
+ result = allocate_socket(manager, sock->type, &nsock);
+ if (result != ISC_R_SUCCESS) {
isc_event_free(ISC_EVENT_PTR(&dev));
UNLOCK(&sock->lock);
- return (ret);
+ return (result);
}
/*
@@ -3320,7 +3608,7 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
isc_result_t
isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
- isc_result_t ret;
+ isc_result_t result;
REQUIRE(VALID_SOCKET(sock));
REQUIRE(addressp != NULL);
@@ -3329,20 +3617,20 @@ isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp) {
if (sock->connected) {
*addressp = sock->address;
- ret = ISC_R_SUCCESS;
+ result = ISC_R_SUCCESS;
} else {
- ret = ISC_R_NOTCONNECTED;
+ result = ISC_R_NOTCONNECTED;
}
UNLOCK(&sock->lock);
- return (ret);
+ return (result);
}
isc_result_t
isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
ISC_SOCKADDR_LEN_T len;
- isc_result_t ret;
+ isc_result_t result;
char strbuf[ISC_STRERRORSIZE];
REQUIRE(VALID_SOCKET(sock));
@@ -3351,18 +3639,18 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
LOCK(&sock->lock);
if (!sock->bound) {
- ret = ISC_R_NOTBOUND;
+ result = ISC_R_NOTBOUND;
goto out;
}
- ret = ISC_R_SUCCESS;
+ result = ISC_R_SUCCESS;
len = sizeof(addressp->type);
if (getsockname(sock->fd, &addressp->type.sa, (void *)&len) < 0) {
isc__strerror(errno, strbuf, sizeof(strbuf));
UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s",
strbuf);
- ret = ISC_R_UNEXPECTED;
+ result = ISC_R_UNEXPECTED;
goto out;
}
addressp->length = (unsigned int)len;
@@ -3370,7 +3658,7 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
out:
UNLOCK(&sock->lock);
- return (ret);
+ return (result);
}
/*