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 17, 2023
1 parent 7214f6a commit fe0a460
Showing 1 changed file with 38 additions and 3 deletions.
41 changes: 38 additions & 3 deletions src/cluster/cluster.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
#include <cstring>
#include <fstream>
#include <memory>

#include <sys/types.h>
#include <ifaddrs.h>
#include <arpa/inet.h>
#include "commands/commander.h"
#include "fmt/format.h"
#include "parse_util.h"
Expand Down Expand Up @@ -157,7 +159,34 @@ 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> ipAddresses;

struct ifaddrs *ifAddrStruct = NULL;
struct ifaddrs *ifa = NULL;
void *tmpAddrPtr = NULL;

getifaddrs(&ifAddrStruct);

for (ifa = ifAddrStruct; ifa != NULL; 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
tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
char addressBuffer[INET_ADDRSTRLEN];
inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
std::string ipAddress(addressBuffer);
ipAddresses.push_back(move(ipAddress));
}
}

if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct);

return ipAddresses;
}
// cluster setnodes $all_nodes_info $version $force
// one line of $all_nodes: $node_id $host $port $role $master_node_id $slot_range
Status Cluster::SetClusterNodes(const std::string &nodes_str, int64_t version, bool force) {
Expand Down Expand Up @@ -201,14 +230,20 @@ Status Cluster::SetClusterNodes(const std::string &nodes_str, int64_t version, b
}

// Find myself
// Get all local IP addresses.
std::vector<std::string> localhost = getLocalIPAddresses();
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;
//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(binds_.begin(), binds_.end(), n.second->host) != binds_.end() ||
std::find(localhost.begin(), localhost.end(), n.second->host) != localhost.end())) {
myid_ = n.first;
break;
}
}
}

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

0 comments on commit fe0a460

Please sign in to comment.