mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 20:40:05 +00:00
resolv: Avoid timeouts in test-resolv-res-init, test-resolv-res_init-thread
Some Linux kernels have very aggressive ICMP rate limiting on the loopback interface. This commit introduces a minimal echoing DNS server inside the network namespace, so that there is no need for ICMP error messages anymore.
This commit is contained in:
parent
e6b4e2de6d
commit
39bd76df3d
@ -1,3 +1,10 @@
|
||||
2017-06-27 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
Work around test timeouts with ICMP rate limiting on localhost.
|
||||
* resolv/tst-resolv-res_init-skeleton.c (start_dummy_server): New
|
||||
function.
|
||||
(do_test): Call it.
|
||||
|
||||
2017-06-27 Florian Weimer <fweimer@redhat.com>
|
||||
|
||||
Call _res_hconf_init from __res_vinit.
|
||||
|
@ -21,6 +21,7 @@
|
||||
in. */
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <gnu/lib-names.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv/resolv-internal.h> /* For DEPRECATED_RES_USE_INET6. */
|
||||
@ -33,6 +34,7 @@
|
||||
#include <support/support.h>
|
||||
#include <support/temp_file.h>
|
||||
#include <support/test-driver.h>
|
||||
#include <support/xsocket.h>
|
||||
#include <support/xstdio.h>
|
||||
#include <support/xunistd.h>
|
||||
|
||||
@ -527,6 +529,73 @@ test_file_contents (const struct test_case *t)
|
||||
}
|
||||
}
|
||||
|
||||
/* Dummy DNS server. It ensures that the probe queries sent by
|
||||
gethostbyname and getaddrinfo receive a reply even if the system
|
||||
applies a very strict rate limit to localhost. */
|
||||
static pid_t
|
||||
start_dummy_server (void)
|
||||
{
|
||||
int server_socket = xsocket (AF_INET, SOCK_DGRAM, 0);
|
||||
{
|
||||
struct sockaddr_in sin =
|
||||
{
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr = { .s_addr = htonl (INADDR_LOOPBACK) },
|
||||
.sin_port = htons (53),
|
||||
};
|
||||
int ret = bind (server_socket, (struct sockaddr *) &sin, sizeof (sin));
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == EACCES)
|
||||
/* The port is reserved, which means we cannot start the
|
||||
server. */
|
||||
return -1;
|
||||
FAIL_EXIT1 ("cannot bind socket to port 53: %m");
|
||||
}
|
||||
}
|
||||
|
||||
pid_t pid = xfork ();
|
||||
if (pid == 0)
|
||||
{
|
||||
/* Child process. Echo back queries as SERVFAIL responses. */
|
||||
while (true)
|
||||
{
|
||||
union
|
||||
{
|
||||
HEADER header;
|
||||
unsigned char bytes[512];
|
||||
} packet;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinlen = sizeof (sin);
|
||||
|
||||
ssize_t ret = recvfrom
|
||||
(server_socket, &packet, sizeof (packet),
|
||||
MSG_NOSIGNAL, (struct sockaddr *) &sin, &sinlen);
|
||||
if (ret < 0)
|
||||
FAIL_EXIT1 ("recvfrom on fake server socket: %m");
|
||||
if (ret > sizeof (HEADER))
|
||||
{
|
||||
/* Turn the query into a SERVFAIL response. */
|
||||
packet.header.qr = 1;
|
||||
packet.header.rcode = ns_r_servfail;
|
||||
|
||||
/* Send the response. */
|
||||
ret = sendto (server_socket, &packet, ret,
|
||||
MSG_NOSIGNAL, (struct sockaddr *) &sin, sinlen);
|
||||
if (ret < 0)
|
||||
/* The peer may have closed socket prematurely, so
|
||||
this is not an error. */
|
||||
printf ("warning: sending DNS server reply: %m\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In the parent, close the socket. */
|
||||
xclose (server_socket);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
static int
|
||||
do_test (void)
|
||||
{
|
||||
@ -552,6 +621,8 @@ do_test (void)
|
||||
support_capture_subprocess_free (&proc);
|
||||
}
|
||||
|
||||
pid_t server = start_dummy_server ();
|
||||
|
||||
for (size_t i = 0; test_cases[i].name != NULL; ++i)
|
||||
{
|
||||
if (test_verbose > 0)
|
||||
@ -590,6 +661,13 @@ do_test (void)
|
||||
}
|
||||
}
|
||||
|
||||
if (server > 0)
|
||||
{
|
||||
if (kill (server, SIGTERM) < 0)
|
||||
FAIL_EXIT1 ("could not terminate server process: %m");
|
||||
xwaitpid (server, NULL, 0);
|
||||
}
|
||||
|
||||
free (path_chroot);
|
||||
path_chroot = NULL;
|
||||
free (path_resolv_conf);
|
||||
|
Loading…
Reference in New Issue
Block a user