From: Mark Andrews Date: Fri, 19 Dec 2014 00:35:07 +0000 (+1100) Subject: 4024. [bug] dns_rdata_opt_first, dns_rdata_opt_next, X-Git-Tag: v9.10.2b1~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=14c7ef12e02d4bb4eb3586a5faeacb570c5a0808;p=thirdparty%2Fbind9.git 4024. [bug] dns_rdata_opt_first, dns_rdata_opt_next, dns_rdata_opt_current, dns_rdata_txt_first, dns_rdata_txt_next and dns_rdata_txt_current were documented but not implemented. These have now been implemented. dns_rdata_spf_first, dns_rdata_spf_next and dns_rdata_spf_current were document but not implemented. The prototypes for these functions have been removed. [RT #38068] 4023. [bug] win32: socket handling with explict ports and invoking named with -4 was broken for some configurations. [RT #38068] (cherry picked from commit 1e0ed0c6f5c359df88767e2c4f0fda24f2da0468) --- diff --git a/CHANGES b/CHANGES index 7c9fecbe0f5..0a9318a961b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,18 @@ +4024. [bug] dns_rdata_opt_first, dns_rdata_opt_next, + dns_rdata_opt_current, dns_rdata_txt_first, + dns_rdata_txt_next and dns_rdata_txt_current were + documented but not implemented. These have now been + implemented. + + dns_rdata_spf_first, dns_rdata_spf_next and + dns_rdata_spf_current were document but not + implemented. The prototypes for these + functions have been removed. [RT #38068] + +4023. [bug] win32: socket handling with explict ports and + invoking named with -4 was broken for some + configurations. [RT #38068] + --- 9.10.2b1 released --- 4021. [bug] Adjust max-recursion-queries to accommodate diff --git a/lib/dns/rdata/generic/opt_41.c b/lib/dns/rdata/generic/opt_41.c index ae09abf71e9..bcd9e77ef58 100644 --- a/lib/dns/rdata/generic/opt_41.c +++ b/lib/dns/rdata/generic/opt_41.c @@ -326,4 +326,63 @@ casecompare_opt(ARGS_COMPARE) { return (compare_opt(rdata1, rdata2)); } +isc_result_t +dns_rdata_opt_first(dns_rdata_opt_t *opt) { + + REQUIRE(opt != NULL); + REQUIRE(opt->common.rdtype == 41); + REQUIRE(opt->options != NULL || opt->length == 0); + + if (opt->length == 0) + return (ISC_R_NOMORE); + + opt->offset = 0; + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_rdata_opt_next(dns_rdata_opt_t *opt) { + isc_region_t r; + isc_uint16_t length; + + REQUIRE(opt != NULL); + REQUIRE(opt->common.rdtype == 41); + REQUIRE(opt->options != NULL && opt->length != 0); + REQUIRE(opt->offset < opt->length); + + INSIST(opt->offset + 4 <= opt->length); + r.base = opt->options + opt->offset + 2; + r.length = opt->length - opt->offset - 2; + length = uint16_fromregion(&r); + INSIST(opt->offset + 4 + length <= opt->length); + opt->offset = opt->offset + 4 + length; + if (opt->offset == opt->length) + return (ISC_R_NOMORE); + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_rdata_opt_current(dns_rdata_opt_t *opt, dns_rdata_opt_opcode_t *opcode) { + isc_region_t r; + + REQUIRE(opt != NULL); + REQUIRE(opcode != NULL); + REQUIRE(opt->common.rdtype == 41); + REQUIRE(opt->options != NULL); + REQUIRE(opt->offset < opt->length); + + INSIST(opt->offset + 4 <= opt->length); + r.base = opt->options + opt->offset; + r.length = opt->length - opt->offset; + + opcode->opcode = uint16_fromregion(&r); + isc_region_consume(&r, 2); + opcode->length = uint16_fromregion(&r); + isc_region_consume(&r, 2); + opcode->data = r.base; + INSIST(opt->offset + 4 + opcode->length <= opt->length); + + return (ISC_R_SUCCESS); +} + #endif /* RDATA_GENERIC_OPT_41_C */ diff --git a/lib/dns/rdata/generic/spf_99.h b/lib/dns/rdata/generic/spf_99.h index be5e9789842..04bb119f259 100644 --- a/lib/dns/rdata/generic/spf_99.h +++ b/lib/dns/rdata/generic/spf_99.h @@ -38,14 +38,4 @@ typedef struct dns_rdata_spf { * ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done * via rdatastructpre.h and rdatastructsuf.h. */ - -isc_result_t -dns_rdata_spf_first(dns_rdata_spf_t *); - -isc_result_t -dns_rdata_spf_next(dns_rdata_spf_t *); - -isc_result_t -dns_rdata_spf_current(dns_rdata_spf_t *, dns_rdata_spf_string_t *); - #endif /* GENERIC_SPF_99_H */ diff --git a/lib/dns/rdata/generic/txt_16.c b/lib/dns/rdata/generic/txt_16.c index 41e27027921..8732072f411 100644 --- a/lib/dns/rdata/generic/txt_16.c +++ b/lib/dns/rdata/generic/txt_16.c @@ -247,4 +247,59 @@ casecompare_txt(ARGS_COMPARE) { return (compare_txt(rdata1, rdata2)); } +isc_result_t +dns_rdata_txt_first(dns_rdata_txt_t *txt) { + + REQUIRE(txt != NULL); + REQUIRE(txt->common.rdtype == 16); + REQUIRE(txt->txt != NULL || txt->txt_len == 0); + + if (txt->txt_len == 0) + return (ISC_R_NOMORE); + + txt->offset = 0; + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_rdata_txt_next(dns_rdata_txt_t *txt) { + isc_region_t r; + isc_uint8_t length; + + REQUIRE(txt != NULL); + REQUIRE(txt->common.rdtype == 16); + REQUIRE(txt->txt != NULL && txt->txt_len != 0); + + INSIST(txt->offset + 1 <= txt->txt_len); + r.base = txt->txt + txt->offset; + r.length = txt->txt_len - txt->offset; + length = uint8_fromregion(&r); + INSIST(txt->offset + 1 + length <= txt->txt_len); + txt->offset = txt->offset + 1 + length; + if (txt->offset == txt->txt_len) + return (ISC_R_NOMORE); + return (ISC_R_SUCCESS); +} + +isc_result_t +dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { + isc_region_t r; + + REQUIRE(txt != NULL); + REQUIRE(string != NULL); + REQUIRE(txt->common.rdtype == 16); + REQUIRE(txt->txt != NULL); + REQUIRE(txt->offset < txt->txt_len); + + INSIST(txt->offset + 1 <= txt->txt_len); + r.base = txt->txt + txt->offset; + r.length = txt->txt_len - txt->offset; + + string->length = uint8_fromregion(&r); + isc_region_consume(&r, 1); + string->data = r.base; + INSIST(txt->offset + 1 + string->length <= txt->txt_len); + + return (ISC_R_SUCCESS); +} #endif /* RDATA_GENERIC_TXT_16_C */ diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index cc00c2a7fd5..e84ddd1a9c1 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -2998,6 +2998,10 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { stdoptions |= DNS_ADBFIND_INET; if (res->dispatches6 != NULL) stdoptions |= DNS_ADBFIND_INET6; + + if ((stdoptions & DNS_ADBFIND_ADDRESSMASK) == 0) + return (DNS_R_SERVFAIL); + isc_stdtime_get(&now); INSIST(ISC_LIST_EMPTY(fctx->finds)); diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index f495ac8599e..f1d272282d7 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -391,14 +391,19 @@ sock_dump(isc_socket_t *sock) { #if 0 isc_sockaddr_t addr; - char socktext[256]; - - isc_socket_getpeername(sock, &addr); - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - printf("Remote Socket: %s\n", socktext); - isc_socket_getsockname(sock, &addr); - isc_sockaddr_format(&addr, socktext, sizeof(socktext)); - printf("This Socket: %s\n", socktext); + char socktext[ISC_SOCKADDR_FORMATSIZE]; + isc_result_t result; + + result = isc_socket_getpeername(sock, &addr); + if (result == ISC_R_SUCCESS) { + isc_sockaddr_format(&addr, socktext, sizeof(socktext)); + printf("Remote Socket: %s\n", socktext); + } + result = isc_socket_getsockname(sock, &addr); + if (result == ISC_R_SUCCESS) { + isc_sockaddr_format(&addr, socktext, sizeof(socktext)); + printf("This Socket: %s\n", socktext); + } #endif printf("\n\t\tSock Dump\n"); @@ -1671,9 +1676,6 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, REQUIRE(socketp != NULL && *socketp == NULL); REQUIRE(type != isc_sockettype_fdwatch); - if (dup_socket != NULL) - return (ISC_R_NOTIMPLEMENTED); - #ifndef SOCK_RAW if (type == isc_sockettype_raw) return (ISC_R_NOTIMPLEMENTED); @@ -1684,55 +1686,40 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, return (result); sock->pf = pf; -#if 0 - if (dup_socket == NULL) { -#endif - switch (type) { - case isc_sockettype_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) { - socket_log(__LINE__, sock, - NULL, EVENT, NULL, 0, 0, - "closed %d %d %d " - "con_reset_fix_failed", - sock->pending_recv, - sock->pending_send, - sock->references); - closesocket(sock->fd); - _set_state(sock, SOCK_CLOSED); - sock->fd = INVALID_SOCKET; - free_socket(&sock, __LINE__); - return (result); - } + switch (type) { + case isc_sockettype_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) { + socket_log(__LINE__, sock, + NULL, EVENT, NULL, 0, 0, + "closed %d %d %d " + "con_reset_fix_failed", + sock->pending_recv, + sock->pending_send, + sock->references); + closesocket(sock->fd); + _set_state(sock, SOCK_CLOSED); + sock->fd = INVALID_SOCKET; + free_socket(&sock, __LINE__); + return (result); } - break; - case isc_sockettype_tcp: - sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP); - break; + } + break; + case isc_sockettype_tcp: + sock->fd = socket(pf, SOCK_STREAM, IPPROTO_TCP); + break; #ifdef SOCK_RAW - case isc_sockettype_raw: - sock->fd = socket(pf, SOCK_RAW, 0); + case isc_sockettype_raw: + sock->fd = socket(pf, SOCK_RAW, 0); #ifdef PF_ROUTE - if (pf == PF_ROUTE) - sock->bound = 1; + if (pf == PF_ROUTE) + sock->bound = 1; #endif - break; + break; #endif - } -#if 0 - } else { - /* - * XXX: dup() is deprecated in windows, use _dup() - * instead. In future we may want to investigate - * WSADuplicateSocket(). - */ - sock->fd = _dup(dup_socket->fd); - sock->dupped = 1; - sock->bound = dup_socket->bound; } -#endif if (sock->fd == INVALID_SOCKET) { socket_errno = WSAGetLastError(); @@ -1836,6 +1823,29 @@ socket_create(isc_socketmgr_t *manager, int pf, isc_sockettype_t type, *socketp = sock; iocompletionport_update(sock); + + if (dup_socket) { +#ifndef ISC_ALLOW_MAPPED + isc__socket_ipv6only(sock, ISC_TRUE); +#endif + + if (dup_socket->bound) { + isc_sockaddr_t local; + + result = isc__socket_getsockname(dup_socket, &local); + if (result != ISC_R_SUCCESS) { + isc_socket_close(sock); + return (result); + } + result = isc__socket_bind(sock, &local, + ISC_SOCKET_REUSEADDRESS); + if (result != ISC_R_SUCCESS) { + isc_socket_close(sock); + return (result); + } + } + sock->dupped = 1; + } /* * Note we don't have to lock the socket like we normally would because @@ -1865,12 +1875,8 @@ isc__socket_dup(isc_socket_t *sock, isc_socket_t **socketp) { REQUIRE(VALID_SOCKET(sock)); REQUIRE(socketp != NULL && *socketp == NULL); -#if 1 - return (ISC_R_NOTIMPLEMENTED); -#else return (socket_create(sock->manager, sock->pf, sock->type, socketp, sock)); -#endif } isc_result_t