handle ip modes & add compilation flags for windows build

This commit is contained in:
Aryan Arora 2024-04-24 15:41:40 +05:30 committed by Kelson
parent a6cf161341
commit b7eadf95bf
8 changed files with 44 additions and 57 deletions

View File

@ -16,6 +16,7 @@
namespace kiwix { namespace kiwix {
enum class IpMode { ipv4, ipv6, all };
typedef zim::size_type size_type; typedef zim::size_type size_type;
typedef zim::offset_type offset_type; typedef zim::offset_type offset_type;

View File

@ -22,6 +22,7 @@
#include <string> #include <string>
#include <memory> #include <memory>
#include "common.h"
namespace kiwix namespace kiwix
{ {
@ -62,10 +63,10 @@ namespace kiwix
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; } { m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
void setBlockExternalLinks(bool blockExternalLinks) void setBlockExternalLinks(bool blockExternalLinks)
{ m_blockExternalLinks = blockExternalLinks; } { m_blockExternalLinks = blockExternalLinks; }
void setIPv6(bool ipv6) { m_ipv6 = ipv6; } void setIpMode(IpMode mode) { m_ipMode = mode; }
int getPort(); int getPort();
std::string getAddress(); std::string getAddress();
bool isAddressIPv6(); IpMode getIpMode() const;
protected: protected:
std::shared_ptr<Library> mp_library; std::shared_ptr<Library> mp_library;
@ -80,7 +81,7 @@ namespace kiwix
bool m_withTaskbar = true; bool m_withTaskbar = true;
bool m_withLibraryButton = true; bool m_withLibraryButton = true;
bool m_blockExternalLinks = false; bool m_blockExternalLinks = false;
bool m_ipv6 = false; IpMode m_ipMode = IpMode::ipv4;
int m_ipConnectionLimit = 0; int m_ipConnectionLimit = 0;
std::unique_ptr<InternalServer> mp_server; std::unique_ptr<InternalServer> mp_server;
}; };

View File

@ -25,12 +25,12 @@
#include <map> #include <map>
#include <cstdint> #include <cstdint>
struct ip_addr{ namespace kiwix {
struct IpAddress{
std::string addr; std::string addr;
std::string addr6; std::string addr6;
}; };
namespace kiwix {
typedef std::pair<std::string, std::string> LangNameCodePair; typedef std::pair<std::string, std::string> LangNameCodePair;
typedef std::vector<LangNameCodePair> FeedLanguages; typedef std::vector<LangNameCodePair> FeedLanguages;
typedef std::vector<std::string> FeedCategories; typedef std::vector<std::string> FeedCategories;
@ -220,23 +220,11 @@ bool fileReadable(const std::string& path);
*/ */
std::string getMimeTypeForFile(const std::string& filename); std::string getMimeTypeForFile(const std::string& filename);
/** Provides all available network interfaces on Windows
*
* This function provides the available IPv4 and IPv6 network interfaces
*/
std::map<std::string,ip_addr> getNetworkInterfacesWin();
/** Provides all available network interfaces on Posix
*
* This function provides the available IPv4 and IPv6 network interfaces
*/
std::map<std::string,ip_addr> getNetworkInterfacesPosix();
/** Provides all available network interfaces /** Provides all available network interfaces
* *
* This function provides the available IPv4 and IPv6 network interfaces * This function provides the available IPv4 and IPv6 network interfaces
*/ */
std::map<std::string,ip_addr> getNetworkInterfaces(); std::map<std::string,IpAddress> getNetworkInterfaces();
/** Provides the best IP address /** Provides the best IP address
* This function provides the best IP address from the list given by getNetworkInterfaces * This function provides the best IP address from the list given by getNetworkInterfaces

View File

@ -48,7 +48,10 @@ if host_machine.system() == 'windows' and static_deps
endif endif
if host_machine.system() == 'windows' if host_machine.system() == 'windows'
add_project_arguments('-DNOMINMAX', language: 'cpp') add_project_arguments('-DNOMINMAX', language: 'cpp')
extra_libs += ['-liphlpapi']
else
extra_link_args = []
endif endif
all_deps = [thread_dep, libicu_dep, libzim_dep, pugixml_dep, libcurl_dep, microhttpd_dep, zlib_dep, xapian_dep] all_deps = [thread_dep, libicu_dep, libzim_dep, pugixml_dep, libcurl_dep, microhttpd_dep, zlib_dep, xapian_dep]
@ -58,12 +61,6 @@ inc = include_directories('include', extra_include)
conf = configuration_data() conf = configuration_data()
conf.set('LIBKIWIX_VERSION', '"@0@"'.format(meson.project_version())) conf.set('LIBKIWIX_VERSION', '"@0@"'.format(meson.project_version()))
if build_machine.system() == 'windows'
extra_link_args = ['-lshlwapi', '-lwinmm']
else
extra_link_args = []
endif
subdir('include') subdir('include')
subdir('scripts') subdir('scripts')
subdir('static') subdir('static')

View File

@ -51,7 +51,7 @@ bool Server::start() {
m_withTaskbar, m_withTaskbar,
m_withLibraryButton, m_withLibraryButton,
m_blockExternalLinks, m_blockExternalLinks,
m_ipv6, m_ipMode,
m_indexTemplateString, m_indexTemplateString,
m_ipConnectionLimit)); m_ipConnectionLimit));
return mp_server->start(); return mp_server->start();
@ -85,9 +85,9 @@ std::string Server::getAddress()
return mp_server->getAddress(); return mp_server->getAddress();
} }
bool Server::isAddressIPv6() IpMode Server::getIpMode() const
{ {
return mp_server->isAddressIPv6(); return mp_server->getIpMode();
} }
} }

View File

@ -416,7 +416,7 @@ InternalServer::InternalServer(LibraryPtr library,
bool withTaskbar, bool withTaskbar,
bool withLibraryButton, bool withLibraryButton,
bool blockExternalLinks, bool blockExternalLinks,
bool ipv6, IpMode ipMode,
std::string indexTemplateString, std::string indexTemplateString,
int ipConnectionLimit) : int ipConnectionLimit) :
m_addr(addr), m_addr(addr),
@ -429,7 +429,7 @@ InternalServer::InternalServer(LibraryPtr library,
m_withTaskbar(withTaskbar), m_withTaskbar(withTaskbar),
m_withLibraryButton(withLibraryButton), m_withLibraryButton(withLibraryButton),
m_blockExternalLinks(blockExternalLinks), m_blockExternalLinks(blockExternalLinks),
m_ipv6(ipv6), m_ipMode(ipMode),
m_indexTemplateString(indexTemplateString.empty() ? RESOURCE::templates::index_html : indexTemplateString), m_indexTemplateString(indexTemplateString.empty() ? RESOURCE::templates::index_html : indexTemplateString),
m_ipConnectionLimit(ipConnectionLimit), m_ipConnectionLimit(ipConnectionLimit),
mp_daemon(nullptr), mp_daemon(nullptr),
@ -466,22 +466,27 @@ bool InternalServer::start() {
sockAddr6.sin6_addr = in6addr_any; sockAddr6.sin6_addr = in6addr_any;
sockAddr4.sin_addr.s_addr = htonl(INADDR_ANY); sockAddr4.sin_addr.s_addr = htonl(INADDR_ANY);
} }
m_addr = kiwix::getBestPublicIp(m_ipv6); m_addr = kiwix::getBestPublicIp(m_ipMode == IpMode::ipv6 || m_ipMode == IpMode::all);
std::cout<<m_addr<<std::endl; } else {
} else if (inet_pton(AF_INET6, m_addr.c_str(), &(sockAddr6.sin6_addr.s6_addr)) == 1 ) { bool ipv6 = inet_pton(AF_INET6, m_addr.c_str(), &(sockAddr6.sin6_addr.s6_addr)) == 1;
m_ipv6 = true; bool ipv4 = inet_pton(AF_INET, m_addr.c_str(), &(sockAddr4.sin_addr.s_addr)) == 1;
} else if (inet_pton(AF_INET, m_addr.c_str(), &(sockAddr4.sin_addr.s_addr)) == 1) { if (ipv6){
if (m_ipv6) { m_ipMode = IpMode::all;
std::cerr << "Ip address " << m_addr << " is not a valid ipv6 address" << std::endl; } else if (!ipv4) {
std::cerr << "Ip address " << m_addr << " is not a valid ip address" << std::endl;
return false; return false;
} }
} else {
std::cerr << "Ip address " << m_addr << " is not a valid ip address" << std::endl;
return false;
} }
if (m_ipv6) if (m_ipMode == IpMode::all) {
flags|=MHD_USE_DUAL_STACK; flags|=MHD_USE_DUAL_STACK;
} else if (m_ipMode == IpMode::ipv6) {
flags|=MHD_USE_IPv6;
}
struct sockaddr* sockaddr = (m_ipMode==IpMode::all || m_ipMode==IpMode::ipv6)
? (struct sockaddr*)&sockAddr6
: (struct sockaddr*)&sockAddr4;
mp_daemon = MHD_start_daemon(flags, mp_daemon = MHD_start_daemon(flags,
m_port, m_port,
@ -489,7 +494,7 @@ bool InternalServer::start() {
NULL, NULL,
&staticHandlerCallback, &staticHandlerCallback,
this, this,
MHD_OPTION_SOCK_ADDR, m_ipv6?(struct sockaddr*)&sockAddr6:(struct sockaddr*)&sockAddr4, MHD_OPTION_SOCK_ADDR, sockaddr,
MHD_OPTION_THREAD_POOL_SIZE, m_nbThreads, MHD_OPTION_THREAD_POOL_SIZE, m_nbThreads,
MHD_OPTION_PER_IP_CONNECTION_LIMIT, m_ipConnectionLimit, MHD_OPTION_PER_IP_CONNECTION_LIMIT, m_ipConnectionLimit,
MHD_OPTION_END); MHD_OPTION_END);

View File

@ -103,7 +103,7 @@ class InternalServer {
bool withTaskbar, bool withTaskbar,
bool withLibraryButton, bool withLibraryButton,
bool blockExternalLinks, bool blockExternalLinks,
bool ipv6, IpMode ipMode,
std::string indexTemplateString, std::string indexTemplateString,
int ipConnectionLimit); int ipConnectionLimit);
virtual ~InternalServer(); virtual ~InternalServer();
@ -119,7 +119,7 @@ class InternalServer {
void stop(); void stop();
std::string getAddress() { return m_addr; } std::string getAddress() { return m_addr; }
int getPort() { return m_port; } int getPort() { return m_port; }
bool isAddressIPv6() { return m_ipv6; } IpMode getIpMode() const { return m_ipMode; }
private: // functions private: // functions
std::unique_ptr<Response> handle_request(const RequestContext& request); std::unique_ptr<Response> handle_request(const RequestContext& request);
@ -176,7 +176,7 @@ class InternalServer {
bool m_withTaskbar; bool m_withTaskbar;
bool m_withLibraryButton; bool m_withLibraryButton;
bool m_blockExternalLinks; bool m_blockExternalLinks;
bool m_ipv6; IpMode m_ipMode;
std::string m_indexTemplateString; std::string m_indexTemplateString;
int m_ipConnectionLimit; int m_ipConnectionLimit;
struct MHD_Daemon* mp_daemon; struct MHD_Daemon* mp_daemon;

View File

@ -79,8 +79,8 @@ std::string kiwix::download(const std::string& url) {
#ifdef _WIN32 #ifdef _WIN32
std::map<std::string,ip_addr> kiwix::getNetworkInterfacesWin() { std::map<std::string,kiwix::IpAddress> getNetworkInterfacesWin() {
std::map<std::string,ip_addr> interfaces; std::map<std::string,kiwix::IpAddress> interfaces;
const int working_buffer_size = 15000; const int working_buffer_size = 15000;
const int max_tries = 3; const int max_tries = 3;
@ -98,7 +98,6 @@ std::map<std::string,ip_addr> kiwix::getNetworkInterfacesWin() {
// Successively allocate the required memory until GetAdaptersAddresses does not // Successively allocate the required memory until GetAdaptersAddresses does not
// results in ERROR_BUFFER_OVERFLOW for a maximum of max_tries // results in ERROR_BUFFER_OVERFLOW for a maximum of max_tries
do{ do{
interfacesHead = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen); interfacesHead = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
if (interfacesHead == NULL) { if (interfacesHead == NULL) {
std::cerr << "Memory allocation failed for IP_ADAPTER_ADDRESSES struct" << std::endl; std::cerr << "Memory allocation failed for IP_ADAPTER_ADDRESSES struct" << std::endl;
@ -106,7 +105,6 @@ std::map<std::string,ip_addr> kiwix::getNetworkInterfacesWin() {
} }
dwRetVal = GetAdaptersAddresses(family, flags, NULL, interfacesHead, &outBufLen); dwRetVal = GetAdaptersAddresses(family, flags, NULL, interfacesHead, &outBufLen);
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < max_tries)); } while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < max_tries));
if (dwRetVal == NO_ERROR) { if (dwRetVal == NO_ERROR) {
@ -147,8 +145,8 @@ std::map<std::string,ip_addr> kiwix::getNetworkInterfacesWin() {
#else #else
std::map<std::string,ip_addr> kiwix::getNetworkInterfacesPosix() { std::map<std::string,kiwix::IpAddress> getNetworkInterfacesPosix() {
std::map<std::string,ip_addr> interfaces; std::map<std::string,kiwix::IpAddress> interfaces;
struct ifaddrs *interfacesHead; struct ifaddrs *interfacesHead;
if (getifaddrs(&interfacesHead) == -1) { if (getifaddrs(&interfacesHead) == -1) {
@ -179,20 +177,17 @@ std::map<std::string,ip_addr> kiwix::getNetworkInterfacesPosix() {
#endif #endif
std::map<std::string,ip_addr> kiwix::getNetworkInterfaces() { std::map<std::string,kiwix::IpAddress> kiwix::getNetworkInterfaces() {
std::map<std::string,ip_addr> interfaces;
#ifdef _WIN32 #ifdef _WIN32
return getNetworkInterfacesWin(); return getNetworkInterfacesWin();
#else #else
return getNetworkInterfacesPosix(); return getNetworkInterfacesPosix();
#endif #endif
} }
std::string kiwix::getBestPublicIp(bool ipv6) { std::string kiwix::getBestPublicIp(bool ipv6) {
ip_addr bestPublicIp = ip_addr{"127.0.0.1","::1"}; kiwix::IpAddress bestPublicIp = kiwix::IpAddress{"127.0.0.1","::1"};
std::map<std::string,ip_addr> interfaces = getNetworkInterfaces(); std::map<std::string,kiwix::IpAddress> interfaces = getNetworkInterfaces();
#ifndef _WIN32 #ifndef _WIN32
const char* const prioritizedNames[] = const char* const prioritizedNames[] =