Skip to content

Commit

Permalink
rpc_address: fix site local address judgement & add docker address ju…
Browse files Browse the repository at this point in the history
…dgement (#140)
  • Loading branch information
shengofsun committed Jul 18, 2018
1 parent d4fb099 commit a8c2d46
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
2 changes: 2 additions & 0 deletions include/dsn/tool-api/rpc_address.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
38 changes: 29 additions & 9 deletions src/core/core/rpc_address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <arpa/inet.h>

#include <dsn/utility/ports.h>
#include <dsn/utility/string_view.h>
#include <dsn/utility/fixed_size_buffer_pool.h>

#include <dsn/c/api_utilities.h>
Expand Down Expand Up @@ -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<const uint8_t *>(&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;
Expand All @@ -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;
Expand All @@ -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) {
Expand Down
20 changes: 20 additions & 0 deletions src/core/tests/address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
{
Expand Down

0 comments on commit a8c2d46

Please sign in to comment.