summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Yonan <james@openvpn.net>2010-07-12 01:55:54 +0000
committerJames Yonan <james@openvpn.net>2010-07-12 01:55:54 +0000
commitf9b2ada0eece06158cc3ce6f6348bd431dfd7f0a (patch)
treeef5688a70b5d9f3d892f73091b20961160f1ad7f
parent9c110e877c76bf44b7b327a1cb795c8422380b0f (diff)
downloadopenvpn-f9b2ada0eece06158cc3ce6f6348bd431dfd7f0a.tar.gz
openvpn-f9b2ada0eece06158cc3ce6f6348bd431dfd7f0a.tar.xz
openvpn-f9b2ada0eece06158cc3ce6f6348bd431dfd7f0a.zip
Implemented multi-address DNS expansion on the network field of route
commands. 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
-rw-r--r--route.c53
-rw-r--r--socket.c34
-rw-r--r--socket.h12
-rw-r--r--version.m42
4 files changed, 85 insertions, 16 deletions
diff --git a/route.c b/route.c
index 2635afd..5d8f8d6 100644
--- a/route.c
+++ b/route.c
@@ -219,6 +219,7 @@ is_special_addr (const char *addr_str)
static bool
init_route (struct route *r,
+ struct resolve_list *network_list,
const struct route_option *ro,
const struct route_special_addr *spec)
{
@@ -237,14 +238,15 @@ init_route (struct route *r,
if (!get_special_addr (spec, ro->network, &r->network, &status))
{
- r->network = getaddr (
- GETADDR_RESOLVE
- | GETADDR_HOST_ORDER
- | GETADDR_WARN_ON_SIGNAL,
- ro->network,
- 0,
- &status,
- NULL);
+ r->network = getaddr_multi (
+ GETADDR_RESOLVE
+ | GETADDR_HOST_ORDER
+ | GETADDR_WARN_ON_SIGNAL,
+ ro->network,
+ 0,
+ &status,
+ NULL,
+ network_list);
}
if (!status)
@@ -438,20 +440,45 @@ init_route_list (struct route_list *rl,
else
rl->spec.remote_endpoint_defined = false;
- if (!(opt->n >= 0 && opt->n <= rl->capacity))
- msg (M_FATAL, PACKAGE_NAME " ROUTE: (init) number of route options (%d) is greater than route list capacity (%d)", opt->n, rl->capacity);
-
/* parse the routes from opt to rl */
{
int i, j = 0;
+ bool warned = false;
for (i = 0; i < opt->n; ++i)
{
- if (!init_route (&rl->routes[j],
+ struct resolve_list netlist;
+ struct route r;
+ int k;
+
+ if (!init_route (&r,
+ &netlist,
&opt->routes[i],
&rl->spec))
ret = false;
else
- ++j;
+ {
+ if (!netlist.len)
+ {
+ netlist.data[0] = r.network;
+ netlist.len = 1;
+ }
+ for (k = 0; k < netlist.len; ++k)
+ {
+ if (j < rl->capacity)
+ {
+ r.network = netlist.data[k];
+ rl->routes[j++] = r;
+ }
+ else
+ {
+ if (!warned)
+ {
+ msg (M_WARN, PACKAGE_NAME " ROUTE: routes dropped because number of expanded routes is greater than route list capacity (%d)", rl->capacity);
+ warned = true;
+ }
+ }
+ }
+ }
}
rl->n = j;
}
diff --git a/socket.c b/socket.c
index cf4ddb6..6f488e9 100644
--- a/socket.c
+++ b/socket.c
@@ -89,12 +89,26 @@ getaddr (unsigned int flags,
bool *succeeded,
volatile int *signal_received)
{
+ return getaddr_multi (flags, hostname, resolve_retry_seconds, succeeded, signal_received, NULL);
+}
+
+in_addr_t
+getaddr_multi (unsigned int flags,
+ const char *hostname,
+ int resolve_retry_seconds,
+ bool *succeeded,
+ volatile int *signal_received,
+ struct resolve_list *reslist)
+{
struct in_addr ia;
int status;
int sigrec = 0;
int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS;
struct gc_arena gc = gc_new ();
+ if (reslist)
+ reslist->len = 0;
+
if (flags & GETADDR_RANDOMIZE)
hostname = hostname_randomize(hostname, &gc);
@@ -212,12 +226,28 @@ getaddr (unsigned int flags,
++n;
ASSERT (n >= 2);
- msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d addresses, choosing one by random",
+ msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d addresses",
hostname,
n);
/* choose address randomly, for basic load-balancing capability */
- ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);
+ /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);*
+
+ /* choose first address */
+ ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]);
+
+ if (reslist)
+ {
+ int i;
+ for (i = 0; i < n && i < SIZE(reslist->data); ++i)
+ {
+ in_addr_t a = *(in_addr_t *) (h->h_addr_list[i]);
+ if (flags & GETADDR_HOST_ORDER)
+ a = ntohl(a);
+ reslist->data[i] = a;
+ }
+ reslist->len = i;
+ }
}
}
diff --git a/socket.h b/socket.h
index 5155853..cd24011 100644
--- a/socket.h
+++ b/socket.h
@@ -439,6 +439,11 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int *
* DNS resolution
*/
+struct resolve_list {
+ int len;
+ in_addr_t data[16];
+};
+
#define GETADDR_RESOLVE (1<<0)
#define GETADDR_FATAL (1<<1)
#define GETADDR_HOST_ORDER (1<<2)
@@ -456,6 +461,13 @@ in_addr_t getaddr (unsigned int flags,
bool *succeeded,
volatile int *signal_received);
+in_addr_t getaddr_multi (unsigned int flags,
+ const char *hostname,
+ int resolve_retry_seconds,
+ bool *succeeded,
+ volatile int *signal_received,
+ struct resolve_list *reslist);
+
/*
* Transport protocol naming and other details.
*/
diff --git a/version.m4 b/version.m4
index 2475fa0..4d88364 100644
--- a/version.m4
+++ b/version.m4
@@ -1,5 +1,5 @@
dnl define the OpenVPN version
-define(PRODUCT_VERSION,[2.1.1k])
+define(PRODUCT_VERSION,[2.1.1l])
dnl define the TAP version
define(PRODUCT_TAP_ID,[tap0901])
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])