Skip to content

Commit

Permalink
Refactor getBestPublicIp for all valid ips
Browse files Browse the repository at this point in the history
  • Loading branch information
sgourdas committed Sep 12, 2024
1 parent f5c91cc commit b9375ea
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 37 deletions.
7 changes: 4 additions & 3 deletions include/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#define KIWIX_SERVER_H

#include <string>
#include <vector>
#include <memory>
#include "common.h"

Expand Down Expand Up @@ -52,7 +53,7 @@ namespace kiwix
void stop();

void setRoot(const std::string& root);
void setAddress(const std::string& addr) { m_addr = addr; }
void setAddress(const std::vector<std::string>& addr) { m_addr = addr; }
void setPort(int port) { m_port = port; }
void setNbThreads(int threads) { m_nbThreads = threads; }
void setMultiZimSearchLimit(unsigned int limit) { m_multizimSearchLimit = limit; }
Expand All @@ -65,14 +66,14 @@ namespace kiwix
{ m_blockExternalLinks = blockExternalLinks; }
void setIpMode(IpMode mode) { m_ipMode = mode; }
int getPort();
std::string getAddress();
std::vector<std::string> getAddresses();
IpMode getIpMode() const;

protected:
std::shared_ptr<Library> mp_library;
std::shared_ptr<NameMapper> mp_nameMapper;
std::string m_root = "";
std::string m_addr = "";
std::vector<std::string> m_addr;
std::string m_indexTemplateString = "";
int m_port = 80;
int m_nbThreads = 1;
Expand Down
5 changes: 3 additions & 2 deletions include/tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <vector>
#include <map>
#include <cstdint>
#include "common.h"

namespace kiwix
{
Expand Down Expand Up @@ -216,13 +217,13 @@ 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);
std::vector<std::string> getBestPublicIps(IpMode mode);

/** Provides the best IPv4 adddress
* Equivalent to getBestPublicIp(false). Provided for backward compatibility
* with libkiwix v13.1.0.
*/
std::string getBestPublicIp();
std::vector<std::string> getBestPublicIps();

/** Converts file size to human readable format.
*
Expand Down
4 changes: 2 additions & 2 deletions src/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ int Server::getPort()
return mp_server->getPort();
}

std::string Server::getAddress()
std::vector<std::string> Server::getAddresses()

Check warning on line 83 in src/server.cpp

View check run for this annotation

Codecov / codecov/patch

src/server.cpp#L83

Added line #L83 was not covered by tests
{
return mp_server->getAddress();
return mp_server->getAddresses();

Check warning on line 85 in src/server.cpp

View check run for this annotation

Codecov / codecov/patch

src/server.cpp#L85

Added line #L85 was not covered by tests
}

IpMode Server::getIpMode() const
Expand Down
15 changes: 8 additions & 7 deletions src/server/internalServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ class InternalServer::CustomizedResources : public std::map<std::string, Customi

InternalServer::InternalServer(LibraryPtr library,
std::shared_ptr<NameMapper> nameMapper,
std::string addr,
std::vector<std::string> addr,
int port,
std::string root,
int nbThreads,
Expand All @@ -419,7 +419,7 @@ InternalServer::InternalServer(LibraryPtr library,
IpMode ipMode,
std::string indexTemplateString,
int ipConnectionLimit) :
m_addr(addr),
m_addr{addr},
m_port(port),
m_root(normalizeRootUrl(root)),
m_rootPrefixOfDecodedURL(m_root),
Expand Down Expand Up @@ -462,18 +462,19 @@ bool InternalServer::start() {
sockAddr6.sin6_port = htons(m_port);

if (m_addr.empty()) {
if (0 != INADDR_ANY) {
if (0 != INADDR_ANY) { // what is the purpose of this? INADDR_ANY is always 0. Refer: http://www.castaglia.org/proftpd/doc/devel-guide/src/include/inet.h.html
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);
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;
// TODO: Needs more work
bool ipv6 = inet_pton(AF_INET6, m_addr[0].c_str(), &(sockAddr6.sin6_addr.s6_addr)) == 1;
bool ipv4 = inet_pton(AF_INET, m_addr[0].c_str(), &(sockAddr4.sin_addr.s_addr)) == 1;
if (ipv6){
m_ipMode = IpMode::all;
} else if (!ipv4) {
std::cerr << "Ip address " << m_addr << " is not a valid ip address" << std::endl;
std::cerr << "Ip address " << m_addr[0] << " is not a valid ip address" << std::endl;
return false;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/server/internalServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class InternalServer {
public:
InternalServer(LibraryPtr library,
std::shared_ptr<NameMapper> nameMapper,
std::string addr,
std::vector<std::string> addr,
int port,
std::string root,
int nbThreads,
Expand All @@ -117,7 +117,7 @@ class InternalServer {
void** cont_cls);
bool start();
void stop();
std::string getAddress() { return m_addr; }
std::vector<std::string> getAddresses() { return m_addr; }

Check warning on line 120 in src/server/internalServer.h

View check run for this annotation

Codecov / codecov/patch

src/server/internalServer.h#L120

Added line #L120 was not covered by tests
int getPort() { return m_port; }
IpMode getIpMode() const { return m_ipMode; }

Expand Down Expand Up @@ -166,7 +166,7 @@ class InternalServer {
typedef ConcurrentCache<std::string, std::shared_ptr<LockableSuggestionSearcher>> SuggestionSearcherCache;

private: // data
std::string m_addr;
std::vector<std::string> m_addr;
int m_port;
std::string m_root; // URI-encoded
std::string m_rootPrefixOfDecodedURL; // URI-decoded
Expand Down
31 changes: 17 additions & 14 deletions src/tools/networkTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,39 +212,42 @@ std::map<std::string, std::string> getNetworkInterfaces() {
}


std::string getBestPublicIp(bool ipv6) {
IpAddress bestPublicIp = IpAddress{"127.0.0.1","::1"};
std::vector<std::string> getBestPublicIps(IpMode mode) {
std::string bestIpv4, bestIpv6;
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;
if (it != interfaces.end()) {
if (it->second.addr.find(':') == std::string::npos) bestIpv4 = it->second.addr;
else bestIpv6 = it->second.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;
}
if (itr.second.addr.find(':') == std::string::npos && itr.second.addr.find(prefix) == 0)
bestIpv4 = itr.second.addr;
if (itr.second.addr6.find(':') != std::string::npos)
bestIpv6 = itr.second.addr6;
}
}
return ipv6 ? bestPublicIp.addr6 : bestPublicIp.addr;
}

std::vector<std::string> bestIps;
if (mode == IpMode::ipv4 || mode == IpMode::all) bestIps.push_back(bestIpv4);
if (mode == IpMode::ipv6 || mode == IpMode::all) bestIps.push_back(bestIpv6);

return bestIps;
}

std::string getBestPublicIp()
std::vector<std::string> getBestPublicIps()

Check warning on line 248 in src/tools/networkTools.cpp

View check run for this annotation

Codecov / codecov/patch

src/tools/networkTools.cpp#L248

Added line #L248 was not covered by tests
{
return getBestPublicIp(false);
return getBestPublicIps(IpMode::ipv4);

Check warning on line 250 in src/tools/networkTools.cpp

View check run for this annotation

Codecov / codecov/patch

src/tools/networkTools.cpp#L250

Added line #L250 was not covered by tests
}

} // namespace kiwix
22 changes: 17 additions & 5 deletions test/otherTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/

#include "gtest/gtest.h"
#include "../include/common.h"
#include "../src/tools/otherTools.h"
#include "zim/suggestion_iterator.h"
#include "../src/server/i18n_utils.h"
Expand Down Expand Up @@ -252,11 +253,22 @@ TEST(networkTools, getNetworkInterfaces)
}
}

TEST(networkTools, getBestPublicIp)
TEST(networkTools, getBestPublicIps)
{
using kiwix::getBestPublicIp;
using kiwix::getBestPublicIps;

std::cout << "getBestPublicIp(true) " << getBestPublicIp(true) << std::endl;
std::cout << "getBestPublicIp(false) " << getBestPublicIp(false) << std::endl;
std::cout << "getBestPublicIp() " << getBestPublicIp() << std::endl;
std::vector<std::string> allIps = getBestPublicIps(kiwix::IpMode::all);
std::cout << "getBestPublicIps(IpMode::all): [ ";
for (const std::string ip : allIps) std::cout << ip << " ";
std::cout << "]" << std::endl;

std::vector<std::string> ipv4Ips = getBestPublicIps(kiwix::IpMode::ipv4);
std::cout << "getBestPublicIps(IpMode::ipv4): [ ";
for (const std::string ip : ipv4Ips) std::cout << ip << " ";
std::cout << "]" << std::endl;

std::vector<std::string> ipv6Ips = getBestPublicIps(kiwix::IpMode::ipv6);
std::cout << "getBestPublicIps(IpMode::ipv6): [ ";
for (const std::string ip : ipv6Ips) std::cout << ip << " ";
std::cout << "]" << std::endl;
}
2 changes: 1 addition & 1 deletion test/server_testing_tools.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ void ZimFileServer::run(int serverPort, std::string indexTemplateString)
}
server.reset(new kiwix::Server(library, nameMapper));
server->setRoot(cfg.root);
server->setAddress(address);
server->setAddress({address});
server->setPort(serverPort);
server->setNbThreads(2);
server->setVerbose(false);
Expand Down

0 comments on commit b9375ea

Please sign in to comment.