move hosts files logic to seprate class, add custom host files #50

develop
Geoffrey Merck 1 year ago
parent c8dc79ce5f
commit 707f9e754c

@ -35,7 +35,6 @@
#include "DStarGatewayConfig.h"
#include "DStarGatewayApp.h"
#include "Version.h"
#include "HostsFileDownloader.h"
#include "IRCDDBMultiClient.h"
#include "IRCDDBClient.h"
#include "Utils.h"
@ -50,6 +49,7 @@
#include "Daemon.h"
#include "APRSISHandlerThread.h"
#include "DummyAPRSHandlerThread.h"
#include "HostsFilesManager.h"
CDStarGatewayApp * CDStarGatewayApp::g_app = nullptr;
const std::string BANNER_1 = CStringUtils::string_format("%s Copyright (C) %s\n", FULL_PRODUCT_NAME.c_str(), VENDOR_NAME.c_str());
@ -325,30 +325,33 @@ bool CDStarGatewayApp::createThread()
TDextra dextraConfig;
m_config->getDExtra(dextraConfig);
CLog::logInfo("DExtra enabled: %d, max. dongles: %u, url: %s", int(dextraConfig.enabled), dextraConfig.maxDongles, dextraConfig.hostfileUrl.c_str());
if(dextraConfig.enabled) CHostsFileDownloader::download(dextraConfig.hostfileUrl, paths.dataDir + "/" + DEXTRA_HOSTS_FILE_NAME);
m_thread->setDExtra(dextraConfig.enabled, dextraConfig.maxDongles);
// Setup DCS
TDCS dcsConfig;
m_config->getDCS(dcsConfig);
CLog::logInfo("DCS enabled: %d, url: %s", int(dcsConfig.enabled), dcsConfig.hostfileUrl.c_str());
if(dextraConfig.enabled) CHostsFileDownloader::download(dcsConfig.hostfileUrl, paths.dataDir + "/" + DCS_HOSTS_FILE_NAME);
m_thread->setDCS(dcsConfig.enabled);
// Setup DPlus
TDplus dplusConfig;
m_config->getDPlus(dplusConfig);
CLog::logInfo("D-Plus enabled: %d, max. dongles: %u, login: %s, url: %s", int(dplusConfig.enabled), dplusConfig.maxDongles, dplusConfig.login.c_str(), dplusConfig.hostfileUrl.c_str());
if(dplusConfig.enabled) CHostsFileDownloader::download(dplusConfig.hostfileUrl, paths.dataDir + "/" + DPLUS_HOSTS_FILE_NAME);
m_thread->setDPlus(dplusConfig.enabled, dplusConfig.maxDongles, dplusConfig.login);
// Setup XLX
TXLX xlxConfig;
m_config->getXLX(xlxConfig);
CLog::logInfo("XLX enabled: %d, Hosts file url: %s", int(xlxConfig.enabled), xlxConfig.hostfileUrl.c_str());
if(xlxConfig.enabled) CHostsFileDownloader::download(xlxConfig.hostfileUrl, paths.dataDir + "/" + XLX_HOSTS_FILE_NAME);
m_thread->setXLX(xlxConfig.enabled);
// Setup hostsfiles
CHostsFilesManager::setHostFilesDirectories(paths.dataDir, paths.customHostsFiles);
CHostsFilesManager::setDextra(dextraConfig.enabled, dextraConfig.hostfileUrl);
CHostsFilesManager::setDCS (dcsConfig.enabled, dcsConfig.hostfileUrl);
CHostsFilesManager::setDPlus (dplusConfig.enabled, dplusConfig.hostfileUrl);
CHostsFilesManager::setXLX (xlxConfig.enabled, xlxConfig.hostfileUrl);
// Setup Remote
TRemote remoteConfig;
m_config->getRemote(remoteConfig);

@ -195,11 +195,16 @@ bool CDStarGatewayConfig::loadLog(const CConfig & cfg)
bool CDStarGatewayConfig::loadPaths(const CConfig & cfg)
{
bool ret = cfg.getValue("paths", "data", m_paths.dataDir, 0, 2048, "/usr/local/share/dstargateway.d/");
ret = cfg.getValue("customHostfiles", "data", m_paths.customHostsFiles, 0, 2048, "/usr/local/share/dstargateway.d/hostfiles.d/") && ret;
if(ret && m_paths.dataDir[m_paths.dataDir.length() - 1] != '/') {
m_paths.dataDir.push_back('/');
}
if(ret && m_paths.dataDir[m_paths.customHostsFiles.length() - 1] != '/') {
m_paths.customHostsFiles.push_back('/');
}
//TODO 20211226 check if directory are accessible
return ret;

@ -80,6 +80,7 @@ typedef struct {
typedef struct {
std::string dataDir;
std::string customHostsFiles;
} Tpaths;
typedef struct {

@ -54,6 +54,7 @@
#include "Defs.h"
#include "Log.h"
#include "StringUtils.h"
#include "HostsFilesManager.h"
const std::string LOOPBACK_ADDRESS("127.0.0.1");
@ -136,6 +137,9 @@ CDStarGatewayThread::~CDStarGatewayThread()
void* CDStarGatewayThread::Entry()
{
CHostsFilesManager::setCache(&m_cache);
auto hostFut = CHostsFilesManager::UpdateHostsAsync(); // Do this in a separate thread
// Truncate the old Links.log file
std::string fullName = m_logDir + "/" + LINKS_BASE_NAME + ".log";
if (!m_name.empty()) {
@ -195,6 +199,7 @@ void* CDStarGatewayThread::Entry()
}
// Wait here until we have the essentials to run
hostFut.get();
while (!m_killed && (m_dextraPool == NULL || m_dplusPool == NULL || m_dcsPool == NULL || m_g2HandlerPool == NULL || (m_icomRepeaterHandler == NULL && m_hbRepeaterHandler == NULL && m_dummyRepeaterHandler == NULL) || m_gatewayCallsign.empty()))
::std::this_thread::sleep_for(std::chrono::milliseconds(500UL)); // 1/2 sec
@ -217,9 +222,6 @@ void* CDStarGatewayThread::Entry()
}
}
loadGateways();
loadAllReflectors();
CG2Handler::setG2ProtocolHandlerPool(m_g2HandlerPool);
CG2Handler::setHeaderLogger(headerLogger);
@ -1139,82 +1141,6 @@ void CDStarGatewayThread::processDD()
}
}
void CDStarGatewayThread::loadGateways()
{
std::string fileName = m_dataDir + "/" + GATEWAY_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DEXTRA);
}
void CDStarGatewayThread::loadAllReflectors()
{
if (m_xlxEnabled) {
std::string fileName = m_dataDir + "/" + DPLUS_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DCS);
}
if (m_dplusEnabled) {
std::string fileName = m_dataDir + "/" + DPLUS_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DPLUS);
}
if (m_dextraEnabled) {
std::string fileName = m_dataDir + "/" + DEXTRA_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DEXTRA);
}
if (m_dcsEnabled) {
std::string fileName = m_dataDir + "/" + DCS_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DCS);
}
}
void CDStarGatewayThread::loadReflectors(std::string hostFileName, DSTAR_PROTOCOL proto)
{
unsigned int count = 0U;
CHostFile hostFile(hostFileName, false);
for (unsigned int i = 0U; i < hostFile.getCount(); i++) {
std::string reflector = hostFile.getName(i);
in_addr address = CUDPReaderWriter::lookup(hostFile.getAddress(i));
bool lock = hostFile.getLock(i);
if (address.s_addr != INADDR_NONE) {
unsigned char* ucp = (unsigned char*)&address;
std::string addrText;
addrText = CStringUtils::string_format("%u.%u.%u.%u", ucp[0U] & 0xFFU, ucp[1U] & 0xFFU, ucp[2U] & 0xFFU, ucp[3U] & 0xFFU);
if (lock)
CLog::logInfo("Locking %s to %s", reflector.c_str(), addrText.c_str());
reflector.resize(LONG_CALLSIGN_LENGTH - 1U, ' ');
reflector += "G";
m_cache.updateGateway(reflector, addrText, proto, lock, true);
count++;
}
}
std::string protoString;
switch (proto)
{
case DP_DEXTRA:
protoString = "DExtra";
break;
case DP_DCS:
protoString = "DCS";
break;
case DP_DPLUS:
protoString = "DPlus";
break;
default:
// ???
break;
}
CLog::logInfo("Loaded %u of %u %s hosts from %s", count, hostFile.getCount(), protoString.c_str() , hostFileName.c_str());
}
void CDStarGatewayThread::writeStatus()
{
std::string fullName = LINKS_BASE_NAME;

@ -146,14 +146,6 @@ private:
void processG2();
void processDD();
void loadGateways();
void loadAllReflectors();
void loadReflectors(std::string hostFileName, DSTAR_PROTOCOL proto);
void loadDExtraReflectors(const std::string& fileName);
void loadDPlusReflectors(const std::string& fileName);
void loadDCSReflectors(const std::string& fileName);
void loadXLXReflectors();
void writeStatus();
void readStatusFiles();

@ -0,0 +1,203 @@
/*
* Copyright (c) 2024 by Geoffrey F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <cassert>
#include "HostsFilesManager.h"
#include "HostsFileDownloader.h"
#include "HostFile.h"
#include "StringUtils.h"
#include "UDPReaderWriter.h"
#include "Log.h"
std::string CHostsFilesManager::m_hostFilesDirectory("");
std::string CHostsFilesManager::m_customFilesDirectory("");
bool CHostsFilesManager::m_dextraEnabled = false;
bool CHostsFilesManager::m_dcsEnabled = false;
bool CHostsFilesManager::m_dplusEnabled = false;
bool CHostsFilesManager::m_xlxEnabled = false;
std::string CHostsFilesManager::m_dextraUrl("");
std::string CHostsFilesManager::m_dcsUrl("");
std::string CHostsFilesManager::m_dplusUrl("");
std::string CHostsFilesManager::m_xlxUrl("");
CCacheManager * CHostsFilesManager::m_cache = nullptr;
CTimer CHostsFilesManager::m_downloadTimer(1000U, 60 * 60 * 24);
void CHostsFilesManager::setHostFilesDirectories(const std::string & hostFilesDir, const std::string & customHostFilesDir)
{
m_hostFilesDirectory.assign(hostFilesDir);
m_customFilesDirectory.assign(customHostFilesDir);
}
void CHostsFilesManager::setDextra(bool enabled, const std::string & url)
{
m_dextraEnabled = enabled;
m_dextraUrl.assign(url);
}
void CHostsFilesManager::setDPlus(bool enabled, const std::string & url)
{
m_dplusEnabled = enabled;
m_dplusUrl.assign(url);
}
void CHostsFilesManager::setDCS(bool enabled, const std::string & url)
{
m_dcsEnabled = enabled;
m_dcsUrl.assign(url);
}
void CHostsFilesManager::setXLX(bool enabled, const std::string & url)
{
m_xlxEnabled = enabled;
m_xlxUrl.assign(url);
}
void CHostsFilesManager::setCache(CCacheManager * cache)
{
assert(cache != nullptr);
m_cache = cache;
}
void CHostsFilesManager::clock(unsigned int ms)
{
m_downloadTimer.clock(ms);
if(m_downloadTimer.hasExpired()) {
UpdateHostsAsync(); // call and forget
}
}
void CHostsFilesManager::setDownloadTimeout(unsigned int seconds)
{
m_downloadTimer.setTimeout(seconds);
}
bool CHostsFilesManager::UpdateHostsFromInternet()
{
CLog::logInfo("Updating hosts files from internet");
bool ret = true;
if(m_dextraEnabled && !m_dextraUrl.empty()) ret = CHostsFileDownloader::download(m_dextraUrl, m_hostFilesDirectory + "/" + DEXTRA_HOSTS_FILE_NAME) && ret;
if(m_dcsEnabled && !m_dcsUrl.empty()) ret = CHostsFileDownloader::download(m_dcsUrl, m_hostFilesDirectory + "/" + DCS_HOSTS_FILE_NAME) && ret;
if(m_dplusEnabled && !m_dplusUrl.empty()) ret = CHostsFileDownloader::download(m_dplusUrl, m_hostFilesDirectory + "/" + DPLUS_HOSTS_FILE_NAME) && ret;
if(m_xlxEnabled && !m_xlxUrl.empty()) ret = CHostsFileDownloader::download(m_xlxUrl, m_hostFilesDirectory + "/" + XLX_HOSTS_FILE_NAME) && ret;
if(!ret) CLog::logWarning("Some hosts files failed to downlaod");
CHostsFilesManager::loadReflectors(m_hostFilesDirectory);
return ret;
}
bool CHostsFilesManager::UpdateHostsFromLocal()
{
CHostsFilesManager::loadReflectors(m_customFilesDirectory);
return true;
}
bool CHostsFilesManager::UpdateHosts()
{
bool ret = UpdateHostsFromInternet();
UpdateHostsFromLocal() && ret;
return ret;
}
std::future<bool> CHostsFilesManager::UpdateHostsAsync()
{
auto fut = std::async(std::launch::async, UpdateHosts);
return fut;
}
void CHostsFilesManager::loadReflectors(const std::string & directory)
{
if (m_xlxEnabled) {
std::string fileName = directory + "/" + DPLUS_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DCS);
}
if (m_dplusEnabled) {
std::string fileName = directory + "/" + DPLUS_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DPLUS);
}
if (m_dextraEnabled) {
std::string fileName = directory + "/" + DEXTRA_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DEXTRA);
}
if (m_dcsEnabled) {
std::string fileName = directory + "/" + DCS_HOSTS_FILE_NAME;
loadReflectors(fileName, DP_DCS);
}
}
void CHostsFilesManager::loadReflectors(const std::string & hostFileName, DSTAR_PROTOCOL proto)
{
if(m_cache == nullptr) {
CLog::logDebug("HostsFilesManager cache not initilized");
return;
}
unsigned int count = 0U;
CHostFile hostFile(hostFileName, false);
for (unsigned int i = 0U; i < hostFile.getCount(); i++) {
std::string reflector = hostFile.getName(i);
in_addr address = CUDPReaderWriter::lookup(hostFile.getAddress(i));
bool lock = hostFile.getLock(i);
if (address.s_addr != INADDR_NONE) {
unsigned char* ucp = (unsigned char*)&address;
std::string addrText;
addrText = CStringUtils::string_format("%u.%u.%u.%u", ucp[0U] & 0xFFU, ucp[1U] & 0xFFU, ucp[2U] & 0xFFU, ucp[3U] & 0xFFU);
if (lock)
CLog::logInfo("Locking %s to %s", reflector.c_str(), addrText.c_str());
reflector.resize(LONG_CALLSIGN_LENGTH - 1U, ' ');
reflector += "G";
m_cache->updateGateway(reflector, addrText, proto, lock, true);
count++;
}
}
std::string protoString;
switch (proto)
{
case DP_DEXTRA:
protoString = "DExtra";
break;
case DP_DCS:
protoString = "DCS";
break;
case DP_DPLUS:
protoString = "DPlus";
break;
default:
// ???
break;
}
CLog::logInfo("Loaded %u of %u %s hosts from %s", count, hostFile.getCount(), protoString.c_str() , hostFileName.c_str());
}

@ -0,0 +1,65 @@
/*
* Copyright (c) 2024 by Geoffrey F4FXL / KC3FRA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef HostsFilesManager_H
#define HostsFilesManager_H
#include <string>
#include <future>
#include "CacheManager.h"
#include "Timer.h"
#include "DStarDefines.h"
class CHostsFilesManager {
public:
static void setHostFilesDirectories(const std::string & hostFilesDir, const std::string & customHostFilesDir);
static void setDextra(bool enabled, const std::string & dextraUrl);
static void setDCS(bool enabled, const std::string & dcsUrl);
static void setDPlus(bool enabled, const std::string & dplusUrl);
static void setXLX(bool enabled, const std::string & xlxUrl);
static void setCache(CCacheManager * cache);
static void clock(unsigned int ms);
static void setDownloadTimeout(unsigned int seconds);
static bool UpdateHostsFromInternet();
static bool UpdateHostsFromLocal();
static bool UpdateHosts();
static std::future<bool> UpdateHostsAsync();
private:
static std::string m_hostFilesDirectory;
static std::string m_customFilesDirectory;
static bool m_dextraEnabled;
static bool m_dcsEnabled;
static bool m_dplusEnabled;
static bool m_xlxEnabled;
static std::string m_dextraUrl;
static std::string m_dcsUrl;
static std::string m_dplusUrl;
static std::string m_xlxUrl;
static CCacheManager * m_cache;
static CTimer m_downloadTimer;
static void loadReflectors(const std::string & directory);
static void loadReflectors(const std::string & hostFileName, DSTAR_PROTOCOL proto);
};
#endif
Loading…
Cancel
Save

Powered by TurnKey Linux.