]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Implemented multi-address DNS expansion on the network field of route
authorJames Yonan <james@openvpn.net>
Mon, 12 Jul 2010 01:55:54 +0000 (01:55 +0000)
committerJames Yonan <james@openvpn.net>
Mon, 12 Jul 2010 01:55:54 +0000 (01:55 +0000)
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

route.c
socket.c
socket.h
version.m4

diff --git a/route.c b/route.c
index 2635afdff5727521176ecc4a68512eb6113e6261..5d8f8d66afc2fe0f58ac44da5885075e87b8e32e 100644 (file)
--- 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;
   }
index cf4ddb6ad04d9673e5ee65afd7e7f18ae48362c5..6f488e9bd4f4679875abe74cb46ff5d036eb7c06 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -88,6 +88,17 @@ getaddr (unsigned int flags,
         int resolve_retry_seconds,
         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;
@@ -95,6 +106,9 @@ getaddr (unsigned int flags,
   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;
+               }
            }
        }
 
index 51558534d794932c2da5ee38c20227ef9444e56a..cd24011efd48c00141f3e2ec934a14eba4e2f0dc 100644 (file)
--- 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.
  */
index 2475fa0097c32f41738d833f5fc6a7b3b78d6008..4d88364cedc602eb477b12e50ad1ab409f1c0eb7 100644 (file)
@@ -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])