client: enable IP_RECVERR socket option
This is useful to get ECONNREFUSED when the host replies with ICMP port unreachable message and avoid having to wait for timeout.
This commit is contained in:
parent
c2dc25e062
commit
b3b2f67d2f
1 changed files with 28 additions and 0 deletions
28
client.c
28
client.c
|
@ -66,6 +66,8 @@ static int on_terminal = 0;
|
||||||
|
|
||||||
static int no_dns = 0;
|
static int no_dns = 0;
|
||||||
|
|
||||||
|
static int recv_errqueue = 0;
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
/* Ought to extract some code from util.c to make
|
/* Ought to extract some code from util.c to make
|
||||||
a new set of utilities that can be linked into either
|
a new set of utilities that can be linked into either
|
||||||
|
@ -139,6 +141,7 @@ static void
|
||||||
open_io(const char *hostname, int port)
|
open_io(const char *hostname, int port)
|
||||||
{
|
{
|
||||||
IPAddr ip;
|
IPAddr ip;
|
||||||
|
int on_off = 1;
|
||||||
|
|
||||||
/* Note, this call could block for a while */
|
/* Note, this call could block for a while */
|
||||||
if (DNS_Name2IPAddress(hostname, &ip) != DNS_Success) {
|
if (DNS_Name2IPAddress(hostname, &ip) != DNS_Success) {
|
||||||
|
@ -176,6 +179,22 @@ open_io(const char *hostname, int port)
|
||||||
perror("Can't create socket");
|
perror("Can't create socket");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Enable extended error reporting (e.g. ECONNREFUSED on ICMP unreachable) */
|
||||||
|
#ifdef IP_RECVERR
|
||||||
|
if (ip.family == IPADDR_INET4 &&
|
||||||
|
!setsockopt(sock_fd, IPPROTO_IP, IP_RECVERR, &on_off, sizeof(on_off))) {
|
||||||
|
recv_errqueue = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
#ifdef IPV6_RECVERR
|
||||||
|
if (ip.family == IPADDR_INET6 &&
|
||||||
|
!setsockopt(sock_fd, IPPROTO_IPV6, IPV6_RECVERR, &on_off, sizeof(on_off))) {
|
||||||
|
recv_errqueue = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================================================== */
|
/* ================================================== */
|
||||||
|
@ -1365,6 +1384,15 @@ submit_request(CMD_Request *request, CMD_Reply *reply, int *reply_auth_ok)
|
||||||
/* If we get connrefused here, it suggests the sendto is
|
/* If we get connrefused here, it suggests the sendto is
|
||||||
going to a dead port - but only if the daemon machine is
|
going to a dead port - but only if the daemon machine is
|
||||||
running Linux (Solaris doesn't return anything) */
|
running Linux (Solaris doesn't return anything) */
|
||||||
|
|
||||||
|
#ifdef IP_RECVERR
|
||||||
|
/* Fetch the message from the error queue */
|
||||||
|
if (recv_errqueue &&
|
||||||
|
recvfrom(sock_fd, (void *)reply, sizeof(CMD_Reply), MSG_ERRQUEUE,
|
||||||
|
&where_from.u, &where_from_len) < 0)
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
n_attempts++;
|
n_attempts++;
|
||||||
if (n_attempts > max_retries) {
|
if (n_attempts > max_retries) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue