diff --git a/Common/Common.vcxproj b/Common/Common.vcxproj
index bdbcfc3..abf30b4 100644
--- a/Common/Common.vcxproj
+++ b/Common/Common.vcxproj
@@ -189,6 +189,7 @@
+
@@ -260,6 +261,7 @@
+
diff --git a/Common/G2ProtocolHandler.cpp b/Common/G2ProtocolHandler.cpp
index 50735c9..fe9d5f6 100644
--- a/Common/G2ProtocolHandler.cpp
+++ b/Common/G2ProtocolHandler.cpp
@@ -147,7 +147,7 @@ CAMBEData* CG2ProtocolHandler::readAMBE(in_addr remoteAddress, unsigned int remo
return data;
}
-void CG2ProtocolHandler::punchUDPHole(const wxString& address)
+void CG2ProtocolHandler::traverseNat(const wxString& address)
{
unsigned char buffer[1];
::memset(buffer, 0, 1);
diff --git a/Common/G2ProtocolHandler.h b/Common/G2ProtocolHandler.h
index b9ff1fa..088af25 100644
--- a/Common/G2ProtocolHandler.h
+++ b/Common/G2ProtocolHandler.h
@@ -52,7 +52,7 @@ public:
CHeaderData* readHeader(in_addr incomingAddress, unsigned int incomingPort);
CAMBEData* readAMBE(in_addr incomingAddress, unsigned int incomingPort);
- void punchUDPHole(const wxString& addr);
+ void traverseNat(const wxString& addr);
void close();
diff --git a/Common/Makefile b/Common/Makefile
index 0243a4b..e215ea2 100644
--- a/Common/Makefile
+++ b/Common/Makefile
@@ -4,7 +4,7 @@ OBJECTS = AMBEData.o AnnouncementUnit.o APRSCollector.o APRSWriter.o APRSWriterT
DPlusAuthenticator.o DPlusHandler.o DPlusProtocolHandler.o DPlusProtocolHandlerPool.o DRATSServer.o DTMF.o \
DummyRepeaterProtocolHandler.o DVTOOLFileReader.o EchoUnit.o G2Handler.o G2ProtocolHandler.o GatewayCache.o \
HBRepeaterProtocolHandler.o HeaderData.o HeaderLogger.o HeardData.o HostFile.o IcomRepeaterProtocolHandler.o IRCDDBGatewayConfig.o \
- LogEvent.o Logger.o PollData.o RemoteHandler.o RemoteLinkData.o RemoteProtocolHandler.o RemoteRepeaterData.o RemoteStarNetGroup.o \
+ LogEvent.o Logger.o NatTraversalHandler.o PollData.o RemoteHandler.o RemoteLinkData.o RemoteProtocolHandler.o RemoteRepeaterData.o RemoteStarNetGroup.o \
RemoteStarNetUser.o RepeaterCache.o RepeaterHandler.o SHA256.o SlowDataEncoder.o StarNetHandler.o StatusData.o \
TCPReaderWriterClient.o TCPReaderWriterServer.o TextCollector.o TextData.o Timer.o UDPReaderWriter.o UserCache.o Utils.o \
VersionUnit.o XLXHostsFileDownloader.o
diff --git a/Common/NatTraversalHandler.cpp b/Common/NatTraversalHandler.cpp
new file mode 100644
index 0000000..052c5d9
--- /dev/null
+++ b/Common/NatTraversalHandler.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010,2011,2012,2013,2014,2015,2016,2017,2018 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
+ * 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 "NatTraversalHandler.h"
+
+const unsigned int CACHE_SIZE = 500U;
+
+CNatTraversalHandler::CNatTraversalHandler() :
+m_g2cache(CACHE_SIZE),
+m_g2Handler(NULL)
+{
+
+}
+
+CNatTraversalHandler::~CNatTraversalHandler()
+{
+ for (CNatTraversalCache_t::iterator it = m_g2cache.begin(); it != m_g2cache.end(); ++it)
+ delete it->second;
+}
+
+void CNatTraversalHandler::setG2Handler(CG2ProtocolHandler * handler)
+{
+ m_g2Handler = handler;
+}
+
+void CNatTraversalHandler::traverseNatG2(const wxString& address)
+{
+ if(m_g2Handler != NULL){
+ CNatTraversalRecord* record = m_g2cache[address];
+
+ if(record == NULL) {
+ record = new CNatTraversalRecord(address);
+ m_g2cache[address] = record;
+ }
+
+ std::time_t currentTime = std::time(NULL);
+ if(currentTime - record->getTimestamp() > G2_TRAVERSAL_TIMEOUT) {
+ record->setTimestamp(currentTime);
+ m_g2Handler->traverseNat(address);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Common/NatTraversalHandler.h b/Common/NatTraversalHandler.h
new file mode 100644
index 0000000..b494dff
--- /dev/null
+++ b/Common/NatTraversalHandler.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010,2011,2012,2013,2014,2015,2016,2017,2018 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
+ * 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 NatTraversalHandler_H
+#define NatTraversalHandler_H
+
+#define G2_TRAVERSAL_TIMEOUT 120 //seconds
+
+#include "G2ProtocolHandler.h"
+
+#include
+#include
+
+enum NAT_TRAVERSAL_TYPE {
+ NTT_G2,
+ //NTT_DEXTRA
+ //NTT_DCS
+ //NTT_DPLUS
+};
+
+class CNatTraversalRecord {
+public:
+ CNatTraversalRecord(const wxString& address) :
+ m_address(address),
+ m_timestamp(0)
+ {
+ }
+
+ std::time_t getTimestamp() const
+ {
+ return m_timestamp;
+ }
+
+ void setTimestamp(std::time_t timestamp)
+ {
+ m_timestamp = timestamp;
+ }
+
+private:
+ wxString m_address;
+ std::time_t m_timestamp;
+};
+
+WX_DECLARE_STRING_HASH_MAP(CNatTraversalRecord*, CNatTraversalCache_t);
+
+/*
+* This keeps track of when we UDP punched to one destination so to avoid unnecessary traffic on each ircddb reporting
+*/
+class CNatTraversalHandler {
+public:
+ CNatTraversalHandler();
+ ~CNatTraversalHandler();
+
+ void setG2Handler(CG2ProtocolHandler* handler);
+ void traverseNatG2(const wxString& address);
+
+private:
+ CNatTraversalCache_t m_g2cache;
+ CG2ProtocolHandler* m_g2Handler;
+};
+
+#endif
\ No newline at end of file
diff --git a/ircDDBGateway/IRCDDBGatewayThread.cpp b/ircDDBGateway/IRCDDBGatewayThread.cpp
index 0ab6978..fc2aa91 100644
--- a/ircDDBGateway/IRCDDBGatewayThread.cpp
+++ b/ircDDBGateway/IRCDDBGatewayThread.cpp
@@ -72,6 +72,7 @@ m_dextraPool(NULL),
m_dplusPool(NULL),
m_dcsPool(NULL),
m_g2Handler(NULL),
+m_natTraversal(NULL),
m_aprsWriter(NULL),
m_irc(NULL),
m_cache(),
@@ -217,6 +218,11 @@ void CIRCDDBGatewayThread::run()
m_g2Handler = NULL;
}
+ if(m_g2Handler != NULL) {
+ m_natTraversal = new CNatTraversalHandler();
+ m_natTraversal->setG2Handler(m_g2Handler);
+ }
+
// Wait here until we have the essentials to run
while (!m_killed && (m_dextraPool == NULL || m_dplusPool == NULL || m_dcsPool == NULL || m_g2Handler == NULL || (m_icomRepeaterHandler == NULL && m_hbRepeaterHandler == NULL && m_dummyRepeaterHandler == NULL) || m_gatewayCallsign.IsEmpty()))
::wxMilliSleep(500UL); // 1/2 sec
@@ -719,7 +725,7 @@ void CIRCDDBGatewayThread::processIrcDDB()
if (!address.IsEmpty()) {
wxLogMessage(wxT("USER: %s %s %s %s"), user.c_str(), repeater.c_str(), gateway.c_str(), address.c_str());
m_cache.updateUser(user, repeater, gateway, address, timestamp, DP_DEXTRA, false, false);
- m_g2Handler->punchUDPHole(address);
+ m_natTraversal->traverseNatG2(address);
} else {
wxLogMessage(wxT("USER: %s NOT FOUND"), user.c_str());
}
@@ -735,7 +741,7 @@ void CIRCDDBGatewayThread::processIrcDDB()
if (!address.IsEmpty()) {
wxLogMessage(wxT("REPEATER: %s %s %s"), repeater.c_str(), gateway.c_str(), address.c_str());
m_cache.updateRepeater(repeater, gateway, address, DP_DEXTRA, false, false);
- m_g2Handler->punchUDPHole(address);
+ m_natTraversal->traverseNatG2(address);
} else {
wxLogMessage(wxT("REPEATER: %s NOT FOUND"), repeater.c_str());
}
@@ -756,7 +762,7 @@ void CIRCDDBGatewayThread::processIrcDDB()
if (!address.IsEmpty()) {
wxLogMessage(wxT("GATEWAY: %s %s"), gateway.c_str(), address.c_str());
m_cache.updateGateway(gateway, address, DP_DEXTRA, false, false);
- m_g2Handler->punchUDPHole(address);
+ m_natTraversal->traverseNatG2(address);
} else {
wxLogMessage(wxT("GATEWAY: %s NOT FOUND"), gateway.c_str());
}
diff --git a/ircDDBGateway/IRCDDBGatewayThread.h b/ircDDBGateway/IRCDDBGatewayThread.h
index e3cc863..6862b63 100644
--- a/ircDDBGateway/IRCDDBGatewayThread.h
+++ b/ircDDBGateway/IRCDDBGatewayThread.h
@@ -28,6 +28,7 @@
#include "IRCDDBGatewayStatusData.h"
#include "DCSProtocolHandlerPool.h"
#include "G2ProtocolHandler.h"
+#include "NatTraversalHandler.h"
#include "RemoteHandler.h"
#include "CacheManager.h"
#include "CallsignList.h"
@@ -92,6 +93,7 @@ private:
CDPlusProtocolHandlerPool* m_dplusPool;
CDCSProtocolHandlerPool* m_dcsPool;
CG2ProtocolHandler* m_g2Handler;
+ CNatTraversalHandler* m_natTraversal;
CAPRSWriter* m_aprsWriter;
CIRCDDB* m_irc;
CCacheManager m_cache;