Browse code

core: Updated check_local_addresses to use getifaddrs

Changed virtual socket code to use getifaddrs instead of gethostbyname as this avoids lookups against the hosts file, which causes incorrect results.

Rhys Hanrahan authored on 24/12/2021 07:41:20 • Daniel-Constantin Mierla committed on 07/01/2022 11:27:25
Showing 1 changed files
... ...
@@ -575,8 +575,8 @@ struct socket_info** get_sock_info_list(unsigned short proto)
575 575
  */
576 576
 static int check_local_addresses(struct socket_info* si)
577 577
 {
578
-	struct hostent* he;
579
-	struct utsname myname;
578
+	int match = 0;
579
+	struct ifaddrs *ifap, *ifa;
580 580
 
581 581
 	if (si == NULL) {
582 582
 		LM_ERR("Socket info is NULL. Returning no match.\n");
... ...
@@ -589,40 +589,41 @@ static int check_local_addresses(struct socket_info* si)
589 589
 		return 1;
590 590
 	}
591 591
 
592
-	if (uname(&myname) <0){
593
-		LM_ERR("Cannot determine hostname. Guessing a not local virtual IP.\n");
592
+	if (getifaddrs(&ifap) != 0) {
593
+		LM_ERR("getifaddrs failed. Assuming no match.\n");
594 594
 		return 0;
595 595
 	}
596
-	
597
-	//Should return a list of local IPs
598
-	he = _resolvehost(myname.nodename);
599
-	if (he == NULL) {
600
-		LM_ERR("Cannot get list of local IPs. Guessing not a local virtual IP.\n");
601
-		return 0;
602
-	}
603
-	char** paddrlist = he->h_addr_list;
604
-	int i = 0;
605
-	while (*paddrlist != NULL)
596
+
597
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next)
606 598
 	{
599
+		/* skip if no IP addr associated with the interface */
600
+		if (ifa->ifa_addr==0)
601
+			continue;
602
+#ifdef AF_PACKET
603
+		/* skip AF_PACKET addr family since it is of no use later on */
604
+		if (ifa->ifa_addr->sa_family == AF_PACKET)
605
+			continue;
606
+#endif
607 607
 		struct ip_addr local_addr;
608
-		hostent2ip_addr(&local_addr, he, i);
608
+		sockaddr2ip_addr(&local_addr, (struct sockaddr*)ifa->ifa_addr);
609 609
 
610 610
 		LM_DBG("Checking local address: %s\n", ip_addr2a(&local_addr));
611 611
 		if (ip_addr_cmp(&si->address, &local_addr)) {
612
-			LM_DBG("Found matching local IP for virtual socket: %s\n", ip_addr2a(&local_addr));
613
-			return 1;
612
+			match = 1;
613
+			LM_DBG("Found matching local IP %s for virtual socket %s\n", ip_addr2a(&local_addr), si->name.s);
614
+			break;
614 615
 		}
615
-
616
-		i++;
617
-		paddrlist++;
618 616
 	}
619
-
617
+	freeifaddrs(ifap);
620 618
 	//Default to not local if no match is found
621
-	LM_DBG("No matching local IP found.\n");
622
-	return 0;
619
+	if (!match) {
620
+		LM_DBG("No matching local IP found for socket %s.\n", si->name.s);
621
+		return 0;
622
+	} else {
623
+		return 1;
624
+	}
623 625
 }
624 626
 
625
-
626 627
 /* helper function for grep_sock_info
627 628
  * params:
628 629
  *  host - hostname to compare with