diff options
author | erwin <erwin@FreeBSD.org> | 2013-08-22 08:15:03 +0000 |
---|---|---|
committer | erwin <erwin@FreeBSD.org> | 2013-08-22 08:15:03 +0000 |
commit | 6a288ef517fece2ca5a21d081efd7b4a81da0053 (patch) | |
tree | 37271fd86c9be9a6bab12a7aebd85ccfbb8a7b62 /contrib/bind9/lib/isc/unix | |
parent | 0b46e38a09fbccfdfd7bca0f387c66b2c64fa5b6 (diff) | |
parent | f32b4abce98c97ee6e51b7aa8f8fde6e4cab7f28 (diff) | |
download | FreeBSD-src-6a288ef517fece2ca5a21d081efd7b4a81da0053.zip FreeBSD-src-6a288ef517fece2ca5a21d081efd7b4a81da0053.tar.gz |
Update Bind to 9.9.3-P2
Notable new features:
* Elliptic Curve Digital Signature Algorithm keys and signatures in
DNSSEC are now supported per RFC 6605. [RT #21918]
* Introduces a new tool "dnssec-verify" that validates a signed zone,
checking for the correctness of signatures and NSEC/NSEC3 chains.
[RT #23673]
* BIND now recognizes the TLSA resource record type, created to
support IETF DANE (DNS-based Authentication of Named Entities)
[RT #28989]
* The new "inline-signing" option, in combination with the
"auto-dnssec" option that was introduced in BIND 9.7, allows
named to sign zones completely transparently.
Approved by: delphij (mentor)
MFC after: 3 days
Sponsored by: DK Hostmaster A/S
Diffstat (limited to 'contrib/bind9/lib/isc/unix')
-rw-r--r-- | contrib/bind9/lib/isc/unix/socket.c | 129 |
1 files changed, 99 insertions, 30 deletions
diff --git a/contrib/bind9/lib/isc/unix/socket.c b/contrib/bind9/lib/isc/unix/socket.c index d007598..7bd12aa 100644 --- a/contrib/bind9/lib/isc/unix/socket.c +++ b/contrib/bind9/lib/isc/unix/socket.c @@ -334,7 +334,8 @@ struct isc__socket { listener : 1, /* listener socket */ connected : 1, connecting : 1, /* connect pending */ - bound : 1; /* bound to local addr */ + bound : 1, /* bound to local addr */ + dupped : 1; #ifdef ISC_NET_RECVOVERFLOW unsigned char overflow; /* used for MSG_TRUNC fake */ @@ -428,6 +429,10 @@ static isc__socketmgr_t *socketmgr = NULL; # define MAXSCATTERGATHER_RECV (ISC_SOCKET_MAXSCATTERGATHER) #endif +static isc_result_t socket_create(isc_socketmgr_t *manager0, int pf, + isc_sockettype_t type, + isc_socket_t **socketp, + isc_socket_t *dup_socket); static void send_recvdone_event(isc__socket_t *, isc_socketevent_t **); static void send_senddone_event(isc__socket_t *, isc_socketevent_t **); static void free_socket(isc__socket_t **); @@ -546,6 +551,10 @@ isc__socket_fdwatchcreate(isc_socketmgr_t *manager, int fd, int flags, isc_task_t *task, isc_socket_t **socketp); ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_fdwatchpoke(isc_socket_t *sock, int flags); +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_dup(isc_socket_t *sock, isc_socket_t **socketp); +ISC_SOCKETFUNC_SCOPE int +isc__socket_getfd(isc_socket_t *sock); static struct { isc_socketmethods_t methods; @@ -563,13 +572,17 @@ static struct { isc__socket_detach, isc__socket_bind, isc__socket_sendto, + isc__socket_sendto2, isc__socket_connect, isc__socket_recv, + isc__socket_recv2, isc__socket_cancel, isc__socket_getsockname, isc__socket_gettype, isc__socket_ipv6only, - isc__socket_fdwatchpoke + isc__socket_fdwatchpoke, + isc__socket_dup, + isc__socket_getfd } #ifndef BIND9 , @@ -2046,6 +2059,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type, sock->manager = manager; sock->type = type; sock->fd = -1; + sock->dupped = 0; sock->statsindex = NULL; ISC_LINK_INIT(sock, link); @@ -2251,7 +2265,9 @@ use_min_mtu(isc__socket_t *sock) { } static isc_result_t -opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { +opensocket(isc__socketmgr_t *manager, isc__socket_t *sock, + isc__socket_t *dup_socket) +{ isc_result_t result; char strbuf[ISC_STRERRORSIZE]; const char *err = "socket"; @@ -2265,22 +2281,29 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { #endif again: - switch (sock->type) { - case isc_sockettype_udp: - sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP); - break; - case isc_sockettype_tcp: - sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); - break; - case isc_sockettype_unix: - sock->fd = socket(sock->pf, SOCK_STREAM, 0); - break; - case isc_sockettype_fdwatch: - /* - * We should not be called for isc_sockettype_fdwatch sockets. - */ - INSIST(0); - break; + if (dup_socket == NULL) { + switch (sock->type) { + case isc_sockettype_udp: + sock->fd = socket(sock->pf, SOCK_DGRAM, IPPROTO_UDP); + break; + case isc_sockettype_tcp: + sock->fd = socket(sock->pf, SOCK_STREAM, IPPROTO_TCP); + break; + case isc_sockettype_unix: + sock->fd = socket(sock->pf, SOCK_STREAM, 0); + 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; @@ -2357,6 +2380,9 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { } } + if (dup_socket != NULL) + goto setup_done; + result = make_nonblock(sock->fd); if (result != ISC_R_SUCCESS) { (void)close(sock->fd); @@ -2521,20 +2547,21 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) { } #endif /* defined(USE_CMSG) || defined(SO_RCVBUF) */ +setup_done: inc_stats(manager->stats, sock->statsindex[STATID_OPEN]); 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'. +/* + * Create a 'type' socket or duplicate an existing 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_SOCKETFUNC_SCOPE isc_result_t -isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, - isc_socket_t **socketp) +static isc_result_t +socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + isc_socket_t **socketp, isc_socket_t *dup_socket) { isc__socket_t *sock = NULL; isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0; @@ -2566,7 +2593,8 @@ isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, } sock->pf = pf; - result = opensocket(manager, sock); + + result = opensocket(manager, sock, (isc__socket_t *)dup_socket); if (result != ISC_R_SUCCESS) { inc_stats(manager->stats, sock->statsindex[STATID_OPENFAIL]); free_socket(&sock); @@ -2601,11 +2629,40 @@ isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, UNLOCK(&manager->lock); socket_log(sock, NULL, CREATION, isc_msgcat, ISC_MSGSET_SOCKET, - ISC_MSG_CREATED, "created"); + ISC_MSG_CREATED, dup_socket != NULL ? "dupped" : "created"); 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_SOCKETFUNC_SCOPE isc_result_t +isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, + isc_socket_t **socketp) +{ + return (socket_create(manager0, pf, type, socketp, NULL)); +} + +/*% + * Duplicate an existing socket. The new socket is returned + * in 'socketp'. + */ +ISC_SOCKETFUNC_SCOPE isc_result_t +isc__socket_dup(isc_socket_t *sock0, isc_socket_t **socketp) { + isc__socket_t *sock = (isc__socket_t *)sock0; + + REQUIRE(VALID_SOCKET(sock)); + REQUIRE(socketp != NULL && *socketp == NULL); + + return (socket_create((isc_socketmgr_t *) sock->manager, + sock->pf, sock->type, socketp, + sock0)); +} + #ifdef BIND9 ISC_SOCKETFUNC_SCOPE isc_result_t isc__socket_open(isc_socket_t *sock0) { @@ -2624,7 +2681,7 @@ isc__socket_open(isc_socket_t *sock0) { */ REQUIRE(sock->fd == -1); - result = opensocket(sock->manager, sock); + result = opensocket(sock->manager, sock, NULL); if (result != ISC_R_SUCCESS) sock->fd = -1; @@ -2804,6 +2861,7 @@ isc__socket_close(isc_socket_t *sock0) { int fd; isc__socketmgr_t *manager; + fflush(stdout); REQUIRE(VALID_SOCKET(sock)); LOCK(&sock->lock); @@ -2824,6 +2882,7 @@ isc__socket_close(isc_socket_t *sock0) { manager = sock->manager; fd = sock->fd; sock->fd = -1; + sock->dupped = 0; memset(sock->name, 0, sizeof(sock->name)); sock->tag = NULL; sock->listener = 0; @@ -4991,11 +5050,13 @@ isc__socket_bind(isc_socket_t *sock0, isc_sockaddr_t *sockaddr, LOCK(&sock->lock); INSIST(!sock->bound); + INSIST(!sock->dupped); if (sock->pf != sockaddr->type.sa.sa_family) { UNLOCK(&sock->lock); return (ISC_R_FAMILYMISMATCH); } + /* * Only set SO_REUSEADDR when we want a specific port. */ @@ -5680,6 +5741,7 @@ isc__socket_ipv6only(isc_socket_t *sock0, isc_boolean_t yes) { #endif REQUIRE(VALID_SOCKET(sock)); + INSIST(!sock->dupped); #ifdef IPV6_V6ONLY if (sock->pf == AF_INET6) { @@ -5846,6 +5908,13 @@ isc__socket_register() { } #endif +ISC_SOCKETFUNC_SCOPE int +isc__socket_getfd(isc_socket_t *socket0) { + isc__socket_t *socket = (isc__socket_t *)socket0; + + return ((short) socket->fd); +} + #if defined(HAVE_LIBXML2) && defined(BIND9) static const char * |