diff --git a/src/ccodecstream.cpp b/src/ccodecstream.cpp
index 7d8e0c8..2a6e1dc 100644
--- a/src/ccodecstream.cpp
+++ b/src/ccodecstream.cpp
@@ -61,7 +61,7 @@ CCodecStream::~CCodecStream()
{
// close socket
m_Socket.Close();
-
+
// kill threads
m_bStopThread = true;
if ( m_pThread != NULL )
@@ -69,7 +69,7 @@ CCodecStream::~CCodecStream()
m_pThread->join();
delete m_pThread;
}
-
+
// empty local queue
while ( !m_LocalQueue.empty() )
{
@@ -90,14 +90,14 @@ CCodecStream::~CCodecStream()
bool CCodecStream::Init(uint16 uiPort)
{
bool ok;
-
+
// reset stop flag
m_bStopThread = false;
-
+
// create server's IP
m_Ip = g_Reflector.GetTranscoderIp();
m_uiPort = uiPort;
-
+
// create our socket
ok = m_Socket.Open(uiPort);
if ( ok )
@@ -111,7 +111,7 @@ bool CCodecStream::Init(uint16 uiPort)
std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << g_Reflector.GetListenIp() << std::endl;
m_bConnected = false;
}
-
+
// done
return ok;
}
@@ -121,7 +121,7 @@ void CCodecStream::Close(void)
// close socket
m_bConnected = false;
m_Socket.Close();
-
+
// kill threads
m_bStopThread = true;
if ( m_pThread != NULL )
@@ -157,33 +157,33 @@ void CCodecStream::Task(void)
CIp Ip;
uint8 Ambe[AMBE_SIZE];
uint8 DStarSync[] = { 0x55,0x2D,0x16 };
-
+
// any packet from transcoder
- if ( m_Socket.Receive(&Buffer, &Ip, 5) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 5) )
{
// crack
if ( IsValidAmbePacket(Buffer, Ambe) )
{
// tickle
m_TimeoutTimer.Now();
-
+
// update statistics
double ping = m_StatsTimer.DurationSinceNow();
if ( m_fPingMin == -1 )
{
m_fPingMin = ping;
m_fPingMax = ping;
-
+
}
else
{
m_fPingMin = MIN(m_fPingMin, ping);
m_fPingMax = MAX(m_fPingMax, ping);
-
+
}
m_fPingSum += ping;
m_fPingCount += 1;
-
+
// pop the original packet
if ( !m_LocalQueue.empty() )
{
@@ -208,14 +208,14 @@ void CCodecStream::Task(void)
}
}
}
-
+
// anything in our queue
while ( !empty() )
{
// yes, pop it from queue
CPacket *Packet = front();
pop();
-
+
// yes, send to ambed
// this assume that thread pushing the Packet
// have verified that the CodecStream is connected
@@ -224,11 +224,11 @@ void CCodecStream::Task(void)
m_uiTotalPackets++;
EncodeAmbePacket(&Buffer, ((CDvFramePacket *)Packet)->GetAmbe(m_uiCodecIn));
m_Socket.Send(Buffer, m_Ip, m_uiPort);
-
+
// and push to our local queue
m_LocalQueue.push(Packet);
}
-
+
// handle timeout
if ( !m_LocalQueue.empty() && (m_TimeoutTimer.DurationSinceNow() >= (TRANSCODER_AMBEPACKET_TIMEOUT/1000.0f)) )
{
@@ -243,7 +243,7 @@ void CCodecStream::Task(void)
bool CCodecStream::IsValidAmbePacket(const CBuffer &Buffer, uint8 *Ambe)
{
bool valid = false;
-
+
if ( (Buffer.size() == 11) && (Buffer.data()[0] == m_uiCodecOut) )
{
::memcpy(Ambe, &(Buffer.data()[2]), 9);
diff --git a/src/cdcsprotocol.cpp b/src/cdcsprotocol.cpp
index f4f7b27..536e0a2 100644
--- a/src/cdcsprotocol.cpp
+++ b/src/cdcsprotocol.cpp
@@ -72,7 +72,7 @@ void CDcsProtocol::Task(void)
CDvFramePacket *Frame;
// handle incoming packets
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
// crack the packet
if ( IsValidDvPacket(Buffer, &Header, &Frame) )
diff --git a/src/cdextraprotocol.cpp b/src/cdextraprotocol.cpp
index be1a31d..568f7cb 100644
--- a/src/cdextraprotocol.cpp
+++ b/src/cdextraprotocol.cpp
@@ -75,7 +75,7 @@ void CDextraProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// any incoming packet ?
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
diff --git a/src/cdmrmmdvmprotocol.cpp b/src/cdmrmmdvmprotocol.cpp
index 41468b3..8e05bb2 100644
--- a/src/cdmrmmdvmprotocol.cpp
+++ b/src/cdmrmmdvmprotocol.cpp
@@ -97,7 +97,7 @@ void CDmrmmdvmProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// handle incoming packets
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
//Buffer.DebugDump(g_Reflector.m_DebugFile);
// crack the packet
diff --git a/src/cdmrplusprotocol.cpp b/src/cdmrplusprotocol.cpp
index cb9b19f..2323732 100644
--- a/src/cdmrplusprotocol.cpp
+++ b/src/cdmrplusprotocol.cpp
@@ -86,7 +86,7 @@ void CDmrplusProtocol::Task(void)
CDvFramePacket *Frames[3];
// handle incoming packets
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
// crack the packet
if ( IsValidDvFramePacket(Ip, Buffer, Frames) )
diff --git a/src/cdplusprotocol.cpp b/src/cdplusprotocol.cpp
index 95e93ac..7d59c41 100644
--- a/src/cdplusprotocol.cpp
+++ b/src/cdplusprotocol.cpp
@@ -73,7 +73,7 @@ void CDplusProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// handle incoming packets
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
diff --git a/src/cg3protocol.cpp b/src/cg3protocol.cpp
index 72b6f8f..6f75be3 100644
--- a/src/cg3protocol.cpp
+++ b/src/cg3protocol.cpp
@@ -156,11 +156,11 @@ void CG3Protocol::PresenceTask(void)
CCallsign Terminal;
- if ( m_PresenceSocket.Receive(&Buffer, &ReqIp, 20) != -1 )
+ if ( m_PresenceSocket.Receive(Buffer, ReqIp, 20) )
{
CIp Ip(ReqIp);
- Ip.GetSockAddr()->sin_port = htons(G3_DV_PORT);
+ Ip.SetPort(G3_DV_PORT);
if (Buffer.size() == 32)
{
@@ -390,7 +390,7 @@ void CG3Protocol::Task(void)
CDvLastFramePacket *LastFrame;
// any incoming packet ?
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) != -1 )
{
CIp ClIp;
CIp *BaseIp = NULL;
diff --git a/src/cip.cpp b/src/cip.cpp
index 5cec9b5..3c5c2ae 100644
--- a/src/cip.cpp
+++ b/src/cip.cpp
@@ -1,91 +1,241 @@
-//
-// cip.cpp
-// xlxd
-//
-// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
-// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
-//
-// ----------------------------------------------------------------------------
-// This file is part of xlxd.
-//
-// xlxd is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// xlxd is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Foobar. If not, see .
-// ----------------------------------------------------------------------------
-
-#include "main.h"
-#include
-#include "cip.h"
+/*
+* Copyright (C) 2020 by Thomas Early N7TAE
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#include
+#include
+#include
#include
-
-////////////////////////////////////////////////////////////////////////////////////////
-// constructors
+#include "cip.h"
CIp::CIp()
{
- ::memset(&m_Addr, 0, sizeof(m_Addr));
- m_Addr.sin_family = AF_INET;
+ Clear();
}
-CIp::CIp(const char *sz)
+CIp::CIp(const char *address, int family, int type, uint16_t port)
+{
+ Clear();
+ struct addrinfo hints, *result;
+ bzero(&hints, sizeof(struct addrinfo));
+ hints.ai_family = family;
+ hints.ai_socktype = type;
+ if (0 == getaddrinfo(address, (port ? std::to_string(port).c_str() : NULL), &hints, &result)) {
+ memcpy(&addr, result->ai_addr, result->ai_addrlen);
+ addr.ss_family = result->ai_family;
+ freeaddrinfo(result);
+ }
+ SetPort(port);
+}
+CIp::CIp(const int family, const uint16_t port, const char *address)
{
- ::memset(&m_Addr, 0, sizeof(m_Addr));
- m_Addr.sin_family = AF_INET;
- // try xxx.xxx.xxx.xxxx first
- m_Addr.sin_addr.s_addr = inet_addr(sz);
- if ( m_Addr.sin_addr.s_addr == INADDR_NONE )
- {
- // otherwise try to resolve via dns
- hostent *record = gethostbyname(sz);
- if( record != NULL )
- {
- m_Addr.sin_addr.s_addr = ((in_addr * )record->h_addr)->s_addr;
- }
- }
+ Initialize(family, port, address);
}
-CIp::CIp(const struct sockaddr_in *sa)
+void CIp::Initialize(const int family, const uint16_t port, const char *address)
{
- ::memcpy(&m_Addr, sa, sizeof(m_Addr));
+ Clear();
+ addr.ss_family = family;
+ if (AF_INET == family) {
+ auto addr4 = (struct sockaddr_in *)&addr;
+ addr4->sin_port = htons(port);
+ if (address) {
+ if (0 == strncasecmp(address, "loc", 3))
+ inet_pton(AF_INET, "127.0.0.1", &(addr4->sin_addr));
+ else if (0 == strncasecmp(address, "any", 3))
+ inet_pton(AF_INET, "0.0.0.0", &(addr4->sin_addr));
+ else if (0 == strncasecmp(address, "none", 4))
+ addr.ss_family = AF_UNSPEC;
+ else {
+ if (1 > inet_pton(AF_INET, address, &(addr4->sin_addr)))
+ std::cerr << "Address Initialization Error: '" << address << "' is not a valdid IPV4 address!" << std::endl;
+ }
+ }
+ } else if (AF_INET6 == family) {
+ auto addr6 = (struct sockaddr_in6 *)&addr;
+ addr6->sin6_port = htons(port);
+ if (address) {
+ if (0 == strncasecmp(address, "loc", 3))
+ inet_pton(AF_INET6, "::1", &(addr6->sin6_addr));
+ else if (0 == strncasecmp(address, "any", 3))
+ inet_pton(AF_INET6, "::", &(addr6->sin6_addr));
+ else if (0 == strncasecmp(address, "none", 4))
+ addr.ss_family = AF_UNSPEC;
+ else {
+ if (1 > inet_pton(AF_INET6, address, &(addr6->sin6_addr)))
+ std::cerr << "Address Initialization Error: '" << address << "' is not a valid IPV6 address!" << std::endl;
+ }
+ }
+ } else
+ std::cerr << "Error: Wrong address family type:" << family << " for [" << (address ? address : "NULL") << "]:" << port << std::endl;
}
+bool CIp::operator==(const CIp &rhs) const // doesn't compare ports, only addresses and families
+{
+ if (addr.ss_family != rhs.addr.ss_family)
+ return false;
+ if (AF_INET == addr.ss_family) {
+ auto l = (struct sockaddr_in *)&addr;
+ auto r = (struct sockaddr_in *)&rhs.addr;
+ return (l->sin_addr.s_addr == r->sin_addr.s_addr);
+ } else if (AF_INET6 == addr.ss_family) {
+ auto l = (struct sockaddr_in6 *)&addr;
+ auto r = (struct sockaddr_in6 *)&rhs.addr;
+ return (0 == memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_addr)));
+ }
+ return false;
+}
-CIp::CIp(const CIp &ip)
+bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addresses and families
{
- ::memcpy(&m_Addr, &ip.m_Addr, sizeof(m_Addr));
+ if (addr.ss_family != rhs.addr.ss_family)
+ return true;
+ if (AF_INET == addr.ss_family) {
+ auto l = (struct sockaddr_in *)&addr;
+ auto r = (struct sockaddr_in *)&rhs.addr;
+ return (l->sin_addr.s_addr != r->sin_addr.s_addr);
+ } else if (AF_INET6 == addr.ss_family) {
+ auto l = (struct sockaddr_in6 *)&addr;
+ auto r = (struct sockaddr_in6 *)&rhs.addr;
+ return (0 != memcmp(&(l->sin6_addr), &(r->sin6_addr), sizeof(struct in6_addr)));
+ }
+ return true;
}
-////////////////////////////////////////////////////////////////////////////////////////
-// set
+bool CIp::AddressIsZero() const
+{
+ if (AF_INET == addr.ss_family) {
+ auto addr4 = (struct sockaddr_in *)&addr;
+ return (addr4->sin_addr.s_addr == 0U);
+ } else {
+ auto addr6 = (struct sockaddr_in6 *)&addr;
+ for (unsigned int i=0; i<16; i++) {
+ if (addr6->sin6_addr.s6_addr[i])
+ return false;
+ }
+ return true;
+ }
+}
-void CIp::SetSockAddr(struct sockaddr_in *sa)
+void CIp::ClearAddress()
{
- ::memcpy(&m_Addr, sa, sizeof(m_Addr));
+ if (AF_INET == addr.ss_family) {
+ auto addr4 = (struct sockaddr_in *)&addr;
+ addr4->sin_addr.s_addr = 0U;
+ strcpy(straddr, "0.0.0.0");
+ } else {
+ auto addr6 = (struct sockaddr_in6 *)&addr;
+ memset(&(addr6->sin6_addr.s6_addr), 0, 16);
+ strcpy(straddr, "::");
+ }
}
-////////////////////////////////////////////////////////////////////////////////////////
-// operator
+const char *CIp::GetAddress() const
+{
+ if (straddr[0])
+ return straddr;
+
+ if (AF_INET == addr.ss_family) {
+ auto addr4 = (struct sockaddr_in *)&addr;
+ inet_ntop(AF_INET, &(addr4->sin_addr), straddr, INET6_ADDRSTRLEN);
+ } else if (AF_INET6 == addr.ss_family) {
+ auto addr6 = (struct sockaddr_in6 *)&addr;
+ inet_ntop(AF_INET6, &(addr6->sin6_addr), straddr, INET6_ADDRSTRLEN);
+ } else {
+ std::cerr << "CIp::GetAddress: unknown socket family=" << addr.ss_family << std::endl;
+ }
+ return straddr;
+}
-bool CIp::operator ==(const CIp &ip) const
+std::ostream &operator<<(std::ostream &stream, const CIp &Ip)
{
- return ( (ip.m_Addr.sin_family == m_Addr.sin_family) &&
- (ip.m_Addr.sin_addr.s_addr == m_Addr.sin_addr.s_addr) &&
- (ip.m_Addr.sin_port == m_Addr.sin_port)) ;
+ const char *sz = Ip;
+ if (AF_INET6 == Ip.GetFamily())
+ stream << "[" << sz << "]";
+ else
+ stream << sz;
+ const uint16_t port = Ip.GetPort();
+ if (port)
+ stream << ":" << port;
+ return stream;
}
-CIp::operator const char *() const
+uint32_t CIp::GetAddr() const
{
- return ::inet_ntoa(m_Addr.sin_addr);
+ if (AF_INET6 == addr.ss_family) {
+ auto addr6 = (struct sockaddr_in6 *)&addr;
+ // hash the results
+ auto *a = (const uint32_t *)&(addr6->sin6_addr.s6_addr);
+ return a[0] ^ a[1] ^ a[2] ^ a[3];
+ } else {
+ auto addr4 = (struct sockaddr_in *)&addr;
+ return addr4->sin_addr.s_addr;
+ }
}
+int CIp::GetFamily() const
+{
+ return addr.ss_family;
+}
+uint16_t CIp::GetPort() const
+{
+ if (AF_INET == addr.ss_family) {
+ auto addr4 = (struct sockaddr_in *)&addr;
+ return ntohs(addr4->sin_port);
+ } else if (AF_INET6 == addr.ss_family) {
+ auto addr6 = (struct sockaddr_in6 *)&addr;
+ return ntohs(addr6->sin6_port);
+ } else
+ return 0;
+}
+
+void CIp::SetPort(const uint16_t newport)
+{
+ if (AF_INET == addr.ss_family) {
+ auto addr4 = (struct sockaddr_in *)&addr;
+ addr4->sin_port = htons(newport);
+ } else if (AF_INET6 == addr.ss_family) {
+ auto addr6 = (struct sockaddr_in6 *)&addr;
+ addr6->sin6_port = htons(newport);
+ }
+}
+
+struct sockaddr *CIp::GetPointer()
+{
+ memset(straddr, 0, INET6_ADDRSTRLEN); // things might change
+ return (struct sockaddr *)&addr;
+}
+
+const struct sockaddr *CIp::GetCPointer() const
+{
+ return (const struct sockaddr *)&addr;
+}
+
+size_t CIp::GetSize() const
+{
+ if (AF_INET == addr.ss_family)
+ return sizeof(struct sockaddr_in);
+ else
+ return sizeof(struct sockaddr_in6);
+}
+
+void CIp::Clear()
+{
+ memset(&addr, 0, sizeof(struct sockaddr_storage));
+ memset(straddr, 0, INET6_ADDRSTRLEN);
+}
diff --git a/src/cip.h b/src/cip.h
index 6c43288..78fc05d 100644
--- a/src/cip.h
+++ b/src/cip.h
@@ -1,63 +1,73 @@
-//
-// cip.h
-// xlxd
-//
-// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
-// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
-//
-// ----------------------------------------------------------------------------
-// This file is part of xlxd.
-//
-// xlxd is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// xlxd is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Foobar. If not, see .
-// ----------------------------------------------------------------------------
-
-#ifndef cip_h
-#define cip_h
-
-
-////////////////////////////////////////////////////////////////////////////////////////
-// class
+#pragma once
+
+/*
+ * Copyright (C) 2020 by Thomas Early N7TAE
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
class CIp
{
public:
- // constructors
- CIp();
- //CIp(uint8, uint8, uint8, uint8);
- CIp(const struct sockaddr_in *);
- CIp(const char *);
- CIp(const CIp &);
-
- // destructor
- virtual ~CIp() {};
-
- // sockaddr
- void SetSockAddr(struct sockaddr_in *);
- struct sockaddr_in *GetSockAddr(void) { return &m_Addr; }
-
- // convertor
- uint32 GetAddr(void) const { return m_Addr.sin_addr.s_addr; }
- uint16 GetPort(void) const { return m_Addr.sin_port; }
-
- // operator
- bool operator ==(const CIp &) const;
- operator const char *() const;
-
-protected:
- // data
- struct sockaddr_in m_Addr;
+ // constructors
+ CIp();
+ CIp(const char *address, int family = AF_UNSPEC, int type = SOCK_DGRAM, uint16_t port = 0U);
+ CIp(const int family, const uint16_t port = 0U, const char *address = NULL);
+
+ // initializer for empty constructor
+ void Initialize(const int family, const uint16_t port = 0U, const char *address = NULL);
+
+ // comparison operators
+ bool operator==(const CIp &rhs) const;
+ bool operator!=(const CIp &rhs) const;
+
+ // state methods
+ bool AddressIsZero() const;
+ void ClearAddress();
+ const char *GetAddress() const;
+ operator const char *() const { return GetAddress(); }
+ friend std::ostream &operator<<(std::ostream &stream, const CIp &Ip);
+ int GetFamily() const;
+ uint16_t GetPort() const;
+ size_t GetSize() const;
+ uint32_t GetAddr() const;
+
+ // modifiers
+ void SetPort(const uint16_t newport);
+
+ // for i/o
+ struct sockaddr *GetPointer();
+ const struct sockaddr *GetCPointer() const;
+
+ void Clear();
+
+private:
+ struct sockaddr_storage addr;
+ mutable char straddr[INET6_ADDRSTRLEN];
};
-////////////////////////////////////////////////////////////////////////////////////////
-#endif /* cip_h */
+std::ostream &operator<<(std::ostream &stream, const CIp &Ip);
diff --git a/src/crawsocket.cpp b/src/crawsocket.cpp
index a30908d..de8514b 100644
--- a/src/crawsocket.cpp
+++ b/src/crawsocket.cpp
@@ -19,7 +19,7 @@
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
-// along with Foobar. If not, see .
+// along with Foobar. If not, see .
// ----------------------------------------------------------------------------
#include "main.h"
@@ -54,7 +54,7 @@ bool CRawSocket::Open(uint16 uiProto)
{
bool open = false;
int on = 1;
-
+
// create socket
m_Socket = socket(AF_INET,SOCK_RAW,uiProto);
if ( m_Socket != -1 )
@@ -63,7 +63,7 @@ bool CRawSocket::Open(uint16 uiProto)
open = true;
m_Proto = uiProto;
}
-
+
// done
return open;
}
@@ -113,7 +113,7 @@ int CRawSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
Buffer->resize(iRecvLen);
// get IP
- Ip->SetSockAddr(&Sin);
+ memcpy(Ip->GetPointer(), &Sin, sizeof(struct sockaddr_in));
}
}
@@ -148,7 +148,7 @@ int CRawSocket::IcmpReceive(CBuffer *Buffer, CIp *Ip, int timeout)
Sin.sin_family = AF_INET;
Sin.sin_addr.s_addr = remote_iph->ip_dst.s_addr;
- Ip->SetSockAddr(&Sin);
+ memcpy(Ip->GetPointer(), &Sin, sizeof(struct sockaddr_in));
}
}
diff --git a/src/creflector.cpp b/src/creflector.cpp
index a5cb278..41e5b7c 100644
--- a/src/creflector.cpp
+++ b/src/creflector.cpp
@@ -429,7 +429,7 @@ void CReflector::JsonReportThread(CReflector *This)
while ( !This->m_bStopThreads )
{
// any command ?
- if ( Socket.Receive(&Buffer, &Ip, 50) != -1 )
+ if ( Socket.Receive(Buffer, Ip, 50) )
{
// check verb
if ( Buffer.Compare((uint8 *)"hello", 5) == 0 )
diff --git a/src/ctranscoder.cpp b/src/ctranscoder.cpp
index 6e48ccc..e4d91b3 100644
--- a/src/ctranscoder.cpp
+++ b/src/ctranscoder.cpp
@@ -140,7 +140,7 @@ void CTranscoder::Task(void)
// anything coming in from codec server ?
//if ( (m_Socket.Receive(&Buffer, &Ip, 20) != -1) && (Ip == m_Ip) )
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
m_LastActivityTime.Now();
diff --git a/src/cudpmsgsocket.cpp b/src/cudpmsgsocket.cpp
index 45d438d..b90f702 100644
--- a/src/cudpmsgsocket.cpp
+++ b/src/cudpmsgsocket.cpp
@@ -19,7 +19,7 @@
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
-// along with Foobar. If not, see .
+// along with Foobar. If not, see .
// ----------------------------------------------------------------------------
#include "main.h"
@@ -34,7 +34,7 @@ bool CUdpMsgSocket::Open(uint16 uiPort)
int on = 1;
ret = CUdpSocket::Open(uiPort);
- setsockopt(m_Socket, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on));
+ setsockopt(m_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on));
return ret;
}
@@ -60,7 +60,7 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
} Control;
// socket valid ?
- if ( m_Socket != -1 )
+ if ( m_fd != -1 )
{
// allocate buffer
Buffer->resize(UDP_MSG_BUFFER_LENMAX);
@@ -80,22 +80,23 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
// control socket
FD_ZERO(&FdSet);
- FD_SET(m_Socket, &FdSet);
+ FD_SET(m_fd, &FdSet);
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
- select(m_Socket + 1, &FdSet, 0, 0, &tv);
-
+ select(m_fd + 1, &FdSet, 0, 0, &tv);
+
// read
- iRecvLen = (int)recvmsg(m_Socket, &Msg, 0);
-
+ iRecvLen = (int)recvmsg(m_fd, &Msg, 0);
+
// handle
if ( iRecvLen != -1 )
{
// adjust buffer size
Buffer->resize(iRecvLen);
-
+
// get IP
- Ip->SetSockAddr(&Sin);
+ if (AF_INET == m_addr.GetFamily())
+ memcpy(Ip->GetPointer(), &Sin, sizeof(struct sockaddr_in));
// get local IP
struct cmsghdr *Cmsg;
@@ -109,8 +110,7 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
}
}
}
-
+
// done
return iRecvLen;
}
-
diff --git a/src/cudpsocket.cpp b/src/cudpsocket.cpp
index 5caa074..9b7fa8a 100644
--- a/src/cudpsocket.cpp
+++ b/src/cudpsocket.cpp
@@ -4,6 +4,7 @@
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
+// Copyright © 2020 Thomas A. Early, N7TAE
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
@@ -19,11 +20,11 @@
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
-// along with Foobar. If not, see .
+// along with Foobar. If not, see .
// ----------------------------------------------------------------------------
-#include "main.h"
#include
+#include "main.h"
#include "creflector.h"
#include "cudpsocket.h"
@@ -33,7 +34,7 @@
CUdpSocket::CUdpSocket()
{
- m_Socket = -1;
+ m_fd = -1;
}
////////////////////////////////////////////////////////////////////////////////////////
@@ -41,133 +42,142 @@ CUdpSocket::CUdpSocket()
CUdpSocket::~CUdpSocket()
{
- if ( m_Socket != -1 )
- {
- Close();
- }
+ Close();
}
////////////////////////////////////////////////////////////////////////////////////////
// open & close
-bool CUdpSocket::Open(uint16 uiPort)
+// returns true on error
+bool CUdpSocket::Open(const CIp &Ip)
{
- bool open = false;
-
- // create socket
- m_Socket = socket(PF_INET,SOCK_DGRAM,0);
- if ( m_Socket != -1 )
- {
- // initialize sockaddr struct
- ::memset(&m_SocketAddr, 0, sizeof(struct sockaddr_in));
- m_SocketAddr.sin_family = AF_INET;
- m_SocketAddr.sin_port = htons(uiPort);
- m_SocketAddr.sin_addr.s_addr = inet_addr(g_Reflector.GetListenIp());
-
- if ( bind(m_Socket, (struct sockaddr *)&m_SocketAddr, sizeof(struct sockaddr_in)) == 0 )
- {
- fcntl(m_Socket, F_SETFL, O_NONBLOCK);
- open = true;
- }
- else
- {
- close(m_Socket);
- m_Socket = -1;
- }
- }
-
- // done
- return open;
+ // check for a vaild family
+ if (AF_UNSPEC == Ip.GetFamily())
+ return true;
+
+ // create socket
+ m_fd = socket(Ip.GetFamily(), SOCK_DGRAM, 0);
+ if ( m_fd < 0 )
+ {
+ std::cerr << "Unable to open socket on " << Ip << ", " << strerror(errno) << std::endl;
+ return false;
+ }
+ // initialize sockaddr struct
+ m_addr = Ip;
+
+ int reuse = 1;
+ if ( 0 > setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)))
+ {
+ std::cerr << "Cannot set the UDP socket option on " << m_addr << ", " << strerror(errno) << std::endl;
+ Close();
+ return false;
+ }
+
+ if (fcntl(m_fd, F_SETFL, O_NONBLOCK))
+ {
+ std::cerr << "fcntl set non-blocking failed on " << m_addr << ", " << strerror(errno) << std::endl;
+ Close();
+ return false;
+ }
+
+ if ( bind(m_fd, m_addr.GetCPointer(), m_addr.GetSize()) )
+ {
+ std::cerr << "bind failed on " << m_addr << ", " << strerror(errno) << std::endl;
+ Close();
+ return false;
+ }
+
+ if (0 == m_addr.GetPort()) { // get the assigned port for an ephemeral port request
+ CIp a;
+ socklen_t len = sizeof(struct sockaddr_storage);
+ if (getsockname(m_fd, a.GetPointer(), &len))
+ {
+ std::cerr << "getsockname error " << m_addr << ", " << strerror(errno) << std::endl;
+ Close();
+ return false;
+ }
+ if (a != m_addr)
+ std::cout << "getsockname didn't return the same address as set: returned " << a << ", should have been " << m_addr << std::endl;
+
+ m_addr.SetPort(a.GetPort());
+ }
+
+ // done
+ return true;
}
void CUdpSocket::Close(void)
{
- if ( m_Socket != -1 )
- {
- close(m_Socket);
- m_Socket = -1;
- }
+ if ( m_fd >= 0 )
+ {
+ close(m_fd);
+ m_fd = -1;
+ }
}
////////////////////////////////////////////////////////////////////////////////////////
// read
-int CUdpSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
+bool CUdpSocket::Receive(CBuffer &Buffer, CIp &Ip, int timeout)
{
- struct sockaddr_in Sin;
- fd_set FdSet;
- unsigned int uiFromLen = sizeof(struct sockaddr_in);
- int iRecvLen = -1;
- struct timeval tv;
-
- // socket valid ?
- if ( m_Socket != -1 )
- {
- // control socket
- FD_ZERO(&FdSet);
- FD_SET(m_Socket, &FdSet);
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- select(m_Socket + 1, &FdSet, 0, 0, &tv);
-
- // allocate buffer
- Buffer->resize(UDP_BUFFER_LENMAX);
-
- // read
- iRecvLen = (int)recvfrom(m_Socket,
- (void *)Buffer->data(), UDP_BUFFER_LENMAX,
- 0, (struct sockaddr *)&Sin, &uiFromLen);
-
- // handle
- if ( iRecvLen != -1 )
- {
- // adjust buffer size
- Buffer->resize(iRecvLen);
-
- // get IP
- Ip->SetSockAddr(&Sin);
- }
- }
-
- // done
- return iRecvLen;
+ // socket valid ?
+ if ( 0 > m_fd )
+ return false;
+
+ // control socket
+ fd_set FdSet;
+ FD_ZERO(&FdSet);
+ FD_SET(m_fd, &FdSet);
+ struct timeval tv;
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ auto rval = select(m_fd + 1, &FdSet, 0, 0, &tv);
+ if (0 > rval)
+ {
+ std::cerr << "select error on UPD port " << m_addr << ": " << strerror(errno) << std::endl;
+ return false;
+ }
+ else if (0 == rval)
+ return false;
+
+ // read
+ uint8_t buf[UDP_BUFFER_LENMAX];
+ unsigned int fromsize = sizeof(struct sockaddr_storage);
+ auto iRecvLen = recvfrom(m_fd, buf, UDP_BUFFER_LENMAX, 0, Ip.GetPointer(), &fromsize);
+
+ // handle
+ if (0 >= iRecvLen)
+ return false;
+
+ Buffer.Set(buf, iRecvLen);
+
+ // done
+ return true;
}
////////////////////////////////////////////////////////////////////////////////////////
// write
-int CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip)
+void CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip) const
{
- CIp temp(Ip);
- return (int)::sendto(m_Socket,
- (void *)Buffer.data(), Buffer.size(),
- 0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
+ sendto(m_fd, Buffer.data(), Buffer.size(), 0, Ip.GetCPointer(), Ip.GetSize());
}
-int CUdpSocket::Send(const char *Buffer, const CIp &Ip)
+void CUdpSocket::Send(const char *Buffer, const CIp &Ip) const
{
- CIp temp(Ip);
- return (int)::sendto(m_Socket,
- (void *)Buffer, ::strlen(Buffer),
- 0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
+ sendto(m_fd, Buffer, ::strlen(Buffer), 0, Ip.GetCPointer(), Ip.GetSize());
}
-int CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip, uint16 destport)
+void CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip, uint16_t destport) const
{
- CIp temp(Ip);
- temp.GetSockAddr()->sin_port = htons(destport);
- return (int)::sendto(m_Socket,
- (void *)Buffer.data(), Buffer.size(),
- 0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
+ CIp temp(Ip);
+ temp.SetPort(destport);
+ sendto(m_fd, Buffer.data(), Buffer.size(), 0, temp.GetCPointer(), temp.GetSize());
}
-int CUdpSocket::Send(const char *Buffer, const CIp &Ip, uint16 destport)
+void CUdpSocket::Send(const char *Buffer, const CIp &Ip, uint16_t destport) const
{
- CIp temp(Ip);
- temp.GetSockAddr()->sin_port = htons(destport);
- return (int)::sendto(m_Socket,
- (void *)Buffer, ::strlen(Buffer),
- 0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
+ CIp temp(Ip);
+ temp.SetPort(destport);
+ sendto(m_fd, Buffer, ::strlen(Buffer), 0, temp.GetCPointer(), temp.GetSize());
}
-
-
diff --git a/src/cudpsocket.h b/src/cudpsocket.h
index e91ed80..5f42e9f 100644
--- a/src/cudpsocket.h
+++ b/src/cudpsocket.h
@@ -4,6 +4,7 @@
//
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
+// Copyright © 2020 Thomas A. Early, N7TAE
//
// ----------------------------------------------------------------------------
// This file is part of xlxd.
@@ -19,14 +20,14 @@
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
-// along with Foobar. If not, see .
+// along with Foobar. If not, see .
// ----------------------------------------------------------------------------
#ifndef cudpsocket_h
#define cudpsocket_h
+#include
#include
-//#include
#include
#include
#include
@@ -48,30 +49,33 @@
class CUdpSocket
{
public:
- // constructor
- CUdpSocket();
-
- // destructor
- ~CUdpSocket();
-
- // open & close
- bool Open(uint16);
- void Close(void);
- int GetSocket(void) { return m_Socket; }
-
- // read
- int Receive(CBuffer *, CIp *, int);
-
- // write
- int Send(const CBuffer &, const CIp &);
- int Send(const CBuffer &, const CIp &, uint16);
- int Send(const char *, const CIp &);
- int Send(const char *, const CIp &, uint16);
-
+ // constructor
+ CUdpSocket();
+
+ // destructor
+ ~CUdpSocket();
+
+ // open & close
+ bool Open(const CIp &Ip);
+ void Close(void);
+ int GetSocket(void)
+ {
+ return m_fd;
+ }
+
+ // read
+ bool Receive(CBuffer &, CIp &, int);
+
+ // write
+ void Send(const CBuffer &, const CIp &) const;
+ void Send(const char *, const CIp &) const;
+ void Send(const CBuffer &, const CIp &, uint16_t) const;
+ void Send(const char *, const CIp &, uint16_t) const;
+
protected:
- // data
- int m_Socket;
- struct sockaddr_in m_SocketAddr;
+ // data
+ int m_fd;
+ CIp m_addr;
};
////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp
index 26a022f..d237aa4 100644
--- a/src/cxlxprotocol.cpp
+++ b/src/cxlxprotocol.cpp
@@ -75,7 +75,7 @@ void CXlxProtocol::Task(void)
CDvLastFramePacket *LastFrame;
// any incoming packet ?
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
// crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
diff --git a/src/cysfprotocol.cpp b/src/cysfprotocol.cpp
index 208fbe4..968fcb8 100644
--- a/src/cysfprotocol.cpp
+++ b/src/cysfprotocol.cpp
@@ -111,7 +111,7 @@ void CYsfProtocol::Task(void)
}
// handle incoming packets
- if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
+ if ( m_Socket.Receive(Buffer, Ip, 20) )
{
// crack the packet
if ( IsValidDvPacket(Buffer, &Fich) )