summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bind/lib/isc/unix/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bind/lib/isc/unix/socket.c')
-rw-r--r--usr.sbin/bind/lib/isc/unix/socket.c1213
1 files changed, 30 insertions, 1183 deletions
diff --git a/usr.sbin/bind/lib/isc/unix/socket.c b/usr.sbin/bind/lib/isc/unix/socket.c
index ce270134b60..33c7d5e8f25 100644
--- a/usr.sbin/bind/lib/isc/unix/socket.c
+++ b/usr.sbin/bind/lib/isc/unix/socket.c
@@ -16,14 +16,16 @@
/*! \file */
-
-
#include <sys/param.h>
#include <sys/types.h>
+#include <sys/event.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/uio.h>
+#include <sys/un.h>
+
+#include <netinet/tcp.h>
#include <errno.h>
#include <fcntl.h>
@@ -37,30 +39,18 @@
#include <isc/bufferlist.h>
#include <isc/condition.h>
#include <isc/formatcheck.h>
-
#include <isc/list.h>
#include <isc/log.h>
-
#include <isc/msgs.h>
#include <isc/net.h>
#include <isc/once.h>
-
-
#include <isc/region.h>
#include <isc/socket.h>
-
#include <isc/strerror.h>
-#include <string.h>
#include <isc/task.h>
#include <isc/thread.h>
#include <isc/util.h>
-
-#include <sys/un.h>
-#include <sys/event.h>
-
-#include <netinet/tcp.h>
-
#include "errno2result.h"
#include "socket_p.h"
@@ -80,18 +70,6 @@ struct isc_socketwait {
*/
int isc_dscp_check_value = -1;
-#ifndef ISC_SOCKET_MAXSOCKETS
-#define ISC_SOCKET_MAXSOCKETS FD_SETSIZE
-#endif /* ISC_SOCKET_MAXSOCKETS */
-
-/*%
- * Mac OS X needs a special definition to support larger values in select().
- * We always define this because a larger value can be specified run-time.
- */
-#ifdef __APPLE__
-#define _DARWIN_UNLIMITED_SELECT
-#endif /* __APPLE__ */
-
/*%
* Size of per-FD lock buckets.
*/
@@ -202,7 +180,6 @@ struct isc__socket {
ISC_LIST(isc_socketevent_t) send_list;
ISC_LIST(isc_socketevent_t) recv_list;
- ISC_LIST(isc_socket_newconnev_t) accept_list;
isc_socket_connev_t *connect_ev;
/*
@@ -217,23 +194,12 @@ struct isc__socket {
unsigned int pending_recv : 1,
pending_send : 1,
- pending_accept : 1,
- listener : 1, /* listener socket */
connected : 1,
connecting : 1, /* connect pending */
bound : 1, /* bound to local addr */
dupped : 1,
active : 1, /* currently active */
pktdscp : 1; /* per packet dscp */
-
-#ifdef ISC_PLATFORM_RECVOVERFLOW
- unsigned char overflow; /* used for MSG_TRUNC fake */
-#endif
-
- void *fdwatcharg;
- isc_sockfdwatch_t fdwatchcb;
- int fdwatchflags;
- isc_task_t *fdwatchtask;
unsigned int dscp;
};
@@ -271,11 +237,7 @@ static isc__socketmgr_t *socketmgr = NULL;
* send() and recv() iovec counts
*/
#define MAXSCATTERGATHER_SEND (ISC_SOCKET_MAXSCATTERGATHER)
-#ifdef ISC_PLATFORM_RECVOVERFLOW
-# define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER + 1)
-#else
-# define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER)
-#endif
+#define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER)
static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf,
isc_sockettype_t type,
@@ -287,12 +249,9 @@ static void free_socket(isc__socket_t **);
static isc_result_t allocate_socket(isc__socketmgr_t *, isc_sockettype_t,
isc__socket_t **);
static void destroy(isc__socket_t **);
-static void internal_accept(isc_task_t *, isc_event_t *);
static void internal_connect(isc_task_t *, isc_event_t *);
static void internal_recv(isc_task_t *, isc_event_t *);
static void internal_send(isc_task_t *, isc_event_t *);
-static void internal_fdwatch_write(isc_task_t *, isc_event_t *);
-static void internal_fdwatch_read(isc_task_t *, isc_event_t *);
static void process_cmsg(isc__socket_t *, struct msghdr *, isc_socketevent_t *);
static void build_msghdr_send(isc__socket_t *, char *, isc_socketevent_t *,
struct msghdr *, struct iovec *, size_t *);
@@ -358,22 +317,12 @@ isc_socket_socketevent(void *sender,
isc_eventtype_t eventtype, isc_taskaction_t action,
void *arg);
-void
-isc__socket_cleanunix(isc_sockaddr_t *sockaddr, isc_boolean_t active);
-isc_result_t
-isc__socket_permunix(isc_sockaddr_t *sockaddr, uint32_t perm,
- uint32_t owner, uint32_t group);
isc_result_t
isc__socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
unsigned int options);
isc_result_t
isc__socket_filter(isc_socket_t *sock, const char *filter);
isc_result_t
-isc__socket_listen(isc_socket_t *sock, unsigned int backlog);
-isc_result_t
-isc__socket_accept(isc_socket_t *sock,
- isc_task_t *task, isc_taskaction_t action, void *arg);
-isc_result_t
isc__socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
isc_task_t *task, isc_taskaction_t action,
void *arg);
@@ -392,12 +341,6 @@ isc__socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
void
isc__socket_dscp(isc_socket_t *sock, isc_dscp_t dscp);
isc_result_t
-isc__socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags,
- isc_sockfdwatch_t callback, void *cbarg,
- isc_task_t *task, isc_socket_t **socketp);
-isc_result_t
-isc__socket_fdwatchpoke(isc_socket_t *sock, int flags);
-isc_result_t
isc__socket_dup(isc_socket_t *sock, isc_socket_t **socketp);
int
isc__socket_getfd(isc_socket_t *sock);
@@ -424,8 +367,7 @@ static struct {
/*%
* The following are defined just for avoiding unused static functions.
*/
- void *recvv, *send, *sendv, *sendto2, *cleanunix, *permunix, *filter,
- *listen, *accept, *getpeername, *isbound;
+ void *recvv, *send, *sendv, *sendto2, *isbound;
} socketmethods = {
{
isc__socket_attach,
@@ -440,23 +382,18 @@ static struct {
isc__socket_getsockname,
isc__socket_gettype,
isc__socket_ipv6only,
- isc__socket_fdwatchpoke,
isc__socket_dup,
isc__socket_getfd,
isc__socket_dscp
},
(void *)isc__socket_recvv, (void *)isc__socket_send,
(void *)isc__socket_sendv, (void *)isc__socket_sendto2,
- (void *)isc__socket_cleanunix, (void *)isc__socket_permunix,
- (void *)isc__socket_filter, (void *)isc__socket_listen,
- (void *)isc__socket_accept, (void *)isc__socket_getpeername,
(void *)isc__socket_isbound
};
static isc_socketmgrmethods_t socketmgrmethods = {
isc__socketmgr_destroy,
- isc__socket_create,
- isc__socket_fdwatchcreate
+ isc__socket_create
};
#define SELECT_POKE_SHUTDOWN (-1)
@@ -641,46 +578,12 @@ make_nonblock(int fd) {
*/
static inline socklen_t
cmsg_len(socklen_t len) {
-#ifdef CMSG_LEN
return (CMSG_LEN(len));
-#else
- socklen_t hdrlen;
-
- /*
- * Cast NULL so that any pointer arithmetic performed by CMSG_DATA
- * is correct.
- */
- hdrlen = (socklen_t)CMSG_DATA(((struct cmsghdr *)NULL));
- return (hdrlen + len);
-#endif
}
static inline socklen_t
cmsg_space(socklen_t len) {
-#ifdef CMSG_SPACE
return (CMSG_SPACE(len));
-#else
- struct msghdr msg;
- struct cmsghdr *cmsgp;
- /*
- * XXX: The buffer length is an ad-hoc value, but should be enough
- * in a practical sense.
- */
- char dummybuf[sizeof(struct cmsghdr) + 1024];
-
- memset(&msg, 0, sizeof(msg));
- msg.msg_control = dummybuf;
- msg.msg_controllen = sizeof(dummybuf);
-
- cmsgp = (struct cmsghdr *)dummybuf;
- cmsgp->cmsg_len = cmsg_len(len);
-
- cmsgp = CMSG_NXTHDR(&msg, cmsgp);
- if (cmsgp != NULL)
- return ((char *)cmsgp - (char *)msg.msg_control);
- else
- return (0);
-#endif
}
/*
@@ -702,15 +605,11 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
UNUSED(msg);
UNUSED(dev);
-#ifdef MSG_TRUNC
if ((msg->msg_flags & MSG_TRUNC) == MSG_TRUNC)
dev->attributes |= ISC_SOCKEVENTATTR_TRUNC;
-#endif
-#ifdef MSG_CTRUNC
if ((msg->msg_flags & MSG_CTRUNC) == MSG_CTRUNC)
dev->attributes |= ISC_SOCKEVENTATTR_CTRUNC;
-#endif
if (msg->msg_controllen == 0U || msg->msg_control == NULL)
return;
@@ -758,11 +657,7 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
}
if (cmsgp->cmsg_level == IPPROTO_IP
- && (cmsgp->cmsg_type == IP_TOS
-#ifdef IP_RECVTOS
- || cmsgp->cmsg_type == IP_RECVTOS
-#endif
- )) {
+ && (cmsgp->cmsg_type == IP_TOS)) {
dev->dscp = (int) *(unsigned char *)CMSG_DATA(cmsgp);
dev->dscp >>= 2;
dev->attributes |= ISC_SOCKEVENTATTR_DSCP;
@@ -883,7 +778,6 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev,
memmove(pktinfop, &dev->pktinfo, sizeof(struct in6_pktinfo));
}
-#if defined(IPV6_USE_MIN_MTU)
if ((sock->type == isc_sockettype_udp) &&
((dev->attributes & ISC_SOCKEVENTATTR_USEMINMTU) != 0))
{
@@ -901,7 +795,6 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev,
cmsgp->cmsg_len = cmsg_len(sizeof(use_min_mtu));
memmove(CMSG_DATA(cmsgp), &use_min_mtu, sizeof(use_min_mtu));
}
-#endif
if (isc_dscp_check_value > -1) {
if (sock->type == isc_sockettype_udp)
@@ -942,7 +835,7 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev,
} else
sock->dscp = dscp;
}
-#if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS)
+
if (sock->pf == AF_INET6 && sock->pktdscp) {
cmsgp = (struct cmsghdr *)(cmsgbuf +
msg->msg_controllen);
@@ -967,7 +860,7 @@ build_msghdr_send(isc__socket_t *sock, char* cmsgbuf, isc_socketevent_t *dev,
} else
sock->dscp = dscp;
}
-#endif
+
if (msg->msg_controllen != 0 &&
msg->msg_controllen < SENDCMSGBUFLEN)
{
@@ -1059,15 +952,6 @@ build_msghdr_recv(isc__socket_t *sock, char *cmsgbuf, isc_socketevent_t *dev,
/*
* If needed, set up to receive that one extra byte.
*/
-#ifdef ISC_PLATFORM_RECVOVERFLOW
- if (sock->type == isc_sockettype_udp) {
- INSIST(iovcount < MAXSCATTERGATHER_RECV);
- iov[iovcount].iov_base = (void *)(&sock->overflow);
- iov[iovcount].iov_len = 1;
- iovcount++;
- }
-#endif
-
msg->msg_iov = iov;
msg->msg_iovlen = iovcount;
@@ -1131,25 +1015,6 @@ allocate_socketevent(void *sender,
return (ev);
}
-#if defined(ISC_SOCKET_DEBUG)
-static void
-dump_msg(struct msghdr *msg) {
- unsigned int i;
-
- printf("MSGHDR %p\n", msg);
- printf("\tname %p, namelen %ld\n", msg->msg_name,
- (long) msg->msg_namelen);
- printf("\tiov %p, iovlen %ld\n", msg->msg_iov,
- (long) msg->msg_iovlen);
- for (i = 0; i < (unsigned int)msg->msg_iovlen; i++)
- printf("\t\t%u\tbase %p, len %ld\n", i,
- msg->msg_iov[i].iov_base,
- (long) msg->msg_iov[i].iov_len);
- printf("\tcontrol %p, controllen %ld\n", msg->msg_control,
- (long) msg->msg_controllen);
-}
-#endif
-
#define DOIO_SUCCESS 0 /* i/o ok, event sent */
#define DOIO_SOFT 1 /* i/o ok, soft error, no event sent */
#define DOIO_HARD 2 /* i/o error, event sent */
@@ -1169,17 +1034,9 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
build_msghdr_recv(sock, cmsgbuf, dev, &msghdr, iov, &read_count);
-#if defined(ISC_SOCKET_DEBUG)
- dump_msg(&msghdr);
-#endif
-
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);
@@ -1239,14 +1096,11 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
*/
switch (sock->type) {
case isc_sockettype_tcp:
- case isc_sockettype_unix:
if (cc == 0)
return (DOIO_EOF);
break;
case isc_sockettype_udp:
- case isc_sockettype_raw:
break;
- case isc_sockettype_fdwatch:
default:
INSIST(0);
}
@@ -1276,13 +1130,6 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
* this indicates an overflow situation. Set the flag in the
* dev entry and adjust how much we read by one.
*/
-#ifdef ISC_PLATFORM_RECVOVERFLOW
- if ((sock->type == isc_sockettype_udp) && ((size_t)cc > read_count)) {
- dev->attributes |= ISC_SOCKEVENTATTR_TRUNC;
- cc--;
- }
-#endif
-
/*
* If there are control messages attached, run through them and pull
* out the interesting bits.
@@ -1452,31 +1299,13 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) {
*/
static void
socketclose(isc__socketmgr_t *manager, isc__socket_t *sock, int fd) {
- isc_sockettype_t type = sock->type;
-
/*
* No one has this socket open, so the watcher doesn't have to be
* poked, and the socket doesn't have to be locked.
*/
manager->fds[fd] = NULL;
- if (type == isc_sockettype_fdwatch)
- manager->fdstate[fd] = CLOSED;
- else
- manager->fdstate[fd] = CLOSE_PENDING;
- if (type == isc_sockettype_fdwatch) {
- /*
- * The caller may close the socket once this function returns,
- * and `fd' may be reassigned for a new socket. So we do
- * unwatch_fd() here, rather than defer it via select_poke().
- * Note: this may complicate data protection among threads and
- * may reduce performance due to additional locks. One way to
- * solve this would be to dup() the watched descriptor, but we
- * take a simpler approach at this moment.
- */
- (void)unwatch_fd(manager, fd, SELECT_POKE_READ);
- (void)unwatch_fd(manager, fd, SELECT_POKE_WRITE);
- } else
- select_poke(manager, fd, SELECT_POKE_CLOSE);
+ manager->fdstate[fd] = CLOSE_PENDING;
+ select_poke(manager, fd, SELECT_POKE_CLOSE);
if (sock->active == 1) {
sock->active = 0;
@@ -1508,7 +1337,6 @@ destroy(isc__socket_t **sockp) {
socket_log(sock, NULL, CREATION, "destroying");
- INSIST(ISC_LIST_EMPTY(sock->accept_list));
INSIST(ISC_LIST_EMPTY(sock->recv_list));
INSIST(ISC_LIST_EMPTY(sock->send_list));
INSIST(sock->connect_ev == NULL);
@@ -1559,12 +1387,9 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
*/
ISC_LIST_INIT(sock->recv_list);
ISC_LIST_INIT(sock->send_list);
- ISC_LIST_INIT(sock->accept_list);
sock->connect_ev = NULL;
sock->pending_recv = 0;
sock->pending_send = 0;
- sock->pending_accept = 0;
- sock->listener = 0;
sock->connected = 0;
sock->connecting = 0;
sock->bound = 0;
@@ -1603,10 +1428,8 @@ free_socket(isc__socket_t **socketp) {
INSIST(!sock->connecting);
INSIST(!sock->pending_recv);
INSIST(!sock->pending_send);
- INSIST(!sock->pending_accept);
INSIST(ISC_LIST_EMPTY(sock->recv_list));
INSIST(ISC_LIST_EMPTY(sock->send_list));
- INSIST(ISC_LIST_EMPTY(sock->accept_list));
INSIST(!ISC_LINK_LINKED(sock, link));
sock->common.magic = 0;
@@ -1617,7 +1440,6 @@ free_socket(isc__socket_t **socketp) {
*socketp = NULL;
}
-#ifdef SO_RCVBUF
static isc_once_t rcvbuf_once = ISC_ONCE_INIT;
static int rcvbuf = RCVBUFSIZE;
@@ -1669,78 +1491,22 @@ set_rcvbuf(void) {
cleanup:
close (fd);
}
-#endif
-
-#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
static void
use_min_mtu(isc__socket_t *sock) {
-#if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU)
- UNUSED(sock);
-#endif
-#ifdef IPV6_USE_MIN_MTU
/* use minimum MTU */
if (sock->pf == AF_INET6) {
int on = 1;
(void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
(void *)&on, sizeof(on));
}
-#endif
-#if defined(IPV6_MTU)
- /*
- * Use minimum MTU on IPv6 sockets.
- */
- if (sock->pf == AF_INET6) {
- int mtu = 1280;
- (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU,
- &mtu, sizeof(mtu));
- }
-#endif
}
static void
set_tcp_maxseg(isc__socket_t *sock, int size) {
-#ifdef TCP_MAXSEG
if (sock->type == isc_sockettype_tcp)
(void)setsockopt(sock->fd, IPPROTO_TCP, TCP_MAXSEG,
(void *)&size, sizeof(size));
-#endif
}
static isc_result_t
@@ -1750,14 +1516,10 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
isc_result_t result;
char strbuf[ISC_STRERRORSIZE];
const char *err = "socket";
- int tries = 0;
int on = 1;
-#if defined(SO_RCVBUF)
socklen_t optlen;
int size;
-#endif
- again:
if (dup_socket == NULL) {
switch (sock->type) {
case isc_sockettype_udp:
@@ -1766,64 +1528,13 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
case isc_sockettype_tcp:
sock->fd = socket(sock->pf, SOCK_STREAM | SOCK_DNS, IPPROTO_TCP);
break;
- case isc_sockettype_unix:
- sock->fd = socket(sock->pf, SOCK_STREAM, 0);
- break;
- case isc_sockettype_raw:
- errno = EPFNOSUPPORT;
- /*
- * PF_ROUTE is a alias for PF_NETLINK on linux.
- */
-#if defined(PF_ROUTE)
- if (sock->fd == -1 && sock->pf == PF_ROUTE) {
-#ifdef NETLINK_ROUTE
- sock->fd = socket(sock->pf, SOCK_RAW,
- NETLINK_ROUTE);
-#else
- sock->fd = socket(sock->pf, SOCK_RAW, 0);
-#endif
- if (sock->fd != -1) {
-#ifdef NETLINK_ROUTE
- struct sockaddr_nl sa;
- int n;
-
- /*
- * Do an implicit bind.
- */
- memset(&sa, 0, sizeof(sa));
- sa.nl_family = AF_NETLINK;
- sa.nl_groups = RTMGRP_IPV4_IFADDR |
- RTMGRP_IPV6_IFADDR;
- n = bind(sock->fd,
- (struct sockaddr *) &sa,
- sizeof(sa));
- if (n < 0) {
- close(sock->fd);
- sock->fd = -1;
- }
-#endif
- sock->bound = 1;
- }
- }
-#endif
- break;
- case isc_sockettype_fdwatch:
- /*
- * We should not be called for isc_sockettype_fdwatch
- * sockets.
- */
- INSIST(0);
- break;
}
} else {
sock->fd = dup(dup_socket->fd);
sock->dupped = 1;
sock->bound = dup_socket->bound;
}
- if (sock->fd == -1 && errno == EINTR && tries++ < 42)
- goto again;
-#ifdef F_DUPFD
/*
* Leave a space for stdio and TCP to work in.
*/
@@ -1845,7 +1556,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
sock->fd = newfd;
err = "isc_socket_create: fcntl";
}
-#endif
if (sock->fd >= (int)manager->maxsocks) {
(void)close(sock->fd);
@@ -1896,31 +1606,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
return (result);
}
-#ifdef SO_BSDCOMPAT
- RUNTIME_CHECK(isc_once_do(&bsdcompat_once,
- clear_bsdcompat) == ISC_R_SUCCESS);
- if (sock->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__,
- "setsockopt(%d, SO_BSDCOMPAT) %s: %s",
- sock->fd, "failed", strbuf);
- /* Press on... */
- }
-#endif
-
-#ifdef SO_NOSIGPIPE
- if (setsockopt(sock->fd, SOL_SOCKET, SO_NOSIGPIPE,
- (void *)&on, sizeof(on)) < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "setsockopt(%d, SO_NOSIGPIPE) %s: %s",
- sock->fd, "failed", strbuf);
- /* Press on... */
- }
-#endif
-
/*
* Use minimum mtu if possible.
*/
@@ -1941,7 +1626,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
/* Press on... */
}
-#ifdef IPV6_RECVPKTINFO
/* RFC 3542 */
if ((sock->pf == AF_INET6)
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
@@ -1952,64 +1636,7 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
"%s: %s", sock->fd, "failed",
strbuf);
}
-#else
- /* RFC 2292 */
- if ((sock->pf == AF_INET6)
- && (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
- (void *)&on, sizeof(on)) < 0)) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "setsockopt(%d, IPV6_PKTINFO) %s: %s",
- sock->fd, "failed", strbuf);
- }
-#endif /* IPV6_RECVPKTINFO */
-#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
- /*
- * Turn off Path MTU discovery on IPv6/UDP sockets.
- */
- if (sock->pf == AF_INET6) {
- int action = IPV6_PMTUDISC_DONT;
- (void)setsockopt(sock->fd, IPPROTO_IPV6,
- IPV6_MTU_DISCOVER, &action,
- sizeof(action));
- }
-#endif
-
-#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
- /*
- * Turn off Path MTU discovery on IPv4/UDP sockets.
- * Prefer IP_PMTUDISC_OMIT over IP_PMTUDISC_DONT
- * if it available.
- */
- if (sock->pf == AF_INET) {
- int action;
-#if defined(IP_PMTUDISC_OMIT)
- action = IP_PMTUDISC_OMIT;
- if (setsockopt(sock->fd, IPPROTO_IP,
- IP_MTU_DISCOVER, &action,
- sizeof(action)) < 0) {
-#endif
- action = IP_PMTUDISC_DONT;
- (void)setsockopt(sock->fd, IPPROTO_IP,
- IP_MTU_DISCOVER,
- &action, sizeof(action));
-#if defined(IP_PMTUDISC_OMIT)
- }
-#endif
- }
-#endif
-#if defined(IP_DONTFRAG)
- /*
- * Turn off Path MTU discovery on IPv4/UDP sockets.
- */
- if (sock->pf == AF_INET) {
- int off = 0;
- (void)setsockopt(sock->fd, IPPROTO_IP, IP_DONTFRAG,
- &off, sizeof(off));
- }
-#endif
-#if defined(SO_RCVBUF)
optlen = sizeof(size);
if (getsockopt(sock->fd, SOL_SOCKET, SO_RCVBUF,
(void *)&size, &optlen) >= 0 && size < rcvbuf) {
@@ -2023,7 +1650,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock,
sock->fd, rcvbuf, "failed", strbuf);
}
}
-#endif
}
setup_done:
@@ -2051,7 +1677,6 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
REQUIRE(VALID_MANAGER(manager));
REQUIRE(socketp != NULL && *socketp == NULL);
- REQUIRE(type != isc_sockettype_fdwatch);
result = allocate_socket(manager, type, &sock);
if (result != ISC_R_SUCCESS)
@@ -2063,11 +1688,6 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
sock->pktdscp = (isc_net_probedscp() & DCSPPKT(pf)) != 0;
break;
case isc_sockettype_tcp:
- break;
- case isc_sockettype_unix:
- break;
- case isc_sockettype_raw:
- break;
default:
INSIST(0);
}
@@ -2139,7 +1759,6 @@ isc__socket_open(isc_socket_t *sock0) {
REQUIRE(VALID_SOCKET(sock));
REQUIRE(sock->references == 1);
- REQUIRE(sock->type != isc_sockettype_fdwatch);
/*
* We don't need to retain the lock hereafter, since no one else has
* this socket.
@@ -2163,100 +1782,6 @@ isc__socket_open(isc_socket_t *sock0) {
}
/*
- * 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
- * in 'socketp'.
- */
-isc_result_t
-isc__socket_fdwatchcreate(isc_socketmgr_t *manager0, int fd, int flags,
- isc_sockfdwatch_t callback, void *cbarg,
- isc_task_t *task, isc_socket_t **socketp)
-{
- isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
- isc__socket_t *sock = NULL;
- isc_result_t result;
- int lockid;
-
- REQUIRE(VALID_MANAGER(manager));
- REQUIRE(socketp != NULL && *socketp == NULL);
-
- if (fd < 0 || (unsigned int)fd >= manager->maxsocks)
- return (ISC_R_RANGE);
-
- result = allocate_socket(manager, isc_sockettype_fdwatch, &sock);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- sock->fd = fd;
- sock->fdwatcharg = cbarg;
- sock->fdwatchcb = callback;
- sock->fdwatchflags = flags;
- sock->fdwatchtask = task;
-
- sock->common.methods = (isc_socketmethods_t *)&socketmethods;
- sock->references = 1;
- *socketp = (isc_socket_t *)sock;
-
- /*
- * Note we don't have to lock the socket like we normally would because
- * there are no external references to it yet.
- */
-
- lockid = FDLOCK_ID(sock->fd);
- manager->fds[sock->fd] = sock;
- manager->fdstate[sock->fd] = MANAGED;
-
- ISC_LIST_APPEND(manager->socklist, sock, link);
- if (manager->maxfd < sock->fd)
- manager->maxfd = sock->fd;
-
- if (flags & ISC_SOCKFDWATCH_READ)
- select_poke(sock->manager, sock->fd, SELECT_POKE_READ);
- if (flags & ISC_SOCKFDWATCH_WRITE)
- select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE);
-
- socket_log(sock, NULL, CREATION, "fdwatch-created");
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * Indicate to the manager that it should watch the socket again.
- * This can be used to restart watching if the previous event handler
- * didn't indicate there was more data to be processed. Primarily
- * it is for writing but could be used for reading if desired
- */
-
-isc_result_t
-isc__socket_fdwatchpoke(isc_socket_t *sock0, int flags)
-{
- isc__socket_t *sock = (isc__socket_t *)sock0;
-
- REQUIRE(VALID_SOCKET(sock));
-
- /*
- * We check both flags first to allow us to get the lock
- * once but only if we need it.
- */
-
- if ((flags & (ISC_SOCKFDWATCH_READ | ISC_SOCKFDWATCH_WRITE)) != 0) {
- if (((flags & ISC_SOCKFDWATCH_READ) != 0) &&
- !sock->pending_recv)
- select_poke(sock->manager, sock->fd,
- SELECT_POKE_READ);
- if (((flags & ISC_SOCKFDWATCH_WRITE) != 0) &&
- !sock->pending_send)
- select_poke(sock->manager, sock->fd,
- SELECT_POKE_WRITE);
- }
-
- socket_log(sock, NULL, TRACE, "fdwatch-poked flags: %d", flags);
-
- return (ISC_R_SUCCESS);
-}
-
-/*
* Attach to a socket. Caller must explicitly detach when it is done.
*/
void
@@ -2306,16 +1831,13 @@ isc__socket_close(isc_socket_t *sock0) {
REQUIRE(sock->references == 1);
- REQUIRE(sock->type != isc_sockettype_fdwatch);
REQUIRE(sock->fd >= 0 && sock->fd < (int)sock->manager->maxsocks);
INSIST(!sock->connecting);
INSIST(!sock->pending_recv);
INSIST(!sock->pending_send);
- INSIST(!sock->pending_accept);
INSIST(ISC_LIST_EMPTY(sock->recv_list));
INSIST(ISC_LIST_EMPTY(sock->send_list));
- INSIST(ISC_LIST_EMPTY(sock->accept_list));
INSIST(sock->connect_ev == NULL);
manager = sock->manager;
@@ -2324,7 +1846,6 @@ isc__socket_close(isc_socket_t *sock0) {
sock->dupped = 0;
memset(sock->name, 0, sizeof(sock->name));
sock->tag = NULL;
- sock->listener = 0;
sock->connected = 0;
sock->connecting = 0;
sock->bound = 0;
@@ -2352,27 +1873,20 @@ dispatch_recv(isc__socket_t *sock) {
INSIST(!sock->pending_recv);
- if (sock->type != isc_sockettype_fdwatch) {
- ev = ISC_LIST_HEAD(sock->recv_list);
- if (ev == NULL)
- return;
- socket_log(sock, NULL, EVENT, NULL, 0, 0,
- "dispatch_recv: event %p -> task %p",
- ev, ev->ev_sender);
- sender = ev->ev_sender;
- } else {
- sender = sock->fdwatchtask;
- }
+ ev = ISC_LIST_HEAD(sock->recv_list);
+ if (ev == NULL)
+ return;
+ socket_log(sock, NULL, EVENT, NULL, 0, 0,
+ "dispatch_recv: event %p -> task %p",
+ ev, ev->ev_sender);
+ sender = ev->ev_sender;
sock->pending_recv = 1;
iev = &sock->readable_ev;
sock->references++;
iev->ev_sender = sock;
- if (sock->type == isc_sockettype_fdwatch)
- iev->ev_action = internal_fdwatch_read;
- else
- iev->ev_action = internal_recv;
+ iev->ev_action = internal_recv;
iev->ev_arg = sock;
isc_task_send(sender, (isc_event_t **)&iev);
@@ -2386,61 +1900,25 @@ dispatch_send(isc__socket_t *sock) {
INSIST(!sock->pending_send);
- if (sock->type != isc_sockettype_fdwatch) {
- ev = ISC_LIST_HEAD(sock->send_list);
- if (ev == NULL)
- return;
- socket_log(sock, NULL, EVENT, NULL, 0, 0,
- "dispatch_send: event %p -> task %p",
- ev, ev->ev_sender);
- sender = ev->ev_sender;
- } else {
- sender = sock->fdwatchtask;
- }
+ ev = ISC_LIST_HEAD(sock->send_list);
+ if (ev == NULL)
+ return;
+ socket_log(sock, NULL, EVENT, NULL, 0, 0,
+ "dispatch_send: event %p -> task %p",
+ ev, ev->ev_sender);
+ sender = ev->ev_sender;
sock->pending_send = 1;
iev = &sock->writable_ev;
sock->references++;
iev->ev_sender = sock;
- if (sock->type == isc_sockettype_fdwatch)
- iev->ev_action = internal_fdwatch_write;
- else
- iev->ev_action = internal_send;
+ iev->ev_action = internal_send;
iev->ev_arg = sock;
isc_task_send(sender, (isc_event_t **)&iev);
}
-/*
- * Dispatch an internal accept event.
- */
-static void
-dispatch_accept(isc__socket_t *sock) {
- intev_t *iev;
- isc_socket_newconnev_t *ev;
-
- INSIST(!sock->pending_accept);
-
- /*
- * Are there any done events left, or were they all canceled
- * before the manager got the socket lock?
- */
- ev = ISC_LIST_HEAD(sock->accept_list);
- if (ev == NULL)
- return;
-
- sock->pending_accept = 1;
- iev = &sock->readable_ev;
-
- sock->references++; /* keep socket around for this internal event */
- iev->ev_sender = sock;
- iev->ev_action = internal_accept;
- iev->ev_arg = sock;
-
- isc_task_send(ev->ev_sender, (isc_event_t **)&iev);
-}
-
static void
dispatch_connect(isc__socket_t *sock) {
intev_t *iev;
@@ -2513,244 +1991,6 @@ send_senddone_event(isc__socket_t *sock, isc_socketevent_t **dev) {
isc_task_send(task, (isc_event_t **)dev);
}
-/*
- * Call accept() on a socket, to get the new file descriptor. The listen
- * socket is used as a prototype to create a new isc_socket_t. The new
- * socket has one outstanding reference. The task receiving the event
- * will be detached from just after the event is delivered.
- *
- * On entry to this function, the event delivered is the internal
- * readable event, and the first item on the accept_list should be
- * the done event we want to send. If the list is empty, this is a no-op,
- * so just unlock and return.
- */
-static void
-internal_accept(isc_task_t *me, isc_event_t *ev) {
- isc__socket_t *sock;
- isc__socketmgr_t *manager;
- isc_socket_newconnev_t *dev;
- isc_task_t *task;
- socklen_t addrlen;
- int fd;
- isc_result_t result = ISC_R_SUCCESS;
- char strbuf[ISC_STRERRORSIZE];
- const char *err = "accept";
-
- UNUSED(me);
-
- sock = ev->ev_sender;
- INSIST(VALID_SOCKET(sock));
-
- socket_log(sock, NULL, TRACE,
- "internal_accept called, locked socket");
-
- manager = sock->manager;
- INSIST(VALID_MANAGER(manager));
-
- INSIST(sock->listener);
- INSIST(sock->pending_accept == 1);
- sock->pending_accept = 0;
-
- INSIST(sock->references > 0);
- sock->references--; /* the internal event is done with this socket */
- if (sock->references == 0) {
- destroy(&sock);
- return;
- }
-
- /*
- * Get the first item off the accept list.
- * If it is empty, unlock the socket and return.
- */
- dev = ISC_LIST_HEAD(sock->accept_list);
- if (dev == NULL) {
- return;
- }
-
- /*
- * Try to accept the new connection. If the accept fails with
- * EAGAIN or EINTR, simply poke the watcher to watch this socket
- * again. Also ignore ECONNRESET, which has been reported to
- * be spuriously returned on Linux 2.2.19 although it is not
- * a documented error for accept(). ECONNABORTED has been
- * reported for Solaris 8. The rest are thrown in not because
- * we have seen them but because they are ignored by other
- * daemons such as BIND 8 and Apache.
- */
-
- addrlen = sizeof(NEWCONNSOCK(dev)->peer_address.type);
- memset(&NEWCONNSOCK(dev)->peer_address.type, 0, addrlen);
- fd = accept(sock->fd, &NEWCONNSOCK(dev)->peer_address.type.sa,
- (void *)&addrlen);
-
-#ifdef F_DUPFD
- /*
- * Leave a space for stdio to work in.
- */
- if (fd >= 0 && fd < 20) {
- int newfd, tmp;
- newfd = fcntl(fd, F_DUPFD, 20);
- tmp = errno;
- (void)close(fd);
- errno = tmp;
- fd = newfd;
- err = "accept/fcntl";
- }
-#endif
-
- if (fd < 0) {
- if (SOFT_ERROR(errno))
- goto soft_error;
- switch (errno) {
- case ENFILE:
- case EMFILE:
- isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
- ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
- "%s: too many open file descriptors",
- err);
- goto soft_error;
-
- case ENOBUFS:
- case ENOMEM:
- case ECONNRESET:
- case ECONNABORTED:
- case EHOSTUNREACH:
- case EHOSTDOWN:
- case ENETUNREACH:
- case ENETDOWN:
- case ECONNREFUSED:
-#ifdef EPROTO
- case EPROTO:
-#endif
-#ifdef ENONET
- case ENONET:
-#endif
- goto soft_error;
- default:
- break;
- }
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "internal_accept: %s() %s: %s", err,
- "failed", strbuf);
- fd = -1;
- result = ISC_R_UNEXPECTED;
- } else {
- if (addrlen == 0U) {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "internal_accept(): "
- "accept() failed to return "
- "remote address");
-
- (void)close(fd);
- goto soft_error;
- } else if (NEWCONNSOCK(dev)->peer_address.type.sa.sa_family !=
- sock->pf)
- {
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "internal_accept(): "
- "accept() returned peer address "
- "family %u (expected %u)",
- NEWCONNSOCK(dev)->peer_address.
- type.sa.sa_family,
- sock->pf);
- (void)close(fd);
- goto soft_error;
- } else if (fd >= (int)manager->maxsocks) {
- isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
- ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
- "accept: "
- "file descriptor exceeds limit (%d/%u)",
- fd, manager->maxsocks);
- (void)close(fd);
- goto soft_error;
- }
- }
-
- if (fd != -1) {
- NEWCONNSOCK(dev)->peer_address.length = addrlen;
- NEWCONNSOCK(dev)->pf = sock->pf;
- }
-
- /*
- * Pull off the done event.
- */
- ISC_LIST_UNLINK(sock->accept_list, dev, ev_link);
-
- /*
- * Poke watcher if there are more pending accepts.
- */
- if (!ISC_LIST_EMPTY(sock->accept_list))
- select_poke(sock->manager, sock->fd, SELECT_POKE_ACCEPT);
-
- if (fd != -1) {
- result = make_nonblock(fd);
- if (result != ISC_R_SUCCESS) {
- (void)close(fd);
- fd = -1;
- }
- }
-
- /*
- * -1 means the new socket didn't happen.
- */
- if (fd != -1) {
- NEWCONNSOCK(dev)->fd = fd;
- NEWCONNSOCK(dev)->bound = 1;
- NEWCONNSOCK(dev)->connected = 1;
-
- /*
- * Use minimum mtu if possible.
- */
- use_min_mtu(NEWCONNSOCK(dev));
- set_tcp_maxseg(NEWCONNSOCK(dev), 1280 - 20 - 40);
-
- /*
- * Ensure DSCP settings are inherited across accept.
- */
- setdscp(NEWCONNSOCK(dev), sock->dscp);
-
- /*
- * Save away the remote address
- */
- dev->address = NEWCONNSOCK(dev)->peer_address;
-
- if (NEWCONNSOCK(dev)->active == 0) {
- NEWCONNSOCK(dev)->active = 1;
- }
-
- manager->fds[fd] = NEWCONNSOCK(dev);
- manager->fdstate[fd] = MANAGED;
-
- if (manager->maxfd < fd)
- manager->maxfd = fd;
-
- socket_log(sock, &NEWCONNSOCK(dev)->peer_address, CREATION,
- "accepted connection, new socket %p",
- dev->newsocket);
-
- ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link);
- } else {
- NEWCONNSOCK(dev)->references--;
- free_socket((isc__socket_t **)&dev->newsocket);
- }
-
- /*
- * Fill in the done event details and send it off.
- */
- dev->result = result;
- task = dev->ev_sender;
- dev->ev_sender = sock;
-
- isc_task_sendanddetach(&task, ISC_EVENT_PTR(&dev));
- return;
-
- soft_error:
- select_poke(sock->manager, sock->fd, SELECT_POKE_ACCEPT);
-
- return;
-}
-
static void
internal_recv(isc_task_t *me, isc_event_t *ev) {
isc_socketevent_t *dev;
@@ -2860,72 +2100,6 @@ internal_send(isc_task_t *me, isc_event_t *ev) {
select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE);
}
-static void
-internal_fdwatch_write(isc_task_t *me, isc_event_t *ev) {
- isc__socket_t *sock;
- int more_data;
-
- INSIST(ev->ev_type == ISC_SOCKEVENT_INTW);
-
- /*
- * Find out what socket this is and lock it.
- */
- sock = (isc__socket_t *)ev->ev_sender;
- INSIST(VALID_SOCKET(sock));
-
- socket_log(sock, NULL, IOEVENT,
- "internal_fdwatch_write: task %p got event %p", me, ev);
-
- INSIST(sock->pending_send == 1);
-
- more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock,
- sock->fdwatcharg, ISC_SOCKFDWATCH_WRITE);
- sock->pending_send = 0;
-
- INSIST(sock->references > 0);
- sock->references--; /* the internal event is done with this socket */
- if (sock->references == 0) {
- destroy(&sock);
- return;
- }
-
- if (more_data)
- select_poke(sock->manager, sock->fd, SELECT_POKE_WRITE);
-}
-
-static void
-internal_fdwatch_read(isc_task_t *me, isc_event_t *ev) {
- isc__socket_t *sock;
- int more_data;
-
- INSIST(ev->ev_type == ISC_SOCKEVENT_INTR);
-
- /*
- * Find out what socket this is and lock it.
- */
- sock = (isc__socket_t *)ev->ev_sender;
- INSIST(VALID_SOCKET(sock));
-
- socket_log(sock, NULL, IOEVENT,
- "internal_fdwatch_read: task %p got event %p", me, ev);
-
- INSIST(sock->pending_recv == 1);
-
- more_data = (sock->fdwatchcb)(me, (isc_socket_t *)sock,
- sock->fdwatcharg, ISC_SOCKFDWATCH_READ);
- sock->pending_recv = 0;
-
- INSIST(sock->references > 0);
- sock->references--; /* the internal event is done with this socket */
- if (sock->references == 0) {
- destroy(&sock);
- return;
- }
-
- if (more_data)
- select_poke(sock->manager, sock->fd, SELECT_POKE_READ);
-}
-
/*
* Process read/writes on each fd here. Avoid locking
* and unlocking twice if both reads and writes are possible.
@@ -2953,10 +2127,7 @@ process_fd(isc__socketmgr_t *manager, int fd, isc_boolean_t readable,
goto check_write;
}
if (!SOCK_DEAD(sock)) {
- if (sock->listener)
- dispatch_accept(sock);
- else
- dispatch_recv(sock);
+ dispatch_recv(sock);
}
unwatch_read = ISC_TRUE;
}
@@ -3025,17 +2196,7 @@ setup_watcher(isc__socketmgr_t *manager) {
UNUSED(result);
-#if ISC_SOCKET_MAXSOCKETS > FD_SETSIZE
- /*
- * Note: this code should also cover the case of MAXSOCKETS <=
- * FD_SETSIZE, but we separate the cases to avoid possible portability
- * issues regarding howmany() and the actual representation of fd_set.
- */
- manager->fd_bufsize = howmany(manager->maxsocks, NFDBITS) *
- sizeof(fd_mask);
-#else
manager->fd_bufsize = sizeof(fd_set);
-#endif
manager->read_fds = NULL;
manager->read_fds_copy = NULL;
@@ -3108,7 +2269,7 @@ isc__socketmgr_create2(isc_socketmgr_t **managerp,
}
if (maxsocks == 0)
- maxsocks = ISC_SOCKET_MAXSOCKETS;
+ maxsocks = FD_SETSIZE;
manager = malloc(sizeof(*manager));
if (manager == NULL)
@@ -3605,138 +2766,6 @@ isc__socket_sendto2(isc_socket_t *sock0, 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) {
- int s;
- struct stat sb;
- char strbuf[ISC_STRERRORSIZE];
-
- if (sockaddr->type.sa.sa_family != AF_UNIX)
- return;
-
-#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
-
- 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);
-}
-
-isc_result_t
-isc__socket_permunix(isc_sockaddr_t *sockaddr, uint32_t perm,
- uint32_t owner, uint32_t group)
-{
- isc_result_t result = ISC_R_SUCCESS;
- char strbuf[ISC_STRERRORSIZE];
- char path[sizeof(sockaddr->type.sunix.sun_path)];
-
- REQUIRE(sockaddr->type.sa.sa_family == AF_UNIX);
- INSIST(strlen(sockaddr->type.sunix.sun_path) < sizeof(path));
- strlcpy(path, sockaddr->type.sunix.sun_path, sizeof(path));
-
- 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);
-}
isc_result_t
isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr,
@@ -3757,10 +2786,6 @@ isc__socket_bind(isc_socket_t *sock0, 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 ((options & ISC_SOCKET_REUSEADDRESS) != 0 &&
isc_sockaddr_getport(sockaddr) != (in_port_t)0 &&
setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&on,
@@ -3769,9 +2794,6 @@ isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr,
"setsockopt(%d) %s", sock->fd, "failed");
/* Press on... */
}
-#ifdef AF_UNIX
- bind_socket:
-#endif
if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) {
switch (errno) {
case EACCES:
@@ -3796,149 +2818,15 @@ isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr,
return (ISC_R_SUCCESS);
}
-/*
- * Enable this only for specific OS versions, and only when they have repaired
- * their problems with it. Until then, this is is broken and needs to be
- * diabled by default. See RT22589 for details.
- */
-#undef ENABLE_ACCEPTFILTER
-
isc_result_t
isc__socket_filter(isc_socket_t *sock0, const char *filter) {
isc__socket_t *sock = (isc__socket_t *)sock0;
-#if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER)
- char strbuf[ISC_STRERRORSIZE];
- struct accept_filter_arg afa;
-#else
UNUSED(sock);
UNUSED(filter);
-#endif
REQUIRE(VALID_SOCKET(sock));
-#if defined(SO_ACCEPTFILTER) && defined(ENABLE_ACCEPTFILTER)
- bzero(&afa, sizeof(afa));
- strlcpy(afa.af_name, filter, sizeof(afa.af_name));
- if (setsockopt(sock->fd, SOL_SOCKET, SO_ACCEPTFILTER,
- &afa, sizeof(afa)) == -1) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- socket_log(sock, NULL, CREATION,
- "setsockopt(SO_ACCEPTFILTER): %s", strbuf);
- return (ISC_R_FAILURE);
- }
- return (ISC_R_SUCCESS);
-#else
return (ISC_R_NOTIMPLEMENTED);
-#endif
-}
-
-/*
- * Set up to listen on a given socket. We do this by creating an internal
- * event that will be dispatched when the socket has read activity. The
- * watcher will send the internal event to the task when there is a new
- * connection.
- *
- * Unlike in read, we don't preallocate a done event here. Every time there
- * is a new connection we'll have to allocate a new one anyway, so we might
- * as well keep things simple rather than having to track them.
- */
-isc_result_t
-isc__socket_listen(isc_socket_t *sock0, unsigned int backlog) {
- isc__socket_t *sock = (isc__socket_t *)sock0;
- char strbuf[ISC_STRERRORSIZE];
-
- REQUIRE(VALID_SOCKET(sock));
-
- REQUIRE(!sock->listener);
- REQUIRE(sock->bound);
- REQUIRE(sock->type == isc_sockettype_tcp ||
- sock->type == isc_sockettype_unix);
-
- if (backlog == 0)
- backlog = SOMAXCONN;
-
- if (listen(sock->fd, (int)backlog) < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
-
- UNEXPECTED_ERROR(__FILE__, __LINE__, "listen: %s", strbuf);
-
- return (ISC_R_UNEXPECTED);
- }
-
- sock->listener = 1;
-
- return (ISC_R_SUCCESS);
-}
-
-/*
- * This should try to do aggressive accept() XXXMLG
- */
-isc_result_t
-isc__socket_accept(isc_socket_t *sock0,
- isc_task_t *task, isc_taskaction_t action, void *arg)
-{
- isc__socket_t *sock = (isc__socket_t *)sock0;
- isc_socket_newconnev_t *dev;
- isc__socketmgr_t *manager;
- isc_task_t *ntask = NULL;
- isc__socket_t *nsock;
- isc_result_t result;
- isc_boolean_t do_poke = ISC_FALSE;
-
- REQUIRE(VALID_SOCKET(sock));
- manager = sock->manager;
- REQUIRE(VALID_MANAGER(manager));
-
- REQUIRE(sock->listener);
-
- /*
- * Sender field is overloaded here with the task we will be sending
- * this event to. Just before the actual event is delivered the
- * actual ev_sender will be touched up to be the socket.
- */
- dev = (isc_socket_newconnev_t *)
- isc_event_allocate(task, ISC_SOCKEVENT_NEWCONN,
- action, arg, sizeof(*dev));
- if (dev == NULL) {
- return (ISC_R_NOMEMORY);
- }
- ISC_LINK_INIT(dev, ev_link);
-
- result = allocate_socket(manager, sock->type, &nsock);
- if (result != ISC_R_SUCCESS) {
- isc_event_free(ISC_EVENT_PTR(&dev));
- return (result);
- }
-
- /*
- * Attach to socket and to task.
- */
- isc_task_attach(task, &ntask);
- if (isc_task_exiting(ntask)) {
- free_socket(&nsock);
- isc_task_detach(&ntask);
- isc_event_free(ISC_EVENT_PTR(&dev));
- return (ISC_R_SHUTTINGDOWN);
- }
- nsock->references++;
-
- dev->ev_sender = ntask;
- dev->newsocket = (isc_socket_t *)nsock;
-
- /*
- * Poke watcher here. We still have the socket locked, so there
- * is no race condition. We will keep the lock for such a short
- * bit of time waking it up now or later won't matter all that much.
- */
- if (ISC_LIST_EMPTY(sock->accept_list))
- do_poke = ISC_TRUE;
-
- ISC_LIST_ENQUEUE(sock->accept_list, dev, ev_link);
-
- if (do_poke)
- select_poke(manager, sock->fd, SELECT_POKE_ACCEPT);
-
- return (ISC_R_SUCCESS);
}
isc_result_t
@@ -4291,35 +3179,6 @@ isc__socket_cancel(isc_socket_t *sock0, isc_task_t *task, unsigned int how) {
}
}
- if (((how & ISC_SOCKCANCEL_ACCEPT) == ISC_SOCKCANCEL_ACCEPT)
- && !ISC_LIST_EMPTY(sock->accept_list)) {
- isc_socket_newconnev_t *dev;
- isc_socket_newconnev_t *next;
- isc_task_t *current_task;
-
- dev = ISC_LIST_HEAD(sock->accept_list);
- while (dev != NULL) {
- current_task = dev->ev_sender;
- next = ISC_LIST_NEXT(dev, ev_link);
-
- if ((task == NULL) || (task == current_task)) {
-
- ISC_LIST_UNLINK(sock->accept_list, dev,
- ev_link);
-
- NEWCONNSOCK(dev)->references--;
- free_socket((isc__socket_t **)&dev->newsocket);
-
- dev->result = ISC_R_CANCELED;
- dev->ev_sender = sock;
- isc_task_sendanddetach(&current_task,
- ISC_EVENT_PTR(&dev));
- }
-
- dev = next;
- }
- }
-
/*
* Connecting is not a list.
*/
@@ -4369,17 +3228,11 @@ isc__socket_isbound(isc_socket_t *sock0) {
void
isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) {
isc__socket_t *sock = (isc__socket_t *)sock0;
-#if defined(IPV6_V6ONLY)
int onoff = yes ? 1 : 0;
-#else
- UNUSED(yes);
- UNUSED(sock);
-#endif
REQUIRE(VALID_SOCKET(sock));
INSIST(!sock->dupped);
-#ifdef IPV6_V6ONLY
if (sock->pf == AF_INET6) {
if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
(void *)&onoff, sizeof(int)) < 0) {
@@ -4391,7 +3244,6 @@ isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) {
strbuf);
}
}
-#endif
}
static void
@@ -4438,11 +3290,6 @@ isc__socket_dscp(isc_socket_t *sock0, isc_dscp_t dscp) {
if (isc_dscp_check_value != -1)
INSIST(dscp == isc_dscp_check_value);
-
-#ifdef notyet
- REQUIRE(!sock->dupped);
-#endif
-
setdscp(sock, dscp);
}