the getaddr6 and getaddr_mutli functions are duplicates of each other.
Since we always require getaddrinfo to be present both function are merge
into one openvpn_getaddrinfo.
This functions also returns a standard struct addrinfo* so our resolve
interface is closer to the standard unix interface. The getaddr function
is a wrapper which provides backward compatibility for IPv4 addresses.
Ipv6 calls and calls to getaddr_multi are replaced with the new interface.
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: 1344333837-22076-1-git-send-email-arne@rfc2549.org
URL: http://article.gmane.org/gmane.network.openvpn.devel/6959
Signed-off-by: David Sommerseth <davids@redhat.com>
[DS: Applied proper indenting on the changes wherever needed]
| ... | ... |
@@ -268,12 +268,14 @@ is_special_addr (const char *addr_str) |
| 268 | 268 |
|
| 269 | 269 |
static bool |
| 270 | 270 |
init_route (struct route *r, |
| 271 |
- struct resolve_list *network_list, |
|
| 271 |
+ struct addrinfo **network_list, |
|
| 272 | 272 |
const struct route_option *ro, |
| 273 | 273 |
const struct route_list *rl) |
| 274 | 274 |
{
|
| 275 | 275 |
const in_addr_t default_netmask = IPV4_NETMASK_HOST; |
| 276 | 276 |
bool status; |
| 277 |
+ int ret; |
|
| 278 |
+ struct in_addr special; |
|
| 277 | 279 |
|
| 278 | 280 |
CLEAR (*r); |
| 279 | 281 |
r->option = ro; |
| ... | ... |
@@ -284,19 +286,22 @@ init_route (struct route *r, |
| 284 | 284 |
{
|
| 285 | 285 |
goto fail; |
| 286 | 286 |
} |
| 287 |
- |
|
| 288 |
- if (!get_special_addr (rl, ro->network, &r->network, &status)) |
|
| 287 |
+ |
|
| 288 |
+ |
|
| 289 |
+ /* get_special_addr replaces specialaddr with a special ip addr |
|
| 290 |
+ like gw. getaddrinfo is called to convert a a addrinfo struct */ |
|
| 291 |
+ |
|
| 292 |
+ if(get_special_addr (rl, ro->network, &special.s_addr, &status)) |
|
| 289 | 293 |
{
|
| 290 |
- r->network = getaddr_multi ( |
|
| 291 |
- GETADDR_RESOLVE |
|
| 292 |
- | GETADDR_HOST_ORDER |
|
| 293 |
- | GETADDR_WARN_ON_SIGNAL, |
|
| 294 |
- ro->network, |
|
| 295 |
- 0, |
|
| 296 |
- &status, |
|
| 297 |
- NULL, |
|
| 298 |
- network_list); |
|
| 294 |
+ special.s_addr = htonl(special.s_addr); |
|
| 295 |
+ ret = openvpn_getaddrinfo(0, inet_ntoa(special), 0, NULL, |
|
| 296 |
+ AF_INET, network_list); |
|
| 299 | 297 |
} |
| 298 |
+ else |
|
| 299 |
+ ret = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL, |
|
| 300 |
+ ro->network, 0, NULL, AF_INET, network_list); |
|
| 301 |
+ |
|
| 302 |
+ status = (ret == 0); |
|
| 300 | 303 |
|
| 301 | 304 |
if (!status) |
| 302 | 305 |
goto fail; |
| ... | ... |
@@ -642,11 +647,8 @@ init_route_list (struct route_list *rl, |
| 642 | 642 |
bool warned = false; |
| 643 | 643 |
for (i = 0; i < opt->n; ++i) |
| 644 | 644 |
{
|
| 645 |
- struct resolve_list netlist; |
|
| 645 |
+ struct addrinfo* netlist; |
|
| 646 | 646 |
struct route r; |
| 647 |
- int k; |
|
| 648 |
- |
|
| 649 |
- CLEAR(netlist); /* init_route() will not always init this */ |
|
| 650 | 647 |
|
| 651 | 648 |
if (!init_route (&r, |
| 652 | 649 |
&netlist, |
| ... | ... |
@@ -655,16 +657,12 @@ init_route_list (struct route_list *rl, |
| 655 | 655 |
ret = false; |
| 656 | 656 |
else |
| 657 | 657 |
{
|
| 658 |
- if (!netlist.len) |
|
| 659 |
- {
|
|
| 660 |
- netlist.data[0] = r.network; |
|
| 661 |
- netlist.len = 1; |
|
| 662 |
- } |
|
| 663 |
- for (k = 0; k < netlist.len; ++k) |
|
| 658 |
+ struct addrinfo* curele; |
|
| 659 |
+ for (curele = netlist; curele; curele = curele->ai_next) |
|
| 664 | 660 |
{
|
| 665 | 661 |
if (j < rl->capacity) |
| 666 | 662 |
{
|
| 667 |
- r.network = netlist.data[k]; |
|
| 663 |
+ r.network = ntohl(((struct sockaddr_in*)(curele)->ai_addr)->sin_addr.s_addr); |
|
| 668 | 664 |
rl->routes[j++] = r; |
| 669 | 665 |
} |
| 670 | 666 |
else |
| ... | ... |
@@ -676,6 +674,7 @@ init_route_list (struct route_list *rl, |
| 676 | 676 |
} |
| 677 | 677 |
} |
| 678 | 678 |
} |
| 679 |
+ freeaddrinfo(netlist); |
|
| 679 | 680 |
} |
| 680 | 681 |
} |
| 681 | 682 |
rl->n = j; |
| ... | ... |
@@ -93,220 +93,53 @@ h_errno_msg(int h_errno_err) |
| 93 | 93 |
*/ |
| 94 | 94 |
in_addr_t |
| 95 | 95 |
getaddr (unsigned int flags, |
| 96 |
- const char *hostname, |
|
| 97 |
- int resolve_retry_seconds, |
|
| 98 |
- bool *succeeded, |
|
| 99 |
- volatile int *signal_received) |
|
| 96 |
+ const char *hostname, |
|
| 97 |
+ int resolve_retry_seconds, |
|
| 98 |
+ bool *succeeded, |
|
| 99 |
+ volatile int *signal_received) |
|
| 100 | 100 |
{
|
| 101 |
- return getaddr_multi (flags, hostname, resolve_retry_seconds, succeeded, signal_received, NULL); |
|
| 102 |
-} |
|
| 103 |
- |
|
| 104 |
-in_addr_t |
|
| 105 |
-getaddr_multi (unsigned int flags, |
|
| 106 |
- const char *hostname, |
|
| 107 |
- int resolve_retry_seconds, |
|
| 108 |
- bool *succeeded, |
|
| 109 |
- volatile int *signal_received, |
|
| 110 |
- struct resolve_list *reslist) |
|
| 111 |
-{
|
|
| 112 |
- struct in_addr ia; |
|
| 101 |
+ struct addrinfo *ai; |
|
| 113 | 102 |
int status; |
| 114 |
- int sigrec = 0; |
|
| 115 |
- int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS; |
|
| 116 |
- struct gc_arena gc = gc_new (); |
|
| 117 |
- |
|
| 118 |
- if (reslist) |
|
| 119 |
- reslist->len = 0; |
|
| 120 |
- |
|
| 121 |
- if (flags & GETADDR_RANDOMIZE) |
|
| 122 |
- hostname = hostname_randomize(hostname, &gc); |
|
| 123 |
- |
|
| 124 |
- if (flags & GETADDR_MSG_VIRT_OUT) |
|
| 125 |
- msglevel |= M_MSG_VIRT_OUT; |
|
| 126 |
- |
|
| 127 |
- CLEAR (ia); |
|
| 128 |
- if (succeeded) |
|
| 129 |
- *succeeded = false; |
|
| 130 |
- |
|
| 131 |
- if ((flags & (GETADDR_FATAL_ON_SIGNAL|GETADDR_WARN_ON_SIGNAL)) |
|
| 132 |
- && !signal_received) |
|
| 133 |
- signal_received = &sigrec; |
|
| 134 |
- |
|
| 135 |
- status = openvpn_inet_aton (hostname, &ia); /* parse ascii IP address */ |
|
| 136 |
- |
|
| 137 |
- if (status != OIA_IP) /* parse as IP address failed? */ |
|
| 138 |
- {
|
|
| 139 |
- const int fail_wait_interval = 5; /* seconds */ |
|
| 140 |
- int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 : (resolve_retry_seconds / fail_wait_interval); |
|
| 141 |
- struct hostent *h; |
|
| 142 |
- const char *fmt; |
|
| 143 |
- int level = 0; |
|
| 144 |
- |
|
| 145 |
- CLEAR (ia); |
|
| 146 |
- |
|
| 147 |
- fmt = "RESOLVE: Cannot resolve host address: %s: %s"; |
|
| 148 |
- if ((flags & GETADDR_MENTION_RESOLVE_RETRY) |
|
| 149 |
- && !resolve_retry_seconds) |
|
| 150 |
- fmt = "RESOLVE: Cannot resolve host address: %s: %s (I would have retried this name query if you had specified the --resolv-retry option.)"; |
|
| 151 |
- |
|
| 152 |
- if (!(flags & GETADDR_RESOLVE) || status == OIA_ERROR) |
|
| 153 |
- {
|
|
| 154 |
- msg (msglevel, "RESOLVE: Cannot parse IP address: %s", hostname); |
|
| 155 |
- goto done; |
|
| 156 |
- } |
|
| 157 |
- |
|
| 158 |
-#ifdef ENABLE_MANAGEMENT |
|
| 159 |
- if (flags & GETADDR_UPDATE_MANAGEMENT_STATE) |
|
| 160 |
- {
|
|
| 161 |
- if (management) |
|
| 162 |
- management_set_state (management, |
|
| 163 |
- OPENVPN_STATE_RESOLVE, |
|
| 164 |
- NULL, |
|
| 165 |
- (in_addr_t)0, |
|
| 166 |
- (in_addr_t)0); |
|
| 167 |
- } |
|
| 168 |
-#endif |
|
| 169 |
- |
|
| 170 |
- /* |
|
| 171 |
- * Resolve hostname |
|
| 172 |
- */ |
|
| 173 |
- while (true) |
|
| 174 |
- {
|
|
| 175 |
- /* try hostname lookup */ |
|
| 176 |
-#if defined(HAVE_RES_INIT) |
|
| 177 |
- res_init (); |
|
| 178 |
-#endif |
|
| 179 |
- h = gethostbyname (hostname); |
|
| 180 |
- |
|
| 181 |
- if (signal_received) |
|
| 182 |
- {
|
|
| 183 |
- get_signal (signal_received); |
|
| 184 |
- if (*signal_received) /* were we interrupted by a signal? */ |
|
| 185 |
- {
|
|
| 186 |
- h = NULL; |
|
| 187 |
- if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ |
|
| 188 |
- {
|
|
| 189 |
- msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); |
|
| 190 |
- *signal_received = 0; |
|
| 191 |
- } |
|
| 192 |
- else |
|
| 193 |
- goto done; |
|
| 194 |
- } |
|
| 195 |
- } |
|
| 196 |
- |
|
| 197 |
- /* success? */ |
|
| 198 |
- if (h) |
|
| 199 |
- break; |
|
| 200 |
- |
|
| 201 |
- /* resolve lookup failed, should we |
|
| 202 |
- continue or fail? */ |
|
| 203 |
- |
|
| 204 |
- level = msglevel; |
|
| 205 |
- if (resolve_retries > 0) |
|
| 206 |
- level = D_RESOLVE_ERRORS; |
|
| 207 |
- |
|
| 208 |
- msg (level, |
|
| 209 |
- fmt, |
|
| 210 |
- hostname, |
|
| 211 |
- h_errno_msg (h_errno)); |
|
| 212 |
- |
|
| 213 |
- if (--resolve_retries <= 0) |
|
| 214 |
- goto done; |
|
| 215 |
- |
|
| 216 |
- openvpn_sleep (fail_wait_interval); |
|
| 217 |
- } |
|
| 218 |
- |
|
| 219 |
- if (h->h_addrtype != AF_INET || h->h_length != 4) |
|
| 220 |
- {
|
|
| 221 |
- msg (msglevel, "RESOLVE: Sorry, but we only accept IPv4 DNS names: %s", hostname); |
|
| 222 |
- goto done; |
|
| 223 |
- } |
|
| 224 |
- |
|
| 225 |
- ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]); |
|
| 226 |
- |
|
| 227 |
- if (ia.s_addr) |
|
| 228 |
- {
|
|
| 229 |
- if (h->h_addr_list[1]) /* more than one address returned */ |
|
| 230 |
- {
|
|
| 231 |
- int n = 0; |
|
| 232 |
- |
|
| 233 |
- /* count address list */ |
|
| 234 |
- while (h->h_addr_list[n]) |
|
| 235 |
- ++n; |
|
| 236 |
- ASSERT (n >= 2); |
|
| 237 |
- |
|
| 238 |
- msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d addresses", |
|
| 239 |
- hostname, |
|
| 240 |
- n); |
|
| 241 |
- |
|
| 242 |
- /* choose address randomly, for basic load-balancing capability */ |
|
| 243 |
- /*ia.s_addr = *(in_addr_t *) (h->h_addr_list[get_random () % n]);*/ |
|
| 244 |
- |
|
| 245 |
- /* choose first address */ |
|
| 246 |
- ia.s_addr = *(in_addr_t *) (h->h_addr_list[0]); |
|
| 247 |
- |
|
| 248 |
- if (reslist) |
|
| 249 |
- {
|
|
| 250 |
- int i; |
|
| 251 |
- for (i = 0; i < n && i < SIZE(reslist->data); ++i) |
|
| 252 |
- {
|
|
| 253 |
- in_addr_t a = *(in_addr_t *) (h->h_addr_list[i]); |
|
| 254 |
- if (flags & GETADDR_HOST_ORDER) |
|
| 255 |
- a = ntohl(a); |
|
| 256 |
- reslist->data[i] = a; |
|
| 257 |
- } |
|
| 258 |
- reslist->len = i; |
|
| 259 |
- } |
|
| 260 |
- } |
|
| 261 |
- } |
|
| 262 |
- |
|
| 263 |
- /* hostname resolve succeeded */ |
|
| 264 |
- if (succeeded) |
|
| 265 |
- *succeeded = true; |
|
| 266 |
- } |
|
| 267 |
- else |
|
| 268 |
- {
|
|
| 269 |
- /* IP address parse succeeded */ |
|
| 270 |
- if (succeeded) |
|
| 271 |
- *succeeded = true; |
|
| 272 |
- } |
|
| 273 |
- |
|
| 274 |
- done: |
|
| 275 |
- if (signal_received && *signal_received) |
|
| 276 |
- {
|
|
| 277 |
- int level = 0; |
|
| 278 |
- if (flags & GETADDR_FATAL_ON_SIGNAL) |
|
| 279 |
- level = M_FATAL; |
|
| 280 |
- else if (flags & GETADDR_WARN_ON_SIGNAL) |
|
| 281 |
- level = M_WARN; |
|
| 282 |
- msg (level, "RESOLVE: signal received during DNS resolution attempt"); |
|
| 283 |
- } |
|
| 284 |
- |
|
| 285 |
- gc_free (&gc); |
|
| 286 |
- return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; |
|
| 103 |
+ status = openvpn_getaddrinfo(flags, hostname, resolve_retry_seconds, |
|
| 104 |
+ signal_received, AF_INET, &ai); |
|
| 105 |
+ if(status==0) {
|
|
| 106 |
+ struct in_addr ia; |
|
| 107 |
+ if(succeeded) |
|
| 108 |
+ *succeeded=true; |
|
| 109 |
+ ia = ((struct sockaddr_in*)ai->ai_addr)->sin_addr; |
|
| 110 |
+ freeaddrinfo(ai); |
|
| 111 |
+ return (flags & GETADDR_HOST_ORDER) ? ntohl (ia.s_addr) : ia.s_addr; |
|
| 112 |
+ } else {
|
|
| 113 |
+ if(succeeded) |
|
| 114 |
+ *succeeded =false; |
|
| 115 |
+ return 0; |
|
| 116 |
+ } |
|
| 287 | 117 |
} |
| 288 | 118 |
|
| 119 |
+ |
|
| 289 | 120 |
/* |
| 290 |
- * Translate IPv6 addr or hostname into struct addrinfo |
|
| 291 |
- * If resolve error, try again for |
|
| 292 |
- * resolve_retry_seconds seconds. |
|
| 121 |
+ * Translate IPv4/IPv6 addr or hostname into struct addrinfo |
|
| 122 |
+ * If resolve error, try again for resolve_retry_seconds seconds. |
|
| 293 | 123 |
*/ |
| 294 |
-bool |
|
| 295 |
-getaddr6 (unsigned int flags, |
|
| 296 |
- const char *hostname, |
|
| 297 |
- int resolve_retry_seconds, |
|
| 298 |
- volatile int *signal_received, |
|
| 299 |
- int *gai_err, |
|
| 300 |
- struct sockaddr_in6 *in6) |
|
| 301 |
-{
|
|
| 302 |
- bool success; |
|
| 303 |
- struct addrinfo hints, *ai; |
|
| 124 |
+int |
|
| 125 |
+openvpn_getaddrinfo (unsigned int flags, |
|
| 126 |
+ const char *hostname, |
|
| 127 |
+ int resolve_retry_seconds, |
|
| 128 |
+ volatile int *signal_received, |
|
| 129 |
+ int ai_family, |
|
| 130 |
+ struct addrinfo **res) |
|
| 131 |
+{
|
|
| 132 |
+ struct addrinfo hints; |
|
| 304 | 133 |
int status; |
| 305 | 134 |
int sigrec = 0; |
| 306 | 135 |
int msglevel = (flags & GETADDR_FATAL) ? M_FATAL : D_RESOLVE_ERRORS; |
| 307 | 136 |
struct gc_arena gc = gc_new (); |
| 308 | 137 |
|
| 309 |
- ASSERT(in6); |
|
| 138 |
+ ASSERT(res); |
|
| 139 |
+ |
|
| 140 |
+#if defined(HAVE_RES_INIT) |
|
| 141 |
+ res_init (); |
|
| 142 |
+#endif |
|
| 310 | 143 |
|
| 311 | 144 |
if (!hostname) |
| 312 | 145 |
hostname = "::"; |
| ... | ... |
@@ -317,151 +150,111 @@ getaddr6 (unsigned int flags, |
| 317 | 317 |
if (flags & GETADDR_MSG_VIRT_OUT) |
| 318 | 318 |
msglevel |= M_MSG_VIRT_OUT; |
| 319 | 319 |
|
| 320 |
- CLEAR (ai); |
|
| 321 |
- success = false; |
|
| 322 |
- |
|
| 323 | 320 |
if ((flags & (GETADDR_FATAL_ON_SIGNAL|GETADDR_WARN_ON_SIGNAL)) |
| 324 | 321 |
&& !signal_received) |
| 325 | 322 |
signal_received = &sigrec; |
| 326 | 323 |
|
| 327 | 324 |
/* try numeric ipv6 addr first */ |
| 328 | 325 |
CLEAR(hints); |
| 329 |
- hints.ai_family = AF_INET6; |
|
| 326 |
+ hints.ai_family = ai_family; |
|
| 330 | 327 |
hints.ai_flags = AI_NUMERICHOST; |
| 331 |
- if ((status = getaddrinfo(hostname, NULL, &hints, &ai))==0) |
|
| 332 |
- {
|
|
| 333 |
- *in6 = *((struct sockaddr_in6 *)(ai->ai_addr)); |
|
| 334 |
- freeaddrinfo(ai); |
|
| 335 |
- ai = NULL; |
|
| 336 |
- } |
|
| 337 |
- if (gai_err) |
|
| 338 |
- *gai_err = status; |
|
| 328 |
+ hints.ai_socktype = dnsflags_to_socktype(flags); |
|
| 339 | 329 |
|
| 330 |
+ status = getaddrinfo(hostname, NULL, &hints, res); |
|
| 340 | 331 |
|
| 341 |
- if (status != 0) /* parse as IPv6 address failed? */ |
|
| 332 |
+ if (status != 0) /* parse as numeric address failed? */ |
|
| 342 | 333 |
{
|
| 343 | 334 |
const int fail_wait_interval = 5; /* seconds */ |
| 344 | 335 |
int resolve_retries = (flags & GETADDR_TRY_ONCE) ? 1 : (resolve_retry_seconds / fail_wait_interval); |
| 345 | 336 |
const char *fmt; |
| 346 | 337 |
int level = 0; |
| 347 |
- int err; |
|
| 348 |
- |
|
| 349 |
- ai = NULL; |
|
| 350 | 338 |
|
| 351 | 339 |
fmt = "RESOLVE: Cannot resolve host address: %s: %s"; |
| 352 | 340 |
if ((flags & GETADDR_MENTION_RESOLVE_RETRY) |
| 353 |
- && !resolve_retry_seconds) |
|
| 354 |
- fmt = "RESOLVE: Cannot resolve host address: %s: %s (I would have retried this name query if you had specified the --resolv-retry option.)"; |
|
| 341 |
+ && !resolve_retry_seconds) |
|
| 342 |
+ fmt = "RESOLVE: Cannot resolve host address: %s: %s (I would have retried this name query if you had specified the --resolv-retry option.)"; |
|
| 355 | 343 |
|
| 356 | 344 |
if (!(flags & GETADDR_RESOLVE) || status == EAI_FAIL) |
| 357 |
- {
|
|
| 358 |
- msg (msglevel, "RESOLVE: Cannot parse IPv6 address: %s", hostname); |
|
| 359 |
- goto done; |
|
| 360 |
- } |
|
| 345 |
+ {
|
|
| 346 |
+ msg (msglevel, "RESOLVE: Cannot parse IP address: %s", hostname); |
|
| 347 |
+ goto done; |
|
| 348 |
+ } |
|
| 361 | 349 |
|
| 362 | 350 |
#ifdef ENABLE_MANAGEMENT |
| 363 | 351 |
if (flags & GETADDR_UPDATE_MANAGEMENT_STATE) |
| 364 |
- {
|
|
| 365 |
- if (management) |
|
| 366 |
- management_set_state (management, |
|
| 367 |
- OPENVPN_STATE_RESOLVE, |
|
| 368 |
- NULL, |
|
| 369 |
- (in_addr_t)0, |
|
| 370 |
- (in_addr_t)0); |
|
| 371 |
- } |
|
| 352 |
+ {
|
|
| 353 |
+ if (management) |
|
| 354 |
+ management_set_state (management, |
|
| 355 |
+ OPENVPN_STATE_RESOLVE, |
|
| 356 |
+ NULL, |
|
| 357 |
+ (in_addr_t)0, |
|
| 358 |
+ (in_addr_t)0); |
|
| 359 |
+ } |
|
| 372 | 360 |
#endif |
| 373 | 361 |
|
| 374 | 362 |
/* |
| 375 | 363 |
* Resolve hostname |
| 376 | 364 |
*/ |
| 377 | 365 |
while (true) |
| 378 |
- {
|
|
| 379 |
- /* try hostname lookup */ |
|
| 366 |
+ {
|
|
| 367 |
+ /* try hostname lookup */ |
|
| 380 | 368 |
hints.ai_flags = 0; |
| 381 |
- hints.ai_socktype = dnsflags_to_socktype(flags); |
|
| 382 |
- dmsg (D_SOCKET_DEBUG, "GETADDR6 flags=0x%04x ai_family=%d ai_socktype=%d", |
|
| 383 |
- flags, hints.ai_family, hints.ai_socktype); |
|
| 384 |
- err = getaddrinfo(hostname, NULL, &hints, &ai); |
|
| 385 |
- |
|
| 386 |
- if (gai_err) |
|
| 387 |
- *gai_err = err; |
|
| 369 |
+ dmsg (D_SOCKET_DEBUG, "GETADDRINFO flags=0x%04x ai_family=%d ai_socktype=%d", |
|
| 370 |
+ flags, hints.ai_family, hints.ai_socktype); |
|
| 371 |
+ status = getaddrinfo(hostname, NULL, &hints, res); |
|
| 388 | 372 |
|
| 389 |
- if (signal_received) |
|
| 390 |
- {
|
|
| 391 |
- get_signal (signal_received); |
|
| 392 |
- if (*signal_received) /* were we interrupted by a signal? */ |
|
| 393 |
- {
|
|
| 394 |
- if (0 == err) {
|
|
| 395 |
- ASSERT(ai); |
|
| 396 |
- freeaddrinfo(ai); |
|
| 397 |
- ai = NULL; |
|
| 373 |
+ if (signal_received) |
|
| 374 |
+ {
|
|
| 375 |
+ get_signal (signal_received); |
|
| 376 |
+ if (*signal_received) /* were we interrupted by a signal? */ |
|
| 377 |
+ {
|
|
| 378 |
+ if (0 == status) {
|
|
| 379 |
+ ASSERT(res); |
|
| 380 |
+ freeaddrinfo(*res); |
|
| 381 |
+ res = NULL; |
|
| 398 | 382 |
} |
| 399 |
- if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ |
|
| 400 |
- {
|
|
| 401 |
- msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); |
|
| 402 |
- *signal_received = 0; |
|
| 403 |
- } |
|
| 404 |
- else |
|
| 405 |
- goto done; |
|
| 406 |
- } |
|
| 407 |
- } |
|
| 408 |
- |
|
| 409 |
- /* success? */ |
|
| 410 |
- if (0 == err) |
|
| 411 |
- break; |
|
| 412 |
- |
|
| 413 |
- /* resolve lookup failed, should we |
|
| 414 |
- continue or fail? */ |
|
| 415 |
- |
|
| 416 |
- level = msglevel; |
|
| 417 |
- if (resolve_retries > 0) |
|
| 418 |
- level = D_RESOLVE_ERRORS; |
|
| 419 |
- |
|
| 420 |
- msg (level, |
|
| 421 |
- fmt, |
|
| 422 |
- hostname, |
|
| 423 |
- gai_strerror(err)); |
|
| 424 |
- |
|
| 425 |
- if (--resolve_retries <= 0) |
|
| 426 |
- goto done; |
|
| 427 |
- |
|
| 428 |
- openvpn_sleep (fail_wait_interval); |
|
| 429 |
- } |
|
| 383 |
+ if (*signal_received == SIGUSR1) /* ignore SIGUSR1 */ |
|
| 384 |
+ {
|
|
| 385 |
+ msg (level, "RESOLVE: Ignored SIGUSR1 signal received during DNS resolution attempt"); |
|
| 386 |
+ *signal_received = 0; |
|
| 387 |
+ } |
|
| 388 |
+ else |
|
| 389 |
+ goto done; |
|
| 390 |
+ } |
|
| 391 |
+ } |
|
| 430 | 392 |
|
| 431 |
- ASSERT(ai); |
|
| 393 |
+ /* success? */ |
|
| 394 |
+ if (0 == status) |
|
| 395 |
+ break; |
|
| 432 | 396 |
|
| 433 |
- if (!ai->ai_next) |
|
| 434 |
- *in6 = *((struct sockaddr_in6*)(ai->ai_addr)); |
|
| 435 |
- else |
|
| 436 |
- /* more than one address returned */ |
|
| 437 |
- {
|
|
| 438 |
- struct addrinfo *ai_cursor; |
|
| 439 |
- int n = 0; |
|
| 440 |
- /* count address list */ |
|
| 441 |
- for (ai_cursor = ai; ai_cursor; ai_cursor = ai_cursor->ai_next) n++; |
|
| 442 |
- ASSERT (n >= 2); |
|
| 397 |
+ /* resolve lookup failed, should we |
|
| 398 |
+ continue or fail? */ |
|
| 399 |
+ level = msglevel; |
|
| 400 |
+ if (resolve_retries > 0) |
|
| 401 |
+ level = D_RESOLVE_ERRORS; |
|
| 443 | 402 |
|
| 444 |
- msg (D_RESOLVE_ERRORS, "RESOLVE: NOTE: %s resolves to %d ipv6 addresses, choosing one by random", |
|
| 403 |
+ msg (level, |
|
| 404 |
+ fmt, |
|
| 445 | 405 |
hostname, |
| 446 |
- n); |
|
| 406 |
+ gai_strerror(status)); |
|
| 407 |
+ |
|
| 408 |
+ if (--resolve_retries <= 0) |
|
| 409 |
+ goto done; |
|
| 447 | 410 |
|
| 448 |
- /* choose address randomly, for basic load-balancing capability */ |
|
| 449 |
- n--; |
|
| 450 |
- n %= get_random(); |
|
| 451 |
- for (ai_cursor = ai; n; ai_cursor = ai_cursor->ai_next) n--; |
|
| 452 |
- *in6 = *((struct sockaddr_in6*)(ai_cursor->ai_addr)); |
|
| 411 |
+ openvpn_sleep (fail_wait_interval); |
|
| 453 | 412 |
} |
| 454 | 413 |
|
| 455 |
- freeaddrinfo(ai); |
|
| 456 |
- ai = NULL; |
|
| 414 |
+ ASSERT(res); |
|
| 457 | 415 |
|
| 458 | 416 |
/* hostname resolve succeeded */ |
| 459 |
- success = true; |
|
| 417 |
+ |
|
| 418 |
+ /* Do not chose an IP Addresse by random or change the order * |
|
| 419 |
+ * of IP addresses, doing so will break RFC 3484 address selection * |
|
| 420 |
+ */ |
|
| 460 | 421 |
} |
| 461 | 422 |
else |
| 462 | 423 |
{
|
| 463 | 424 |
/* IP address parse succeeded */ |
| 464 |
- success = true; |
|
| 465 | 425 |
} |
| 466 | 426 |
|
| 467 | 427 |
done: |
| ... | ... |
@@ -469,14 +262,14 @@ getaddr6 (unsigned int flags, |
| 469 | 469 |
{
|
| 470 | 470 |
int level = 0; |
| 471 | 471 |
if (flags & GETADDR_FATAL_ON_SIGNAL) |
| 472 |
- level = M_FATAL; |
|
| 472 |
+ level = M_FATAL; |
|
| 473 | 473 |
else if (flags & GETADDR_WARN_ON_SIGNAL) |
| 474 |
- level = M_WARN; |
|
| 474 |
+ level = M_WARN; |
|
| 475 | 475 |
msg (level, "RESOLVE: signal received during DNS resolution attempt"); |
| 476 | 476 |
} |
| 477 | 477 |
|
| 478 | 478 |
gc_free (&gc); |
| 479 |
- return success; |
|
| 479 |
+ return status; |
|
| 480 | 480 |
} |
| 481 | 481 |
|
| 482 | 482 |
/* |
| ... | ... |
@@ -652,18 +445,16 @@ update_remote (const char* host, |
| 652 | 652 |
case AF_INET6: |
| 653 | 653 |
if (host && addr) |
| 654 | 654 |
{
|
| 655 |
- struct sockaddr_in6 sin6; |
|
| 656 |
- int success; |
|
| 657 |
- CLEAR(sin6); |
|
| 658 |
- success = getaddr6 ( |
|
| 659 |
- sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), |
|
| 660 |
- host, |
|
| 661 |
- 1, |
|
| 662 |
- NULL, |
|
| 663 |
- NULL, |
|
| 664 |
- &sin6); |
|
| 665 |
- if ( success ) |
|
| 655 |
+ int status; |
|
| 656 |
+ struct addrinfo* ai; |
|
| 657 |
+ |
|
| 658 |
+ status = openvpn_getaddrinfo(sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sockflags), host, 1, NULL, AF_INET6, &ai); |
|
| 659 |
+ |
|
| 660 |
+ if ( status ==0 ) |
|
| 666 | 661 |
{
|
| 662 |
+ struct sockaddr_in6 sin6; |
|
| 663 |
+ CLEAR(sin6); |
|
| 664 |
+ sin6 = *((struct sockaddr_in6*)ai->ai_addr); |
|
| 667 | 665 |
if (!IN6_ARE_ADDR_EQUAL(&sin6.sin6_addr, &addr->addr.in6.sin6_addr)) |
| 668 | 666 |
{
|
| 669 | 667 |
int port = addr->addr.in6.sin6_port; |
| ... | ... |
@@ -671,6 +462,7 @@ update_remote (const char* host, |
| 671 | 671 |
addr->addr.in6 = sin6; |
| 672 | 672 |
addr->addr.in6.sin6_port = port; |
| 673 | 673 |
} |
| 674 |
+ freeaddrinfo(ai); |
|
| 674 | 675 |
} |
| 675 | 676 |
} |
| 676 | 677 |
break; |
| ... | ... |
@@ -1355,25 +1147,27 @@ resolve_bind_local (struct link_socket *sock) |
| 1355 | 1355 |
break; |
| 1356 | 1356 |
case AF_INET6: |
| 1357 | 1357 |
{
|
| 1358 |
- int success; |
|
| 1358 |
+ int status; |
|
| 1359 | 1359 |
int err; |
| 1360 | 1360 |
CLEAR(sock->info.lsa->local.addr.in6); |
| 1361 | 1361 |
if (sock->local_host) |
| 1362 | 1362 |
{
|
| 1363 |
- success = getaddr6(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, |
|
| 1364 |
- sock->local_host, |
|
| 1365 |
- 0, |
|
| 1366 |
- NULL, |
|
| 1367 |
- &err, |
|
| 1368 |
- &sock->info.lsa->local.addr.in6); |
|
| 1363 |
+ struct addrinfo *ai; |
|
| 1364 |
+ |
|
| 1365 |
+ status = openvpn_getaddrinfo(GETADDR_RESOLVE | GETADDR_WARN_ON_SIGNAL | GETADDR_FATAL, |
|
| 1366 |
+ sock->local_host, 0, NULL, AF_INET6, &ai); |
|
| 1367 |
+ if(status ==0) {
|
|
| 1368 |
+ sock->info.lsa->local.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr)); |
|
| 1369 |
+ freeaddrinfo(ai); |
|
| 1370 |
+ } |
|
| 1369 | 1371 |
} |
| 1370 | 1372 |
else |
| 1371 | 1373 |
{
|
| 1372 | 1374 |
sock->info.lsa->local.addr.in6.sin6_family = AF_INET6; |
| 1373 | 1375 |
sock->info.lsa->local.addr.in6.sin6_addr = in6addr_any; |
| 1374 |
- success = true; |
|
| 1376 |
+ status = 0; |
|
| 1375 | 1377 |
} |
| 1376 |
- if (!success) |
|
| 1378 |
+ if (!status == 0) |
|
| 1377 | 1379 |
{
|
| 1378 | 1380 |
msg (M_FATAL, "getaddr6() failed for local \"%s\": %s", |
| 1379 | 1381 |
sock->local_host, |
| ... | ... |
@@ -1430,7 +1224,7 @@ resolve_remote (struct link_socket *sock, |
| 1430 | 1430 |
{
|
| 1431 | 1431 |
unsigned int flags = sf2gaf(GETADDR_RESOLVE|GETADDR_UPDATE_MANAGEMENT_STATE, sock->sockflags); |
| 1432 | 1432 |
int retry = 0; |
| 1433 |
- bool status = false; |
|
| 1433 |
+ int status = -1; |
|
| 1434 | 1434 |
|
| 1435 | 1435 |
if (sock->connection_profiles_defined && sock->resolve_retry_seconds == RESOLV_RETRY_INFINITE) |
| 1436 | 1436 |
{
|
| ... | ... |
@@ -1467,40 +1261,27 @@ resolve_remote (struct link_socket *sock, |
| 1467 | 1467 |
ASSERT (0); |
| 1468 | 1468 |
} |
| 1469 | 1469 |
|
| 1470 |
- switch(af) |
|
| 1471 |
- {
|
|
| 1472 |
- case AF_INET: |
|
| 1473 |
- sock->info.lsa->remote.addr.in4.sin_addr.s_addr = getaddr ( |
|
| 1474 |
- flags, |
|
| 1475 |
- sock->remote_host, |
|
| 1476 |
- retry, |
|
| 1477 |
- &status, |
|
| 1478 |
- signal_received); |
|
| 1479 |
- break; |
|
| 1480 |
- case AF_INET6: |
|
| 1481 |
- status = getaddr6 ( |
|
| 1482 |
- flags, |
|
| 1483 |
- sock->remote_host, |
|
| 1484 |
- retry, |
|
| 1485 |
- signal_received, |
|
| 1486 |
- NULL, |
|
| 1487 |
- &sock->info.lsa->remote.addr.in6); |
|
| 1488 |
- break; |
|
| 1489 |
- } |
|
| 1490 |
- |
|
| 1491 |
- dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", |
|
| 1492 |
- flags, |
|
| 1493 |
- phase, |
|
| 1494 |
- retry, |
|
| 1495 |
- signal_received ? *signal_received : -1, |
|
| 1496 |
- status); |
|
| 1497 |
- |
|
| 1470 |
+ struct addrinfo* ai; |
|
| 1471 |
+ /* Temporary fix, this need to be changed for dual stack */ |
|
| 1472 |
+ status = openvpn_getaddrinfo(flags, sock->remote_host, retry, |
|
| 1473 |
+ signal_received, af, &ai); |
|
| 1474 |
+ if(status == 0) {
|
|
| 1475 |
+ sock->info.lsa->remote.addr.in6 = *((struct sockaddr_in6*)(ai->ai_addr)); |
|
| 1476 |
+ freeaddrinfo(ai); |
|
| 1477 |
+ |
|
| 1478 |
+ dmsg (D_SOCKET_DEBUG, "RESOLVE_REMOTE flags=0x%04x phase=%d rrs=%d sig=%d status=%d", |
|
| 1479 |
+ flags, |
|
| 1480 |
+ phase, |
|
| 1481 |
+ retry, |
|
| 1482 |
+ signal_received ? *signal_received : -1, |
|
| 1483 |
+ status); |
|
| 1484 |
+ } |
|
| 1498 | 1485 |
if (signal_received) |
| 1499 | 1486 |
{
|
| 1500 | 1487 |
if (*signal_received) |
| 1501 | 1488 |
goto done; |
| 1502 | 1489 |
} |
| 1503 |
- if (!status) |
|
| 1490 |
+ if (status!=0) |
|
| 1504 | 1491 |
{
|
| 1505 | 1492 |
if (signal_received) |
| 1506 | 1493 |
*signal_received = SIGUSR1; |
| ... | ... |
@@ -467,11 +467,6 @@ bool unix_socket_get_peer_uid_gid (const socket_descriptor_t sd, int *uid, int * |
| 467 | 467 |
* DNS resolution |
| 468 | 468 |
*/ |
| 469 | 469 |
|
| 470 |
-struct resolve_list {
|
|
| 471 |
- int len; |
|
| 472 |
- in_addr_t data[16]; |
|
| 473 |
-}; |
|
| 474 |
- |
|
| 475 | 470 |
#define GETADDR_RESOLVE (1<<0) |
| 476 | 471 |
#define GETADDR_FATAL (1<<1) |
| 477 | 472 |
#define GETADDR_HOST_ORDER (1<<2) |
| ... | ... |
@@ -494,12 +489,12 @@ in_addr_t getaddr (unsigned int flags, |
| 494 | 494 |
bool *succeeded, |
| 495 | 495 |
volatile int *signal_received); |
| 496 | 496 |
|
| 497 |
-in_addr_t getaddr_multi (unsigned int flags, |
|
| 498 |
- const char *hostname, |
|
| 499 |
- int resolve_retry_seconds, |
|
| 500 |
- bool *succeeded, |
|
| 501 |
- volatile int *signal_received, |
|
| 502 |
- struct resolve_list *reslist); |
|
| 497 |
+int openvpn_getaddrinfo (unsigned int flags, |
|
| 498 |
+ const char *hostname, |
|
| 499 |
+ int resolve_retry_seconds, |
|
| 500 |
+ volatile int *signal_received, |
|
| 501 |
+ int ai_family, |
|
| 502 |
+ struct addrinfo **res); |
|
| 503 | 503 |
|
| 504 | 504 |
/* |
| 505 | 505 |
* Transport protocol naming and other details. |