new CIp & CUdpSocket

pull/1/head
Tom Early 6 years ago
parent e6f4096f2c
commit 30a47e1bd3

@ -61,7 +61,7 @@ CCodecStream::~CCodecStream()
{ {
// close socket // close socket
m_Socket.Close(); m_Socket.Close();
// kill threads // kill threads
m_bStopThread = true; m_bStopThread = true;
if ( m_pThread != NULL ) if ( m_pThread != NULL )
@ -69,7 +69,7 @@ CCodecStream::~CCodecStream()
m_pThread->join(); m_pThread->join();
delete m_pThread; delete m_pThread;
} }
// empty local queue // empty local queue
while ( !m_LocalQueue.empty() ) while ( !m_LocalQueue.empty() )
{ {
@ -90,14 +90,14 @@ CCodecStream::~CCodecStream()
bool CCodecStream::Init(uint16 uiPort) bool CCodecStream::Init(uint16 uiPort)
{ {
bool ok; bool ok;
// reset stop flag // reset stop flag
m_bStopThread = false; m_bStopThread = false;
// create server's IP // create server's IP
m_Ip = g_Reflector.GetTranscoderIp(); m_Ip = g_Reflector.GetTranscoderIp();
m_uiPort = uiPort; m_uiPort = uiPort;
// create our socket // create our socket
ok = m_Socket.Open(uiPort); ok = m_Socket.Open(uiPort);
if ( ok ) 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; std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << g_Reflector.GetListenIp() << std::endl;
m_bConnected = false; m_bConnected = false;
} }
// done // done
return ok; return ok;
} }
@ -121,7 +121,7 @@ void CCodecStream::Close(void)
// close socket // close socket
m_bConnected = false; m_bConnected = false;
m_Socket.Close(); m_Socket.Close();
// kill threads // kill threads
m_bStopThread = true; m_bStopThread = true;
if ( m_pThread != NULL ) if ( m_pThread != NULL )
@ -157,33 +157,33 @@ void CCodecStream::Task(void)
CIp Ip; CIp Ip;
uint8 Ambe[AMBE_SIZE]; uint8 Ambe[AMBE_SIZE];
uint8 DStarSync[] = { 0x55,0x2D,0x16 }; uint8 DStarSync[] = { 0x55,0x2D,0x16 };
// any packet from transcoder // any packet from transcoder
if ( m_Socket.Receive(&Buffer, &Ip, 5) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 5) )
{ {
// crack // crack
if ( IsValidAmbePacket(Buffer, Ambe) ) if ( IsValidAmbePacket(Buffer, Ambe) )
{ {
// tickle // tickle
m_TimeoutTimer.Now(); m_TimeoutTimer.Now();
// update statistics // update statistics
double ping = m_StatsTimer.DurationSinceNow(); double ping = m_StatsTimer.DurationSinceNow();
if ( m_fPingMin == -1 ) if ( m_fPingMin == -1 )
{ {
m_fPingMin = ping; m_fPingMin = ping;
m_fPingMax = ping; m_fPingMax = ping;
} }
else else
{ {
m_fPingMin = MIN(m_fPingMin, ping); m_fPingMin = MIN(m_fPingMin, ping);
m_fPingMax = MAX(m_fPingMax, ping); m_fPingMax = MAX(m_fPingMax, ping);
} }
m_fPingSum += ping; m_fPingSum += ping;
m_fPingCount += 1; m_fPingCount += 1;
// pop the original packet // pop the original packet
if ( !m_LocalQueue.empty() ) if ( !m_LocalQueue.empty() )
{ {
@ -208,14 +208,14 @@ void CCodecStream::Task(void)
} }
} }
} }
// anything in our queue // anything in our queue
while ( !empty() ) while ( !empty() )
{ {
// yes, pop it from queue // yes, pop it from queue
CPacket *Packet = front(); CPacket *Packet = front();
pop(); pop();
// yes, send to ambed // yes, send to ambed
// this assume that thread pushing the Packet // this assume that thread pushing the Packet
// have verified that the CodecStream is connected // have verified that the CodecStream is connected
@ -224,11 +224,11 @@ void CCodecStream::Task(void)
m_uiTotalPackets++; m_uiTotalPackets++;
EncodeAmbePacket(&Buffer, ((CDvFramePacket *)Packet)->GetAmbe(m_uiCodecIn)); EncodeAmbePacket(&Buffer, ((CDvFramePacket *)Packet)->GetAmbe(m_uiCodecIn));
m_Socket.Send(Buffer, m_Ip, m_uiPort); m_Socket.Send(Buffer, m_Ip, m_uiPort);
// and push to our local queue // and push to our local queue
m_LocalQueue.push(Packet); m_LocalQueue.push(Packet);
} }
// handle timeout // handle timeout
if ( !m_LocalQueue.empty() && (m_TimeoutTimer.DurationSinceNow() >= (TRANSCODER_AMBEPACKET_TIMEOUT/1000.0f)) ) 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 CCodecStream::IsValidAmbePacket(const CBuffer &Buffer, uint8 *Ambe)
{ {
bool valid = false; bool valid = false;
if ( (Buffer.size() == 11) && (Buffer.data()[0] == m_uiCodecOut) ) if ( (Buffer.size() == 11) && (Buffer.data()[0] == m_uiCodecOut) )
{ {
::memcpy(Ambe, &(Buffer.data()[2]), 9); ::memcpy(Ambe, &(Buffer.data()[2]), 9);

@ -72,7 +72,7 @@ void CDcsProtocol::Task(void)
CDvFramePacket *Frame; CDvFramePacket *Frame;
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
// crack the packet // crack the packet
if ( IsValidDvPacket(Buffer, &Header, &Frame) ) if ( IsValidDvPacket(Buffer, &Header, &Frame) )

@ -75,7 +75,7 @@ void CDextraProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// any incoming packet ? // any incoming packet ?
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
// crack the packet // crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )

@ -97,7 +97,7 @@ void CDmrmmdvmProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
//Buffer.DebugDump(g_Reflector.m_DebugFile); //Buffer.DebugDump(g_Reflector.m_DebugFile);
// crack the packet // crack the packet

@ -86,7 +86,7 @@ void CDmrplusProtocol::Task(void)
CDvFramePacket *Frames[3]; CDvFramePacket *Frames[3];
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
// crack the packet // crack the packet
if ( IsValidDvFramePacket(Ip, Buffer, Frames) ) if ( IsValidDvFramePacket(Ip, Buffer, Frames) )

@ -73,7 +73,7 @@ void CDplusProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
// crack the packet // crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )

@ -156,11 +156,11 @@ void CG3Protocol::PresenceTask(void)
CCallsign Terminal; CCallsign Terminal;
if ( m_PresenceSocket.Receive(&Buffer, &ReqIp, 20) != -1 ) if ( m_PresenceSocket.Receive(Buffer, ReqIp, 20) )
{ {
CIp Ip(ReqIp); CIp Ip(ReqIp);
Ip.GetSockAddr()->sin_port = htons(G3_DV_PORT); Ip.SetPort(G3_DV_PORT);
if (Buffer.size() == 32) if (Buffer.size() == 32)
{ {
@ -390,7 +390,7 @@ void CG3Protocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// any incoming packet ? // any incoming packet ?
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) != -1 )
{ {
CIp ClIp; CIp ClIp;
CIp *BaseIp = NULL; CIp *BaseIp = NULL;

@ -1,91 +1,241 @@
// /*
// cip.cpp * Copyright (C) 2020 by Thomas Early N7TAE
// xlxd *
// * This program is free software; you can redistribute it and/or modify
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015. * it under the terms of the GNU General Public License as published by
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. * the Free Software Foundation; either version 2 of the License, or
// * (at your option) any later version.
// ---------------------------------------------------------------------------- *
// This file is part of xlxd. * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// xlxd is free software: you can redistribute it and/or modify * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// it under the terms of the GNU General Public License as published by * GNU General Public License for more details.
// the Free Software Foundation, either version 3 of the License, or *
// (at your option) any later version. * You should have received a copy of the GNU General Public License
// * along with this program; if not, write to the Free Software
// xlxd is distributed in the hope that it will be useful, * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// 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 <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#include "cip.h"
#include <cstdint>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
#include "cip.h"
////////////////////////////////////////////////////////////////////////////////////////
// constructors
CIp::CIp() CIp::CIp()
{ {
::memset(&m_Addr, 0, sizeof(m_Addr)); Clear();
m_Addr.sin_family = AF_INET;
} }
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)); Initialize(family, port, address);
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;
}
}
} }
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;
} }
//////////////////////////////////////////////////////////////////////////////////////// bool CIp::AddressIsZero() const
// set {
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, "::");
}
} }
//////////////////////////////////////////////////////////////////////////////////////// const char *CIp::GetAddress() const
// operator {
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) && const char *sz = Ip;
(ip.m_Addr.sin_addr.s_addr == m_Addr.sin_addr.s_addr) && if (AF_INET6 == Ip.GetFamily())
(ip.m_Addr.sin_port == m_Addr.sin_port)) ; 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);
}

@ -1,63 +1,73 @@
// #pragma once
// cip.h
// xlxd /*
// * Copyright (C) 2020 by Thomas Early N7TAE
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015. *
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. * 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
// This file is part of xlxd. * (at your option) any later version.
// *
// xlxd is free software: you can redistribute it and/or modify * This program is distributed in the hope that it will be useful,
// it under the terms of the GNU General Public License as published by * but WITHOUT ANY WARRANTY; without even the implied warranty of
// the Free Software Foundation, either version 3 of the License, or * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// (at your option) any later version. * GNU General Public License for more details.
// *
// xlxd is distributed in the hope that it will be useful, * You should have received a copy of the GNU General Public License
// but WITHOUT ANY WARRANTY; without even the implied warranty of * along with this program; if not, write to the Free Software
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// GNU General Public License for more details. */
//
// You should have received a copy of the GNU General Public License #include <iostream>
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. #include <cstring>
// ---------------------------------------------------------------------------- #include <chrono>
#include <thread>
#ifndef cip_h
#define cip_h #include <strings.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//////////////////////////////////////////////////////////////////////////////////////// #include <netdb.h>
// class #include <sys/socket.h>
#include <sys/types.h>
class CIp class CIp
{ {
public: public:
// constructors // constructors
CIp(); CIp();
//CIp(uint8, uint8, uint8, uint8); CIp(const char *address, int family = AF_UNSPEC, int type = SOCK_DGRAM, uint16_t port = 0U);
CIp(const struct sockaddr_in *); CIp(const int family, const uint16_t port = 0U, const char *address = NULL);
CIp(const char *);
CIp(const CIp &); // initializer for empty constructor
void Initialize(const int family, const uint16_t port = 0U, const char *address = NULL);
// destructor
virtual ~CIp() {}; // comparison operators
bool operator==(const CIp &rhs) const;
// sockaddr bool operator!=(const CIp &rhs) const;
void SetSockAddr(struct sockaddr_in *);
struct sockaddr_in *GetSockAddr(void) { return &m_Addr; } // state methods
bool AddressIsZero() const;
// convertor void ClearAddress();
uint32 GetAddr(void) const { return m_Addr.sin_addr.s_addr; } const char *GetAddress() const;
uint16 GetPort(void) const { return m_Addr.sin_port; } operator const char *() const { return GetAddress(); }
friend std::ostream &operator<<(std::ostream &stream, const CIp &Ip);
// operator int GetFamily() const;
bool operator ==(const CIp &) const; uint16_t GetPort() const;
operator const char *() const; size_t GetSize() const;
uint32_t GetAddr() const;
protected:
// data // modifiers
struct sockaddr_in m_Addr; 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];
}; };
//////////////////////////////////////////////////////////////////////////////////////// std::ostream &operator<<(std::ostream &stream, const CIp &Ip);
#endif /* cip_h */

@ -19,7 +19,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "main.h" #include "main.h"
@ -54,7 +54,7 @@ bool CRawSocket::Open(uint16 uiProto)
{ {
bool open = false; bool open = false;
int on = 1; int on = 1;
// create socket // create socket
m_Socket = socket(AF_INET,SOCK_RAW,uiProto); m_Socket = socket(AF_INET,SOCK_RAW,uiProto);
if ( m_Socket != -1 ) if ( m_Socket != -1 )
@ -63,7 +63,7 @@ bool CRawSocket::Open(uint16 uiProto)
open = true; open = true;
m_Proto = uiProto; m_Proto = uiProto;
} }
// done // done
return open; return open;
} }
@ -113,7 +113,7 @@ int CRawSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
Buffer->resize(iRecvLen); Buffer->resize(iRecvLen);
// get IP // 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_family = AF_INET;
Sin.sin_addr.s_addr = remote_iph->ip_dst.s_addr; Sin.sin_addr.s_addr = remote_iph->ip_dst.s_addr;
Ip->SetSockAddr(&Sin); memcpy(Ip->GetPointer(), &Sin, sizeof(struct sockaddr_in));
} }
} }

@ -429,7 +429,7 @@ void CReflector::JsonReportThread(CReflector *This)
while ( !This->m_bStopThreads ) while ( !This->m_bStopThreads )
{ {
// any command ? // any command ?
if ( Socket.Receive(&Buffer, &Ip, 50) != -1 ) if ( Socket.Receive(Buffer, Ip, 50) )
{ {
// check verb // check verb
if ( Buffer.Compare((uint8 *)"hello", 5) == 0 ) if ( Buffer.Compare((uint8 *)"hello", 5) == 0 )

@ -140,7 +140,7 @@ void CTranscoder::Task(void)
// anything coming in from codec server ? // 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) && (Ip == m_Ip) )
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
m_LastActivityTime.Now(); m_LastActivityTime.Now();

@ -19,7 +19,7 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "main.h" #include "main.h"
@ -34,7 +34,7 @@ bool CUdpMsgSocket::Open(uint16 uiPort)
int on = 1; int on = 1;
ret = CUdpSocket::Open(uiPort); 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; return ret;
} }
@ -60,7 +60,7 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
} Control; } Control;
// socket valid ? // socket valid ?
if ( m_Socket != -1 ) if ( m_fd != -1 )
{ {
// allocate buffer // allocate buffer
Buffer->resize(UDP_MSG_BUFFER_LENMAX); Buffer->resize(UDP_MSG_BUFFER_LENMAX);
@ -80,22 +80,23 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
// control socket // control socket
FD_ZERO(&FdSet); FD_ZERO(&FdSet);
FD_SET(m_Socket, &FdSet); FD_SET(m_fd, &FdSet);
tv.tv_sec = timeout / 1000; tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000; tv.tv_usec = (timeout % 1000) * 1000;
select(m_Socket + 1, &FdSet, 0, 0, &tv); select(m_fd + 1, &FdSet, 0, 0, &tv);
// read // read
iRecvLen = (int)recvmsg(m_Socket, &Msg, 0); iRecvLen = (int)recvmsg(m_fd, &Msg, 0);
// handle // handle
if ( iRecvLen != -1 ) if ( iRecvLen != -1 )
{ {
// adjust buffer size // adjust buffer size
Buffer->resize(iRecvLen); Buffer->resize(iRecvLen);
// get IP // get IP
Ip->SetSockAddr(&Sin); if (AF_INET == m_addr.GetFamily())
memcpy(Ip->GetPointer(), &Sin, sizeof(struct sockaddr_in));
// get local IP // get local IP
struct cmsghdr *Cmsg; struct cmsghdr *Cmsg;
@ -109,8 +110,7 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
} }
} }
} }
// done // done
return iRecvLen; return iRecvLen;
} }

@ -4,6 +4,7 @@
// //
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015. // Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
// Copyright © 2020 Thomas A. Early, N7TAE
// //
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// This file is part of xlxd. // This file is part of xlxd.
@ -19,11 +20,11 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#include "main.h"
#include <string.h> #include <string.h>
#include "main.h"
#include "creflector.h" #include "creflector.h"
#include "cudpsocket.h" #include "cudpsocket.h"
@ -33,7 +34,7 @@
CUdpSocket::CUdpSocket() CUdpSocket::CUdpSocket()
{ {
m_Socket = -1; m_fd = -1;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
@ -41,133 +42,142 @@ CUdpSocket::CUdpSocket()
CUdpSocket::~CUdpSocket() CUdpSocket::~CUdpSocket()
{ {
if ( m_Socket != -1 ) Close();
{
Close();
}
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// open & close // open & close
bool CUdpSocket::Open(uint16 uiPort) // returns true on error
bool CUdpSocket::Open(const CIp &Ip)
{ {
bool open = false; // check for a vaild family
if (AF_UNSPEC == Ip.GetFamily())
// create socket return true;
m_Socket = socket(PF_INET,SOCK_DGRAM,0);
if ( m_Socket != -1 ) // create socket
{ m_fd = socket(Ip.GetFamily(), SOCK_DGRAM, 0);
// initialize sockaddr struct if ( m_fd < 0 )
::memset(&m_SocketAddr, 0, sizeof(struct sockaddr_in)); {
m_SocketAddr.sin_family = AF_INET; std::cerr << "Unable to open socket on " << Ip << ", " << strerror(errno) << std::endl;
m_SocketAddr.sin_port = htons(uiPort); return false;
m_SocketAddr.sin_addr.s_addr = inet_addr(g_Reflector.GetListenIp()); }
// initialize sockaddr struct
if ( bind(m_Socket, (struct sockaddr *)&m_SocketAddr, sizeof(struct sockaddr_in)) == 0 ) m_addr = Ip;
{
fcntl(m_Socket, F_SETFL, O_NONBLOCK); int reuse = 1;
open = true; if ( 0 > setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)))
} {
else std::cerr << "Cannot set the UDP socket option on " << m_addr << ", " << strerror(errno) << std::endl;
{ Close();
close(m_Socket); return false;
m_Socket = -1; }
}
} if (fcntl(m_fd, F_SETFL, O_NONBLOCK))
{
// done std::cerr << "fcntl set non-blocking failed on " << m_addr << ", " << strerror(errno) << std::endl;
return open; 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) void CUdpSocket::Close(void)
{ {
if ( m_Socket != -1 ) if ( m_fd >= 0 )
{ {
close(m_Socket); close(m_fd);
m_Socket = -1; m_fd = -1;
} }
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// read // read
int CUdpSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout) bool CUdpSocket::Receive(CBuffer &Buffer, CIp &Ip, int timeout)
{ {
struct sockaddr_in Sin; // socket valid ?
fd_set FdSet; if ( 0 > m_fd )
unsigned int uiFromLen = sizeof(struct sockaddr_in); return false;
int iRecvLen = -1;
struct timeval tv; // control socket
fd_set FdSet;
// socket valid ? FD_ZERO(&FdSet);
if ( m_Socket != -1 ) FD_SET(m_fd, &FdSet);
{ struct timeval tv;
// control socket tv.tv_sec = timeout / 1000;
FD_ZERO(&FdSet); tv.tv_usec = (timeout % 1000) * 1000;
FD_SET(m_Socket, &FdSet); auto rval = select(m_fd + 1, &FdSet, 0, 0, &tv);
tv.tv_sec = timeout / 1000; if (0 > rval)
tv.tv_usec = (timeout % 1000) * 1000; {
select(m_Socket + 1, &FdSet, 0, 0, &tv); std::cerr << "select error on UPD port " << m_addr << ": " << strerror(errno) << std::endl;
return false;
// allocate buffer }
Buffer->resize(UDP_BUFFER_LENMAX); else if (0 == rval)
return false;
// read
iRecvLen = (int)recvfrom(m_Socket, // read
(void *)Buffer->data(), UDP_BUFFER_LENMAX, uint8_t buf[UDP_BUFFER_LENMAX];
0, (struct sockaddr *)&Sin, &uiFromLen); unsigned int fromsize = sizeof(struct sockaddr_storage);
auto iRecvLen = recvfrom(m_fd, buf, UDP_BUFFER_LENMAX, 0, Ip.GetPointer(), &fromsize);
// handle
if ( iRecvLen != -1 ) // handle
{ if (0 >= iRecvLen)
// adjust buffer size return false;
Buffer->resize(iRecvLen);
Buffer.Set(buf, iRecvLen);
// get IP
Ip->SetSockAddr(&Sin); // done
} return true;
}
// done
return iRecvLen;
} }
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// write // write
int CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip) void CUdpSocket::Send(const CBuffer &Buffer, const CIp &Ip) const
{ {
CIp temp(Ip); sendto(m_fd, Buffer.data(), Buffer.size(), 0, Ip.GetCPointer(), Ip.GetSize());
return (int)::sendto(m_Socket,
(void *)Buffer.data(), Buffer.size(),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
} }
int CUdpSocket::Send(const char *Buffer, const CIp &Ip) void CUdpSocket::Send(const char *Buffer, const CIp &Ip) const
{ {
CIp temp(Ip); sendto(m_fd, Buffer, ::strlen(Buffer), 0, Ip.GetCPointer(), Ip.GetSize());
return (int)::sendto(m_Socket,
(void *)Buffer, ::strlen(Buffer),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
} }
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); CIp temp(Ip);
temp.GetSockAddr()->sin_port = htons(destport); temp.SetPort(destport);
return (int)::sendto(m_Socket, sendto(m_fd, Buffer.data(), Buffer.size(), 0, temp.GetCPointer(), temp.GetSize());
(void *)Buffer.data(), Buffer.size(),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
} }
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); CIp temp(Ip);
temp.GetSockAddr()->sin_port = htons(destport); temp.SetPort(destport);
return (int)::sendto(m_Socket, sendto(m_fd, Buffer, ::strlen(Buffer), 0, temp.GetCPointer(), temp.GetSize());
(void *)Buffer, ::strlen(Buffer),
0, (struct sockaddr *)temp.GetSockAddr(), sizeof(struct sockaddr_in));
} }

@ -4,6 +4,7 @@
// //
// Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015. // Created by Jean-Luc Deltombe (LX3JL) on 31/10/2015.
// Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved. // Copyright © 2015 Jean-Luc Deltombe (LX3JL). All rights reserved.
// Copyright © 2020 Thomas A. Early, N7TAE
// //
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// This file is part of xlxd. // This file is part of xlxd.
@ -19,14 +20,14 @@
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Foobar. If not, see <http://www.gnu.org/licenses/>. // along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#ifndef cudpsocket_h #ifndef cudpsocket_h
#define cudpsocket_h #define cudpsocket_h
#include <cstdint>
#include <sys/types.h> #include <sys/types.h>
//#include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/socket.h> #include <sys/socket.h>
@ -48,30 +49,33 @@
class CUdpSocket class CUdpSocket
{ {
public: public:
// constructor // constructor
CUdpSocket(); CUdpSocket();
// destructor // destructor
~CUdpSocket(); ~CUdpSocket();
// open & close // open & close
bool Open(uint16); bool Open(const CIp &Ip);
void Close(void); void Close(void);
int GetSocket(void) { return m_Socket; } int GetSocket(void)
{
// read return m_fd;
int Receive(CBuffer *, CIp *, int); }
// write // read
int Send(const CBuffer &, const CIp &); bool Receive(CBuffer &, CIp &, int);
int Send(const CBuffer &, const CIp &, uint16);
int Send(const char *, const CIp &); // write
int Send(const char *, const CIp &, uint16); 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: protected:
// data // data
int m_Socket; int m_fd;
struct sockaddr_in m_SocketAddr; CIp m_addr;
}; };
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////

@ -75,7 +75,7 @@ void CXlxProtocol::Task(void)
CDvLastFramePacket *LastFrame; CDvLastFramePacket *LastFrame;
// any incoming packet ? // any incoming packet ?
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
// crack the packet // crack the packet
if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )

@ -111,7 +111,7 @@ void CYsfProtocol::Task(void)
} }
// handle incoming packets // handle incoming packets
if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 ) if ( m_Socket.Receive(Buffer, Ip, 20) )
{ {
// crack the packet // crack the packet
if ( IsValidDvPacket(Buffer, &Fich) ) if ( IsValidDvPacket(Buffer, &Fich) )

Loading…
Cancel
Save

Powered by TurnKey Linux.