Upgrade to IPv6.

This commit is contained in:
Jonathan Naylor 2020-11-16 15:13:57 +00:00
parent 87012ff6f5
commit 086e665af8
19 changed files with 372 additions and 361 deletions

View file

@ -59,7 +59,9 @@ bool CAPRSTransmit::run()
if (!opened)
return false;
in_addr address = CUDPReaderWriter::lookup(wxT("127.0.0.1"));
sockaddr_storage addr;
unsigned int addrLen;
CUDPReaderWriter::lookup("127.0.0.1", G2_DV_PORT, addr, addrLen);
unsigned int id = CHeaderData::createId();
@ -73,7 +75,7 @@ bool CAPRSTransmit::run()
header.setRptCall1(callsignG);
header.setRptCall2(m_repeaterCallsign);
header.setYourCall(wxT("CQCQCQ "));
header.setDestination(address, G2_DV_PORT);
header.setDestination(addr, addrLen);
sendHeader(header);
@ -83,7 +85,7 @@ bool CAPRSTransmit::run()
encoder.setTextData(wxT("APRS to DPRS"));
CAMBEData data;
data.setDestination(address, G2_DV_PORT);
data.setDestination(addr, addrLen);
data.setId(id);
wxStopWatch timer;
@ -132,7 +134,7 @@ bool CAPRSTransmit::sendHeader(const CHeaderData& header)
unsigned int length = header.getG2Data(buffer, 60U, true);
for (unsigned int i = 0U; i < 2U; i++) {
bool res = m_socket.write(buffer, length, header.getYourAddress(), header.getYourPort());
bool res = m_socket.write(buffer, length, header.getYourAddr(), header.getYourAddrLen());
if (!res)
return false;
}
@ -145,7 +147,7 @@ bool CAPRSTransmit::sendData(const CAMBEData& data)
unsigned char buffer[60U];
unsigned int length = data.getG2Data(buffer, 60U);
return m_socket.write(buffer, length, data.getYourAddress(), data.getYourPort());
return m_socket.write(buffer, length, data.getYourAddr(), data.getYourAddrLen());
}
unsigned int CAPRSTransmit::calcCRC(const wxString& gpsData)

View file

@ -193,7 +193,7 @@ bool CAPRSWriter::open()
wxLogMessage(wxT("Connected to GPSD"));
}
#endif
bool ret = m_aprsSocket.open();
bool ret = m_aprsSocket.open(m_aprsAddr);
if (!ret)
return false;

View file

@ -120,9 +120,17 @@ void CCacheManager::updateRepeater(const wxString& repeater, const wxString& gat
m_gatewayCache.update(gateway, address, protocol, addrLock, protoLock);
}
void CCacheManager::updateGateway(const wxString& gateway, const sockaddr_storage& addr, unsigned int addrLen, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock)
{
wxMutexLocker locker(m_mutex);
m_gatewayCache.update(gateway, addr, addrLen, protocol, addrLock, protoLock);
}
void CCacheManager::updateGateway(const wxString& gateway, const wxString& address, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock)
{
wxMutexLocker locker(m_mutex);
m_gatewayCache.update(gateway, address, protocol, addrLock, protoLock);
}

View file

@ -166,7 +166,10 @@ public:
CRepeaterData* findRepeater(const wxString& repeater);
void updateUser(const wxString& user, const wxString& repeater, const wxString& gateway, const wxString& address, const wxString& timeStamp, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock);
void updateRepeater(const wxString& repeater, const wxString& gateway, const wxString& address, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock);
void updateGateway(const wxString& gateway, const sockaddr_storage& addr, unsigned int addrLen, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock);
void updateGateway(const wxString& gateway, const wxString& address, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock);
private:

View file

@ -38,6 +38,18 @@ CGatewayRecord* CGatewayCache::find(const wxString& gateway)
return m_cache[gateway];
}
void CGatewayCache::update(const wxString& gateway, const sockaddr_storage& addr, unsigned int addrLen, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock)
{
CGatewayRecord* rec = m_cache[gateway];
if (rec == NULL)
// A brand new record is needed
m_cache[gateway] = new CGatewayRecord(gateway, addr, addrLen, protocol, addrLock, protoLock);
else
// Update an existing record
rec->setData(addr, addrLen, protocol, addrLock, protoLock);
}
void CGatewayCache::update(const wxString& gateway, const wxString& address, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock)
{
CGatewayRecord* rec = m_cache[gateway];

View file

@ -103,6 +103,7 @@ public:
CGatewayRecord* find(const wxString& gateway);
void update(const wxString& gateway, const sockaddr_storage& addr, unsigned int addrLen, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock);
void update(const wxString& gateway, const wxString& address, DSTAR_PROTOCOL protocol, bool addrLock, bool protoLock);
unsigned int getCount() const;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2014 by Jonathan Naylor G4KLX
* Copyright (C) 2010-2014,2020 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
@ -35,8 +35,8 @@ const unsigned int LOOP_TICKS = 200U;
CIcomRepeaterProtocolHandler::CIcomRepeaterProtocolHandler(const wxString& address, unsigned int port, const wxString& icomAddress, unsigned int icomPort) :
wxThread(wxTHREAD_JOINABLE),
m_socket(address, port),
m_icomAddress(),
m_icomPort(icomPort),
m_icomAddr(),
m_icomAddrLen(),
m_over1(false),
m_seqNo(0U),
m_tries(0U),
@ -53,7 +53,7 @@ m_retryTimer(LOOP_TICKS, 0U, 200U) // 200ms
wxASSERT(icomPort > 0U);
wxASSERT(port > 0U);
m_icomAddress.s_addr = ::inet_addr(icomAddress.mb_str());
CUDPReaderWriter::lookup(icomAddress, icomPort, m_icomAddr, m_icomAddrLen);
m_buffer = new unsigned char[BUFFER_LENGTH];
@ -100,7 +100,7 @@ bool CIcomRepeaterProtocolHandler::open()
buffer[8U] = 0x00;
buffer[9U] = 0x00;
ret = m_socket.write(buffer, 10U, m_icomAddress, m_icomPort);
ret = m_socket.write(buffer, 10U, m_icomAddr, m_icomAddrLen);
if (!ret) {
m_socket.close();
return false;
@ -108,9 +108,9 @@ bool CIcomRepeaterProtocolHandler::open()
// Wait for a reply from the RP2C
for (unsigned int i = 0U; i < 10U; i++) {
in_addr address;
unsigned int port;
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port);
sockaddr_storage addr;
unsigned int addrLen;
int length = m_socket.read(m_buffer, BUFFER_LENGTH, addr, addrLen);
if (length == 10 && m_buffer[0U] == 'I' && m_buffer[1U] == 'N' && m_buffer[2U] == 'I' && m_buffer[3U] == 'T' && m_buffer[6U] == 0x72 && m_buffer[7U] == 0x00) {
m_seqNo = m_buffer[4U] * 256U + m_buffer[5U] + 1U;
@ -204,13 +204,13 @@ void CIcomRepeaterProtocolHandler::readIcomPackets()
{
for (;;) {
// No more data?
in_addr address;
unsigned int port;
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port);
sockaddr_storage addr;
unsigned int addrLen;
int length = m_socket.read(m_buffer, BUFFER_LENGTH, addr, addrLen);
if (length <= 0)
return;
if (address.s_addr != m_icomAddress.s_addr || port != m_icomPort) {
if (!CUDPReaderWriter::match(addr, m_icomAddr)) {
wxLogError(wxT("Incoming Icom data from an unknown source"));
continue;
}
@ -247,7 +247,7 @@ void CIcomRepeaterProtocolHandler::readIcomPackets()
// Heard data
if (m_buffer[6] == 0x73 && m_buffer[7] == 0x21) {
CHeardData* heard = new CHeardData;
bool ret = heard->setIcomRepeaterData(m_buffer, length, m_icomAddress, m_icomPort);
bool ret = heard->setIcomRepeaterData(m_buffer, length, m_icomAddr, m_icomAddrLen);
if (!ret) {
wxLogError(wxT("Invalid heard data from the RP2C"));
delete heard;
@ -267,7 +267,7 @@ void CIcomRepeaterProtocolHandler::readIcomPackets()
// DD Data
if (m_buffer[6] == 0x73 && m_buffer[7] == 0x11) {
CDDData* data = new CDDData;
bool ret = data->setIcomRepeaterData(m_buffer, length, m_icomAddress, m_icomPort);
bool ret = data->setIcomRepeaterData(m_buffer, length, m_icomAddr, m_icomAddrLen);
if (!ret) {
wxLogError(wxT("Invalid DD data from the RP2C"));
delete data;
@ -282,7 +282,7 @@ void CIcomRepeaterProtocolHandler::readIcomPackets()
if (m_buffer[6] == 0x73 && m_buffer[7] == 0x12 && m_buffer[10] == 0x20) {
if ((m_buffer[16] & 0x80) == 0x80) {
CHeaderData* header = new CHeaderData;
bool ret = header->setIcomRepeaterData(m_buffer, length, true, m_icomAddress, m_icomPort);
bool ret = header->setIcomRepeaterData(m_buffer, length, true, m_icomAddr, m_icomAddrLen);
if (!ret) {
wxLogError(wxT("Invalid header data or checksum from the RP2C"));
delete header;
@ -298,7 +298,7 @@ void CIcomRepeaterProtocolHandler::readIcomPackets()
continue;
} else {
CAMBEData* data = new CAMBEData;
bool ret = data->setIcomRepeaterData(m_buffer, length, m_icomAddress, m_icomPort);
bool ret = data->setIcomRepeaterData(m_buffer, length, m_icomAddr, m_icomAddrLen);
if (!ret) {
wxLogError(wxT("Invalid AMBE data from the RP2C"));
delete data;
@ -362,7 +362,7 @@ void CIcomRepeaterProtocolHandler::sendGwyPackets()
}
if (length > 0U) {
m_socket.write(m_buffer, length, m_icomAddress, m_icomPort);
m_socket.write(m_buffer, length, m_icomAddr, m_icomAddrLen);
m_tries++;
m_retryTimer.start();
@ -545,7 +545,7 @@ bool CIcomRepeaterProtocolHandler::sendAck(wxUint16 seqNo)
buffer[8U] = 0x00U;
buffer[9U] = 0x00U;
return m_socket.write(buffer, 10U, m_icomAddress, m_icomPort);
return m_socket.write(buffer, 10U, m_icomAddr, m_icomAddrLen);
}
void CIcomRepeaterProtocolHandler::sendSingleReply(const CHeaderData& header)

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010,2012,2013 by Jonathan Naylor G4KLX
* Copyright (C) 2010,2012,2013,2020 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
@ -21,43 +21,43 @@
#include "DStarDefines.h"
#include "Utils.h"
CPollData::CPollData(const wxString& data1, const wxString& data2, DIRECTION direction, const in_addr& yourAddress, unsigned int yourPort, unsigned int myPort) :
CPollData::CPollData(const wxString& data1, const wxString& data2, DIRECTION direction, const sockaddr_storage& yourAddr, unsigned int yourAddrLen, unsigned int myPort) :
m_data1(data1),
m_data2(data2),
m_direction(direction),
m_dongle(false),
m_length(0U),
m_yourAddress(yourAddress),
m_yourPort(yourPort),
m_yourAddr(yourAddr),
m_yourAddrLen(yourAddrLen),
m_myPort(myPort)
{
wxASSERT(yourPort > 0U);
wxASSERT(yourAddrLen > 0U);
}
CPollData::CPollData(const wxString& data, const in_addr& yourAddress, unsigned int yourPort, unsigned int myPort) :
CPollData::CPollData(const wxString& data, const sockaddr_storage& yourAddr, unsigned int yourAddrLen, unsigned int myPort) :
m_data1(data),
m_data2(),
m_direction(DIR_OUTGOING),
m_dongle(false),
m_length(0U),
m_yourAddress(yourAddress),
m_yourPort(yourPort),
m_yourAddr(yourAddr),
m_yourAddrLen(yourAddrLen),
m_myPort(myPort)
{
wxASSERT(yourPort > 0U);
wxASSERT(yourAddrLen > 0U);
}
CPollData::CPollData(const in_addr& yourAddress, unsigned int yourPort, unsigned int myPort) :
CPollData::CPollData(const sockaddr_storage& yourAddr, unsigned int yourAddrLen, unsigned int myPort) :
m_data1(),
m_data2(),
m_direction(DIR_OUTGOING),
m_dongle(false),
m_length(0U),
m_yourAddress(yourAddress),
m_yourPort(yourPort),
m_yourAddr(yourAddr),
m_yourAddrLen(yourAddrLen),
m_myPort(myPort)
{
wxASSERT(yourPort > 0U);
wxASSERT(yourAddrLen > 0U);
}
CPollData::CPollData() :
@ -66,8 +66,8 @@ m_data2(),
m_direction(DIR_OUTGOING),
m_dongle(false),
m_length(0U),
m_yourAddress(),
m_yourPort(0U),
m_yourAddr(),
m_yourAddrLen(0U),
m_myPort(0U)
{
}
@ -76,28 +76,28 @@ CPollData::~CPollData()
{
}
bool CPollData::setDExtraData(const unsigned char* data, unsigned int length, const in_addr& yourAddress, unsigned int yourPort, unsigned int myPort)
bool CPollData::setDExtraData(const unsigned char* data, unsigned int length, const sockaddr_storage& yourAddr, unsigned int yourAddrLen, unsigned int myPort)
{
wxASSERT(data != NULL);
wxASSERT(length >= 9U);
wxASSERT(yourPort > 0U);
wxASSERT(yourAddrLen > 0U);
m_data1 = wxString((const char*)data, wxConvLocal, LONG_CALLSIGN_LENGTH);
m_dongle = data[LONG_CALLSIGN_LENGTH] != 0x00;
m_length = length;
m_yourAddress = yourAddress;
m_yourPort = yourPort;
m_yourAddr = yourAddr;
m_yourAddrLen = yourAddrLen;
m_myPort = myPort;
return true;
}
bool CPollData::setDCSData(const unsigned char* data, unsigned int length, const in_addr& yourAddress, unsigned int yourPort, unsigned int myPort)
bool CPollData::setDCSData(const unsigned char* data, unsigned int length, const sockaddr_storage& yourAddr, unsigned int yourAddrLen, unsigned int myPort)
{
wxASSERT(data != NULL);
wxASSERT(yourPort > 0U);
wxASSERT(yourAddrLen > 0U);
switch (length) {
case 17U:
@ -105,8 +105,8 @@ bool CPollData::setDCSData(const unsigned char* data, unsigned int length, const
m_data2 = wxString((const char*)(data + 9U), wxConvLocal, LONG_CALLSIGN_LENGTH);
m_length = length;
m_direction = DIR_INCOMING;
m_yourAddress = yourAddress;
m_yourPort = yourPort;
m_yourAddr = yourAddr;
m_yourAddrLen = yourAddrLen;
m_myPort = myPort;
break;
@ -116,8 +116,8 @@ bool CPollData::setDCSData(const unsigned char* data, unsigned int length, const
m_data2.Append(wxString((const char*)(data + 17U), wxConvLocal, 1U));
m_length = length;
m_direction = DIR_OUTGOING;
m_yourAddress = yourAddress;
m_yourPort = yourPort;
m_yourAddr = yourAddr;
m_yourAddrLen = yourAddrLen;
m_myPort = myPort;
break;
}
@ -125,28 +125,28 @@ bool CPollData::setDCSData(const unsigned char* data, unsigned int length, const
return true;
}
bool CPollData::setCCSData(const unsigned char* data, unsigned int length, const in_addr& yourAddress, unsigned int yourPort, unsigned int myPort)
bool CPollData::setCCSData(const unsigned char* data, unsigned int length, const sockaddr_storage& yourAddr, unsigned int yourAddrLen, unsigned int myPort)
{
wxASSERT(data != NULL);
wxASSERT(length >= 25U);
wxASSERT(yourPort > 0U);
wxASSERT(yourAddrLen > 0U);
m_data1 = wxString((const char*)(data + 0U), wxConvLocal, 25U);
m_length = length;
m_yourAddress = yourAddress;
m_yourPort = yourPort;
m_yourAddr = yourAddr;
m_yourAddrLen = yourAddrLen;
m_myPort = myPort;
return true;
}
bool CPollData::setDPlusData(const unsigned char*, unsigned int length, const in_addr& yourAddress, unsigned int yourPort, unsigned int myPort)
bool CPollData::setDPlusData(const unsigned char*, unsigned int length, const sockaddr_storage& yourAddr, unsigned int yourAddrLen, unsigned int myPort)
{
wxASSERT(yourPort > 0U);
wxASSERT(yourAddrLen > 0U);
m_length = length;
m_yourAddress = yourAddress;
m_yourPort = yourPort;
m_yourAddr = yourAddr;
m_yourAddrLen = yourAddrLen;
m_myPort = myPort;
return true;
@ -258,14 +258,14 @@ bool CPollData::isDongle() const
return m_dongle;
}
in_addr CPollData::getYourAddress() const
sockaddr_storage CPollData::getYourAddr() const
{
return m_yourAddress;
return m_yourAddr;
}
unsigned int CPollData::getYourPort() const
unsigned int CPollData::getYourAddrLen() const
{
return m_yourPort;
return m_yourAddrLen;
}
unsigned int CPollData::getMyPort() const

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011,2013 by Jonathan Naylor G4KLX
* Copyright (C) 2011,2013,2020 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
@ -25,8 +25,8 @@ const unsigned int BUFFER_LENGTH = 2000U;
CRemoteProtocolHandler::CRemoteProtocolHandler(unsigned int port, const wxString& address) :
m_socket(address, port),
m_address(),
m_port(0U),
m_addr(),
m_addrLen(0U),
m_loggedIn(false),
m_type(RPHT_NONE),
m_inBuffer(NULL),
@ -54,10 +54,10 @@ RPH_TYPE CRemoteProtocolHandler::readType()
{
m_type = RPHT_NONE;
in_addr address;
unsigned int port;
sockaddr_storage addr;
unsigned int addrLen;
int length = m_socket.read(m_inBuffer, BUFFER_LENGTH, address, port);
int length = m_socket.read(m_inBuffer, BUFFER_LENGTH, addr, addrLen);
if (length <= 0)
return m_type;
@ -65,12 +65,13 @@ RPH_TYPE CRemoteProtocolHandler::readType()
if (::memcmp(m_inBuffer, "LIN", 3U) == 0) {
m_loggedIn = false;
m_address = address;
m_port = port;
m_addr = addr;
m_addrLen = addrLen;
m_type = RPHT_LOGIN;
return m_type;
}
/* XXX FIXME How to detect loopback in IPv4 and IPv6?
if (address.s_addr == inet_addr("127.0.0.1")) {
if (::memcmp(m_inBuffer, "LKS", 3U) == 0) {
m_inLength = length;
@ -78,9 +79,9 @@ RPH_TYPE CRemoteProtocolHandler::readType()
return m_type;
}
}
*/
if (m_loggedIn) {
if (address.s_addr != m_address.s_addr || port != m_port) {
if (!CUDPReaderWriter::match(addr, m_addr)) {
sendNAK(wxT("You are not logged in"));
return m_type;
}
@ -294,7 +295,7 @@ bool CRemoteProtocolHandler::sendCallsigns(const wxArrayString& repeaters, const
// CUtils::dump(wxT("Outgoing"), m_outBuffer, p - m_outBuffer);
return m_socket.write(m_outBuffer, p - m_outBuffer, m_address, m_port);
return m_socket.write(m_outBuffer, p - m_outBuffer, m_addr, m_addrLen);
}
bool CRemoteProtocolHandler::sendRepeater(const CRemoteRepeaterData& data)
@ -345,7 +346,7 @@ bool CRemoteProtocolHandler::sendRepeater(const CRemoteRepeaterData& data)
// CUtils::dump(wxT("Outgoing"), m_outBuffer, p - m_outBuffer);
return m_socket.write(m_outBuffer, p - m_outBuffer, m_address, m_port);
return m_socket.write(m_outBuffer, p - m_outBuffer, m_addr, m_addrLen);
}
bool CRemoteProtocolHandler::sendStarNetGroup(const CRemoteStarNetGroup& data)
@ -392,7 +393,7 @@ bool CRemoteProtocolHandler::sendStarNetGroup(const CRemoteStarNetGroup& data)
// CUtils::dump(wxT("Outgoing"), m_outBuffer, p - m_outBuffer);
return m_socket.write(m_outBuffer, p - m_outBuffer, m_address, m_port);
return m_socket.write(m_outBuffer, p - m_outBuffer, m_addr, m_addrLen);
}
void CRemoteProtocolHandler::setLoggedIn(bool set)
@ -411,7 +412,7 @@ bool CRemoteProtocolHandler::sendACK()
// CUtils::dump(wxT("Outgoing"), m_outBuffer, 3U);
return m_socket.write(m_outBuffer, 3U, m_address, m_port);
return m_socket.write(m_outBuffer, 3U, m_addr, m_addrLen);
}
bool CRemoteProtocolHandler::sendNAK(const wxString& text)
@ -425,7 +426,7 @@ bool CRemoteProtocolHandler::sendNAK(const wxString& text)
// CUtils::dump(wxT("Outgoing"), m_outBuffer, 3U + text.Len() + 1U);
return m_socket.write(m_outBuffer, 3U + text.Len() + 1U, m_address, m_port);
return m_socket.write(m_outBuffer, 3U + text.Len() + 1U, m_addr, m_addrLen);
}
bool CRemoteProtocolHandler::sendRandom(wxUint32 random)
@ -437,5 +438,5 @@ bool CRemoteProtocolHandler::sendRandom(wxUint32 random)
// CUtils::dump(wxT("Outgoing"), m_outBuffer, 3U + sizeof(wxUint32));
return m_socket.write(m_outBuffer, 3U + sizeof(wxUint32), m_address, m_port);
return m_socket.write(m_outBuffer, 3U + sizeof(wxUint32), m_addr, m_addrLen);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2015,2018,2019 by Jonathan Naylor G4KLX
* Copyright (C) 2010-2015,2018,2019,2020 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
@ -64,8 +64,8 @@ m_index(0x00U),
m_rptCallsign(),
m_gwyCallsign(),
m_band(' '),
m_address(),
m_port(port),
m_addr(),
m_addrLen(0U),
m_hwType(hwType),
m_repeaterHandler(handler),
m_frequency(frequency),
@ -108,7 +108,8 @@ m_g2User(),
m_g2Repeater(),
m_g2Gateway(),
m_g2Header(NULL),
m_g2Address(),
m_g2Addr(),
m_g2AddrLen(0U),
m_linkStatus(LS_NONE),
m_linkRepeater(),
m_linkGateway(),
@ -153,7 +154,7 @@ m_heardTimer(1000U, 0U, 100U) // 100ms
m_gwyCallsign.Truncate(LONG_CALLSIGN_LENGTH - 1U);
m_gwyCallsign.Append(wxT("G"));
m_address.s_addr = ::inet_addr(address.mb_str());
CUDPReaderWriter::lookup(address, port, m_addr, m_addrLen);
m_pollTimer.start();
@ -415,12 +416,12 @@ void CRepeaterHandler::finalise()
CRepeaterHandler* CRepeaterHandler::findDVRepeater(const CHeaderData& header)
{
wxString rpt1 = header.getRptCall1();
in_addr address = header.getYourAddress();
sockaddr_storage addr = header.getYourAddr();
for (unsigned int i = 0U; i < m_maxRepeaters; i++) {
CRepeaterHandler* repeater = m_repeaters[i];
if (repeater != NULL) {
if (!repeater->m_ddMode && repeater->m_address.s_addr == address.s_addr && repeater->m_rptCallsign.IsSameAs(rpt1))
if (!repeater->m_ddMode && CUDPReaderWriter::match(repeater->m_addr, addr, IMT_ADDRESS_ONLY) && repeater->m_rptCallsign.IsSameAs(rpt1))
return repeater;
}
}
@ -460,13 +461,12 @@ CRepeaterHandler* CRepeaterHandler::findDVRepeater(const wxString& callsign)
CRepeaterHandler* CRepeaterHandler::findRepeater(const CPollData& data)
{
in_addr address = data.getYourAddress();
unsigned int port = data.getYourPort();
sockaddr_storage addr = data.getYourAddr();
for (unsigned int i = 0U; i < m_maxRepeaters; i++) {
CRepeaterHandler* repeater = m_repeaters[i];
if (repeater != NULL) {
if (repeater->m_address.s_addr == address.s_addr && repeater->m_port == port)
if (CUDPReaderWriter::match(repeater->m_addr, addr))
return repeater;
}
}
@ -826,7 +826,7 @@ void CRepeaterHandler::processRepeater(CAMBEData& data)
break;
case G2_OK:
data.setDestination(m_g2Address, G2_DV_PORT);
data.setDestination(m_g2Addr, m_g2AddrLen);
m_g2Handler->writeAMBE(data);
if (data.isEnd()) {
@ -1091,7 +1091,7 @@ bool CRepeaterHandler::process(CDDData& data)
else
data.setRepeaters(m_gwyCallsign, m_rptCallsign);
data.setDestination(m_address, m_port);
data.setDestination(m_addr, m_addrLen);
data.setFlags(0xC0U, 0x00U, 0x00U);
data.setMyCall1(m_ddCallsign);
data.setMyCall2(wxT(" "));
@ -1119,7 +1119,7 @@ bool CRepeaterHandler::process(CHeaderData& header, DIRECTION, AUDIO_SOURCE sour
header.setBand1(m_band1);
header.setBand2(m_band2);
header.setBand3(m_band3);
header.setDestination(m_address, m_port);
header.setDestination(m_addr, m_addrLen);
header.setRepeaters(m_gwyCallsign, m_rptCallsign);
m_repeaterHandler->writeHeader(header);
@ -1162,7 +1162,7 @@ bool CRepeaterHandler::process(CAMBEData& data, DIRECTION, AUDIO_SOURCE source)
data.setBand1(m_band1);
data.setBand2(m_band2);
data.setBand3(m_band3);
data.setDestination(m_address, m_port);
data.setDestination(m_addr, m_addrLen);
m_repeaterHandler->writeAMBE(data);
@ -1205,12 +1205,12 @@ void CRepeaterHandler::resolveUserInt(const wxString& user, const wxString& repe
}
// User found, update the settings and send the header to the correct place
m_g2Address.s_addr = ::inet_addr(address.mb_str());
CUDPReaderWriter::lookup(address, G2_DV_PORT, m_g2Addr, m_g2AddrLen);
m_g2Repeater = repeater;
m_g2Gateway = gateway;
m_g2Header->setDestination(m_g2Address, G2_DV_PORT);
m_g2Header->setDestination(m_g2Addr, m_g2AddrLen);
m_g2Header->setRepeaters(m_g2Gateway, m_g2Repeater);
m_g2Handler->writeHeader(*m_g2Header);
@ -1237,12 +1237,12 @@ void CRepeaterHandler::resolveRepeaterInt(const wxString& repeater, const wxStri
if (!address.IsEmpty()) {
// Repeater found, update the settings and send the header to the correct place
m_g2Address.s_addr = ::inet_addr(address.mb_str());
CUDPReaderWriter::lookup(address, G2_DV_PORT, m_g2Addr, m_g2AddrLen);
m_g2Repeater = repeater;
m_g2Gateway = gateway;
m_g2Header->setDestination(m_g2Address, G2_DV_PORT);
m_g2Header->setDestination(m_g2Addr, m_g2AddrLen);
m_g2Header->setRepeaters(m_g2Gateway, m_g2Repeater);
m_g2Handler->writeHeader(*m_g2Header);
@ -1266,13 +1266,14 @@ void CRepeaterHandler::resolveRepeaterInt(const wxString& repeater, const wxStri
if (!address.IsEmpty()) {
// Repeater found
in_addr addr;
sockaddr_storage addr;
unsigned int addrLen;
switch (protocol) {
case DP_DPLUS:
if (m_dplusEnabled) {
m_linkGateway = gateway;
addr.s_addr = ::inet_addr(address.mb_str());
CDPlusHandler::link(this, m_rptCallsign, m_linkRepeater, addr);
CUDPReaderWriter::lookup(address, DPLUS_PORT, addr, addrLen);
CDPlusHandler::link(this, m_rptCallsign, m_linkRepeater, addr, addrLen);
m_linkStatus = LS_LINKING_DPLUS;
} else {
wxLogMessage(wxT("Require D-Plus for linking to %s, but D-Plus is disabled"), repeater.c_str());
@ -1287,8 +1288,8 @@ void CRepeaterHandler::resolveRepeaterInt(const wxString& repeater, const wxStri
case DP_DCS:
if (m_dcsEnabled) {
m_linkGateway = gateway;
addr.s_addr = ::inet_addr(address.mb_str());
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, addr);
CUDPReaderWriter::lookup(address, DCS_PORT, addr, addrLen);
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, addr, addrLen);
m_linkStatus = LS_LINKING_DCS;
} else {
wxLogMessage(wxT("Require DCS for linking to %s, but DCS is disabled"), repeater.c_str());
@ -1302,16 +1303,16 @@ void CRepeaterHandler::resolveRepeaterInt(const wxString& repeater, const wxStri
case DP_LOOPBACK:
m_linkGateway = gateway;
addr.s_addr = ::inet_addr(address.mb_str());
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, addr);
CUDPReaderWriter::lookup(address, DCS_PORT, addr, addrLen);
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, addr, addrLen);
m_linkStatus = LS_LINKING_LOOPBACK;
break;
default:
if (m_dextraEnabled) {
m_linkGateway = gateway;
addr.s_addr = ::inet_addr(address.mb_str());
CDExtraHandler::link(this, m_rptCallsign, m_linkRepeater, addr);
CUDPReaderWriter::lookup(address, DEXTRA_PORT, addr, addrLen);
CDExtraHandler::link(this, m_rptCallsign, m_linkRepeater, addr, addrLen);
m_linkStatus = LS_LINKING_DEXTRA;
} else {
wxLogMessage(wxT("Require DExtra for linking to %s, but DExtra is disabled"), repeater.c_str());
@ -1977,10 +1978,11 @@ void CRepeaterHandler::g2CommandHandler(const wxString& callsign, const wxString
m_g2Header = new CHeaderData(header);
m_queryTimer.start();
} else {
m_g2Status = G2_OK;
m_g2Address = data->getAddress();
m_g2Status = G2_OK;
m_g2Addr = data->getAddr();
m_g2AddrLen = data->getAddrLen();
m_g2Gateway = data->getGateway();
header.setDestination(m_g2Address, G2_DV_PORT);
header.setDestination(m_g2Addr, m_g2AddrLen);
header.setRepeaters(m_g2Gateway, m_g2Repeater);
m_g2Handler->writeHeader(header);
delete data;
@ -2019,10 +2021,11 @@ void CRepeaterHandler::g2CommandHandler(const wxString& callsign, const wxString
m_g2Status = G2_OK;
m_g2User = callsign;
m_g2Address = data->getAddress();
m_g2Addr = data->getAddr();
m_g2AddrLen = data->getAddrLen();
m_g2Repeater = data->getRepeater();
m_g2Gateway = data->getGateway();
header.setDestination(m_g2Address, G2_DV_PORT);
header.setDestination(m_g2Addr, m_g2AddrLen);
header.setRepeaters(m_g2Gateway, m_g2Repeater);
m_g2Handler->writeHeader(header);
@ -2196,7 +2199,7 @@ void CRepeaterHandler::linkInt(const wxString& callsign)
case DP_DPLUS:
if (m_dplusEnabled) {
m_linkStatus = LS_LINKING_DPLUS;
CDPlusHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDPlusHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
} else {
@ -2210,7 +2213,7 @@ void CRepeaterHandler::linkInt(const wxString& callsign)
case DP_DCS:
if (m_dcsEnabled) {
m_linkStatus = LS_LINKING_DCS;
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
} else {
@ -2223,7 +2226,7 @@ void CRepeaterHandler::linkInt(const wxString& callsign)
case DP_LOOPBACK:
m_linkStatus = LS_LINKING_LOOPBACK;
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
break;
@ -2231,7 +2234,7 @@ void CRepeaterHandler::linkInt(const wxString& callsign)
default:
if (m_dextraEnabled) {
m_linkStatus = LS_LINKING_DEXTRA;
CDExtraHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDExtraHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
} else {
@ -2361,7 +2364,7 @@ void CRepeaterHandler::startupInt()
case DP_DPLUS:
if (m_dplusEnabled) {
m_linkStatus = LS_LINKING_DPLUS;
CDPlusHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDPlusHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
} else {
@ -2375,7 +2378,7 @@ void CRepeaterHandler::startupInt()
case DP_DCS:
if (m_dcsEnabled) {
m_linkStatus = LS_LINKING_DCS;
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
} else {
@ -2388,7 +2391,7 @@ void CRepeaterHandler::startupInt()
case DP_LOOPBACK:
m_linkStatus = LS_LINKING_LOOPBACK;
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDCSHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
break;
@ -2396,7 +2399,7 @@ void CRepeaterHandler::startupInt()
default:
if (m_dextraEnabled) {
m_linkStatus = LS_LINKING_DEXTRA;
CDExtraHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddress());
CDExtraHandler::link(this, m_rptCallsign, m_linkRepeater, data->getAddr(), data->getAddrLen());
writeLinkingTo(m_linkRepeater);
triggerInfo();
} else {
@ -2469,7 +2472,7 @@ void CRepeaterHandler::writeLinkingTo(const wxString &callsign)
break;
}
CTextData textData(m_linkStatus, callsign, text, m_address, m_port);
CTextData textData(m_linkStatus, callsign, text, m_addr, m_addrLen);
m_repeaterHandler->writeText(textData);
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
@ -2519,7 +2522,7 @@ void CRepeaterHandler::writeLinkedTo(const wxString &callsign)
break;
}
CTextData textData(m_linkStatus, callsign, text, m_address, m_port);
CTextData textData(m_linkStatus, callsign, text, m_addr, m_addrLen);
m_repeaterHandler->writeText(textData);
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
@ -2569,7 +2572,7 @@ void CRepeaterHandler::writeNotLinked()
break;
}
CTextData textData(LS_NONE, wxEmptyString, text, m_address, m_port);
CTextData textData(LS_NONE, wxEmptyString, text, m_addr, m_addrLen);
m_repeaterHandler->writeText(textData);
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
@ -2631,10 +2634,10 @@ void CRepeaterHandler::writeIsBusy(const wxString& callsign)
break;
}
CTextData textData1(m_linkStatus, m_linkRepeater, tempText, m_address, m_port, true);
CTextData textData1(m_linkStatus, m_linkRepeater, tempText, m_addr, m_addrLen, true);
m_repeaterHandler->writeText(textData1);
CTextData textData2(m_linkStatus, m_linkRepeater, text, m_address, m_port);
CTextData textData2(m_linkStatus, m_linkRepeater, text, m_addr, m_addrLen);
m_repeaterHandler->writeText(textData2);
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
@ -2692,13 +2695,13 @@ void CRepeaterHandler::ccsLinkMade(const wxString& callsign, DIRECTION direction
m_linkRepeater = callsign;
m_queryTimer.stop();
CTextData textData(m_linkStatus, callsign, text, m_address, m_port);
CTextData textData(m_linkStatus, callsign, text, m_addr, m_addrLen);
m_repeaterHandler->writeText(textData);
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
triggerInfo();
} else {
CTextData textData(m_linkStatus, m_linkRepeater, text, m_address, m_port, true);
CTextData textData(m_linkStatus, m_linkRepeater, text, m_addr, m_addrLen, true);
m_repeaterHandler->writeText(textData);
m_infoAudio->setTempStatus(LS_LINKED_CCS, callsign, text);
@ -2766,10 +2769,10 @@ void CRepeaterHandler::ccsLinkEnded(const wxString&, DIRECTION direction)
bool res = restoreLinks();
if (!res) {
CTextData textData1(m_linkStatus, m_linkRepeater, tempText, m_address, m_port, true);
CTextData textData1(m_linkStatus, m_linkRepeater, tempText, m_addr, m_addrLen, true);
m_repeaterHandler->writeText(textData1);
CTextData textData2(m_linkStatus, m_linkRepeater, text, m_address, m_port);
CTextData textData2(m_linkStatus, m_linkRepeater, text, m_addr, m_addrLen);
m_repeaterHandler->writeText(textData2);
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
@ -2777,7 +2780,7 @@ void CRepeaterHandler::ccsLinkEnded(const wxString&, DIRECTION direction)
triggerInfo();
}
} else {
CTextData textData(m_linkStatus, m_linkRepeater, tempText, m_address, m_port, true);
CTextData textData(m_linkStatus, m_linkRepeater, tempText, m_addr, m_addrLen, true);
m_repeaterHandler->writeText(textData);
m_infoAudio->setTempStatus(m_linkStatus, m_linkRepeater, tempText);
@ -2845,10 +2848,10 @@ void CRepeaterHandler::ccsLinkFailed(const wxString& dtmf, DIRECTION direction)
bool res = restoreLinks();
if (!res) {
CTextData textData1(m_linkStatus, m_linkRepeater, tempText, m_address, m_port, true);
CTextData textData1(m_linkStatus, m_linkRepeater, tempText, m_addr, m_addrLen, true);
m_repeaterHandler->writeText(textData1);
CTextData textData2(m_linkStatus, m_linkRepeater, text, m_address, m_port);
CTextData textData2(m_linkStatus, m_linkRepeater, text, m_addr, m_addrLen);
m_repeaterHandler->writeText(textData2);
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
@ -2856,7 +2859,7 @@ void CRepeaterHandler::ccsLinkFailed(const wxString& dtmf, DIRECTION direction)
triggerInfo();
}
} else {
CTextData textData(m_linkStatus, m_linkRepeater, tempText, m_address, m_port, true);
CTextData textData(m_linkStatus, m_linkRepeater, tempText, m_addr, m_addrLen, true);
m_repeaterHandler->writeText(textData);
m_infoAudio->setTempStatus(m_linkStatus, m_linkRepeater, tempText);
@ -2868,7 +2871,7 @@ void CRepeaterHandler::writeStatus(CStatusData& statusData)
{
for (unsigned int i = 0U; i < m_maxRepeaters; i++) {
if (m_repeaters[i] != NULL) {
statusData.setDestination(m_repeaters[i]->m_address, m_repeaters[i]->m_port);
statusData.setDestination(m_repeaters[i]->m_addr, m_repeaters[i]->m_addrLen);
m_repeaters[i]->m_repeaterHandler->writeStatus(statusData);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2014 by Jonathan Naylor G4KLX
* Copyright (C) 2011-2014,2020 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
@ -596,7 +596,8 @@ void CStarNetHandler::process(CHeaderData &header)
repeater->m_destination = wxT("/") + userData->getRepeater().Left(6U) + userData->getRepeater().Right(1U);
repeater->m_repeater = userData->getRepeater();
repeater->m_gateway = userData->getGateway();
repeater->m_address = userData->getAddress();
repeater->m_addr = userData->getAddr();
repeater->m_addrLen = userData->getAddrLen();
repeater->m_local = CRepeaterHandler::findDVRepeater(userData->getRepeater());
m_repeaters[userData->getRepeater()] = repeater;
}
@ -1143,7 +1144,7 @@ void CStarNetHandler::sendToRepeaters(CHeaderData& header) const
CStarNetRepeater* repeater = it->second;
if (repeater != NULL) {
header.setYourCall(repeater->m_destination);
header.setDestination(repeater->m_address, G2_DV_PORT);
header.setDestination(repeater->m_addr, repeater->m_addrLen);
header.setRepeaters(repeater->m_gateway, repeater->m_repeater);
if (repeater->m_local != NULL)
repeater->m_local->process(header, DIR_INCOMING, AS_G2);
@ -1158,7 +1159,7 @@ void CStarNetHandler::sendToRepeaters(CAMBEData& data) const
for (CStarNetRepeatersHashMap::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) {
CStarNetRepeater* repeater = it->second;
if (repeater != NULL) {
data.setDestination(repeater->m_address, G2_DV_PORT);
data.setDestination(repeater->m_addr, repeater->m_addrLen);
if (repeater->m_local != NULL)
repeater->m_local->process(data, DIR_INCOMING, AS_G2);
else
@ -1214,7 +1215,7 @@ void CStarNetHandler::sendAck(const CUserData& user, const wxString& text) const
unsigned int id = CHeaderData::createId();
CHeaderData header(m_groupCallsign, wxT(" "), user.getUser(), user.getGateway(), user.getRepeater());
header.setDestination(user.getAddress(), G2_DV_PORT);
header.setDestination(user.getAddr(), user.getAddrLen());
header.setId(id);
m_g2Handler->writeHeader(header);
@ -1223,7 +1224,7 @@ void CStarNetHandler::sendAck(const CUserData& user, const wxString& text) const
CAMBEData data;
data.setId(id);
data.setDestination(user.getAddress(), G2_DV_PORT);
data.setDestination(user.getAddr(), user.getAddrLen());
unsigned char buffer[DV_FRAME_MAX_LENGTH_BYTES];
::memcpy(buffer + 0U, NULL_AMBE_DATA_BYTES, VOICE_FRAME_LENGTH_BYTES);

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011,2012 by Jonathan Naylor G4KLX
* Copyright (C) 2011,2012,2020 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
@ -24,8 +24,8 @@
CStatusData::CStatusData(const wxString& text, unsigned int n) :
m_data(NULL),
m_n(n),
m_address(),
m_port(0U)
m_addr(),
m_addrLen(0U)
{
m_data = new unsigned char[20U];
::memset(m_data, ' ', 20U);
@ -58,18 +58,18 @@ unsigned int CStatusData::getHBRepeaterData(unsigned char *data, unsigned int le
return 26U;
}
void CStatusData::setDestination(const in_addr& address, unsigned int port)
void CStatusData::setDestination(const sockaddr_storage& addr, unsigned int addrLen)
{
m_address = address;
m_port = port;
m_addr = addr;
m_addrLen = addrLen;
}
in_addr CStatusData::getAddress() const
sockaddr_storage CStatusData::getAddr() const
{
return m_address;
return m_addr;
}
unsigned int CStatusData::getPort() const
unsigned int CStatusData::getAddrLen() const
{
return m_port;
return m_addrLen;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010-2013 by Jonathan Naylor G4KLX
* Copyright (C) 2010-2013,2020 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
@ -97,7 +97,12 @@ bool CTCPReaderWriterClient::open()
if (m_address.IsEmpty() || m_port == 0U)
return false;
m_fd = ::socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(m_address, m_port, addr, addrLen) != 0)
return false;
m_fd = ::socket(addr.ss_family, SOCK_STREAM, 0);
if (m_fd < 0) {
#if defined(__WINDOWS__)
wxLogError(wxT("Cannot create the TCP client socket, err=%d"), ::GetLastError());
@ -108,22 +113,15 @@ bool CTCPReaderWriterClient::open()
}
if (!m_localAddress.IsEmpty()) {
sockaddr_in addr;
::memset(&addr, 0x00, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = 0U;
#if defined(__WINDOWS__)
addr.sin_addr.s_addr = ::inet_addr(m_localAddress.mb_str());
#else
addr.sin_addr.s_addr = ::inet_addr(m_localAddress.mb_str());
#endif
if (addr.sin_addr.s_addr == INADDR_NONE) {
wxLogError(wxT("The address is invalid - %s"), m_localAddress.c_str());
sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(m_localAddress, 0U, addr, addrLen) != 0) {
wxLogError(wxT("The local address is invalid - %s"), m_localAddress.c_str());
close();
return false;
}
if (::bind(m_fd, (sockaddr*)&addr, sizeof(sockaddr_in)) == -1) {
if (::bind(m_fd, (sockaddr*)&addr, addrLen) == -1) {
#if defined(__WINDOWS__)
wxLogError(wxT("Cannot bind the TCP client address, err=%d"), ::GetLastError());
#else
@ -134,18 +132,7 @@ bool CTCPReaderWriterClient::open()
}
}
struct sockaddr_in addr;
::memset(&addr, 0x00, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(m_port);
addr.sin_addr = CUDPReaderWriter::lookup(m_address);
if (addr.sin_addr.s_addr == INADDR_NONE) {
close();
return false;
}
if (::connect(m_fd, (sockaddr*)&addr, sizeof(struct sockaddr_in)) == -1) {
if (::connect(m_fd, (sockaddr*)&addr, addrLen) == -1) {
#if defined(__WINDOWS__)
wxLogError(wxT("Cannot connect the TCP client socket, err=%d"), ::GetLastError());
#else

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011,2014 by Jonathan Naylor G4KLX
* Copyright (C) 2011,2014,2020 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
@ -17,6 +17,7 @@
*/
#include "TCPReaderWriterServer.h"
#include "UDPReaderWriter.h"
#if !defined(__WINDOWS__)
#include <cerrno>
@ -159,7 +160,14 @@ void CTCPReaderWriterServer::stop()
bool CTCPReaderWriterServer::open()
{
m_fd = ::socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(m_address, m_port, addr, addrLen) != 0) {
wxLogError(wxT("The local address is invalid - %s"), m_address.c_str());
return false;
}
m_fd = ::socket(addr.ss_family, SOCK_STREAM, 0);
if (m_fd < 0) {
#if defined(__WINDOWS__)
wxLogError(wxT("Cannot create the TCP server socket, err=%d"), ::GetLastError());
@ -169,21 +177,6 @@ bool CTCPReaderWriterServer::open()
return false;
}
struct sockaddr_in addr;
::memset(&addr, 0x00, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(m_port);
if (m_address.IsEmpty())
addr.sin_addr.s_addr = htonl(INADDR_ANY);
else
addr.sin_addr = lookup(m_address);
if (addr.sin_addr.s_addr == INADDR_NONE) {
wxLogError(wxT("The address is invalid - %s"), m_address.c_str());
close();
return false;
}
int reuse = 1;
if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) {
#if defined(__WINDOWS__)
@ -195,7 +188,7 @@ bool CTCPReaderWriterServer::open()
return false;
}
if (::bind(m_fd, (sockaddr*)&addr, sizeof(struct sockaddr_in)) == -1) {
if (::bind(m_fd, (sockaddr*)&addr, addrLen) == -1) {
#if defined(__WINDOWS__)
wxLogError(wxT("Cannot bind the TCP server address, err=%d"), ::GetLastError());
#else
@ -247,11 +240,11 @@ int CTCPReaderWriterServer::accept()
return -1;
#endif
struct sockaddr_in addr;
struct sockaddr_storage addr;
#if defined(__WINDOWS__)
int len = sizeof(struct sockaddr_in);
int len = sizeof(struct sockaddr_storage);
#else
socklen_t len = sizeof(struct sockaddr_in);
socklen_t len = sizeof(struct sockaddr_storage);
#endif
ret = ::accept(m_fd, (sockaddr*)&addr, &len);
@ -278,42 +271,3 @@ void CTCPReaderWriterServer::close()
}
}
in_addr CTCPReaderWriterServer::lookup(const wxString& hostname) const
{
in_addr addr;
#if defined(WIN32)
unsigned long address = ::inet_addr(hostname.mb_str());
if (address != INADDR_NONE && address != INADDR_ANY) {
addr.s_addr = address;
return addr;
}
struct hostent* hp = ::gethostbyname(hostname.mb_str());
if (hp != NULL) {
::memcpy(&addr, hp->h_addr_list[0], hp->h_length);
return addr;
}
wxLogError(wxT("Cannot find %s"), hostname.c_str());
addr.s_addr = INADDR_NONE;
return addr;
#else
in_addr_t address = ::inet_addr(hostname.mb_str());
if (address != in_addr_t(-1)) {
addr.s_addr = address;
return addr;
}
struct hostent* hp = ::gethostbyname(hostname.mb_str());
if (hp != NULL) {
::memcpy(&addr, hp->h_addr_list[0], hp->h_length);
return addr;
}
wxLogError(wxT("Cannot find %s"), hostname.c_str());
addr.s_addr = INADDR_NONE;
return addr;
#endif
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010,2012,2013 by Jonathan Naylor G4KLX
* Copyright (C) 2010,2012,2013,2020 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
@ -21,15 +21,15 @@
#include "DStarDefines.h"
#include "Utils.h"
CTextData::CTextData(LINK_STATUS status, const wxString& reflector, const wxString& text, const in_addr& address, unsigned int port, bool temporary) :
CTextData::CTextData(LINK_STATUS status, const wxString& reflector, const wxString& text, const sockaddr_storage& addr, unsigned int addrLen, bool temporary) :
m_status(status),
m_reflector(NULL),
m_text(NULL),
m_address(address),
m_port(port),
m_addr(addr),
m_addrLen(addrLen),
m_temporary(temporary)
{
wxASSERT(port > 0U);
wxASSERT(addrLen > 0U);
m_reflector = new unsigned char[8U];
m_text = new unsigned char[20U];
@ -46,15 +46,15 @@ m_temporary(temporary)
m_text[i] = text.GetChar(i);
}
CTextData::CTextData(const wxString& text, const in_addr& address, unsigned int port, bool temporary) :
CTextData::CTextData(const wxString& text, const sockaddr_storage& addr, unsigned int addrLen, bool temporary) :
m_status(LS_NONE),
m_reflector(NULL),
m_text(NULL),
m_address(address),
m_port(port),
m_addr(addr),
m_addrLen(addrLen),
m_temporary(temporary)
{
wxASSERT(port > 0U);
wxASSERT(addrLen > 0U);
m_reflector = new unsigned char[8U];
m_text = new unsigned char[20U];
@ -95,12 +95,12 @@ unsigned int CTextData::getHBRepeaterData(unsigned char *data, unsigned int leng
}
}
in_addr CTextData::getAddress() const
sockaddr_storage CTextData::getAddr() const
{
return m_address;
return m_addr;
}
unsigned int CTextData::getPort() const
unsigned int CTextData::getAddrLen() const
{
return m_port;
return m_addrLen;
}

View file

@ -43,7 +43,7 @@ private:
LINK_STATUS m_status;
unsigned char* m_reflector;
unsigned char* m_text;
sockaddr_storage m_address;
sockaddr_storage m_addr;
unsigned int m_addrLen;
bool m_temporary;
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2014,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2006-2014,2018,2020 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
@ -27,6 +27,7 @@ CUDPReaderWriter::CUDPReaderWriter(const wxString& address, unsigned int port) :
m_address(address),
m_port(port),
m_addr(),
m_addrLen(0U),
m_fd(-1)
{
#if defined(__WINDOWS__)
@ -41,6 +42,7 @@ CUDPReaderWriter::CUDPReaderWriter(unsigned int port) :
m_address(),
m_port(port),
m_addr(),
m_addrLen(0U),
m_fd(-1)
{
#if defined(__WINDOWS__)
@ -55,6 +57,7 @@ CUDPReaderWriter::CUDPReaderWriter() :
m_address(),
m_port(0U),
m_addr(),
m_addrLen(0U),
m_fd(-1)
{
#if defined(__WINDOWS__)
@ -72,49 +75,98 @@ CUDPReaderWriter::~CUDPReaderWriter()
#endif
}
in_addr CUDPReaderWriter::lookup(const wxString& hostname)
int CUDPReaderWriter::lookup(const wxString& hostname, unsigned int port, sockaddr_storage& addr, unsigned int& address_length)
{
in_addr addr;
#if defined(WIN32)
unsigned long address = ::inet_addr(hostname.mb_str());
if (address != INADDR_NONE && address != INADDR_ANY) {
addr.s_addr = address;
return addr;
struct addrinfo hints;
::memset(&hints, 0, sizeof(hints));
return lookup(hostname, port, addr, address_length, hints);
}
int CUDPReaderWriter::lookup(const wxString& hostname, unsigned int port, sockaddr_storage& addr, unsigned int& address_length, struct addrinfo& hints)
{
std::string portstr = std::to_string(port);
struct addrinfo *res;
/* port is always digits, no needs to lookup service */
hints.ai_flags |= AI_NUMERICSERV;
int err = ::getaddrinfo(hostname.IsEmpty() ? NULL : (const char*)hostname, portstr.c_str(), &hints, &res);
if (err != 0) {
sockaddr_in* paddr = (sockaddr_in*)&addr;
::memset(paddr, 0x00U, address_length = sizeof(sockaddr_in));
paddr->sin_family = AF_INET;
paddr->sin_port = htons(port);
paddr->sin_addr.s_addr = htonl(INADDR_NONE);
wxLogError(wxT("Cannot find address for host %s"), hostname.c_str());
return err;
}
struct hostent* hp = ::gethostbyname(hostname.mb_str());
if (hp != NULL) {
::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr));
return addr;
::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen);
::freeaddrinfo(res);
return 0;
}
bool CUDPReaderWriter::match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type)
{
if (addr1.ss_family != addr2.ss_family)
return false;
if (type == IMT_ADDRESS_AND_PORT) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return (in_1->sin_addr.s_addr == in_2->sin_addr.s_addr) && (in_1->sin_port == in_2->sin_port);
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr) && (in6_1->sin6_port == in6_2->sin6_port);
default:
return false;
}
} else if (type == IMT_ADDRESS_ONLY) {
switch (addr1.ss_family) {
case AF_INET:
struct sockaddr_in *in_1, *in_2;
in_1 = (struct sockaddr_in*)&addr1;
in_2 = (struct sockaddr_in*)&addr2;
return in_1->sin_addr.s_addr == in_2->sin_addr.s_addr;
case AF_INET6:
struct sockaddr_in6 *in6_1, *in6_2;
in6_1 = (struct sockaddr_in6*)&addr1;
in6_2 = (struct sockaddr_in6*)&addr2;
return IN6_ARE_ADDR_EQUAL(&in6_1->sin6_addr, &in6_2->sin6_addr);
default:
return false;
}
} else {
return false;
}
wxLogError(wxT("Cannot find address for host %s"), hostname.c_str());
addr.s_addr = INADDR_NONE;
return addr;
#else
in_addr_t address = ::inet_addr(hostname.mb_str());
if (address != in_addr_t(-1)) {
addr.s_addr = address;
return addr;
}
struct hostent* hp = ::gethostbyname(hostname.mb_str());
if (hp != NULL) {
::memcpy(&addr, hp->h_addr_list[0], sizeof(struct in_addr));
return addr;
}
wxLogError(wxT("Cannot find address for host %s"), hostname.c_str());
addr.s_addr = INADDR_NONE;
return addr;
#endif
}
bool CUDPReaderWriter::open()
{
m_fd = ::socket(PF_INET, SOCK_DGRAM, 0);
sockaddr_storage addr;
unsigned int addrLen;
lookup(m_address, m_port, addr, addrLen);
return open(addr);
}
bool CUDPReaderWriter::open(const sockaddr_storage& addr)
{
return open(addr.ss_family);
}
bool CUDPReaderWriter::open(int family)
{
m_fd = ::socket(family, SOCK_DGRAM, 0);
if (m_fd < 0) {
#if defined(__WINDOWS__)
wxLogError(wxT("Cannot create the UDP socket, err: %lu"), ::GetLastError());
@ -125,20 +177,17 @@ bool CUDPReaderWriter::open()
}
if (m_port > 0U) {
sockaddr_in addr;
::memset(&addr, 0x00, sizeof(sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(m_port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
sockaddr_storage addr;
unsigned int addrLen;
if (!m_address.IsEmpty()) {
#if defined(__WINDOWS__)
addr.sin_addr.s_addr = ::inet_addr(m_address.mb_str());
#else
addr.sin_addr.s_addr = ::inet_addr(m_address.mb_str());
#endif
if (addr.sin_addr.s_addr == INADDR_NONE) {
wxLogError(wxT("The address is invalid - %s"), m_address.c_str());
if (lookup(m_address, m_port, addr, addrLen) != 0) {
wxLogError(wxT("The local address is invalid - %s"), m_address.c_str());
return false;
}
} else {
if (lookup("", m_port, addr, addrLen) != 0) {
wxLogError(wxT("The local address is invalid"));
return false;
}
}
@ -153,7 +202,7 @@ bool CUDPReaderWriter::open()
return false;
}
if (::bind(m_fd, (sockaddr*)&addr, sizeof(sockaddr_in)) == -1) {
if (::bind(m_fd, (sockaddr*)&addr, sizeof(sockaddr_storage)) == -1) {
#if defined(__WINDOWS__)
wxLogError(wxT("Cannot bind the UDP address (port: %u), err: %lu"), m_port, ::GetLastError());
#else
@ -166,7 +215,7 @@ bool CUDPReaderWriter::open()
return true;
}
int CUDPReaderWriter::read(unsigned char* buffer, unsigned int length, in_addr& address, unsigned int& port)
int CUDPReaderWriter::read(unsigned char* buffer, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen)
{
// Check that the readfrom() won't block
fd_set readFds;
@ -195,11 +244,10 @@ int CUDPReaderWriter::read(unsigned char* buffer, unsigned int length, in_addr&
if (ret == 0)
return 0;
sockaddr_in addr;
#if defined(__WINDOWS__)
int size = sizeof(sockaddr_in);
int size = sizeof(sockaddr_storage);
#else
socklen_t size = sizeof(sockaddr_in);
socklen_t size = sizeof(sockaddr_storage);
#endif
ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&addr, &size);
@ -212,22 +260,14 @@ int CUDPReaderWriter::read(unsigned char* buffer, unsigned int length, in_addr&
return -1;
}
address = addr.sin_addr;
port = ntohs(addr.sin_port);
addrLen = size;
return len;
}
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 sockaddr_storage& addr, unsigned int addrLen)
{
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));
ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&addr, addrLen);
if (ret < 0) {
#if defined(__WINDOWS__)
wxLogError(wxT("Error returned from sendto (port: %u), err: %lu"), m_port, ::GetLastError());

View file

@ -32,6 +32,15 @@
#include <errno.h>
#endif
#if !defined(UDP_SOCKET_MAX)
#define UDP_SOCKET_MAX 1
#endif
enum IPMATCHTYPE {
IMT_ADDRESS_AND_PORT,
IMT_ADDRESS_ONLY
};
class CUDPReaderWriter {
public:
CUDPReaderWriter(const wxString& address, unsigned int port);
@ -39,10 +48,13 @@ public:
CUDPReaderWriter();
~CUDPReaderWriter();
static int lookup(const wxString& hostName, unsigned int port, sockaddr_storage& addr, unsigned int& addrLen);
static int lookup(const wxString& hostName, unsigned int port, sockaddr_storage& address, unsigned int& address_length);
static int lookup(const wxString& hostName, unsigned int port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints);
static bool match(const sockaddr_storage& first, const sockaddr_storage& second);
static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT);
bool open(const sockaddr_storage& addr);
bool open(int family);
bool open();
int read(unsigned char* buffer, unsigned int length, sockaddr_storage& addr, unsigned int& addrLen);

View file

@ -1093,20 +1093,20 @@ void CIRCDDBGatewayThread::loadGateways()
CHostFile hostFile(fileName.GetFullPath(), false);
for (unsigned int i = 0U; i < hostFile.getCount(); i++) {
wxString gateway = hostFile.getName(i);
in_addr address = CUDPReaderWriter::lookup(hostFile.getAddress(i));
if (address.s_addr != INADDR_NONE) {
unsigned char* ucp = (unsigned char*)&address;
sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(hostFile.getAddress(i), DCS_PORT, addr, addrLen) == 0) {
bool lock = hostFile.getLock(i);
wxString addrText;
addrText.Printf(wxT("%u.%u.%u.%u"), ucp[0U] & 0xFFU, ucp[1U] & 0xFFU, ucp[2U] & 0xFFU, ucp[3U] & 0xFFU);
wxLogMessage(wxT("Locking %s to %s"), gateway.c_str(), addrText.c_str());
if (lock)
wxLogMessage(wxT("Locking %s"), gateway.c_str());
gateway.Append(wxT(" "));
gateway.Truncate(LONG_CALLSIGN_LENGTH - 1U);
gateway.Append(wxT("G"));
m_cache.updateGateway(gateway, addrText, DP_DEXTRA, true, false);
m_cache.updateGateway(gateway, addr, addrLen, DP_DEXTRA, true, false);
count++;
}
@ -1170,22 +1170,20 @@ void CIRCDDBGatewayThread::loadDExtraReflectors(const wxString& fileName)
CHostFile hostFile(fileName, false);
for (unsigned int i = 0U; i < hostFile.getCount(); i++) {
wxString reflector = hostFile.getName(i);
in_addr address = CUDPReaderWriter::lookup(hostFile.getAddress(i));
bool lock = hostFile.getLock(i);
if (address.s_addr != INADDR_NONE) {
unsigned char* ucp = (unsigned char*)&address;
wxString addrText;
addrText.Printf(wxT("%u.%u.%u.%u"), ucp[0U] & 0xFFU, ucp[1U] & 0xFFU, ucp[2U] & 0xFFU, ucp[3U] & 0xFFU);
sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(hostFile.getAddress(i), DCS_PORT, addr, addrLen) == 0) {
bool lock = hostFile.getLock(i);
if (lock)
wxLogMessage(wxT("Locking %s to %s"), reflector.c_str(), addrText.c_str());
wxLogMessage(wxT("Locking %s"), reflector.c_str());
reflector.Append(wxT(" "));
reflector.Truncate(LONG_CALLSIGN_LENGTH - 1U);
reflector.Append(wxT("G"));
m_cache.updateGateway(reflector, addrText, DP_DEXTRA, lock, true);
m_cache.updateGateway(reflector, addr, addrLen, DP_DEXTRA, lock, true);
count++;
}
@ -1201,22 +1199,20 @@ void CIRCDDBGatewayThread::loadDPlusReflectors(const wxString& fileName)
CHostFile hostFile(fileName, false);
for (unsigned int i = 0U; i < hostFile.getCount(); i++) {
wxString reflector = hostFile.getName(i);
in_addr address = CUDPReaderWriter::lookup(hostFile.getAddress(i));
bool lock = hostFile.getLock(i);
if (address.s_addr != INADDR_NONE) {
unsigned char* ucp = (unsigned char*)&address;
wxString addrText;
addrText.Printf(wxT("%u.%u.%u.%u"), ucp[0U] & 0xFFU, ucp[1U] & 0xFFU, ucp[2U] & 0xFFU, ucp[3U] & 0xFFU);
sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(hostFile.getAddress(i), DCS_PORT, addr, addrLen) == 0) {
bool lock = hostFile.getLock(i);
if (lock)
wxLogMessage(wxT("Locking %s to %s"), reflector.c_str(), addrText.c_str());
wxLogMessage(wxT("Locking %s"), reflector.c_str());
reflector.Append(wxT(" "));
reflector.Truncate(LONG_CALLSIGN_LENGTH - 1U);
reflector.Append(wxT("G"));
m_cache.updateGateway(reflector, addrText, DP_DPLUS, lock, true);
m_cache.updateGateway(reflector, addr, addrLen, DP_DPLUS, lock, true);
count++;
}
@ -1232,22 +1228,20 @@ void CIRCDDBGatewayThread::loadDCSReflectors(const wxString& fileName)
CHostFile hostFile(fileName, false);
for (unsigned int i = 0U; i < hostFile.getCount(); i++) {
wxString reflector = hostFile.getName(i);
in_addr address = CUDPReaderWriter::lookup(hostFile.getAddress(i));
bool lock = hostFile.getLock(i);
if (address.s_addr != INADDR_NONE) {
unsigned char* ucp = (unsigned char*)&address;
wxString addrText;
addrText.Printf(wxT("%u.%u.%u.%u"), ucp[0U] & 0xFFU, ucp[1U] & 0xFFU, ucp[2U] & 0xFFU, ucp[3U] & 0xFFU);
sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(hostFile.getAddress(i), DCS_PORT, addr, addrLen) == 0) {
bool lock = hostFile.getLock(i);
if (lock)
wxLogMessage(wxT("Locking %s to %s"), reflector.c_str(), addrText.c_str());
wxLogMessage(wxT("Locking %s"), reflector.c_str());
reflector.Append(wxT(" "));
reflector.Truncate(LONG_CALLSIGN_LENGTH - 1U);
reflector.Append(wxT("G"));
m_cache.updateGateway(reflector, addrText, DP_DCS, lock, true);
m_cache.updateGateway(reflector, addr, addrLen, DP_DCS, lock, true);
count++;
}
@ -1266,26 +1260,19 @@ void CIRCDDBGatewayThread::loadXLXReflectors()
if (!reflector.StartsWith(wxT("XLX")))
continue;
in_addr address = CUDPReaderWriter::lookup(hostFile.getAddress(i));
bool lock = hostFile.getLock(i);
if (address.s_addr != INADDR_NONE) {
unsigned char* ucp = (unsigned char*)&address;
wxString addrText;
addrText.Printf(wxT("%u.%u.%u.%u"), ucp[0U] & 0xFFU, ucp[1U] & 0xFFU, ucp[2U] & 0xFFU, ucp[3U] & 0xFFU);
sockaddr_storage addr;
unsigned int addrLen;
if (CUDPReaderWriter::lookup(hostFile.getAddress(i), DCS_PORT, addr, addrLen) == 0) {
bool lock = hostFile.getLock(i);
if (lock)
wxLogMessage(wxT("Locking %s to %s"), reflector.c_str(), addrText.c_str());
wxLogMessage(wxT("Locking %s"), reflector.c_str());
reflector.Append(wxT(" "));
reflector.Truncate(LONG_CALLSIGN_LENGTH - 1U);
reflector.Append(wxT("G"));
//if (m_dcsEnabled && reflector.StartsWith(wxT("DCS")))
m_cache.updateGateway(reflector, addrText, DP_DCS, lock, true);
//else if (m_dextraEnabled && reflector.StartsWith(wxT("XRF")))
// m_cache.updateGateway(reflector, addrText, DP_DEXTRA, lock, true);
m_cache.updateGateway(reflector, addr, addrLen, DP_DCS, lock, true);
count++;
}