When only a single IP address is desired from a multi-address DNS
expansion, use the first address rather than a random selection.
Version 2.1.1l
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@6291 e7ae566f-a301-0410-adde-c780ea21d3b5
| ... | ... |
@@ -219,6 +219,7 @@ is_special_addr (const char *addr_str) |
| 219 | 219 |
|
| 220 | 220 |
static bool |
| 221 | 221 |
init_route (struct route *r, |
| 222 |
+ struct resolve_list *network_list, |
|
| 222 | 223 |
const struct route_option *ro, |
| 223 | 224 |
const struct route_special_addr *spec) |
| 224 | 225 |
{
|
| ... | ... |
@@ -237,14 +238,15 @@ init_route (struct route *r, |
| 237 | 237 |
|
| 238 | 238 |
if (!get_special_addr (spec, ro->network, &r->network, &status)) |
| 239 | 239 |
{
|
| 240 |
- r->network = getaddr ( |
|
| 241 |
- GETADDR_RESOLVE |
|
| 242 |
- | GETADDR_HOST_ORDER |
|
| 243 |
- | GETADDR_WARN_ON_SIGNAL, |
|
| 244 |
- ro->network, |
|
| 245 |
- 0, |
|
| 246 |
- &status, |
|
| 247 |
- NULL); |
|
| 240 |
+ r->network = getaddr_multi ( |
|
| 241 |
+ GETADDR_RESOLVE |
|
| 242 |
+ | GETADDR_HOST_ORDER |
|
| 243 |
+ | GETADDR_WARN_ON_SIGNAL, |
|
| 244 |
+ ro->network, |
|
| 245 |
+ 0, |
|
| 246 |
+ &status, |
|
| 247 |
+ NULL, |
|
| 248 |
+ network_list); |
|
| 248 | 249 |
} |
| 249 | 250 |
|
| 250 | 251 |
if (!status) |
| ... | ... |
@@ -438,20 +440,45 @@ init_route_list (struct route_list *rl, |
| 438 | 438 |
else |
| 439 | 439 |
rl->spec.remote_endpoint_defined = false; |
| 440 | 440 |
|
| 441 |
- if (!(opt->n >= 0 && opt->n <= rl->capacity)) |
|
| 442 |
- msg (M_FATAL, PACKAGE_NAME " ROUTE: (init) number of route options (%d) is greater than route list capacity (%d)", opt->n, rl->capacity); |
|
| 443 |
- |
|
| 444 | 441 |
/* parse the routes from opt to rl */ |
| 445 | 442 |
{
|
| 446 | 443 |
int i, j = 0; |
| 444 |
+ bool warned = false; |
|
| 447 | 445 |
for (i = 0; i < opt->n; ++i) |
| 448 | 446 |
{
|
| 449 |
- if (!init_route (&rl->routes[j], |
|
| 447 |
+ struct resolve_list netlist; |
|
| 448 |
+ struct route r; |
|
| 449 |
+ int k; |
|
| 450 |
+ |
|
| 451 |
+ if (!init_route (&r, |
|
| 452 |
+ &netlist, |
|
| 450 | 453 |
&opt->routes[i], |
| 451 | 454 |
&rl->spec)) |
| 452 | 455 |
ret = false; |
| 453 | 456 |
else |
| 454 |
- ++j; |
|
| 457 |
+ {
|
|
| 458 |
+ if (!netlist.len) |
|
| 459 |
+ {
|
|
| 460 |
+ netlist.data[0] = r.network; |
|
| 461 |
+ netlist.len = 1; |
|
| 462 |
+ } |
|
| 463 |
+ for (k = 0; k < netlist.len; ++k) |
|
| 464 |
+ {
|
|
| 465 |
+ if (j < rl->capacity) |
|
| 466 |
+ {
|
|
| 467 |
+ r.network = netlist.data[k]; |
|
| 468 |
+ rl->routes[j++] = r; |
|
| 469 |
+ } |
|
| 470 |
+ else |
|
| 471 |
+ {
|
|
| 472 |
+ if (!warned) |
|
| 473 |
+ {
|
|
| 474 |
+ msg (M_WARN, PACKAGE_NAME " ROUTE: routes dropped because number of expanded routes is greater than route list capacity (%d)", rl->capacity); |
|
| 475 |
+ warned = true; |
|
| 476 |
+ } |
|
| 477 |
+ } |
|
| 478 |
+ } |
|
| 479 |
+ } |
|
| 455 | 480 |
} |
| 456 | 481 |
rl->n = j; |
| 457 | 482 |
} |
| ... | ... |
@@ -89,12 +89,26 @@ getaddr (unsigned int flags, |
| 89 | 89 |
bool *succeeded, |
| 90 | 90 |
volatile int *signal_received) |
| 91 | 91 |
{
|
| 92 |
+ return getaddr_multi (flags, hostname, resolve_retry_seconds, succeeded, signal_received, NULL); |
|
| 93 |
+} |
|
| 94 |
+ |
|
| 95 |
+in_addr_t |
|
| 96 |
+getaddr_multi (unsigned int flags, |
|
| 97 |
+ const char *hostname, |
|
| 98 |
+ int resolve_retry_seconds, |
|
| 99 |
+ bool *succeeded, |
|
| 100 |
+ volatile int *signal_received, |
|
| 101 |
+ struct resolve_list *reslist) |
|
| 102 |
+{
|
|
| 92 | 103 |
struct in_addr ia; |
| 93 | 104 |
int status; |
| 94 | 105 |
int sigrec = 0; |
| 95 | 106 |
int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS; |
| 96 | 107 |
struct gc_arena gc = gc_new (); |
| 97 | 108 |
|
| 109 |
+ if (reslist) |
|
| 110 |
+ reslist->len = 0; |
|
| 111 |
+ |
|
| 98 | 112 |
if (flags & GETADDR_RANDOMIZE) |
| 99 | 113 |
hostname = hostname_randomize(hostname, &gc); |
| 100 | 114 |
|
| ... | ... |
@@ -212,12 +226,28 @@ getaddr (unsigned int flags, |
| 212 | 212 |
++n; |
| 213 | 213 |
ASSERT (n >= 2); |
| 214 | 214 |
|
| 215 |
- msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d addresses, choosing one by random", |
|
| 215 |
+ msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d addresses", |
|
| 216 | 216 |
hostname, |
| 217 | 217 |
n); |
| 218 | 218 |
|
| 219 | 219 |
/* choose address randomly, for basic load-balancing capability */ |
| 220 |
- ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]); |
|
| 220 |
+ /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);* |
|
| 221 |
+ |
|
| 222 |
+ /* choose first address */ |
|
| 223 |
+ ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]); |
|
| 224 |
+ |
|
| 225 |
+ if (reslist) |
|
| 226 |
+ {
|
|
| 227 |
+ int i; |
|
| 228 |
+ for (i = 0; i < n && i < SIZE(reslist->data); ++i) |
|
| 229 |
+ {
|
|
| 230 |
+ in_addr_t a = *(in_addr_t *) (h->h_addr_list[i]); |
|
| 231 |
+ if (flags & GETADDR_HOST_ORDER) |
|
| 232 |
+ a = ntohl(a); |
|
| 233 |
+ reslist->data[i] = a; |
|
| 234 |
+ } |
|
| 235 |
+ reslist->len = i; |
|
| 236 |
+ } |
|
| 221 | 237 |
} |
| 222 | 238 |
} |
| 223 | 239 |
|
| ... | ... |
@@ -439,6 +439,11 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int * |
| 439 | 439 |
* DNS resolution |
| 440 | 440 |
*/ |
| 441 | 441 |
|
| 442 |
+struct resolve_list {
|
|
| 443 |
+ int len; |
|
| 444 |
+ in_addr_t data[16]; |
|
| 445 |
+}; |
|
| 446 |
+ |
|
| 442 | 447 |
#define GETADDR_RESOLVE (1<<0) |
| 443 | 448 |
#define GETADDR_FATAL (1<<1) |
| 444 | 449 |
#define GETADDR_HOST_ORDER (1<<2) |
| ... | ... |
@@ -456,6 +461,13 @@ in_addr_t getaddr (unsigned int flags, |
| 456 | 456 |
bool *succeeded, |
| 457 | 457 |
volatile int *signal_received); |
| 458 | 458 |
|
| 459 |
+in_addr_t getaddr_multi (unsigned int flags, |
|
| 460 |
+ const char *hostname, |
|
| 461 |
+ int resolve_retry_seconds, |
|
| 462 |
+ bool *succeeded, |
|
| 463 |
+ volatile int *signal_received, |
|
| 464 |
+ struct resolve_list *reslist); |
|
| 465 |
+ |
|
| 459 | 466 |
/* |
| 460 | 467 |
* Transport protocol naming and other details. |
| 461 | 468 |
*/ |