new CIp & CUdpSocket

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

@ -159,7 +159,7 @@ void CCodecStream::Task(void)
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) )

@ -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) )

@ -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 )

@ -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

@ -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) )

@ -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 )

@ -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;

@ -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 <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#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 <cstdint>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
////////////////////////////////////////////////////////////////////////////////////////
// constructors
#include "cip.h"
CIp::CIp()
{
::memset(&m_Addr, 0, sizeof(m_Addr));
m_Addr.sin_family = AF_INET;
Clear();
}
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)
{
Initialize(family, port, address);
}
void CIp::Initialize(const int family, const uint16_t port, const char *address)
{
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;
}
bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addresses and families
{
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;
}
CIp::CIp(const char *sz)
bool CIp::AddressIsZero() const
{
::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;
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;
}
}
CIp::CIp(const 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
{
if (straddr[0])
return straddr;
CIp::CIp(const CIp &ip)
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;
}
std::ostream &operator<<(std::ostream &stream, const CIp &Ip)
{
::memcpy(&m_Addr, &ip.m_Addr, sizeof(m_Addr));
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;
}
////////////////////////////////////////////////////////////////////////////////////////
// set
uint32_t CIp::GetAddr() const
{
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;
}
}
void CIp::SetSockAddr(struct sockaddr_in *sa)
int CIp::GetFamily() const
{
::memcpy(&m_Addr, sa, sizeof(m_Addr));
return addr.ss_family;
}
////////////////////////////////////////////////////////////////////////////////////////
// operator
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);
}
}
bool CIp::operator ==(const CIp &ip) const
struct sockaddr *CIp::GetPointer()
{
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)) ;
memset(straddr, 0, INET6_ADDRSTRLEN); // things might change
return (struct sockaddr *)&addr;
}
CIp::operator const char *() const
const struct sockaddr *CIp::GetCPointer() const
{
return ::inet_ntoa(m_Addr.sin_addr);
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 @@
//
// 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 <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#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 <iostream>
#include <cstring>
#include <chrono>
#include <thread>
#include <strings.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
class CIp
{
public:
// constructors
CIp();
//CIp(uint8, uint8, uint8, uint8);
CIp(const struct sockaddr_in *);
CIp(const char *);
CIp(const 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;
// destructor
virtual ~CIp() {};
// 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;
// sockaddr
void SetSockAddr(struct sockaddr_in *);
struct sockaddr_in *GetSockAddr(void) { return &m_Addr; }
// modifiers
void SetPort(const uint16_t newport);
// convertor
uint32 GetAddr(void) const { return m_Addr.sin_addr.s_addr; }
uint16 GetPort(void) const { return m_Addr.sin_port; }
// for i/o
struct sockaddr *GetPointer();
const struct sockaddr *GetCPointer() const;
// operator
bool operator ==(const CIp &) const;
operator const char *() const;
void Clear();
protected:
// data
struct sockaddr_in m_Addr;
private:
struct sockaddr_storage addr;
mutable char straddr[INET6_ADDRSTRLEN];
};
////////////////////////////////////////////////////////////////////////////////////////
#endif /* cip_h */
std::ostream &operator<<(std::ostream &stream, const CIp &Ip);

@ -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));
}
}

@ -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 )

@ -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();

@ -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,13 +80,13 @@ 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 )
@ -95,7 +95,8 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
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;
@ -113,4 +114,3 @@ int CUdpMsgSocket::Receive(CBuffer *Buffer, CIp *Ip, int timeout)
// done
return iRecvLen;
}

@ -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.
@ -22,8 +23,8 @@
// along with Foobar. If not, see <http://www.gnu.org/licenses/>.
// ----------------------------------------------------------------------------
#include "main.h"
#include <string.h>
#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();
}
}
////////////////////////////////////////////////////////////////////////////////////////
// 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())
return true;
// create socket
m_Socket = socket(PF_INET,SOCK_DGRAM,0);
if ( m_Socket != -1 )
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
::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());
m_addr = Ip;
if ( bind(m_Socket, (struct sockaddr *)&m_SocketAddr, sizeof(struct sockaddr_in)) == 0 )
int reuse = 1;
if ( 0 > setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int)))
{
fcntl(m_Socket, F_SETFL, O_NONBLOCK);
open = true;
std::cerr << "Cannot set the UDP socket option on " << m_addr << ", " << strerror(errno) << std::endl;
Close();
return false;
}
else
if (fcntl(m_fd, F_SETFL, O_NONBLOCK))
{
close(m_Socket);
m_Socket = -1;
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 open;
return true;
}
void CUdpSocket::Close(void)
{
if ( m_Socket != -1 )
if ( m_fd >= 0 )
{
close(m_Socket);
m_Socket = -1;
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 )
{
if ( 0 > m_fd )
return false;
// control socket
fd_set FdSet;
FD_ZERO(&FdSet);
FD_SET(m_Socket, &FdSet);
FD_SET(m_fd, &FdSet);
struct timeval tv;
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);
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
iRecvLen = (int)recvfrom(m_Socket,
(void *)Buffer->data(), UDP_BUFFER_LENMAX,
0, (struct sockaddr *)&Sin, &uiFromLen);
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 ( iRecvLen != -1 )
{
// adjust buffer size
Buffer->resize(iRecvLen);
if (0 >= iRecvLen)
return false;
// get IP
Ip->SetSockAddr(&Sin);
}
}
Buffer.Set(buf, iRecvLen);
// done
return iRecvLen;
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));
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));
temp.SetPort(destport);
sendto(m_fd, Buffer, ::strlen(Buffer), 0, temp.GetCPointer(), temp.GetSize());
}

@ -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.
@ -25,8 +26,8 @@
#ifndef cudpsocket_h
#define cudpsocket_h
#include <cstdint>
#include <sys/types.h>
//#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
@ -55,23 +56,26 @@ public:
~CUdpSocket();
// open & close
bool Open(uint16);
bool Open(const CIp &Ip);
void Close(void);
int GetSocket(void) { return m_Socket; }
int GetSocket(void)
{
return m_fd;
}
// read
int Receive(CBuffer *, CIp *, int);
bool 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);
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;
int m_fd;
CIp m_addr;
};
////////////////////////////////////////////////////////////////////////////////////////

@ -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 )

@ -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) )

Loading…
Cancel
Save

Powered by TurnKey Linux.