From a8c2d46568889902df820ac65e045a1e78aa84d4 Mon Sep 17 00:00:00 2001 From: WeijieSun Date: Wed, 18 Jul 2018 14:27:50 +0800 Subject: [PATCH] rpc_address: fix site local address judgement & add docker address judgement (#140) --- include/dsn/tool-api/rpc_address.h | 2 ++ src/core/core/rpc_address.cpp | 38 +++++++++++++++++++++++------- src/core/tests/address.cpp | 20 ++++++++++++++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/include/dsn/tool-api/rpc_address.h b/include/dsn/tool-api/rpc_address.h index f01785950c..b0779458a3 100644 --- a/include/dsn/tool-api/rpc_address.h +++ b/include/dsn/tool-api/rpc_address.h @@ -53,6 +53,8 @@ class rpc_address { public: static const rpc_address s_invalid_address; + static bool is_docker_netcard(const char *netcard_interface, uint32_t ip_net); + static bool is_site_local_address(uint32_t ip_net); static uint32_t ipv4_from_host(const char *hostname); static uint32_t ipv4_from_network_interface(const char *network_interface); diff --git a/src/core/core/rpc_address.cpp b/src/core/core/rpc_address.cpp index d756bdf1be..009fa2cb27 100644 --- a/src/core/core/rpc_address.cpp +++ b/src/core/core/rpc_address.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -67,19 +68,30 @@ uint32_t rpc_address::ipv4_from_host(const char *name) return (uint32_t)ntohl(addr.sin_addr.s_addr); } -// if network_interface is "", then return the first -// site-local ipv4 address: 10.*.*.*, 172.16.*.*, 192.168.*.* +/*static*/ +bool rpc_address::is_site_local_address(uint32_t ip_net) +{ + uint32_t iphost = ntohl(ip_net); + return (iphost >= 0x0A000000 && iphost <= 0x0AFFFFFF) || // 10.0.0.0-10.255.255.255 + (iphost >= 0xAC100000 && iphost <= 0xAC1FFFFF) || // 172.16.0.0-172.31.255.255 + (iphost >= 0xC0A80000 && iphost <= 0xC0A8FFFF) || // 192.168.0.0-192.168.255.255 + false; +} + +/*static*/ +bool rpc_address::is_docker_netcard(const char *netcard_interface, uint32_t ip_net) +{ + if (dsn::string_view(netcard_interface).find("docker") != dsn::string_view::npos) + return true; + uint32_t iphost = ntohl(ip_net); + return iphost == 0xAC112A01; // 172.17.42.1 +} + /*static*/ uint32_t rpc_address::ipv4_from_network_interface(const char *network_interface) { uint32_t ret = 0; - static auto is_site_local = [&](uint32_t ip_net) { - const uint8_t *addr = reinterpret_cast(&ip_net); - return addr[0] == 10 || (addr[0] == 172 && addr[1] == 16) || - (addr[0] == 192 && addr[1] == 168); - }; - struct ifaddrs *ifa = nullptr; if (getifaddrs(&ifa) == 0) { struct ifaddrs *i = ifa; @@ -88,9 +100,12 @@ uint32_t rpc_address::ipv4_from_network_interface(const char *network_interface) i->ifa_addr->sa_family == AF_INET) { uint32_t ip_val = ((struct sockaddr_in *)i->ifa_addr)->sin_addr.s_addr; if (strcmp(i->ifa_name, network_interface) == 0 || - (network_interface[0] == '\0' && is_site_local(ip_val))) { + (network_interface[0] == '\0' && !is_docker_netcard(i->ifa_name, ip_val) && + is_site_local_address(ip_val))) { ret = (uint32_t)ntohl(ip_val); break; + } else { + ddebug("skip interface(%s), address(%08X)", i->ifa_name, ip_val); } } i = i->ifa_next; @@ -99,6 +114,11 @@ uint32_t rpc_address::ipv4_from_network_interface(const char *network_interface) if (i == nullptr) { derror("get local ip from network interfaces failed, network_interface = %s", network_interface); + } else { + ddebug("get ip address from network interface(%s), addr(%08X), input interface(%s)", + i->ifa_name, + ret, + network_interface); } if (ifa != nullptr) { diff --git a/src/core/tests/address.cpp b/src/core/tests/address.cpp index 3961c0481b..31e43e7bf4 100644 --- a/src/core/tests/address.cpp +++ b/src/core/tests/address.cpp @@ -66,6 +66,26 @@ TEST(core, rpc_address_ipv4_from_network_interface) rpc_address::ipv4_from_network_interface("not_exist_interface")); } +TEST(core, is_site_local_address) +{ + ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(1, 2, 3, 4)))); + ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(10, 235, 111, 111)))); + ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(171, 11, 11, 11)))); + ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(172, 16, 2, 2)))); + ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(172, 31, 234, 255)))); + ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(191, 128, 1, 2)))); + ASSERT_TRUE(rpc_address::is_site_local_address(htonl(host_ipv4(192, 168, 3, 45)))); + ASSERT_FALSE(rpc_address::is_site_local_address(htonl(host_ipv4(201, 201, 201, 201)))); +} + +TEST(core, is_docker_netcard) +{ + ASSERT_TRUE(rpc_address::is_docker_netcard("docker0", htonl(host_ipv4(1, 2, 3, 4)))); + ASSERT_TRUE(rpc_address::is_docker_netcard("10docker5", htonl(host_ipv4(4, 5, 6, 8)))); + ASSERT_FALSE(rpc_address::is_docker_netcard("eth0", htonl(host_ipv4(192, 168, 123, 123)))); + ASSERT_TRUE(rpc_address::is_docker_netcard("eth0", htonl(host_ipv4(172, 17, 42, 1)))); +} + TEST(core, rpc_address_to_string) { {