diff options
-rw-r--r-- | route.c | 53 | ||||
-rw-r--r-- | socket.c | 34 | ||||
-rw-r--r-- | socket.h | 12 | ||||
-rw-r--r-- | version.m4 | 2 |
4 files changed, 85 insertions, 16 deletions
@@ -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; } @@ -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; + } } } @@ -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. */ @@ -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]) |