Skip to content

Commit

Permalink
Merge pull request #139 from ggtakec/update/fix_and_ipv6
Browse files Browse the repository at this point in the history
Improved IPv6 support and support for launch host domains
  • Loading branch information
ggtakec authored Nov 12, 2024
2 parents 47b2551 + 42d81c0 commit 35079ce
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 12 deletions.
2 changes: 1 addition & 1 deletion buildutils/APKBUILD.templ.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ arch="x86_64"
license="MIT"

depends="
procps
k2hash
"
depends_dev="
Expand All @@ -66,7 +67,6 @@ makedepends="
groff
util-linux-misc
musl-locales
procps
yaml-dev
@ALP_DEPS_TLS_DEV_PKG@
"
Expand Down
11 changes: 10 additions & 1 deletion lib/chmconf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2302,10 +2302,13 @@ bool CHMIniConf::LoadConfiguration(CHMCFGINFO& chmcfginfo) const
for(strlst_t::const_iterator svrnodeiter = expand_svrnodes.begin(); svrnodeiter != expand_svrnodes.end(); ++svrnodeiter){
strlst_t nodehost_list;
nodehost_list.clear();
nodehost_list.push_back(*svrnodeiter);

if(!ChmNetDb::Get()->GetAllHostList(svrnodeiter->c_str(), nodehost_list, true)){
// if not found hostname/IP addresses for server node, add the original hostname
nodehost_list.push_back(*svrnodeiter);
}

// set first hostname
svrnode.name = nodehost_list.front();
chmcfginfo.servers.push_back(svrnode);
Expand All @@ -2316,7 +2319,7 @@ bool CHMIniConf::LoadConfiguration(CHMCFGINFO& chmcfginfo) const
for(strlst_t::const_iterator nodehostiter = nodehost_list.begin(); nodehost_list.end() != nodehostiter; ++nodehostiter){
for(strlst_t::const_iterator liter = localhost_list.begin(); localhost_list.end() != liter; ++liter){
if(0 == strcasecmp(nodehostiter->c_str(), liter->c_str())){
MSG_CHMPRN("Found self host name(%s) in server node list.", nodehostiter->c_str());
MSG_CHMPRN("Found self host name(%s) in server node list.", nodehostiter->c_str()); // FOUND
ccvals.server_mode_by_comp = true;
is_break_loop = true;
break;
Expand All @@ -2326,6 +2329,12 @@ bool CHMIniConf::LoadConfiguration(CHMCFGINFO& chmcfginfo) const
break;
}
}
// Set self server node name in configuration to localhostname cache.
if(!ChmNetDb::Get()->ReplaceFullLocalName(svrnode.name.c_str())){
ERR_CHMPRN("Failed to replace full local hostname(%s) in cache, but continue...", svrnode.name.c_str());
}else{
MSG_CHMPRN("Replaced full local hostname(%s) in cache.", svrnode.name.c_str());
}
}
}
}
Expand Down
78 changes: 70 additions & 8 deletions lib/chmnetdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,19 @@ const time_t ChmNetDb::ALIVE_TIME;
int ChmNetDb::lockval = FLCK_NOSHARED_MUTEX_VAL_UNLOCKED;
const size_t ChmNetDb::PORT_NMATCH;

// [NOTE]
// If INET6 (IPv6) does not exist in the local host interface,
// INET6(IPv6) name resolution will not be performed.
//
// When executing INET6 resolve on a HOST (Container) that does
// not have IPv6 in its interface, it may be forced to wait
// until a timeout occurs.
// This occurs with ALPINE's INET6 and takes a very long time.
// Therefore, we perform inspection from INET4 and also use a
// flag to bypass the allocation of INET6.
//
bool ChmNetDb::inet6 = true; // default true

//---------------------------------------------------------
// Class methods
//---------------------------------------------------------
Expand Down Expand Up @@ -392,26 +405,31 @@ bool ChmNetDb::GetLocalHostList(strlst_t& hostinfo, bool remove_localhost)
return true;
}

bool ChmNetDb::GetAnyAddrInfo(short port, struct addrinfo** ppaddrinfo, bool is_inetv6)
bool ChmNetDb::GetAnyAddrInfo(short port, struct addrinfo** ppaddrinfo, bool is_inet6)
{
if(!ppaddrinfo){
ERR_CHMPRN("Parameter is wrong.");
return false;
}
*ppaddrinfo = NULL;

if(is_inet6 && !ChmNetDb::inet6){
// Not processing for INET6
return false;
}

struct addrinfo hints;
int result;
string strPort = to_string(port);

memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_PASSIVE;
hints.ai_family = is_inetv6 ? AF_INET6 : AF_INET;
hints.ai_family = is_inet6 ? AF_INET6 : AF_INET;
hints.ai_socktype = SOCK_STREAM;

// addrinfo
if(0 != (result = getaddrinfo(NULL, strPort.c_str(), &hints, ppaddrinfo)) || !(*ppaddrinfo)){
MSG_CHMPRN("Could not get %s addrinfo for %s, errno=%d.", (is_inetv6 ? "IN6ADDR_ANY_INIT" : "INADDR_ANY"), (is_inetv6 ? "AF_INET6" : "AF_INET"), result);
MSG_CHMPRN("Could not get %s addrinfo for %s, errno=%d.", (is_inet6 ? "IN6ADDR_ANY_INIT" : "INADDR_ANY"), (is_inet6 ? "AF_INET6" : "AF_INET"), result);
return false;
}
return true;
Expand Down Expand Up @@ -788,6 +806,7 @@ bool ChmNetDb::CheckHostnameInResolv(const char* hostname, bool is_default_domai
return false;
}
MSG_CHMPRN("Found hostname(%s) %s in resolv(DNS).", hostname, is_default_domain ? "with default domain" : "strictly");

return true;
}

Expand Down Expand Up @@ -829,6 +848,7 @@ bool ChmNetDb::InitializeLocalHostInfo(void)
if(!InitializeLocalHostIpAddresses()){
WAN_CHMPRN("Obtaining the IP address of the local interfaces may have failed, but continue...");
}

if(!InitializeLocalHostnames()){
WAN_CHMPRN("Obtaining the local hostnames may have failed, but continue...");
}
Expand All @@ -839,6 +859,7 @@ bool ChmNetDb::InitializeLocalHostIpAddresses()
{
struct ifaddrs* ifaddr;
char ipaddr[NI_MAXHOST];
bool found_inet6 = false;

// get ip addresses on interface
memset(&ipaddr, 0, sizeof(ipaddr));
Expand All @@ -852,6 +873,11 @@ bool ChmNetDb::InitializeLocalHostIpAddresses()
if(NULL == tmp_ifaddr->ifa_addr){
continue;
}
if(AF_INET6 == tmp_ifaddr->ifa_addr->sa_family){
// found INET6(IPv6 interface)
found_inet6 = true;
}

if(AF_INET == tmp_ifaddr->ifa_addr->sa_family || AF_INET6 == tmp_ifaddr->ifa_addr->sa_family){
memset(ipaddr, 0, sizeof(ipaddr));
socklen_t salen = (AF_INET == tmp_ifaddr->ifa_addr->sa_family) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
Expand Down Expand Up @@ -892,6 +918,13 @@ bool ChmNetDb::InitializeLocalHostIpAddresses()
}
freeifaddrs(ifaddr);

// Check & set INET6 flag
if(found_inet6){
ChmNetDb::inet6 = true;
}else{
ChmNetDb::inet6 = false;
}

return true;
}

Expand Down Expand Up @@ -919,6 +952,9 @@ bool ChmNetDb::InitializeLocalHostnames()
MSG_CHMPRN("Allowed hostname(%s) is full local hostname", buf.nodename);
fulllocalname = buf.nodename;

// add localnames
AddUniqueStringToList(fulllocalname, localnames, false);

// add cache without ip addresses
HostnammeAddCache(fulllocalname, string(""), true);
}else{
Expand All @@ -930,7 +966,7 @@ bool ChmNetDb::InitializeLocalHostnames()
// local hostname -> addrinfo
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
hints.ai_family = ChmNetDb::inet6 ? AF_UNSPEC : AF_INET;
hints.ai_socktype = SOCK_STREAM;
if(0 != (result = getaddrinfo(buf.nodename, NULL, &hints, &res_info)) || !res_info){ // port is NULL
MSG_CHMPRN("Could not get addrinfo from %s, errno=%d.", buf.nodename, result);
Expand All @@ -955,7 +991,6 @@ bool ChmNetDb::InitializeLocalHostnames()
}else{
is_same_nodename = true;
}

if(is_same_nodename && fulllocalname.empty()){
MSG_CHMPRN("Found another local hostname : %s -> But not add to localnames array", hostname);
}else{
Expand All @@ -968,7 +1003,6 @@ bool ChmNetDb::InitializeLocalHostnames()
memset(&ipaddr, 0, sizeof(ipaddr));
if(0 == getnameinfo(tmpaddrinfo->ai_addr, tmpaddrinfo->ai_addrlen, ipaddr, sizeof(ipaddr), NULL, 0, NI_NUMERICHOST)){
HostnammeAddCache(string(hostname), string(ipaddr), true);

if(is_same_nodename && !fulllocalname.empty()){
HostnammeAddCache(fulllocalname, string(ipaddr), true);
}
Expand Down Expand Up @@ -1297,7 +1331,7 @@ bool ChmNetDb::GetHostAddressInfo(const char* target, CHMNDBCACHE& data)
// target -> addrinfo
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
hints.ai_family = ChmNetDb::inet6 ? AF_UNSPEC : AF_INET;
hints.ai_socktype = SOCK_STREAM;
if(0 != getaddrinfo(target, NULL, &hints, &res_info) || !res_info){ // port is NULL
return false;
Expand Down Expand Up @@ -1424,7 +1458,7 @@ bool ChmNetDb::GetAddrInfoList(const char* target, short port, addrinfolist_t& i
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_flags = AI_CANONNAME;
hints.ai_family = AF_UNSPEC;
hints.ai_family = ChmNetDb::inet6 ? AF_UNSPEC : AF_INET;
hints.ai_socktype = SOCK_STREAM;

// ip addresses
Expand Down Expand Up @@ -1486,6 +1520,34 @@ bool ChmNetDb::GetHostnameList(const char* target, strlst_t& hostnames, bool is_
return true;
}

bool ChmNetDb::ReplaceFullLocalName(const char* localneme)
{
if(CHMEMPTYSTR(localneme)){
ERR_CHMPRN("Parameter is wrong.");
return false;
}
if(0 == strcmp(fulllocalname.c_str(), localneme)){
MSG_CHMPRN("Already set fulllocalname(%s).", localneme);
return true;
}

// overwrite fulllocalname
fulllocalname = localneme;

// erase same name in localnames list
for(strlst_t::const_iterator iter = localnames.begin(); localnames.end() != iter; ++iter){
if((*iter) == fulllocalname){
localnames.erase(iter);
break;
}
}

// add name to front of localnames list
localnames.push_front(fulllocalname);

return true;
}

// {NOTE]
// If the same hostname as localhost is detected, add full local hostname to the beginning.
// (If it exists in the middle of the list, it moves to the top)
Expand Down
4 changes: 3 additions & 1 deletion lib/chmnetdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ChmNetDb
static const time_t ALIVE_TIME = 60; // default 60s
static int lockval; // like mutex
static const size_t PORT_NMATCH = 5; // maximum 3 matches + 2(reserve)
static bool inet6; // inet6 is allowed

chmndbmap_t cachemap;
time_t timeout; // 0 means no timeout
Expand Down Expand Up @@ -91,7 +92,7 @@ class ChmNetDb
static bool GetLocalHostname(std::string& hostname);
static bool GetLocalHostnameList(strlst_t& hostnames);
static bool GetLocalHostList(strlst_t& hostinfo, bool remove_localhost = false);
static bool GetAnyAddrInfo(short port, struct addrinfo** ppaddrinfo, bool is_inetv6);
static bool GetAnyAddrInfo(short port, struct addrinfo** ppaddrinfo, bool is_inet6);
static bool CvtAddrInfoToIpAddress(struct sockaddr_storage* info, socklen_t infolen, std::string& stripaddress);
static bool CvtSockToLocalPort(int sock, short& port);
static bool CvtSockToPeerPort(int sock, short& port);
Expand All @@ -109,6 +110,7 @@ class ChmNetDb
bool GetHostnameList(const char* target, strlst_t& hostnames, bool is_cvt_localhost);
bool GetIpAddressString(const char* target, std::string& ipaddress, bool is_cvt_localhost);
bool GetIpAddressStringList(const char* target, strlst_t& ipaddrs, bool is_cvt_localhost);
bool ReplaceFullLocalName(const char* localneme);
bool GetAllHostList(const char* target, strlst_t& expandlist, bool is_cvt_localhost);
};

Expand Down
2 changes: 1 addition & 1 deletion lib/chmstructure.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ class structure_lap
st_ptr_type GetAbsPtr(void) const { return pAbsPtr; }
st_ptr_type GetRelPtr(void) const { return CHM_REL(pShmBase, pAbsPtr, st_ptr_type); }

virtual void Reset(st_ptr_type ptr, const void* shmbase, bool is_abs = true);
void Reset(st_ptr_type ptr, const void* shmbase, bool is_abs = true);
virtual bool Initialize(void);
virtual bool Dump(std::stringstream& sstream, const char* spacer) const;
virtual bool Clear(void);
Expand Down
8 changes: 8 additions & 0 deletions tests/chmpxlinetool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6904,6 +6904,14 @@ int main(int argc, char** argv)
// Initialize map
HostnameMap::Initialize();

// Initialize ChmNetDb
//
// [NOTE]
// We can initialize the ChmNetDb singleton by calling ChmNetDb::Get().
// Initialization allows to configure INET6(Ipv6) in advance.
//
ChmNetDb::Get();

//----------------------
// initialize nodes information
//----------------------
Expand Down

0 comments on commit 35079ce

Please sign in to comment.