re-merged rt18194 after fixing problems
This commit is contained in:
+15
-3
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: dispatch.c,v 1.116.18.24 2008/06/26 22:18:18 jinmei Exp $ */
|
||||
/* $Id: dispatch.c,v 1.116.18.25 2008/07/03 00:14:39 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -801,6 +801,8 @@ destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
|
||||
*/
|
||||
static void
|
||||
deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
||||
isc_result_t result;
|
||||
|
||||
/*
|
||||
* The dispatch must be locked.
|
||||
*/
|
||||
@@ -813,8 +815,18 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
|
||||
if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
|
||||
destroy_dispsocket(disp, &dispsock);
|
||||
else {
|
||||
isc_socket_close(dispsock->socket);
|
||||
ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
|
||||
result = isc_socket_close(dispsock->socket);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
ISC_LIST_APPEND(disp->inactivesockets, dispsock, link);
|
||||
else {
|
||||
/*
|
||||
* If the underlying system does not allow this
|
||||
* optimization, destroy this temporary structure (and
|
||||
* create a new one for a new transaction).
|
||||
*/
|
||||
INSIST(result == ISC_R_NOTIMPLEMENTED);
|
||||
destroy_dispsocket(disp, &dispsock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: socket.h,v 1.57.18.8 2008/06/24 23:45:55 tbox Exp $ */
|
||||
/* $Id: socket.h,v 1.57.18.9 2008/07/03 00:14:39 each Exp $ */
|
||||
|
||||
#ifndef ISC_SOCKET_H
|
||||
#define ISC_SOCKET_H 1
|
||||
@@ -320,7 +320,8 @@ isc_socket_open(isc_socket_t *sock);
|
||||
* avoid overhead of destroying and creating sockets when many short-lived
|
||||
* sockets are frequently opened and closed. When the efficiency is not an
|
||||
* issue, it should be safer to detach the unused socket and re-create a new
|
||||
* one.
|
||||
* one. This optimization may not be available for some systems, in which
|
||||
* case this function will return ISC_R_NOTIMPLEMENTED and must not be used.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
@@ -330,15 +331,18 @@ isc_socket_open(isc_socket_t *sock);
|
||||
*
|
||||
* Returns:
|
||||
* Same as isc_socket_create().
|
||||
* \li ISC_R_NOTIMPLEMENTED
|
||||
*/
|
||||
|
||||
void
|
||||
isc_result_t
|
||||
isc_socket_close(isc_socket_t *sock);
|
||||
/*%<
|
||||
* Close a socket file descriptor of the given socket structure. This function
|
||||
* is provided as an alternative to destroying an unused socket when overhead
|
||||
* destroying/re-creating sockets can be significant, and is expected to be
|
||||
* used with isc_socket_open().
|
||||
* used with isc_socket_open(). This optimization may not be available for some
|
||||
* systems, in which case this function will return ISC_R_NOTIMPLEMENTED and
|
||||
* must not be used.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
@@ -348,6 +352,8 @@ isc_socket_close(isc_socket_t *sock);
|
||||
*
|
||||
* \li There must be no pending I/O requests.
|
||||
*
|
||||
* Returns:
|
||||
* \li #ISC_R_NOTIMPLEMENTED
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: socket.c,v 1.237.18.37 2008/06/25 22:57:37 jinmei Exp $ */
|
||||
/* $Id: socket.c,v 1.237.18.38 2008/07/03 00:14:40 each Exp $ */
|
||||
|
||||
/*! \file */
|
||||
|
||||
@@ -2113,7 +2113,7 @@ isc_socket_detach(isc_socket_t **socketp) {
|
||||
*socketp = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
isc_result_t
|
||||
isc_socket_close(isc_socket_t *sock) {
|
||||
int fd;
|
||||
|
||||
@@ -2147,6 +2147,8 @@ isc_socket_close(isc_socket_t *sock) {
|
||||
isc_sockaddr_any(&sock->address);
|
||||
|
||||
closesocket(sock->manager, sock->type, fd);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+33
-85
@@ -15,7 +15,7 @@
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: socket.c,v 1.30.18.23 2008/07/01 02:10:06 each Exp $ */
|
||||
/* $Id: socket.c,v 1.30.18.24 2008/07/03 00:14:40 each Exp $ */
|
||||
|
||||
/* This code has been rewritten to take advantage of Windows Sockets
|
||||
* I/O Completion Ports and Events. I/O Completion Ports is ONLY
|
||||
@@ -1171,7 +1171,7 @@ build_msghdr_send(isc_socket_t *sock, isc_socketevent_t *dev,
|
||||
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
|
||||
if (!sock->connected) {
|
||||
if (sock->type == isc_sockettype_udp) {
|
||||
msg->msg_name = (void *)&dev->address.type.sa;
|
||||
msg->msg_namelen = dev->address.length;
|
||||
} else {
|
||||
@@ -1867,8 +1867,16 @@ free_socket(isc_socket_t **socketp) {
|
||||
*socketp = NULL;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
|
||||
/*
|
||||
* 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_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
isc_socket_t **socketp) {
|
||||
isc_socket_t *sock = NULL;
|
||||
isc_result_t result;
|
||||
#if defined(USE_CMSG)
|
||||
int on = 1;
|
||||
@@ -1880,9 +1888,17 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
|
||||
int socket_errno;
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
|
||||
switch (sock->type) {
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
REQUIRE(socketp != NULL && *socketp == NULL);
|
||||
|
||||
result = allocate_socket(manager, type, &sock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
sock->pf = pf;
|
||||
switch (type) {
|
||||
case isc_sockettype_udp:
|
||||
sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP);
|
||||
sock->fd = socket(pf, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (sock->fd != INVALID_SOCKET) {
|
||||
result = connection_reset_fix(sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
@@ -1893,12 +1909,13 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
|
||||
}
|
||||
break;
|
||||
case isc_sockettype_tcp:
|
||||
sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP);
|
||||
sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (sock->fd == INVALID_SOCKET) {
|
||||
socket_errno = WSAGetLastError();
|
||||
free_socket(&sock);
|
||||
|
||||
switch (socket_errno) {
|
||||
case WSAEMFILE:
|
||||
@@ -1926,17 +1943,19 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
|
||||
result = make_nonblock(sock->fd);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
closesocket(sock->fd);
|
||||
free_socket(&sock);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
||||
#if defined(USE_CMSG) || defined(SO_RCVBUF)
|
||||
if (sock->type == isc_sockettype_udp) {
|
||||
if (type == isc_sockettype_udp) {
|
||||
|
||||
#if defined(USE_CMSG)
|
||||
#if defined(ISC_PLATFORM_HAVEIPV6)
|
||||
#ifdef IPV6_RECVPKTINFO
|
||||
/* 2292bis */
|
||||
if ((sock->pf == AF_INET6)
|
||||
if ((pf == AF_INET6)
|
||||
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
|
||||
(void *)&on, sizeof(on)) < 0)) {
|
||||
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
|
||||
@@ -1951,7 +1970,7 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
|
||||
}
|
||||
#else
|
||||
/* 2292 */
|
||||
if ((sock->pf == AF_INET6)
|
||||
if ((pf == AF_INET6)
|
||||
&& (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_PKTINFO,
|
||||
(void *)&on, sizeof(on)) < 0)) {
|
||||
isc__strerror(WSAGetLastError(), strbuf, sizeof(strbuf));
|
||||
@@ -1967,7 +1986,7 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
|
||||
#endif /* IPV6_RECVPKTINFO */
|
||||
#ifdef IPV6_USE_MIN_MTU /*2292bis, not too common yet*/
|
||||
/* use minimum MTU */
|
||||
if (sock->pf == AF_INET6) {
|
||||
if (pf == AF_INET6) {
|
||||
(void)setsockopt(sock->fd, IPPROTO_IPV6,
|
||||
IPV6_USE_MIN_MTU,
|
||||
(void *)&on, sizeof(on));
|
||||
@@ -1990,36 +2009,6 @@ internal_open(isc_socketmgr_t *manager, isc_socket_t *sock) {
|
||||
}
|
||||
#endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
isc_socket_t **socketp) {
|
||||
isc_socket_t *sock = NULL;
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_MANAGER(manager));
|
||||
REQUIRE(socketp != NULL && *socketp == NULL);
|
||||
|
||||
result = allocate_socket(manager, type, &sock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
return (result);
|
||||
|
||||
sock->pf = pf;
|
||||
result = internal_open(manager, sock);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
free_socket(&sock);
|
||||
return (result);
|
||||
}
|
||||
|
||||
sock->references = 1;
|
||||
*socketp = sock;
|
||||
|
||||
@@ -2041,25 +2030,9 @@ isc_socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type,
|
||||
|
||||
isc_result_t
|
||||
isc_socket_open(isc_socket_t *sock) {
|
||||
isc_result_t result;
|
||||
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
|
||||
LOCK(&sock->lock);
|
||||
REQUIRE(sock->references == 1);
|
||||
UNLOCK(&sock->lock);
|
||||
|
||||
/*
|
||||
* We don't need to retain the lock hereafter, since no one else has
|
||||
* this socket.
|
||||
*/
|
||||
REQUIRE(sock->fd == -1);
|
||||
|
||||
result = internal_open(sock->manager, sock);
|
||||
if (result != ISC_R_SUCCESS)
|
||||
sock->fd = -1;
|
||||
|
||||
return (result);
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2103,36 +2076,11 @@ isc_socket_detach(isc_socket_t **socketp) {
|
||||
*socketp = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
isc_result_t
|
||||
isc_socket_close(isc_socket_t *sock) {
|
||||
REQUIRE(VALID_SOCKET(sock));
|
||||
|
||||
LOCK(&sock->lock);
|
||||
REQUIRE(sock->references == 1);
|
||||
UNLOCK(&sock->lock);
|
||||
/*
|
||||
* We don't need to retain the lock hereafter, since no one else has
|
||||
* this socket.
|
||||
*/
|
||||
REQUIRE(sock->fd >= 0);
|
||||
|
||||
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);
|
||||
|
||||
sock->fd = -1;
|
||||
sock->listener = 0;
|
||||
sock->connected = 0;
|
||||
sock->connecting = 0;
|
||||
sock->bound = 0;
|
||||
isc_sockaddr_any(&sock->address);
|
||||
|
||||
socket_close(sock);
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user