On Wed, 6 Apr 2005, Charles Duffy wrote:
> I'm trying to put together a patch to implement my desired behaviour wrt
> resolv-retry and multiple remote hosts.
>
> So far, I've made the following changes:
>
> Setting the default resolv-retry count:
> * Create a new constant, RESOLV_RETRY_UNSET
> * Initialize resolve_retry_seconds to RESOLV_RETRY_UNSET rather
> than RESOLV_RETRY_INFINITE
> * In options_postprocess(), set resolve_retry_seconds
> appropriately based on the number of remote hosts provided
>
> Retrying on DNS failures with resolv-retry 0 and multiple hosts:
> * Modify resolve_remote() to accept a boolean argument
> multiple_remotes
> * In the phase-specific handlers within that same function, treat
> multiple_remotes as an alternative to resolve_retry_seconds when
> determining whether GETADDR_FATAL and
> GETADDR_MENTION_RESOLVE_RETRY should be set (in phase 1) and
> whether to fail out with an assertion error (in phase 2).
>
> Thing is, this doesn't actually work: When I run it in a test case in
> with the first remote specified by DNS and the second host specified by
> IP, it tries to resolve the first host in phase 1; fails; tries again in
> phase 2; and fails again (fatally, there, because GETADDR_FATAL is set).
>
> I presume that it's supposed to loop around to trying phase1 with the
> next host if getaddr fails (on account of using all the available
> retries on the current host) rather than proceeding to phase 2 -- but
> what's the mechanism?
Not really. phase1 and phase2 are meant to be called only once per
restart.
I would take a different approach (see attached patch). Rather than
change the defaulting of resolve_retry_seconds, I would just change the
interpretation of RESOLV_RETRY_INFINITE when the remote list > 1 to
something that makes more sense, i.e. apply the infinite timeout to the
list as a whole, but resolve each list member with GETADDR_TRY_ONCE.
James
diff -ur openvpn-2.0_rc20/socket.c openvpn-2.0_rc20RR/socket.c
--- openvpn-2.0_rc20/socket.c 2005-02-05 01:42:13.000000000 -0700
+++ openvpn-2.0_rc20RR/socket.c 2005-04-07 00:02:56.385578040 -0600
@@ -94,7 +94,7 @@
if (status != OIA_IP) /* parse as IP address failed? */
{
const int fail_wait_interval = 5; /* seconds */
- int resolve_retries = resolve_retry_seconds / fail_wait_interval;
+ int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 :
(resolve_retry_seconds / fail_wait_interval);
struct hostent *h;
const char *fmt;
int level = 0;
@@ -764,7 +764,14 @@
int retry = 0;
bool status = false;
- if (phase == 1)
+ if (remote_list_len (sock->remote_list) > 1 &&
sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE)
+ {
+ flags = GETADDR_RESOLVE;
+ if (phase == 2)
+ flags |= (GETADDR_TRY_ONCE | GETADDR_FATAL);
+ retry = 0;
+ }
+ else if (phase == 1)
{
if (sock->resolve_retry_seconds)
{
diff -ur openvpn-2.0_rc20/socket.h openvpn-2.0_rc20RR/socket.h
--- openvpn-2.0_rc20/socket.h 2005-02-05 01:36:31.000000000 -0700
+++ openvpn-2.0_rc20RR/socket.h 2005-04-06 23:18:39.385503448 -0600
@@ -363,6 +363,7 @@
#define GETADDR_FATAL_ON_SIGNAL (1<<4)
#define GETADDR_WARN_ON_SIGNAL (1<<5)
#define GETADDR_MSG_VIRT_OUT (1<<6)
+#define GETADDR_TRY_ONCE (1<<7)
in_addr_t getaddr (unsigned int flags,
const char *hostname,