From 92d22f72b39f997a69475e1cec9620dc62db6b89 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 24 Mar 2017 15:37:46 +0000 Subject: [PATCH] Reload the reflector list in a different way to avoid crashes. --- YSFGateway/Reflectors.cpp | 52 ++++++++++++++++++++++++++------------- YSFGateway/Reflectors.h | 7 ++++-- YSFGateway/WiresX.cpp | 19 ++++++++------ 3 files changed, 51 insertions(+), 27 deletions(-) diff --git a/YSFGateway/Reflectors.cpp b/YSFGateway/Reflectors.cpp index 997808e..e465071 100644 --- a/YSFGateway/Reflectors.cpp +++ b/YSFGateway/Reflectors.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -30,7 +30,8 @@ CReflectors::CReflectors(const std::string& hostsFile, unsigned int reloadTime) m_hostsFile(hostsFile), m_parrotAddress(), m_parrotPort(0U), -m_reflectors(), +m_newReflectors(), +m_currReflectors(), m_search(), m_timer(1000U, reloadTime * 60U) { @@ -40,10 +41,14 @@ m_timer(1000U, reloadTime * 60U) CReflectors::~CReflectors() { - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) + for (std::vector::iterator it = m_newReflectors.begin(); it != m_newReflectors.end(); ++it) delete *it; - m_reflectors.clear(); + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) + delete *it; + + m_newReflectors.clear(); + m_currReflectors.clear(); } static bool refComparison(const CYSFReflector* r1, const CYSFReflector* r2) @@ -71,11 +76,7 @@ void CReflectors::setParrot(const std::string& address, unsigned int port) bool CReflectors::load() { - // Clear out the old reflector list - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) - delete *it; - - m_reflectors.clear(); + m_newReflectors.clear(); FILE* fp = ::fopen(m_hostsFile.c_str(), "rt"); if (fp != NULL) { @@ -107,7 +108,7 @@ bool CReflectors::load() refl->m_name.resize(16U, ' '); refl->m_desc.resize(14U, ' '); - m_reflectors.push_back(refl); + m_newReflectors.push_back(refl); } } } @@ -115,7 +116,7 @@ bool CReflectors::load() ::fclose(fp); } - size_t size = m_reflectors.size(); + size_t size = m_newReflectors.size(); LogInfo("Loaded %u YSF reflectors", size); // Add the Parrot entry @@ -127,22 +128,22 @@ bool CReflectors::load() refl->m_address = CUDPSocket::lookup(m_parrotAddress); refl->m_port = m_parrotPort; refl->m_count = "000"; - m_reflectors.push_back(refl); + m_newReflectors.push_back(refl); LogInfo("Loaded YSF parrot"); } - size = m_reflectors.size(); + size = m_newReflectors.size(); if (size == 0U) return false; - std::sort(m_reflectors.begin(), m_reflectors.end(), refComparison); + std::sort(m_newReflectors.begin(), m_newReflectors.end(), refComparison); return true; } CYSFReflector* CReflectors::find(const std::string& id) { - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) { + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) { if (id == (*it)->m_id) return *it; } @@ -154,7 +155,7 @@ CYSFReflector* CReflectors::find(const std::string& id) std::vector& CReflectors::current() { - return m_reflectors; + return m_currReflectors; } std::vector& CReflectors::search(const std::string& name) @@ -167,7 +168,7 @@ std::vector& CReflectors::search(const std::string& name) unsigned int len = trimmed.size(); - for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) { + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) { std::string reflector = (*it)->m_name; reflector.erase(std::find_if(reflector.rbegin(), reflector.rend(), std::not1(std::ptr_fun(std::isspace))).base(), reflector.end()); std::transform(reflector.begin(), reflector.end(), reflector.begin(), ::toupper); @@ -181,6 +182,23 @@ std::vector& CReflectors::search(const std::string& name) return m_search; } +bool CReflectors::reload() +{ + if (m_newReflectors.empty()) + return false; + + for (std::vector::iterator it = m_currReflectors.begin(); it != m_currReflectors.end(); ++it) + delete *it; + + m_currReflectors.clear(); + + m_currReflectors = m_newReflectors; + + m_newReflectors.clear(); + + return true; +} + void CReflectors::clock(unsigned int ms) { m_timer.clock(ms); diff --git a/YSFGateway/Reflectors.h b/YSFGateway/Reflectors.h index 9b15ecd..d1b1d14 100644 --- a/YSFGateway/Reflectors.h +++ b/YSFGateway/Reflectors.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2017 by Jonathan Naylor G4KLX * * 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 @@ -60,13 +60,16 @@ public: std::vector& search(const std::string& name); + bool reload(); + void clock(unsigned int ms); private: std::string m_hostsFile; std::string m_parrotAddress; unsigned int m_parrotPort; - std::vector m_reflectors; + std::vector m_newReflectors; + std::vector m_currReflectors; std::vector m_search; CTimer m_timer; }; diff --git a/YSFGateway/WiresX.cpp b/YSFGateway/WiresX.cpp index ad30767..1f0334e 100644 --- a/YSFGateway/WiresX.cpp +++ b/YSFGateway/WiresX.cpp @@ -497,13 +497,13 @@ void CWiresX::sendDXReply() for (unsigned int i = 0U; i < 5U; i++) data[i + 36U] = m_reflector->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < m_reflector->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + 41U] = m_reflector->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) data[i + 57U] = m_reflector->m_count.at(i); - for (unsigned int i = 0U; i < 14U && i < m_reflector->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + 70U] = m_reflector->m_desc.at(i); } @@ -564,13 +564,13 @@ void CWiresX::sendConnectReply() for (unsigned int i = 0U; i < 5U; i++) data[i + 36U] = m_reflector->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < m_reflector->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + 41U] = m_reflector->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) data[i + 57U] = m_reflector->m_count.at(i); - for (unsigned int i = 0U; i < 14U && i < m_reflector->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + 70U] = m_reflector->m_desc.at(i); data[84U] = '0'; @@ -628,6 +628,9 @@ void CWiresX::sendDisconnectReply() void CWiresX::sendAllReply() { + if (m_start == 0U) + m_reflectors.reload(); + std::vector& curr = m_reflectors.current(); unsigned char data[1100U]; @@ -668,7 +671,7 @@ void CWiresX::sendAllReply() for (unsigned int i = 0U; i < 5U; i++) data[i + offset + 1U] = refl->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < refl->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + offset + 6U] = refl->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) @@ -677,7 +680,7 @@ void CWiresX::sendAllReply() for (unsigned int i = 0U; i < 10U; i++) data[i + offset + 25U] = ' '; - for (unsigned int i = 0U; i < 14U && i < refl->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + offset + 35U] = refl->m_desc.at(i); data[offset + 49U] = 0x0DU; @@ -752,7 +755,7 @@ void CWiresX::sendSearchReply() for (unsigned int i = 0U; i < 5U; i++) data[i + offset + 1U] = refl->m_id.at(i); - for (unsigned int i = 0U; i < 16U && i < refl->m_name.size(); i++) + for (unsigned int i = 0U; i < 16U; i++) data[i + offset + 6U] = refl->m_name.at(i); for (unsigned int i = 0U; i < 3U; i++) @@ -761,7 +764,7 @@ void CWiresX::sendSearchReply() for (unsigned int i = 0U; i < 10U; i++) data[i + offset + 25U] = ' '; - for (unsigned int i = 0U; i < 14U && i < refl->m_desc.size(); i++) + for (unsigned int i = 0U; i < 14U; i++) data[i + offset + 35U] = refl->m_desc.at(i); data[offset + 49U] = 0x0DU;