mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
Fix select to set and check for exception fds for the connect() function for the socket. Miscellaneous error handling cleanup. [RT #1870]
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: socket.c,v 1.6 2001/09/16 06:19:22 mayer Exp $ */
|
||||
/* $Id: socket.c,v 1.7 2001/11/07 04:24:38 mayer Exp $ */
|
||||
|
||||
|
||||
#define MAKE_EXTERNAL 1
|
||||
@@ -27,8 +27,6 @@
|
||||
#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
|
||||
#endif
|
||||
|
||||
#include "errno2result.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
@@ -50,10 +48,12 @@
|
||||
#include <isc/print.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/socket.h>
|
||||
#include <isc/strerror.h>
|
||||
#include <isc/task.h>
|
||||
#include <isc/thread.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include "errno2result.h"
|
||||
/*
|
||||
* 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.
|
||||
@@ -70,9 +70,11 @@
|
||||
* from recv() but will have errno==0. This is broken, but we have to
|
||||
* work around it here.
|
||||
*/
|
||||
#define SOFT_ERROR(e) ((e) == EAGAIN || \
|
||||
#define SOFT_ERROR(e) ((e) == WSAEINTR || \
|
||||
(e) == WSAEWOULDBLOCK || \
|
||||
(e) == WSAEINTR || \
|
||||
(e) == EWOULDBLOCK || \
|
||||
(e) == EINTR || \
|
||||
(e) == EAGAIN || \
|
||||
(e) == 0)
|
||||
|
||||
#define DLVL(x) ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_SOCKET, ISC_LOG_DEBUG(x)
|
||||
@@ -98,8 +100,8 @@
|
||||
|
||||
typedef isc_event_t intev_t;
|
||||
|
||||
#define SOCKET_MAGIC 0x494f696fU /* IOio */
|
||||
#define VALID_SOCKET(t) ((t) != NULL && (t)->magic == SOCKET_MAGIC)
|
||||
#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
|
||||
@@ -156,6 +158,11 @@ struct msghdr {
|
||||
int msg_flags; /* flags on received message */
|
||||
} msghdr;
|
||||
|
||||
/*
|
||||
* The number of times a send operation is repeated if the result is EINTR.
|
||||
*/
|
||||
#define NRETRIES 10
|
||||
|
||||
struct isc_socket {
|
||||
/* Not locked. */
|
||||
unsigned int magic;
|
||||
@@ -197,9 +204,9 @@ struct isc_socket {
|
||||
#endif
|
||||
};
|
||||
|
||||
#define SOCKET_MANAGER_MAGIC 0x494f6d67U /* IOmg */
|
||||
#define VALID_MANAGER(m) ((m) != NULL && \
|
||||
(m)->magic == SOCKET_MANAGER_MAGIC)
|
||||
#define SOCKET_MANAGER_MAGIC ISC_MAGIC('I', 'O', 'm', 'g')
|
||||
#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, SOCKET_MANAGER_MAGIC)
|
||||
|
||||
struct isc_socketmgr {
|
||||
/* Not locked. */
|
||||
unsigned int magic;
|
||||
@@ -209,6 +216,7 @@ struct isc_socketmgr {
|
||||
ISC_LIST(isc_socket_t) socklist;
|
||||
fd_set read_fds;
|
||||
fd_set write_fds;
|
||||
fd_set except_fds;
|
||||
isc_socket_t *fds[FD_SETSIZE];
|
||||
int fdstate[FD_SETSIZE];
|
||||
int maxfd;
|
||||
@@ -256,8 +264,8 @@ static void build_msghdr_recv(isc_socket_t *, isc_socketevent_t *,
|
||||
#define SELECT_POKE_READ (-3)
|
||||
#define SELECT_POKE_ACCEPT (-3) /* Same as _READ */
|
||||
#define SELECT_POKE_WRITE (-4)
|
||||
#define SELECT_POKE_CONNECT (-4) /* Same as _WRITE */
|
||||
#define SELECT_POKE_CLOSE (-5)
|
||||
#define SELECT_POKE_CONNECT (-5)
|
||||
#define SELECT_POKE_CLOSE (-6)
|
||||
|
||||
long bpipe_written = 0;
|
||||
|
||||
@@ -315,21 +323,21 @@ internal_sendmsg(int sock, const struct msghdr *msg, int flags) {
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (Error == SOCKET_ERROR) {
|
||||
BytesSent = -1;
|
||||
/* There is an error... */
|
||||
Error = WSAGetLastError();
|
||||
if (Error == WSA_IO_PENDING) {
|
||||
if (Error == SOCKET_ERROR) {
|
||||
BytesSent = -1;
|
||||
/* There is an error... */
|
||||
Error = WSAGetLastError();
|
||||
if (Error == WSA_IO_PENDING) {
|
||||
/* Overlapped send successfully initiated. */
|
||||
errno = EAGAIN;
|
||||
} else {
|
||||
/* An unexpected error occurred. */
|
||||
errno = Error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* An unexpected error occurred. */
|
||||
errno = Error;
|
||||
}
|
||||
}
|
||||
|
||||
/* No error -- the I/O request was completed immediately... */
|
||||
return (BytesSent);
|
||||
/* No error -- the I/O request was completed immediately... */
|
||||
return (BytesSent);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -394,6 +402,11 @@ manager_log(isc_socketmgr_t *sockmgr,
|
||||
"sockmgr %p: %s", sockmgr, msgbuf);
|
||||
}
|
||||
|
||||
static void
|
||||
socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
|
||||
isc_logcategory_t *category, isc_logmodule_t *module, int level,
|
||||
isc_msgcat_t *msgcat, int msgset, int message,
|
||||
const char *fmt, ...) ISC_FORMAT_PRINTF(9, 10);
|
||||
static void
|
||||
socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
|
||||
isc_logcategory_t *category, isc_logmodule_t *module, int level,
|
||||
@@ -432,12 +445,14 @@ wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) {
|
||||
* process of being closed, start watching it for either reads
|
||||
* or writes.
|
||||
*/
|
||||
INSIST(fd < FD_SETSIZE);
|
||||
|
||||
INSIST(fd >= 0 && fd < FD_SETSIZE);
|
||||
|
||||
if (manager->fdstate[fd] == CLOSE_PENDING) {
|
||||
manager->fdstate[fd] = CLOSED;
|
||||
FD_CLR(fd, &manager->read_fds);
|
||||
FD_CLR(fd, &manager->write_fds);
|
||||
FD_CLR(fd, &manager->except_fds);
|
||||
closesocket(fd);
|
||||
return;
|
||||
}
|
||||
@@ -455,6 +470,10 @@ wakeup_socket(isc_socketmgr_t *manager, int fd, int msg) {
|
||||
FD_SET(sock->fd, &manager->read_fds);
|
||||
if (msg == SELECT_POKE_WRITE)
|
||||
FD_SET(sock->fd, &manager->write_fds);
|
||||
if (msg == SELECT_POKE_CONNECT) { /* Need both here */
|
||||
FD_SET(sock->fd, &manager->write_fds);
|
||||
FD_SET(sock->fd, &manager->except_fds);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
@@ -467,7 +486,7 @@ static void
|
||||
select_poke(isc_socketmgr_t *mgr, int fd, int msg) {
|
||||
int cc;
|
||||
int buf[2];
|
||||
int errval;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
buf[0] = fd;
|
||||
buf[1] = msg;
|
||||
@@ -475,17 +494,17 @@ select_poke(isc_socketmgr_t *mgr, int fd, int msg) {
|
||||
if (msg == SELECT_POKE_SHUTDOWN) {
|
||||
do {
|
||||
cc = _write(mgr->pipe_fds[1], buf, sizeof(buf));
|
||||
errval = errno;
|
||||
} while (cc < 0 && SOFT_ERROR(errno));
|
||||
|
||||
if (cc < 0)
|
||||
if (cc < 0) {
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
FATAL_ERROR(__FILE__, __LINE__,
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_SOCKET,
|
||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET,
|
||||
ISC_MSG_WRITEFAILED,
|
||||
"_write() failed "
|
||||
"write() failed "
|
||||
"during watcher poke: %s"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
}
|
||||
|
||||
INSIST(cc == sizeof(buf));
|
||||
|
||||
@@ -502,6 +521,7 @@ static void
|
||||
select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) {
|
||||
int buf[2];
|
||||
int cc;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
cc = _read(mgr->pipe_fds[0], buf, sizeof(buf));
|
||||
if (cc < 0) {
|
||||
@@ -509,12 +529,14 @@ select_readmsg(isc_socketmgr_t *mgr, int *fd, int *msg) {
|
||||
if (SOFT_ERROR(errno))
|
||||
return;
|
||||
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
FATAL_ERROR(__FILE__, __LINE__,
|
||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKET,
|
||||
ISC_MSG_READFAILED,
|
||||
"_read() failed "
|
||||
"read() failed "
|
||||
"during watcher poke: %s"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
|
||||
return;
|
||||
}
|
||||
INSIST(cc == sizeof(buf));
|
||||
@@ -543,14 +565,16 @@ static isc_result_t
|
||||
make_nonblock(int fd) {
|
||||
int ret;
|
||||
unsigned long flags = 1;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
/* Set the socket to non-blocking */
|
||||
ret = ioctlsocket((SOCKET) fd, FIONBIO, &flags);
|
||||
|
||||
if (ret == -1) {
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"ioctlsocket(%d, FIOBIO, %d): %s",
|
||||
fd, flags, strerror(errno));
|
||||
fd, flags, strbuf);
|
||||
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
@@ -598,12 +622,6 @@ process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
|
||||
dev->attributes |= ISC_SOCKEVENTATTR_CTRUNC;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check for multicast.
|
||||
*/
|
||||
if (isc_sockaddr_ismulticast(&dev->address))
|
||||
dev->attributes |= ISC_SOCKEVENTATTR_MULTICAST;
|
||||
|
||||
#ifndef USE_CMSG
|
||||
return;
|
||||
#else
|
||||
@@ -636,6 +654,8 @@ process_cmsg(isc_socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
|
||||
ISC_MSG_IFRECEIVED,
|
||||
"interface received on ifindex %u",
|
||||
dev->pktinfo.ipi6_ifindex);
|
||||
if (IN6_IS_ADDR_MULTICAST(&pktinfop->ipi6_addr))
|
||||
dev->attributes |= ISC_SOCKEVENTATTR_MULTICAST;
|
||||
goto next;
|
||||
}
|
||||
#endif
|
||||
@@ -752,7 +772,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
msg->msg_control = NULL;
|
||||
msg->msg_controllen = 0;
|
||||
msg->msg_flags = 0;
|
||||
#ifdef USE_CMSG
|
||||
#if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIPV6)
|
||||
if ((sock->type == isc_sockettype_udp)
|
||||
&& ((dev->attributes & ISC_SOCKEVENTATTR_PKTINFO) != 0)) {
|
||||
struct cmsghdr *cmsgp;
|
||||
@@ -773,7 +793,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
pktinfop = (struct in6_pktinfo *)CMSG_DATA(cmsgp);
|
||||
memcpy(pktinfop, &dev->pktinfo, sizeof(struct in6_pktinfo));
|
||||
}
|
||||
#endif /* USE_CMSG */
|
||||
#endif /* USE_CMSG && ISC_PLATFORM_HAVEIPV6 */
|
||||
#endif /* ISC_NET_BSD44MSGHDR */
|
||||
|
||||
if (write_countp != NULL)
|
||||
@@ -833,10 +853,8 @@ build_msghdr_recv(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
iov[0].buf = (void *)(dev->region.base + dev->n);
|
||||
iov[0].len = read_count;
|
||||
iovcount = 1;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/*
|
||||
* Multibuffer I/O.
|
||||
* Skip empty buffers.
|
||||
@@ -968,11 +986,13 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
size_t actual_count;
|
||||
struct msghdr msghdr;
|
||||
isc_buffer_t *buffer;
|
||||
int recv_errno;
|
||||
#if USE_CMSG
|
||||
char cmsg[CMSG_BUF_SIZE];
|
||||
#else
|
||||
char *cmsg = NULL;
|
||||
#endif
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
build_msghdr_recv(sock, dev, &msghdr, cmsg, iov, &read_count);
|
||||
|
||||
@@ -981,21 +1001,23 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
#endif
|
||||
|
||||
cc = internal_recvmsg(sock->fd, &msghdr, 0);
|
||||
recv_errno = WSAGetLastError();
|
||||
|
||||
if (cc < 0) {
|
||||
if (SOFT_ERROR(errno))
|
||||
if (SOFT_ERROR(recv_errno))
|
||||
return (DOIO_SOFT);
|
||||
|
||||
if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL))
|
||||
if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) {
|
||||
isc__strerror(recv_errno, strbuf, sizeof(strbuf));
|
||||
socket_log(sock, NULL, IOEVENT,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET,
|
||||
ISC_MSG_DOIORECV,
|
||||
"doio_recv: internal_recvmsg(%d) %d bytes, "
|
||||
"err %d/%s",
|
||||
sock->fd, cc, errno, NTstrerror(errno));
|
||||
"doio_recv: recvmsg(%d) %d bytes, err %d/%s",
|
||||
sock->fd, cc, recv_errno, strbuf);
|
||||
}
|
||||
|
||||
#define SOFT_OR_HARD(_system, _isc) \
|
||||
if (errno == _system) { \
|
||||
if (recv_errno == _system) { \
|
||||
if (sock->connected) { \
|
||||
dev->result = _isc; \
|
||||
return (DOIO_HARD); \
|
||||
@@ -1003,7 +1025,7 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
return (DOIO_SOFT); \
|
||||
}
|
||||
#define ALWAYS_HARD(_system, _isc) \
|
||||
if (errno == _system) { \
|
||||
if (recv_errno == _system) { \
|
||||
dev->result = _isc; \
|
||||
return (DOIO_HARD); \
|
||||
}
|
||||
@@ -1020,7 +1042,7 @@ doio_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
#undef SOFT_OR_HARD
|
||||
#undef ALWAYS_HARD
|
||||
|
||||
dev->result = ISC_R_UNEXPECTED;
|
||||
dev->result = isc__errno2result(recv_errno);
|
||||
return (DOIO_HARD);
|
||||
}
|
||||
|
||||
@@ -1120,20 +1142,28 @@ doio_send(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
#else
|
||||
char *cmsg = NULL;
|
||||
#endif
|
||||
int attempts = 0;
|
||||
int send_errno;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
build_msghdr_send(sock, dev, &msghdr, cmsg, iov, &write_count);
|
||||
|
||||
resend:
|
||||
cc = internal_sendmsg(sock->fd, &msghdr, 0);
|
||||
send_errno = WSAGetLastError();
|
||||
|
||||
/*
|
||||
* Check for error or block condition.
|
||||
*/
|
||||
if (cc < 0) {
|
||||
if (SOFT_ERROR(errno))
|
||||
if (send_errno == WSAEINTR && ++attempts < NRETRIES)
|
||||
goto resend;
|
||||
|
||||
if (SOFT_ERROR(send_errno))
|
||||
return (DOIO_SOFT);
|
||||
|
||||
#define SOFT_OR_HARD(_system, _isc) \
|
||||
if (errno == _system) { \
|
||||
if (send_errno == _system) { \
|
||||
if (sock->connected) { \
|
||||
dev->result = _isc; \
|
||||
return (DOIO_HARD); \
|
||||
@@ -1141,7 +1171,7 @@ doio_send(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
return (DOIO_SOFT); \
|
||||
}
|
||||
#define ALWAYS_HARD(_system, _isc) \
|
||||
if (errno == _system) { \
|
||||
if (send_errno == _system) { \
|
||||
dev->result = _isc; \
|
||||
return (DOIO_HARD); \
|
||||
}
|
||||
@@ -1174,10 +1204,10 @@ doio_send(isc_socket_t *sock, isc_socketevent_t *dev) {
|
||||
* a status.
|
||||
*/
|
||||
isc_sockaddr_format(&dev->address, addrbuf, sizeof(addrbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"internal_send: %s: %s",
|
||||
addrbuf, strerror(errno));
|
||||
dev->result = ISC_R_UNEXPECTED;
|
||||
isc__strerror(send_errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "internal_send: %s: %s",
|
||||
addrbuf, strbuf);
|
||||
dev->result = isc__errno2result(send_errno);
|
||||
return (DOIO_HARD);
|
||||
}
|
||||
|
||||
@@ -1220,6 +1250,7 @@ destroy(isc_socket_t **sockp) {
|
||||
INSIST(ISC_LIST_EMPTY(sock->recv_list));
|
||||
INSIST(ISC_LIST_EMPTY(sock->send_list));
|
||||
INSIST(sock->connect_ev == NULL);
|
||||
REQUIRE(sock->fd >= 0 && sock->fd < FD_SETSIZE);
|
||||
|
||||
LOCK(&manager->lock);
|
||||
|
||||
@@ -1356,13 +1387,14 @@ free_socket(isc_socket_t **socketp) {
|
||||
*/
|
||||
isc_result_t
|
||||
isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
isc_socket_t **socketp)
|
||||
{
|
||||
isc_socket_t **socketp) {
|
||||
isc_socket_t *sock = NULL;
|
||||
isc_result_t ret;
|
||||
#if defined(USE_CMSG) || defined(SO_BSDCOMPAT)
|
||||
int on = 1;
|
||||
#endif
|
||||
int socket_errno;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
REQUIRE(socketp != NULL && *socketp == NULL);
|
||||
@@ -1380,28 +1412,41 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sock->fd >= FD_SETSIZE) {
|
||||
(void)closesocket(sock->fd);
|
||||
isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL,
|
||||
ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET,
|
||||
ISC_MSG_TOOMANYFDS,
|
||||
"%s: too many open file descriptors", "socket");
|
||||
free_socket(&sock);
|
||||
return (ISC_R_NORESOURCES);
|
||||
}
|
||||
|
||||
if (sock->fd < 0) {
|
||||
socket_errno = WSAGetLastError();
|
||||
free_socket(&sock);
|
||||
|
||||
switch (errno) {
|
||||
case EMFILE:
|
||||
case ENFILE:
|
||||
case ENOBUFS:
|
||||
switch (socket_errno) {
|
||||
case WSAEMFILE:
|
||||
case WSAENOBUFS:
|
||||
return (ISC_R_NORESOURCES);
|
||||
|
||||
case EPROTONOSUPPORT:
|
||||
case EPFNOSUPPORT:
|
||||
case EAFNOSUPPORT:
|
||||
case WSAEPROTONOSUPPORT:
|
||||
case WSAEPFNOSUPPORT:
|
||||
case WSAEAFNOSUPPORT:
|
||||
return (ISC_R_FAMILYNOSUPPORT);
|
||||
|
||||
default:
|
||||
isc__strerror(socket_errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"socket() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
}
|
||||
@@ -1414,12 +1459,14 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
#ifdef SO_BSDCOMPAT
|
||||
if (setsockopt(sock->fd, SOL_SOCKET, SO_BSDCOMPAT,
|
||||
(void *)&on, sizeof on) < 0) {
|
||||
socket_errno = WSAGetLastError();
|
||||
isc__strerror(socket_errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"setsockopt(%d, SO_BSDCOMPAT) %s: %s",
|
||||
sock->fd,
|
||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED, "failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
/* Press on... */
|
||||
}
|
||||
#endif
|
||||
@@ -1430,7 +1477,8 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
#if defined(SO_TIMESTAMP)
|
||||
if (setsockopt(sock->fd, SOL_SOCKET, SO_TIMESTAMP,
|
||||
(void *)&on, sizeof on) < 0
|
||||
&& errno != ENOPROTOOPT) {
|
||||
&& WSAGetLastError() != WSAENOPROTOOPT) {
|
||||
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"setsockopt(%d, SO_TIMESTAMP) %s: %s",
|
||||
sock->fd,
|
||||
@@ -1438,7 +1486,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
/* Press on... */
|
||||
}
|
||||
#endif /* SO_TIMESTAMP */
|
||||
@@ -1449,6 +1497,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
if ((pf == AF_INET6)
|
||||
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
|
||||
(void *)&on, sizeof (on)) < 0)) {
|
||||
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"setsockopt(%d, IPV6_RECVPKTINFO) "
|
||||
"%s: %s", sock->fd,
|
||||
@@ -1456,13 +1505,14 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
}
|
||||
#else
|
||||
/* 2292 */
|
||||
if ((pf == AF_INET6)
|
||||
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
|
||||
(void *)&on, sizeof (on)) < 0)) {
|
||||
isc__strerror(WSAGetLaastError(), strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"setsockopt(%d, IPV6_PKTINFO) %s: %s",
|
||||
sock->fd,
|
||||
@@ -1470,7 +1520,7 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
}
|
||||
#endif /* IPV6_RECVPKTINFO */
|
||||
#ifdef IPV6_USE_MIN_MTU /*2292bis, not too common yet*/
|
||||
@@ -1730,6 +1780,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
|
||||
ISC_SOCKADDR_LEN_T addrlen;
|
||||
int fd;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
int accept_errno;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
UNUSED(me);
|
||||
|
||||
@@ -1776,16 +1828,18 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
|
||||
fd = accept(sock->fd, &dev->newsocket->address.type.sa,
|
||||
(void *)&addrlen);
|
||||
if (fd < 0) {
|
||||
if (SOFT_ERROR(errno)) {
|
||||
accept_errno = WSAGetLastError();
|
||||
if (SOFT_ERROR(accept_errno) || accept_errno == WSAECONNRESET) {
|
||||
goto soft_error;
|
||||
} else {
|
||||
isc__strerror(accept_errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"internal_accept: accept() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
fd = -1;
|
||||
result = ISC_R_UNEXPECTED;
|
||||
}
|
||||
@@ -1810,6 +1864,15 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
|
||||
sock->pf);
|
||||
(void)closesocket(fd);
|
||||
goto soft_error;
|
||||
} else if (fd >= FD_SETSIZE) {
|
||||
isc_log_iwrite(isc_lctx, ISC_LOGCATEGORY_GENERAL,
|
||||
ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET,
|
||||
ISC_MSG_TOOMANYFDS,
|
||||
"%s: too many open file descriptors",
|
||||
"accept");
|
||||
(void)closesocket(fd);
|
||||
goto soft_error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1837,13 +1900,13 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
|
||||
result = ISC_R_UNEXPECTED;
|
||||
}
|
||||
|
||||
LOCK(&manager->lock);
|
||||
ISC_LIST_APPEND(manager->socklist, dev->newsocket, link);
|
||||
|
||||
/*
|
||||
* -1 means the new socket didn't happen.
|
||||
*/
|
||||
if (fd != -1) {
|
||||
LOCK(&manager->lock);
|
||||
ISC_LIST_APPEND(manager->socklist, dev->newsocket, link);
|
||||
|
||||
dev->newsocket->fd = fd;
|
||||
dev->newsocket->bound = 1;
|
||||
dev->newsocket->connected = 1;
|
||||
@@ -1862,9 +1925,12 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_ACCEPTEDCXN,
|
||||
"accepted connection, new socket %p",
|
||||
dev->newsocket);
|
||||
}
|
||||
|
||||
UNLOCK(&manager->lock);
|
||||
} else {
|
||||
dev->newsocket->references--;
|
||||
free_socket(&dev->newsocket);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the done event details and send it off.
|
||||
@@ -1895,7 +1961,7 @@ internal_recv(isc_task_t *me, isc_event_t *ev) {
|
||||
LOCK(&sock->lock);
|
||||
socket_log(sock, NULL, IOEVENT,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALRECV,
|
||||
"internal_recv: task %p got event %p", me, ev, sock);
|
||||
"internal_recv: task %p got event %p", me, ev);
|
||||
|
||||
INSIST(sock->pending_recv == 1);
|
||||
sock->pending_recv = 0;
|
||||
@@ -1963,7 +2029,7 @@ internal_send(isc_task_t *me, isc_event_t *ev) {
|
||||
LOCK(&sock->lock);
|
||||
socket_log(sock, NULL, IOEVENT,
|
||||
isc_msgcat, ISC_MSGSET_SOCKET, ISC_MSG_INTERNALSEND,
|
||||
"internal_send: task %p got event %p", me, ev, sock);
|
||||
"internal_send: task %p got event %p", me, ev);
|
||||
|
||||
INSIST(sock->pending_send == 1);
|
||||
sock->pending_send = 0;
|
||||
@@ -2004,11 +2070,14 @@ internal_send(isc_task_t *me, isc_event_t *ev) {
|
||||
|
||||
static void
|
||||
process_fds(isc_socketmgr_t *manager, int maxfd,
|
||||
fd_set *readfds, fd_set *writefds)
|
||||
fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
|
||||
{
|
||||
int i;
|
||||
isc_socket_t *sock;
|
||||
isc_boolean_t unlock_sock;
|
||||
BOOL conn_check = FALSE;
|
||||
|
||||
REQUIRE(maxfd <= FD_SETSIZE);
|
||||
|
||||
/*
|
||||
* Process read/writes on other fds here. Avoid locking
|
||||
@@ -2019,6 +2088,7 @@ process_fds(isc_socketmgr_t *manager, int maxfd,
|
||||
manager->fdstate[i] = CLOSED;
|
||||
FD_CLR(i, &manager->read_fds);
|
||||
FD_CLR(i, &manager->write_fds);
|
||||
FD_CLR(i, &manager->except_fds);
|
||||
|
||||
closesocket(i);
|
||||
|
||||
@@ -2053,13 +2123,37 @@ process_fds(isc_socketmgr_t *manager, int maxfd,
|
||||
LOCK(&sock->lock);
|
||||
}
|
||||
if (!SOCK_DEAD(sock)) {
|
||||
if (sock->connecting)
|
||||
if (sock->connecting) {
|
||||
dispatch_connect(sock);
|
||||
conn_check = TRUE;
|
||||
}
|
||||
else
|
||||
dispatch_send(sock);
|
||||
}
|
||||
FD_CLR(i, &manager->write_fds);
|
||||
}
|
||||
if (FD_ISSET(i, exceptfds)) {
|
||||
if (sock == NULL) {
|
||||
FD_CLR(i, &manager->except_fds);
|
||||
continue;
|
||||
}
|
||||
if (!unlock_sock) {
|
||||
unlock_sock = ISC_TRUE;
|
||||
LOCK(&sock->lock);
|
||||
}
|
||||
if (!SOCK_DEAD(sock)) {
|
||||
if (sock->connecting) {
|
||||
dispatch_connect(sock);
|
||||
conn_check = TRUE;
|
||||
}
|
||||
}
|
||||
FD_CLR(i, &manager->write_fds);
|
||||
FD_CLR(i, &manager->except_fds);
|
||||
}
|
||||
|
||||
// if(sock != NULL && sock->connecting && conn_check == FALSE)
|
||||
// dispatch_connect(sock);
|
||||
|
||||
if (unlock_sock)
|
||||
UNLOCK(&sock->lock);
|
||||
}
|
||||
@@ -2081,8 +2175,10 @@ watcher(void *uap) {
|
||||
int cc;
|
||||
fd_set readfds;
|
||||
fd_set writefds;
|
||||
fd_set exceptfds;
|
||||
int msg, fd;
|
||||
int maxfd;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
/* 30 Second timeout on select in case it's necesasary */
|
||||
struct timeval tv;
|
||||
@@ -2100,20 +2196,24 @@ watcher(void *uap) {
|
||||
do {
|
||||
readfds = manager->read_fds;
|
||||
writefds = manager->write_fds;
|
||||
exceptfds = manager->except_fds;
|
||||
maxfd = manager->maxfd + 1;
|
||||
|
||||
UNLOCK(&manager->lock);
|
||||
|
||||
cc = select(maxfd, &readfds, &writefds, NULL, &tv);
|
||||
cc = select(maxfd, &readfds, &writefds, &exceptfds, &tv);
|
||||
if (cc < 0) {
|
||||
if (!SOFT_ERROR(errno))
|
||||
if (!SOFT_ERROR(errno)) {
|
||||
isc__strerror(errno, strbuf,
|
||||
sizeof(strbuf));
|
||||
FATAL_ERROR(__FILE__, __LINE__,
|
||||
"select() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat,
|
||||
ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED,
|
||||
"failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
}
|
||||
}
|
||||
|
||||
LOCK(&manager->lock);
|
||||
@@ -2152,7 +2252,7 @@ watcher(void *uap) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
process_fds(manager, maxfd, &readfds, &writefds);
|
||||
process_fds(manager, maxfd, &readfds, &writefds, &exceptfds);
|
||||
}
|
||||
|
||||
manager_log(manager, TRACE,
|
||||
@@ -2170,6 +2270,9 @@ watcher(void *uap) {
|
||||
isc_result_t
|
||||
isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
|
||||
isc_socketmgr_t *manager;
|
||||
#ifdef ISC_PLATFORM_USETHREADS
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
#endif
|
||||
|
||||
REQUIRE(managerp != NULL && *managerp == NULL);
|
||||
|
||||
@@ -2214,11 +2317,12 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
|
||||
if (internal_pipe(manager->pipe_fds) != 0) {
|
||||
DESTROYLOCK(&manager->lock);
|
||||
isc_mem_put(mctx, manager, sizeof *manager);
|
||||
isc__strerror(errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"pipe() %s: %s",
|
||||
isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
|
||||
ISC_MSG_FAILED, "failed"),
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
@@ -2229,6 +2333,7 @@ isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp) {
|
||||
*/
|
||||
FD_ZERO(&manager->read_fds);
|
||||
FD_ZERO(&manager->write_fds);
|
||||
FD_ZERO(&manager->except_fds);
|
||||
manager->maxfd = 0;
|
||||
memset(manager->fdstate, 0, sizeof(manager->fdstate));
|
||||
|
||||
@@ -2565,8 +2670,9 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
||||
case DOIO_SOFT:
|
||||
/*
|
||||
* We couldn't send all or part of the request right now, so
|
||||
* queue it.
|
||||
* queue it unless ISC_SOCKFLAG_NORETRY is set.
|
||||
*/
|
||||
if ((flags & ISC_SOCKFLAG_NORETRY) == 0) {
|
||||
isc_task_attach(task, &ntask);
|
||||
dev->attributes |= ISC_SOCKEVENTATTR_ATTACHED;
|
||||
|
||||
@@ -2591,6 +2697,7 @@ socket_send(isc_socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
|
||||
if ((flags & ISC_SOCKFLAG_IMMEDIATE) != 0)
|
||||
result = ISC_R_INPROGRESS;
|
||||
break;
|
||||
}
|
||||
|
||||
case DOIO_HARD:
|
||||
case DOIO_SUCCESS:
|
||||
@@ -2698,6 +2805,9 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
|
||||
isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
|
||||
isc_socketevent_t *event, unsigned int flags)
|
||||
{
|
||||
REQUIRE((flags & ~(ISC_SOCKFLAG_IMMEDIATE|ISC_SOCKFLAG_NORETRY)) == 0);
|
||||
if ((flags & ISC_SOCKFLAG_NORETRY) != 0)
|
||||
REQUIRE(sock->type == isc_sockettype_udp);
|
||||
event->ev_sender = sock;
|
||||
event->result = ISC_R_UNEXPECTED;
|
||||
ISC_LIST_INIT(event->bufferlist);
|
||||
@@ -2711,6 +2821,8 @@ isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
|
||||
|
||||
isc_result_t
|
||||
isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
|
||||
int bind_errno;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
int on = 1;
|
||||
|
||||
LOCK(&sock->lock);
|
||||
@@ -2730,19 +2842,21 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
|
||||
/* Press on... */
|
||||
}
|
||||
if (bind(sock->fd, &sockaddr->type.sa, sockaddr->length) < 0) {
|
||||
bind_errno = WSAGetLastError();
|
||||
UNLOCK(&sock->lock);
|
||||
switch (errno) {
|
||||
case EACCES:
|
||||
switch (bind_errno) {
|
||||
case WSAEACCES:
|
||||
return (ISC_R_NOPERM);
|
||||
case EADDRNOTAVAIL:
|
||||
case WSAEADDRNOTAVAIL:
|
||||
return (ISC_R_ADDRNOTAVAIL);
|
||||
case EADDRINUSE:
|
||||
case WSAEADDRINUSE:
|
||||
return (ISC_R_ADDRINUSE);
|
||||
case EINVAL:
|
||||
case WSAEINVAL:
|
||||
return (ISC_R_BOUND);
|
||||
default:
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"bind: %s", strerror(errno));
|
||||
isc__strerror(bind_errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "bind: %s",
|
||||
strbuf);
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
}
|
||||
@@ -2767,6 +2881,8 @@ isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *sockaddr) {
|
||||
*/
|
||||
isc_result_t
|
||||
isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
|
||||
LOCK(&sock->lock);
|
||||
@@ -2780,8 +2896,9 @@ isc_socket_listen(isc_socket_t *sock, unsigned int backlog) {
|
||||
|
||||
if (listen(sock->fd, (int)backlog) < 0) {
|
||||
UNLOCK(&sock->lock);
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "listen: %s",
|
||||
strerror(errno));
|
||||
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
|
||||
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "listen: %s", strbuf);
|
||||
|
||||
return (ISC_R_UNEXPECTED);
|
||||
}
|
||||
@@ -2869,6 +2986,8 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
|
||||
isc_task_t *ntask = NULL;
|
||||
isc_socketmgr_t *manager;
|
||||
int cc;
|
||||
int errval;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(addr != NULL);
|
||||
@@ -2903,10 +3022,11 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
|
||||
sock->address = *addr;
|
||||
cc = connect(sock->fd, &addr->type.sa, addr->length);
|
||||
if (cc < 0) {
|
||||
if (SOFT_ERROR(errno) || errno == EINPROGRESS)
|
||||
errval = WSAGetLastError();
|
||||
if (SOFT_ERROR(errval) || errval == WSAEINPROGRESS)
|
||||
goto queue;
|
||||
|
||||
switch (errno) {
|
||||
switch (errval) {
|
||||
#define ERROR_MATCH(a, b) case a: dev->result = b; goto err_exit;
|
||||
ERROR_MATCH(WSAEACCES, ISC_R_NOPERM);
|
||||
ERROR_MATCH(WSAEADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);
|
||||
@@ -2923,8 +3043,8 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr,
|
||||
|
||||
sock->connected = 0;
|
||||
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "%d/%s",
|
||||
errno, strerror(errno));
|
||||
isc__strerror(errval, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "%d/%s", errval, strbuf);
|
||||
|
||||
UNLOCK(&sock->lock);
|
||||
isc_event_free((isc_event_t **)&dev);
|
||||
@@ -2986,6 +3106,8 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
isc_task_t *task;
|
||||
int cc;
|
||||
ISC_SOCKADDR_LEN_T optlen;
|
||||
int connect_errno;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
UNUSED(me);
|
||||
INSIST(ev->ev_type == ISC_SOCKEVENT_INTW);
|
||||
@@ -3026,16 +3148,16 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
optlen = sizeof(cc);
|
||||
if (getsockopt(sock->fd, SOL_SOCKET, SO_ERROR,
|
||||
(void *)&cc, (void *)&optlen) < 0)
|
||||
cc = errno;
|
||||
connect_errno = WSAGetLastError();
|
||||
else
|
||||
errno = cc;
|
||||
connect_errno = cc;
|
||||
|
||||
if (errno != 0) {
|
||||
if (connect_errno != 0) {
|
||||
/*
|
||||
* If the error is EAGAIN, just re-select on this
|
||||
* fd and pretend nothing strange happened.
|
||||
*/
|
||||
if (SOFT_ERROR(errno) || errno == EINPROGRESS) {
|
||||
if (SOFT_ERROR(connect_errno) || connect_errno == WSAEINPROGRESS) {
|
||||
sock->connecting = 1;
|
||||
select_poke(sock->manager, sock->fd,
|
||||
SELECT_POKE_CONNECT);
|
||||
@@ -3047,7 +3169,7 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
/*
|
||||
* Translate other errors into ISC_R_* flavors.
|
||||
*/
|
||||
switch (errno) {
|
||||
switch (connect_errno) {
|
||||
#define ERROR_MATCH(a, b) case a: dev->result = b; break;
|
||||
ERROR_MATCH(WSAEACCES, ISC_R_NOPERM);
|
||||
ERROR_MATCH(WSAEADDRNOTAVAIL, ISC_R_ADDRNOTAVAIL);
|
||||
@@ -3063,9 +3185,10 @@ internal_connect(isc_task_t *me, isc_event_t *ev) {
|
||||
#undef ERROR_MATCH
|
||||
default:
|
||||
dev->result = ISC_R_UNEXPECTED;
|
||||
isc__strerror(connect_errno, strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"internal_connect: connect() %s",
|
||||
strerror(errno));
|
||||
strbuf);
|
||||
}
|
||||
} else {
|
||||
dev->result = ISC_R_SUCCESS;
|
||||
@@ -3107,6 +3230,7 @@ isc_result_t
|
||||
isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
|
||||
ISC_SOCKADDR_LEN_T len;
|
||||
isc_result_t ret;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
REQUIRE(addressp != NULL);
|
||||
@@ -3122,8 +3246,9 @@ isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp) {
|
||||
|
||||
len = sizeof addressp->type;
|
||||
if (getsockname(sock->fd, &addressp->type.sa, (void *)&len) < 0) {
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||
"getsockname: %s", strerror(errno));
|
||||
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
|
||||
UNEXPECTED_ERROR(__FILE__, __LINE__, "getsockname: %s",
|
||||
strbuf);
|
||||
ret = ISC_R_UNEXPECTED;
|
||||
goto out;
|
||||
}
|
||||
|
Reference in New Issue
Block a user