diff --git a/src/ccodecstream.cpp b/src/ccodecstream.cpp index 2a6e1dc..cd4c224 100644 --- a/src/ccodecstream.cpp +++ b/src/ccodecstream.cpp @@ -89,31 +89,32 @@ CCodecStream::~CCodecStream() bool CCodecStream::Init(uint16 uiPort) { - bool ok; - // reset stop flag - m_bStopThread = false; + m_bConnected = m_bStopThread = false; // create server's IP - m_Ip = g_Reflector.GetTranscoderIp(); m_uiPort = uiPort; + auto s = g_Reflector.GetTranscoderIp(); + m_Ip.Initialize(strchr(s, ':') ? AF_INET6 : AF_INET, m_uiPort, s); // create our socket - ok = m_Socket.Open(uiPort); - if ( ok ) - { - // start thread; - m_pThread = new std::thread(CCodecStream::Thread, this); - m_bConnected = true; - } - else - { - std::cout << "Error opening socket on port UDP" << uiPort << " on ip " << g_Reflector.GetListenIp() << std::endl; - m_bConnected = false; - } - - // done - return ok; + if (m_Ip.IsSet()) + { + if (! m_Socket.Open(m_Ip)) { + std::cerr << "Error opening socket on port UDP" << uiPort << " on ip " << m_Ip << std::endl; + return false; + } + } + else + { + std::cerr << "Could not initialize Codec Stream on " << m_Ip << std::endl; + return false; + } + + m_pThread = new std::thread(CCodecStream::Thread, this); + m_bConnected = true; + + return true; } void CCodecStream::Close(void) diff --git a/src/cdcsprotocol.cpp b/src/cdcsprotocol.cpp index 536e0a2..b275a83 100644 --- a/src/cdcsprotocol.cpp +++ b/src/cdcsprotocol.cpp @@ -35,26 +35,15 @@ bool CDcsProtocol::Init(void) { - bool ok; - // base class - ok = CProtocol::Init(); - - // update the reflector callsign - m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DCS", 3); - - // create our socket - ok &= m_Socket.Open(DCS_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << DCS_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } + if (! Initialize("DCS", DCS_PORT)) + return false; // update time m_LastKeepaliveTime.Now(); // done - return ok; + return true; } @@ -72,7 +61,7 @@ void CDcsProtocol::Task(void) CDvFramePacket *Frame; // handle incoming packets - if ( m_Socket.Receive(Buffer, Ip, 20) ) + if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) { // crack the packet if ( IsValidDvPacket(Buffer, &Header, &Frame) ) @@ -114,7 +103,7 @@ void CDcsProtocol::Task(void) { // acknowledge the request EncodeConnectAckPacket(Callsign, ToLinkModule, &Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); // create the client CDcsClient *client = new CDcsClient(Callsign, Ip, ToLinkModule); @@ -129,14 +118,14 @@ void CDcsProtocol::Task(void) // deny the request EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } else { // deny the request EncodeConnectNackPacket(Callsign, ToLinkModule, &Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } @@ -153,7 +142,7 @@ void CDcsProtocol::Task(void) clients->RemoveClient(client); // and acknowledge the disconnect EncodeConnectNackPacket(Callsign, ' ', &Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } g_Reflector.ReleaseClients(); } @@ -310,7 +299,7 @@ void CDcsProtocol::HandleQueue(void) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) { // no, send the packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } @@ -346,8 +335,8 @@ void CDcsProtocol::HandleKeepalives(void) EncodeKeepAlivePacket(&keepalive2, client); // send keepalive - m_Socket.Send(keepalive1, client->GetIp()); - m_Socket.Send(keepalive2, client->GetIp()); + Send(keepalive1, client->GetIp()); + Send(keepalive2, client->GetIp()); // is this client busy ? if ( client->IsAMaster() ) @@ -361,7 +350,7 @@ void CDcsProtocol::HandleKeepalives(void) // no, disconnect CBuffer disconnect; EncodeDisconnectPacket(&disconnect, client); - m_Socket.Send(disconnect, client->GetIp()); + Send(disconnect, client->GetIp()); // remove it std::cout << "DCS client " << client->GetCallsign() << " keepalive timeout" << std::endl; diff --git a/src/cdcsprotocol.h b/src/cdcsprotocol.h index b455dc2..36501ff 100644 --- a/src/cdcsprotocol.h +++ b/src/cdcsprotocol.h @@ -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 . // ---------------------------------------------------------------------------- #ifndef cdcsprotocol_h @@ -42,7 +42,7 @@ class CDcsStreamCacheItem public: CDcsStreamCacheItem() { m_iSeqCounter = 0; } ~CDcsStreamCacheItem() {} - + CDvHeaderPacket m_dvHeader; uint32 m_iSeqCounter; }; @@ -50,35 +50,29 @@ public: class CDcsProtocol : public CProtocol { public: - // constructor - CDcsProtocol() {}; - - // destructor - virtual ~CDcsProtocol() {}; - // initialization bool Init(void); - + // task void Task(void); - + protected: // queue helper void HandleQueue(void); - + // keepalive helpers void HandleKeepalives(void); - + // stream helpers bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &); - + // packet decoding helpers bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *); bool IsValidDisconnectPacket(const CBuffer &, CCallsign *); bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *); bool IsValidDvPacket(const CBuffer &, CDvHeaderPacket **, CDvFramePacket **); bool IsIgnorePacket(const CBuffer &); - + // packet encoding helpers void EncodeKeepAlivePacket(CBuffer *); void EncodeKeepAlivePacket(CBuffer *, CClient *); @@ -87,11 +81,11 @@ protected: void EncodeDisconnectPacket(CBuffer *, CClient *); void EncodeDvPacket(const CDvHeaderPacket &, const CDvFramePacket &, uint32, CBuffer *) const; void EncodeDvLastPacket(const CDvHeaderPacket &, const CDvFramePacket &, uint32, CBuffer *) const; - + protected: // for keep alive CTimePoint m_LastKeepaliveTime; - + // for queue header caches std::array m_StreamsCache; }; diff --git a/src/cdextraprotocol.cpp b/src/cdextraprotocol.cpp index 568f7cb..07bf6d6 100644 --- a/src/cdextraprotocol.cpp +++ b/src/cdextraprotocol.cpp @@ -37,27 +37,16 @@ bool CDextraProtocol::Init(void) { - bool ok; - // base class - ok = CProtocol::Init(); - - // update the reflector callsign - m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XRF", 3); - - // create our socket - ok &= m_Socket.Open(DEXTRA_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << DEXTRA_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } + if (! Initialize("XRF", DEXTRA_PORT)) + return false; // update time m_LastKeepaliveTime.Now(); m_LastPeersLinkTime.Now(); // done - return ok; + return true; } //////////////////////////////////////////////////////////////////////////////////////// @@ -75,7 +64,7 @@ void CDextraProtocol::Task(void) CDvLastFramePacket *LastFrame; // any incoming packet ? - if ( m_Socket.Receive(Buffer, Ip, 20) ) + if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) { // crack the packet if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) @@ -143,7 +132,7 @@ void CDextraProtocol::Task(void) { // acknowledge the request EncodeConnectAckPacket(&Buffer, ProtRev); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); // create the client CDextraClient *client = new CDextraClient(Callsign, Ip, ToLinkModule, ProtRev); @@ -160,14 +149,14 @@ void CDextraProtocol::Task(void) // deny the request EncodeConnectNackPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } else { // deny the request EncodeConnectNackPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } else if ( IsValidDisconnectPacket(Buffer, &Callsign) ) @@ -183,11 +172,11 @@ void CDextraProtocol::Task(void) if ( client->GetProtocolRevision() == 1 ) { EncodeDisconnectedPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } else if ( client->GetProtocolRevision() == 2 ) { - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } // and remove it clients->RemoveClient(client); @@ -271,7 +260,7 @@ void CDextraProtocol::HandleQueue(void) int n = packet->IsDvHeader() ? 5 : 1; for ( int i = 0; i < n; i++ ) { - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } } @@ -303,7 +292,7 @@ void CDextraProtocol::HandleKeepalives(void) while ( (client = clients->FindNextClient(PROTOCOL_DEXTRA, it)) != NULL ) { // send keepalive - m_Socket.Send(keepalive, client->GetIp()); + Send(keepalive, client->GetIp()); // client busy ? if ( client->IsAMaster() ) @@ -325,7 +314,7 @@ void CDextraProtocol::HandleKeepalives(void) // no, disconnect CBuffer disconnect; EncodeDisconnectPacket(&disconnect, client->GetReflectorModule()); - m_Socket.Send(disconnect, client->GetIp()); + Send(disconnect, client->GetIp()); // remove it std::cout << "DExtra client " << client->GetCallsign() << " keepalive timeout" << std::endl; @@ -354,7 +343,7 @@ void CDextraProtocol::HandleKeepalives(void) CClients *clients = g_Reflector.GetClients(); for ( auto cit=peer->cbegin(); cit!=peer->cend(); cit++ ) { - m_Socket.Send(disconnect, (*cit)->GetIp()); + Send(disconnect, (*cit)->GetIp()); } g_Reflector.ReleaseClients(); @@ -387,7 +376,7 @@ void CDextraProtocol::HandlePeerLinks(void) { // send disconnect packet EncodeDisconnectPacket(&buffer, peer->GetReflectorModules()[0]); - m_Socket.Send(buffer, peer->GetIp()); + Send(buffer, peer->GetIp()); std::cout << "Sending disconnect packet to XRF peer " << peer->GetCallsign() << std::endl; // remove client peers->RemovePeer(peer); @@ -408,7 +397,7 @@ void CDextraProtocol::HandlePeerLinks(void) (*it).ResolveIp(); // send connect packet to re-initiate peer link EncodeConnectPacket(&buffer, (*it).GetModules()); - m_Socket.Send(buffer, (*it).GetIp(), DEXTRA_PORT); + Send(buffer, (*it).GetIp(), DEXTRA_PORT); std::cout << "Sending connect packet to XRF peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for module " << (*it).GetModules()[1] << " (module " << (*it).GetModules()[0] << ")" << std::endl; } } diff --git a/src/cdextraprotocol.h b/src/cdextraprotocol.h index 4512295..ab4889f 100644 --- a/src/cdextraprotocol.h +++ b/src/cdextraprotocol.h @@ -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 . // ---------------------------------------------------------------------------- #ifndef cdextraprotocol_h @@ -58,15 +58,9 @@ class CDextraProtocol : public CProtocol { public: - // constructor - CDextraProtocol() {}; - - // destructor - virtual ~CDextraProtocol() {}; - // initialization bool Init(void); - + // task void Task(void); @@ -80,7 +74,7 @@ protected: // stream helpers bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &); - + // packet decoding helpers bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, int *); bool IsValidDisconnectPacket(const CBuffer &, CCallsign *); @@ -88,7 +82,7 @@ protected: CDvHeaderPacket *IsValidDvHeaderPacket(const CBuffer &); CDvFramePacket *IsValidDvFramePacket(const CBuffer &); CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &); - + // packet encoding helpers void EncodeKeepAlivePacket(CBuffer *); void EncodeConnectPacket(CBuffer *, const char *); @@ -99,7 +93,7 @@ protected: bool EncodeDvHeaderPacket(const CDvHeaderPacket &, CBuffer *) const; bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const; - + protected: // time CTimePoint m_LastKeepaliveTime; diff --git a/src/cdmrmmdvmprotocol.cpp b/src/cdmrmmdvmprotocol.cpp index 8e05bb2..4bb646d 100644 --- a/src/cdmrmmdvmprotocol.cpp +++ b/src/cdmrmmdvmprotocol.cpp @@ -56,16 +56,9 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 }; bool CDmrmmdvmProtocol::Init(void) { - bool ok; - // base class - ok = CProtocol::Init(); - - // update the reflector callsign - //m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3); - - // create our socket - ok &= m_Socket.Open(DMRMMDVM_PORT); + if (! Initialize(NULL, DMRMMDVM_PORT)) + return false; // update time m_LastKeepaliveTime.Now(); @@ -76,7 +69,7 @@ bool CDmrmmdvmProtocol::Init(void) m_uiAuthSeed = (uint32)rand(); // done - return ok; + return true; } @@ -97,7 +90,7 @@ void CDmrmmdvmProtocol::Task(void) CDvLastFramePacket *LastFrame; // handle incoming packets - if ( m_Socket.Receive(Buffer, Ip, 20) ) + if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket6.Receive(Buffer, Ip, 10) ) { //Buffer.DebugDump(g_Reflector.m_DebugFile); // crack the packet @@ -141,13 +134,13 @@ void CDmrmmdvmProtocol::Task(void) { // acknowledge the request EncodeConnectAckPacket(&Buffer, Callsign, m_uiAuthSeed); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } else { // deny the request EncodeNackPacket(&Buffer, Callsign); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } @@ -160,7 +153,7 @@ void CDmrmmdvmProtocol::Task(void) { // acknowledge the request EncodeAckPacket(&Buffer, Callsign); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); // add client if needed CClients *clients = g_Reflector.GetClients(); @@ -187,7 +180,7 @@ void CDmrmmdvmProtocol::Task(void) { // deny the request EncodeNackPacket(&Buffer, Callsign); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } @@ -210,7 +203,7 @@ void CDmrmmdvmProtocol::Task(void) // acknowledge the request EncodeAckPacket(&Buffer, Callsign); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } else if ( IsValidKeepAlivePacket(Buffer, &Callsign) ) { @@ -224,7 +217,7 @@ void CDmrmmdvmProtocol::Task(void) { // acknowledge EncodeKeepAlivePacket(&Buffer, client); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); // and mark as alive client->Alive(); @@ -243,7 +236,7 @@ void CDmrmmdvmProtocol::Task(void) // acknowledge the request EncodeAckPacket(&Buffer, Callsign); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } else if ( Buffer.size() != 55 ) { @@ -450,7 +443,7 @@ void CDmrmmdvmProtocol::HandleQueue(void) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) { // no, send the packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } @@ -489,7 +482,7 @@ void CDmrmmdvmProtocol::HandleKeepalives(void) { // no, disconnect CBuffer disconnect; - m_Socket.Send(disconnect, client->GetIp()); + Send(disconnect, client->GetIp()); // remove it std::cout << "DMRmmdvm client " << client->GetCallsign() << " keepalive timeout" << std::endl; diff --git a/src/cdmrmmdvmprotocol.h b/src/cdmrmmdvmprotocol.h index 54e34b6..0155b9a 100644 --- a/src/cdmrmmdvmprotocol.h +++ b/src/cdmrmmdvmprotocol.h @@ -54,11 +54,11 @@ class CDmrmmdvmStreamCacheItem public: CDmrmmdvmStreamCacheItem() {} ~CDmrmmdvmStreamCacheItem() {} - + CDvHeaderPacket m_dvHeader; CDvFramePacket m_dvFrame0; CDvFramePacket m_dvFrame1; - + uint8 m_uiSeqId; }; @@ -66,28 +66,22 @@ public: class CDmrmmdvmProtocol : public CProtocol { public: - // constructor - CDmrmmdvmProtocol() {}; - - // destructor - virtual ~CDmrmmdvmProtocol() {}; - // initialization bool Init(void); - + // task void Task(void); - + protected: // queue helper void HandleQueue(void); - + // keepalive helpers void HandleKeepalives(void); - + // stream helpers bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &, uint8, uint8); - + // packet decoding helpers bool IsValidConnectPacket(const CBuffer &, CCallsign *, const CIp &); bool IsValidAuthenticationPacket(const CBuffer &, CCallsign *, const CIp &); @@ -99,7 +93,7 @@ protected: bool IsValidDvHeaderPacket(const CBuffer &, CDvHeaderPacket **, uint8 *, uint8 *); bool IsValidDvFramePacket(const CBuffer &, CDvFramePacket **); bool IsValidDvLastFramePacket(const CBuffer &, CDvLastFramePacket **); - + // packet encoding helpers void EncodeKeepAlivePacket(CBuffer *, CClient *); void EncodeAckPacket(CBuffer *, const CCallsign &); @@ -109,11 +103,11 @@ protected: bool EncodeDvHeaderPacket(const CDvHeaderPacket &, uint8, CBuffer *) const; void EncodeDvPacket(const CDvHeaderPacket &, const CDvFramePacket &, const CDvFramePacket &, const CDvFramePacket &, uint8, CBuffer *) const; void EncodeDvLastPacket(const CDvHeaderPacket &, uint8, CBuffer *) const; - + // dmr DstId to Module helper char DmrDstIdToModule(uint32) const; uint32 ModuleToDmrDestId(char) const; - + // Buffer & LC helpers void AppendVoiceLCToBuffer(CBuffer *, uint32) const; void AppendTerminatorLCToBuffer(CBuffer *, uint32) const; @@ -125,13 +119,13 @@ protected: protected: // for keep alive CTimePoint m_LastKeepaliveTime; - + // for stream id uint16 m_uiStreamId; - + // for queue header caches std::array m_StreamsCache; - + // for authentication uint32 m_uiAuthSeed; }; diff --git a/src/cdmrplusprotocol.cpp b/src/cdmrplusprotocol.cpp index 2323732..c0a246f 100644 --- a/src/cdmrplusprotocol.cpp +++ b/src/cdmrplusprotocol.cpp @@ -47,18 +47,11 @@ static uint8 g_DmrSyncMSData[] = { 0x0D,0x5D,0x7F,0x77,0xFD,0x75,0x70 }; //////////////////////////////////////////////////////////////////////////////////////// // operation -bool CDmrplusProtocol::Init(void) +bool CDmrplusProtocol::Init() { - bool ok; - // base class - ok = CProtocol::Init(); - - // update the reflector callsign - //m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"DMR", 3); - - // create our socket - ok &= m_Socket.Open(DMRPLUS_PORT); + if (! Initialize(NULL, DMRPLUS_PORT)) + return false; // update time m_LastKeepaliveTime.Now(); @@ -68,7 +61,7 @@ bool CDmrplusProtocol::Init(void) ::srand((unsigned) time(&t)); // done - return ok; + return true; } @@ -86,7 +79,7 @@ void CDmrplusProtocol::Task(void) CDvFramePacket *Frames[3]; // handle incoming packets - if ( m_Socket.Receive(Buffer, Ip, 20) ) + if ( m_Socket6.Receive(Buffer, Ip, 10) && m_Socket4.Receive(Buffer, Ip, 10) ) { // crack the packet if ( IsValidDvFramePacket(Ip, Buffer, Frames) ) @@ -135,7 +128,7 @@ void CDmrplusProtocol::Task(void) { // acknowledge the request EncodeConnectAckPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); // add client if needed CClients *clients = g_Reflector.GetClients(); @@ -162,7 +155,7 @@ void CDmrplusProtocol::Task(void) { // deny the request EncodeConnectNackPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } @@ -324,7 +317,7 @@ void CDmrplusProtocol::HandleQueue(void) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) { // no, send the packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } g_Reflector.ReleaseClients(); @@ -353,7 +346,7 @@ void CDmrplusProtocol::SendBufferToClients(const CBuffer &buffer, uint8 module) if ( !client->IsAMaster() && (client->GetReflectorModule() == module) ) { // no, send the packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } g_Reflector.ReleaseClients(); @@ -391,7 +384,7 @@ void CDmrplusProtocol::HandleKeepalives(void) // no, disconnect //CBuffer disconnect; //EncodeDisconnectPacket(&disconnect, client); - //m_Socket.Send(disconnect, client->GetIp()); + //Send(disconnect, client->GetIp()); // remove it std::cout << "DMRplus client " << client->GetCallsign() << " keepalive timeout" << std::endl; diff --git a/src/cdmrplusprotocol.h b/src/cdmrplusprotocol.h index e9d4c1e..5c02ba0 100644 --- a/src/cdmrplusprotocol.h +++ b/src/cdmrplusprotocol.h @@ -44,12 +44,11 @@ class CDmrplusStreamCacheItem { public: CDmrplusStreamCacheItem() { m_uiSeqId = 0x77; } - ~CDmrplusStreamCacheItem() {} - + CDvHeaderPacket m_dvHeader; CDvFramePacket m_dvFrame0; CDvFramePacket m_dvFrame1; - + uint8 m_uiSeqId; }; @@ -57,35 +56,29 @@ public: class CDmrplusProtocol : public CProtocol { public: - // constructor - CDmrplusProtocol() {}; - - // destructor - virtual ~CDmrplusProtocol() {}; - // initialization - bool Init(void); - + bool Init(); + // task void Task(void); - + protected: // queue helper void HandleQueue(void); void SendBufferToClients(const CBuffer &, uint8); - + // keepalive helpers void HandleKeepalives(void); - + // stream helpers bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &); - + // packet decoding helpers bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, const CIp &); bool IsValidDisconnectPacket(const CBuffer &, CCallsign *, char *); bool IsValidDvHeaderPacket(const CIp &, const CBuffer &, CDvHeaderPacket **); bool IsValidDvFramePacket(const CIp &, const CBuffer &, CDvFramePacket **); - + // packet encoding helpers void EncodeConnectAckPacket(CBuffer *); void EncodeConnectNackPacket(CBuffer *); @@ -93,27 +86,27 @@ protected: void EncodeDvPacket(const CDvHeaderPacket &, const CDvFramePacket &, const CDvFramePacket &, const CDvFramePacket &, uint8, CBuffer *) const; void EncodeDvLastPacket(const CDvHeaderPacket &, const CDvFramePacket &, const CDvFramePacket &, const CDvFramePacket &, uint8, CBuffer *) const; void SwapEndianess(uint8 *, int) const; - + // dmr SeqId helper uint8 GetNextSeqId(uint8) const; - + // dmr DstId to Module helper char DmrDstIdToModule(uint32) const; uint32 ModuleToDmrDestId(char) const; - + // uiStreamId helpers uint32 IpToStreamId(const CIp &) const; - + // Buffer & LC helpers void AppendVoiceLCToBuffer(CBuffer *, uint32) const; void AppendTerminatorLCToBuffer(CBuffer *, uint32) const; void ReplaceEMBInBuffer(CBuffer *, uint8) const; - + protected: // for keep alive CTimePoint m_LastKeepaliveTime; - + // for queue header caches std::array m_StreamsCache; }; diff --git a/src/cdplusprotocol.cpp b/src/cdplusprotocol.cpp index 7d59c41..7cafc3c 100644 --- a/src/cdplusprotocol.cpp +++ b/src/cdplusprotocol.cpp @@ -36,26 +36,15 @@ bool CDplusProtocol::Init(void) { - bool ok; - // base class - ok = CProtocol::Init(); - - // update the reflector callsign - m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"REF", 3); - - // create our socket - ok &= m_Socket.Open(DPLUS_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << DPLUS_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } + if (Initialize("REF", DPLUS_PORT)) + return false; // update time m_LastKeepaliveTime.Now(); // done - return ok; + return true; } @@ -73,7 +62,7 @@ void CDplusProtocol::Task(void) CDvLastFramePacket *LastFrame; // handle incoming packets - if ( m_Socket.Receive(Buffer, Ip, 20) ) + if ( m_Socket6.Receive(Buffer, Ip, 10) && m_Socket4.Receive(Buffer, Ip, 10) ) { // crack the packet if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) @@ -110,7 +99,7 @@ void CDplusProtocol::Task(void) std::cout << "DPlus connect request packet from " << Ip << std::endl; // acknowledge the request - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } else if ( IsValidLoginPacket(Buffer, &Callsign) ) { @@ -121,7 +110,7 @@ void CDplusProtocol::Task(void) { // acknowledge the request EncodeLoginAckPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); // create the client CDplusClient *client = new CDplusClient(Callsign, Ip); @@ -134,7 +123,7 @@ void CDplusProtocol::Task(void) { // deny the request EncodeLoginNackPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } @@ -151,7 +140,7 @@ void CDplusProtocol::Task(void) clients->RemoveClient(client); // and acknowledge the disconnect EncodeDisconnectPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } g_Reflector.ReleaseClients(); } @@ -313,7 +302,7 @@ void CDplusProtocol::HandleQueue(void) else if ( packet->IsDvFrame() ) { // and send the DV frame - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); // is it time to insert a DVheader copy ? if ( (m_StreamsCache[iModId].m_iSeqCounter++ % 21) == 20 ) @@ -327,7 +316,7 @@ void CDplusProtocol::HandleQueue(void) else { // otherwise, send the original packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } } @@ -360,20 +349,20 @@ void CDplusProtocol::SendDvHeader(CDvHeaderPacket *packet, CDplusClient *client) if ( EncodeDvPacket(packet2, &buffer2) ) { // and send it - m_Socket.Send(buffer2, client->GetIp()); + Send(buffer2, client->GetIp()); } // client type known ? if ( !client->HasModule() ) { // no, send also the genuine packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } else { // otherwise, send the original packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } } @@ -395,7 +384,7 @@ void CDplusProtocol::HandleKeepalives(void) { // send keepalive //std::cout << "Sending DPlus packet @ " << client->GetIp() << std::endl; - m_Socket.Send(keepalive, client->GetIp()); + Send(keepalive, client->GetIp()); // is this client busy ? if ( client->IsAMaster() ) @@ -409,7 +398,7 @@ void CDplusProtocol::HandleKeepalives(void) // no, disconnect CBuffer disconnect; EncodeDisconnectPacket(&disconnect); - m_Socket.Send(disconnect, client->GetIp()); + Send(disconnect, client->GetIp()); // and remove it std::cout << "DPlus client " << client->GetCallsign() << " keepalive timeout" << std::endl; diff --git a/src/cdplusprotocol.h b/src/cdplusprotocol.h index 80bf1be..bdbf45f 100644 --- a/src/cdplusprotocol.h +++ b/src/cdplusprotocol.h @@ -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 . // ---------------------------------------------------------------------------- #ifndef cdplusprotocol_h @@ -43,8 +43,7 @@ class CDPlusStreamCacheItem { public: CDPlusStreamCacheItem() { m_iSeqCounter = 0; } - ~CDPlusStreamCacheItem() {} - + CDvHeaderPacket m_dvHeader; uint8 m_iSeqCounter; }; @@ -52,12 +51,6 @@ public: class CDplusProtocol : public CProtocol { public: - // constructor - CDplusProtocol() {}; - - // destructor - virtual ~CDplusProtocol() {}; - // initialization bool Init(void); @@ -68,13 +61,13 @@ protected: // queue helper void HandleQueue(void); void SendDvHeader(CDvHeaderPacket *, CDplusClient *); - + // keepalive helpers void HandleKeepalives(void); - + // stream helpers bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &); - + // packet decoding helpers bool IsValidConnectPacket(const CBuffer &); bool IsValidLoginPacket(const CBuffer &, CCallsign *); @@ -83,7 +76,7 @@ protected: CDvHeaderPacket *IsValidDvHeaderPacket(const CBuffer &); CDvFramePacket *IsValidDvFramePacket(const CBuffer &); CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &); - + // packet encoding helpers void EncodeKeepAlivePacket(CBuffer *); void EncodeLoginAckPacket(CBuffer *); @@ -93,11 +86,11 @@ protected: bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const; - + protected: // for keep alive CTimePoint m_LastKeepaliveTime; - + // for queue header caches std::array m_StreamsCache; }; diff --git a/src/cg3protocol.cpp b/src/cg3protocol.cpp index 6f75be3..68ef97f 100644 --- a/src/cg3protocol.cpp +++ b/src/cg3protocol.cpp @@ -40,55 +40,58 @@ bool CG3Protocol::Init(void) { - bool ok; - ReadOptions(); - // base class - ok = CProtocol::Init(); - - // update reflector callsign - m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3); - - // create our DV socket - ok &= m_Socket.Open(G3_DV_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << G3_DV_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } - - //create helper sockets - ok &= m_PresenceSocket.Open(G3_PRESENCE_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << G3_PRESENCE_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; + // init reflector apparent callsign + m_ReflectorCallsign = g_Reflector.GetCallsign(); + + // reset stop flag + m_bStopThread = false; + + // update the reflector callsign + m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3); + + // create our sockets + CIp ip(AF_INET, G3_DV_PORT, g_Reflector.GetListenIPv4()); + if ( ip.IsSet() ) + { + if (! m_Socket4.Open(ip)) + return false; + } + else + return false; + + //create helper socket + ip.SetPort(G3_PRESENCE_PORT); + if (! m_PresenceSocket.Open(ip)) { + std::cout << "Error opening socket on port UDP" << G3_PRESENCE_PORT << " on ip " << ip << std::endl; + return false; } - ok &= m_ConfigSocket.Open(G3_CONFIG_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << G3_CONFIG_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } + ip.SetPort(G3_CONFIG_PORT); + if (! m_ConfigSocket.Open(ip)) + { + std::cout << "Error opening G3 config socket on port UDP" << G3_CONFIG_PORT << " on ip " << ip << std::endl; + return false; + } - ok &= m_IcmpRawSocket.Open(IPPROTO_ICMP); - if ( !ok ) + if (! m_IcmpRawSocket.Open(IPPROTO_ICMP)) { std::cout << "Error opening raw socket for ICMP" << std::endl; + return false; } - if (ok) - { - // start helper threads - m_pPresenceThread = new std::thread(PresenceThread, this); - m_pPresenceThread = new std::thread(ConfigThread, this); - m_pPresenceThread = new std::thread(IcmpThread, this); - } + // start helper threads + m_pThread = new std::thread(CProtocol::Thread, this); + m_pPresenceThread = new std::thread(PresenceThread, this); + m_pPresenceThread = new std::thread(ConfigThread, this); + m_pPresenceThread = new std::thread(IcmpThread, this); // update time m_LastKeepaliveTime.Now(); // done - return ok; + return true; } void CG3Protocol::Close(void) @@ -390,7 +393,7 @@ void CG3Protocol::Task(void) CDvLastFramePacket *LastFrame; // any incoming packet ? - if ( m_Socket.Receive(Buffer, Ip, 20) != -1 ) + if ( m_Socket4.Receive(Buffer, Ip, 20) ) { CIp ClIp; CIp *BaseIp = NULL; @@ -508,7 +511,7 @@ void CG3Protocol::HandleQueue(void) int n = packet->IsDvHeader() ? 5 : 1; for ( int i = 0; i < n; i++ ) { - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } } @@ -544,7 +547,7 @@ void CG3Protocol::HandleKeepalives(void) else { // send keepalive packet - m_Socket.Send(keepalive, client->GetIp()); + Send(keepalive, client->GetIp()); } } g_Reflector.ReleaseClients(); diff --git a/src/cg3protocol.h b/src/cg3protocol.h index 5ffdb79..1ae056b 100644 --- a/src/cg3protocol.h +++ b/src/cg3protocol.h @@ -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 . // ---------------------------------------------------------------------------- #ifndef cg3protocol_h @@ -64,17 +64,14 @@ class CG3Protocol : public CProtocol { public: // constructor - CG3Protocol() : m_GwAddress(0u), m_Modules("*"), m_LastModTime(0) {}; - - // destructor - virtual ~CG3Protocol() {}; - + CG3Protocol() : m_GwAddress(0u), m_Modules("*"), m_LastModTime(0) {} + // initialization bool Init(void); // close void Close(void); - + // task void Task(void); diff --git a/src/cip.cpp b/src/cip.cpp index 3c5c2ae..7e17c4f 100644 --- a/src/cip.cpp +++ b/src/cip.cpp @@ -22,14 +22,19 @@ #include #include "cip.h" -CIp::CIp() +CIp::CIp() : is_set(false) { Clear(); } -CIp::CIp(const char *address, int family, int type, uint16_t port) +CIp::CIp(const char *address, int family, int type, uint16_t port) : is_set(true) { Clear(); + if (0 == strncasecmp(address, "none", 4)) + { + is_set = false; + return; + } struct addrinfo hints, *result; bzero(&hints, sizeof(struct addrinfo)); hints.ai_family = family; @@ -41,7 +46,7 @@ CIp::CIp(const char *address, int family, int type, uint16_t port) } SetPort(port); } -CIp::CIp(const int family, const uint16_t port, const char *address) +CIp::CIp(const int family, const uint16_t port, const char *address) : is_set(true) { Initialize(family, port, address); } @@ -49,50 +54,68 @@ CIp::CIp(const int family, const uint16_t port, const char *address) void CIp::Initialize(const int family, const uint16_t port, const char *address) { Clear(); + if (0 == strncasecmp(address, "none", 4)) + { + is_set = false; + return; + } + is_set = true; addr.ss_family = family; - if (AF_INET == family) { + if (AF_INET == family) + { auto addr4 = (struct sockaddr_in *)&addr; addr4->sin_port = htons(port); - if (address) { + 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 { + 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; + is_set = false; } } - } else if (AF_INET6 == family) { + } + else if (AF_INET6 == family) + { auto addr6 = (struct sockaddr_in6 *)&addr; addr6->sin6_port = htons(port); - if (address) { + 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 { + 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; + is_set = false; } } - } else + } + else + { std::cerr << "Error: Wrong address family type:" << family << " for [" << (address ? address : "NULL") << "]:" << port << std::endl; + is_set = 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 false; - if (AF_INET == addr.ss_family) { + 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) { + } + 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))); @@ -104,11 +127,14 @@ bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addres { if (addr.ss_family != rhs.addr.ss_family) return true; - if (AF_INET == addr.ss_family) { + 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) { + } + 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))); @@ -118,12 +144,16 @@ bool CIp::operator!=(const CIp &rhs) const // doesn't compare ports, only addres bool CIp::AddressIsZero() const { - if (AF_INET == addr.ss_family) { - auto addr4 = (struct sockaddr_in *)&addr; + if (AF_INET == addr.ss_family) + { + auto addr4 = (struct sockaddr_in *)&addr; return (addr4->sin_addr.s_addr == 0U); - } else { + } + else + { auto addr6 = (struct sockaddr_in6 *)&addr; - for (unsigned int i=0; i<16; i++) { + for (unsigned int i=0; i<16; i++) + { if (addr6->sin6_addr.s6_addr[i]) return false; } @@ -133,11 +163,14 @@ bool CIp::AddressIsZero() const void CIp::ClearAddress() { - if (AF_INET == addr.ss_family) { + 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 { + } + else + { auto addr6 = (struct sockaddr_in6 *)&addr; memset(&(addr6->sin6_addr.s6_addr), 0, 16); strcpy(straddr, "::"); @@ -149,13 +182,18 @@ const char *CIp::GetAddress() const if (straddr[0]) return straddr; - if (AF_INET == addr.ss_family) { + 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) { + } + else if (AF_INET6 == addr.ss_family) + { auto addr6 = (struct sockaddr_in6 *)&addr; inet_ntop(AF_INET6, &(addr6->sin6_addr), straddr, INET6_ADDRSTRLEN); - } else { + } + else + { std::cerr << "CIp::GetAddress: unknown socket family=" << addr.ss_family << std::endl; } return straddr; @@ -176,12 +214,15 @@ std::ostream &operator<<(std::ostream &stream, const CIp &Ip) uint32_t CIp::GetAddr() const { - if (AF_INET6 == addr.ss_family) { + 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 { + } + else + { auto addr4 = (struct sockaddr_in *)&addr; return addr4->sin_addr.s_addr; } @@ -194,10 +235,13 @@ int CIp::GetFamily() const uint16_t CIp::GetPort() const { - if (AF_INET == addr.ss_family) { + if (AF_INET == addr.ss_family) + { auto addr4 = (struct sockaddr_in *)&addr; return ntohs(addr4->sin_port); - } else if (AF_INET6 == addr.ss_family) { + } + else if (AF_INET6 == addr.ss_family) + { auto addr6 = (struct sockaddr_in6 *)&addr; return ntohs(addr6->sin6_port); } else @@ -206,10 +250,13 @@ uint16_t CIp::GetPort() const void CIp::SetPort(const uint16_t newport) { - if (AF_INET == addr.ss_family) { + if (AF_INET == addr.ss_family) + { auto addr4 = (struct sockaddr_in *)&addr; addr4->sin_port = htons(newport); - } else if (AF_INET6 == addr.ss_family) { + } + else if (AF_INET6 == addr.ss_family) + { auto addr6 = (struct sockaddr_in6 *)&addr; addr6->sin6_port = htons(newport); } @@ -238,4 +285,5 @@ void CIp::Clear() { memset(&addr, 0, sizeof(struct sockaddr_storage)); memset(straddr, 0, INET6_ADDRSTRLEN); + is_set = false; } diff --git a/src/cip.h b/src/cip.h index 78fc05d..ea969a2 100644 --- a/src/cip.h +++ b/src/cip.h @@ -46,6 +46,7 @@ public: bool operator!=(const CIp &rhs) const; // state methods + bool IsSet() const { return is_set; } bool AddressIsZero() const; void ClearAddress(); const char *GetAddress() const; @@ -68,6 +69,7 @@ public: private: struct sockaddr_storage addr; mutable char straddr[INET6_ADDRSTRLEN]; + bool is_set; }; std::ostream &operator<<(std::ostream &stream, const CIp &Ip); diff --git a/src/cprotocol.cpp b/src/cprotocol.cpp index 3904b07..968be53 100644 --- a/src/cprotocol.cpp +++ b/src/cprotocol.cpp @@ -33,11 +33,7 @@ // constructor -CProtocol::CProtocol() -{ - m_bStopThread = false; - m_pThread = NULL; -} +CProtocol::CProtocol() : m_bStopThread(false), m_pThread(NULL) {} //////////////////////////////////////////////////////////////////////////////////////// @@ -53,6 +49,10 @@ CProtocol::~CProtocol() delete m_pThread; } + // Close sockets + m_Socket6.Close(); + m_Socket4.Close(); + // empty queue m_Queue.Lock(); while ( !m_Queue.empty() ) @@ -65,7 +65,7 @@ CProtocol::~CProtocol() //////////////////////////////////////////////////////////////////////////////////////// // initialization -bool CProtocol::Init(void) +bool CProtocol::Initialize(const char *type, uint16 port) { // init reflector apparent callsign m_ReflectorCallsign = g_Reflector.GetCallsign(); @@ -73,13 +73,49 @@ bool CProtocol::Init(void) // reset stop flag m_bStopThread = false; + // update the reflector callsign + if (type) + m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)type, 3); + + // create our sockets + CIp ip4(AF_INET, port, g_Reflector.GetListenIPv4()); + if ( ip4.IsSet() ) + { + if (! m_Socket4.Open(ip4)) + return false; + } + CIp ip6(AF_INET6, port, g_Reflector.GetListenIPv6()); + if ( ip6.IsSet() ) + { + if (! m_Socket6.Open(ip6)) + { + m_Socket4.Close(); + return false; + } + } + // start thread; - m_pThread = new std::thread(CProtocol::Thread, this); + m_pThread = new std::thread(CProtocol::Thread, this); + if (m_pThread == NULL) + { + std::cerr << "Could not start DCS thread!" << std::endl; + m_Socket4.Close(); + m_Socket6.Close(); + return false; + } // done return true; } +void CProtocol::Thread(CProtocol *This) +{ + while (! This->m_bStopThread) + { + This->Task(); + } +} + void CProtocol::Close(void) { m_bStopThread = true; @@ -89,18 +125,8 @@ void CProtocol::Close(void) delete m_pThread; m_pThread = NULL; } -} - - -//////////////////////////////////////////////////////////////////////////////////////// -// thread - -void CProtocol::Thread(CProtocol *This) -{ - while ( !This->m_bStopThread ) - { - This->Task(); - } + m_Socket4.Close(); + m_Socket6.Close(); } //////////////////////////////////////////////////////////////////////////////////////// @@ -263,3 +289,66 @@ uint32 CProtocol::ModuleToDmrDestId(char m) const { return (uint32)(m - 'A')+1; } + +//////////////////////////////////////////////////////////////////////////////////////// +// dual stack senders + +void CProtocol::Send(const CBuffer &buf, const CIp &Ip) const +{ + switch (Ip.GetFamily()) { + case AF_INET: + m_Socket4.Send(buf, Ip); + break; + case AF_INET6: + m_Socket6.Send(buf, Ip); + break; + default: + std::cerr << "Wrong family: " << Ip.GetFamily() << std::endl; + break; + } +} + +void CProtocol::Send(const char *buf, const CIp &Ip) const +{ + switch (Ip.GetFamily()) { + case AF_INET: + m_Socket4.Send(buf, Ip); + break; + case AF_INET6: + m_Socket6.Send(buf, Ip); + break; + default: + std::cerr << "ERROR: wrong family: " << Ip.GetFamily() << std::endl; + break; + } +} + +void CProtocol::Send(const CBuffer &buf, const CIp &Ip, uint16_t port) const +{ + switch (Ip.GetFamily()) { + case AF_INET: + m_Socket4.Send(buf, Ip, port); + break; + case AF_INET6: + m_Socket6.Send(buf, Ip, port); + break; + default: + std::cerr << "Wrong family: " << Ip.GetFamily() << " on port " << port << std::endl; + break; + } +} + +void CProtocol::Send(const char *buf, const CIp &Ip, uint16_t port) const +{ + switch (Ip.GetFamily()) { + case AF_INET: + m_Socket4.Send(buf, Ip, port); + break; + case AF_INET6: + m_Socket6.Send(buf, Ip, port); + break; + default: + std::cerr << "Wrong family: " << Ip.GetFamily() << " on port " << port << std::endl; + break; + } +} diff --git a/src/cprotocol.h b/src/cprotocol.h index f736ed7..b7a9fef 100644 --- a/src/cprotocol.h +++ b/src/cprotocol.h @@ -77,7 +77,7 @@ public: virtual ~CProtocol(); // initialization - virtual bool Init(void); + bool Initialize(const char *, uint16); virtual void Close(void); // queue @@ -89,7 +89,7 @@ public: // task static void Thread(CProtocol *); - virtual void Task(void) {} + virtual void Task(void) = 0; protected: // packet encoding helpers @@ -122,9 +122,13 @@ protected: virtual char DmrDstIdToModule(uint32) const; virtual uint32 ModuleToDmrDestId(char) const; -protected: + void Send(const CBuffer &buf, const CIp &Ip) const; + void Send(const char *buf, const CIp &Ip) const; + void Send(const CBuffer &buf, const CIp &Ip, uint16 port) const; + void Send(const char *buf, const CIp &Ip, uint16 port) const; + // socket - CUdpSocket m_Socket; + CUdpSocket m_Socket4, m_Socket6; // streams std::list m_Streams; diff --git a/src/cprotocols.cpp b/src/cprotocols.cpp index bc6c4d4..3355f18 100644 --- a/src/cprotocols.cpp +++ b/src/cprotocols.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" @@ -33,18 +33,6 @@ #include "cg3protocol.h" #include "cprotocols.h" - -//////////////////////////////////////////////////////////////////////////////////////// -// constructor - -CProtocols::CProtocols() -{ - for ( int i = 0; i < m_Protocols.size(); i++ ) - { - m_Protocols[i] = NULL; - } -} - //////////////////////////////////////////////////////////////////////////////////////// // destructor @@ -52,10 +40,12 @@ CProtocols::~CProtocols() { m_Mutex.lock(); { - for ( int i = 0; i < m_Protocols.size(); i++ ) - { - delete m_Protocols[i]; - } + for ( auto it=m_Protocols.begin(); it!=m_Protocols.end(); it++) + { + (*it)->Close(); + delete *it; + } + m_Protocols.clear(); } m_Mutex.unlock(); } @@ -65,65 +55,105 @@ CProtocols::~CProtocols() bool CProtocols::Init(void) { - bool ok = true; - m_Mutex.lock(); { - // create and initialize DEXTRA - delete m_Protocols[0]; - m_Protocols[0] = new CDextraProtocol; - ok &= m_Protocols[0]->Init(); - + auto dextra = new CDextraProtocol; + if (dextra->Init()) + m_Protocols.push_back(dextra); + else + { + delete dextra; + return false; + } + + // create and initialize DPLUS - delete m_Protocols[1]; - m_Protocols[1] = new CDplusProtocol; - ok &= m_Protocols[1]->Init(); - + auto dplus = new CDplusProtocol; + if (dplus->Init()) + m_Protocols.push_back(dplus); + else + { + delete dplus; + return false; + } + // create and initialize DCS - delete m_Protocols[2]; - m_Protocols[2] = new CDcsProtocol; - ok &= m_Protocols[2]->Init(); - + auto dcs = new CDcsProtocol; + if (dcs->Init()) + m_Protocols.push_back(dcs); + else + { + delete dcs; + return false; + } + // create and initialize XLX - interlink - delete m_Protocols[3]; - m_Protocols[3] = new CXlxProtocol; - ok &= m_Protocols[3]->Init(); - + auto xlx = new CXlxProtocol; + if (xlx->Init()) + m_Protocols.push_back(xlx); + else + { + delete xlx; + return false; + } + // create and initialize DMRPLUS - delete m_Protocols[4]; - m_Protocols[4] = new CDmrplusProtocol; - ok &= m_Protocols[4]->Init(); - + auto dmrplus = new CDmrplusProtocol; + if (dmrplus->Init()) + m_Protocols.push_back(dmrplus); + else + { + delete dmrplus; + return false; + } + // create and initialize DMRMMDVM - delete m_Protocols[5]; - m_Protocols[5] = new CDmrmmdvmProtocol; - ok &= m_Protocols[5]->Init(); - + auto dmrmmdvm = new CDmrmmdvmProtocol; + if (dmrmmdvm->Init()) + m_Protocols.push_back(dmrmmdvm); + else + { + delete dmrmmdvm; + return false; + } + // create and initialize YSF - delete m_Protocols[6]; - m_Protocols[6] = new CYsfProtocol; - ok &= m_Protocols[6]->Init(); + auto ysf = new CYsfProtocol; + if (ysf->Init()) + m_Protocols.push_back(ysf); + else + { + delete ysf; + return false; + } // create and initialize G3 - delete m_Protocols[7]; - m_Protocols[7] = new CG3Protocol; - ok &= m_Protocols[7]->Init(); + auto g3 = new CG3Protocol; + if (g3->Init()) + m_Protocols.push_back(g3); + else + { + delete g3; + return true; + } } m_Mutex.unlock(); - + // done - return ok; + return true; } void CProtocols::Close(void) { m_Mutex.lock(); { - for ( int i = 0; i < m_Protocols.size(); i++ ) - { - m_Protocols[i]->Close(); - } + for ( auto it=m_Protocols.begin(); it!=m_Protocols.end(); it++) + { + (*it)->Close(); + delete *it; + } + m_Protocols.clear(); } m_Mutex.unlock(); } diff --git a/src/cprotocols.h b/src/cprotocols.h index c0194a7..3f0124b 100644 --- a/src/cprotocols.h +++ b/src/cprotocols.h @@ -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 . // ---------------------------------------------------------------------------- #ifndef cprotocols_h @@ -38,24 +38,21 @@ class CProtocols { public: - // constructors - CProtocols(); - // destructors - virtual ~CProtocols(); - + ~CProtocols(); + // initialization bool Init(void); void Close(void); - - // get - int Size(void) const { return (int)m_Protocols.size(); } - CProtocol *GetProtocol(int i) { return m_Protocols[i]; } - + + // pass-thru + std::list::iterator begin() { return m_Protocols.begin(); } + std::list::iterator end() { return m_Protocols.end(); } + protected: // data - std::mutex m_Mutex; - std::array m_Protocols; + std::mutex m_Mutex; + std::list m_Protocols; }; diff --git a/src/creflector.cpp b/src/creflector.cpp index 41e5b7c..0d8da87 100644 --- a/src/creflector.cpp +++ b/src/creflector.cpp @@ -348,27 +348,24 @@ void CReflector::RouterThread(CReflector *This, CPacketStream *streamIn) packet->SetModuleId(uiModuleId); // iterate on all protocols - for ( int i = 0; i < This->m_Protocols.Size(); i++ ) + for ( auto it=This->m_Protocols.begin(); it!=This->m_Protocols.end(); it++ ) { // duplicate packet CPacket *packetClone = packet->Duplicate(); - // get protocol - CProtocol *protocol = This->m_Protocols.GetProtocol(i); - // if packet is header, update RPT2 according to protocol if ( packetClone->IsDvHeader() ) { // get our callsign - CCallsign csRPT = protocol->GetReflectorCallsign(); + CCallsign csRPT = (*it)->GetReflectorCallsign(); csRPT.SetModule(This->GetStreamModule(streamIn)); ((CDvHeaderPacket *)packetClone)->SetRpt2Callsign(csRPT); } // and push it - CPacketQueue *queue = protocol->GetQueue(); + CPacketQueue *queue = (*it)->GetQueue(); queue->push(packetClone); - protocol->ReleaseQueue(); + (*it)->ReleaseQueue(); } // done delete packet; diff --git a/src/creflector.h b/src/creflector.h index 1424453..bd6c913 100644 --- a/src/creflector.h +++ b/src/creflector.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,7 +20,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 . // ---------------------------------------------------------------------------- #ifndef creflector_h @@ -50,96 +51,99 @@ public: // constructor CReflector(); CReflector(const CCallsign &); - + // destructor virtual ~CReflector(); - + // settings - void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; } - const CCallsign &GetCallsign(void) const { return m_Callsign; } - void SetListenIp(const CIp &ip) { m_Ip = ip; } - void SetTranscoderIp(const CIp &ip) { m_AmbedIp = ip; } - const CIp &GetListenIp(void) const { return m_Ip; } - const CIp &GetTranscoderIp(void) const { return m_AmbedIp; } - + void SetCallsign(const CCallsign &callsign) { m_Callsign = callsign; } + const CCallsign &GetCallsign(void) const { return m_Callsign; } + void SetListenIPv4(const char *a, const int n) { memset(m_IPv4, 0, n); strncpy(m_IPv4, a, n-1); } + void SetListenIPv6(const char *a, const int n) { memset(m_IPv6, 0, n); strncpy(m_IPv6, a, n-1); } + void SetTranscoderIp(const char *a, const int n) { memset(m_AmbedIp, 0, n); strncpy(m_AmbedIp, a, n-1); } + const char *GetListenIPv4(void) const { return m_IPv4; } + const char *GetListenIPv6(void) const { return m_IPv6; } + const char *GetTranscoderIp(void) const { return m_AmbedIp; } + // operation bool Start(void); void Stop(void); - + // clients CClients *GetClients(void) { m_Clients.Lock(); return &m_Clients; } void ReleaseClients(void) { m_Clients.Unlock(); } - + // peers CPeers *GetPeers(void) { m_Peers.Lock(); return &m_Peers; } void ReleasePeers(void) { m_Peers.Unlock(); } - + // stream opening & closing CPacketStream *OpenStream(CDvHeaderPacket *, CClient *); bool IsStreaming(char); void CloseStream(CPacketStream *); - + // users CUsers *GetUsers(void) { m_Users.Lock(); return &m_Users; } void ReleaseUsers(void) { m_Users.Unlock(); } - + // get bool IsValidModule(char c) const { return (GetModuleIndex(c) >= 0); } int GetModuleIndex(char) const; char GetModuleLetter(int i) const { return 'A' + (char)i; } - + // notifications void OnPeersChanged(void); void OnClientsChanged(void); void OnUsersChanged(void); void OnStreamOpen(const CCallsign &); void OnStreamClose(const CCallsign &); - + protected: // threads static void RouterThread(CReflector *, CPacketStream *); static void XmlReportThread(CReflector *); static void JsonReportThread(CReflector *); - + // streams CPacketStream *GetStream(char); bool IsStreamOpen(const CDvHeaderPacket *); char GetStreamModule(CPacketStream *); - + // xml helpers void WriteXmlFile(std::ofstream &); - + // json helpers void SendJsonReflectorObject(CUdpSocket &, CIp &); void SendJsonNodesObject(CUdpSocket &, CIp &); void SendJsonStationsObject(CUdpSocket &, CIp &); void SendJsonOnairObject(CUdpSocket &, CIp &, const CCallsign &); void SendJsonOffairObject(CUdpSocket &, CIp &, const CCallsign &); - + protected: // identity - CCallsign m_Callsign; - CIp m_Ip; - CIp m_AmbedIp; - + CCallsign m_Callsign; + char m_IPv4[INET_ADDRSTRLEN]; + char m_IPv6[INET6_ADDRSTRLEN]; + char m_AmbedIp[INET6_ADDRSTRLEN]; + // objects CUsers m_Users; // sorted list of lastheard stations CClients m_Clients; // list of linked repeaters/nodes/peers's modules CPeers m_Peers; // list of linked peers CProtocols m_Protocols; // list of supported protocol handlers - + // queues std::array m_Streams; - + // threads bool m_bStopThreads; std::array m_RouterThreads; std::thread *m_XmlReportThread; std::thread *m_JsonReportThread; - + // notifications CNotificationQueue m_Notifications; - + public: #ifdef DEBUG_DUMPFILE std::ofstream m_DebugFile; diff --git a/src/ctranscoder.cpp b/src/ctranscoder.cpp index e4d91b3..bf545d7 100644 --- a/src/ctranscoder.cpp +++ b/src/ctranscoder.cpp @@ -75,22 +75,27 @@ bool CTranscoder::Init(void) m_bStopThread = false; // create server's IP - m_Ip = g_Reflector.GetTranscoderIp(); + auto s = g_Reflector.GetTranscoderIp(); + m_Ip.Initialize(strchr(s, ':') ? AF_INET6 : AF_INET, TRANSCODER_PORT, s); // create our socket - ok = m_Socket.Open(TRANSCODER_PORT); - if ( ok ) - { - // start thread; - m_pThread = new std::thread(CTranscoder::Thread, this); - } - else - { - std::cout << "Error opening socket on port UDP" << TRANSCODER_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } - - // done - return ok; + if (m_Ip.IsSet()) + { + if (! m_Socket.Open(TRANSCODER_PORT)) { + std::cerr << "Error opening socket on port UDP" << TRANSCODER_PORT << " on ip " << m_Ip << std::endl; + return false; + } + } + else + { + std::cerr << "Could not initialize transcoder socket on " << m_Ip << std::endl; + return false; + } + + // start thread; + m_pThread = new std::thread(CTranscoder::Thread, this); + + return true; } void CTranscoder::Close(void) diff --git a/src/cudpmsgsocket.cpp b/src/cudpmsgsocket.cpp index b90f702..39b09ec 100644 --- a/src/cudpmsgsocket.cpp +++ b/src/cudpmsgsocket.cpp @@ -28,12 +28,12 @@ //////////////////////////////////////////////////////////////////////////////////////// // open -bool CUdpMsgSocket::Open(uint16 uiPort) +bool CUdpMsgSocket::Open(const CIp &ip) { bool ret; int on = 1; - ret = CUdpSocket::Open(uiPort); + ret = CUdpSocket::Open(ip); setsockopt(m_fd, IPPROTO_IP, IP_PKTINFO, (char *)&on, sizeof(on)); return ret; diff --git a/src/cudpmsgsocket.h b/src/cudpmsgsocket.h index f4245c1..32bb512 100644 --- a/src/cudpmsgsocket.h +++ b/src/cudpmsgsocket.h @@ -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 . // ---------------------------------------------------------------------------- // Description: @@ -40,7 +40,7 @@ class CUdpMsgSocket : public CUdpSocket { public: // open - bool Open(uint16); + bool Open(const CIp &ip); // read int Receive(CBuffer *, CIp *, int); diff --git a/src/cxlxprotocol.cpp b/src/cxlxprotocol.cpp index d237aa4..83d0b71 100644 --- a/src/cxlxprotocol.cpp +++ b/src/cxlxprotocol.cpp @@ -37,27 +37,15 @@ bool CXlxProtocol::Init(void) { - bool ok; - - // base class - ok = CProtocol::Init(); - - // update the reflector callsign - m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"XLX", 3); - - // create our socket - ok &= m_Socket.Open(XLX_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << XLX_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } + if (! Initialize("XLX", XLX_PORT)) + return false; // update time m_LastKeepaliveTime.Now(); m_LastPeersLinkTime.Now(); // done - return ok; + return true; } //////////////////////////////////////////////////////////////////////////////////////// @@ -75,7 +63,7 @@ void CXlxProtocol::Task(void) CDvLastFramePacket *LastFrame; // any incoming packet ? - if ( m_Socket.Receive(Buffer, Ip, 20) ) + if ( m_Socket4.Receive(Buffer, Ip, 10) || m_Socket6.Receive(Buffer, Ip, 10) ) { // crack the packet if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL ) @@ -130,7 +118,7 @@ void CXlxProtocol::Task(void) { // acknowledge the request EncodeConnectAckPacket(&Buffer, Modules); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } g_Reflector.ReleasePeers(); @@ -141,7 +129,7 @@ void CXlxProtocol::Task(void) default: // acknowledge the request EncodeConnectAckPacket(&Buffer, Modules); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); break; } } @@ -149,7 +137,7 @@ void CXlxProtocol::Task(void) { // deny the request EncodeConnectNackPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } } else if ( IsValidAckPacket(Buffer, &Callsign, Modules, &Version) ) @@ -284,17 +272,17 @@ void CXlxProtocol::HandleQueue(void) { case XLX_PROTOCOL_REVISION_0: case XLX_PROTOCOL_REVISION_1: - m_Socket.Send(bufferLegacy, client->GetIp()); + Send(bufferLegacy, client->GetIp()); break; case XLX_PROTOCOL_REVISION_2: default: if ( g_Transcoder.IsConnected() ) { - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } else { - m_Socket.Send(bufferLegacy, client->GetIp()); + Send(bufferLegacy, client->GetIp()); } break; } @@ -328,7 +316,7 @@ void CXlxProtocol::HandleKeepalives(void) while ( (peer = peers->FindNextPeer(PROTOCOL_XLX, pit)) != NULL ) { // send keepalive - m_Socket.Send(keepalive, peer->GetIp()); + Send(keepalive, peer->GetIp()); // client busy ? if ( peer->IsAMaster() ) @@ -342,7 +330,7 @@ void CXlxProtocol::HandleKeepalives(void) // no, disconnect CBuffer disconnect; EncodeDisconnectPacket(&disconnect); - m_Socket.Send(disconnect, peer->GetIp()); + Send(disconnect, peer->GetIp()); // remove it std::cout << "XLX peer " << peer->GetCallsign() << " keepalive timeout" << std::endl; @@ -373,7 +361,7 @@ void CXlxProtocol::HandlePeerLinks(void) { // send disconnect packet EncodeDisconnectPacket(&buffer); - m_Socket.Send(buffer, peer->GetIp()); + Send(buffer, peer->GetIp()); std::cout << "Sending disconnect packet to XLX peer " << peer->GetCallsign() << std::endl; // remove client peers->RemovePeer(peer); @@ -392,7 +380,7 @@ void CXlxProtocol::HandlePeerLinks(void) (*it).ResolveIp(); // send connect packet to re-initiate peer link EncodeConnectPacket(&buffer, (*it).GetModules()); - m_Socket.Send(buffer, (*it).GetIp(), XLX_PORT); + Send(buffer, (*it).GetIp(), XLX_PORT); std::cout << "Sending connect packet to XLX peer " << (*it).GetCallsign() << " @ " << (*it).GetIp() << " for modules " << (*it).GetModules() << std::endl; } } diff --git a/src/cxlxprotocol.h b/src/cxlxprotocol.h index c9b66a1..b36a469 100644 --- a/src/cxlxprotocol.h +++ b/src/cxlxprotocol.h @@ -40,31 +40,25 @@ class CPeer; class CXlxProtocol : public CDextraProtocol { public: - // constructor - CXlxProtocol() {}; - - // destructor - virtual ~CXlxProtocol() {}; - // initialization bool Init(void); - + // task void Task(void); - + protected: // queue helper void HandleQueue(void); - + // keepalive helpers void HandlePeerLinks(void); void HandleKeepalives(void); - + // stream helpers bool OnDvHeaderPacketIn(CDvHeaderPacket *, const CIp &); void OnDvFramePacketIn(CDvFramePacket *, const CIp * = NULL); void OnDvLastFramePacketIn(CDvLastFramePacket *, const CIp * = NULL); - + // packet decoding helpers bool IsValidKeepAlivePacket(const CBuffer &, CCallsign *); bool IsValidConnectPacket(const CBuffer &, CCallsign *, char *, CVersion *); @@ -73,7 +67,7 @@ protected: bool IsValidNackPacket(const CBuffer &, CCallsign *); CDvFramePacket *IsValidDvFramePacket(const CBuffer &); CDvLastFramePacket *IsValidDvLastFramePacket(const CBuffer &); - + // packet encoding helpers void EncodeKeepAlivePacket(CBuffer *); void EncodeConnectPacket(CBuffer *, const char *); @@ -82,11 +76,11 @@ protected: void EncodeConnectNackPacket(CBuffer *); bool EncodeDvFramePacket(const CDvFramePacket &, CBuffer *) const; bool EncodeDvLastFramePacket(const CDvLastFramePacket &, CBuffer *) const; - + // protocol revision helper int GetConnectingPeerProtocolRevision(const CCallsign &, const CVersion &); CPeer *CreateNewPeer(const CCallsign &, const CIp &, char *, const CVersion &); - + protected: // time CTimePoint m_LastKeepaliveTime; diff --git a/src/cysfprotocol.cpp b/src/cysfprotocol.cpp index 968fcb8..983fa45 100644 --- a/src/cysfprotocol.cpp +++ b/src/cysfprotocol.cpp @@ -47,29 +47,19 @@ CYsfProtocol::CYsfProtocol() bool CYsfProtocol::Init(void) { - bool ok; - // base class - ok = CProtocol::Init(); - - // update the reflector callsign - m_ReflectorCallsign.PatchCallsign(0, (const uint8 *)"YSF", 3); - - // create our socket - ok &= m_Socket.Open(YSF_PORT); - if ( !ok ) - { - std::cout << "Error opening socket on port UDP" << YSF_PORT << " on ip " << g_Reflector.GetListenIp() << std::endl; - } + if (! Initialize("YSF", YSF_PORT)) + return false; // init the wiresx cmd handler - ok &= m_WiresxCmdHandler.Init(); + if (! m_WiresxCmdHandler.Init()) + return false; // update time m_LastKeepaliveTime.Now(); // done - return ok; + return true; } void CYsfProtocol::Close(void) @@ -105,13 +95,13 @@ void CYsfProtocol::Task(void) { CWiresxPacket packet = queue->front(); queue->pop(); - m_Socket.Send(packet.GetBuffer(), packet.GetIp()); + Send(packet.GetBuffer(), packet.GetIp()); } m_WiresxCmdHandler.ReleasePacketQueue(); } // handle incoming packets - if ( m_Socket.Receive(Buffer, Ip, 20) ) + if ( m_Socket6.Receive(Buffer, Ip, 10) || m_Socket4.Receive(Buffer, Ip, 10) ) { // crack the packet if ( IsValidDvPacket(Buffer, &Fich) ) @@ -164,7 +154,7 @@ void CYsfProtocol::Task(void) { // acknowledge the request EncodeConnectAckPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); // add client if needed CClients *clients = g_Reflector.GetClients(); @@ -207,7 +197,7 @@ void CYsfProtocol::Task(void) std::cout << "YSF server status enquiry from " << Ip << std::endl; // reply EncodeServerStatusPacket(&Buffer); - m_Socket.Send(Buffer, Ip); + Send(Buffer, Ip); } else { @@ -359,7 +349,7 @@ void CYsfProtocol::HandleQueue(void) if ( !client->IsAMaster() && (client->GetReflectorModule() == packet->GetModuleId()) ) { // no, send the packet - m_Socket.Send(buffer, client->GetIp()); + Send(buffer, client->GetIp()); } } diff --git a/src/main.cpp b/src/main.cpp index 723ab5b..008e0d2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,13 +19,12 @@ // 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 "creflector.h" -#include "syslog.h" #include @@ -41,99 +40,58 @@ CReflector g_Reflector; int main(int argc, const char * argv[]) { -#ifdef RUN_AS_DAEMON - - // redirect cout, cerr and clog to syslog - syslog::redirect cout_redir(std::cout); - syslog::redirect cerr_redir(std::cerr); - syslog::redirect clog_redir(std::clog); - - //Fork the Parent Process - pid_t pid, sid; - pid = ::fork(); - if ( pid < 0 ) - { - exit(EXIT_FAILURE); - } - - // We got a good pid, Close the Parent Process - if (pid > 0) - { - exit(EXIT_SUCCESS); - } - - // Change File Mask - ::umask(0); - - //Create a new Signature Id for our child - sid = ::setsid(); - if (sid < 0) - { - exit(EXIT_FAILURE); - } - - // Change Directory - // If we cant find the directory we exit with failure. - if ( (::chdir("/")) < 0) - { - exit(EXIT_FAILURE); - } - - // Close Standard File Descriptors - close(STDIN_FILENO); - close(STDOUT_FILENO); - close(STDERR_FILENO); - -#endif // check arguments - if ( argc != 4 ) + if ( argc != 5 ) { - std::cout << "Usage: xlxd callsign xlxdip ambedip" << std::endl; - std::cout << "example: xlxd XLX999 192.168.178.212 127.0.0.1" << std::endl; - return 1; + std::cout << "Usage: " << argv[0] << " callsign ipv4 ipv6 ambedip" << std::endl; + std::cout << "example: " << argv[0] << " XLX999 192.168.178.212 2001:400:534::675b 127.0.0.1" << std::endl; + return EXIT_FAILURE; } + bool is4none = 0 == strncasecmp(argv[2], "none", 4); + bool is6none = 0 == strncasecmp(argv[3], "none", 4); + if (is4none && is6none) { + std::cerr << "Both IPv4 and 6 address can't both be 'none'" << std::endl; + return EXIT_FAILURE; + } + // splash - std::cout << "Starting xlxd " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl; + std::cout << "Starting " << argv[0] << " " << VERSION_MAJOR << "." << VERSION_MINOR << "." << VERSION_REVISION << std::endl << std::endl; // initialize reflector g_Reflector.SetCallsign(argv[1]); - g_Reflector.SetListenIp(CIp(argv[2])); - g_Reflector.SetTranscoderIp(CIp(CIp(argv[3]))); - + g_Reflector.SetListenIPv4(argv[2], INET_ADDRSTRLEN); + g_Reflector.SetListenIPv6(argv[3], INET6_ADDRSTRLEN); + g_Reflector.SetTranscoderIp(argv[4], INET6_ADDRSTRLEN); + + // and let it run if ( !g_Reflector.Start() ) { std::cout << "Error starting reflector" << std::endl; - exit(EXIT_FAILURE); - } - std::cout << "Reflector " << g_Reflector.GetCallsign() - << "started and listening on " << g_Reflector.GetListenIp() << std::endl; - -#ifdef RUN_AS_DAEMON - // run forever - while ( true ) - { - // sleep 60 seconds - CTimePoint::TaskSleepFor(60000); - } -#else - // wait any key - for (;;) - { - // sleep 60 seconds - CTimePoint::TaskSleepFor(60000); -#ifdef DEBUG_DUMPFILE - g_Reflector.m_DebugFile.close(); -#endif + return EXIT_FAILURE; } -#endif - - // and wait for end + + std::cout << "Reflector " << g_Reflector.GetCallsign() << "started and listening on "; + if (! is4none) + { + std::cout << g_Reflector.GetListenIPv4(); + if (! is6none) + { + std::cout << " and " << g_Reflector.GetListenIPv4() << std::endl; + } + } + else + { + std::cout << g_Reflector.GetListenIPv6() << std::endl; + } + + pause(); // wait for any signal + g_Reflector.Stop(); std::cout << "Reflector stopped" << std::endl; - + // done - exit(EXIT_SUCCESS); + return EXIT_SUCCESS; }