#16 Add G2 Pool, start some IPV6 changes

pull/32/head
Geoffrey Merck 4 years ago
parent 53b5d469a8
commit 4d4f9f3a52

@ -24,6 +24,7 @@
#include "AMBEData.h" #include "AMBEData.h"
#include "DStarDefines.h" #include "DStarDefines.h"
#include "Utils.h" #include "Utils.h"
#include "NetUtils.h"
CAMBEData::CAMBEData() : CAMBEData::CAMBEData() :
m_rptSeq(0U), m_rptSeq(0U),
@ -582,6 +583,17 @@ unsigned int CAMBEData::getMyPort() const
return m_myPort; return m_myPort;
} }
struct sockaddr_storage CAMBEData::getDestination() const
{
struct sockaddr_storage dest;
::memset(&dest, 0, sizeof(sockaddr_storage));
dest.ss_family = AF_INET;
TOIPV4(dest)->sin_addr = m_yourAddress;
TOIPV4(dest)->sin_port = htons(m_yourPort);
return dest;
}
CHeaderData& CAMBEData::getHeader() CHeaderData& CAMBEData::getHeader()
{ {
return m_header; return m_header;

@ -77,6 +77,7 @@ public:
in_addr getYourAddress() const; in_addr getYourAddress() const;
unsigned int getYourPort() const; unsigned int getYourPort() const;
struct sockaddr_storage getDestination() const;
unsigned int getMyPort() const; unsigned int getMyPort() const;
unsigned int getErrors() const; unsigned int getErrors() const;

@ -198,7 +198,7 @@ void* CDStarGatewayThread::Entry()
CLog::logError("Failed to allocate incoming DCS handler\n"); CLog::logError("Failed to allocate incoming DCS handler\n");
} }
m_g2Handler = new CG2ProtocolHandler(G2_DV_PORT, m_gatewayAddress); m_g2Handler = new CG2ProtocolHandlerPool(G2_DV_PORT, m_gatewayAddress);
bool ret = m_g2Handler->open(); bool ret = m_g2Handler->open();
if (!ret) { if (!ret) {
CLog::logError("Could not open the G2 protocol handler"); CLog::logError("Could not open the G2 protocol handler");
@ -232,7 +232,7 @@ void* CDStarGatewayThread::Entry()
loadGateways(); loadGateways();
loadAllReflectors(); loadAllReflectors();
CG2Handler::setG2ProtocolHandler(m_g2Handler); CG2Handler::setG2ProtocolHandlerPool(m_g2Handler);
CG2Handler::setHeaderLogger(headerLogger); CG2Handler::setHeaderLogger(headerLogger);
CDExtraHandler::setCallsign(m_gatewayCallsign); CDExtraHandler::setCallsign(m_gatewayCallsign);
@ -250,7 +250,7 @@ void* CDStarGatewayThread::Entry()
CDCSHandler::setHeaderLogger(headerLogger); CDCSHandler::setHeaderLogger(headerLogger);
CRepeaterHandler::setLocalAddress(m_gatewayAddress); CRepeaterHandler::setLocalAddress(m_gatewayAddress);
CRepeaterHandler::setG2Handler(m_g2Handler); CRepeaterHandler::setG2HandlerPool(m_g2Handler);
if (m_irc != NULL) if (m_irc != NULL)
CRepeaterHandler::setIRC(m_irc); CRepeaterHandler::setIRC(m_irc);
@ -284,7 +284,7 @@ void* CDStarGatewayThread::Entry()
#ifdef USE_STARNET #ifdef USE_STARNET
CStarNetHandler::setCache(&m_cache); CStarNetHandler::setCache(&m_cache);
CStarNetHandler::setGateway(m_gatewayCallsign); CStarNetHandler::setGateway(m_gatewayCallsign);
CStarNetHandler::setG2Handler(m_g2Handler); CStarNetHandler::setG2HandlerPool(m_g2Handler);
if (m_irc != NULL) if (m_irc != NULL)
CStarNetHandler::setIRC(m_irc); CStarNetHandler::setIRC(m_irc);

@ -28,7 +28,7 @@
#include "RepeaterProtocolHandler.h" #include "RepeaterProtocolHandler.h"
#include "DStarGatewayStatusData.h" #include "DStarGatewayStatusData.h"
#include "DCSProtocolHandlerPool.h" #include "DCSProtocolHandlerPool.h"
#include "G2ProtocolHandler.h" #include "G2ProtocolHandlerPool.h"
#include "RemoteHandler.h" #include "RemoteHandler.h"
#include "CacheManager.h" #include "CacheManager.h"
#include "CallsignList.h" #include "CallsignList.h"
@ -102,7 +102,7 @@ private:
CDExtraProtocolHandlerPool* m_dextraPool; CDExtraProtocolHandlerPool* m_dextraPool;
CDPlusProtocolHandlerPool* m_dplusPool; CDPlusProtocolHandlerPool* m_dplusPool;
CDCSProtocolHandlerPool* m_dcsPool; CDCSProtocolHandlerPool* m_dcsPool;
CG2ProtocolHandler* m_g2Handler; CG2ProtocolHandlerPool* m_g2Handler;
CAPRSHandler* m_aprsWriter; CAPRSHandler* m_aprsWriter;
CIRCDDB* m_irc; CIRCDDB* m_irc;
CCacheManager m_cache; CCacheManager m_cache;

@ -31,7 +31,7 @@
unsigned int CG2Handler::m_maxRoutes = 0U; unsigned int CG2Handler::m_maxRoutes = 0U;
CG2Handler** CG2Handler::m_routes = NULL; CG2Handler** CG2Handler::m_routes = NULL;
CG2ProtocolHandler* CG2Handler::m_handler = NULL; CG2ProtocolHandlerPool* CG2Handler::m_handler = NULL;
CHeaderLogger* CG2Handler::m_headerLogger = NULL; CHeaderLogger* CG2Handler::m_headerLogger = NULL;
@ -60,7 +60,7 @@ void CG2Handler::initialise(unsigned int maxRoutes)
m_routes[i] = NULL; m_routes[i] = NULL;
} }
void CG2Handler::setG2ProtocolHandler(CG2ProtocolHandler* handler) void CG2Handler::setG2ProtocolHandlerPool(CG2ProtocolHandlerPool* handler)
{ {
assert(handler != NULL); assert(handler != NULL);

@ -22,7 +22,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include "G2ProtocolHandler.h" #include "G2ProtocolHandlerPool.h"
#include "RepeaterHandler.h" #include "RepeaterHandler.h"
#include "DStarDefines.h" #include "DStarDefines.h"
#include "HeaderLogger.h" #include "HeaderLogger.h"
@ -34,7 +34,7 @@ class CG2Handler {
public: public:
static void initialise(unsigned int maxRoutes); static void initialise(unsigned int maxRoutes);
static void setG2ProtocolHandler(CG2ProtocolHandler* handler); static void setG2ProtocolHandlerPool(CG2ProtocolHandlerPool* handler);
static void setHeaderLogger(CHeaderLogger* logger); static void setHeaderLogger(CHeaderLogger* logger);
static void process(CHeaderData& header); static void process(CHeaderData& header);
@ -54,7 +54,7 @@ private:
static unsigned int m_maxRoutes; static unsigned int m_maxRoutes;
static CG2Handler** m_routes; static CG2Handler** m_routes;
static CG2ProtocolHandler* m_handler; static CG2ProtocolHandlerPool* m_handler;
static CHeaderLogger* m_headerLogger; static CHeaderLogger* m_headerLogger;

@ -18,6 +18,7 @@
*/ */
#include <string> #include <string>
#include <cstring>
#include "G2ProtocolHandler.h" #include "G2ProtocolHandler.h"
#include "Utils.h" #include "Utils.h"
@ -27,26 +28,20 @@
const unsigned int BUFFER_LENGTH = 255U; const unsigned int BUFFER_LENGTH = 255U;
CG2ProtocolHandler::CG2ProtocolHandler(unsigned int port, const std::string& addr) : CG2ProtocolHandler::CG2ProtocolHandler(CUDPReaderWriter* socket, const struct sockaddr_storage& destination, unsigned int bufferSize) :
m_socket(addr, port), m_socket(socket),
m_type(GT_NONE), m_type(GT_NONE),
m_buffer(NULL), m_buffer(nullptr),
m_length(0U), m_length(0U),
m_address(), m_address(destination)
m_port(0U)
{ {
m_buffer = new unsigned char[BUFFER_LENGTH]; m_buffer = new unsigned char[bufferSize];
::memset(m_buffer, 0, bufferSize);
} }
CG2ProtocolHandler::~CG2ProtocolHandler() CG2ProtocolHandler::~CG2ProtocolHandler()
{ {
delete[] m_buffer; delete[] m_buffer;
m_portmap.clear();
}
bool CG2ProtocolHandler::open()
{
return m_socket.open();
} }
bool CG2ProtocolHandler::writeHeader(const CHeaderData& header) bool CG2ProtocolHandler::writeHeader(const CHeaderData& header)
@ -58,12 +53,12 @@ bool CG2ProtocolHandler::writeHeader(const CHeaderData& header)
CUtils::dump("Sending Header", buffer, length); CUtils::dump("Sending Header", buffer, length);
#endif #endif
in_addr addr = header.getYourAddress(); assert(CNetUtils::match(header.getDestination(), m_address, IMT_ADDRESS_ONLY));
auto found = m_portmap.find(addr.s_addr);
unsigned int port = (m_portmap.end()==found) ? header.getYourPort() : found->second; //CLog::logTrace("Write header to %s:%u", inet_ntoa(addr), ntohs(TOIPV4(m_address)->sin_port));
for (unsigned int i = 0U; i < 5U; i++) { for (unsigned int i = 0U; i < 5U; i++) {
bool res = m_socket.write(buffer, length, addr, port); bool res = m_socket->write(buffer, length, m_address);
if (!res) if (!res)
return false; return false;
} }
@ -80,58 +75,34 @@ bool CG2ProtocolHandler::writeAMBE(const CAMBEData& data)
CUtils::dump("Sending Data", buffer, length); CUtils::dump("Sending Data", buffer, length);
#endif #endif
in_addr addr = data.getYourAddress(); assert(CNetUtils::match(data.getDestination(), m_address, IMT_ADDRESS_ONLY));
auto found = m_portmap.find(addr.s_addr); //CLog::logTrace("Write ambe to %s:%u", inet_ntoa(addr), ntohs(TOIPV4(m_address)->sin_port));
unsigned int port = (m_portmap.end()==found) ? data.getYourPort() : found->second; return m_socket->write(buffer, length, m_address);
return m_socket.write(buffer, length, addr, port);
} }
G2_TYPE CG2ProtocolHandler::read() bool CG2ProtocolHandler::setBuffer(unsigned char * buffer, int length)
{ {
bool res = true; assert(buffer != nullptr);
// Loop until we have no more data from the socket or we have data for the higher layers
while (res)
res = readPackets();
return m_type;
}
bool CG2ProtocolHandler::readPackets()
{
m_type = GT_NONE; m_type = GT_NONE;
::memcpy(m_buffer, buffer, length);
// No more data? if(length <= 0)
int length = m_socket.read(m_buffer, BUFFER_LENGTH, m_address, m_port);
if (length <= 0)
return false; return false;
if(length == 1) {
CLog::logDebug("G2 Nat traversal packet received");
}
m_length = length; m_length = length;
// save the incoming port (this is to enable mobile hotspots)
if (m_portmap.end() == m_portmap.find(m_address.s_addr)) {
CLog::logInfo("G2 new address %s on port %u\n", inet_ntoa(m_address), m_port);
m_portmap[m_address.s_addr] = m_port;
} else {
if (m_portmap[m_address.s_addr] != m_port) {
CLog::logInfo("G2 new port for %s is %u, was %u\n", inet_ntoa(m_address), m_port, m_portmap[m_address.s_addr]);
m_portmap[m_address.s_addr] = m_port;
}
}
if (m_buffer[0] != 'D' || m_buffer[1] != 'S' || m_buffer[2] != 'V' || m_buffer[3] != 'T') { if (m_buffer[0] != 'D' || m_buffer[1] != 'S' || m_buffer[2] != 'V' || m_buffer[3] != 'T') {
CLog::logTrace("DSVT");
return true; return true;
} else { } else {
// Header or data packet type? // Header or data packet type?
if ((m_buffer[14] & 0x80) == 0x80) if ((m_buffer[14] & 0x80) == 0x80) {
m_type = GT_HEADER; m_type = GT_HEADER;
else }
else {
m_type = GT_AMBE; m_type = GT_AMBE;
}
return false; return false;
} }
@ -140,15 +111,16 @@ bool CG2ProtocolHandler::readPackets()
CHeaderData* CG2ProtocolHandler::readHeader() CHeaderData* CG2ProtocolHandler::readHeader()
{ {
if (m_type != GT_HEADER) if (m_type != GT_HEADER)
return NULL; return nullptr;
m_type = GT_NONE; // Header data has been consumed, reset our status
CHeaderData* header = new CHeaderData; CHeaderData* header = new CHeaderData;
// G2 checksums are unreliable // G2 checksums are unreliable
bool res = header->setG2Data(m_buffer, m_length, false, m_address, m_port); bool res = header->setG2Data(m_buffer, m_length, false, TOIPV4(m_address)->sin_addr, ntohs(GETPORT(m_address)));
if (!res) { if (!res) {
delete header; delete header;
return NULL; return nullptr;
} }
return header; return header;
@ -159,9 +131,10 @@ CAMBEData* CG2ProtocolHandler::readAMBE()
if (m_type != GT_AMBE) if (m_type != GT_AMBE)
return NULL; return NULL;
m_type = GT_NONE; // Ambe data has been consumed, reset our status
CAMBEData* data = new CAMBEData; CAMBEData* data = new CAMBEData;
bool res = data->setG2Data(m_buffer, m_length, m_address, m_port); bool res = data->setG2Data(m_buffer, m_length, TOIPV4(m_address)->sin_addr, ntohs(GETPORT(m_address)));
if (!res) { if (!res) {
delete data; delete data;
return NULL; return NULL;
@ -169,19 +142,3 @@ CAMBEData* CG2ProtocolHandler::readAMBE()
return data; return data;
} }
void CG2ProtocolHandler::close()
{
m_socket.close();
}
void CG2ProtocolHandler::traverseNat(const std::string& address)
{
unsigned char buffer = 0x00U;
in_addr addr = CUDPReaderWriter::lookup(address);
CLog::logInfo("G2 Punching hole to %s", address.c_str());
m_socket.write(&buffer, 1U, addr, G2_DV_PORT);
}

@ -21,7 +21,6 @@
#include <unordered_map> #include <unordered_map>
#include <sys/socket.h> #include <sys/socket.h>
#include <boost/container_hash/hash.hpp>
#include "UDPReaderWriter.h" #include "UDPReaderWriter.h"
#include "DStarDefines.h" #include "DStarDefines.h"
@ -35,40 +34,9 @@ enum G2_TYPE {
GT_AMBE GT_AMBE
}; };
// struct sockaddr_storage_map {
// struct comp {
// bool operator() (const struct sockaddr_storage& a, const struct sockaddr_storage& b) const {
// return CNetUtils::match(a, b, IMT_ADDRESS_AND_PORT);
// }
// };
// struct hash {
// std::size_t operator() (const sockaddr_storage& a) const {
// switch(a.ss_family)
// {
// case AF_INET: {
// auto ptr4 = ((struct sockaddr_in *)&a);
// size_t res = AF_INET;
// boost::hash_combine(res, ptr4->sin_addr.s_addr);
// boost::hash_combine(res, ptr4->sin_port);
// return res;
// }
// case AF_INET6: {
// auto ptr6 = ((struct sockaddr_in6 *)&a);
// size_t res = AF_INET6;
// boost::hash_combine(res, ptr6->sin6_port);
// boost::hash_combine(res, ptr6->sin6_addr);
// return res;
// }
// default:
// return 0U;
// }
// }
// };
// };
class CG2ProtocolHandler { class CG2ProtocolHandler {
public: public:
CG2ProtocolHandler(unsigned int port, const std::string& addr = std::string("")); CG2ProtocolHandler(CUDPReaderWriter* socket, const struct sockaddr_storage& destination, unsigned int bufferSize);
~CG2ProtocolHandler(); ~CG2ProtocolHandler();
bool open(); bool open();
@ -76,22 +44,24 @@ public:
bool writeHeader(const CHeaderData& header); bool writeHeader(const CHeaderData& header);
bool writeAMBE(const CAMBEData& data); bool writeAMBE(const CAMBEData& data);
G2_TYPE read();
CHeaderData* readHeader(); CHeaderData* readHeader();
CAMBEData* readAMBE(); CAMBEData* readAMBE();
struct sockaddr_storage getDestination() { return m_address; }
G2_TYPE getType() { return m_type; }
bool setBuffer(unsigned char * buffer, int length);
void close(); void close();
void traverseNat(const std::string& address);
private: private:
std::unordered_map<uint32_t, unsigned int> m_portmap;
CUDPReaderWriter m_socket; CUDPReaderWriter * m_socket;
G2_TYPE m_type; G2_TYPE m_type;
unsigned char* m_buffer; unsigned char* m_buffer;
unsigned int m_length; unsigned int m_length;
in_addr m_address; struct sockaddr_storage m_address;
unsigned int m_port;
bool readPackets(); bool readPackets();
}; };

@ -0,0 +1,169 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck 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 "Log.h"
#include "G2ProtocolHandlerPool.h"
const unsigned int G2_BUFFER_LENGTH = 255U;
CG2ProtocolHandlerPool::CG2ProtocolHandlerPool(unsigned short port, const std::string& address) :
m_address(address),
m_basePort(port),
m_socket(address, port)
{
assert(port > 0U);
m_index = m_pool.end();
}
CG2ProtocolHandlerPool::~CG2ProtocolHandlerPool()
{
}
bool CG2ProtocolHandlerPool::open()
{
bool res = m_socket.open();
return res;
}
void CG2ProtocolHandlerPool::close()
{
for(auto handler : m_pool) {
delete handler;
}
m_pool.clear();
m_index = m_pool.end();
m_socket.close();
}
G2_TYPE CG2ProtocolHandlerPool::read()
{
bool res = true;
while(res)
res = readPackets();
if(m_index == m_pool.end())
m_index = m_pool.begin();
while(m_index != m_pool.end()) {
if((*m_index)->getType() != GT_NONE) {
return (*m_index)->getType();
}
m_index++;
}
return GT_NONE;
}
CAMBEData * CG2ProtocolHandlerPool::readAMBE()
{
if(m_index == m_pool.end() || (*m_index)->getType() != GT_AMBE)
return nullptr;
return (*m_index)->readAMBE();
}
CHeaderData * CG2ProtocolHandlerPool::readHeader()
{
if(m_index == m_pool.end() || (*m_index)->getType() != GT_HEADER)
return nullptr;
return (*m_index)->readHeader();
}
bool CG2ProtocolHandlerPool::readPackets()
{
unsigned char buffer[G2_BUFFER_LENGTH];
struct sockaddr_storage addr;
::memset(&addr, 0, sizeof(sockaddr_storage));
// No more data?
int length = m_socket.read(buffer, G2_BUFFER_LENGTH, addr);
if(length <= 0) return false;
if(length == 1 && buffer[0] == 0U) {
CLog::logDebug("G2 Nat traversal packet received");
}
CG2ProtocolHandler * handler = findHandler(addr, IMT_ADDRESS_AND_PORT);
if(handler == nullptr) {
CLog::logTrace("new incoming G2 %s:%u", inet_ntoa(TOIPV4(addr)->sin_addr), ntohs(TOIPV4(addr)->sin_port));
handler = new CG2ProtocolHandler(&m_socket, addr, G2_BUFFER_LENGTH);
m_pool.push_back(handler);
m_index = m_pool.end();
}
bool res = handler->setBuffer(buffer, length);
return res;
}
void CG2ProtocolHandlerPool::traverseNat(const std::string& address)
{
unsigned char buffer = 0x00U;
in_addr addr = CUDPReaderWriter::lookup(address);
CLog::logInfo("G2 Punching hole to %s", address.c_str());
m_socket.write(&buffer, 1U, addr, G2_DV_PORT);
}
bool CG2ProtocolHandlerPool::writeHeader(const CHeaderData& header)
{
auto handler = findHandler(header.getDestination(), IMT_ADDRESS_ONLY);
if(handler == nullptr) {
handler = new CG2ProtocolHandler(&m_socket, header.getDestination(), G2_BUFFER_LENGTH);
m_pool.push_back(handler);
m_index = m_pool.end();
}
return handler->writeHeader(header);
}
bool CG2ProtocolHandlerPool::writeAMBE(const CAMBEData& data)
{
auto handler = findHandler(data.getDestination(), IMT_ADDRESS_ONLY);
if(handler == nullptr) {
handler = new CG2ProtocolHandler(&m_socket, data.getDestination(), G2_BUFFER_LENGTH);
m_pool.push_back(handler);
m_index = m_pool.end();
}
return handler->writeAMBE(data);
}
CG2ProtocolHandler * CG2ProtocolHandlerPool::findHandler(const struct sockaddr_storage& addr, IPMATCHTYPE matchType) const
{
for(auto handler : m_pool) {
if(handler != nullptr && CNetUtils::match(addr, handler->getDestination(), matchType))
return handler;
}
return nullptr;
}
CG2ProtocolHandler * CG2ProtocolHandlerPool::findHandler(in_addr addr, unsigned int port, IPMATCHTYPE matchType) const
{
struct sockaddr_storage addrStorage;
addrStorage.ss_family = AF_INET;
TOIPV4(addrStorage)->sin_addr = addr;
TOIPV4(addrStorage)->sin_port = port;
return findHandler(addrStorage, matchType);
}

@ -0,0 +1,91 @@
/*
* Copyright (c) 2021-2022 by Geoffrey Merck 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.
*/
#pragma once
#include <string>
#include <vector>
#include <sys/socket.h>
#include <boost/container_hash/hash.hpp>
#include "G2ProtocolHandler.h"
#include "NetUtils.h"
struct sockaddr_storage_map {
struct compAddrAndPort {
bool operator() (const struct sockaddr_storage& a, const struct sockaddr_storage& b) const {
return CNetUtils::match(a, b, IMT_ADDRESS_AND_PORT);
}
};
struct hash {
std::size_t operator() (const sockaddr_storage& a) const {
switch(a.ss_family)
{
case AF_INET: {
auto ptr4 = ((struct sockaddr_in *)&a);
size_t res = AF_INET;
boost::hash_combine(res, ptr4->sin_port);
boost::hash_combine(res, ptr4->sin_addr.s_addr);
return res;
}
case AF_INET6: {
auto ptr6 = ((struct sockaddr_in6 *)&a);
size_t res = AF_INET6;
boost::hash_combine(res, ptr6->sin6_port);
auto in6Ptr = (unsigned int *)&(ptr6->sin6_addr);
boost::hash_combine(res, in6Ptr[0]);
boost::hash_combine(res, in6Ptr[1]);
boost::hash_combine(res, in6Ptr[2]);
boost::hash_combine(res, in6Ptr[3]);
return res;
}
default:
return 0U;
}
}
};
};
class CG2ProtocolHandlerPool
{
public:
CG2ProtocolHandlerPool(unsigned short g2Port, const std::string& address = "");
~CG2ProtocolHandlerPool();
bool open();
void close();
G2_TYPE read();
CAMBEData * readAMBE();
CHeaderData * readHeader();
bool writeAMBE(const CAMBEData& data);
bool writeHeader(const CHeaderData& header);
void traverseNat(const std::string& address);
private:
bool readPackets();
CG2ProtocolHandler * findHandler(const struct sockaddr_storage& addr, IPMATCHTYPE matchType) const;
CG2ProtocolHandler * findHandler(in_addr addr, unsigned int port, IPMATCHTYPE matchType) const;
std::string m_address;
unsigned int m_basePort;
CUDPReaderWriter m_socket;
std::vector<CG2ProtocolHandler *> m_pool;
std::vector<CG2ProtocolHandler *>::iterator m_index;
};

@ -23,7 +23,7 @@
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include "HeaderData.h" #include "HeaderData.h"
#include "NetUtils.h"
#include "CCITTChecksum.h" #include "CCITTChecksum.h"
#include "DStarDefines.h" #include "DStarDefines.h"
#include "Utils.h" #include "Utils.h"
@ -922,6 +922,17 @@ unsigned int CHeaderData::getYourPort() const
return m_yourPort; return m_yourPort;
} }
struct sockaddr_storage CHeaderData::getDestination() const
{
struct sockaddr_storage dest;
::memset(&dest, 0, sizeof(sockaddr_storage));
dest.ss_family = AF_INET;
TOIPV4(dest)->sin_addr = m_yourAddress;
TOIPV4(dest)->sin_port = htons(m_yourPort);
return dest;
}
unsigned int CHeaderData::getMyPort() const unsigned int CHeaderData::getMyPort() const
{ {
return m_myPort; return m_myPort;

@ -94,6 +94,7 @@ public:
in_addr getYourAddress() const; in_addr getYourAddress() const;
unsigned int getYourPort() const; unsigned int getYourPort() const;
struct sockaddr_storage getDestination() const;
unsigned int getMyPort() const; unsigned int getMyPort() const;
unsigned int getErrors() const; unsigned int getErrors() const;

@ -22,9 +22,6 @@
#include "NetUtils.h" #include "NetUtils.h"
#define TOIPV6(s) ((struct sockaddr_in6*)&s)
#define TOIPV4(s) (((struct sockaddr_in*)&s))
bool CNetUtils::lookupV4(const std::string& hostname, sockaddr_storage& addr) bool CNetUtils::lookupV4(const std::string& hostname, sockaddr_storage& addr)
{ {
struct addrinfo hints; struct addrinfo hints;

@ -23,8 +23,10 @@
#include <netdb.h> #include <netdb.h>
#include <sys/socket.h> #include <sys/socket.h>
#define TOIPV6(s) ((struct sockaddr_in6*)&s)
#define TOIPV4(s) (((struct sockaddr_in*)&s))
#define GETPORT(s) (s.ss_family == AF_INET6 ? TOIPV6(s)->sin6_port : TOIPV4(s)->sin_port) #define GETPORT(s) (s.ss_family == AF_INET6 ? TOIPV6(s)->sin6_port : TOIPV4(s)->sin_port)
#define SETPORT(s, p) (if(s.ss_family == AF_INET6)TOIPV6(s)->sin6_port = p;else TOIPV4(s)->sin_port = p;)
enum IPMATCHTYPE { enum IPMATCHTYPE {
IMT_ADDRESS_AND_PORT, IMT_ADDRESS_AND_PORT,

@ -45,7 +45,7 @@ unsigned int CRepeaterHandler::m_maxRepeaters = 0U;
CRepeaterHandler** CRepeaterHandler::m_repeaters = NULL; CRepeaterHandler** CRepeaterHandler::m_repeaters = NULL;
std::string CRepeaterHandler::m_localAddress; std::string CRepeaterHandler::m_localAddress;
CG2ProtocolHandler* CRepeaterHandler::m_g2Handler = NULL; CG2ProtocolHandlerPool* CRepeaterHandler::m_g2Handler = NULL;
CIRCDDB* CRepeaterHandler::m_irc = NULL; CIRCDDB* CRepeaterHandler::m_irc = NULL;
CCacheManager* CRepeaterHandler::m_cache = NULL; CCacheManager* CRepeaterHandler::m_cache = NULL;
std::string CRepeaterHandler::m_gateway; std::string CRepeaterHandler::m_gateway;
@ -301,7 +301,7 @@ void CRepeaterHandler::add(const std::string& callsign, const std::string& band,
delete repeater; delete repeater;
} }
void CRepeaterHandler::setG2Handler(CG2ProtocolHandler* handler) void CRepeaterHandler::setG2HandlerPool(CG2ProtocolHandlerPool* handler)
{ {
assert(handler != NULL); assert(handler != NULL);

@ -28,7 +28,7 @@
#include "DExtraProtocolHandler.h" #include "DExtraProtocolHandler.h"
#include "DPlusProtocolHandler.h" #include "DPlusProtocolHandler.h"
#include "RemoteRepeaterData.h" #include "RemoteRepeaterData.h"
#include "G2ProtocolHandler.h" #include "G2ProtocolHandlerPool.h"
#include "ReflectorCallback.h" #include "ReflectorCallback.h"
#include "RepeaterCallback.h" #include "RepeaterCallback.h"
#include "AnnouncementUnit.h" #include "AnnouncementUnit.h"
@ -75,7 +75,7 @@ public:
#endif #endif
static void setLocalAddress(const std::string& address); static void setLocalAddress(const std::string& address);
static void setG2Handler(CG2ProtocolHandler* handler); static void setG2HandlerPool(CG2ProtocolHandlerPool* handler);
static void setIRC(CIRCDDB* irc); static void setIRC(CIRCDDB* irc);
static void setCache(CCacheManager* cache); static void setCache(CCacheManager* cache);
static void setGateway(const std::string& gateway); static void setGateway(const std::string& gateway);
@ -168,7 +168,7 @@ private:
static CRepeaterHandler** m_repeaters; static CRepeaterHandler** m_repeaters;
static std::string m_localAddress; static std::string m_localAddress;
static CG2ProtocolHandler* m_g2Handler; static CG2ProtocolHandlerPool* m_g2Handler;
static CCacheManager* m_cache; static CCacheManager* m_cache;
static std::string m_gateway; static std::string m_gateway;
static CIRCDDB* m_irc; static CIRCDDB* m_irc;

@ -21,6 +21,7 @@
#include <string.h> #include <string.h>
#include "UDPReaderWriter.h" #include "UDPReaderWriter.h"
#include "Log.h" #include "Log.h"
#include "NetUtils.h"
CUDPReaderWriter::CUDPReaderWriter(const std::string& address, unsigned int port) : CUDPReaderWriter::CUDPReaderWriter(const std::string& address, unsigned int port) :
m_address(address), m_address(address),
@ -139,8 +140,8 @@ int CUDPReaderWriter::read(unsigned char* buffer, unsigned int length, in_addr&
auto res = read(buffer, length, addr); auto res = read(buffer, length, addr);
if(res >= 0 && addr.ss_family == AF_INET) { if(res >= 0 && addr.ss_family == AF_INET) {
address = ((struct sockaddr_in*)&addr)->sin_addr; address = TOIPV4(addr)->sin_addr;
port = ntohs(((struct sockaddr_in*)&addr)->sin_port); port = ntohs(TOIPV4(addr)->sin_port);
} }
return res; return res;
@ -148,14 +149,36 @@ int CUDPReaderWriter::read(unsigned char* buffer, unsigned int length, in_addr&
bool CUDPReaderWriter::write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port) bool CUDPReaderWriter::write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port)
{ {
sockaddr_in addr; struct sockaddr_storage addr;
::memset(&addr, 0x00, sizeof(sockaddr_in)); ::memset(&addr, 0, sizeof(sockaddr_storage));
addr.ss_family = AF_INET;
TOIPV4(addr)->sin_addr = address;
TOIPV4(addr)->sin_port = htons(port);
return write(buffer, length, addr);
// sockaddr_in addr;
// ::memset(&addr, 0x00, sizeof(sockaddr_in));
// addr.sin_family = AF_INET;
// addr.sin_addr = address;
// addr.sin_port = htons(port);
// ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(sockaddr_in));
// if (ret < 0) {
// CLog::logError("Error returned from sendto (port: %u), err: %s\n", m_port, strerror(errno));
// return false;
// }
addr.sin_family = AF_INET; // if (ret != ssize_t(length))
addr.sin_addr = address; // return false;
addr.sin_port = htons(port);
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(sockaddr_in)); // return true;
}
bool CUDPReaderWriter::write(const unsigned char* buffer, unsigned int length, const struct sockaddr_storage& addr)
{
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, sizeof(addr));
if (ret < 0) { if (ret < 0) {
CLog::logError("Error returned from sendto (port: %u), err: %s\n", m_port, strerror(errno)); CLog::logError("Error returned from sendto (port: %u), err: %s\n", m_port, strerror(errno));
return false; return false;
@ -167,6 +190,8 @@ bool CUDPReaderWriter::write(const unsigned char* buffer, unsigned int length, c
return true; return true;
} }
void CUDPReaderWriter::close() void CUDPReaderWriter::close()
{ {
::close(m_fd); ::close(m_fd);

@ -44,6 +44,7 @@ public:
int read(unsigned char* buffer, unsigned int length, struct sockaddr_storage& addr); int read(unsigned char* buffer, unsigned int length, struct sockaddr_storage& addr);
int read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port); int read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port);
bool write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port); bool write(const unsigned char* buffer, unsigned int length, const in_addr& address, unsigned int port);
bool write(const unsigned char* buffer, unsigned int length, const struct sockaddr_storage& addr);
void close(); void close();

Loading…
Cancel
Save

Powered by TurnKey Linux.