diff options
author | Florian Weimer <fweimer@redhat.com> | 2024-07-24 12:06:47 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2024-07-24 14:07:32 +0200 |
commit | 40a1e1798b2414c6ab32244b8cb03c2c39940b71 (patch) | |
tree | fc7679990939265e4392d5a20992cd8cba739454 /resolv/tst-resolv-short-response.c | |
parent | 7f769dd0084cb1c857fd6fa90f60e92711b9ce7c (diff) | |
download | glibc-40a1e1798b2414c6ab32244b8cb03c2c39940b71.zip glibc-40a1e1798b2414c6ab32244b8cb03c2c39940b71.tar.gz glibc-40a1e1798b2414c6ab32244b8cb03c2c39940b71.tar.bz2 |
resolv: Allow short error responses to match any query (bug 31890)
Reviewed-by: DJ Delorie <dj@redhat.com>
(cherry picked from commit 691a3b2e9bfaba842e46a5ccb7f5e6ea144c3ade)
Diffstat (limited to 'resolv/tst-resolv-short-response.c')
-rw-r--r-- | resolv/tst-resolv-short-response.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c new file mode 100644 index 0000000..cf1e398 --- /dev/null +++ b/resolv/tst-resolv-short-response.c @@ -0,0 +1,112 @@ +/* Test for spurious timeouts with short 12-byte responses (bug 31890). + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <resolv.h> +#include <support/check.h> +#include <support/resolv_test.h> +#include <support/check_nss.h> + +/* The rcode in the initial response. */ +static volatile int rcode; + +static void +response (const struct resolv_response_context *ctx, + struct resolv_response_builder *b, + const char *qname, uint16_t qclass, uint16_t qtype) +{ + switch (ctx->server_index) + { + case 0: + /* First server times out. */ + struct resolv_response_flags flags = {.rcode = rcode}; + resolv_response_init (b, flags); + break; + case 1: + /* Second server sends reply. */ + resolv_response_init (b, (struct resolv_response_flags) {}); + resolv_response_add_question (b, qname, qclass, qtype); + resolv_response_section (b, ns_s_an); + resolv_response_open_record (b, qname, qclass, qtype, 0); + switch (qtype) + { + case T_A: + { + char ipv4[4] = {192, 0, 2, 17}; + resolv_response_add_data (b, &ipv4, sizeof (ipv4)); + } + break; + case T_AAAA: + { + char ipv6[16] + = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; + resolv_response_add_data (b, &ipv6, sizeof (ipv6)); + } + break; + default: + FAIL_EXIT1 ("unexpected TYPE%d query", qtype); + } + resolv_response_close_record (b); + break; + default: + FAIL_EXIT1 ("unexpected query to server %d", ctx->server_index); + } +} + +static void +check_one (void) +{ + + /* The buggy 1-second query timeout results in 30 seconds of delay, + which triggers a test timeout failure. */ + for (int i = 0; i < 10; ++i) + { + check_hostent ("www.example", gethostbyname ("www.example"), + "name: www.example\n" + "address: 192.0.2.17\n"); + check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6), + "name: www.example\n" + "address: 2001:db8::1\n"); + } +} + +static int +do_test (void) +{ + struct resolv_test *aux = resolv_test_start + ((struct resolv_redirect_config) + { + .response_callback = response, + }); + + _res.options |= RES_SNGLKUP; + + rcode = 2; /* SERVFAIL. */ + check_one (); + + rcode = 4; /* NOTIMP. */ + check_one (); + + rcode = 5; /* REFUSED. */ + check_one (); + + resolv_test_end (aux); + + return 0; +} + +#include <support/test-driver.c> |