Browse code

Merge getaddr_multi and getaddr6 into one function

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]

Arne Schwabe authored on 2012/08/07 19:03:57
Showing 3 changed files
... ...
@@ -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.