Skip to content

Commit

Permalink
feat: implement local IP address retrieval function
Browse files Browse the repository at this point in the history
fixes: #1381

- Add a function to get all local IP addresses

Signed-off-by: Zewen Xu <zevin9427@gmail.com>
  • Loading branch information
zevin02 committed Apr 18, 2023
1 parent 7214f6a commit bfceb58
Showing 1 changed file with 51 additions and 5 deletions.
56 changes: 51 additions & 5 deletions src/cluster/cluster.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@

#include "cluster.h"

#include <arpa/inet.h>
#include <config/config_util.h>
#include <ifaddrs.h>
#include <sys/types.h>

#include <algorithm>
#include <cstring>
#include <fstream>
#include <memory>
Expand Down Expand Up @@ -157,6 +159,33 @@ Status Cluster::SetSlot(int slot, const std::string &node_id, int64_t new_versio

return Status::OK();
}
// Get all local IP addresses.
std::vector<std::string> GetLocalIpAddresses() {
std::vector<std::string> ip_addresses;

struct ifaddrs *if_addr_struct = nullptr;
struct ifaddrs *ifa = nullptr;
void *tmp_addr_ptr = nullptr;

getifaddrs(&if_addr_struct);

for (ifa = if_addr_struct; ifa; ifa = ifa->ifa_next) {
if (!ifa->ifa_addr) {
continue;
}
if (ifa->ifa_addr->sa_family == AF_INET) {
// check it is IP4 and not a loopback address
tmp_addr_ptr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
char address_buffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmp_addr_ptr, address_buffer, INET_ADDRSTRLEN);
ip_addresses.emplace_back(std::string(address_buffer));
}
}

if (if_addr_struct) freeifaddrs(if_addr_struct);

return ip_addresses;
}

// cluster setnodes $all_nodes_info $version $force
// one line of $all_nodes: $node_id $host $port $role $master_node_id $slot_range
Expand Down Expand Up @@ -199,16 +228,33 @@ Status Cluster::SetClusterNodes(const std::string &nodes_str, int64_t version, b
size_++;
}
}
// Used to check if listening on "0.0.0.0“
bool is_listen_all_ip = false;

std::unique_ptr<std::vector<std::string>> local_hosts(nullptr);
if (std::find(binds_.begin(), binds_.end(), "0.0.0.0") != binds_.end()) {
is_listen_all_ip = true;
local_hosts = std::make_unique<std::vector<std::string>>(GetLocalIpAddresses());
}

// Find myself
if (myid_.empty() || force) {
for (auto &n : nodes_) {
if (n.second->port == port_ && std::find(binds_.begin(), binds_.end(), n.second->host) != binds_.end()) {
myid_ = n.first;
break;
if (is_listen_all_ip) {
// If the IP being listened on is 0.0.0.0, we need to compare the node's IP address with all local IP addresses.
if (n.second->port == port_ &&
std::find(local_hosts->begin(), local_hosts->end(), n.second->host) != local_hosts->end()) {
myid_ = n.first;
break;
}
} else {
if (n.second->port == port_ && std::find(binds_.begin(), binds_.end(), n.second->host) != binds_.end()) {
myid_ = n.first;
break;
}
}
}
}

myself_ = nullptr;
if (!myid_.empty() && nodes_.find(myid_) != nodes_.end()) {
myself_ = nodes_[myid_];
Expand Down

0 comments on commit bfceb58

Please sign in to comment.