mirror of
https://github.com/kiwix/libkiwix.git
synced 2025-12-23 22:47:57 -05:00
Refactor getBestPublicIp for both protocols
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "common.h"
|
||||
#include "tools.h"
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
@@ -52,7 +52,7 @@ namespace kiwix
|
||||
void stop();
|
||||
|
||||
void setRoot(const std::string& root);
|
||||
void setAddress(const std::string& addr) { m_addr = addr; }
|
||||
void setAddress(const std::string& addr);
|
||||
void setPort(int port) { m_port = port; }
|
||||
void setNbThreads(int threads) { m_nbThreads = threads; }
|
||||
void setMultiZimSearchLimit(unsigned int limit) { m_multizimSearchLimit = limit; }
|
||||
@@ -72,7 +72,7 @@ namespace kiwix
|
||||
std::shared_ptr<Library> mp_library;
|
||||
std::shared_ptr<NameMapper> mp_nameMapper;
|
||||
std::string m_root = "";
|
||||
std::string m_addr = "";
|
||||
IpAddress m_addr;
|
||||
std::string m_indexTemplateString = "";
|
||||
int m_port = 80;
|
||||
int m_nbThreads = 1;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include "common.h"
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
@@ -32,6 +33,12 @@ struct IpAddress
|
||||
{
|
||||
std::string addr; // IPv4 address
|
||||
std::string addr6; // IPv6 address
|
||||
|
||||
bool empty() const { return addr.empty() && addr6.empty(); }
|
||||
bool empty4() const { return addr.empty(); }
|
||||
bool empty6() const { return addr6.empty(); }
|
||||
bool valid4(IpMode mode) const { return (mode == IpMode::ipv4 || mode == IpMode::all) && !this->empty4(); }
|
||||
bool valid6(IpMode mode) const { return (mode == IpMode::ipv6 || mode == IpMode::all) && !this->empty6(); }
|
||||
};
|
||||
|
||||
typedef std::pair<std::string, std::string> LangNameCodePair;
|
||||
@@ -216,7 +223,7 @@ std::map<std::string, std::string> getNetworkInterfaces();
|
||||
/** Provides the best IP address
|
||||
* This function provides the best IP address from the list given by getNetworkInterfacesIPv4Or6()
|
||||
*/
|
||||
std::string getBestPublicIp(bool ipv6);
|
||||
IpAddress getBestPublicIps(IpMode mode);
|
||||
|
||||
/** Provides the best IPv4 adddress
|
||||
* Equivalent to getBestPublicIp(false). Provided for backward compatibility
|
||||
|
||||
@@ -75,12 +75,25 @@ void Server::setRoot(const std::string& root)
|
||||
}
|
||||
}
|
||||
|
||||
void Server::setAddress(const std::string& addr)
|
||||
{
|
||||
if (addr.empty())
|
||||
return;
|
||||
|
||||
if (addr.find(':') != std::string::npos) { // IPv6
|
||||
for (char ch : addr) if (ch == '[' or ch == ']') ch = '\0'; // Clean possible brackets
|
||||
m_addr.addr6 = addr;
|
||||
} else {
|
||||
m_addr.addr = addr;
|
||||
}
|
||||
}
|
||||
|
||||
int Server::getPort() const
|
||||
{
|
||||
return mp_server->getPort();
|
||||
}
|
||||
|
||||
std::string Server::getAddress()
|
||||
IpAddress Server::getAddress() const
|
||||
{
|
||||
return mp_server->getAddress();
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ public:
|
||||
|
||||
InternalServer::InternalServer(LibraryPtr library,
|
||||
std::shared_ptr<NameMapper> nameMapper,
|
||||
std::string addr,
|
||||
IpAddress addr,
|
||||
int port,
|
||||
std::string root,
|
||||
int nbThreads,
|
||||
@@ -462,18 +462,21 @@ bool InternalServer::start() {
|
||||
sockAddr6.sin6_port = htons(m_port);
|
||||
|
||||
if (m_addr.empty()) {
|
||||
if (0 != INADDR_ANY) {
|
||||
sockAddr6.sin6_addr = in6addr_any;
|
||||
sockAddr4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
m_addr = kiwix::getBestPublicIp(m_ipMode == IpMode::ipv6 || m_ipMode == IpMode::all);
|
||||
sockAddr6.sin6_addr = in6addr_any;
|
||||
sockAddr4.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
m_addr = kiwix::getBestPublicIps(m_ipMode);
|
||||
} else {
|
||||
bool ipv6 = inet_pton(AF_INET6, m_addr.c_str(), &(sockAddr6.sin6_addr.s6_addr)) == 1;
|
||||
bool ipv4 = inet_pton(AF_INET, m_addr.c_str(), &(sockAddr4.sin_addr.s_addr)) == 1;
|
||||
bool ipv6 = inet_pton(AF_INET6, m_addr.addr6.c_str(), &(sockAddr6.sin6_addr.s6_addr)) == 1;
|
||||
bool ipv4 = inet_pton(AF_INET, m_addr.addr.c_str(), &(sockAddr4.sin_addr.s_addr)) == 1;
|
||||
|
||||
if (ipv6){
|
||||
m_ipMode = IpMode::all;
|
||||
m_ipMode = IpMode::ipv6;
|
||||
} else if (!ipv4) {
|
||||
std::cerr << "Ip address " << m_addr << " is not a valid ip address" << std::endl;
|
||||
if(!m_addr.addr.empty())
|
||||
std::cerr << "Ip address " << m_addr.addr << " is not a valid ip address" << std::endl;
|
||||
else
|
||||
std::cerr << "Ip address " << m_addr.addr6 << " is not a valid ip address" << std::endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ extern "C" {
|
||||
|
||||
#include "library.h"
|
||||
#include "name_mapper.h"
|
||||
#include "tools.h"
|
||||
|
||||
#include <zim/search.h>
|
||||
#include <zim/suggestion.h>
|
||||
@@ -94,7 +95,7 @@ class InternalServer {
|
||||
public:
|
||||
InternalServer(LibraryPtr library,
|
||||
std::shared_ptr<NameMapper> nameMapper,
|
||||
std::string addr,
|
||||
IpAddress addr,
|
||||
int port,
|
||||
std::string root,
|
||||
int nbThreads,
|
||||
@@ -166,7 +167,7 @@ class InternalServer {
|
||||
typedef ConcurrentCache<std::string, std::shared_ptr<LockableSuggestionSearcher>> SuggestionSearcherCache;
|
||||
|
||||
private: // data
|
||||
std::string m_addr;
|
||||
IpAddress m_addr;
|
||||
int m_port;
|
||||
std::string m_root; // URI-encoded
|
||||
std::string m_rootPrefixOfDecodedURL; // URI-decoded
|
||||
|
||||
@@ -211,39 +211,36 @@ std::map<std::string, std::string> getNetworkInterfaces() {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::string getBestPublicIp(bool ipv6) {
|
||||
IpAddress bestPublicIp = IpAddress{"127.0.0.1","::1"};
|
||||
IpAddress getBestPublicIps(IpMode mode) {
|
||||
IpAddress bestPublicIps = IpAddress{"127.0.0.1","::1"};
|
||||
std::map<std::string, IpAddress> interfaces = getNetworkInterfacesIPv4Or6();
|
||||
|
||||
#ifndef _WIN32
|
||||
const char* const prioritizedNames[] = { "eth0", "eth1", "wlan0", "wlan1", "en0", "en1" };
|
||||
for(auto name: prioritizedNames) {
|
||||
auto it=interfaces.find(name);
|
||||
if(it != interfaces.end() && !(ipv6 && (*it).second.addr6.empty())) {
|
||||
bestPublicIp = (*it).second;
|
||||
break;
|
||||
}
|
||||
const auto it = interfaces.find(name);
|
||||
if(it == interfaces.end()) continue;
|
||||
const IpAddress& interfaceIps = (*it).second;
|
||||
if(!bestPublicIps.empty4() && interfaceIps.valid4(mode)) bestPublicIps.addr = interfaceIps.addr;
|
||||
if(!bestPublicIps.empty6() && interfaceIps.valid6(mode)) bestPublicIps.addr6 = interfaceIps.addr6;
|
||||
}
|
||||
#endif
|
||||
|
||||
const char* const prefixes[] = { "192.168", "172.16.", "10.0" };
|
||||
for(auto prefix : prefixes){
|
||||
for(auto& itr : interfaces) {
|
||||
std::string interfaceIp(itr.second.addr);
|
||||
if (interfaceIp.find(prefix) == 0 && !(ipv6 && itr.second.addr6.empty())) {
|
||||
bestPublicIp = itr.second;
|
||||
break;
|
||||
}
|
||||
const IpAddress& interfaceIps = itr.second;
|
||||
if(!bestPublicIps.empty4() && interfaceIps.valid4(mode) && interfaceIps.addr.find(prefix) == 0) bestPublicIps.addr = interfaceIps.addr;
|
||||
if(!bestPublicIps.empty6() && interfaceIps.valid6(mode)) bestPublicIps.addr6 = interfaceIps.addr6;
|
||||
}
|
||||
}
|
||||
return ipv6 ? bestPublicIp.addr6 : bestPublicIp.addr;
|
||||
}
|
||||
|
||||
return bestPublicIps;
|
||||
}
|
||||
|
||||
std::string getBestPublicIp()
|
||||
{
|
||||
return getBestPublicIp(false);
|
||||
return getBestPublicIps(IpMode::ipv4).addr;
|
||||
}
|
||||
|
||||
} // namespace kiwix
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "../include/tools.h"
|
||||
#include "../src/tools/otherTools.h"
|
||||
#include "zim/suggestion_iterator.h"
|
||||
#include "../src/server/i18n_utils.h"
|
||||
@@ -252,11 +253,14 @@ TEST(networkTools, getNetworkInterfaces)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(networkTools, getBestPublicIp)
|
||||
TEST(networkTools, getBestPublicIps)
|
||||
{
|
||||
using kiwix::getBestPublicIps;
|
||||
using kiwix::getBestPublicIp;
|
||||
using kiwix::IpMode;
|
||||
|
||||
std::cout << "getBestPublicIp(true) " << getBestPublicIp(true) << std::endl;
|
||||
std::cout << "getBestPublicIp(false) " << getBestPublicIp(false) << std::endl;
|
||||
std::cout << "getBestPublicIp() " << getBestPublicIp() << std::endl;
|
||||
std::cout << "getBestPublicIps(true) : [" << getBestPublicIps(IpMode::ipv4).addr << ", " << getBestPublicIps(IpMode::ipv4).addr6 << "]" << std::endl;
|
||||
std::cout << "getBestPublicIps(false) : [" << getBestPublicIps(IpMode::ipv6).addr << ", " << getBestPublicIps(IpMode::ipv6).addr6 << "]" << std::endl;
|
||||
std::cout << "getBestPublicIps(false) : [" << getBestPublicIps(IpMode::all).addr << ", " << getBestPublicIps(IpMode::all).addr6 << "]" << std::endl;
|
||||
std::cout << "getBestPublicIp() : " << getBestPublicIp() << std::endl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user