Merge branch '2790-properly-handle-oversized-messages-in-isc_nm_send-v9_16' into 'v9_16'
Handle `UV_EMSGSIZE` in the uv_udp_send() callback (v9.16) See merge request isc-projects/bind9!5226
This commit is contained in:
6
CHANGES
6
CHANGES
@@ -1,3 +1,9 @@
|
||||
5664. [func] Handle a UDP sending error on UDP messages larger
|
||||
than the path MTU; in such a case an empty response is
|
||||
sent back with the TC (TrunCated) bit set. Re-enable
|
||||
setting the DF (Don't Fragment) flag on outgoing
|
||||
UDP sockets. [GL #2790]
|
||||
|
||||
5662. [bug] Views with recursion disabled are now configured with a
|
||||
default cache size of 2 MB, unless "max-cache-size" is
|
||||
explicitly set. This prevents cache RBT hash tables from
|
||||
|
||||
@@ -34,7 +34,10 @@ Removed Features
|
||||
Feature Changes
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
- None.
|
||||
- IP fragmentation on outgoing UDP sockets has been disabled. Errors from
|
||||
sending DNS messages larger than the specified path MTU are properly handled;
|
||||
``named`` now sends back empty DNS messages with the TC (TrunCated) bit set,
|
||||
forcing the DNS client to fall back to TCP. :gl:`#2790`
|
||||
|
||||
Bug Fixes
|
||||
~~~~~~~~~
|
||||
|
||||
@@ -2944,22 +2944,14 @@ isc__nm_socket_dontfrag(uv_os_sock_t fd, sa_family_t sa_family) {
|
||||
*/
|
||||
if (sa_family == AF_INET6) {
|
||||
#if defined(IPV6_DONTFRAG)
|
||||
if (setsockopt_off(fd, IPPROTO_IPV6, IPV6_DONTFRAG) == -1) {
|
||||
if (setsockopt_on(fd, IPPROTO_IPV6, IPV6_DONTFRAG) == -1) {
|
||||
return (ISC_R_FAILURE);
|
||||
} else {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT)
|
||||
#elif defined(IPV6_MTU_DISCOVER)
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
|
||||
&(int){ IP_PMTUDISC_OMIT }, sizeof(int)) == -1)
|
||||
{
|
||||
return (ISC_R_FAILURE);
|
||||
} else {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER,
|
||||
&(int){ IP_PMTUDISC_DONT }, sizeof(int)) == -1)
|
||||
&(int){ IP_PMTUDISC_DO }, sizeof(int)) == -1)
|
||||
{
|
||||
return (ISC_R_FAILURE);
|
||||
} else {
|
||||
@@ -2970,22 +2962,14 @@ isc__nm_socket_dontfrag(uv_os_sock_t fd, sa_family_t sa_family) {
|
||||
#endif
|
||||
} else if (sa_family == AF_INET) {
|
||||
#if defined(IP_DONTFRAG)
|
||||
if (setsockopt_off(fd, IPPROTO_IP, IP_DONTFRAG) == -1) {
|
||||
if (setsockopt_on(fd, IPPROTO_IP, IP_DONTFRAG) == -1) {
|
||||
return (ISC_R_FAILURE);
|
||||
} else {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_OMIT)
|
||||
#elif defined(IP_MTU_DISCOVER)
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER,
|
||||
&(int){ IP_PMTUDISC_OMIT }, sizeof(int)) == -1)
|
||||
{
|
||||
return (ISC_R_FAILURE);
|
||||
} else {
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
#elif defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER,
|
||||
&(int){ IP_PMTUDISC_DONT }, sizeof(int)) == -1)
|
||||
&(int){ IP_PMTUDISC_DO }, sizeof(int)) == -1)
|
||||
{
|
||||
return (ISC_R_FAILURE);
|
||||
} else {
|
||||
|
||||
@@ -85,6 +85,8 @@ isc___nm_uverr2result(int uverr, bool dolog, const char *file,
|
||||
return (ISC_R_CANCELED);
|
||||
case UV_EOF:
|
||||
return (ISC_R_EOF);
|
||||
case UV_EMSGSIZE:
|
||||
return (ISC_R_MAXSIZE);
|
||||
default:
|
||||
if (dolog) {
|
||||
UNEXPECTED_ERROR(
|
||||
|
||||
@@ -279,13 +279,33 @@ client_senddone(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) {
|
||||
REQUIRE(client->sendhandle == handle);
|
||||
|
||||
CTRACE("senddone");
|
||||
|
||||
/*
|
||||
* Set sendhandle to NULL, but don't detach it immediately, in
|
||||
* case we need to retry the send. If we do resend, then
|
||||
* sendhandle will be reattached. Whether or not we resend,
|
||||
* we will then detach the handle from *this* send by detaching
|
||||
* 'handle' directly below.
|
||||
*/
|
||||
client->sendhandle = NULL;
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
|
||||
"send failed: %s", isc_result_totext(result));
|
||||
if (!TCP_CLIENT(client) && result == ISC_R_MAXSIZE) {
|
||||
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
|
||||
"send exceeded maximum size: truncating");
|
||||
client->query.attributes &= ~NS_QUERYATTR_ANSWERED;
|
||||
client->rcode_override = dns_rcode_noerror;
|
||||
ns_client_error(client, ISC_R_MAXSIZE);
|
||||
} else {
|
||||
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
|
||||
"send failed: %s",
|
||||
isc_result_totext(result));
|
||||
}
|
||||
}
|
||||
|
||||
isc_nmhandle_detach(&client->sendhandle);
|
||||
isc_nmhandle_detach(&handle);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -721,8 +741,9 @@ ns_client_dropport(in_port_t port) {
|
||||
|
||||
void
|
||||
ns_client_error(ns_client_t *client, isc_result_t result) {
|
||||
dns_message_t *message = NULL;
|
||||
dns_rcode_t rcode;
|
||||
dns_message_t *message;
|
||||
bool trunc = false;
|
||||
|
||||
REQUIRE(NS_CLIENT_VALID(client));
|
||||
|
||||
@@ -736,6 +757,10 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
|
||||
rcode = (dns_rcode_t)(client->rcode_override & 0xfff);
|
||||
}
|
||||
|
||||
if (result == ISC_R_MAXSIZE) {
|
||||
trunc = true;
|
||||
}
|
||||
|
||||
#if NS_CLIENT_DROPPORT
|
||||
/*
|
||||
* Don't send FORMERR to ports on the drop port list.
|
||||
@@ -832,7 +857,11 @@ ns_client_error(ns_client_t *client, isc_result_t result) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
message->rcode = rcode;
|
||||
if (trunc) {
|
||||
message->flags |= DNS_MESSAGEFLAG_TC;
|
||||
}
|
||||
|
||||
if (rcode == dns_rcode_formerr) {
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user