mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
snapshot
This commit is contained in:
@@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#define SOFT_ERROR(e) ((e) == EAGAIN || (e) == EWOULDBLOCK || (e) == EINTR)
|
#define SOFT_ERROR(e) ((e) == EAGAIN || (e) == EWOULDBLOCK || (e) == EINTR)
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
#define ISC_SOCKET_DEBUG
|
#define ISC_SOCKET_DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -57,7 +57,6 @@
|
|||||||
#define TRACE_RECV 0x0008
|
#define TRACE_RECV 0x0008
|
||||||
#define TRACE_SEND 0x0010
|
#define TRACE_SEND 0x0010
|
||||||
#define TRACE_MANAGER 0x0020
|
#define TRACE_MANAGER 0x0020
|
||||||
#define TRACE_LOCK 0x0040
|
|
||||||
|
|
||||||
int trace_level = 0xffffffff;
|
int trace_level = 0xffffffff;
|
||||||
#define XTRACE(l, a) if (l & trace_level) printf a
|
#define XTRACE(l, a) if (l & trace_level) printf a
|
||||||
@@ -123,6 +122,7 @@ struct isc_socket {
|
|||||||
isc_boolean_t pending_send;
|
isc_boolean_t pending_send;
|
||||||
isc_boolean_t pending_accept;
|
isc_boolean_t pending_accept;
|
||||||
isc_boolean_t listener; /* is a listener socket */
|
isc_boolean_t listener; /* is a listener socket */
|
||||||
|
isc_boolean_t connected;
|
||||||
isc_boolean_t connecting; /* connect pending */
|
isc_boolean_t connecting; /* connect pending */
|
||||||
rwintev_t * riev; /* allocated recv intev */
|
rwintev_t * riev; /* allocated recv intev */
|
||||||
rwintev_t * wiev; /* allocated send intev */
|
rwintev_t * wiev; /* allocated send intev */
|
||||||
@@ -295,7 +295,7 @@ done_event_destroy(isc_event_t *ev)
|
|||||||
* task when we actually queue this event up.
|
* task when we actually queue this event up.
|
||||||
*/
|
*/
|
||||||
LOCK(&sock->lock);
|
LOCK(&sock->lock);
|
||||||
|
|
||||||
REQUIRE(sock->references > 0);
|
REQUIRE(sock->references > 0);
|
||||||
sock->references--;
|
sock->references--;
|
||||||
XTRACE(TRACE_MANAGER, ("done_event_destroy: sock %p, ref cnt == %d\n",
|
XTRACE(TRACE_MANAGER, ("done_event_destroy: sock %p, ref cnt == %d\n",
|
||||||
@@ -373,6 +373,7 @@ allocate_socket(isc_socketmgr_t *manager, isc_sockettype_t type,
|
|||||||
sock->pending_accept = ISC_FALSE;
|
sock->pending_accept = ISC_FALSE;
|
||||||
sock->listener = ISC_FALSE;
|
sock->listener = ISC_FALSE;
|
||||||
sock->connecting = ISC_FALSE;
|
sock->connecting = ISC_FALSE;
|
||||||
|
sock->connected = ISC_FALSE;
|
||||||
|
|
||||||
sock->recv_result = ISC_R_SUCCESS;
|
sock->recv_result = ISC_R_SUCCESS;
|
||||||
sock->send_result = ISC_R_SUCCESS;
|
sock->send_result = ISC_R_SUCCESS;
|
||||||
@@ -750,12 +751,7 @@ internal_accept(isc_task_t *task, isc_event_t *ev)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If some other error, ignore it as well and hope
|
* If some other error, ignore it as well and hope
|
||||||
* for the best, but log it. XXX This will have to be
|
* for the best, but log it.
|
||||||
* changed, thanks to broken OSs trying to overload what
|
|
||||||
* accept does.
|
|
||||||
*
|
|
||||||
* XXX we should log something. Consider if we really
|
|
||||||
* want to press on here. Need to catch fatal errors.
|
|
||||||
*/
|
*/
|
||||||
XTRACE(TRACE_LISTEN, ("internal_accept: accept returned %s\n",
|
XTRACE(TRACE_LISTEN, ("internal_accept: accept returned %s\n",
|
||||||
strerror(errno)));
|
strerror(errno)));
|
||||||
@@ -864,7 +860,7 @@ internal_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
if (iev->canceled) {
|
if (iev->canceled) {
|
||||||
DEQUEUE(sock->recv_list, iev, link);
|
DEQUEUE(sock->recv_list, iev, link);
|
||||||
isc_event_free((isc_event_t **)&iev);
|
isc_event_free((isc_event_t **)&iev);
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -874,7 +870,7 @@ internal_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
if (dev->common.type == ISC_SOCKEVENT_RECVMARK) {
|
if (dev->common.type == ISC_SOCKEVENT_RECVMARK) {
|
||||||
send_recvdone_event(sock, &iev, &dev,
|
send_recvdone_event(sock, &iev, &dev,
|
||||||
sock->recv_result);
|
sock->recv_result);
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -907,6 +903,32 @@ internal_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
if (cc < 0) {
|
if (cc < 0) {
|
||||||
if (SOFT_ERROR(errno))
|
if (SOFT_ERROR(errno))
|
||||||
goto poke;
|
goto poke;
|
||||||
|
|
||||||
|
#define SOFT_OR_HARD(_system, _isc) \
|
||||||
|
if (errno == _system) { \
|
||||||
|
if (sock->connected) { \
|
||||||
|
if (sock->type == isc_socket_tcp) \
|
||||||
|
sock->recv_result = _isc; \
|
||||||
|
send_recvdone_event(sock, &iev, &dev, _isc); \
|
||||||
|
} \
|
||||||
|
goto next; \
|
||||||
|
}
|
||||||
|
|
||||||
|
SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED);
|
||||||
|
SOFT_OR_HARD(ENETUNREACH, ISC_R_NETUNREACH);
|
||||||
|
SOFT_OR_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH);
|
||||||
|
#undef SOFT_OR_HARD
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This might not be a permanent error.
|
||||||
|
*/
|
||||||
|
if (errno == ENOBUFS) {
|
||||||
|
send_recvdone_event(sock, &iev, &dev,
|
||||||
|
ISC_R_NORESOURCES);
|
||||||
|
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"internal read: %s", strerror(errno));
|
"internal read: %s", strerror(errno));
|
||||||
|
|
||||||
@@ -914,8 +936,9 @@ internal_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
send_recvdone_event(sock, &iev, &dev,
|
send_recvdone_event(sock, &iev, &dev,
|
||||||
ISC_R_UNEXPECTED); /* XXX */
|
ISC_R_UNEXPECTED); /* XXX */
|
||||||
|
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read of 0 means the remote end was closed. Run through
|
* read of 0 means the remote end was closed. Run through
|
||||||
* the event queue and dispatch all the events with an EOF
|
* the event queue and dispatch all the events with an EOF
|
||||||
@@ -947,7 +970,7 @@ internal_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
if (iev->partial) {
|
if (iev->partial) {
|
||||||
send_recvdone_event(sock, &iev, &dev,
|
send_recvdone_event(sock, &iev, &dev,
|
||||||
ISC_R_SUCCESS);
|
ISC_R_SUCCESS);
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -966,6 +989,7 @@ internal_recv(isc_task_t *task, isc_event_t *ev)
|
|||||||
send_recvdone_event(sock, &iev, &dev, ISC_R_SUCCESS);
|
send_recvdone_event(sock, &iev, &dev, ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
} while (!EMPTY(sock->recv_list));
|
} while (!EMPTY(sock->recv_list));
|
||||||
|
|
||||||
poke:
|
poke:
|
||||||
@@ -1020,7 +1044,7 @@ internal_send(isc_task_t *task, isc_event_t *ev)
|
|||||||
if (iev->canceled) {
|
if (iev->canceled) {
|
||||||
DEQUEUE(sock->send_list, iev, link);
|
DEQUEUE(sock->send_list, iev, link);
|
||||||
isc_event_free((isc_event_t **)&iev);
|
isc_event_free((isc_event_t **)&iev);
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1030,7 +1054,7 @@ internal_send(isc_task_t *task, isc_event_t *ev)
|
|||||||
if (dev->common.type == ISC_SOCKEVENT_SENDMARK) {
|
if (dev->common.type == ISC_SOCKEVENT_SENDMARK) {
|
||||||
send_senddone_event(sock, &iev, &dev,
|
send_senddone_event(sock, &iev, &dev,
|
||||||
sock->send_result);
|
sock->send_result);
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1055,6 +1079,31 @@ internal_send(isc_task_t *task, isc_event_t *ev)
|
|||||||
if (SOFT_ERROR(errno))
|
if (SOFT_ERROR(errno))
|
||||||
goto poke;
|
goto poke;
|
||||||
|
|
||||||
|
#define SOFT_OR_HARD(_system, _isc) \
|
||||||
|
if (errno == _system) { \
|
||||||
|
if (sock->connected) { \
|
||||||
|
if (sock->type == isc_socket_tcp) \
|
||||||
|
sock->recv_result = _isc; \
|
||||||
|
send_senddone_event(sock, &iev, &dev, _isc); \
|
||||||
|
} \
|
||||||
|
goto next; \
|
||||||
|
}
|
||||||
|
|
||||||
|
SOFT_OR_HARD(ECONNREFUSED, ISC_R_CONNREFUSED);
|
||||||
|
SOFT_OR_HARD(ENETUNREACH, ISC_R_NETUNREACH);
|
||||||
|
SOFT_OR_HARD(EHOSTUNREACH, ISC_R_HOSTUNREACH);
|
||||||
|
#undef SOFT_OR_HARD
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This might not be a permanent error.
|
||||||
|
*/
|
||||||
|
if (errno == ENOBUFS) {
|
||||||
|
send_recvdone_event(sock, &iev, &dev,
|
||||||
|
ISC_R_NORESOURCES);
|
||||||
|
|
||||||
|
goto next;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The other error types depend on wether or not the
|
* The other error types depend on wether or not the
|
||||||
* socket is UDP or TCP. If it is UDP, some errors
|
* socket is UDP or TCP. If it is UDP, some errors
|
||||||
@@ -1067,12 +1116,11 @@ internal_send(isc_task_t *task, isc_event_t *ev)
|
|||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"internal_send: %s",
|
"internal_send: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
|
sock->send_result = ISC_R_UNEXPECTED;
|
||||||
sock->send_result = ISC_R_UNEXPECTED; /* XXX */
|
|
||||||
send_senddone_event(sock, &iev, &dev,
|
send_senddone_event(sock, &iev, &dev,
|
||||||
ISC_R_UNEXPECTED); /* XXX */
|
ISC_R_UNEXPECTED);
|
||||||
|
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc == 0)
|
if (cc == 0)
|
||||||
@@ -1097,9 +1145,10 @@ internal_send(isc_task_t *task, isc_event_t *ev)
|
|||||||
dev->n += write_count;
|
dev->n += write_count;
|
||||||
send_senddone_event(sock, &iev, &dev, ISC_R_SUCCESS);
|
send_senddone_event(sock, &iev, &dev, ISC_R_SUCCESS);
|
||||||
|
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
next:
|
||||||
} while (!EMPTY(sock->send_list));
|
} while (!EMPTY(sock->send_list));
|
||||||
|
|
||||||
poke:
|
poke:
|
||||||
@@ -1529,17 +1578,17 @@ isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
|
|||||||
|
|
||||||
sock->references++; /* attach to socket in cheap way */
|
sock->references++; /* attach to socket in cheap way */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remember that we need to detach on event free
|
||||||
|
*/
|
||||||
|
ev->common.destroy = done_event_destroy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* UDP sockets are always partial read
|
* UDP sockets are always partial read
|
||||||
*/
|
*/
|
||||||
if (sock->type == isc_socket_udp)
|
if (sock->type == isc_socket_udp)
|
||||||
partial = ISC_TRUE;
|
partial = ISC_TRUE;
|
||||||
|
|
||||||
/*
|
|
||||||
* Remember that we need to detach on event free
|
|
||||||
*/
|
|
||||||
ev->common.destroy = done_event_destroy;
|
|
||||||
|
|
||||||
ev->region = *region;
|
ev->region = *region;
|
||||||
ev->n = 0;
|
ev->n = 0;
|
||||||
ev->result = ISC_R_SUCCESS;
|
ev->result = ISC_R_SUCCESS;
|
||||||
@@ -1676,6 +1725,7 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
|
|||||||
if (iev == NULL) {
|
if (iev == NULL) {
|
||||||
/* no special free routine yet */
|
/* no special free routine yet */
|
||||||
isc_event_free((isc_event_t **)&ev);
|
isc_event_free((isc_event_t **)&ev);
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1729,6 +1779,7 @@ isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
|
|||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"isc_socket_send: "
|
"isc_socket_send: "
|
||||||
"unknown socket type");
|
"unknown socket type");
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_UNEXPECTED);
|
return (ISC_R_UNEXPECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2020,11 +2071,6 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, int addrlen,
|
|||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* attach to socket
|
|
||||||
*/
|
|
||||||
sock->references++;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to do the connect right away, as there can be only one
|
* Try to do the connect right away, as there can be only one
|
||||||
* outstanding, and it might happen to complete.
|
* outstanding, and it might happen to complete.
|
||||||
@@ -2036,16 +2082,26 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, int addrlen,
|
|||||||
if (SOFT_ERROR(errno) || errno == EINPROGRESS)
|
if (SOFT_ERROR(errno) || errno == EINPROGRESS)
|
||||||
goto queue;
|
goto queue;
|
||||||
|
|
||||||
|
sock->connected = ISC_FALSE;
|
||||||
|
|
||||||
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
UNEXPECTED_ERROR(__FILE__, __LINE__,
|
||||||
"%s", strerror(errno));
|
"%s", strerror(errno));
|
||||||
|
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_UNEXPECTED);
|
return (ISC_R_UNEXPECTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* attach to socket
|
||||||
|
*/
|
||||||
|
sock->references++;
|
||||||
|
dev->common.destroy = done_event_destroy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If connect completed, fire off the done event
|
* If connect completed, fire off the done event
|
||||||
*/
|
*/
|
||||||
if (cc == 0) {
|
if (cc == 0) {
|
||||||
|
sock->connected = ISC_TRUE;
|
||||||
dev->result = ISC_R_SUCCESS;
|
dev->result = ISC_R_SUCCESS;
|
||||||
ISC_TASK_SEND(task, (isc_event_t **)&dev);
|
ISC_TASK_SEND(task, (isc_event_t **)&dev);
|
||||||
UNLOCK(&sock->lock);
|
UNLOCK(&sock->lock);
|
||||||
@@ -2066,7 +2122,6 @@ isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addr, int addrlen,
|
|||||||
sock->ciev->task = ntask;
|
sock->ciev->task = ntask;
|
||||||
sock->ciev->done_ev = dev;
|
sock->ciev->done_ev = dev;
|
||||||
sock->ciev->canceled = ISC_FALSE;
|
sock->ciev->canceled = ISC_FALSE;
|
||||||
dev->common.destroy = done_event_destroy;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* poke watcher here. We still have the socket locked, so there
|
* poke watcher here. We still have the socket locked, so there
|
||||||
@@ -2420,6 +2475,7 @@ isc_socket_recvmark(isc_socket_t *sock,
|
|||||||
|
|
||||||
if (iev == NULL) {
|
if (iev == NULL) {
|
||||||
isc_event_free((isc_event_t **)&dev);
|
isc_event_free((isc_event_t **)&dev);
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2497,6 +2553,7 @@ isc_socket_sendmark(isc_socket_t *sock,
|
|||||||
|
|
||||||
if (iev == NULL) {
|
if (iev == NULL) {
|
||||||
isc_event_free((isc_event_t **)&dev);
|
isc_event_free((isc_event_t **)&dev);
|
||||||
|
UNLOCK(&sock->lock);
|
||||||
return (ISC_R_NOMEMORY);
|
return (ISC_R_NOMEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user