2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 15:05:23 +00:00
This commit is contained in:
Michael Graff
1998-12-18 01:48:43 +00:00
parent b8255019a5
commit 93e065e7a6

View File

@@ -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);
} }