From 457be810a3902f16174ab78177ec49dfaf9ddfb8 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 6 Sep 2020 12:09:37 +0900 Subject: [PATCH 1/5] UDPSocket renewal Currently there is six variations of (IPv4) UDPSocket.cpp. - FMClients, NXDNClients, P25Clients, YSFClients(YSFParrot) use ::fprintf() for logging - YSFClients(YSFReflector) use LogError() and LogInfo() for logging special open(string &bindaddr) function - YSFClients(YSFGateway), DAPNETGateway use LogError() and LogInfo() for logging - P25Clients, DMRGateway use LogError() for logging no LogInfo("Opening UDP port on") message - NXDNClients use LogError() for logging no LogInfo("Opening UDP port on") message add #include - MMDVMHost use LogError() for logging no LogInfo("Opening UDP port on") message no assert(!address.empty()) at constructor to avoid explosion, commonized them. switch ::fprintf()/LogError by #define HAVE_LOG_H always display LogInfo("Opening UDP port on") message delete #include , this is not needed no assert(!address.empty()) at constructor and to support YSFReflector, add multiple socket support. default is #define UDP_SOCKET_MAX 1 so normally this feature is disabled. added these functions. CUDPSocket() (constructor without any parameters) open(index, af, addr, port) close(index) CUDPSocket() means CUDPSocket(address = "", port = 0) index selects socket, address and port is defined at open. to have compatibility for old codes, these function works as CUDPSocket(addr, port) store addr and port to index #0 CUDPSocket(port) store addr = "" and port to index #0 open() open with addr and port of index #0, AF_UNSPEC open(af) open with addr and port of index #0, specified af close() close *all* sockets read/write operation is for all opened sockets. --- Makefile | 1 + UDPSocket.cpp | 175 ++++++++++++++++++++++++++++++++------------------ UDPSocket.h | 18 ++++-- 3 files changed, 128 insertions(+), 66 deletions(-) diff --git a/Makefile b/Makefile index 1ad3c8a..16c0195 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ LIBS = -lpthread #CFLAGS = -g -O3 -Wall -DUSE_GPSD -std=c++0x -pthread #LIBS = -lpthread -lgps +CFLAGS += -DHAVE_LOG_H LDFLAGS = -g OBJECTS = \ diff --git a/UDPSocket.cpp b/UDPSocket.cpp index 0bbe27b..bfdc057 100644 --- a/UDPSocket.cpp +++ b/UDPSocket.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2016 by Jonathan Naylor G4KLX + * Copyright (C) 2006-2016,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 @@ -17,7 +17,6 @@ */ #include "UDPSocket.h" -#include "Log.h" #include @@ -26,11 +25,14 @@ #include #endif +#if defined(HAVE_LOG_H) +#include "Log.h" +#else +#define LogError(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__) +#define LogInfo(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__) +#endif -CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) : -m_address(address), -m_port(port), -m_fd(-1) +CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) { #if defined(_WIN32) || defined(_WIN64) WSAData data; @@ -38,19 +40,26 @@ m_fd(-1) if (wsaRet != 0) LogError("Error from WSAStartup"); #endif + for (int i = 0; i < UDP_SOCKET_MAX; i++) { + m_address[i] = ""; + m_port[i] = 0U; + m_af[i] = 0U; + m_fd[i] = -1; + } + + m_address[0] = address; + m_port[0] = port; + m_counter = 0U; } -CUDPSocket::CUDPSocket(unsigned int port) : -m_address(), -m_port(port), -m_fd(-1) +CUDPSocket::CUDPSocket(unsigned int port) { -#if defined(_WIN32) || defined(_WIN64) - WSAData data; - int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data); - if (wsaRet != 0) - LogError("Error from WSAStartup"); -#endif + CUDPSocket("", port); +} + +CUDPSocket::CUDPSocket() +{ + CUDPSocket("", 0U); } CUDPSocket::~CUDPSocket() @@ -149,12 +158,17 @@ bool CUDPSocket::isnone(const sockaddr_storage &addr) bool CUDPSocket::open() { - return open(AF_UNSPEC); + return open(0, AF_UNSPEC, m_address[0], m_port[0]); } bool CUDPSocket::open(const unsigned int af) { - int err; + return open(0, af, m_address[0], m_port[0]); +} + +bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned int port) +{ + int err, fd; sockaddr_storage addr; unsigned int addrlen; struct addrinfo hints; @@ -164,14 +178,14 @@ bool CUDPSocket::open(const unsigned int af) hints.ai_family = af; /* to determine protocol family, call lookup() first. */ - err = lookup(m_address, m_port, addr, addrlen, hints); + err = lookup(address, port, addr, addrlen, hints); if (err) { - LogError("The local address is invalid - %s", m_address.c_str()); + LogError("The local address is invalid - %s", address.c_str()); return false; } - m_fd = ::socket(addr.ss_family, SOCK_DGRAM, 0); - if (m_fd < 0) { + fd = ::socket(addr.ss_family, SOCK_DGRAM, 0); + if (fd < 0) { #if defined(_WIN32) || defined(_WIN64) LogError("Cannot create the UDP socket, err: %lu", ::GetLastError()); #else @@ -180,9 +194,14 @@ bool CUDPSocket::open(const unsigned int af) return false; } - if (m_port > 0U) { + m_address[index] = address; + m_port[index] = port; + m_af[index] = addr.ss_family; + m_fd[index] = fd; + + if (port > 0U) { int reuse = 1; - if (::setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) { + if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse)) == -1) { #if defined(_WIN32) || defined(_WIN64) LogError("Cannot set the UDP socket option, err: %lu", ::GetLastError()); #else @@ -191,7 +210,7 @@ bool CUDPSocket::open(const unsigned int af) return false; } - if (::bind(m_fd, (sockaddr*)&addr, addrlen) == -1) { + if (::bind(fd, (sockaddr*)&addr, addrlen) == -1) { #if defined(_WIN32) || defined(_WIN64) LogError("Cannot bind the UDP address, err: %lu", ::GetLastError()); #else @@ -199,6 +218,8 @@ bool CUDPSocket::open(const unsigned int af) #endif return false; } + + LogInfo("Opening UDP port on %u", port); } return true; @@ -210,30 +231,43 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag assert(length > 0U); // Check that the readfrom() won't block - fd_set readFds; - FD_ZERO(&readFds); -#if defined(_WIN32) || defined(_WIN64) - FD_SET((unsigned int)m_fd, &readFds); -#else - FD_SET(m_fd, &readFds); -#endif + int i, n; + struct pollfd pfd[UDP_SOCKET_MAX]; + for (i = n = 0; i < UDP_SOCKET_MAX; i++) { + if (m_fd[i] >= 0) { + pfd[n].fd = m_fd[i]; + pfd[n].events = POLLIN; + n++; + } + } + + // no socket descriptor to receive + if (n == 0) + return 0; // Return immediately - timeval tv; - tv.tv_sec = 0L; - tv.tv_usec = 0L; - - int ret = ::select(m_fd + 1, &readFds, NULL, NULL, &tv); +#if defined(_WIN32) || defined(_WIN64) + int ret = WSAPoll(pfd, n, 0); +#else + int ret = ::poll(pfd, n, 0); +#endif if (ret < 0) { #if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from UDP select, err: %lu", ::GetLastError()); + LogError("Error returned from UDP poll, err: %lu", ::GetLastError()); #else - LogError("Error returned from UDP select, err: %d", errno); + LogError("Error returned from UDP poll, err: %d", errno); #endif return -1; } - if (ret == 0) + int index; + for (i = 0; i < n; i++) { + // round robin + index = (i + m_counter) % n; + if (pfd[index].revents & POLLIN) + break; + } + if (i == n) return 0; #if defined(_WIN32) || defined(_WIN64) @@ -243,9 +277,9 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag #endif #if defined(_WIN32) || defined(_WIN64) - int len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size); + int len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size); #else - ssize_t len = ::recvfrom(m_fd, (char*)buffer, length, 0, (sockaddr *)&address, &size); + ssize_t len = ::recvfrom(pfd[index].fd, (char*)buffer, length, 0, (sockaddr *)&address, &size); #endif if (len <= 0) { #if defined(_WIN32) || defined(_WIN64) @@ -256,6 +290,7 @@ int CUDPSocket::read(unsigned char* buffer, unsigned int length, sockaddr_storag return -1; } + m_counter++; address_length = size; return len; } @@ -265,36 +300,52 @@ bool CUDPSocket::write(const unsigned char* buffer, unsigned int length, const s assert(buffer != NULL); assert(length > 0U); + bool result = false; + + for (int i = 0; i < UDP_SOCKET_MAX; i++) { + if (m_fd[i] < 0 || m_af[i] != address.ss_family) + continue; + #if defined(_WIN32) || defined(_WIN64) - int ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, address_length); + int ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length); #else - ssize_t ret = ::sendto(m_fd, (char *)buffer, length, 0, (sockaddr *)&address, address_length); + ssize_t ret = ::sendto(m_fd[i], (char *)buffer, length, 0, (sockaddr *)&address, address_length); #endif - if (ret < 0) { + + if (ret < 0) { #if defined(_WIN32) || defined(_WIN64) - LogError("Error returned from sendto, err: %lu", ::GetLastError()); + LogError("Error returned from sendto, err: %lu", ::GetLastError()); #else - LogError("Error returned from sendto, err: %d", errno); + LogError("Error returned from sendto, err: %d", errno); #endif - return false; + } else { +#if defined(_WIN32) || defined(_WIN64) + if (ret == int(length)) + result = true; +#else + if (ret == ssize_t(length)) + result = true; +#endif + } } -#if defined(_WIN32) || defined(_WIN64) - if (ret != int(length)) - return false; -#else - if (ret != ssize_t(length)) - return false; -#endif - - return true; + return result; } void CUDPSocket::close() { -#if defined(_WIN32) || defined(_WIN64) - ::closesocket(m_fd); -#else - ::close(m_fd); -#endif + for (int i = 0; i < UDP_SOCKET_MAX; i++) + close(m_fd[i]); +} + +void CUDPSocket::close(const unsigned int index) +{ + if (m_fd[index] >= 0) { +#if defined(_WIN32) || defined(_WIN64) + ::closesocket(m_fd[index]); +#else + ::close(m_fd[index]); +#endif + m_fd[index] = -1; + } } diff --git a/UDPSocket.h b/UDPSocket.h index ad5b2a1..5d9fd07 100644 --- a/UDPSocket.h +++ b/UDPSocket.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2011,2013,2015,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2011,2013,2015,2016,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 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -35,19 +36,26 @@ #include #endif +#if !defined(UDP_SOCKET_MAX) +#define UDP_SOCKET_MAX 1 +#endif + class CUDPSocket { public: CUDPSocket(const std::string& address, unsigned int port = 0U); CUDPSocket(unsigned int port = 0U); + CUDPSocket(); ~CUDPSocket(); bool open(); bool open(const unsigned int af); + bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned int port); int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length); bool write(const unsigned char* buffer, unsigned int length, const sockaddr_storage& address, unsigned int address_length); void close(); + void close(const unsigned int index); static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage &address, unsigned int &address_length); static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage &address, unsigned int &address_length, struct addrinfo &hints); @@ -56,9 +64,11 @@ public: static bool isnone(const sockaddr_storage &addr); private: - std::string m_address; - unsigned short m_port; - int m_fd; + std::string m_address[UDP_SOCKET_MAX]; + unsigned short m_port[UDP_SOCKET_MAX]; + unsigned int m_af[UDP_SOCKET_MAX]; + int m_fd[UDP_SOCKET_MAX]; + unsigned int m_counter; }; #endif From def0edbaca7f5420668b17d1f6be7b09290ee799 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 6 Sep 2020 15:48:22 +0900 Subject: [PATCH 2/5] UDPSocket renewal (2) introduced YSFClients code match_addr(addr1, addr2) -> match(addr1, addr2, IMT_ADDRESS_ONLY) isnone() -> isNone() open(sockaddr_storage&) added (this refers address family only) --- UDPSocket.cpp | 110 ++++++++++++++++++++++---------------------------- UDPSocket.h | 20 +++++---- 2 files changed, 61 insertions(+), 69 deletions(-) diff --git a/UDPSocket.cpp b/UDPSocket.cpp index bfdc057..ccb93a4 100644 --- a/UDPSocket.cpp +++ b/UDPSocket.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2016,2018,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2006-2016,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 @@ -57,11 +57,6 @@ CUDPSocket::CUDPSocket(unsigned int port) CUDPSocket("", port); } -CUDPSocket::CUDPSocket() -{ - CUDPSocket("", 0U); -} - CUDPSocket::~CUDPSocket() { #if defined(_WIN32) || defined(_WIN64) @@ -69,28 +64,26 @@ CUDPSocket::~CUDPSocket() #endif } -int CUDPSocket::lookup(const std::string& hostname, unsigned int port, sockaddr_storage &addr, unsigned int &address_length) +int CUDPSocket::lookup(const std::string& hostname, unsigned int port, sockaddr_storage& addr, unsigned int& address_length) { struct addrinfo hints; - ::memset(&hints, 0, sizeof(hints)); return lookup(hostname, port, addr, address_length, hints); } -int CUDPSocket::lookup(const std::string& hostname, unsigned int port, sockaddr_storage &addr, unsigned int &address_length, struct addrinfo &hints) +int CUDPSocket::lookup(const std::string& hostname, unsigned int port, sockaddr_storage& addr, unsigned int& address_length, struct addrinfo& hints) { - int err; std::string portstr = std::to_string(port); struct addrinfo *res; /* port is always digits, no needs to lookup service */ hints.ai_flags |= AI_NUMERICSERV; - err = getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), portstr.c_str(), &hints, &res); - if (err) { - sockaddr_in *paddr = (sockaddr_in *)&addr; - ::memset(paddr, 0, address_length = sizeof(sockaddr_in)); + int err = getaddrinfo(hostname.empty() ? NULL : hostname.c_str(), 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); @@ -101,90 +94,85 @@ int CUDPSocket::lookup(const std::string& hostname, unsigned int port, sockaddr_ ::memcpy(&addr, res->ai_addr, address_length = res->ai_addrlen); freeaddrinfo(res); + return 0; } -bool CUDPSocket::match(const sockaddr_storage &addr1, const sockaddr_storage &addr2) +bool CUDPSocket::match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type) { if (addr1.ss_family != addr2.ss_family) return false; - 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: + 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; } } -bool CUDPSocket::match_addr(const sockaddr_storage &addr1, const sockaddr_storage &addr2) -{ - if (addr1.ss_family != addr2.ss_family) - return false; - - 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; - } -} - -bool CUDPSocket::isnone(const sockaddr_storage &addr) +bool CUDPSocket::isNone(const sockaddr_storage& addr) { struct sockaddr_in *in = (struct sockaddr_in *)&addr; - return ( (addr.ss_family == AF_INET) && - (in->sin_addr.s_addr == htonl(INADDR_NONE)) ); + return ((addr.ss_family == AF_INET) && (in->sin_addr.s_addr == htonl(INADDR_NONE))); } -bool CUDPSocket::open() +bool CUDPSocket::open(const sockaddr_storage& address) { - return open(0, AF_UNSPEC, m_address[0], m_port[0]); + return open(address.ss_family); } -bool CUDPSocket::open(const unsigned int af) +bool CUDPSocket::open(unsigned int af) { return open(0, af, m_address[0], m_port[0]); } bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned int port) { - int err, fd; sockaddr_storage addr; unsigned int addrlen; struct addrinfo hints; ::memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_PASSIVE; + hints.ai_flags = AI_PASSIVE; hints.ai_family = af; /* to determine protocol family, call lookup() first. */ - err = lookup(address, port, addr, addrlen, hints); - if (err) { + int err = lookup(address, port, addr, addrlen, hints); + if (err != 0) { LogError("The local address is invalid - %s", address.c_str()); return false; } - fd = ::socket(addr.ss_family, SOCK_DGRAM, 0); + int fd = ::socket(addr.ss_family, SOCK_DGRAM, 0); if (fd < 0) { #if defined(_WIN32) || defined(_WIN64) LogError("Cannot create the UDP socket, err: %lu", ::GetLastError()); diff --git a/UDPSocket.h b/UDPSocket.h index 5d9fd07..4523991 100644 --- a/UDPSocket.h +++ b/UDPSocket.h @@ -40,15 +40,19 @@ #define UDP_SOCKET_MAX 1 #endif +enum IPMATCHTYPE { + IMT_ADDRESS_AND_PORT, + IMT_ADDRESS_ONLY +}; + class CUDPSocket { public: CUDPSocket(const std::string& address, unsigned int port = 0U); CUDPSocket(unsigned int port = 0U); - CUDPSocket(); ~CUDPSocket(); - bool open(); - bool open(const unsigned int af); + bool open(unsigned int af = AF_UNSPEC); + bool open(const sockaddr_storage& address); bool open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned int port); int read(unsigned char* buffer, unsigned int length, sockaddr_storage& address, unsigned int &address_length); @@ -57,11 +61,11 @@ public: void close(); void close(const unsigned int index); - static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage &address, unsigned int &address_length); - static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage &address, unsigned int &address_length, struct addrinfo &hints); - static bool match(const sockaddr_storage &addr1, const sockaddr_storage &addr2); - static bool match_addr(const sockaddr_storage &addr1, const sockaddr_storage &addr2); - static bool isnone(const sockaddr_storage &addr); + static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage& address, unsigned int& address_length); + static int lookup(const std::string& hostName, unsigned int port, sockaddr_storage& address, unsigned int& address_length, struct addrinfo& hints); + static bool match(const sockaddr_storage& addr1, const sockaddr_storage& addr2, IPMATCHTYPE type = IMT_ADDRESS_AND_PORT); + + static bool isNone(const sockaddr_storage& addr); private: std::string m_address[UDP_SOCKET_MAX]; From 98560259231f4bf4e2d07c2ddbcfb49bab661032 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 6 Sep 2020 15:52:46 +0900 Subject: [PATCH 3/5] rewrite for UDPSocket renewal --- DMRNetwork.cpp | 2 +- DStarNetwork.cpp | 2 +- NXDNIcomNetwork.cpp | 2 +- NXDNKenwoodNetwork.cpp | 8 ++++---- P25Network.cpp | 2 +- POCSAGNetwork.cpp | 2 +- YSFNetwork.cpp | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/DMRNetwork.cpp b/DMRNetwork.cpp index 959bb65..7772ce4 100644 --- a/DMRNetwork.cpp +++ b/DMRNetwork.cpp @@ -128,7 +128,7 @@ bool CDMRNetwork::open() { LogMessage("DMR, Opening DMR Network"); - if (CUDPSocket::isnone(m_address)) + if (CUDPSocket::isNone(m_address)) CUDPSocket::lookup(m_addressStr, m_port, m_address, m_addrlen); m_status = WAITING_CONNECT; diff --git a/DStarNetwork.cpp b/DStarNetwork.cpp index 551a1c5..b499853 100644 --- a/DStarNetwork.cpp +++ b/DStarNetwork.cpp @@ -65,7 +65,7 @@ bool CDStarNetwork::open() { LogMessage("Opening D-Star network connection"); - if (CUDPSocket::isnone(m_address)) + if (CUDPSocket::isNone(m_address)) return false; m_pollTimer.start(); diff --git a/NXDNIcomNetwork.cpp b/NXDNIcomNetwork.cpp index 3b340cc..c118be6 100644 --- a/NXDNIcomNetwork.cpp +++ b/NXDNIcomNetwork.cpp @@ -50,7 +50,7 @@ bool CNXDNIcomNetwork::open() { LogMessage("Opening NXDN network connection"); - if (CUDPSocket::isnone(m_address)) + if (CUDPSocket::isNone(m_address)) return false; return m_socket.open(); diff --git a/NXDNKenwoodNetwork.cpp b/NXDNKenwoodNetwork.cpp index f84af6e..22165dd 100644 --- a/NXDNKenwoodNetwork.cpp +++ b/NXDNKenwoodNetwork.cpp @@ -82,8 +82,8 @@ bool CNXDNKenwoodNetwork::open() { LogMessage("Opening Kenwood connection"); - if (CUDPSocket::isnone(m_rtpaddress) || - CUDPSocket::isnone(m_rtcpaddress)) + if (CUDPSocket::isNone(m_rtpaddress) || + CUDPSocket::isNone(m_rtcpaddress)) return false; if (!m_rtcpSocket.open()) @@ -766,7 +766,7 @@ unsigned int CNXDNKenwoodNetwork::readRTP(unsigned char* data) sockaddr_storage address; unsigned int addrlen; int length = m_rtpSocket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match_addr(m_rtpaddress, address)) + if (length <= 0 || !CUDPSocket::match(m_rtpaddress, address, IMT_ADDRESS_ONLY)) return 0U; if (!m_enabled) @@ -789,7 +789,7 @@ unsigned int CNXDNKenwoodNetwork::readRTCP(unsigned char* data) sockaddr_storage address; unsigned int addrlen; int length = m_rtcpSocket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match_addr(m_rtcpaddress, address)) + if (length <= 0 || !CUDPSocket::match(m_rtcpaddress, address, IMT_ADDRESS_ONLY)) return 0U; if (!m_enabled) diff --git a/P25Network.cpp b/P25Network.cpp index ed28fa6..8485d2f 100644 --- a/P25Network.cpp +++ b/P25Network.cpp @@ -107,7 +107,7 @@ bool CP25Network::open() { LogMessage("Opening P25 network connection"); - if (CUDPSocket::isnone(m_address)) + if (CUDPSocket::isNone(m_address)) return false; return m_socket.open(m_address.ss_family); diff --git a/POCSAGNetwork.cpp b/POCSAGNetwork.cpp index e6b755a..e8e0d65 100644 --- a/POCSAGNetwork.cpp +++ b/POCSAGNetwork.cpp @@ -47,7 +47,7 @@ bool CPOCSAGNetwork::open() { LogMessage("Opening POCSAG network connection"); - if (CUDPSocket::isnone(m_address)) + if (CUDPSocket::isNone(m_address)) return false; return m_socket.open(); diff --git a/YSFNetwork.cpp b/YSFNetwork.cpp index ff5cab8..7ddc996 100644 --- a/YSFNetwork.cpp +++ b/YSFNetwork.cpp @@ -57,7 +57,7 @@ bool CYSFNetwork::open() { LogMessage("Opening YSF network connection"); - if (CUDPSocket::isnone(m_address)) + if (CUDPSocket::isNone(m_address)) return false; m_pollTimer.start(); From f2543de3da8830a966101f43ae2de09f9cabddd8 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 6 Sep 2020 16:32:33 +0900 Subject: [PATCH 4/5] fix CUDPSocket(port) constructor bug constructor CUDPSocket(port) cannot create properly, fixed --- UDPSocket.cpp | 29 +++++++++++++++++++++-------- UDPSocket.h | 2 ++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/UDPSocket.cpp b/UDPSocket.cpp index ccb93a4..382925f 100644 --- a/UDPSocket.cpp +++ b/UDPSocket.cpp @@ -32,7 +32,10 @@ #define LogInfo(fmt, ...) ::fprintf(stderr, fmt "\n", ## __VA_ARGS__) #endif -CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) +CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) : +m_address_save(address), +m_port_save(port), +m_counter(0U) { #if defined(_WIN32) || defined(_WIN64) WSAData data; @@ -46,15 +49,25 @@ CUDPSocket::CUDPSocket(const std::string& address, unsigned int port) m_af[i] = 0U; m_fd[i] = -1; } - - m_address[0] = address; - m_port[0] = port; - m_counter = 0U; } -CUDPSocket::CUDPSocket(unsigned int port) +CUDPSocket::CUDPSocket(unsigned int port) : +m_address_save(), +m_port_save(port), +m_counter(0U) { - CUDPSocket("", port); +#if defined(_WIN32) || defined(_WIN64) + WSAData data; + int wsaRet = ::WSAStartup(MAKEWORD(2, 2), &data); + if (wsaRet != 0) + LogError("Error from WSAStartup"); +#endif + for (int i = 0; i < UDP_SOCKET_MAX; i++) { + m_address[i] = ""; + m_port[i] = 0U; + m_af[i] = 0U; + m_fd[i] = -1; + } } CUDPSocket::~CUDPSocket() @@ -152,7 +165,7 @@ bool CUDPSocket::open(const sockaddr_storage& address) bool CUDPSocket::open(unsigned int af) { - return open(0, af, m_address[0], m_port[0]); + return open(0, af, m_address_save, m_port_save); } bool CUDPSocket::open(const unsigned int index, const unsigned int af, const std::string& address, const unsigned int port) diff --git a/UDPSocket.h b/UDPSocket.h index 4523991..b22eefc 100644 --- a/UDPSocket.h +++ b/UDPSocket.h @@ -68,6 +68,8 @@ public: static bool isNone(const sockaddr_storage& addr); private: + std::string m_address_save; + unsigned short m_port_save; std::string m_address[UDP_SOCKET_MAX]; unsigned short m_port[UDP_SOCKET_MAX]; unsigned int m_af[UDP_SOCKET_MAX]; From 7d3e8991041385f46030c2d6fb9c6448862078cc Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 6 Sep 2020 12:54:08 +0100 Subject: [PATCH 5/5] Clean ups for IPv6. --- DMRNetwork.cpp | 36 +++++++------- DMRNetwork.h | 46 +++++++++--------- DStarNetwork.cpp | 36 ++++++++------ DStarNetwork.h | 30 ++++++------ MMDVMHost.cpp | 7 ++- NXDNIcomNetwork.cpp | 36 ++++++++------ NXDNIcomNetwork.h | 24 +++++----- NXDNKenwoodNetwork.cpp | 63 +++++++++++++++---------- NXDNKenwoodNetwork.h | 103 +++++++++++++++++++++-------------------- P25Network.cpp | 70 +++++++++++++++------------- P25Network.h | 14 +++--- POCSAGNetwork.cpp | 36 ++++++++------ POCSAGNetwork.h | 12 ++--- RemoteCommand.cpp | 15 +++--- Version.h | 2 +- YSFNetwork.cpp | 34 ++++++++------ YSFNetwork.h | 18 +++---- 17 files changed, 323 insertions(+), 259 deletions(-) diff --git a/DMRNetwork.cpp b/DMRNetwork.cpp index 3b98357..01fe954 100644 --- a/DMRNetwork.cpp +++ b/DMRNetwork.cpp @@ -34,8 +34,8 @@ const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U; CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType) : m_addressStr(address), -m_address(), -m_addrlen(), +m_addr(), +m_addrLen(0U), m_port(port), m_id(NULL), m_duplex(duplex), @@ -62,7 +62,8 @@ m_pingTimer(1000U, 10U) assert(port > 0U); assert(id > 1000U); - CUDPSocket::lookup(m_addressStr, m_port, m_address, m_addrlen); + if (CUDPSocket::lookup(m_addressStr, m_port, m_addr, m_addrLen) != 0) + m_addrLen = 0U; m_buffer = new unsigned char[BUFFER_LENGTH]; m_id = new uint8_t[4U]; @@ -100,12 +101,14 @@ void CDMRNetwork::setConfig(const std::string & callsign, unsigned int rxFrequen bool CDMRNetwork::open() { + if (m_addrLen == 0U) { + LogError("Unable to resolve the address of the DMR Gateway"); + return false; + } + LogMessage("DMR, Opening DMR Network"); - if (CUDPSocket::isNone(m_address)) - CUDPSocket::lookup(m_addressStr, m_port, m_address, m_addrlen); - - bool ret = m_socket.open(); + bool ret = m_socket.open(m_addr); if (ret) m_pingTimer.start(); @@ -297,26 +300,25 @@ void CDMRNetwork::clock(unsigned int ms) } sockaddr_storage address; - unsigned int addrlen; - int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrlen); + unsigned int addrLen; + int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrLen); if (length <= 0) return; - if (!CUDPSocket::match(m_address, address)) { + if (!CUDPSocket::match(m_addr, address)) { LogMessage("DMR, packet received from an invalid source"); return; } - if (!m_enabled) - return; - if (m_debug) CUtils::dump(1U, "Network Received", m_buffer, length); if (::memcmp(m_buffer, "DMRD", 4U) == 0) { - unsigned char len = length; - m_rxData.addData(&len, 1U); - m_rxData.addData(m_buffer, len); + if (m_enabled) { + unsigned char len = length; + m_rxData.addData(&len, 1U); + m_rxData.addData(m_buffer, len); + } } else if (::memcmp(m_buffer, "DMRP", 4U) == 0) { ; } else if (::memcmp(m_buffer, "DMRB", 4U) == 0) { @@ -427,7 +429,7 @@ bool CDMRNetwork::write(const unsigned char* data, unsigned int length) if (m_debug) CUtils::dump(1U, "Network Transmitted", data, length); - bool ret = m_socket.write(data, length, m_address, m_addrlen); + bool ret = m_socket.write(data, length, m_addr, m_addrLen); if (!ret) { LogError("DMR, socket error when writing to the DMR Gateway"); return false; diff --git a/DMRNetwork.h b/DMRNetwork.h index 0f1368a..1ddccb6 100644 --- a/DMRNetwork.h +++ b/DMRNetwork.h @@ -56,30 +56,30 @@ public: void close(); private: - std::string m_addressStr; - sockaddr_storage m_address; - unsigned int m_addrlen; - unsigned int m_port; - uint8_t* m_id; - bool m_duplex; - const char* m_version; - bool m_debug; - CUDPSocket m_socket; - bool m_enabled; - bool m_slot1; - bool m_slot2; - HW_TYPE m_hwType; - unsigned char* m_buffer; - uint32_t* m_streamId; + std::string m_addressStr; + sockaddr_storage m_addr; + unsigned int m_addrLen; + unsigned int m_port; + uint8_t* m_id; + bool m_duplex; + const char* m_version; + bool m_debug; + CUDPSocket m_socket; + bool m_enabled; + bool m_slot1; + bool m_slot2; + HW_TYPE m_hwType; + unsigned char* m_buffer; + uint32_t* m_streamId; CRingBuffer m_rxData; - bool m_beacon; - std::mt19937 m_random; - std::string m_callsign; - unsigned int m_rxFrequency; - unsigned int m_txFrequency; - unsigned int m_power; - unsigned int m_colorCode; - CTimer m_pingTimer; + bool m_beacon; + std::mt19937 m_random; + std::string m_callsign; + unsigned int m_rxFrequency; + unsigned int m_txFrequency; + unsigned int m_power; + unsigned int m_colorCode; + CTimer m_pingTimer; bool writeConfig(); diff --git a/DStarNetwork.cpp b/DStarNetwork.cpp index b499853..21bbc9d 100644 --- a/DStarNetwork.cpp +++ b/DStarNetwork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016,2019 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2014,2016,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 @@ -32,8 +32,8 @@ const unsigned int BUFFER_LENGTH = 100U; CDStarNetwork::CDStarNetwork(const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int localPort, bool duplex, const char* version, bool debug) : m_socket(localPort), -m_address(), -m_addrlen(), +m_addr(), +m_addrLen(0U), m_duplex(duplex), m_version(version), m_debug(debug), @@ -47,7 +47,8 @@ m_linkStatus(LS_NONE), m_linkReflector(NULL), m_random() { - CUDPSocket::lookup(gatewayAddress, gatewayPort, m_address, m_addrlen); + if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0) + m_addrLen = 0U; m_linkReflector = new unsigned char[DSTAR_LONG_CALLSIGN_LENGTH]; @@ -63,14 +64,16 @@ CDStarNetwork::~CDStarNetwork() bool CDStarNetwork::open() { - LogMessage("Opening D-Star network connection"); - - if (CUDPSocket::isNone(m_address)) + if (m_addrLen == 0U) { + LogError("Unable to resolve the address of the ircDDB Gateway"); return false; + } + + LogMessage("Opening D-Star network connection"); m_pollTimer.start(); - return m_socket.open(m_address.ss_family); + return m_socket.open(m_addr); } bool CDStarNetwork::writeHeader(const unsigned char* header, unsigned int length, bool busy) @@ -103,7 +106,7 @@ bool CDStarNetwork::writeHeader(const unsigned char* header, unsigned int length CUtils::dump(1U, "D-Star Network Header Sent", buffer, 49U); for (unsigned int i = 0U; i < 2U; i++) { - bool ret = m_socket.write(buffer, 49U, m_address, m_addrlen); + bool ret = m_socket.write(buffer, 49U, m_addr, m_addrLen); if (!ret) return false; } @@ -146,7 +149,7 @@ bool CDStarNetwork::writeData(const unsigned char* data, unsigned int length, un if (m_debug) CUtils::dump(1U, "D-Star Network Data Sent", buffer, length + 9U); - return m_socket.write(buffer, length + 9U, m_address, m_addrlen); + return m_socket.write(buffer, length + 9U, m_addr, m_addrLen); } bool CDStarNetwork::writePoll(const char* text) @@ -170,7 +173,7 @@ bool CDStarNetwork::writePoll(const char* text) // if (m_debug) // CUtils::dump(1U, "D-Star Network Poll Sent", buffer, 6U + length); - return m_socket.write(buffer, 6U + length, m_address, m_addrlen); + return m_socket.write(buffer, 6U + length, m_addr, m_addrLen); } void CDStarNetwork::clock(unsigned int ms) @@ -196,11 +199,16 @@ void CDStarNetwork::clock(unsigned int ms) unsigned char buffer[BUFFER_LENGTH]; sockaddr_storage address; - unsigned int addrlen; - int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match(m_address, address)) + unsigned int addrLen; + int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen); + if (length <= 0) return; + if (!CUDPSocket::match(m_addr, address)) { + LogMessage("D-Star, packet received from an invalid source"); + return; + } + // Invalid packet type? if (::memcmp(buffer, "DSRP", 4U) != 0) return; diff --git a/DStarNetwork.h b/DStarNetwork.h index fc1fd68..1e0d5f0 100644 --- a/DStarNetwork.h +++ b/DStarNetwork.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2014,2016,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 @@ -51,21 +51,21 @@ public: void clock(unsigned int ms); private: - CUDPSocket m_socket; - sockaddr_storage m_address; - unsigned int m_addrlen; - bool m_duplex; - const char* m_version; - bool m_debug; - bool m_enabled; - uint16_t m_outId; - uint8_t m_outSeq; - uint16_t m_inId; + CUDPSocket m_socket; + sockaddr_storage m_addr; + unsigned int m_addrLen; + bool m_duplex; + const char* m_version; + bool m_debug; + bool m_enabled; + uint16_t m_outId; + uint8_t m_outSeq; + uint16_t m_inId; CRingBuffer m_buffer; - CTimer m_pollTimer; - LINK_STATUS m_linkStatus; - unsigned char* m_linkReflector; - std::mt19937 m_random; + CTimer m_pollTimer; + LINK_STATUS m_linkStatus; + unsigned char* m_linkReflector; + std::mt19937 m_random; bool writePoll(const char* text); }; diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index ab76284..1061e7e 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -338,10 +338,13 @@ int CMMDVMHost::run() LogInfo(" Local Port: %u", localPort); LogInfo(" Send Frame Type: %u", sendFrameType); - CUDPSocket::lookup(remoteAddress, remotePort, transparentAddress, transparentAddrLen); + if (CUDPSocket::lookup(remoteAddress, remotePort, transparentAddress, transparentAddrLen) != 0) { + LogError("Unable to resolve the address of the Transparent Data source"); + return 1; + } transparentSocket = new CUDPSocket(localPort); - ret = transparentSocket->open(transparentAddress.ss_family); + ret = transparentSocket->open(transparentAddress); if (!ret) { LogWarning("Could not open the Transparent data socket, disabling"); delete transparentSocket; diff --git a/NXDNIcomNetwork.cpp b/NXDNIcomNetwork.cpp index c118be6..b13ca2a 100644 --- a/NXDNIcomNetwork.cpp +++ b/NXDNIcomNetwork.cpp @@ -30,8 +30,8 @@ const unsigned int BUFFER_LENGTH = 200U; CNXDNIcomNetwork::CNXDNIcomNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug) : m_socket(localAddress, localPort), -m_address(), -m_addrlen(), +m_addr(), +m_addrLen(0U), m_debug(debug), m_enabled(false), m_buffer(1000U, "NXDN Network") @@ -39,7 +39,8 @@ m_buffer(1000U, "NXDN Network") assert(gatewayPort > 0U); assert(!gatewayAddress.empty()); - CUDPSocket::lookup(gatewayAddress, gatewayPort, m_address, m_addrlen); + if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0) + m_addrLen = 0U; } CNXDNIcomNetwork::~CNXDNIcomNetwork() @@ -48,12 +49,14 @@ CNXDNIcomNetwork::~CNXDNIcomNetwork() bool CNXDNIcomNetwork::open() { + if (m_addrLen == 0U) { + LogError("Unable to resolve the address of the NXDN Gateway"); + return false; + } + LogMessage("Opening NXDN network connection"); - if (CUDPSocket::isNone(m_address)) - return false; - - return m_socket.open(); + return m_socket.open(m_addr); } bool CNXDNIcomNetwork::write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type) @@ -100,7 +103,7 @@ bool CNXDNIcomNetwork::write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYP if (m_debug) CUtils::dump(1U, "NXDN Network Data Sent", buffer, 102U); - return m_socket.write(buffer, 102U, m_address, m_addrlen); + return m_socket.write(buffer, 102U, m_addr, m_addrLen); } void CNXDNIcomNetwork::clock(unsigned int ms) @@ -108,11 +111,19 @@ void CNXDNIcomNetwork::clock(unsigned int ms) unsigned char buffer[BUFFER_LENGTH]; sockaddr_storage address; - unsigned int addrlen; - int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match(m_address, address)) + unsigned int addrLen; + int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen); + if (length <= 0) return; + if (!CUDPSocket::match(m_addr, address)) { + LogMessage("NXDN, packet received from an invalid source"); + return; + } + + if (m_debug) + CUtils::dump(1U, "NXDN Network Data Received", buffer, length); + // Invalid packet type? if (::memcmp(buffer, "ICOM", 4U) != 0) return; @@ -123,9 +134,6 @@ void CNXDNIcomNetwork::clock(unsigned int ms) if (!m_enabled) return; - if (m_debug) - CUtils::dump(1U, "NXDN Network Data Received", buffer, length); - m_buffer.addData(buffer + 40U, 33U); } diff --git a/NXDNIcomNetwork.h b/NXDNIcomNetwork.h index 18bdd97..3113a9f 100644 --- a/NXDNIcomNetwork.h +++ b/NXDNIcomNetwork.h @@ -33,26 +33,26 @@ public: CNXDNIcomNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug); virtual ~CNXDNIcomNetwork(); - virtual bool open(); + virtual bool open(); - virtual void enable(bool enabled); + virtual void enable(bool enabled); - virtual bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type); + virtual bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type); - virtual bool read(unsigned char* data); + virtual bool read(unsigned char* data); - virtual void reset(); + virtual void reset(); - virtual void close(); + virtual void close(); - virtual void clock(unsigned int ms); + virtual void clock(unsigned int ms); private: - CUDPSocket m_socket; - sockaddr_storage m_address; - unsigned int m_addrlen; - bool m_debug; - bool m_enabled; + CUDPSocket m_socket; + sockaddr_storage m_addr; + unsigned int m_addrLen; + bool m_debug; + bool m_enabled; CRingBuffer m_buffer; }; diff --git a/NXDNKenwoodNetwork.cpp b/NXDNKenwoodNetwork.cpp index 22165dd..67de39b 100644 --- a/NXDNKenwoodNetwork.cpp +++ b/NXDNKenwoodNetwork.cpp @@ -36,9 +36,10 @@ const unsigned int BUFFER_LENGTH = 200U; CNXDNKenwoodNetwork::CNXDNKenwoodNetwork(const std::string& localAddress, unsigned int localPort, const std::string& gwyAddress, unsigned int gwyPort, bool debug) : m_rtpSocket(localAddress, localPort + 0U), m_rtcpSocket(localAddress, localPort + 1U), -m_rtcpaddress(), -m_rtpaddress(), -m_addrlen(), +m_rtcpAddr(), +m_rtpAddr(), +m_rtcpAddrLen(0U), +m_rtpAddrLen(0U), m_enabled(false), m_headerSeen(false), m_seen1(false), @@ -65,8 +66,11 @@ m_random() m_sacch = new unsigned char[10U]; - CUDPSocket::lookup(gwyAddress, gwyPort + 1, m_rtcpaddress, m_addrlen); - CUDPSocket::lookup(gwyAddress, gwyPort, m_rtpaddress, m_addrlen); + if (CUDPSocket::lookup(gwyAddress, gwyPort + 1U, m_rtcpAddr, m_rtcpAddrLen) != 0) + m_rtcpAddrLen = 0U; + + if (CUDPSocket::lookup(gwyAddress, gwyPort + 0U, m_rtpAddr, m_rtpAddrLen) != 0) + m_rtpAddrLen = 0U; std::random_device rd; std::mt19937 mt(rd()); @@ -80,16 +84,17 @@ CNXDNKenwoodNetwork::~CNXDNKenwoodNetwork() bool CNXDNKenwoodNetwork::open() { + if (m_rtcpAddrLen == 0U || m_rtpAddrLen == 0U) { + LogError("Unable to resolve the address of the NXDN Gateway"); + return false; + } + LogMessage("Opening Kenwood connection"); - if (CUDPSocket::isNone(m_rtpaddress) || - CUDPSocket::isNone(m_rtcpaddress)) + if (!m_rtcpSocket.open(m_rtcpAddr)) return false; - if (!m_rtcpSocket.open()) - return false; - - if (!m_rtpSocket.open()) { + if (!m_rtpSocket.open(m_rtpAddr)) { m_rtcpSocket.close(); return false; } @@ -365,7 +370,7 @@ bool CNXDNKenwoodNetwork::writeRTPVoiceHeader(const unsigned char* data) if (m_debug) CUtils::dump(1U, "Kenwood Network RTP Data Sent", buffer, 47U); - return m_rtpSocket.write(buffer, 47U, m_rtpaddress, m_addrlen); + return m_rtpSocket.write(buffer, 47U, m_rtpAddr, m_rtpAddrLen); } bool CNXDNKenwoodNetwork::writeRTPVoiceTrailer(const unsigned char* data) @@ -411,7 +416,7 @@ bool CNXDNKenwoodNetwork::writeRTPVoiceTrailer(const unsigned char* data) if (m_debug) CUtils::dump(1U, "Kenwood Network RTP Data Sent", buffer, 47U); - return m_rtpSocket.write(buffer, 47U, m_rtpaddress, m_addrlen); + return m_rtpSocket.write(buffer, 47U, m_rtpAddr, m_rtpAddrLen); } bool CNXDNKenwoodNetwork::writeRTPVoiceData(const unsigned char* data) @@ -457,7 +462,7 @@ bool CNXDNKenwoodNetwork::writeRTPVoiceData(const unsigned char* data) if (m_debug) CUtils::dump(1U, "Kenwood Network RTP Data Sent", buffer, 59U); - return m_rtpSocket.write(buffer, 59U, m_rtpaddress, m_addrlen); + return m_rtpSocket.write(buffer, 59U, m_rtpAddr, m_rtpAddrLen); } bool CNXDNKenwoodNetwork::writeRTPDataHeader(const unsigned char* data) @@ -499,7 +504,7 @@ bool CNXDNKenwoodNetwork::writeRTPDataHeader(const unsigned char* data) if (m_debug) CUtils::dump(1U, "Kenwood Network RTP Data Sent", buffer, 42U); - return m_rtpSocket.write(buffer, 42U, m_rtpaddress, m_addrlen); + return m_rtpSocket.write(buffer, 42U, m_rtpAddr, m_rtpAddrLen); } bool CNXDNKenwoodNetwork::writeRTPDataTrailer(const unsigned char* data) @@ -541,7 +546,7 @@ bool CNXDNKenwoodNetwork::writeRTPDataTrailer(const unsigned char* data) if (m_debug) CUtils::dump(1U, "Kenwood Network RTP Data Sent", buffer, 42U); - return m_rtpSocket.write(buffer, 42U, m_rtpaddress, m_addrlen); + return m_rtpSocket.write(buffer, 42U, m_rtpAddr, m_rtpAddrLen); } bool CNXDNKenwoodNetwork::writeRTPDataData(const unsigned char* data) @@ -583,7 +588,7 @@ bool CNXDNKenwoodNetwork::writeRTPDataData(const unsigned char* data) if (m_debug) CUtils::dump(1U, "Kenwood Network RTP Data Sent", buffer, 42U); - return m_rtpSocket.write(buffer, 42U, m_rtpaddress, m_addrlen); + return m_rtpSocket.write(buffer, 42U, m_rtpAddr, m_rtpAddrLen); } bool CNXDNKenwoodNetwork::writeRTCPStart() @@ -643,7 +648,7 @@ bool CNXDNKenwoodNetwork::writeRTCPStart() if (m_debug) CUtils::dump(1U, "Kenwood Network RTCP Data Sent", buffer, 28U); - return m_rtcpSocket.write(buffer, 28U, m_rtcpaddress, m_addrlen); + return m_rtcpSocket.write(buffer, 28U, m_rtcpAddr, m_rtcpAddrLen); } bool CNXDNKenwoodNetwork::writeRTCPPing() @@ -685,7 +690,7 @@ bool CNXDNKenwoodNetwork::writeRTCPPing() if (m_debug) CUtils::dump(1U, "Kenwood Network RTCP Data Sent", buffer, 28U); - return m_rtcpSocket.write(buffer, 28U, m_rtcpaddress, m_addrlen); + return m_rtcpSocket.write(buffer, 28U, m_rtcpAddr, m_rtcpAddrLen); } bool CNXDNKenwoodNetwork::writeRTCPHang(unsigned char type, unsigned short src, unsigned short dst) @@ -728,7 +733,7 @@ bool CNXDNKenwoodNetwork::writeRTCPHang() if (m_debug) CUtils::dump(1U, "Kenwood Network RTCP Data Sent", buffer, 20U); - return m_rtcpSocket.write(buffer, 20U, m_rtcpaddress, m_addrlen); + return m_rtcpSocket.write(buffer, 20U, m_rtcpAddr, m_rtcpAddrLen); } bool CNXDNKenwoodNetwork::read(unsigned char* data) @@ -764,11 +769,16 @@ unsigned int CNXDNKenwoodNetwork::readRTP(unsigned char* data) unsigned char buffer[BUFFER_LENGTH]; sockaddr_storage address; - unsigned int addrlen; - int length = m_rtpSocket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match(m_rtpaddress, address, IMT_ADDRESS_ONLY)) + unsigned int addrLen; + int length = m_rtpSocket.read(buffer, BUFFER_LENGTH, address, addrLen); + if (length <= 0) return 0U; + if (!CUDPSocket::match(m_rtpAddr, address, IMT_ADDRESS_ONLY)) { + LogMessage("NXDN, RTP packet received from an invalid source"); + return 0U; + } + if (!m_enabled) return 0U; @@ -789,9 +799,14 @@ unsigned int CNXDNKenwoodNetwork::readRTCP(unsigned char* data) sockaddr_storage address; unsigned int addrlen; int length = m_rtcpSocket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match(m_rtcpaddress, address, IMT_ADDRESS_ONLY)) + if (length <= 0) return 0U; + if (!CUDPSocket::match(m_rtpAddr, address, IMT_ADDRESS_ONLY)) { + LogMessage("NXDN, RTCP packet received from an invalid source"); + return 0U; + } + if (!m_enabled) return 0U; diff --git a/NXDNKenwoodNetwork.h b/NXDNKenwoodNetwork.h index 3466569..af28618 100644 --- a/NXDNKenwoodNetwork.h +++ b/NXDNKenwoodNetwork.h @@ -34,66 +34,67 @@ public: virtual bool open(); - virtual void enable(bool enabled); + virtual void enable(bool enabled); - virtual bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type); + virtual bool write(const unsigned char* data, NXDN_NETWORK_MESSAGE_TYPE type); virtual bool read(unsigned char* data); - virtual void reset(); + virtual void reset(); - virtual void close(); + virtual void close(); - virtual void clock(unsigned int ms); + virtual void clock(unsigned int ms); private: - CUDPSocket m_rtpSocket; - CUDPSocket m_rtcpSocket; - sockaddr_storage m_rtcpaddress; - sockaddr_storage m_rtpaddress; - unsigned int m_addrlen; - bool m_enabled; - bool m_headerSeen; - bool m_seen1; - bool m_seen2; - bool m_seen3; - bool m_seen4; - unsigned char* m_sacch; - uint8_t m_sessionId; - uint16_t m_seqNo; - unsigned int m_ssrc; - bool m_debug; - uint32_t m_startSecs; - uint32_t m_startUSecs; - CTimer m_rtcpTimer; - CTimer m_hangTimer; - unsigned char m_hangType; - unsigned short m_hangSrc; - unsigned short m_hangDst; - std::mt19937 m_random; + CUDPSocket m_rtpSocket; + CUDPSocket m_rtcpSocket; + sockaddr_storage m_rtcpAddr; + sockaddr_storage m_rtpAddr; + unsigned int m_rtcpAddrLen; + unsigned int m_rtpAddrLen; + bool m_enabled; + bool m_headerSeen; + bool m_seen1; + bool m_seen2; + bool m_seen3; + bool m_seen4; + unsigned char* m_sacch; + uint8_t m_sessionId; + uint16_t m_seqNo; + unsigned int m_ssrc; + bool m_debug; + uint32_t m_startSecs; + uint32_t m_startUSecs; + CTimer m_rtcpTimer; + CTimer m_hangTimer; + unsigned char m_hangType; + unsigned short m_hangSrc; + unsigned short m_hangDst; + std::mt19937 m_random; - bool processIcomVoiceHeader(const unsigned char* data); - bool processIcomVoiceData(const unsigned char* data); - bool processIcomDataHeader(const unsigned char* data); - bool processIcomDataData(const unsigned char* data); - bool processIcomDataTrailer(const unsigned char* data); - bool processKenwoodVoiceHeader(unsigned char* data); - bool processKenwoodVoiceData(unsigned char* data); - bool processKenwoodVoiceLateEntry(unsigned char* data); - bool processKenwoodData(unsigned char* data); - bool writeRTPVoiceHeader(const unsigned char* data); - bool writeRTPVoiceData(const unsigned char* data); - bool writeRTPVoiceTrailer(const unsigned char* data); - bool writeRTPDataHeader(const unsigned char* data); - bool writeRTPDataData(const unsigned char* data); - bool writeRTPDataTrailer(const unsigned char* data); - bool writeRTCPStart(); - bool writeRTCPPing(); - bool writeRTCPHang(unsigned char type, unsigned short src, unsigned short dst); - bool writeRTCPHang(); - unsigned int readRTP(unsigned char* data); - unsigned int readRTCP(unsigned char* data); - unsigned long getTimeStamp() const; + bool processIcomVoiceHeader(const unsigned char* data); + bool processIcomVoiceData(const unsigned char* data); + bool processIcomDataHeader(const unsigned char* data); + bool processIcomDataData(const unsigned char* data); + bool processIcomDataTrailer(const unsigned char* data); + bool processKenwoodVoiceHeader(unsigned char* data); + bool processKenwoodVoiceData(unsigned char* data); + bool processKenwoodVoiceLateEntry(unsigned char* data); + bool processKenwoodData(unsigned char* data); + bool writeRTPVoiceHeader(const unsigned char* data); + bool writeRTPVoiceData(const unsigned char* data); + bool writeRTPVoiceTrailer(const unsigned char* data); + bool writeRTPDataHeader(const unsigned char* data); + bool writeRTPDataData(const unsigned char* data); + bool writeRTPDataTrailer(const unsigned char* data); + bool writeRTCPStart(); + bool writeRTCPPing(); + bool writeRTCPHang(unsigned char type, unsigned short src, unsigned short dst); + bool writeRTCPHang(); + unsigned int readRTP(unsigned char* data); + unsigned int readRTCP(unsigned char* data); + unsigned long getTimeStamp() const; }; #endif diff --git a/P25Network.cpp b/P25Network.cpp index 8485d2f..3bb39b9 100644 --- a/P25Network.cpp +++ b/P25Network.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016,2019 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2014,2016,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 @@ -89,14 +89,15 @@ const unsigned int BUFFER_LENGTH = 100U; CP25Network::CP25Network(const std::string& gatewayAddress, unsigned int gatewayPort, unsigned int localPort, bool debug) : m_socket(localPort), -m_address(), -m_addrlen(), +m_addr(), +m_addrLen(0U), m_debug(debug), m_enabled(false), m_buffer(1000U, "P25 Network"), m_audio() { - CUDPSocket::lookup(gatewayAddress, gatewayPort, m_address, m_addrlen); + if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0) + m_addrLen = 0U; } CP25Network::~CP25Network() @@ -105,12 +106,14 @@ CP25Network::~CP25Network() bool CP25Network::open() { + if (m_addrLen == 0U) { + LogError("Unable to resolve the address of the P25 Gateway"); + return false; + } + LogMessage("Opening P25 network connection"); - if (CUDPSocket::isNone(m_address)) - return false; - - return m_socket.open(m_address.ss_family); + return m_socket.open(m_addr); } bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, const CP25LowSpeedData& lsd, bool end) @@ -126,7 +129,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 22U); - bool ret = m_socket.write(buffer, 22U, m_address, m_addrlen); + bool ret = m_socket.write(buffer, 22U, m_addr, m_addrLen); if (!ret) return false; @@ -137,7 +140,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 14U); - ret = m_socket.write(buffer, 14U, m_address, m_addrlen); + ret = m_socket.write(buffer, 14U, m_addr, m_addrLen); if (!ret) return false; @@ -150,7 +153,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -165,7 +168,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -180,7 +183,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -191,7 +194,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -202,7 +205,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -213,7 +216,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -226,7 +229,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU1 Sent", buffer, 16U); - ret = m_socket.write(buffer, 16U, m_address, m_addrlen); + ret = m_socket.write(buffer, 16U, m_addr, m_addrLen); if (!ret) return false; @@ -234,7 +237,7 @@ bool CP25Network::writeLDU1(const unsigned char* ldu1, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network END Sent", REC80, 17U); - ret = m_socket.write(REC80, 17U, m_address, m_addrlen); + ret = m_socket.write(REC80, 17U, m_addr, m_addrLen); if (!ret) return false; } @@ -255,7 +258,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 22U); - bool ret = m_socket.write(buffer, 22U, m_address, m_addrlen); + bool ret = m_socket.write(buffer, 22U, m_addr, m_addrLen); if (!ret) return false; @@ -266,7 +269,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 14U); - ret = m_socket.write(buffer, 14U, m_address, m_addrlen); + ret = m_socket.write(buffer, 14U, m_addr, m_addrLen); if (!ret) return false; @@ -283,7 +286,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -297,7 +300,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -311,7 +314,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -326,7 +329,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -337,7 +340,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -348,7 +351,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 17U); - ret = m_socket.write(buffer, 17U, m_address, m_addrlen); + ret = m_socket.write(buffer, 17U, m_addr, m_addrLen); if (!ret) return false; @@ -361,7 +364,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network LDU2 Sent", buffer, 16U); - ret = m_socket.write(buffer, 16U, m_address, m_addrlen); + ret = m_socket.write(buffer, 16U, m_addr, m_addrLen); if (!ret) return false; @@ -369,7 +372,7 @@ bool CP25Network::writeLDU2(const unsigned char* ldu2, const CP25Data& control, if (m_debug) CUtils::dump(1U, "P25 Network END Sent", REC80, 17U); - ret = m_socket.write(REC80, 17U, m_address, m_addrlen); + ret = m_socket.write(REC80, 17U, m_addr, m_addrLen); if (!ret) return false; } @@ -382,11 +385,16 @@ void CP25Network::clock(unsigned int ms) unsigned char buffer[BUFFER_LENGTH]; sockaddr_storage address; - unsigned int addrlen; - int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match(m_address, address)) + unsigned int addrLen; + int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen); + if (length <= 0) return; + if (!CUDPSocket::match(m_addr, address)) { + LogMessage("P25, packet received from an invalid source"); + return; + } + if (!m_enabled) return; diff --git a/P25Network.h b/P25Network.h index 009c994..4c52761 100644 --- a/P25Network.h +++ b/P25Network.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2014,2016,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 @@ -48,13 +48,13 @@ public: void clock(unsigned int ms); private: - CUDPSocket m_socket; - sockaddr_storage m_address; - unsigned int m_addrlen; - bool m_debug; - bool m_enabled; + CUDPSocket m_socket; + sockaddr_storage m_addr; + unsigned int m_addrLen; + bool m_debug; + bool m_enabled; CRingBuffer m_buffer; - CP25Audio m_audio; + CP25Audio m_audio; }; #endif diff --git a/POCSAGNetwork.cpp b/POCSAGNetwork.cpp index e8e0d65..c0437bd 100644 --- a/POCSAGNetwork.cpp +++ b/POCSAGNetwork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018,2019 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -30,13 +30,14 @@ const unsigned int BUFFER_LENGTH = 200U; CPOCSAGNetwork::CPOCSAGNetwork(const std::string& myAddress, unsigned int myPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug) : m_socket(myAddress, myPort), -m_address(), -m_addrlen(), +m_addr(), +m_addrLen(0U), m_debug(debug), m_enabled(false), m_buffer(1000U, "POCSAG Network") { - CUDPSocket::lookup(gatewayAddress, gatewayPort, m_address, m_addrlen); + if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0) + m_addrLen = 0U; } CPOCSAGNetwork::~CPOCSAGNetwork() @@ -45,10 +46,12 @@ CPOCSAGNetwork::~CPOCSAGNetwork() bool CPOCSAGNetwork::open() { - LogMessage("Opening POCSAG network connection"); - - if (CUDPSocket::isNone(m_address)) + if (m_addrLen == 0U) { + LogError("Unable to resolve the address of the DAPNET Gateway"); return false; + } + + LogMessage("Opening POCSAG network connection"); return m_socket.open(); } @@ -58,11 +61,19 @@ void CPOCSAGNetwork::clock(unsigned int ms) unsigned char buffer[BUFFER_LENGTH]; sockaddr_storage address; - unsigned int addrlen; - int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match(m_address, address)) + unsigned int addrLen; + int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen); + if (length <= 0) return; + if (!CUDPSocket::match(m_addr, address)) { + LogMessage("POCSAG, packet received from an invalid source"); + return; + } + + if (m_debug) + CUtils::dump(1U, "POCSAG Network Data Received", buffer, length); + // Invalid packet type? if (::memcmp(buffer, "POCSAG", 6U) != 0) return; @@ -70,9 +81,6 @@ void CPOCSAGNetwork::clock(unsigned int ms) if (!m_enabled) return; - if (m_debug) - CUtils::dump(1U, "POCSAG Network Data Received", buffer, length); - unsigned char len = length - 6U; m_buffer.addData(&len, 1U); m_buffer.addData(buffer + 6U, length - 6U); @@ -112,7 +120,7 @@ void CPOCSAGNetwork::enable(bool enabled) unsigned char c = enabled ? 0x00U : 0xFFU; - m_socket.write(&c, 1U, m_address, m_addrlen); + m_socket.write(&c, 1U, m_addr, m_addrLen); m_enabled = enabled; } diff --git a/POCSAGNetwork.h b/POCSAGNetwork.h index dd3945b..693f5ac 100644 --- a/POCSAGNetwork.h +++ b/POCSAGNetwork.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -45,11 +45,11 @@ public: void clock(unsigned int ms); private: - CUDPSocket m_socket; - sockaddr_storage m_address; - unsigned int m_addrlen; - bool m_debug; - bool m_enabled; + CUDPSocket m_socket; + sockaddr_storage m_addr; + unsigned int m_addrLen; + bool m_debug; + bool m_enabled; CRingBuffer m_buffer; }; diff --git a/RemoteCommand.cpp b/RemoteCommand.cpp index 25b07fd..addc0c6 100644 --- a/RemoteCommand.cpp +++ b/RemoteCommand.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 by Jonathan Naylor G4KLX + * Copyright (C) 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 @@ -61,17 +61,20 @@ CRemoteCommand::~CRemoteCommand() int CRemoteCommand::send(const std::string& command) { - sockaddr_storage address; - unsigned int addrlen; - CUDPSocket::lookup("127.0.0.1", m_port, address, addrlen); + sockaddr_storage addr; + unsigned int addrLen; + if (CUDPSocket::lookup("127.0.0.1", m_port, addr, addrLen) != 0) { + LogError("Unable to resolve the address of the host"); + return 1; + } CUDPSocket socket(0U); - bool ret = socket.open(address.ss_family); + bool ret = socket.open(addr); if (!ret) return 1; - ret = socket.write((unsigned char*)command.c_str(), command.length(), address, addrlen); + ret = socket.write((unsigned char*)command.c_str(), command.length(), addr, addrLen); if (!ret) { socket.close(); return 1; diff --git a/Version.h b/Version.h index 23ae81e..a988871 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200830"; +const char* VERSION = "20200906"; #endif diff --git a/YSFNetwork.cpp b/YSFNetwork.cpp index 7ddc996..099a550 100644 --- a/YSFNetwork.cpp +++ b/YSFNetwork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016,2019 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2014,2016,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 @@ -30,8 +30,8 @@ const unsigned int BUFFER_LENGTH = 200U; CYSFNetwork::CYSFNetwork(const std::string& myAddress, unsigned int myPort, const std::string& gatewayAddress, unsigned int gatewayPort, const std::string& callsign, bool debug) : m_socket(myAddress, myPort), -m_address(), -m_addrlen(), +m_addr(), +m_addrLen(0U), m_callsign(), m_debug(debug), m_enabled(false), @@ -42,7 +42,8 @@ m_tag(NULL) m_callsign = callsign; m_callsign.resize(YSF_CALLSIGN_LENGTH, ' '); - CUDPSocket::lookup(gatewayAddress, gatewayPort, m_address, m_addrlen); + if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0) + m_addrLen = 0U; m_tag = new unsigned char[YSF_CALLSIGN_LENGTH]; ::memset(m_tag, ' ', YSF_CALLSIGN_LENGTH); @@ -55,14 +56,16 @@ CYSFNetwork::~CYSFNetwork() bool CYSFNetwork::open() { - LogMessage("Opening YSF network connection"); - - if (CUDPSocket::isNone(m_address)) + if (m_addrLen == 0U) { + LogError("Unable to resolve the address of the YSF Gateway"); return false; + } + + LogMessage("Opening YSF network connection"); m_pollTimer.start(); - return m_socket.open(); + return m_socket.open(m_addr); } bool CYSFNetwork::write(const unsigned char* src, const unsigned char* dest, const unsigned char* data, unsigned int count, bool end) @@ -97,7 +100,7 @@ bool CYSFNetwork::write(const unsigned char* src, const unsigned char* dest, con if (m_debug) CUtils::dump(1U, "YSF Network Data Sent", buffer, 155U); - return m_socket.write(buffer, 155U, m_address, m_addrlen); + return m_socket.write(buffer, 155U, m_addr, m_addrLen); } bool CYSFNetwork::writePoll() @@ -115,7 +118,7 @@ bool CYSFNetwork::writePoll() if (m_debug) CUtils::dump(1U, "YSF Network Poll Sent", buffer, 14U); - return m_socket.write(buffer, 14U, m_address, m_addrlen); + return m_socket.write(buffer, 14U, m_addr, m_addrLen); } void CYSFNetwork::clock(unsigned int ms) @@ -129,11 +132,16 @@ void CYSFNetwork::clock(unsigned int ms) unsigned char buffer[BUFFER_LENGTH]; sockaddr_storage address; - unsigned int addrlen; - int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrlen); - if (length <= 0 || !CUDPSocket::match(m_address, address)) + unsigned int addrLen; + int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen); + if (length <= 0) return; + if (!CUDPSocket::match(m_addr, address)) { + LogMessage("YSF, packet received from an invalid source"); + return; + } + // Ignore incoming polls if (::memcmp(buffer, "YSFP", 4U) == 0) return; diff --git a/YSFNetwork.h b/YSFNetwork.h index 292364d..aef43d3 100644 --- a/YSFNetwork.h +++ b/YSFNetwork.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014,2016 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2014,2016,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 @@ -47,15 +47,15 @@ public: void clock(unsigned int ms); private: - CUDPSocket m_socket; - sockaddr_storage m_address; - unsigned int m_addrlen; - std::string m_callsign; - bool m_debug; - bool m_enabled; + CUDPSocket m_socket; + sockaddr_storage m_addr; + unsigned int m_addrLen; + std::string m_callsign; + bool m_debug; + bool m_enabled; CRingBuffer m_buffer; - CTimer m_pollTimer; - unsigned char* m_tag; + CTimer m_pollTimer; + unsigned char* m_tag; bool writePoll(); };