mirror of https://github.com/nostar/urfd.git
Merge pull request #2 from n7tae/main
Add the ability to put and get information from a existing distributed hash tablepull/8/head
commit
715365f737
@ -1,14 +1,20 @@
|
||||
##############################################################################
|
||||
# URFD interlink file
|
||||
#
|
||||
# one line per entry
|
||||
# each entry specifies a remote XLX or XRF to peer with
|
||||
# format:
|
||||
# <URF callsign> <ip> <list of modules shared>
|
||||
# example:
|
||||
# URF270 158.64.26.132 ACD
|
||||
# One line per entry.
|
||||
# Each entry specifies a remote URF to peer with.
|
||||
# If no Port is specified, 10017 will be used.
|
||||
# If DHT is enabled and the target is also DHT-enabled, then you only
|
||||
# need to specify the URF-Callsign and the Shared-Modules.
|
||||
# Format:
|
||||
# <URF-Callsign> <IP-Address> <Shared-Mdoules> <Port>
|
||||
# Examples:
|
||||
# URF270 158.64.26.132 EF
|
||||
# URF280 ABC
|
||||
#
|
||||
# note: the remote URFD must list this in its interlink file
|
||||
# for the link to be established
|
||||
# Brandmeister links use three params, no port is specified. Example:
|
||||
# BM3104 162.248.88.117 E
|
||||
#
|
||||
# note: Remote URFD must list this in its interlink file
|
||||
# for the link to be established.
|
||||
#############################################################################
|
||||
|
||||
@ -0,0 +1,193 @@
|
||||
//
|
||||
// ccallsignlist.cpp
|
||||
// m17ref
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of m17ref.
|
||||
//
|
||||
// m17ref 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "BlackWhiteSet.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// file io
|
||||
|
||||
bool CBlackWhiteSet::LoadFromFile(const std::string &filename)
|
||||
{
|
||||
bool ok = false;
|
||||
char sz[256];
|
||||
|
||||
// and load
|
||||
std::ifstream file(filename);
|
||||
if ( file.is_open() )
|
||||
{
|
||||
Lock();
|
||||
|
||||
// empty list
|
||||
m_Callsigns.clear();
|
||||
// fill with file content
|
||||
while ( file.getline(sz, sizeof(sz)).good() )
|
||||
{
|
||||
// remove leading & trailing spaces
|
||||
char *szt = TrimWhiteSpaces(sz);
|
||||
|
||||
// crack it
|
||||
if ( (strlen(szt) > 0) && (szt[0] != '#') )
|
||||
{
|
||||
// 1st token is callsign
|
||||
if ( (szt = strtok(szt, " ,\t")) != nullptr )
|
||||
{
|
||||
std::string cs(ToUpper(szt));
|
||||
if (m_Callsigns.end() == m_Callsigns.find(cs))
|
||||
{
|
||||
m_Callsigns.insert(cs);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Duplicate ," << cs << " in " << filename << " will be ignored." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
// keep file path
|
||||
m_Filename = filename;
|
||||
|
||||
// update time
|
||||
GetLastModTime(&m_LastModTime);
|
||||
|
||||
// and done
|
||||
Unlock();
|
||||
ok = true;
|
||||
std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CBlackWhiteSet::ReloadFromFile(void)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
if ( ! m_Filename.empty() )
|
||||
{
|
||||
ok = LoadFromFile(m_Filename);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CBlackWhiteSet::NeedReload(void)
|
||||
{
|
||||
bool needReload = false;
|
||||
|
||||
time_t time;
|
||||
if ( GetLastModTime(&time) )
|
||||
{
|
||||
needReload = time != m_LastModTime;
|
||||
}
|
||||
return needReload;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// compare
|
||||
|
||||
bool CBlackWhiteSet::IsMatched(const std::string &cs) const
|
||||
{
|
||||
for ( const auto &item : m_Callsigns )
|
||||
{
|
||||
auto pos = item.find('*');
|
||||
switch (pos)
|
||||
{
|
||||
case 0:
|
||||
return true;
|
||||
case std::string::npos:
|
||||
if (0 == item.compare(cs))
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
if (0 == item.compare(0, pos, cs, 0, pos))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// helpers
|
||||
|
||||
char *CBlackWhiteSet::TrimWhiteSpaces(char *str)
|
||||
{
|
||||
char *end;
|
||||
|
||||
// Trim leading space & tabs
|
||||
while((*str == ' ') || (*str == '\t')) str++;
|
||||
|
||||
// All spaces?
|
||||
if(*str == 0)
|
||||
return str;
|
||||
|
||||
// Trim trailing space, tab or lf
|
||||
end = str + ::strlen(str) - 1;
|
||||
while((end > str) && ((*end == ' ') || (*end == '\t') || (*end == '\r'))) end--;
|
||||
|
||||
// Write new null terminator
|
||||
*(end+1) = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool CBlackWhiteSet::GetLastModTime(time_t *time)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
if ( !m_Filename.empty() )
|
||||
{
|
||||
struct stat fileStat;
|
||||
if( ::stat(m_Filename.c_str(), &fileStat) != -1 )
|
||||
{
|
||||
*time = fileStat.st_mtime;
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
char *CBlackWhiteSet::ToUpper(char *str)
|
||||
{
|
||||
constexpr auto diff = 'a' - 'A';
|
||||
for (char *p=str; *p; p++)
|
||||
{
|
||||
if (*p >= 'a' && *p <= 'z')
|
||||
*p -= diff;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
//
|
||||
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of m17ref.
|
||||
//
|
||||
// m17ref 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CBlackWhiteSet
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CBlackWhiteSet() : m_LastModTime(0) {}
|
||||
|
||||
// locks
|
||||
void Lock(void) const { m_Mutex.lock(); }
|
||||
void Unlock(void) const { m_Mutex.unlock(); }
|
||||
|
||||
// file io
|
||||
bool LoadFromFile(const std::string &filename);
|
||||
bool ReloadFromFile(void);
|
||||
bool NeedReload(void);
|
||||
|
||||
// pass-through
|
||||
bool empty() const { return m_Callsigns.empty(); }
|
||||
|
||||
// compare
|
||||
bool IsMatched(const std::string &) const;
|
||||
|
||||
protected:
|
||||
bool GetLastModTime(time_t *);
|
||||
char *TrimWhiteSpaces(char *);
|
||||
char *ToUpper(char *str);
|
||||
|
||||
// data
|
||||
mutable std::mutex m_Mutex;
|
||||
std::string m_Filename;
|
||||
time_t m_LastModTime;
|
||||
std::set<std::string> m_Callsigns;
|
||||
};
|
||||
@ -1,49 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc. All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
#include "Notification.h"
|
||||
|
||||
class CNotificationQueue
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CNotificationQueue() {}
|
||||
|
||||
// destructor
|
||||
~CNotificationQueue() {}
|
||||
|
||||
// lock
|
||||
void Lock() { m_Mutex.lock(); }
|
||||
void Unlock() { m_Mutex.unlock(); }
|
||||
|
||||
// pass thru
|
||||
CNotification front() { return queue.front(); }
|
||||
void pop() { queue.pop(); }
|
||||
void push(CNotification note) { queue.push(note); }
|
||||
bool empty() const { return queue.empty(); }
|
||||
|
||||
protected:
|
||||
// data
|
||||
std::mutex m_Mutex;
|
||||
std::queue<CNotification> queue;
|
||||
};
|
||||
@ -1,223 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "CallsignList.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CCallsignList::CCallsignList()
|
||||
{
|
||||
memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// file io
|
||||
|
||||
bool CCallsignList::LoadFromFile(const std::string &filename)
|
||||
{
|
||||
bool ok = false;
|
||||
char sz[256];
|
||||
char szStar[2] = "*";
|
||||
|
||||
// and load
|
||||
std::ifstream file (filename);
|
||||
if ( file.is_open() )
|
||||
{
|
||||
Lock();
|
||||
|
||||
// empty list
|
||||
m_Callsigns.clear();
|
||||
// fill with file content
|
||||
while ( file.getline(sz, sizeof(sz)).good() )
|
||||
{
|
||||
// remove leading & trailing spaces
|
||||
char *szt = TrimWhiteSpaces(sz);
|
||||
|
||||
// crack it
|
||||
if ( (::strlen(szt) > 0) && (szt[0] != '#') )
|
||||
{
|
||||
// 1st token is callsign
|
||||
if ( (szt = ::strtok(szt, " ,\t")) != nullptr )
|
||||
{
|
||||
CCallsign callsign(szt);
|
||||
// 2nd token is modules list
|
||||
szt = ::strtok(nullptr, " ,\t");
|
||||
// if token absent, use wildcard
|
||||
if ( szt == nullptr )
|
||||
{
|
||||
szt = szStar;
|
||||
}
|
||||
// and add to list
|
||||
m_Callsigns.push_back(CCallsignListItem(callsign, CIp(), szt));
|
||||
}
|
||||
}
|
||||
}
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
// keep file path
|
||||
m_Filename.assign(filename);
|
||||
|
||||
// update time
|
||||
GetLastModTime(&m_LastModTime);
|
||||
|
||||
// and done
|
||||
Unlock();
|
||||
ok = true;
|
||||
std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CCallsignList::ReloadFromFile(void)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
if (! m_Filename.empty())
|
||||
{
|
||||
ok = LoadFromFile(m_Filename);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CCallsignList::NeedReload(void)
|
||||
{
|
||||
bool needReload = false;
|
||||
|
||||
time_t time;
|
||||
if ( GetLastModTime(&time) )
|
||||
{
|
||||
needReload = time != m_LastModTime;
|
||||
}
|
||||
return needReload;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// compare
|
||||
|
||||
bool CCallsignList::IsCallsignListedWithWildcard(const CCallsign &callsign) const
|
||||
{
|
||||
for ( const auto &item : m_Callsigns )
|
||||
{
|
||||
if (item.HasSameCallsignWithWildcard(callsign))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCallsignList::IsCallsignListedWithWildcard(const CCallsign &callsign, char module) const
|
||||
{
|
||||
for ( const auto &item : m_Callsigns )
|
||||
{
|
||||
if (item.HasSameCallsignWithWildcard(callsign) && ((module == ' ') || item.HasModuleListed(module)) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCallsignList::IsCallsignListed(const CCallsign &callsign, char module) const
|
||||
{
|
||||
for ( const auto &item : m_Callsigns )
|
||||
{
|
||||
if (item.HasSameCallsign(callsign) && item.HasModuleListed(module))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCallsignList::IsCallsignListed(const CCallsign &callsign, char *modules) const
|
||||
{
|
||||
for ( const auto &item : m_Callsigns )
|
||||
{
|
||||
if (item.HasSameCallsign(callsign) && item.CheckListedModules(modules))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// find
|
||||
|
||||
CCallsignListItem *CCallsignList::FindListItem(const CCallsign &Callsign)
|
||||
{
|
||||
for ( auto &item : m_Callsigns )
|
||||
{
|
||||
if ( item.GetCallsign().HasSameCallsign(Callsign) )
|
||||
{
|
||||
return &item;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// helpers
|
||||
|
||||
char *CCallsignList::TrimWhiteSpaces(char *str)
|
||||
{
|
||||
char *end;
|
||||
|
||||
// Trim leading space & tabs
|
||||
while((*str == ' ') || (*str == '\t')) str++;
|
||||
|
||||
// All spaces?
|
||||
if(*str == 0)
|
||||
return str;
|
||||
|
||||
// Trim trailing space, tab or lf
|
||||
end = str + ::strlen(str) - 1;
|
||||
while((end > str) && ((*end == ' ') || (*end == '\t') || (*end == '\r'))) end--;
|
||||
|
||||
// Write new null terminator
|
||||
*(end+1) = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool CCallsignList::GetLastModTime(time_t *time)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
if (! m_Filename.empty())
|
||||
{
|
||||
struct stat fileStat;
|
||||
if( ::stat(m_Filename.c_str(), &fileStat) != -1 )
|
||||
{
|
||||
*time = fileStat.st_mtime;
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
@ -1,67 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
|
||||
#include "CallsignListItem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CCallsignList
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CCallsignList();
|
||||
|
||||
// locks
|
||||
void Lock(void) const { m_Mutex.lock(); }
|
||||
void Unlock(void) const { m_Mutex.unlock(); }
|
||||
|
||||
// file io
|
||||
virtual bool LoadFromFile(const std::string &str);
|
||||
bool ReloadFromFile(void);
|
||||
bool NeedReload(void);
|
||||
|
||||
// compare
|
||||
bool IsCallsignListedWithWildcard(const CCallsign &) const;
|
||||
bool IsCallsignListedWithWildcard(const CCallsign &, char) const;
|
||||
bool IsCallsignListed(const CCallsign &, char) const;
|
||||
bool IsCallsignListed(const CCallsign &, char*) const;
|
||||
|
||||
// pass-thru
|
||||
bool empty() const { return m_Callsigns.empty(); }
|
||||
std::list<CCallsignListItem>::iterator begin() { return m_Callsigns.begin(); }
|
||||
std::list<CCallsignListItem>::iterator end() { return m_Callsigns.end(); }
|
||||
|
||||
// find
|
||||
CCallsignListItem *FindListItem(const CCallsign &);
|
||||
|
||||
protected:
|
||||
bool GetLastModTime(time_t *);
|
||||
char *TrimWhiteSpaces(char *);
|
||||
|
||||
// data
|
||||
mutable std::mutex m_Mutex;
|
||||
std::string m_Filename;
|
||||
time_t m_LastModTime;
|
||||
std::list<CCallsignListItem> m_Callsigns;
|
||||
};
|
||||
@ -1,136 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Global.h"
|
||||
|
||||
#include "CallsignListItem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
|
||||
CCallsignListItem::CCallsignListItem()
|
||||
{
|
||||
memset(m_Modules, 0, sizeof(m_Modules));
|
||||
memset(m_szUrl, 0, sizeof(m_szUrl));
|
||||
}
|
||||
|
||||
CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const CIp &ip, const char *modules)
|
||||
{
|
||||
const std::string mods(g_Configure.GetString(g_Keys.modules.modules));
|
||||
m_Callsign = callsign;
|
||||
memset(m_szUrl, 0, sizeof(m_szUrl));
|
||||
m_Ip = ip;
|
||||
if ( modules != nullptr )
|
||||
{
|
||||
memset(m_Modules, 0, sizeof(m_Modules));
|
||||
if ( modules[0] == '*' )
|
||||
{
|
||||
memcpy(m_Modules, mods.c_str(), mods.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = MIN(::strlen(modules), sizeof(m_Modules)-1);
|
||||
for (int i=0, j=0; i<n; i++)
|
||||
{
|
||||
if (std::string::npos != mods.find(modules[i]))
|
||||
{
|
||||
m_Modules[j++] = modules[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCallsignListItem::CCallsignListItem(const CCallsign &callsign, const char *url, const char *modules)
|
||||
{
|
||||
const std::string mods(g_Configure.GetString(g_Keys.modules.modules));
|
||||
m_Callsign = callsign;
|
||||
::strncpy(m_szUrl, url, URL_MAXLEN);
|
||||
m_Ip = CIp(m_szUrl);
|
||||
if ( modules != nullptr )
|
||||
{
|
||||
memset(m_Modules, 0, sizeof(m_Modules));
|
||||
if ( modules[0] == '*' )
|
||||
{
|
||||
memcpy(m_Modules, mods.c_str(), mods.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
int n = MIN(::strlen(modules), sizeof(m_Modules)-1);
|
||||
for (int i=0, j=0; i<n; i++)
|
||||
{
|
||||
if (std::string::npos != mods.find(modules[i]))
|
||||
{
|
||||
m_Modules[j++] = modules[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCallsignListItem::CCallsignListItem(const CCallsignListItem &item)
|
||||
{
|
||||
m_Callsign = item.m_Callsign;
|
||||
memcpy(m_szUrl, item.m_szUrl, sizeof(m_szUrl));
|
||||
m_Ip = item.m_Ip;
|
||||
memcpy(m_Modules, item.m_Modules, sizeof(m_Modules));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// compare
|
||||
|
||||
bool CCallsignListItem::HasSameCallsign(const CCallsign &callsign) const
|
||||
{
|
||||
return m_Callsign.HasSameCallsign(callsign);
|
||||
}
|
||||
|
||||
bool CCallsignListItem::HasSameCallsignWithWildcard(const CCallsign &callsign) const
|
||||
{
|
||||
return m_Callsign.HasSameCallsignWithWildcard(callsign);
|
||||
}
|
||||
|
||||
bool CCallsignListItem::HasModuleListed(char module) const
|
||||
{
|
||||
return (::strchr(m_Modules, (int)module) != nullptr);
|
||||
}
|
||||
|
||||
bool CCallsignListItem::CheckListedModules(char *Modules) const
|
||||
{
|
||||
bool listed = false;
|
||||
|
||||
if ( Modules != nullptr )
|
||||
{
|
||||
// build a list of common modules
|
||||
char list[27];
|
||||
list[0] = 0;
|
||||
//
|
||||
for ( unsigned i = 0; i < ::strlen(Modules); i++ )
|
||||
{
|
||||
if ( HasModuleListed(Modules[i]) )
|
||||
{
|
||||
::strncat(list, &(Modules[i]), 1);
|
||||
listed = true;
|
||||
}
|
||||
}
|
||||
::strcpy(Modules, list);
|
||||
}
|
||||
return listed;
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "Callsign.h"
|
||||
#include "IP.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// define
|
||||
|
||||
#define URL_MAXLEN 256
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CCallsignListItem
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CCallsignListItem();
|
||||
CCallsignListItem(const CCallsign &, const CIp &, const char *);
|
||||
CCallsignListItem(const CCallsign &, const char *, const char *);
|
||||
CCallsignListItem(const CCallsignListItem &);
|
||||
|
||||
// destructor
|
||||
virtual ~CCallsignListItem() {}
|
||||
|
||||
// compare
|
||||
bool HasSameCallsign(const CCallsign &) const;
|
||||
bool HasSameCallsignWithWildcard(const CCallsign &) const;
|
||||
bool HasModuleListed(char) const;
|
||||
bool CheckListedModules(char*) const;
|
||||
|
||||
// get
|
||||
const CCallsign &GetCallsign(void) const { return m_Callsign; }
|
||||
const CIp &GetIp(void) const { return m_Ip; }
|
||||
const char *GetModules(void) { return m_Modules; }
|
||||
|
||||
// update
|
||||
void ResolveIp(void) { m_Ip = CIp(m_szUrl); }
|
||||
|
||||
protected:
|
||||
// data
|
||||
CCallsign m_Callsign;
|
||||
char m_szUrl[URL_MAXLEN+1];
|
||||
CIp m_Ip;
|
||||
char m_Modules[27];
|
||||
};
|
||||
@ -0,0 +1,261 @@
|
||||
//
|
||||
// ccallsignlist.cpp
|
||||
// m17ref
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2020,2022 Thomas A. Early, N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of m17ref.
|
||||
//
|
||||
// m17ref 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "Global.h"
|
||||
#include "InterlinkMap.h"
|
||||
|
||||
CInterlinkMap::CInterlinkMap()
|
||||
{
|
||||
m_Filename.clear();
|
||||
::memset(&m_LastModTime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
bool CInterlinkMap::LoadFromFile(const std::string &filename)
|
||||
{
|
||||
bool ok = false;
|
||||
char line[256];
|
||||
|
||||
// and load
|
||||
std::ifstream file(filename);
|
||||
if ( file.is_open() )
|
||||
{
|
||||
Lock();
|
||||
|
||||
// empty list
|
||||
m_InterlinkMap.clear();
|
||||
// fill with file content
|
||||
while ( file.getline(line, sizeof(line)).good() )
|
||||
{
|
||||
char *token[4];
|
||||
// remove leading & trailing spaces
|
||||
token[0] = ToUpper(TrimWhiteSpaces(line));
|
||||
// crack it
|
||||
if ( (strlen(token[0]) > 0) && (token[0][0] != '#') )
|
||||
{
|
||||
const char *delim = " \t\r";
|
||||
// 1st token is callsign
|
||||
if ( (token[0] = strtok(token[0], delim)) != nullptr )
|
||||
{
|
||||
if (strcmp(token[0], g_Configure.GetString(g_Keys.names.callsign).c_str()))
|
||||
{
|
||||
// the default port depends on the protocol type (URF or BM)
|
||||
int default_port = (0 == memcmp(token[0], "URF", 3)) ? 10017 : 10002;
|
||||
if (m_InterlinkMap.end() == m_InterlinkMap.find(token[0]))
|
||||
{
|
||||
// read remaining tokens
|
||||
// 1=IP 2=Modules 3=Port Port is optional and defaults to 10017
|
||||
// OR... 1=Modules and the dht will be used
|
||||
for (int i=1; i<4; i++)
|
||||
{
|
||||
token[i] = strtok(nullptr, delim);
|
||||
}
|
||||
|
||||
if (token[2])
|
||||
{
|
||||
int port = default_port;
|
||||
if (token[3])
|
||||
{
|
||||
port = std::atoi(token[3]);
|
||||
if (port < 1024 || port > 49000)
|
||||
{
|
||||
std::cout << token[0] << " Port " << port << " is out of range, resetting to " << default_port << std::endl;
|
||||
port = default_port;
|
||||
}
|
||||
}
|
||||
m_InterlinkMap[token[0]] = CInterlinkMapItem(token[1], token[2], (uint16_t)port);
|
||||
}
|
||||
#ifndef NO_DHT
|
||||
else if (token[1])
|
||||
{
|
||||
m_InterlinkMap[token[0]] = CInterlinkMapItem(token[1]);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
std::cout << token[0] << " has insufficient parameters!" << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Duplicate found: " << token[0] << " in " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Self linking is not allowed! You cannot use " << token[0] << " in " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
// keep file path
|
||||
m_Filename.assign(filename);
|
||||
|
||||
// update time
|
||||
GetLastModTime(&m_LastModTime);
|
||||
|
||||
// and done
|
||||
Unlock();
|
||||
ok = true;
|
||||
std::cout << "Gatekeeper loaded " << m_InterlinkMap.size() << " lines from " << filename << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CInterlinkMap::ReloadFromFile(void)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
if ( ! m_Filename.empty() )
|
||||
{
|
||||
ok = LoadFromFile(m_Filename);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool CInterlinkMap::NeedReload(void)
|
||||
{
|
||||
bool needReload = false;
|
||||
|
||||
time_t time;
|
||||
if ( GetLastModTime(&time) )
|
||||
{
|
||||
needReload = time != m_LastModTime;
|
||||
}
|
||||
return needReload;
|
||||
}
|
||||
|
||||
bool CInterlinkMap::IsCallsignListed(const std::string &callsign, char module) const
|
||||
{
|
||||
const auto item = m_InterlinkMap.find(callsign);
|
||||
if (m_InterlinkMap.cend() == item)
|
||||
return false;
|
||||
else
|
||||
return item->second.HasModuleListed(module);
|
||||
}
|
||||
|
||||
bool CInterlinkMap::IsCallsignListed(const std::string &callsign, const CIp &ip, const char *modules) const
|
||||
{
|
||||
const auto item = m_InterlinkMap.find(callsign);
|
||||
if (m_InterlinkMap.cend() != item)
|
||||
{
|
||||
if ( item->second.CheckListedModules(modules) )
|
||||
{
|
||||
if ( ip == item->second.GetIp() )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "'" << callsign << "' not found in interlink map\n";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
CInterlinkMapItem *CInterlinkMap::FindMapItem(const std::string &cs)
|
||||
{
|
||||
auto it = m_InterlinkMap.find(cs);
|
||||
if (m_InterlinkMap.end() == it)
|
||||
return nullptr;
|
||||
return &it->second;
|
||||
}
|
||||
|
||||
char *CInterlinkMap::TrimWhiteSpaces(char *str)
|
||||
{
|
||||
char *end;
|
||||
|
||||
// Trim leading space & tabs
|
||||
while((*str == ' ') || (*str == '\t')) str++;
|
||||
|
||||
// All spaces?
|
||||
if(*str == 0)
|
||||
return str;
|
||||
|
||||
// Trim trailing space, tab or lf
|
||||
end = str + ::strlen(str) - 1;
|
||||
while((end > str) && ((*end == ' ') || (*end == '\t') || (*end == '\r'))) end--;
|
||||
|
||||
// Write new null terminator
|
||||
*(end+1) = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
bool CInterlinkMap::GetLastModTime(time_t *time)
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
if ( ! m_Filename.empty() )
|
||||
{
|
||||
struct stat fileStat;
|
||||
if( ::stat(m_Filename.c_str(), &fileStat) != -1 )
|
||||
{
|
||||
*time = fileStat.st_mtime;
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
char *CInterlinkMap::ToUpper(char *str)
|
||||
{
|
||||
constexpr auto diff = 'a' - 'A';
|
||||
for (char *p=str; *p; p++)
|
||||
{
|
||||
if (*p >= 'a' && *p <= 'z')
|
||||
*p -= diff;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
#ifndef NO_DHT
|
||||
void CInterlinkMap::Update(const std::string &cs, const std::string &cmods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &emods)
|
||||
{
|
||||
auto it = m_InterlinkMap.find(cs);
|
||||
if (m_InterlinkMap.end() == it)
|
||||
{
|
||||
std::cerr << "Can't Update CInterlinkMap item '" << cs << "' because it doesn't exist!";
|
||||
}
|
||||
else
|
||||
{
|
||||
it->second.UpdateItem(cmods, ipv4, ipv6, port, emods);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,79 @@
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 30/12/2015.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2020 Thomas A. Early, N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of m17ref.
|
||||
//
|
||||
// m17ref 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
|
||||
#include "InterlinkMapItem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CInterlinkMap
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CInterlinkMap();
|
||||
|
||||
// destructor
|
||||
virtual ~CInterlinkMap() {}
|
||||
|
||||
// locks
|
||||
void Lock(void) const { m_Mutex.lock(); }
|
||||
void Unlock(void) const { m_Mutex.unlock(); }
|
||||
|
||||
// file io
|
||||
virtual bool LoadFromFile(const std::string &filename);
|
||||
bool ReloadFromFile(void);
|
||||
bool NeedReload(void);
|
||||
|
||||
#ifndef NO_DHT
|
||||
void Update(const std::string &cs, const std::string &mods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &tcmods);
|
||||
#endif
|
||||
|
||||
// compare
|
||||
bool IsCallsignListed(const std::string &, const char) const;
|
||||
bool IsCallsignListed(const std::string &, const CIp &ip, const char*) const;
|
||||
|
||||
// pass-through
|
||||
bool empty() const { return m_InterlinkMap.empty(); }
|
||||
std::map<std::string, CInterlinkMapItem>::iterator begin() { return m_InterlinkMap.begin(); }
|
||||
std::map<std::string, CInterlinkMapItem>::iterator end() { return m_InterlinkMap.end(); }
|
||||
std::map<std::string, CInterlinkMapItem>::const_iterator cbegin() { return m_InterlinkMap.cbegin(); }
|
||||
std::map<std::string, CInterlinkMapItem>::const_iterator cend() { return m_InterlinkMap.cend(); }
|
||||
|
||||
// find
|
||||
CInterlinkMapItem *FindMapItem(const std::string &);
|
||||
|
||||
protected:
|
||||
bool GetLastModTime(time_t *);
|
||||
char *TrimWhiteSpaces(char *);
|
||||
char *ToUpper(char *str);
|
||||
|
||||
// data
|
||||
mutable std::mutex m_Mutex;
|
||||
std::string m_Filename;
|
||||
time_t m_LastModTime;
|
||||
std::map<std::string, CInterlinkMapItem> m_InterlinkMap;
|
||||
};
|
||||
@ -0,0 +1,143 @@
|
||||
//
|
||||
// ccallsignlistitem.cpp
|
||||
// m17ref
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 31/01/2016.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2020,2022 Thomas A. Early N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of m17ref.
|
||||
//
|
||||
// m17ref 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "Configure.h"
|
||||
#include "InterlinkMapItem.h"
|
||||
#include "Reflector.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// constructor
|
||||
#ifdef NO_DHT
|
||||
CInterlinkMapItem::CInterlinkMapItem()
|
||||
{
|
||||
m_UsesDHT = false;
|
||||
}
|
||||
#else
|
||||
CInterlinkMapItem::CInterlinkMapItem()
|
||||
{
|
||||
m_UsesDHT = false;
|
||||
m_Updated = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NO_DHT
|
||||
CInterlinkMapItem::CInterlinkMapItem(const char *mods)
|
||||
{
|
||||
m_UsesDHT = true;
|
||||
m_Updated = false;
|
||||
m_Mods.assign(mods);
|
||||
}
|
||||
#endif
|
||||
|
||||
CInterlinkMapItem::CInterlinkMapItem(const char *addr, const char *mods, uint16_t port) : CInterlinkMapItem()
|
||||
{
|
||||
m_Mods.assign(mods);
|
||||
m_Ip.Initialize(strchr(addr, ':') ? AF_INET6 : AF_INET, port, addr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// compare
|
||||
|
||||
bool CInterlinkMapItem::HasModuleListed(char module) const
|
||||
{
|
||||
return m_Mods.npos != m_Mods.find(module);
|
||||
}
|
||||
|
||||
bool CInterlinkMapItem::HasSameIp(const CIp &ip)
|
||||
{
|
||||
return ip == m_Ip;
|
||||
}
|
||||
|
||||
bool CInterlinkMapItem::CheckListedModules(const char *mods) const
|
||||
{
|
||||
if (mods == nullptr)
|
||||
return false;
|
||||
|
||||
// make sure every mods character is matched in m_Mods
|
||||
const auto count = m_Mods.size();
|
||||
bool found[count];
|
||||
for (unsigned i=0; i<count; i++)
|
||||
found[i] = false;
|
||||
for (auto p=mods; *p; p++)
|
||||
{
|
||||
auto pos = m_Mods.find(*p);
|
||||
if (pos == m_Mods.npos)
|
||||
return false;
|
||||
else
|
||||
found[pos] = true;
|
||||
}
|
||||
for (unsigned i=0; i<count; i++)
|
||||
{
|
||||
if (! found[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NO_DHT
|
||||
void CInterlinkMapItem::UpdateItem(const std::string &cmods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &tcmods)
|
||||
{
|
||||
if (m_CMods.compare(cmods))
|
||||
{
|
||||
m_CMods.assign(cmods);
|
||||
m_Updated = true;
|
||||
}
|
||||
if (m_IPv4.compare(ipv4))
|
||||
{
|
||||
m_IPv4.assign(ipv4);
|
||||
m_Updated = true;
|
||||
}
|
||||
if (m_IPv6.compare(ipv6))
|
||||
{
|
||||
m_IPv6.assign(ipv6);
|
||||
m_Updated = true;
|
||||
}
|
||||
if (m_Port != port)
|
||||
{
|
||||
m_Port = port;
|
||||
m_Updated = true;
|
||||
}
|
||||
if (m_TCMods.compare(tcmods))
|
||||
{
|
||||
m_TCMods.assign(tcmods);
|
||||
m_Updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CInterlinkMapItem::UpdateIP(bool IPv6NotConfigured)
|
||||
{
|
||||
if (m_Updated)
|
||||
{
|
||||
if (IPv6NotConfigured || m_IPv6.empty())
|
||||
m_Ip.Initialize(AF_INET, m_Port, m_IPv4.c_str());
|
||||
else
|
||||
m_Ip.Initialize(AF_INET6, m_Port, m_IPv6.c_str());
|
||||
|
||||
m_Updated = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,74 @@
|
||||
//
|
||||
// Created by Jean-Luc Deltombe (LX3JL) on 31/01/2016.
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
// Copyright © 2020 Thomas A. Early N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of m17ref.
|
||||
//
|
||||
// m17ref 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// m17ref 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Callsign.h"
|
||||
#include "IP.h"
|
||||
|
||||
class CInterlinkMapItem
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CInterlinkMapItem();
|
||||
#ifndef NO_DHT
|
||||
CInterlinkMapItem(const char *mods);
|
||||
#endif
|
||||
CInterlinkMapItem(const char *addr, const char *mods, uint16_t port);
|
||||
|
||||
// Update things
|
||||
#ifndef NO_DHT
|
||||
void UpdateIP(bool IPv6NotConfigured);
|
||||
void UpdateItem(const std::string &cmods, const std::string &ipv4, const std::string &ipv6, uint16_t port, const std::string &tcmods);
|
||||
#endif
|
||||
|
||||
// compare
|
||||
bool HasSameIp(const CIp &ip);
|
||||
bool HasModuleListed(char) const;
|
||||
bool CheckListedModules(const char*) const;
|
||||
|
||||
// get
|
||||
const CIp &GetIp(void) const { return m_Ip; }
|
||||
const std::string &GetModules(void) const { return m_Mods; }
|
||||
bool UsesDHT(void) const { return m_UsesDHT; }
|
||||
uint16_t GetPort(void) const { return m_Port; }
|
||||
#ifndef NO_DHT
|
||||
const std::string &GetIPv4(void) const { return m_IPv4; }
|
||||
const std::string &GetIPv6(void) const { return m_IPv6; }
|
||||
const std::string &GetTCMods(void) const { return m_TCMods; }
|
||||
const std::string &GetCMods(void) const { return m_CMods; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
// data
|
||||
CIp m_Ip;
|
||||
std::string m_Mods;
|
||||
uint16_t m_Port;
|
||||
bool m_UsesDHT;
|
||||
|
||||
#ifndef NO_DHT
|
||||
bool m_Updated;
|
||||
std::string m_CMods, m_TCMods, m_IPv4, m_IPv6;
|
||||
#endif
|
||||
};
|
||||
@ -1,37 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc. All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
#include "Notification.h"
|
||||
|
||||
CNotification::CNotification()
|
||||
{
|
||||
// init variables
|
||||
m_iId = NOTIFICATION_NONE;
|
||||
}
|
||||
|
||||
CNotification::CNotification(int iId)
|
||||
{
|
||||
m_iId = iId;
|
||||
}
|
||||
|
||||
CNotification::CNotification(int iId, const CCallsign &Callsign)
|
||||
{
|
||||
m_iId = iId;
|
||||
m_Callsign = Callsign;
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc. All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Callsign.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Id
|
||||
#define NOTIFICATION_NONE 0
|
||||
#define NOTIFICATION_CLIENTS 1
|
||||
#define NOTIFICATION_USERS 2
|
||||
#define NOTIFICATION_STREAM_OPEN 3
|
||||
#define NOTIFICATION_STREAM_CLOSE 4
|
||||
#define NOTIFICATION_PEERS 5
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CNotification
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CNotification();
|
||||
CNotification(int);
|
||||
CNotification(int, const CCallsign &);
|
||||
|
||||
// get
|
||||
int GetId(void) const { return m_iId; }
|
||||
const CCallsign &GetCallsign(void) const { return m_Callsign; }
|
||||
|
||||
protected:
|
||||
// data
|
||||
int m_iId;
|
||||
CCallsign m_Callsign;
|
||||
|
||||
};
|
||||
@ -1,49 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc. All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <mutex>
|
||||
|
||||
#include "Notification.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CNotificationQueue
|
||||
{
|
||||
public:
|
||||
// lock
|
||||
void Lock() { m_Mutex.lock(); }
|
||||
void Unlock() { m_Mutex.unlock(); }
|
||||
|
||||
// pass thru
|
||||
CNotification front() { return queue.front(); }
|
||||
void pop() { queue.pop(); }
|
||||
void push(CNotification note) { queue.push(note); }
|
||||
bool empty() const { return queue.empty(); }
|
||||
|
||||
protected:
|
||||
// data
|
||||
std::mutex m_Mutex;
|
||||
std::queue<CNotification> queue;
|
||||
};
|
||||
@ -1,84 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
#include "PeerCallsignList.h"
|
||||
|
||||
bool CPeerCallsignList::LoadFromFile(const std::string &filename)
|
||||
{
|
||||
bool ok = false;
|
||||
char sz[256];
|
||||
|
||||
// and load
|
||||
std::ifstream file (filename);
|
||||
if ( file.is_open() )
|
||||
{
|
||||
Lock();
|
||||
|
||||
// empty list
|
||||
m_Callsigns.clear();
|
||||
// fill with file content
|
||||
while ( file.getline(sz, sizeof(sz)).good() )
|
||||
{
|
||||
// remove leading & trailing spaces
|
||||
char *szt = TrimWhiteSpaces(sz);
|
||||
|
||||
// crack it
|
||||
if ( (::strlen(szt) > 0) && (szt[0] != '#') )
|
||||
{
|
||||
// 1st token is callsign
|
||||
if ( (szt = ::strtok(szt, " ,\t")) != nullptr )
|
||||
{
|
||||
CCallsign callsign(szt);
|
||||
// 2nd token is ip
|
||||
char *szip;
|
||||
if ( (szip = ::strtok(nullptr, " ,\t")) != nullptr )
|
||||
{
|
||||
// 3rd token is modules list
|
||||
if ( (szt = ::strtok(nullptr, " ,\t")) != nullptr )
|
||||
{
|
||||
// and load
|
||||
m_Callsigns.push_back(CCallsignListItem(callsign, szip, szt));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// close file
|
||||
file.close();
|
||||
|
||||
// keep file path
|
||||
m_Filename = filename;
|
||||
|
||||
// update time
|
||||
GetLastModTime(&m_LastModTime);
|
||||
|
||||
// and done
|
||||
Unlock();
|
||||
ok = true;
|
||||
std::cout << "Gatekeeper loaded " << m_Callsigns.size() << " lines from " << filename << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Gatekeeper cannot find " << filename << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
|
||||
|
||||
// urfd -- The universal reflector
|
||||
// Copyright © 2021 Thomas A. Early N7TAE
|
||||
//
|
||||
// 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "CallsignList.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class
|
||||
|
||||
class CPeerCallsignList : public CCallsignList
|
||||
{
|
||||
public:
|
||||
// constructor
|
||||
CPeerCallsignList() {}
|
||||
|
||||
// destructor
|
||||
virtual ~CPeerCallsignList() {}
|
||||
|
||||
// file io
|
||||
bool LoadFromFile(const std::string &filename);
|
||||
};
|
||||
@ -0,0 +1,89 @@
|
||||
// Copyright © 2023 Thomas A. Early, N7TAE
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// This file is part of urfd.
|
||||
//
|
||||
// M17Refd 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 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// M17Refd 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
|
||||
// with this software. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <opendht.h>
|
||||
|
||||
/* HELPERS */
|
||||
#ifndef TO_U_TYPE_DEF
|
||||
#define TO_U_TYPE_DEF
|
||||
template<typename E> constexpr auto toUType(E enumerator) noexcept
|
||||
{
|
||||
return static_cast<std::underlying_type_t<E>>(enumerator);
|
||||
} // Item #10 in "Effective Modern C++", by Scott Meyers, O'REILLY
|
||||
#endif
|
||||
|
||||
enum class EUrfdValueID : uint64_t { Config=1, Peers=2, Clients=3, Users=4 };
|
||||
|
||||
/* PEERS */
|
||||
using UrfdPeerTuple = std::tuple<std::string, std::string, std::time_t>;
|
||||
enum class EUrfdPeerFields { Callsign, Modules, ConnectTime };
|
||||
struct SUrfdPeers1
|
||||
{
|
||||
std::time_t timestamp;
|
||||
unsigned int sequence;
|
||||
std::list<UrfdPeerTuple> list;
|
||||
|
||||
MSGPACK_DEFINE(timestamp, sequence, list)
|
||||
};
|
||||
|
||||
/* CLIENTS */
|
||||
using UrfdClientTuple = std::tuple<std::string, std::string, char, std::time_t, std::time_t>;
|
||||
enum class EUrfdClientFields { Callsign, Ip, Module, ConnectTime, LastHeardTime };
|
||||
struct SUrfdClients1
|
||||
{
|
||||
std::time_t timestamp;
|
||||
unsigned int sequence;
|
||||
std::list<UrfdClientTuple> list;
|
||||
|
||||
MSGPACK_DEFINE(timestamp, sequence, list)
|
||||
};
|
||||
|
||||
/* USERS */
|
||||
using UrfdUserTuple = std::tuple<std::string, std::string, char, std::string, std::time_t>;
|
||||
enum class EUrfdUserFields { Callsign, ViaNode, OnModule, ViaPeer, LastHeardTime };
|
||||
struct SUrfdUsers1
|
||||
{
|
||||
std::time_t timestamp;
|
||||
unsigned int sequence;
|
||||
std::list<UrfdUserTuple> list;
|
||||
|
||||
MSGPACK_DEFINE(timestamp, sequence, list)
|
||||
};
|
||||
|
||||
/* CONFIGURATION */
|
||||
// 'SIZE' has to be last for these scoped enums
|
||||
enum class EUrfdPorts : unsigned { dcs, dextra, dmrplus, dplus, m17, mmdvm, nxdn, p25, urf, ysf, SIZE };
|
||||
enum class EUrfdAlMod : unsigned { nxdn, p25, ysf, SIZE };
|
||||
enum class EUrfdTxRx : unsigned { rx, tx, SIZE };
|
||||
enum class EUrfdRefId : unsigned { nxdn, p25, SIZE };
|
||||
struct SUrfdConfig1
|
||||
{
|
||||
std::time_t timestamp;
|
||||
std::string cs, ipv4, ipv6, mods, tcmods, url, email, sponsor, country, version;
|
||||
std::array<uint16_t, toUType(EUrfdPorts::SIZE)> port;
|
||||
std::array<char, toUType(EUrfdAlMod::SIZE)> almod;
|
||||
std::array<unsigned long, toUType(EUrfdTxRx::SIZE)> ysffreq;
|
||||
std::array<unsigned, toUType(EUrfdRefId::SIZE)> refid;
|
||||
std::unordered_map<char, std::string> description;
|
||||
bool g3enabled;
|
||||
|
||||
MSGPACK_DEFINE(timestamp, cs, ipv4, ipv6, mods, tcmods, url, email, sponsor, country, version, almod, ysffreq, refid, g3enabled, port, description)
|
||||
};
|
||||
Loading…
Reference in new issue