@ -9,7 +9,7 @@
* @ license GPLv2 License ( https : //opensource.org/licenses/GPL-2.0)
*
* Copyright ( C ) 2016 Jonathan Naylor , G4KLX
* Copyright ( C ) 2017 - 2022 Bryan Biedenkapp , N2PLL
* Copyright ( C ) 2017 - 2022 , 2024 Bryan Biedenkapp , N2PLL
* Copyright ( c ) 2024 Patrick McDonnell , W3AXL
* Copyright ( c ) 2024 Caleb , KO4UYJ
*
@ -35,42 +35,43 @@ std::mutex PeerListLookup::m_mutex;
/// <summary>
/// Initializes a new instance of the PeerListLookup class.
/// </summary>
/// <param name=" listFil e">Full-path to the list file.</param>
/// <param name=" filenam e">Full-path to the list file.</param>
/// <param name="mode">Mode to operate in (WHITELIST or BLACKLIST).</param>
/// <param name=" enabled ">Flag indicating if the lookup is enabled.</param>
PeerListLookup : : PeerListLookup ( const std : : string & listFil e, Mode mode , uint32_t reloadTime , bool enabled)
: LookupTable ( listFile , reloadTime ) , m_mode ( mode ) , m_enabled ( enabled )
/// <param name=" peerAcl ">Flag indicating if the lookup is enabled.</param>
PeerListLookup : : PeerListLookup ( const std : : string & filenam e, Mode mode , uint32_t reloadTime , bool peerAcl) : LookupTable ( filename , reloadTime ) ,
m_acl ( peerAcl ) , m_mode ( mode )
{
/* stub */
}
/// <summary>
/// Get the list of peers in the table.
/// </summary>
std : : vector < uint32_t > PeerListLookup : : getPeerList ( ) const
{
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
return m_list ;
}
/// <summary>
/// Clears all entries from the list.
/// </summary>
void PeerListLookup : : clear ( )
{
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
m_ list . clear ( ) ;
m_table . clear ( ) ;
}
/// <summary>
/// Adds a new entry to the list.
/// </summary>
/// <param name="peerId">Unique peer ID to add.</param>
void PeerListLookup : : addEntry ( uint32_t peerId )
/// <param name="password"></param>
void PeerListLookup : : addEntry ( uint32_t id , const std : : string & password )
{
PeerId entry = PeerId ( id , password , false ) ;
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
if ( std : : find ( m_list . begin ( ) , m_list . end ( ) , peerId ) = = m_list . end ( ) ) {
m_list . push_back ( peerId ) ;
try {
PeerId _entry = m_table . at ( id ) ;
// if either the alias or the enabled flag doesn't match, update the entry
if ( _entry . peerId ( ) = = id ) {
_entry = PeerId ( id , password , false ) ;
m_table [ id ] = _entry ;
}
} catch ( . . . ) {
m_table [ id ] = entry ;
}
}
@ -78,55 +79,89 @@ void PeerListLookup::addEntry(uint32_t peerId)
/// Removes an existing entry from the list.
/// </summary>
/// <param name="peerId">Unique peer ID to remove.</param>
void PeerListLookup : : removeEntry ( uint32_t peerId )
void PeerListLookup : : eraseEntry ( uint32_t id )
{
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
try {
m_table . at ( id ) ;
m_table . erase ( id ) ;
} catch ( . . . ) {
/* stub */
}
}
/// <summary>
/// Finds a table entry in this lookup table.
/// </summary>
/// <param name="id">Unique identifier for table entry.</param>
/// <returns>Table entry.</returns>
PeerId PeerListLookup : : find ( uint32_t id )
{
PeerId entry ;
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
m_list . erase ( std : : remove ( m_list . begin ( ) , m_list . end ( ) , peerId ) , m_list . end ( ) ) ;
try {
entry = m_table . at ( id ) ;
} catch ( . . . ) {
entry = PeerId ( 0U , " " , true ) ;
}
return entry ;
}
/// <summary>
/// Commit the table.
/// </summary>
/// <param name="mode">The mode to set.</param>
void PeerListLookup : : commit ( )
{
save ( ) ;
}
/// <summary>
/// Gets whether the lookup is enabled.
/// </summary>
bool PeerListLookup : : getACL ( ) const
{
return m_acl ;
}
/// <summary>
/// Checks if a peer ID is in the list.
/// </summary>
/// <param name="peerId">Unique peer ID to check.</param>
/// <param name=" i d">Unique peer ID to check.</param>
/// <returns>True if the peer ID is in the list, otherwise false.</returns>
bool PeerListLookup : : isPeerInList ( uint32_t peerId ) const
bool PeerListLookup : : isPeerInList ( uint32_t i d) const
{
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
bool found = std : : find ( m_list . begin ( ) , m_list . end ( ) , peerId ) ! = m_list . end ( ) ;
if ( m_table . find ( id ) ! = m_table . end ( ) ) {
return true ;
}
return found ;
return false ;
}
/// <summary>
/// Checks if a peer ID is allowed based on the mode and enabled flag.
/// </summary>
/// <param name="peerId">Unique peer ID to check.</param>
/// <param name=" i d">Unique peer ID to check.</param>
/// <returns>True if the peer ID is allowed, otherwise false.</returns>
bool PeerListLookup : : isPeerAllowed ( uint32_t peerId ) const
bool PeerListLookup : : isPeerAllowed ( uint32_t i d) const
{
if ( ! m_enabled ) {
if ( ! m_ acl ) {
return true ; // if not enabled, allow all peers
}
bool allowed = false ;
if ( m_mode = = WHITELIST ) {
allowed = isPeerInList ( peerI d) ;
allowed = isPeerInList ( i d) ;
} else if ( m_mode = = BLACKLIST ) {
allowed = ! isPeerInList ( peerI d) ;
allowed = ! isPeerInList ( i d) ;
}
return allowed ;
}
/// <summary>
/// Commit the table.
/// </summary>
/// <param name="mode">The mode to set.</param>
void PeerListLookup : : commit ( )
{
save ( ) ;
}
/// <summary>
/// Sets the mode to either WHITELIST or BLACKLIST.
/// </summary>
@ -145,39 +180,6 @@ PeerListLookup::Mode PeerListLookup::getMode() const
return m_mode ;
}
/// <summary>
/// Sets whether the lookup is enabled.
/// </summary>
/// <param name="enabled">Flag indicating if the lookup is enabled.</param>
void PeerListLookup : : setEnabled ( bool enabled )
{
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
m_enabled = enabled ;
}
/// <summary>
/// Gets whether the lookup is enabled.
/// </summary>
bool PeerListLookup : : getEnabled ( ) const
{
return m_enabled ;
}
/// <summary>
/// Finds a table entry in this lookup table.
/// </summary>
/// <param name="id">Unique identifier for table entry.</param>
/// <returns>Table entry.</returns>
uint32_t PeerListLookup : : find ( uint32_t id )
{
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
if ( isPeerInList ( id ) ) {
return id ;
} else {
return 0 ;
}
}
// ---------------------------------------------------------------------------
// Private Class Members
// ---------------------------------------------------------------------------
@ -198,28 +200,57 @@ bool PeerListLookup::load()
return false ;
}
m_ list . clear ( ) ;
m_ table . clear ( ) ;
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
// read lines from file
std : : string line ;
while ( std : : getline ( file , line ) ) {
if ( line . length ( ) > 0 ) {
if ( line . at ( 0 ) = = ' # ' ) {
// Skip comments with #
if ( line . at ( 0 ) = = ' # ' )
continue ;
}
uint32_t peerId = : : strtoul ( line . c_str ( ) , nullptr , 10 ) ;
if ( peerId ! = 0 ) {
m_list . push_back ( peerId ) ;
LogDebug ( LOG_HOST , " Loaded peer ID %u into peer lookup table " , peerId ) ;
// tokenize line
std : : string next ;
std : : vector < std : : string > parsed ;
char delim = ' , ' ;
for ( char c : line ) {
if ( c = = delim ) {
if ( ! next . empty ( ) ) {
parsed . push_back ( next ) ;
next . clear ( ) ;
}
}
else
next + = c ;
}
if ( ! next . empty ( ) )
parsed . push_back ( next ) ;
// parse tokenized line
uint32_t id = : : atoi ( parsed [ 0 ] . c_str ( ) ) ;
// Check for an optional alias field
if ( parsed . size ( ) > = 2 ) {
m_table [ id ] = PeerId ( id , parsed [ 1 ] , false ) ;
LogDebug ( LOG_HOST , " Loaded peer ID %u into peer ID lookup table, using unique peer password " , id ) ;
} else {
m_table [ id ] = PeerId ( id , " " , false ) ;
LogDebug ( LOG_HOST , " Loaded peer ID %u into peer ID lookup table, using master password " , id ) ;
}
}
}
file . close ( ) ;
LogInfoEx ( LOG_HOST , " Loaded %lu peers into list " , m_list . size ( ) ) ;
return ! m_list . empty ( ) ;
size_t size = m_table . size ( ) ;
if ( size = = 0U )
return false ;
LogInfoEx ( LOG_HOST , " Loaded %lu peers into list " , size ) ;
return true ;
}
/// <summary>
@ -240,14 +271,39 @@ bool PeerListLookup::save()
return false ;
}
// Counter for lines written
unsigned int lines = 0 ;
std : : lock_guard < std : : mutex > lock ( m_mutex ) ;
for ( auto & peerId : m_list ) {
file < < peerId < < " \n " ;
// String for writing
std : : string line ;
// iterate over each entry in the RID lookup and write it to the open file
for ( auto & entry : m_table ) {
// Get the parameters
uint32_t peerId = entry . first ;
std : : string password = entry . second . peerPassword ( ) ;
// Format into a string
line = std : : to_string ( peerId ) + " , " ;
// Add the alias if we have one
if ( password . length ( ) > 0 ) {
line + = password ;
line + = " , " ;
}
// Add the newline
line + = " \n " ;
// Write to file
file < < line ;
// Increment
lines + + ;
}
file . close ( ) ;
LogInfoEx ( LOG_HOST , " Saved %lu peers to list " , m_list . size ( ) ) ;
if ( lines ! = m_table . size ( ) )
return false ;
LogInfoEx ( LOG_HOST , " Saved %u entries to lookup table file %s " , lines , m_filename . c_str ( ) ) ;
return true ;
}