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 {
enum class IpMode { ipv4, ipv6, all };
typedef zim::size_type size_type;
typedef zim::offset_type offset_type;

View File

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

View File

@ -25,12 +25,12 @@
#include <map>
#include <cstdint>
struct ip_addr{
namespace kiwix {
struct IpAddress{
std::string addr;
std::string addr6;
};
namespace kiwix {
typedef std::pair<std::string, std::string> LangNameCodePair;
typedef std::vector<LangNameCodePair> FeedLanguages;
typedef std::vector<std::string> FeedCategories;
@ -220,23 +220,11 @@ bool fileReadable(const std::string& path);
*/
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
*
* 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
* This function provides the best IP address from the list given by getNetworkInterfaces

View File

@ -49,6 +49,9 @@ endif
if host_machine.system() == 'windows'
add_project_arguments('-DNOMINMAX', language: 'cpp')
extra_libs += ['-liphlpapi']
else
extra_link_args = []
endif
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.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('scripts')
subdir('static')

View File

@ -51,7 +51,7 @@ bool Server::start() {
m_withTaskbar,
m_withLibraryButton,
m_blockExternalLinks,
m_ipv6,
m_ipMode,
m_indexTemplateString,
m_ipConnectionLimit));
return mp_server->start();
@ -85,9 +85,9 @@ std::string 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 withLibraryButton,
bool blockExternalLinks,
bool ipv6,
IpMode ipMode,
std::string indexTemplateString,
int ipConnectionLimit) :
m_addr(addr),
@ -429,7 +429,7 @@ InternalServer::InternalServer(LibraryPtr library,
m_withTaskbar(withTaskbar),
m_withLibraryButton(withLibraryButton),
m_blockExternalLinks(blockExternalLinks),
m_ipv6(ipv6),
m_ipMode(ipMode),
m_indexTemplateString(indexTemplateString.empty() ? RESOURCE::templates::index_html : indexTemplateString),
m_ipConnectionLimit(ipConnectionLimit),
mp_daemon(nullptr),
@ -466,22 +466,27 @@ bool InternalServer::start() {
sockAddr6.sin6_addr = in6addr_any;
sockAddr4.sin_addr.s_addr = htonl(INADDR_ANY);
}
m_addr = kiwix::getBestPublicIp(m_ipv6);
std::cout<<m_addr<<std::endl;
} else if (inet_pton(AF_INET6, m_addr.c_str(), &(sockAddr6.sin6_addr.s6_addr)) == 1 ) {
m_ipv6 = true;
} else if (inet_pton(AF_INET, m_addr.c_str(), &(sockAddr4.sin_addr.s_addr)) == 1) {
if (m_ipv6) {
std::cerr << "Ip address " << m_addr << " is not a valid ipv6 address" << std::endl;
return false;
}
m_addr = kiwix::getBestPublicIp(m_ipMode == IpMode::ipv6 || m_ipMode == IpMode::all);
} 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;
if (ipv6){
m_ipMode = IpMode::all;
} else if (!ipv4) {
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;
} 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,
m_port,
@ -489,7 +494,7 @@ bool InternalServer::start() {
NULL,
&staticHandlerCallback,
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_PER_IP_CONNECTION_LIMIT, m_ipConnectionLimit,
MHD_OPTION_END);

View File

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

View File

@ -79,8 +79,8 @@ std::string kiwix::download(const std::string& url) {
#ifdef _WIN32
std::map<std::string,ip_addr> kiwix::getNetworkInterfacesWin() {
std::map<std::string,ip_addr> interfaces;
std::map<std::string,kiwix::IpAddress> getNetworkInterfacesWin() {
std::map<std::string,kiwix::IpAddress> interfaces;
const int working_buffer_size = 15000;
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
// results in ERROR_BUFFER_OVERFLOW for a maximum of max_tries
do{
interfacesHead = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
if (interfacesHead == NULL) {
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);
} while ((dwRetVal == ERROR_BUFFER_OVERFLOW) && (Iterations < max_tries));
if (dwRetVal == NO_ERROR) {
@ -147,8 +145,8 @@ std::map<std::string,ip_addr> kiwix::getNetworkInterfacesWin() {
#else
std::map<std::string,ip_addr> kiwix::getNetworkInterfacesPosix() {
std::map<std::string,ip_addr> interfaces;
std::map<std::string,kiwix::IpAddress> getNetworkInterfacesPosix() {
std::map<std::string,kiwix::IpAddress> interfaces;
struct ifaddrs *interfacesHead;
if (getifaddrs(&interfacesHead) == -1) {
@ -179,20 +177,17 @@ std::map<std::string,ip_addr> kiwix::getNetworkInterfacesPosix() {
#endif
std::map<std::string,ip_addr> kiwix::getNetworkInterfaces() {
std::map<std::string,ip_addr> interfaces;
std::map<std::string,kiwix::IpAddress> kiwix::getNetworkInterfaces() {
#ifdef _WIN32
return getNetworkInterfacesWin();
#else
return getNetworkInterfacesPosix();
#endif
}
std::string kiwix::getBestPublicIp(bool ipv6) {
ip_addr bestPublicIp = ip_addr{"127.0.0.1","::1"};
std::map<std::string,ip_addr> interfaces = getNetworkInterfaces();
kiwix::IpAddress bestPublicIp = kiwix::IpAddress{"127.0.0.1","::1"};
std::map<std::string,kiwix::IpAddress> interfaces = getNetworkInterfaces();
#ifndef _WIN32
const char* const prioritizedNames[] =