Package: finger Version: 0.17-14 Severity: normal Tags: patch In the present situation with two address families supported by Finger, it will be more common that the target system is not responding to a finger query due to a missed configuration of a particular address.
Consider this: A name server reports an IPv4 as well as an IPv6 address for a particular host, but in fact the host in question has not yet activated its external IPv6 address. This would cause the Finger client to wait for the full duration of the TCP handshake timeout, before being able to proceed to querying the IPv4 address. The same thing goes for a multihomed host where not every address within the same address family is responding to finger queries. The following patch uses the SIGALRM machinery to reduce this timeout to five seconds before trying the next address on the resolver's address list. It is sometimes stated that rerouting regularly causes a delay in excess of fifteen seconds, but taking the optional character of Finger for an interactive user into account, I still find a short timeout of five seconds is the appropriate amount of time. The package builder can easily override this setting in a tailored package. Best regards, -- Mats Erik Andersson, fil. dr <[email protected]>
Description: Decrease timeout length during connect(). In cases where a name server is answering with A as well as AAAA records, but the system to be queried has lost a corresponding address, the TCP handshake timeout will cause a long delay before allowing the query of the next address family, or the next address in general. . The use of a trivial signal handler for SIGALRM allows the reduction of this timeout, thus producing better responsiveness for the interactive user of the Finger service. Author: Mats Erik Andersson <[email protected]> Forwarded: no Last-Updated: 2010-03-02 --- bsd-finger-0.17/finger/net.c.debian +++ bsd-finger-0.17/finger/net.c @@ -49,14 +49,25 @@ #include <string.h> #include <unistd.h> #include <ctype.h> +#include <signal.h> #include "finger.h" +#if ! defined(FINGER_TIMEOUT) || FINGER_TIMEOUT < 1 +# define FINGER_TIMEOUT 5 +#endif + +static void trivial_alarm(int sig) { + /* Just to trigger EINTR, and to later use it. */ + return; +} + int netfinger(const char *name) { register FILE *fp; register int c, sawret, ateol; struct addrinfo hints, *result, *resptr; struct servent *sp; struct sockaddr_storage sn; + struct sigaction sigact, oldsigact; int s, status; char *host; @@ -77,6 +88,10 @@ hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; + sigact.sa_handler = trivial_alarm; + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = 0; + status = getaddrinfo(host, "finger", &hints, &result); if (status != 0) { eprintf("finger: unknown host: %s\n", host); @@ -95,13 +110,21 @@ /* This should probably be removed. */ /* xprintf("[%s]\n", result->ai_canonname); */ + sigaction(SIGALRM, &sigact, &oldsigact); + alarm(FINGER_TIMEOUT); + if (connect(s, resptr->ai_addr, resptr->ai_addrlen) < 0) { + if ( errno == EINTR ) + errno = ETIMEDOUT; close(s); continue; } + alarm(0); + sigaction(SIGALRM, &oldsigact, NULL); + /* Connection is now established. - /* Assemble the gained information. */ + * Assemble the gained information. */ memcpy(&sn, resptr->ai_addr, resptr->ai_addrlen); break; }
signature.asc
Description: Digital signature

