diff --git a/qrtplib/CMakeLists.txt b/qrtplib/CMakeLists.txt index 75ba994c0..a5472b153 100644 --- a/qrtplib/CMakeLists.txt +++ b/qrtplib/CMakeLists.txt @@ -19,12 +19,8 @@ set (qrtplib_HEADERS rtpdefines.h rtpendian.h rtperrors.h - rtphashtable.h rtpinternalsourcedata.h -# rtpipv4address.h -# rtpipv4destination.h rtpkeyhashtable.h - rtplibraryversion.h rtppacket.h rtppacketbuilder.h rtprandom.h @@ -43,14 +39,7 @@ set (qrtplib_HEADERS rtptypes_win.h rtptypes.h rtpudptransmitter.h -# rtpudpv4transmitter.h -# rtpudpv4transmitternobind.h -# rtpexternaltransmitter.h rtpsocketutil.h - rtpabortdescriptors.h - rtpselect.h -# rtptcpaddress.h -# rtptcptransmitter.h ) set(qrtplib_SOURCES @@ -68,9 +57,6 @@ set(qrtplib_SOURCES rtpcollisionlist.cpp rtperrors.cpp rtpinternalsourcedata.cpp -# rtpipv4address.cpp -# rtpipv4destination.cpp - rtplibraryversion.cpp rtppacket.cpp rtppacketbuilder.cpp rtprandom.cpp @@ -84,12 +70,6 @@ set(qrtplib_SOURCES rtpsources.cpp rtptimeutilities.cpp rtpudptransmitter.cpp -# rtpudpv4transmitter.cpp -# rtpudpv4transmitternobind.cpp -# rtpexternaltransmitter.cpp - rtpabortdescriptors.cpp -# rtptcpaddress.cpp -# rtptcptransmitter.cpp ) include_directories( diff --git a/qrtplib/qrtplib.pro b/qrtplib/qrtplib.pro index 4e8140f44..50dc5d777 100644 --- a/qrtplib/qrtplib.pro +++ b/qrtplib/qrtplib.pro @@ -40,10 +40,7 @@ HEADERS += $$PWD/rtcpapppacket.h \ $$PWD/rtpdefines.h \ $$PWD/rtpendian.h \ $$PWD/rtperrors.h \ - $$PWD/rtphashtable.h \ $$PWD/rtpinternalsourcedata.h \ - $$PWD/rtpkeyhashtable.h \ - $$PWD/rtplibraryversion.h \ $$PWD/rtppacket.h \ $$PWD/rtppacketbuilder.h \ $$PWD/rtprandom.h \ @@ -80,7 +77,6 @@ SOURCES += $$PWD/rtcpapppacket.cpp \ $$PWD/rtpcollisionlist.cpp \ $$PWD/rtperrors.cpp \ $$PWD/rtpinternalsourcedata.cpp \ - $$PWD/rtplibraryversion.cpp \ $$PWD/rtppacket.cpp \ $$PWD/rtppacketbuilder.cpp \ $$PWD/rtprandom.cpp \ diff --git a/qrtplib/rtpabortdescriptors.cpp b/qrtplib/rtpabortdescriptors.cpp deleted file mode 100644 index 8753154bc..000000000 --- a/qrtplib/rtpabortdescriptors.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtpabortdescriptors.h" -#include "rtpsocketutilinternal.h" -#include "rtperrors.h" -#include "rtpselect.h" - -namespace qrtplib -{ - -RTPAbortDescriptors::RTPAbortDescriptors() -{ - m_descriptors[0] = RTPSOCKERR; - m_descriptors[1] = RTPSOCKERR; - m_init = false; -} - -RTPAbortDescriptors::~RTPAbortDescriptors() -{ - Destroy(); -} - -#ifdef RTP_SOCKETTYPE_WINSOCK - -int RTPAbortDescriptors::Init() -{ - if (m_init) - return ERR_RTP_ABORTDESC_ALREADYINIT; - - SOCKET listensock; - int size; - struct sockaddr_in addr; - - listensock = socket(PF_INET,SOCK_STREAM,0); - if (listensock == RTPSOCKERR) - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - - memset(&addr,0,sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - if (bind(listensock,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) - { - RTPCLOSE(listensock); - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - } - - memset(&addr,0,sizeof(struct sockaddr_in)); - size = sizeof(struct sockaddr_in); - if (getsockname(listensock,(struct sockaddr*)&addr,&size) != 0) - { - RTPCLOSE(listensock); - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - } - - unsigned short connectport = ntohs(addr.sin_port); - - m_descriptors[0] = socket(PF_INET,SOCK_STREAM,0); - if (m_descriptors[0] == RTPSOCKERR) - { - RTPCLOSE(listensock); - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - } - - memset(&addr,0,sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - if (bind(m_descriptors[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) - { - RTPCLOSE(listensock); - RTPCLOSE(m_descriptors[0]); - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - } - - if (listen(listensock,1) != 0) - { - RTPCLOSE(listensock); - RTPCLOSE(m_descriptors[0]); - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - } - - memset(&addr,0,sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - addr.sin_port = htons(connectport); - - if (connect(m_descriptors[0],(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) != 0) - { - RTPCLOSE(listensock); - RTPCLOSE(m_descriptors[0]); - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - } - - memset(&addr,0,sizeof(struct sockaddr_in)); - size = sizeof(struct sockaddr_in); - m_descriptors[1] = accept(listensock,(struct sockaddr *)&addr,&size); - if (m_descriptors[1] == RTPSOCKERR) - { - RTPCLOSE(listensock); - RTPCLOSE(m_descriptors[0]); - return ERR_RTP_ABORTDESC_CANTCREATEABORTDESCRIPTORS; - } - - // okay, got the connection, close the listening socket - - RTPCLOSE(listensock); - - m_init = true; - return 0; -} - -void RTPAbortDescriptors::Destroy() -{ - if (!m_init) - return; - - RTPCLOSE(m_descriptors[0]); - RTPCLOSE(m_descriptors[1]); - m_descriptors[0] = RTPSOCKERR; - m_descriptors[1] = RTPSOCKERR; - - m_init = false; -} - -int RTPAbortDescriptors::SendAbortSignal() -{ - if (!m_init) - return ERR_RTP_ABORTDESC_NOTINIT; - - send(m_descriptors[1],"*",1,0); - return 0; -} - -int RTPAbortDescriptors::ReadSignallingByte() -{ - if (!m_init) - return ERR_RTP_ABORTDESC_NOTINIT; - - char buf[1]; - - recv(m_descriptors[0],buf,1,0); - return 0; -} - -#else // unix-style - -int RTPAbortDescriptors::Init() -{ - if (m_init) - return ERR_RTP_ABORTDESC_ALREADYINIT; - - if (pipe(m_descriptors) < 0) - return ERR_RTP_ABORTDESC_CANTCREATEPIPE; - - m_init = true; - return 0; -} - -void RTPAbortDescriptors::Destroy() -{ - if (!m_init) - return; - - close(m_descriptors[0]); - close(m_descriptors[1]); - m_descriptors[0] = RTPSOCKERR; - m_descriptors[1] = RTPSOCKERR; - - m_init = false; -} - -int RTPAbortDescriptors::SendAbortSignal() -{ - if (!m_init) - return ERR_RTP_ABORTDESC_NOTINIT; - - if (write(m_descriptors[1], "*", 1)) - { - // To get rid of __wur related compiler warnings - } - - return 0; -} - -int RTPAbortDescriptors::ReadSignallingByte() -{ - if (!m_init) - return ERR_RTP_ABORTDESC_NOTINIT; - - unsigned char buf[1]; - - if (read(m_descriptors[0], buf, 1)) - { - // To get rid of __wur related compiler warnings - } - return 0; -} - -#endif // RTP_SOCKETTYPE_WINSOCK - -// Keep calling 'ReadSignallingByte' until there's no byte left -int RTPAbortDescriptors::ClearAbortSignal() -{ - if (!m_init) - return ERR_RTP_ABORTDESC_NOTINIT; - - bool done = false; - while (!done) - { - int8_t isset = 0; - - // Not used: struct timeval tv = { 0, 0 }; - - int status = RTPSelect(&m_descriptors[0], &isset, 1, RTPTime(0)); - if (status < 0) - return status; - - if (!isset) - done = true; - else - { - int status = ReadSignallingByte(); - if (status < 0) - return status; - } - } - - return 0; -} - -} // end namespace diff --git a/qrtplib/rtpabortdescriptors.h b/qrtplib/rtpabortdescriptors.h deleted file mode 100644 index cab7f68b6..000000000 --- a/qrtplib/rtpabortdescriptors.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtpabortdescriptors.h - */ - -#ifndef RTPABORTDESCRIPTORS_H - -#define RTPABORTDESCRIPTORS_H - -#include "rtpconfig.h" -#include "rtpsocketutil.h" - -#include "util/export.h" - -namespace qrtplib -{ - -/** - * Helper class for several RTPTransmitter instances, to be able to cancel a - * call to 'select', 'poll' or 'WSAPoll'. - * - * This is a helper class for several RTPTransmitter instances. Typically a - * call to 'select' (or 'poll' or 'WSAPoll', depending on the platform) is used - * to wait for incoming data for a certain time. To be able to cancel this wait - * from another thread, this class provides a socket descriptor that's compatible - * with e.g. the 'select' call, and to which data can be sent using - * RTPAbortDescriptors::SendAbortSignal. If the descriptor is included in the - * 'select' call, the function will detect incoming data and the function stops - * waiting for incoming data. - * - * The class can be useful in case you'd like to create an implementation which - * uses a single poll thread for several RTPSession and RTPTransmitter instances. - * This idea is further illustrated in `example8.cpp`. - */ -class QRTPLIB_API RTPAbortDescriptors -{ -public: - RTPAbortDescriptors(); - ~RTPAbortDescriptors(); - - /** Initializes this instance. */ - int Init(); - - /** Returns the socket descriptor that can be included in a call to - * 'select' (for example).*/ - SocketType GetAbortSocket() const - { - return m_descriptors[0]; - } - - /** Returns a flag indicating if this instance was initialized. */ - bool IsInitialized() const - { - return m_init; - } - - /** De-initializes this instance. */ - void Destroy(); - - /** Send a signal to the socket that's returned by RTPAbortDescriptors::GetAbortSocket, - * causing the 'select' call to detect that data is available, making the call - * end. */ - int SendAbortSignal(); - - /** For each RTPAbortDescriptors::SendAbortSignal function that's called, a call - * to this function can be made to clear the state again. */ - int ReadSignallingByte(); - - /** Similar to ReadSignallingByte::ReadSignallingByte, this function clears the signalling - * state, but this also works independently from the amount of times that - * RTPAbortDescriptors::SendAbortSignal was called. */ - int ClearAbortSignal(); -private: - SocketType m_descriptors[2]; - bool m_init; -}; - -} // end namespace - -#endif // RTPABORTDESCRIPTORS_H diff --git a/qrtplib/rtpexternaltransmitter.cpp b/qrtplib/rtpexternaltransmitter.cpp deleted file mode 100644 index 83c6cec08..000000000 --- a/qrtplib/rtpexternaltransmitter.cpp +++ /dev/null @@ -1,634 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtpexternaltransmitter.h" -#include "rtprawpacket.h" -#include "rtptimeutilities.h" -#include "rtpdefines.h" -#include "rtperrors.h" -#include "rtpsocketutilinternal.h" -#include "rtpselect.h" -#include -#include - -#include - -namespace qrtplib -{ - -RTPExternalTransmitter::RTPExternalTransmitter() : - packetinjector((RTPExternalTransmitter *) this) -{ - created = false; - init = false; -} - -RTPExternalTransmitter::~RTPExternalTransmitter() -{ - Destroy(); -} - -int RTPExternalTransmitter::Init(bool tsafe) -{ - if (init) - return ERR_RTP_EXTERNALTRANS_ALREADYINIT; - - if (tsafe) - return ERR_RTP_NOTHREADSUPPORT; - - init = true; - return 0; -} - -int RTPExternalTransmitter::Create(std::size_t maximumpacketsize, const RTPTransmissionParams *transparams) -{ - const RTPExternalTransmissionParams *params; - int status; - - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (created) - { - return ERR_RTP_EXTERNALTRANS_ALREADYCREATED; - } - - // Obtain transmission parameters - - if (transparams == 0) - { - return ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS; - } - if (transparams->GetTransmissionProtocol() != RTPTransmitter::ExternalProto) - { - return ERR_RTP_EXTERNALTRANS_ILLEGALPARAMETERS; - } - - params = (const RTPExternalTransmissionParams *) transparams; - - if ((status = m_abortDesc.Init()) < 0) - { - return status; - } - m_abortCount = 0; - - maxpacksize = maximumpacketsize; - sender = params->GetSender(); - headersize = params->GetAdditionalHeaderSize(); - - localhostname = 0; - localhostnamelength = 0; - - waitingfordata = false; - created = true; - return 0; -} - -void RTPExternalTransmitter::Destroy() -{ - if (!init) - return; - - if (!created) - { - return; - } - - if (localhostname) - { - delete[] localhostname; - localhostname = 0; - localhostnamelength = 0; - } - - FlushPackets(); - created = false; - - if (waitingfordata) - { - m_abortDesc.SendAbortSignal(); - m_abortCount++; - m_abortDesc.Destroy(); - // to make sure that the WaitForIncomingData function ended - - } - else - m_abortDesc.Destroy(); - -} - -RTPTransmissionInfo *RTPExternalTransmitter::GetTransmissionInfo() -{ - if (!init) - return 0; - - RTPTransmissionInfo *tinf = new RTPExternalTransmissionInfo(&packetinjector); - return tinf; -} - -void RTPExternalTransmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i) -{ - if (!init) - return; - - delete i; -} - -int RTPExternalTransmitter::GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength) -{ - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (!created) - { - return ERR_RTP_EXTERNALTRANS_NOTCREATED; - } - - if (localhostname == 0) - { -// We'll just use 'gethostname' for simplicity - - char name[1024]; - - if (gethostname(name, 1023) != 0) - strcpy(name, "localhost"); // failsafe - else - name[1023] = 0; // ensure null-termination - - localhostnamelength = strlen(name); - localhostname = new uint8_t[localhostnamelength + 1]; - - memcpy(localhostname, name, localhostnamelength); - localhostname[localhostnamelength] = 0; - } - - if ((*bufferlength) < localhostnamelength) - { - *bufferlength = localhostnamelength; // tell the application the required size of the buffer - return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; - } - - memcpy(buffer, localhostname, localhostnamelength); - *bufferlength = localhostnamelength; - - return 0; -} - -bool RTPExternalTransmitter::ComesFromThisTransmitter(const RTPAddress *addr) -{ - - bool value = false; - if (sender) - value = sender->ComesFromThisSender(addr); - return value; -} - -int RTPExternalTransmitter::Poll() -{ - return 0; -} - -int RTPExternalTransmitter::WaitForIncomingData(const RTPTime &delay, bool *dataavailable) -{ - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (!created) - { - return ERR_RTP_EXTERNALTRANS_NOTCREATED; - } - if (waitingfordata) - { - return ERR_RTP_EXTERNALTRANS_ALREADYWAITING; - } - - waitingfordata = true; - - if (!rawpacketlist.empty()) - { - if (dataavailable != 0) - *dataavailable = true; - waitingfordata = false; - return 0; - } - - int8_t isset = 0; - SocketType abortSock = m_abortDesc.GetAbortSocket(); - int status = RTPSelect(&abortSock, &isset, 1, delay); - if (status < 0) - { - - waitingfordata = false; - - return status; - } - - waitingfordata = false; - if (!created) // destroy called - { - - return 0; - } - - // if aborted, read from abort buffer - if (isset) - { - m_abortDesc.ClearAbortSignal(); - m_abortCount = 0; - } - - if (dataavailable != 0) - { - if (rawpacketlist.empty()) - *dataavailable = false; - else - *dataavailable = true; - } - - return 0; -} - -int RTPExternalTransmitter::AbortWait() -{ - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (!created) - { - return ERR_RTP_EXTERNALTRANS_NOTCREATED; - } - if (!waitingfordata) - { - return ERR_RTP_EXTERNALTRANS_NOTWAITING; - } - - m_abortDesc.SendAbortSignal(); - m_abortCount++; - - return 0; -} - -int RTPExternalTransmitter::SendRTPData(const void *data, std::size_t len) -{ - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (!created) - { - return ERR_RTP_EXTERNALTRANS_NOTCREATED; - } - if (len > maxpacksize) - { - return ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG; - } - - if (!sender) - { - return ERR_RTP_EXTERNALTRANS_NOSENDER; - } - - if (!sender->SendRTP(data, len)) - return ERR_RTP_EXTERNALTRANS_SENDERROR; - - return 0; -} - -int RTPExternalTransmitter::SendRTCPData(const void *data, std::size_t len) -{ - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (!created) - { - return ERR_RTP_EXTERNALTRANS_NOTCREATED; - } - if (len > maxpacksize) - { - return ERR_RTP_EXTERNALTRANS_SPECIFIEDSIZETOOBIG; - } - - if (!sender) - { - return ERR_RTP_EXTERNALTRANS_NOSENDER; - } - - if (!sender->SendRTCP(data, len)) - return ERR_RTP_EXTERNALTRANS_SENDERROR; - - return 0; -} - -int RTPExternalTransmitter::AddDestination(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED; -} - -int RTPExternalTransmitter::DeleteDestination(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NODESTINATIONSSUPPORTED; -} - -void RTPExternalTransmitter::ClearDestinations() -{ -} - -bool RTPExternalTransmitter::SupportsMulticasting() -{ - return false; -} - -int RTPExternalTransmitter::JoinMulticastGroup(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT; -} - -int RTPExternalTransmitter::LeaveMulticastGroup(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NOMULTICASTSUPPORT; -} - -void RTPExternalTransmitter::LeaveAllMulticastGroups() -{ -} - -int RTPExternalTransmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m) -{ - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (!created) - { - return ERR_RTP_EXTERNALTRANS_NOTCREATED; - } - if (m != RTPTransmitter::AcceptAll) - { - return ERR_RTP_EXTERNALTRANS_BADRECEIVEMODE; - } - return 0; -} - -int RTPExternalTransmitter::AddToIgnoreList(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NOIGNORELIST; -} - -int RTPExternalTransmitter::DeleteFromIgnoreList(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NOIGNORELIST; -} - -void RTPExternalTransmitter::ClearIgnoreList() -{ -} - -int RTPExternalTransmitter::AddToAcceptList(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NOACCEPTLIST; -} - -int RTPExternalTransmitter::DeleteFromAcceptList(const RTPAddress &) -{ - return ERR_RTP_EXTERNALTRANS_NOACCEPTLIST; -} - -void RTPExternalTransmitter::ClearAcceptList() -{ -} - -int RTPExternalTransmitter::SetMaximumPacketSize(std::size_t s) -{ - if (!init) - return ERR_RTP_EXTERNALTRANS_NOTINIT; - - if (!created) - { - return ERR_RTP_EXTERNALTRANS_NOTCREATED; - } - maxpacksize = s; - return 0; -} - -bool RTPExternalTransmitter::NewDataAvailable() -{ - if (!init) - return false; - - bool v; - - if (!created) - v = false; - else - { - if (rawpacketlist.empty()) - v = false; - else - v = true; - } - - return v; -} - -RTPRawPacket *RTPExternalTransmitter::GetNextPacket() -{ - if (!init) - return 0; - - RTPRawPacket *p; - - if (!created) - { - return 0; - } - if (rawpacketlist.empty()) - { - return 0; - } - - p = *(rawpacketlist.begin()); - rawpacketlist.pop_front(); - - return p; -} - -// Here the private functions start... - -void RTPExternalTransmitter::FlushPackets() -{ - std::list::const_iterator it; - - for (it = rawpacketlist.begin(); it != rawpacketlist.end(); ++it) - delete *it; - rawpacketlist.clear(); -} - -void RTPExternalTransmitter::InjectRTP(const void *data, std::size_t len, const RTPAddress &a) -{ - if (!init) - return; - - if (!created) - { - return; - } - - RTPAddress *addr = a.CreateCopy(); - if (addr == 0) - return; - - uint8_t *datacopy; - - datacopy = new uint8_t[len]; - if (datacopy == 0) - { - delete addr; - return; - } - memcpy(datacopy, data, len); - - RTPTime curtime = RTPTime::CurrentTime(); - RTPRawPacket *pack; - - pack = new RTPRawPacket(datacopy, len, addr, curtime, true); - if (pack == 0) - { - delete addr; - delete[] localhostname; - return; - } - rawpacketlist.push_back(pack); - - if (m_abortCount == 0) - { - m_abortDesc.SendAbortSignal(); - m_abortCount++; - } - -} - -void RTPExternalTransmitter::InjectRTCP(const void *data, std::size_t len, const RTPAddress &a) -{ - if (!init) - return; - - if (!created) - { - return; - } - - RTPAddress *addr = a.CreateCopy(); - if (addr == 0) - return; - - uint8_t *datacopy; - - datacopy = new uint8_t[len]; - if (datacopy == 0) - { - delete addr; - return; - } - memcpy(datacopy, data, len); - - RTPTime curtime = RTPTime::CurrentTime(); - RTPRawPacket *pack; - - pack = new RTPRawPacket(datacopy, len, addr, curtime, false); - if (pack == 0) - { - delete addr; - delete[] localhostname; - return; - } - rawpacketlist.push_back(pack); - - if (m_abortCount == 0) - { - m_abortDesc.SendAbortSignal(); - m_abortCount++; - } - -} - -void RTPExternalTransmitter::InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a) -{ - if (!init) - return; - - if (!created) - { - return; - } - - RTPAddress *addr = a.CreateCopy(); - if (addr == 0) - return; - - uint8_t *datacopy; - bool rtp = true; - - if (len >= 2) - { - const uint8_t *pData = (const uint8_t *) data; - if (pData[1] >= 200 && pData[1] <= 204) - rtp = false; - } - - datacopy = new uint8_t[len]; - if (datacopy == 0) - { - delete addr; - return; - } - memcpy(datacopy, data, len); - - RTPTime curtime = RTPTime::CurrentTime(); - RTPRawPacket *pack; - - pack = new RTPRawPacket(datacopy, len, addr, curtime, rtp); - if (pack == 0) - { - delete addr; - delete[] localhostname; - return; - } - rawpacketlist.push_back(pack); - - if (m_abortCount == 0) - { - m_abortDesc.SendAbortSignal(); - m_abortCount++; - } - -} - -} // end namespace - diff --git a/qrtplib/rtpexternaltransmitter.h b/qrtplib/rtpexternaltransmitter.h deleted file mode 100644 index d937d68e4..000000000 --- a/qrtplib/rtpexternaltransmitter.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtpexternaltransmitter.h - */ - -#ifndef RTPEXTERNALTRANSMITTER_H - -#define RTPEXTERNALTRANSMITTER_H - -#include "rtpconfig.h" -#include "rtptransmitter.h" -#include "rtpabortdescriptors.h" -#include - -#include "util/export.h" - -namespace qrtplib -{ - -class RTPExternalTransmitter; - -/** Base class to specify a mechanism to transmit RTP packets outside of this library. - * Base class to specify a mechanism to transmit RTP packets outside of this library. When - * you want to use your own mechanism to transmit RTP packets, you need to specify that - * you'll be using the external transmission component, and derive a class from this base - * class. An instance should then be specified in the RTPExternalTransmissionParams object, - * so that the transmitter will call the \c SendRTP, \c SendRTCP and \c ComesFromThisSender - * methods of this instance when needed. - */ -class QRTPLIB_API RTPExternalSender -{ -public: - RTPExternalSender() - { - } - virtual ~RTPExternalSender() - { - } - - /** This member function will be called when RTP data needs to be transmitted. */ - virtual bool SendRTP(const void *data, std::size_t len) = 0; - - /** This member function will be called when an RTCP packet needs to be transmitted. */ - virtual bool SendRTCP(const void *data, std::size_t len) = 0; - - /** Used to identify if an RTPAddress instance originated from this sender (to be able to detect own packets). */ - virtual bool ComesFromThisSender(const RTPAddress *a) = 0; -}; - -/** Interface to inject incoming RTP and RTCP packets into the library. - * Interface to inject incoming RTP and RTCP packets into the library. When you have your own - * mechanism to receive incoming RTP/RTCP data, you'll need to pass these packets to the library. - * By first retrieving the RTPExternalTransmissionInfo instance for the external transmitter you'll - * be using, you can obtain the associated RTPExternalPacketInjecter instance. By calling it's - * member functions, you can then inject RTP or RTCP data into the library for further processing. - */ -class RTPExternalPacketInjecter -{ -public: - RTPExternalPacketInjecter(RTPExternalTransmitter *trans) - { - transmitter = trans; - } - ~RTPExternalPacketInjecter() - { - } - - /** This function can be called to insert an RTP packet into the transmission component. */ - void InjectRTP(const void *data, std::size_t len, const RTPAddress &a); - - /** This function can be called to insert an RTCP packet into the transmission component. */ - void InjectRTCP(const void *data, std::size_t len, const RTPAddress &a); - - /** Use this function to inject an RTP or RTCP packet and the transmitter will try to figure out which type of packet it is. */ - void InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a); -private: - RTPExternalTransmitter *transmitter; -}; - -/** Parameters to initialize a transmitter of type RTPExternalTransmitter. */ -class RTPExternalTransmissionParams: public RTPTransmissionParams -{ -public: - /** Using this constructor you can specify which RTPExternalSender object you'll be using - * and how much the additional header overhead for each packet will be. */ - RTPExternalTransmissionParams(RTPExternalSender *s, int headeroverhead) : - RTPTransmissionParams(RTPTransmitter::ExternalProto) - { - sender = s; - headersize = headeroverhead; - } - - RTPExternalSender *GetSender() const - { - return sender; - } - int GetAdditionalHeaderSize() const - { - return headersize; - } -private: - RTPExternalSender *sender; - int headersize; -}; - -/** Additional information about the external transmission component. */ -class RTPExternalTransmissionInfo: public RTPTransmissionInfo -{ -public: - RTPExternalTransmissionInfo(RTPExternalPacketInjecter *p) : - RTPTransmissionInfo(RTPTransmitter::ExternalProto) - { - packetinjector = p; - } - - /** Tells you which RTPExternalPacketInjecter you need to use to pass RTP or RTCP - * data on to the transmission component. */ - RTPExternalPacketInjecter *GetPacketInjector() const - { - return packetinjector; - } -private: - RTPExternalPacketInjecter *packetinjector; -}; - -/** A transmission component which will use user specified functions to transmit the data and - * which will expose functions to inject received RTP or RTCP data into this component. - * A transmission component which will use user specified functions to transmit the data and - * which will expose functions to inject received RTP or RTCP data into this component. Use - * a class derived from RTPExternalSender to specify the functions which need to be used for - * sending the data. Obtain the RTPExternalTransmissionInfo object associated with this - * transmitter to obtain the functions needed to pass RTP/RTCP packets on to the transmitter. - */ -class RTPExternalTransmitter: public RTPTransmitter -{ -public: - RTPExternalTransmitter(); - ~RTPExternalTransmitter(); - - int Init(bool treadsafe); - int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams); - void Destroy(); - RTPTransmissionInfo *GetTransmissionInfo(); - void DeleteTransmissionInfo(RTPTransmissionInfo *inf); - - int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength); - bool ComesFromThisTransmitter(const RTPAddress *addr); - std::size_t GetHeaderOverhead() - { - return headersize; - } - - int Poll(); - int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0); - int AbortWait(); - - int SendRTPData(const void *data, std::size_t len); - int SendRTCPData(const void *data, std::size_t len); - - int AddDestination(const RTPAddress &addr); - int DeleteDestination(const RTPAddress &addr); - void ClearDestinations(); - - bool SupportsMulticasting(); - int JoinMulticastGroup(const RTPAddress &addr); - int LeaveMulticastGroup(const RTPAddress &addr); - void LeaveAllMulticastGroups(); - - int SetReceiveMode(RTPTransmitter::ReceiveMode m); - int AddToIgnoreList(const RTPAddress &addr); - int DeleteFromIgnoreList(const RTPAddress &addr); - void ClearIgnoreList(); - int AddToAcceptList(const RTPAddress &addr); - int DeleteFromAcceptList(const RTPAddress &addr); - void ClearAcceptList(); - int SetMaximumPacketSize(std::size_t s); - - bool NewDataAvailable(); - RTPRawPacket *GetNextPacket(); - - void InjectRTP(const void *data, std::size_t len, const RTPAddress &a); - void InjectRTCP(const void *data, std::size_t len, const RTPAddress &a); - void InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a); -private: - void FlushPackets(); - - bool init; - bool created; - bool waitingfordata; - RTPExternalSender *sender; - RTPExternalPacketInjecter packetinjector; - - std::list rawpacketlist; - - uint8_t *localhostname; - std::size_t localhostnamelength; - - std::size_t maxpacksize; - int headersize; - - RTPAbortDescriptors m_abortDesc; - int m_abortCount; -}; - -inline void RTPExternalPacketInjecter::InjectRTP(const void *data, std::size_t len, const RTPAddress &a) -{ - transmitter->InjectRTP(data, len, a); -} - -inline void RTPExternalPacketInjecter::InjectRTCP(const void *data, std::size_t len, const RTPAddress &a) -{ - transmitter->InjectRTCP(data, len, a); -} - -inline void RTPExternalPacketInjecter::InjectRTPorRTCP(const void *data, std::size_t len, const RTPAddress &a) -{ - transmitter->InjectRTPorRTCP(data, len, a); -} - -} // end namespace - -#endif // RTPTCPSOCKETTRANSMITTER_H - diff --git a/qrtplib/rtphashtable.h b/qrtplib/rtphashtable.h deleted file mode 100644 index 9c98a089c..000000000 --- a/qrtplib/rtphashtable.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#ifndef RTPHASHTABLE_H - -#define RTPHASHTABLE_H - -/** - * \file rtphashtable.h - */ - -#include "rtperrors.h" - -namespace qrtplib -{ - -//template -template -class RTPHashTable -{ -public: - RTPHashTable(); - ~RTPHashTable() - { - Clear(); - } - - void GotoFirstElement() - { - curhashelem = firsthashelem; - } - void GotoLastElement() - { - curhashelem = lasthashelem; - } - bool HasCurrentElement() - { - return (curhashelem == 0) ? false : true; - } - int DeleteCurrentElement(); - Element &GetCurrentElement() - { - return curhashelem->GetElement(); - } - int GotoElement(const Element &e); - bool HasElement(const Element &e); - void GotoNextElement(); - void GotoPreviousElement(); - void Clear(); - - int AddElement(const Element &elem); - int DeleteElement(const Element &elem); - -private: - class HashElement - { - public: - HashElement(const Element &e, int index) : - element(e) - { - hashprev = 0; - hashnext = 0; - listnext = 0; - listprev = 0; - hashindex = index; - } - int GetHashIndex() - { - return hashindex; - } - Element &GetElement() - { - return element; - } - - private: - int hashindex; - Element element; - public: - HashElement *hashprev, *hashnext; - HashElement *listprev, *listnext; - }; - - HashElement *table[hashsize]; - HashElement *firsthashelem, *lasthashelem; - HashElement *curhashelem; -#ifdef RTP_SUPPORT_MEMORYMANAGEMENT - int memorytype; -#endif // RTP_SUPPORT_MEMORYMANAGEMENT -}; - -template -inline RTPHashTable::RTPHashTable() -{ - for (int i = 0; i < hashsize; i++) - table[i] = 0; - firsthashelem = 0; - lasthashelem = 0; -} - -template -inline int RTPHashTable::DeleteCurrentElement() -{ - if (curhashelem) - { - HashElement *tmp1, *tmp2; - int index; - - // First, relink elements in current hash bucket - - index = curhashelem->GetHashIndex(); - tmp1 = curhashelem->hashprev; - tmp2 = curhashelem->hashnext; - if (tmp1 == 0) // no previous element in hash bucket - { - table[index] = tmp2; - if (tmp2 != 0) - tmp2->hashprev = 0; - } - else // there is a previous element in the hash bucket - { - tmp1->hashnext = tmp2; - if (tmp2 != 0) - tmp2->hashprev = tmp1; - } - - // Relink elements in list - - tmp1 = curhashelem->listprev; - tmp2 = curhashelem->listnext; - if (tmp1 == 0) // curhashelem is first in list - { - firsthashelem = tmp2; - if (tmp2 != 0) - tmp2->listprev = 0; - else - // curhashelem is also last in list - lasthashelem = 0; - } - else - { - tmp1->listnext = tmp2; - if (tmp2 != 0) - tmp2->listprev = tmp1; - else - // curhashelem is last in list - lasthashelem = tmp1; - } - - // finally, with everything being relinked, we can delete curhashelem - delete curhashelem; - curhashelem = tmp2; // Set to next element in the list - } - else - return ERR_RTP_HASHTABLE_NOCURRENTELEMENT; - return 0; -} - -template -inline int RTPHashTable::GotoElement(const Element &e) -{ - int index; - bool found; - - index = GetIndex::GetIndex(e); - if (index >= hashsize) - return ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX; - - curhashelem = table[index]; - found = false; - while (!found && curhashelem != 0) - { - if (curhashelem->GetElement() == e) - found = true; - else - curhashelem = curhashelem->hashnext; - } - if (!found) - return ERR_RTP_HASHTABLE_ELEMENTNOTFOUND; - return 0; -} - -template -inline bool RTPHashTable::HasElement(const Element &e) -{ - int index; - bool found; - HashElement *tmp; - - index = GetIndex::GetIndex(e); - if (index >= hashsize) - return false; - - tmp = table[index]; - found = false; - while (!found && tmp != 0) - { - if (tmp->GetElement() == e) - found = true; - else - tmp = tmp->hashnext; - } - return found; -} - -template -inline void RTPHashTable::GotoNextElement() -{ - if (curhashelem) - curhashelem = curhashelem->listnext; -} - -template -inline void RTPHashTable::GotoPreviousElement() -{ - if (curhashelem) - curhashelem = curhashelem->listprev; -} - -template -inline void RTPHashTable::Clear() -{ - HashElement *tmp1, *tmp2; - - for (int i = 0; i < hashsize; i++) - table[i] = 0; - - tmp1 = firsthashelem; - while (tmp1 != 0) - { - tmp2 = tmp1->listnext; - delete tmp1; - tmp1 = tmp2; - } - firsthashelem = 0; - lasthashelem = 0; -} - -template -inline int RTPHashTable::AddElement(const Element &elem) -{ - int index; - bool found; - HashElement *e, *newelem; - - index = GetIndex::GetIndex(elem); - if (index >= hashsize) - return ERR_RTP_HASHTABLE_FUNCTIONRETURNEDINVALIDHASHINDEX; - - e = table[index]; - found = false; - while (!found && e != 0) - { - if (e->GetElement() == elem) - found = true; - else - e = e->hashnext; - } - if (found) - return ERR_RTP_HASHTABLE_ELEMENTALREADYEXISTS; - - // Okay, the key doesn't exist, so we can add the new element in the hash table - - newelem = new HashElement(elem, index); - if (newelem == 0) - return ERR_RTP_OUTOFMEM; - - e = table[index]; - table[index] = newelem; - newelem->hashnext = e; - if (e != 0) - e->hashprev = newelem; - - // Now, we still got to add it to the linked list - - if (firsthashelem == 0) - { - firsthashelem = newelem; - lasthashelem = newelem; - } - else // there already are some elements in the list - { - lasthashelem->listnext = newelem; - newelem->listprev = lasthashelem; - lasthashelem = newelem; - } - return 0; -} - -template -inline int RTPHashTable::DeleteElement(const Element &elem) -{ - int status; - - status = GotoElement(elem); - if (status < 0) - return status; - return DeleteCurrentElement(); -} - -} // end namespace - -#endif // RTPHASHTABLE_H - diff --git a/qrtplib/rtpipv4address.cpp b/qrtplib/rtpipv4address.cpp deleted file mode 100644 index 6a204259e..000000000 --- a/qrtplib/rtpipv4address.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtpipv4address.h" - -namespace qrtplib -{ - -bool RTPIPv4Address::IsSameAddress(const RTPAddress *addr) const -{ - if (addr == 0) - return false; - if (addr->GetAddressType() != IPv4Address) - return false; - - const RTPIPv4Address *addr2 = (const RTPIPv4Address *) addr; - if (addr2->GetIP() == ip && addr2->GetPort() == port) - return true; - return false; -} - -bool RTPIPv4Address::IsFromSameHost(const RTPAddress *addr) const -{ - if (addr == 0) - return false; - if (addr->GetAddressType() != IPv4Address) - return false; - - const RTPIPv4Address *addr2 = (const RTPIPv4Address *) addr; - if (addr2->GetIP() == ip) - return true; - return false; -} - -RTPAddress *RTPIPv4Address::CreateCopy() const -{ - RTPIPv4Address *a = new RTPIPv4Address(ip, port); - return a; -} - -} // end namespace - diff --git a/qrtplib/rtpipv4address.h b/qrtplib/rtpipv4address.h deleted file mode 100644 index 0253d9be3..000000000 --- a/qrtplib/rtpipv4address.h +++ /dev/null @@ -1,176 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtpipv4address.h - */ - -#ifndef RTPIPV4ADDRESS_H - -#define RTPIPV4ADDRESS_H - -#include "rtpconfig.h" -#include "rtpaddress.h" -#include "rtptypes.h" - -#include "util/export.h" - -namespace qrtplib -{ - -/** Represents an IPv4 IP address and port. - * This class is used by the UDP over IPv4 transmission component. - * When an RTPIPv4Address is used in one of the multicast functions of the transmitter, the port - * number is ignored. When an instance is used in one of the accept or ignore functions of the - * transmitter, a zero port number represents all ports for the specified IP address. - */ -class QRTPLIB_API RTPIPv4Address: public RTPAddress -{ -public: - /** Creates an instance with IP address \c ip and port number \c port (both - * are interpreted in host byte order), and possibly sets the RTCP multiplex flag - * (see RTPIPv4Address::UseRTCPMultiplexingOnTransmission). */ - RTPIPv4Address(uint32_t ip = 0, uint16_t port = 0, bool rtcpmux = false) : - RTPAddress(IPv4Address) - { - RTPIPv4Address::ip = ip; - RTPIPv4Address::port = port; - if (rtcpmux) - rtcpsendport = port; - else - rtcpsendport = port + 1; - } - - /** Creates an instance with IP address \c ip and port number \c port (both - * are interpreted in host byte order), and sets a specific port to - * send RTCP packets to (see RTPIPv4Address::GetRTCPSendPort). */ - RTPIPv4Address(uint32_t ip, uint16_t port, uint16_t rtcpsendport) : - RTPAddress(IPv4Address) - { - RTPIPv4Address::ip = ip; - RTPIPv4Address::port = port; - RTPIPv4Address::rtcpsendport = rtcpsendport; - } - - /** Creates an instance with IP address \c ip and port number \c port (\c port is - * interpreted in host byte order) and possibly sets the RTCP multiplex flag - * (see RTPIPv4Address::UseRTCPMultiplexingOnTransmission). */ - RTPIPv4Address(const uint8_t ip[4], uint16_t port = 0, bool rtcpmux = false) : - RTPAddress(IPv4Address) - { - RTPIPv4Address::ip = (uint32_t) ip[3]; - RTPIPv4Address::ip |= (((uint32_t) ip[2]) << 8); - RTPIPv4Address::ip |= (((uint32_t) ip[1]) << 16); - RTPIPv4Address::ip |= (((uint32_t) ip[0]) << 24); - - RTPIPv4Address::port = port; - if (rtcpmux) - rtcpsendport = port; - else - rtcpsendport = port + 1; - } - - /** Creates an instance with IP address \c ip and port number \c port (both - * are interpreted in host byte order), and sets a specific port to - * send RTCP packets to (see RTPIPv4Address::GetRTCPSendPort). */ - RTPIPv4Address(const uint8_t ip[4], uint16_t port, uint16_t rtcpsendport) : - RTPAddress(IPv4Address) - { - RTPIPv4Address::ip = (uint32_t) ip[3]; - RTPIPv4Address::ip |= (((uint32_t) ip[2]) << 8); - RTPIPv4Address::ip |= (((uint32_t) ip[1]) << 16); - RTPIPv4Address::ip |= (((uint32_t) ip[0]) << 24); - - RTPIPv4Address::port = port; - RTPIPv4Address::rtcpsendport = rtcpsendport; - } - - ~RTPIPv4Address() - { - } - - /** Sets the IP address for this instance to \c ip which is assumed to be in host byte order. */ - void SetIP(uint32_t ip) - { - RTPIPv4Address::ip = ip; - } - - /** Sets the IP address of this instance to \c ip. */ - void SetIP(const uint8_t ip[4]) - { - RTPIPv4Address::ip = (uint32_t) ip[3]; - RTPIPv4Address::ip |= (((uint32_t) ip[2]) << 8); - RTPIPv4Address::ip |= (((uint32_t) ip[1]) << 16); - RTPIPv4Address::ip |= (((uint32_t) ip[0]) << 24); - } - - /** Sets the port number for this instance to \c port which is interpreted in host byte order. */ - void SetPort(uint16_t port) - { - RTPIPv4Address::port = port; - } - - /** Returns the IP address contained in this instance in host byte order. */ - uint32_t GetIP() const - { - return ip; - } - - /** Returns the port number of this instance in host byte order. */ - uint16_t GetPort() const - { - return port; - } - - /** For outgoing packets, this indicates to which port RTCP packets will be sent (can, - * be the same port as the RTP packets in case RTCP multiplexing is used). */ - uint16_t GetRTCPSendPort() const - { - return rtcpsendport; - } - - RTPAddress *CreateCopy() const; - - // Note that these functions are only used for received packets, and for those - // the rtcpsendport variable is not important and should be ignored. - bool IsSameAddress(const RTPAddress *addr) const; - bool IsFromSameHost(const RTPAddress *addr) const; -private: - uint32_t ip; - uint16_t port; - uint16_t rtcpsendport; -}; - -} // end namespace - -#endif // RTPIPV4ADDRESS_H - diff --git a/qrtplib/rtpipv4destination.cpp b/qrtplib/rtpipv4destination.cpp deleted file mode 100644 index ad5047baf..000000000 --- a/qrtplib/rtpipv4destination.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2011 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtpipv4destination.h" -#include "rtpinternalutils.h" - -namespace qrtplib -{ - -std::string RTPIPv4Destination::GetDestinationString() const -{ - char str[24]; - uint32_t ip = GetIP(); - uint16_t portbase = ntohs(GetRTPPort_NBO()); - - RTP_SNPRINTF(str, 24, "%d.%d.%d.%d:%d", (int) ((ip >> 24) & 0xFF), (int) ((ip >> 16) & 0xFF), (int) ((ip >> 8) & 0xFF), (int) (ip & 0xFF), (int) (portbase)); - return std::string(str); -} - -} // end namespace - diff --git a/qrtplib/rtpipv4destination.h b/qrtplib/rtpipv4destination.h deleted file mode 100644 index 32491bdcc..000000000 --- a/qrtplib/rtpipv4destination.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtpipv4destination.h - */ - -#ifndef RTPIPV4DESTINATION_H - -#define RTPIPV4DESTINATION_H - -#include "rtpconfig.h" -#include "rtptypes.h" -#include "rtpipv4address.h" -#ifndef RTP_SOCKETTYPE_WINSOCK -#include -#include -#include -#endif // RTP_SOCKETTYPE_WINSOCK -#include -#include - -#include "util/export.h" - -namespace qrtplib -{ - -class QRTPLIB_API RTPIPv4Destination -{ -public: - RTPIPv4Destination() - { - ip = 0; - memset(&rtpaddr, 0, sizeof(struct sockaddr_in)); - memset(&rtcpaddr, 0, sizeof(struct sockaddr_in)); - } - - RTPIPv4Destination(uint32_t ip, uint16_t rtpport, uint16_t rtcpport) - { - memset(&rtpaddr, 0, sizeof(struct sockaddr_in)); - memset(&rtcpaddr, 0, sizeof(struct sockaddr_in)); - - rtpaddr.sin_family = AF_INET; - rtpaddr.sin_port = htons(rtpport); - rtpaddr.sin_addr.s_addr = htonl(ip); - - rtcpaddr.sin_family = AF_INET; - rtcpaddr.sin_port = htons(rtcpport); - rtcpaddr.sin_addr.s_addr = htonl(ip); - - RTPIPv4Destination::ip = ip; - } - - bool operator==(const RTPIPv4Destination &src) const - { - if (rtpaddr.sin_addr.s_addr == src.rtpaddr.sin_addr.s_addr && rtpaddr.sin_port == src.rtpaddr.sin_port) - return true; - return false; - } - uint32_t GetIP() const - { - return ip; - } - // nbo = network byte order - uint32_t GetIP_NBO() const - { - return rtpaddr.sin_addr.s_addr; - } - uint16_t GetRTPPort_NBO() const - { - return rtpaddr.sin_port; - } - uint16_t GetRTCPPort_NBO() const - { - return rtcpaddr.sin_port; - } - const struct sockaddr_in *GetRTPSockAddr() const - { - return &rtpaddr; - } - const struct sockaddr_in *GetRTCPSockAddr() const - { - return &rtcpaddr; - } - std::string GetDestinationString() const; - - static bool AddressToDestination(const RTPAddress &addr, RTPIPv4Destination &dest) - { - if (addr.GetAddressType() != RTPAddress::IPv4Address) - return false; - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - uint16_t rtpport = address.GetPort(); - uint16_t rtcpport = address.GetRTCPSendPort(); - - dest = RTPIPv4Destination(address.GetIP(), rtpport, rtcpport); - return true; - } - -private: - uint32_t ip; - struct sockaddr_in rtpaddr; - struct sockaddr_in rtcpaddr; -}; - -} // end namespace - -#endif // RTPIPV4DESTINATION_H - diff --git a/qrtplib/rtplibraryversion.cpp b/qrtplib/rtplibraryversion.cpp deleted file mode 100644 index 447cef4b7..000000000 --- a/qrtplib/rtplibraryversion.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtplibraryversion.h" -#include "rtpdefines.h" -#include "rtplibraryversioninternal.h" -#include "rtpinternalutils.h" -#include - -namespace qrtplib -{ - -RTPLibraryVersion RTPLibraryVersion::GetVersion() -{ - return RTPLibraryVersion(JRTPLIB_VERSION_MAJOR, JRTPLIB_VERSION_MINOR, JRTPLIB_VERSION_DEBUG); -} - -std::string RTPLibraryVersion::GetVersionString() const -{ - char str[16]; - - RTP_SNPRINTF(str, 16, "%d.%d.%d", majornr, minornr, debugnr); - - return std::string(str); -} - -} // end namespace - diff --git a/qrtplib/rtplibraryversion.h b/qrtplib/rtplibraryversion.h deleted file mode 100644 index 8f46255f6..000000000 --- a/qrtplib/rtplibraryversion.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtplibraryversion.h - */ - -#ifndef RTPLIBRARYVERSION_H - -#define RTPLIBRARYVERSION_H - -#include "rtpconfig.h" -#include -#include - -#include "util/export.h" - -namespace qrtplib -{ - -/** - * Used to provide information about the version of the library. - */ -class QRTPLIB_API RTPLibraryVersion -{ -public: - /** Returns an instance of RTPLibraryVersion describing the version of the library. */ - static RTPLibraryVersion GetVersion(); -private: - RTPLibraryVersion(int major, int minor, int debug) - { - majornr = major; - minornr = minor; - debugnr = debug; - } -public: - /** Returns the major version number. */ - int GetMajorNumber() const - { - return majornr; - } - - /** Returns the minor version number. */ - int GetMinorNumber() const - { - return minornr; - } - - /** Returns the debug version number. */ - int GetDebugNumber() const - { - return debugnr; - } - - /** Returns a string describing the library version. */ - std::string GetVersionString() const; -private: - int debugnr, minornr, majornr; -}; - -} // end namespace - -#endif // RTPLIBRARYVERSION_H - diff --git a/qrtplib/rtpselect.h b/qrtplib/rtpselect.h deleted file mode 100644 index 679cef0cf..000000000 --- a/qrtplib/rtpselect.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtpselect.h - */ - -#ifndef RTPSELECT_H - -#define RTPSELECT_H - -#include "rtpconfig.h" -#include "rtptypes.h" -#include "rtperrors.h" -#include "rtptimeutilities.h" -#include "rtpsocketutil.h" - -#if defined(RTP_HAVE_WSAPOLL) || defined(RTP_HAVE_POLL) - -#ifndef RTP_HAVE_WSAPOLL -#include -#include -#endif // !RTP_HAVE_WSAPOLL - -#include -#include - -namespace qrtplib -{ - -inline int RTPSelect(const SocketType *sockets, int8_t *readflags, std::size_t numsocks, RTPTime timeout) -{ - using namespace std; - - vector fds(numsocks); - - for (std::size_t i = 0; i < numsocks; i++) - { - fds[i].fd = sockets[i]; - fds[i].events = POLLIN; - fds[i].revents = 0; - readflags[i] = 0; - } - - int timeoutmsec = -1; - if (timeout.GetDouble() >= 0) - { - double dtimeoutmsec = timeout.GetDouble() * 1000.0; - if (dtimeoutmsec > (numeric_limits::max)()) // parentheses to prevent windows 'max' macro expansion - dtimeoutmsec = (numeric_limits::max)(); - - timeoutmsec = (int) dtimeoutmsec; - } - -#ifdef RTP_HAVE_WSAPOLL - int status = WSAPoll(&(fds[0]), (ULONG)numsocks, timeoutmsec); - if (status < 0) - return ERR_RTP_SELECT_ERRORINPOLL; -#else - int status = poll(&(fds[0]), numsocks, timeoutmsec); - if (status < 0) - { - // We're just going to ignore an EINTR - if (errno == EINTR) - return 0; - return ERR_RTP_SELECT_ERRORINPOLL; - } -#endif // RTP_HAVE_WSAPOLL - - if (status > 0) - { - for (std::size_t i = 0; i < numsocks; i++) - { - if (fds[i].revents) - readflags[i] = 1; - } - } - return status; -} - -} // end namespace - -#else - -#ifndef RTP_SOCKETTYPE_WINSOCK -#include -#include -#include -#include -#endif // !RTP_SOCKETTYPE_WINSOCK - -namespace qrtplib -{ - - /** Wrapper function around 'select', 'poll' or 'WSAPoll', depending on the - * availability on your platform. - * - * Wrapper function around 'select', 'poll' or 'WSAPoll', depending on the - * availability on your platform. The function will check the specified - * `sockets` for incoming data and sets the flags in `readflags` if so. - * A maximum time `timeout` will be waited for data to arrive, which is - * indefinitely if set to a negative value. The function returns the number - * of sockets that have data incoming. - */ - inline int RTPSelect(const SocketType *sockets, int8_t *readflags, std::size_t numsocks, RTPTime timeout) - { - struct timeval tv; - struct timeval *pTv = 0; - - if (timeout.GetDouble() >= 0) - { - tv.tv_sec = (long)timeout.GetSeconds(); - tv.tv_usec = timeout.GetMicroSeconds(); - pTv = &tv; - } - - fd_set fdset; - FD_ZERO(&fdset); - for (std::size_t i = 0; i < numsocks; i++) - { -#ifndef RTP_SOCKETTYPE_WINSOCK - const int setsize = FD_SETSIZE; - // On windows it seems that comparing the socket value to FD_SETSIZE does - // not make sense - if (sockets[i] >= setsize) - return ERR_RTP_SELECT_SOCKETDESCRIPTORTOOLARGE; -#endif // RTP_SOCKETTYPE_WINSOCK - FD_SET(sockets[i], &fdset); - readflags[i] = 0; - } - - int status = select(FD_SETSIZE, &fdset, 0, 0, pTv); -#ifdef RTP_SOCKETTYPE_WINSOCK - if (status < 0) - return ERR_RTP_SELECT_ERRORINSELECT; -#else - if (status < 0) - { - // We're just going to ignore an EINTR - if (errno == EINTR) - return 0; - return ERR_RTP_SELECT_ERRORINSELECT; - } -#endif // RTP_HAVE_WSAPOLL - - if (status > 0) // some descriptors were set, check them - { - for (std::size_t i = 0; i < numsocks; i++) - { - if (FD_ISSET(sockets[i], &fdset)) - readflags[i] = 1; - } - } - return status; - } - -} // end namespace - -#endif // RTP_HAVE_POLL || RTP_HAVE_WSAPOLL - -#endif // RTPSELECT_H diff --git a/qrtplib/rtpsession.h b/qrtplib/rtpsession.h index 2ad288a44..e81994c7a 100644 --- a/qrtplib/rtpsession.h +++ b/qrtplib/rtpsession.h @@ -39,7 +39,6 @@ #define RTPSESSION_H #include "rtpconfig.h" -#include "rtplibraryversion.h" #include "rtppacketbuilder.h" #include "rtpsessionsources.h" #include "rtptransmitter.h" diff --git a/qrtplib/rtptcpaddress.cpp b/qrtplib/rtptcpaddress.cpp deleted file mode 100644 index 7ea9ead54..000000000 --- a/qrtplib/rtptcpaddress.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtptcpaddress.h" - -namespace qrtplib -{ - -bool RTPTCPAddress::IsSameAddress(const RTPAddress *addr) const -{ - if (addr == 0) - return false; - if (addr->GetAddressType() != TCPAddress) - return false; - - const RTPTCPAddress *a = static_cast(addr); - - // We're using a socket to identify connections - if (a->m_socket == m_socket) - return true; - - return false; -} - -bool RTPTCPAddress::IsFromSameHost(const RTPAddress *addr) const -{ - return IsSameAddress(addr); -} - -RTPAddress *RTPTCPAddress::CreateCopy() const -{ - RTPTCPAddress *a = new RTPTCPAddress(m_socket); - return a; -} - -} // end namespace - diff --git a/qrtplib/rtptcpaddress.h b/qrtplib/rtptcpaddress.h deleted file mode 100644 index ba3a50bd1..000000000 --- a/qrtplib/rtptcpaddress.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtptcpaddress.h - */ - -#ifndef RTPTCPADDRESS_H - -#define RTPTCPADDRESS_H - -#include "rtpconfig.h" -#include "rtpaddress.h" -#include "rtptypes.h" -#include "rtpsocketutil.h" - -#include "util/export.h" - -namespace qrtplib -{ -/** Represents a TCP 'address' and port. - * This class is used by the TCP transmission component, to specify which sockets - * should be used to send/receive data, and to know on which socket incoming data - * was received. - */ -class QRTPLIB_API RTPTCPAddress: public RTPAddress -{ -public: - /** Creates an instance with which you can use a specific socket - * in the TCP transmitter (must be connected). */ - RTPTCPAddress(SocketType sock) : - RTPAddress(TCPAddress) - { - m_socket = sock; - } - - ~RTPTCPAddress() - { - } - - /** Returns the socket that was specified in the constructor. */ - SocketType GetSocket() const - { - return m_socket; - } - - RTPAddress *CreateCopy() const; - - // Note that these functions are only used for received packets - bool IsSameAddress(const RTPAddress *addr) const; - bool IsFromSameHost(const RTPAddress *addr) const; - -private: - SocketType m_socket; -}; - -} // end namespace - -#endif // RTPTCPADDRESS_H - diff --git a/qrtplib/rtptcptransmitter.cpp b/qrtplib/rtptcptransmitter.cpp deleted file mode 100644 index 411c6f56a..000000000 --- a/qrtplib/rtptcptransmitter.cpp +++ /dev/null @@ -1,831 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtptcptransmitter.h" -#include "rtprawpacket.h" -#include "rtptcpaddress.h" -#include "rtptimeutilities.h" -#include "rtpdefines.h" -#include "rtpstructs.h" -#include "rtpsocketutilinternal.h" -#include "rtpinternalutils.h" -#include "rtpselect.h" -#include -#include -#include - -#include - -using namespace std; - -#define RTPTCPTRANS_MAXPACKSIZE 65535 - -namespace qrtplib -{ - -RTPTCPTransmitter::RTPTCPTransmitter() -{ - m_created = false; - m_init = false; -} - -RTPTCPTransmitter::~RTPTCPTransmitter() -{ - Destroy(); -} - -int RTPTCPTransmitter::Init(bool tsafe) -{ - if (m_init) - return ERR_RTP_TCPTRANS_ALREADYINIT; - - if (tsafe) - return ERR_RTP_NOTHREADSUPPORT; - - m_maxPackSize = RTPTCPTRANS_MAXPACKSIZE; - m_init = true; - return 0; -} - -int RTPTCPTransmitter::Create(std::size_t maximumpacketsize __attribute__((unused)), const RTPTransmissionParams *transparams) -{ - const RTPTCPTransmissionParams *params, defaultparams; - int status; - - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (m_created) - { - return ERR_RTP_TCPTRANS_ALREADYCREATED; - } - - // Obtain transmission parameters - - if (transparams == 0) - params = &defaultparams; - else - { - if (transparams->GetTransmissionProtocol() != RTPTransmitter::TCPProto) - { - return ERR_RTP_TCPTRANS_ILLEGALPARAMETERS; - } - params = static_cast(transparams); - } - - if (!params->GetCreatedAbortDescriptors()) - { - if ((status = m_abortDesc.Init()) < 0) - { - return status; - } - m_pAbortDesc = &m_abortDesc; - } - else - { - m_pAbortDesc = params->GetCreatedAbortDescriptors(); - if (!m_pAbortDesc->IsInitialized()) - { - return ERR_RTP_ABORTDESC_NOTINIT; - } - } - - m_waitingForData = false; - m_created = true; - return 0; -} - -void RTPTCPTransmitter::Destroy() -{ - if (!m_init) - return; - - if (!m_created) - { - return; - } - - ClearDestSockets(); - FlushPackets(); - m_created = false; - - if (m_waitingForData) - { - m_pAbortDesc->SendAbortSignal(); - m_abortDesc.Destroy(); // Doesn't do anything if not initialized - // to make sure that the WaitForIncomingData function ended - - } - else - m_abortDesc.Destroy(); // Doesn't do anything if not initialized - -} - -RTPTransmissionInfo *RTPTCPTransmitter::GetTransmissionInfo() -{ - if (!m_init) - return 0; - - RTPTransmissionInfo *tinf = new RTPTCPTransmissionInfo(); - return tinf; -} - -void RTPTCPTransmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i) -{ - if (!m_init) - return; - - delete i; -} - -int RTPTCPTransmitter::GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength) -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - return ERR_RTP_TCPTRANS_NOTCREATED; - } - - if (m_localHostname.size() == 0) - { -// -// TODO -// TODO -// TODO -// TODO -// - m_localHostname.resize(9); - memcpy(&m_localHostname[0], "localhost", m_localHostname.size()); - } - - if ((*bufferlength) < m_localHostname.size()) - { - *bufferlength = m_localHostname.size(); // tell the application the required size of the buffer - return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; - } - - memcpy(buffer, &m_localHostname[0], m_localHostname.size()); - *bufferlength = m_localHostname.size(); - - return 0; -} - -bool RTPTCPTransmitter::ComesFromThisTransmitter(const RTPAddress *addr) -{ - if (!m_init) - return false; - - if (addr == 0) - return false; - - if (!m_created) - return false; - - if (addr->GetAddressType() != RTPAddress::TCPAddress) - return false; - - bool v = false; - - // TODO: for now, we're assuming that we can't just send to the same transmitter - - return v; -} - -int RTPTCPTransmitter::Poll() -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - return ERR_RTP_TCPTRANS_NOTCREATED; - } - - std::map::iterator it = m_destSockets.begin(); - std::map::iterator end = m_destSockets.end(); - int status = 0; - - vector errSockets; - - while (it != end) - { - SocketType sock = it->first; - status = PollSocket(sock, it->second); - if (status < 0) - { - // Stop immediately on out of memory - if (status == ERR_RTP_OUTOFMEM) - break; - else - { - errSockets.push_back(sock); - // Don't let this count as an error (due to a closed connection for example), - // otherwise the poll thread (if used) will stop because of this. Since there - // may be more than one connection, that's not desirable in general. - status = 0; - } - } - ++it; - } - - for (std::size_t i = 0; i < errSockets.size(); i++) - OnReceiveError(errSockets[i]); - - return status; -} - -int RTPTCPTransmitter::WaitForIncomingData(const RTPTime &delay, bool *dataavailable) -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - return ERR_RTP_TCPTRANS_NOTCREATED; - } - if (m_waitingForData) - { - return ERR_RTP_TCPTRANS_ALREADYWAITING; - } - - m_tmpSocks.resize(m_destSockets.size() + 1); - m_tmpFlags.resize(m_tmpSocks.size()); - SocketType abortSocket = m_pAbortDesc->GetAbortSocket(); - - std::map::iterator it = m_destSockets.begin(); - std::map::iterator end = m_destSockets.end(); - int idx = 0; - - while (it != end) - { - m_tmpSocks[idx] = it->first; - m_tmpFlags[idx] = 0; - ++it; - idx++; - } - m_tmpSocks[idx] = abortSocket; - m_tmpFlags[idx] = 0; - int idxAbort = idx; - - m_waitingForData = true; - - //cout << "Waiting for " << delay.GetDouble() << " seconds for data on " << m_tmpSocks.size() << " sockets" << endl; - int status = RTPSelect(&m_tmpSocks[0], &m_tmpFlags[0], m_tmpSocks.size(), delay); - if (status < 0) - { - m_waitingForData = false; - - return status; - } - - m_waitingForData = false; - if (!m_created) // destroy called - { - - return 0; - } - - // if aborted, read from abort buffer - if (m_tmpFlags[idxAbort]) - m_pAbortDesc->ReadSignallingByte(); - - if (dataavailable != 0) - { - bool avail = false; - - for (std::size_t i = 0; i < m_tmpFlags.size(); i++) - { - if (m_tmpFlags[i]) - { - avail = true; - //cout << "Data available!" << endl; - break; - } - } - - if (avail) - *dataavailable = true; - else - *dataavailable = false; - } - - return 0; -} - -int RTPTCPTransmitter::AbortWait() -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - return ERR_RTP_TCPTRANS_NOTCREATED; - } - if (!m_waitingForData) - { - return ERR_RTP_TCPTRANS_NOTWAITING; - } - - m_pAbortDesc->SendAbortSignal(); - - return 0; -} - -int RTPTCPTransmitter::SendRTPData(const void *data, std::size_t len) -{ - return SendRTPRTCPData(data, len); -} - -int RTPTCPTransmitter::SendRTCPData(const void *data, std::size_t len) -{ - return SendRTPRTCPData(data, len); -} - -int RTPTCPTransmitter::AddDestination(const RTPAddress &addr) -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - return ERR_RTP_TCPTRANS_NOTCREATED; - } - - if (addr.GetAddressType() != RTPAddress::TCPAddress) - { - return ERR_RTP_TCPTRANS_INVALIDADDRESSTYPE; - } - - const RTPTCPAddress &a = static_cast(addr); - SocketType s = a.GetSocket(); - if (s == 0) - { - return ERR_RTP_TCPTRANS_NOSOCKETSPECIFIED; - } - - int status = ValidateSocket(s); - if (status != 0) - { - - return status; - } - - std::map::iterator it = m_destSockets.find(s); - if (it != m_destSockets.end()) - { - - return ERR_RTP_TCPTRANS_SOCKETALREADYINDESTINATIONS; - } - m_destSockets[s] = SocketData(); - - // Because the sockets are also used for incoming data, we'll abort a wait - // that may be in progress, otherwise it could take a few seconds until the - // new socket is monitored for incoming data - m_pAbortDesc->SendAbortSignal(); - - return 0; -} - -int RTPTCPTransmitter::DeleteDestination(const RTPAddress &addr) -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - - return ERR_RTP_TCPTRANS_NOTCREATED; - } - - if (addr.GetAddressType() != RTPAddress::TCPAddress) - { - - return ERR_RTP_TCPTRANS_INVALIDADDRESSTYPE; - } - - const RTPTCPAddress &a = static_cast(addr); - SocketType s = a.GetSocket(); - if (s == 0) - { - - return ERR_RTP_TCPTRANS_NOSOCKETSPECIFIED; - } - - std::map::iterator it = m_destSockets.find(s); - if (it == m_destSockets.end()) - { - - return ERR_RTP_TCPTRANS_SOCKETNOTFOUNDINDESTINATIONS; - } - - // Clean up possibly allocated memory - uint8_t *pBuf = it->second.ExtractDataBuffer(); - if (pBuf) - delete[] pBuf; - - m_destSockets.erase(it); - - return 0; -} - -void RTPTCPTransmitter::ClearDestinations() -{ - if (!m_init) - return; - - if (m_created) - ClearDestSockets(); - -} - -bool RTPTCPTransmitter::SupportsMulticasting() -{ - return false; -} - -int RTPTCPTransmitter::JoinMulticastGroup(const RTPAddress &) -{ - return ERR_RTP_TCPTRANS_NOMULTICASTSUPPORT; -} - -int RTPTCPTransmitter::LeaveMulticastGroup(const RTPAddress &) -{ - return ERR_RTP_TCPTRANS_NOMULTICASTSUPPORT; -} - -void RTPTCPTransmitter::LeaveAllMulticastGroups() -{ -} - -int RTPTCPTransmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m) -{ - if (m != RTPTransmitter::AcceptAll) - return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED; - return 0; -} - -int RTPTCPTransmitter::AddToIgnoreList(const RTPAddress &) -{ - return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED; -} - -int RTPTCPTransmitter::DeleteFromIgnoreList(const RTPAddress &) -{ - return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED; -} - -void RTPTCPTransmitter::ClearIgnoreList() -{ -} - -int RTPTCPTransmitter::AddToAcceptList(const RTPAddress &) -{ - return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED; -} - -int RTPTCPTransmitter::DeleteFromAcceptList(const RTPAddress &) -{ - return ERR_RTP_TCPTRANS_RECEIVEMODENOTSUPPORTED; -} - -void RTPTCPTransmitter::ClearAcceptList() -{ -} - -int RTPTCPTransmitter::SetMaximumPacketSize(std::size_t s) -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - - return ERR_RTP_TCPTRANS_NOTCREATED; - } - if (s > RTPTCPTRANS_MAXPACKSIZE) - { - - return ERR_RTP_TCPTRANS_SPECIFIEDSIZETOOBIG; - } - m_maxPackSize = s; - - return 0; -} - -bool RTPTCPTransmitter::NewDataAvailable() -{ - if (!m_init) - return false; - - bool v; - - if (!m_created) - v = false; - else - { - if (m_rawpacketlist.empty()) - v = false; - else - v = true; - } - - return v; -} - -RTPRawPacket *RTPTCPTransmitter::GetNextPacket() -{ - if (!m_init) - return 0; - - RTPRawPacket *p; - - if (!m_created) - { - - return 0; - } - if (m_rawpacketlist.empty()) - { - - return 0; - } - - p = *(m_rawpacketlist.begin()); - m_rawpacketlist.pop_front(); - - return p; -} - -// Here the private functions start... - -void RTPTCPTransmitter::FlushPackets() -{ - std::list::const_iterator it; - - for (it = m_rawpacketlist.begin(); it != m_rawpacketlist.end(); ++it) - delete *it; - m_rawpacketlist.clear(); -} - -int RTPTCPTransmitter::PollSocket(SocketType sock, SocketData &sdata) -{ -#ifdef RTP_SOCKETTYPE_WINSOCK - unsigned long len; -#else - std::size_t len; -#endif // RTP_SOCKETTYPE_WINSOCK - bool dataavailable; - - do - { - len = 0; - RTPIOCTL(sock, FIONREAD, &len); - - if (len <= 0) - dataavailable = false; - else - dataavailable = true; - - if (dataavailable) - { - RTPTime curtime = RTPTime::CurrentTime(); - int relevantLen = RTPTCPTRANS_MAXPACKSIZE + 2; - - if ((int) len < relevantLen) - relevantLen = (int) len; - - bool complete = false; - int status = sdata.ProcessAvailableBytes(sock, relevantLen, complete); - if (status < 0) - return status; - - if (complete) - { - uint8_t *pBuf = sdata.ExtractDataBuffer(); - if (pBuf) - { - int dataLength = sdata.m_dataLength; - sdata.Reset(); - - RTPTCPAddress *pAddr = new RTPTCPAddress(sock); - if (pAddr == 0) - return ERR_RTP_OUTOFMEM; - - bool isrtp = true; - if (dataLength > (int) sizeof(RTCPCommonHeader)) - { - RTCPCommonHeader *rtcpheader = (RTCPCommonHeader *) pBuf; - uint8_t packettype = rtcpheader->packettype; - - if (packettype >= 200 && packettype <= 204) - isrtp = false; - } - - RTPRawPacket *pPack = new RTPRawPacket(pBuf, dataLength, pAddr, curtime, isrtp); - if (pPack == 0) - { - delete pAddr; - delete[] pBuf; - return ERR_RTP_OUTOFMEM; - } - m_rawpacketlist.push_back(pPack); - } - } - } - } while (dataavailable); - - return 0; -} - -int RTPTCPTransmitter::SendRTPRTCPData(const void *data, std::size_t len) -{ - if (!m_init) - return ERR_RTP_TCPTRANS_NOTINIT; - - if (!m_created) - { - - return ERR_RTP_TCPTRANS_NOTCREATED; - } - if (len > RTPTCPTRANS_MAXPACKSIZE) - { - - return ERR_RTP_TCPTRANS_SPECIFIEDSIZETOOBIG; - } - - std::map::iterator it = m_destSockets.begin(); - std::map::iterator end = m_destSockets.end(); - - vector errSockets; - int flags = 0; -#ifdef RTP_HAVE_MSG_NOSIGNAL - flags = MSG_NOSIGNAL; -#endif // RTP_HAVE_MSG_NOSIGNAL - - while (it != end) - { - uint8_t lengthBytes[2] = - { (uint8_t) ((len >> 8) & 0xff), (uint8_t) (len & 0xff) }; - SocketType sock = it->first; - - if (send(sock, (const char *) lengthBytes, 2, flags) < 0 || send(sock, (const char *) data, len, flags) < 0) - errSockets.push_back(sock); - ++it; - } - - if (errSockets.size() != 0) - { - for (std::size_t i = 0; i < errSockets.size(); i++) - OnSendError(errSockets[i]); - } - - // Don't return an error code to avoid the poll thread exiting - // due to one closed connection for example - - return 0; -} - -int RTPTCPTransmitter::ValidateSocket(SocketType) -{ - // TODO: should we even do a check (for a TCP socket)? - return 0; -} - -void RTPTCPTransmitter::ClearDestSockets() -{ - std::map::iterator it = m_destSockets.begin(); - std::map::iterator end = m_destSockets.end(); - - while (it != end) - { - uint8_t *pBuf = it->second.ExtractDataBuffer(); - if (pBuf) - delete[] pBuf; - - ++it; - } - m_destSockets.clear(); -} - -RTPTCPTransmitter::SocketData::SocketData() -{ - Reset(); -} - -void RTPTCPTransmitter::SocketData::Reset() -{ - m_lengthBufferOffset = 0; - m_dataLength = 0; - m_dataBufferOffset = 0; - m_pDataBuffer = 0; -} - -RTPTCPTransmitter::SocketData::~SocketData() -{ - assert(m_pDataBuffer == 0); // Should be deleted externally to avoid storing a memory manager in the class -} - -int RTPTCPTransmitter::SocketData::ProcessAvailableBytes(SocketType sock, int availLen, bool &complete) -{ - - const int numLengthBuffer = 2; - if (m_lengthBufferOffset < numLengthBuffer) // first we need to get the length - { - assert(m_pDataBuffer == 0); - int num = numLengthBuffer - m_lengthBufferOffset; - if (num > availLen) - num = availLen; - - int r = 0; - if (num > 0) - { - r = (int) recv(sock, (char *) (m_lengthBuffer + m_lengthBufferOffset), num, 0); - if (r < 0) - return ERR_RTP_TCPTRANS_ERRORINRECV; - } - - m_lengthBufferOffset += r; - availLen -= r; - - assert(m_lengthBufferOffset <= numLengthBuffer); - if (m_lengthBufferOffset == numLengthBuffer) // we can constuct a length - { - int l = 0; - for (int i = numLengthBuffer - 1, shift = 0; i >= 0; i--, shift += 8) - l |= ((int) m_lengthBuffer[i]) << shift; - - m_dataLength = l; - m_dataBufferOffset = 0; - -//cout << "Expecting " << m_dataLength << " bytes" << endl; - -// avoid allocation of length 0 - if (l == 0) - l = 1; - -// We don't yet know if it's an RTP or RTCP packet, so we'll stick to RTP - m_pDataBuffer = new uint8_t[l]; - if (m_pDataBuffer == 0) - return ERR_RTP_OUTOFMEM; - } - } - - if (m_lengthBufferOffset == numLengthBuffer && m_pDataBuffer) // the last one is to make sure we didn't run out of memory - { - if (m_dataBufferOffset < m_dataLength) - { - int num = m_dataLength - m_dataBufferOffset; - if (num > availLen) - num = availLen; - - int r = 0; - if (num > 0) - { - r = (int) recv(sock, (char *) (m_pDataBuffer + m_dataBufferOffset), num, 0); - if (r < 0) - return ERR_RTP_TCPTRANS_ERRORINRECV; - } - - m_dataBufferOffset += r; - availLen -= r; - } - - if (m_dataBufferOffset == m_dataLength) - complete = true; - } - return 0; -} - -} // end namespace - diff --git a/qrtplib/rtptcptransmitter.h b/qrtplib/rtptcptransmitter.h deleted file mode 100644 index dc964c304..000000000 --- a/qrtplib/rtptcptransmitter.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtptcptransmitter.h - */ - -#ifndef RTPTCPTRANSMITTER_H - -#define RTPTCPTRANSMITTER_H - -#include "rtpconfig.h" -#include "rtptransmitter.h" -#include "rtpsocketutil.h" -#include "rtpabortdescriptors.h" -#include -#include -#include - -#include "util/export.h" - -namespace qrtplib -{ - -/** Parameters for the TCP transmitter. */ -class QRTPLIB_API RTPTCPTransmissionParams: public RTPTransmissionParams -{ -public: - RTPTCPTransmissionParams(); - - /** If non null, the specified abort descriptors will be used to cancel - * the function that's waiting for packets to arrive; set to null (the default) - * to let the transmitter create its own instance. */ - void SetCreatedAbortDescriptors(RTPAbortDescriptors *desc) - { - m_pAbortDesc = desc; - } - - /** If non-null, this RTPAbortDescriptors instance will be used internally, - * which can be useful when creating your own poll thread for multiple - * sessions. */ - RTPAbortDescriptors *GetCreatedAbortDescriptors() const - { - return m_pAbortDesc; - } -private: - RTPAbortDescriptors *m_pAbortDesc; -}; - -inline RTPTCPTransmissionParams::RTPTCPTransmissionParams() : - RTPTransmissionParams(RTPTransmitter::TCPProto) -{ - m_pAbortDesc = 0; -} - -/** Additional information about the TCP transmitter. */ -class RTPTCPTransmissionInfo: public RTPTransmissionInfo -{ -public: - RTPTCPTransmissionInfo() : - RTPTransmissionInfo(RTPTransmitter::TCPProto) - { - } - ~RTPTCPTransmissionInfo() - { - } -}; - -// TODO: this is for IPv4, and will only be valid if one rtp packet is in one tcp frame -#define RTPTCPTRANS_HEADERSIZE (20+20+2) // 20 IP, 20 TCP, 2 for framing (RFC 4571) - -/** A TCP transmission component. - * - * This class inherits the RTPTransmitter interface and implements a transmission component - * which uses TCP to send and receive RTP and RTCP data. The component's parameters - * are described by the class RTPTCPTransmissionParams. The functions which have an RTPAddress - * argument require an argument of RTPTCPAddress. The RTPTransmitter::GetTransmissionInfo member function - * returns an instance of type RTPTCPTransmissionInfo. - * - * After this transmission component was created, no data will actually be sent or received - * yet. You can specify over which TCP connections (which must be established first) data - * should be transmitted by using the RTPTransmitter::AddDestination member function. This - * takes an argument of type RTPTCPAddress, with which relevant the socket descriptor can - * be passed to the transmitter. - * - * These sockets will also be used to check for incoming RTP or RTCP data. The RTPTCPAddress - * instance that's associated with a received packet, will contain the socket descriptor - * on which the data was received. This descriptor can be obtained using RTPTCPAddress::GetSocket. - * - * To get notified of an error when sending over or receiving from a socket, override the - * RTPTCPTransmitter::OnSendError and RTPTCPTransmitter::OnReceiveError member functions. - */ -class RTPTCPTransmitter : public RTPTransmitter -{ -public: - RTPTCPTransmitter(); - ~RTPTCPTransmitter(); - - int Init(bool treadsafe); - int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams); - void Destroy(); - RTPTransmissionInfo *GetTransmissionInfo(); - void DeleteTransmissionInfo(RTPTransmissionInfo *inf); - - int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength); - bool ComesFromThisTransmitter(const RTPAddress *addr); - std::size_t GetHeaderOverhead() - { - return RTPTCPTRANS_HEADERSIZE; - } - - int Poll(); - int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0); - int AbortWait(); - - int SendRTPData(const void *data, std::size_t len); - int SendRTCPData(const void *data, std::size_t len); - - int AddDestination(const RTPAddress &addr); - int DeleteDestination(const RTPAddress &addr); - void ClearDestinations(); - - bool SupportsMulticasting(); - int JoinMulticastGroup(const RTPAddress &addr); - int LeaveMulticastGroup(const RTPAddress &addr); - void LeaveAllMulticastGroups(); - - int SetReceiveMode(RTPTransmitter::ReceiveMode m); - int AddToIgnoreList(const RTPAddress &addr); - int DeleteFromIgnoreList(const RTPAddress &addr); - void ClearIgnoreList(); - int AddToAcceptList(const RTPAddress &addr); - int DeleteFromAcceptList(const RTPAddress &addr); - void ClearAcceptList(); - int SetMaximumPacketSize(std::size_t s); - - bool NewDataAvailable(); - RTPRawPacket *GetNextPacket(); -protected: - /** By overriding this function you can be notified of an error when sending over a socket. */ - virtual void OnSendError(SocketType sock); - /** By overriding this function you can be notified of an error when receiving from a socket. */ - virtual void OnReceiveError(SocketType sock); -private: - class SocketData - { - public: - SocketData(); - ~SocketData(); - void Reset(); - - uint8_t m_lengthBuffer[2]; - int m_lengthBufferOffset; - int m_dataLength; - int m_dataBufferOffset; - uint8_t *m_pDataBuffer; - - uint8_t *ExtractDataBuffer() - { - uint8_t *pTmp = m_pDataBuffer; - m_pDataBuffer = 0; - return pTmp; - } - int ProcessAvailableBytes(SocketType sock, int availLen, bool &complete); - }; - - int SendRTPRTCPData(const void *data, std::size_t len); - void FlushPackets(); - int PollSocket(SocketType sock, SocketData &sdata); - void ClearDestSockets(); - int ValidateSocket(SocketType s); - - bool m_init; - bool m_created; - bool m_waitingForData; - - std::map m_destSockets; - std::vector m_tmpSocks; - std::vector m_tmpFlags; - std::vector m_localHostname; - std::size_t m_maxPackSize; - - std::list m_rawpacketlist; - - RTPAbortDescriptors m_abortDesc; - RTPAbortDescriptors *m_pAbortDesc; // in case an external one was specified - -}; - -inline void RTPTCPTransmitter::OnSendError(SocketType) -{ -} -inline void RTPTCPTransmitter::OnReceiveError(SocketType) -{ -} - -} // end namespace - -#endif // RTPTCPTRANSMITTER_H - diff --git a/qrtplib/rtpudpv4transmitter.cpp b/qrtplib/rtpudpv4transmitter.cpp deleted file mode 100644 index 12f165281..000000000 --- a/qrtplib/rtpudpv4transmitter.cpp +++ /dev/null @@ -1,1834 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtpudpv4transmitter.h" -#include "rtprawpacket.h" -#include "rtpipv4address.h" -#include "rtptimeutilities.h" -#include "rtpdefines.h" -#include "rtpstructs.h" -#include "rtpsocketutilinternal.h" -#include "rtpinternalutils.h" -#include "rtpselect.h" -#include -#include -#include - -#include - -using namespace std; - -#define RTPUDPV4TRANS_MAXPACKSIZE 65535 -#define RTPUDPV4TRANS_IFREQBUFSIZE 8192 - -#define RTPUDPV4TRANS_IS_MCASTADDR(x) (((x)&0xF0000000) == 0xE0000000) - -#define RTPUDPV4TRANS_MCASTMEMBERSHIP(socket,type,mcastip,status) {\ - struct ip_mreq mreq;\ - \ - mreq.imr_multiaddr.s_addr = htonl(mcastip);\ - mreq.imr_interface.s_addr = htonl(mcastifaceIP);\ - status = setsockopt(socket,IPPROTO_IP,type,(const char *)&mreq,sizeof(struct ip_mreq));\ - } - -#define CLOSESOCKETS do { \ - if (closesocketswhendone) \ - {\ - if (rtpsock != rtcpsock) \ - RTPCLOSE(rtcpsock); \ - RTPCLOSE(rtpsock); \ - } \ -} while(0) - -namespace qrtplib -{ - -RTPUDPv4Transmitter::RTPUDPv4Transmitter() -{ - created = false; - init = false; -} - -RTPUDPv4Transmitter::~RTPUDPv4Transmitter() -{ - Destroy(); -} - -int RTPUDPv4Transmitter::Init(bool tsafe) -{ - if (init) - return ERR_RTP_UDPV4TRANS_ALREADYINIT; - - if (tsafe) - return ERR_RTP_NOTHREADSUPPORT; - - init = true; - return 0; -} - -int RTPUDPv4Transmitter::GetIPv4SocketPort(SocketType s, uint16_t *pPort) -{ - assert(pPort != 0); - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - - RTPSOCKLENTYPE size = sizeof(struct sockaddr_in); - if (getsockname(s, (struct sockaddr*) &addr, &size) != 0) - return ERR_RTP_UDPV4TRANS_CANTGETSOCKETPORT; - - if (addr.sin_family != AF_INET) - return ERR_RTP_UDPV4TRANS_NOTANIPV4SOCKET; - - uint16_t port = ntohs(addr.sin_port); - if (port == 0) - return ERR_RTP_UDPV4TRANS_SOCKETPORTNOTSET; - - int type = 0; - RTPSOCKLENTYPE length = sizeof(type); - - if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char*) &type, &length) != 0) - return ERR_RTP_UDPV4TRANS_CANTGETSOCKETTYPE; - - if (type != SOCK_DGRAM) - return ERR_RTP_UDPV4TRANS_INVALIDSOCKETTYPE; - - *pPort = port; - return 0; -} - -int RTPUDPv4Transmitter::GetAutoSockets(uint32_t bindIP, bool allowOdd, bool rtcpMux, SocketType *pRtpSock, SocketType *pRtcpSock, uint16_t *pRtpPort, uint16_t *pRtcpPort) -{ - const int maxAttempts = 1024; - int attempts = 0; - vector toClose; - - while (attempts++ < maxAttempts) - { - SocketType sock = socket(PF_INET, SOCK_DGRAM, 0); - if (sock == RTPSOCKERR) - { - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - - // First we get an automatically chosen port - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - { - RTPCLOSE(sock); - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return ERR_RTP_UDPV4TRANS_CANTGETVALIDSOCKET; - } - - uint16_t basePort = 0; - int status = GetIPv4SocketPort(sock, &basePort); - if (status < 0) - { - RTPCLOSE(sock); - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return status; - } - - if (rtcpMux) // only need one socket - { - if (basePort % 2 == 0 || allowOdd) - { - *pRtpSock = sock; - *pRtcpSock = sock; - *pRtpPort = basePort; - *pRtcpPort = basePort; - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - - return 0; - } - else - toClose.push_back(sock); - } - else - { - SocketType sock2 = socket(PF_INET, SOCK_DGRAM, 0); - if (sock2 == RTPSOCKERR) - { - RTPCLOSE(sock); - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - - // Try the next port or the previous port - uint16_t secondPort = basePort; - bool possiblyValid = false; - - if (basePort % 2 == 0) - { - secondPort++; - possiblyValid = true; - } - else if (basePort > 1) // avoid landing on port 0 - { - secondPort--; - possiblyValid = true; - } - - if (possiblyValid) - { - memset(&addr, 0, sizeof(struct sockaddr_in)); - - addr.sin_family = AF_INET; - addr.sin_port = htons(secondPort); - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(sock2, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == 0) - { - // In this case, we have two consecutive port numbers, the lower of - // which is even - - if (basePort < secondPort) - { - *pRtpSock = sock; - *pRtcpSock = sock2; - *pRtpPort = basePort; - *pRtcpPort = secondPort; - } - else - { - *pRtpSock = sock2; - *pRtcpSock = sock; - *pRtpPort = secondPort; - *pRtcpPort = basePort; - } - - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - - return 0; - } - } - - toClose.push_back(sock); - toClose.push_back(sock2); - } - } - - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - - return ERR_RTP_UDPV4TRANS_TOOMANYATTEMPTSCHOOSINGSOCKET; -} - -int RTPUDPv4Transmitter::Create(std::size_t maximumpacketsize, const RTPTransmissionParams *transparams) -{ - const RTPUDPv4TransmissionParams *params, defaultparams; - struct sockaddr_in addr; - RTPSOCKLENTYPE size; - int status; - - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (created) - { - - return ERR_RTP_UDPV4TRANS_ALREADYCREATED; - } - - // Obtain transmission parameters - - if (transparams == 0) - params = &defaultparams; - else - { - if (transparams->GetTransmissionProtocol() != RTPTransmitter::IPv4UDPProto) - { - - return ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS; - } - params = (const RTPUDPv4TransmissionParams *) transparams; - } - - if (params->GetUseExistingSockets(rtpsock, rtcpsock)) - { - closesocketswhendone = false; - - // Determine the port numbers - int status = GetIPv4SocketPort(rtpsock, &m_rtpPort); - if (status < 0) - { - - return status; - } - status = GetIPv4SocketPort(rtcpsock, &m_rtcpPort); - if (status < 0) - { - - return status; - } - } - else - { - closesocketswhendone = true; - - if (params->GetPortbase() == 0) - { - int status = GetAutoSockets(params->GetBindIP(), params->GetAllowOddPortbase(), params->GetRTCPMultiplexing(), &rtpsock, &rtcpsock, &m_rtpPort, &m_rtcpPort); - if (status < 0) - { - - return status; - } - } - else - { - // Check if portbase is even (if necessary) - if (!params->GetAllowOddPortbase() && params->GetPortbase() % 2 != 0) - { - - return ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN; - } - - // create sockets - - rtpsock = socket(PF_INET, SOCK_DGRAM, 0); - if (rtpsock == RTPSOCKERR) - { - - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - - // If we're multiplexing, we're just going to set the RTCP socket to equal the RTP socket - if (params->GetRTCPMultiplexing()) - rtcpsock = rtpsock; - else - { - rtcpsock = socket(PF_INET, SOCK_DGRAM, 0); - if (rtcpsock == RTPSOCKERR) - { - RTPCLOSE(rtpsock); - - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - } - - // bind sockets - - uint32_t bindIP = params->GetBindIP(); - - m_rtpPort = params->GetPortbase(); - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(params->GetPortbase()); - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(rtpsock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET; - } - - if (rtpsock != rtcpsock) // no need to bind same socket twice when multiplexing - { - uint16_t rtpport = params->GetPortbase(); - uint16_t rtcpport = params->GetForcedRTCPPort(); - - if (rtcpport == 0) - { - rtcpport = rtpport; - if (rtcpport < 0xFFFF) - rtcpport++; - } - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(rtcpport); - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(rtcpsock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET; - } - - m_rtcpPort = rtcpport; - } - else - m_rtcpPort = m_rtpPort; - } - - // set socket buffer sizes - - size = params->GetRTPReceiveBuffer(); - if (setsockopt(rtpsock, SOL_SOCKET, SO_RCVBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF; - } - size = params->GetRTPSendBuffer(); - if (setsockopt(rtpsock, SOL_SOCKET, SO_SNDBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF; - } - - if (rtpsock != rtcpsock) // no need to set RTCP flags when multiplexing - { - size = params->GetRTCPReceiveBuffer(); - if (setsockopt(rtcpsock, SOL_SOCKET, SO_RCVBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF; - } - size = params->GetRTCPSendBuffer(); - if (setsockopt(rtcpsock, SOL_SOCKET, SO_SNDBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF; - } - } - } - - // Try to obtain local IP addresses - - localIPs = params->GetLocalIPList(); - if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them - { - int status; - - if ((status = CreateLocalIPList()) < 0) - { - CLOSESOCKETS; - - return status; - } - } - -#ifdef RTP_SUPPORT_IPV4MULTICAST - if (SetMulticastTTL(params->GetMulticastTTL())) - supportsmulticasting = true; - else - supportsmulticasting = false; -#else // no multicast support enabled - supportsmulticasting = false; -#endif // RTP_SUPPORT_IPV4MULTICAST - - if (maximumpacketsize > RTPUDPV4TRANS_MAXPACKSIZE) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - - if (!params->GetCreatedAbortDescriptors()) - { - if ((status = m_abortDesc.Init()) < 0) - { - CLOSESOCKETS; - - return status; - } - m_pAbortDesc = &m_abortDesc; - } - else - { - m_pAbortDesc = params->GetCreatedAbortDescriptors(); - if (!m_pAbortDesc->IsInitialized()) - { - CLOSESOCKETS; - - return ERR_RTP_ABORTDESC_NOTINIT; - } - } - - maxpacksize = maximumpacketsize; - multicastTTL = params->GetMulticastTTL(); - mcastifaceIP = params->GetMulticastInterfaceIP(); - receivemode = RTPTransmitter::AcceptAll; - - localhostname = 0; - localhostnamelength = 0; - - waitingfordata = false; - created = true; - - return 0; -} - -void RTPUDPv4Transmitter::Destroy() -{ - if (!init) - return; - - if (!created) - { - ; - return; - } - - if (localhostname) - { - delete[] localhostname; - localhostname = 0; - localhostnamelength = 0; - } - - CLOSESOCKETS; - destinations.Clear(); -#ifdef RTP_SUPPORT_IPV4MULTICAST - multicastgroups.Clear(); -#endif // RTP_SUPPORT_IPV4MULTICAST - FlushPackets(); - ClearAcceptIgnoreInfo(); - localIPs.clear(); - created = false; - - if (waitingfordata) - { - m_pAbortDesc->SendAbortSignal(); - m_abortDesc.Destroy(); // Doesn't do anything if not initialized - - // to make sure that the WaitForIncomingData function ended - - } - else - m_abortDesc.Destroy(); // Doesn't do anything if not initialized - -} - -RTPTransmissionInfo *RTPUDPv4Transmitter::GetTransmissionInfo() -{ - if (!init) - return 0; - - RTPTransmissionInfo *tinf = new RTPUDPv4TransmissionInfo(localIPs, rtpsock, rtcpsock, m_rtpPort, m_rtcpPort); - - return tinf; -} - -void RTPUDPv4Transmitter::DeleteTransmissionInfo(RTPTransmissionInfo *i) -{ - if (!init) - return; - - delete i; -} - -int RTPUDPv4Transmitter::GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - - if (localhostname == 0) - { - if (localIPs.empty()) - { - - return ERR_RTP_UDPV4TRANS_NOLOCALIPS; - } - - std::list::const_iterator it; - std::list hostnames; - - for (it = localIPs.begin(); it != localIPs.end(); it++) - { - bool founddouble = false; - bool foundentry = true; - - while (!founddouble && foundentry) - { - struct hostent *he; - uint8_t addr[4]; - uint32_t ip = (*it); - - addr[0] = (uint8_t) ((ip >> 24) & 0xFF); - addr[1] = (uint8_t) ((ip >> 16) & 0xFF); - addr[2] = (uint8_t) ((ip >> 8) & 0xFF); - addr[3] = (uint8_t) (ip & 0xFF); - he = gethostbyaddr((char *) addr, 4, AF_INET); - if (he != 0) - { - std::string hname = std::string(he->h_name); - std::list::const_iterator it; - - for (it = hostnames.begin(); !founddouble && it != hostnames.end(); it++) - if ((*it) == hname) - founddouble = true; - - if (!founddouble) - hostnames.push_back(hname); - - int i = 0; - while (!founddouble && he->h_aliases[i] != 0) - { - std::string hname = std::string(he->h_aliases[i]); - - for (it = hostnames.begin(); !founddouble && it != hostnames.end(); it++) - if ((*it) == hname) - founddouble = true; - - if (!founddouble) - { - hostnames.push_back(hname); - i++; - } - } - } - else - foundentry = false; - } - } - - bool found = false; - - if (!hostnames.empty()) // try to select the most appropriate hostname - { - std::list::const_iterator it; - - hostnames.sort(); - for (it = hostnames.begin(); !found && it != hostnames.end(); it++) - { - if ((*it).find('.') != std::string::npos) - { - found = true; - localhostnamelength = (*it).length(); - localhostname = new uint8_t[localhostnamelength + 1]; - if (localhostname == 0) - { - - return ERR_RTP_OUTOFMEM; - } - memcpy(localhostname, (*it).c_str(), localhostnamelength); - localhostname[localhostnamelength] = 0; - } - } - } - - if (!found) // use an IP address - { - uint32_t ip; - int len; - char str[16]; - - it = localIPs.begin(); - ip = (*it); - - RTP_SNPRINTF(str, 16, "%d.%d.%d.%d", (int) ((ip >> 24) & 0xFF), (int) ((ip >> 16) & 0xFF), (int) ((ip >> 8) & 0xFF), (int) (ip & 0xFF)); - len = strlen(str); - - localhostnamelength = len; - localhostname = new uint8_t[localhostnamelength + 1]; - if (localhostname == 0) - { - - return ERR_RTP_OUTOFMEM; - } - memcpy(localhostname, str, localhostnamelength); - localhostname[localhostnamelength] = 0; - } - } - - if ((*bufferlength) < localhostnamelength) - { - *bufferlength = localhostnamelength; // tell the application the required size of the buffer - - return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; - } - - memcpy(buffer, localhostname, localhostnamelength); - *bufferlength = localhostnamelength; - - return 0; -} - -bool RTPUDPv4Transmitter::ComesFromThisTransmitter(const RTPAddress *addr) -{ - if (!init) - return false; - - if (addr == 0) - return false; - - bool v; - - if (created && addr->GetAddressType() == RTPAddress::IPv4Address) - { - const RTPIPv4Address *addr2 = (const RTPIPv4Address *) addr; - bool found = false; - std::list::const_iterator it; - - it = localIPs.begin(); - while (!found && it != localIPs.end()) - { - if (addr2->GetIP() == *it) - found = true; - else - ++it; - } - - if (!found) - v = false; - else - { - if (addr2->GetPort() == m_rtpPort || addr2->GetPort() == m_rtcpPort) // check for RTP port and RTCP port - v = true; - else - v = false; - } - } - else - v = false; - - return v; -} - -int RTPUDPv4Transmitter::Poll() -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - status = PollSocket(true); // poll RTP socket - if (rtpsock != rtcpsock) // no need to poll twice when multiplexing - { - if (status >= 0) - status = PollSocket(false); // poll RTCP socket - } - - return status; -} - -int RTPUDPv4Transmitter::WaitForIncomingData(const RTPTime &delay, bool *dataavailable) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (waitingfordata) - { - - return ERR_RTP_UDPV4TRANS_ALREADYWAITING; - } - - SocketType abortSocket = m_pAbortDesc->GetAbortSocket(); - - SocketType socks[3] = - { rtpsock, rtcpsock, abortSocket }; - int8_t readflags[3] = - { 0, 0, 0 }; - const int idxRTP = 0; - const int idxRTCP = 1; - const int idxAbort = 2; - - waitingfordata = true; - - int status = RTPSelect(socks, readflags, 3, delay); - if (status < 0) - { - waitingfordata = false; - - return status; - } - - waitingfordata = false; - if (!created) // destroy called - { - ; - - return 0; - } - - // if aborted, read from abort buffer - if (readflags[idxAbort]) - m_pAbortDesc->ReadSignallingByte(); - - if (dataavailable != 0) - { - if (readflags[idxRTP] || readflags[idxRTCP]) - *dataavailable = true; - else - *dataavailable = false; - } - - return 0; -} - -int RTPUDPv4Transmitter::AbortWait() -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (!waitingfordata) - { - - return ERR_RTP_UDPV4TRANS_NOTWAITING; - } - - m_pAbortDesc->SendAbortSignal(); - - return 0; -} - -int RTPUDPv4Transmitter::SendRTPData(const void *data, std::size_t len) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (len > maxpacksize) - { - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - - destinations.GotoFirstElement(); - while (destinations.HasCurrentElement()) - { - sendto(rtpsock, (const char *) data, len, 0, (const struct sockaddr *) destinations.GetCurrentElement().GetRTPSockAddr(), sizeof(struct sockaddr_in)); - destinations.GotoNextElement(); - } - - return 0; -} - -int RTPUDPv4Transmitter::SendRTCPData(const void *data, std::size_t len) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (len > maxpacksize) - { - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - - destinations.GotoFirstElement(); - while (destinations.HasCurrentElement()) - { - sendto(rtcpsock, (const char *) data, len, 0, (const struct sockaddr *) destinations.GetCurrentElement().GetRTCPSockAddr(), sizeof(struct sockaddr_in)); - destinations.GotoNextElement(); - } - - return 0; -} - -int RTPUDPv4Transmitter::AddDestination(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - - RTPIPv4Destination dest; - if (!RTPIPv4Destination::AddressToDestination(addr, dest)) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - int status = destinations.AddElement(dest); - - return status; -} - -int RTPUDPv4Transmitter::DeleteDestination(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - RTPIPv4Destination dest; - if (!RTPIPv4Destination::AddressToDestination(addr, dest)) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - int status = destinations.DeleteElement(dest); - - return status; -} - -void RTPUDPv4Transmitter::ClearDestinations() -{ - if (!init) - return; - - if (created) - destinations.Clear(); - -} - -bool RTPUDPv4Transmitter::SupportsMulticasting() -{ - if (!init) - return false; - - bool v; - - if (!created) - v = false; - else - v = supportsmulticasting; - - return v; -} - -#ifdef RTP_SUPPORT_IPV4MULTICAST - -int RTPUDPv4Transmitter::JoinMulticastGroup(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - uint32_t mcastIP = address.GetIP(); - - if (!RTPUDPV4TRANS_IS_MCASTADDR(mcastIP)) - { - - return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS; - } - - status = multicastgroups.AddElement(mcastIP); - if (status >= 0) - { - RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock, IP_ADD_MEMBERSHIP, mcastIP, status); - if (status != 0) - { - multicastgroups.DeleteElement(mcastIP); - - return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP; - } - - if (rtpsock != rtcpsock) // no need to join multicast group twice when multiplexing - { - RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock, IP_ADD_MEMBERSHIP, mcastIP, status); - if (status != 0) - { - RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - multicastgroups.DeleteElement(mcastIP); - - return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP; - } - } - } - - return status; -} - -int RTPUDPv4Transmitter::LeaveMulticastGroup(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - uint32_t mcastIP = address.GetIP(); - - if (!RTPUDPV4TRANS_IS_MCASTADDR(mcastIP)) - { - - return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS; - } - - status = multicastgroups.DeleteElement(mcastIP); - if (status >= 0) - { - RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - if (rtpsock != rtcpsock) // no need to leave multicast group twice when multiplexing - RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - - status = 0; - } - - return status; -} - -void RTPUDPv4Transmitter::LeaveAllMulticastGroups() -{ - if (!init) - return; - - if (created) - { - multicastgroups.GotoFirstElement(); - while (multicastgroups.HasCurrentElement()) - { - uint32_t mcastIP; - int status __attribute__((unused)) = 0; - - mcastIP = multicastgroups.GetCurrentElement(); - - RTPUDPV4TRANS_MCASTMEMBERSHIP(rtpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - if (rtpsock != rtcpsock) // no need to leave multicast group twice when multiplexing - RTPUDPV4TRANS_MCASTMEMBERSHIP(rtcpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - - multicastgroups.GotoNextElement(); - } - multicastgroups.Clear(); - } - -} - -#else // no multicast support - -int RTPUDPv4Transmitter::JoinMulticastGroup(const RTPAddress &addr) -{ - return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT; -} - -int RTPUDPv4Transmitter::LeaveMulticastGroup(const RTPAddress &addr) -{ - return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT; -} - -void RTPUDPv4Transmitter::LeaveAllMulticastGroups() -{ -} - -#endif // RTP_SUPPORT_IPV4MULTICAST - -int RTPUDPv4Transmitter::SetReceiveMode(RTPTransmitter::ReceiveMode m) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (m != receivemode) - { - receivemode = m; - acceptignoreinfo.Clear(); - } - - return 0; -} - -int RTPUDPv4Transmitter::AddToIgnoreList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::IgnoreSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessAddAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -int RTPUDPv4Transmitter::DeleteFromIgnoreList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::IgnoreSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -void RTPUDPv4Transmitter::ClearIgnoreList() -{ - if (!init) - return; - - if (created && receivemode == RTPTransmitter::IgnoreSome) - ClearAcceptIgnoreInfo(); - -} - -int RTPUDPv4Transmitter::AddToAcceptList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::AcceptSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessAddAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -int RTPUDPv4Transmitter::DeleteFromAcceptList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::AcceptSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -void RTPUDPv4Transmitter::ClearAcceptList() -{ - if (!init) - return; - - if (created && receivemode == RTPTransmitter::AcceptSome) - ClearAcceptIgnoreInfo(); - -} - -int RTPUDPv4Transmitter::SetMaximumPacketSize(std::size_t s) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (s > RTPUDPV4TRANS_MAXPACKSIZE) - { - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - maxpacksize = s; - - return 0; -} - -bool RTPUDPv4Transmitter::NewDataAvailable() -{ - if (!init) - return false; - - bool v; - - if (!created) - v = false; - else - { - if (rawpacketlist.empty()) - v = false; - else - v = true; - } - - return v; -} - -RTPRawPacket *RTPUDPv4Transmitter::GetNextPacket() -{ - if (!init) - return 0; - - RTPRawPacket *p; - - if (!created) - { - - return 0; - } - if (rawpacketlist.empty()) - { - - return 0; - } - - p = *(rawpacketlist.begin()); - rawpacketlist.pop_front(); - - return p; -} - -// Here the private functions start... - -#ifdef RTP_SUPPORT_IPV4MULTICAST -bool RTPUDPv4Transmitter::SetMulticastTTL(uint8_t ttl) -{ - int ttl2, status; - - ttl2 = (int) ttl; - status = setsockopt(rtpsock, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &ttl2, sizeof(int)); - if (status != 0) - return false; - - if (rtpsock != rtcpsock) // no need to set TTL twice when multiplexing - { - status = setsockopt(rtcpsock, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &ttl2, sizeof(int)); - if (status != 0) - return false; - } - return true; -} -#endif // RTP_SUPPORT_IPV4MULTICAST - -void RTPUDPv4Transmitter::FlushPackets() -{ - std::list::const_iterator it; - - for (it = rawpacketlist.begin(); it != rawpacketlist.end(); ++it) - delete *it; - rawpacketlist.clear(); -} - -int RTPUDPv4Transmitter::PollSocket(bool rtp) -{ - RTPSOCKLENTYPE fromlen; - int recvlen; - char packetbuffer[RTPUDPV4TRANS_MAXPACKSIZE]; -#ifdef RTP_SOCKETTYPE_WINSOCK - SOCKET sock; - unsigned long len; -#else - std::size_t len; - int sock; -#endif // RTP_SOCKETTYPE_WINSOCK - struct sockaddr_in srcaddr; - bool dataavailable; - - if (rtp) - sock = rtpsock; - else - sock = rtcpsock; - - do - { - len = 0; - RTPIOCTL(sock, FIONREAD, &len); - - if (len <= 0) // make sure a packet of length zero is not queued - { - // An alternative workaround would be to just use non-blocking sockets. - // However, since the user does have access to the sockets and I do not - // know how this would affect anyone else's code, I chose to do it using - // an extra select call in case ioctl says the length is zero. - - int8_t isset = 0; - int status = RTPSelect(&sock, &isset, 1, RTPTime(0)); - if (status < 0) - return status; - - if (isset) - dataavailable = true; - else - dataavailable = false; - } - else - dataavailable = true; - - if (dataavailable) - { - RTPTime curtime = RTPTime::CurrentTime(); - fromlen = sizeof(struct sockaddr_in); - recvlen = recvfrom(sock, packetbuffer, RTPUDPV4TRANS_MAXPACKSIZE, 0, (struct sockaddr *) &srcaddr, &fromlen); - if (recvlen > 0) - { - bool acceptdata; - - // got data, process it - if (receivemode == RTPTransmitter::AcceptAll) - acceptdata = true; - else - acceptdata = ShouldAcceptData(ntohl(srcaddr.sin_addr.s_addr), ntohs(srcaddr.sin_port)); - - if (acceptdata) - { - RTPRawPacket *pack; - RTPIPv4Address *addr; - uint8_t *datacopy; - - addr = new RTPIPv4Address(ntohl(srcaddr.sin_addr.s_addr), ntohs(srcaddr.sin_port)); - if (addr == 0) - return ERR_RTP_OUTOFMEM; - datacopy = new uint8_t[recvlen]; - if (datacopy == 0) - { - delete addr; - return ERR_RTP_OUTOFMEM; - } - memcpy(datacopy, packetbuffer, recvlen); - - bool isrtp = rtp; - if (rtpsock == rtcpsock) // check payload type when multiplexing - { - isrtp = true; - - if ((std::size_t) recvlen > sizeof(RTCPCommonHeader)) - { - RTCPCommonHeader *rtcpheader = (RTCPCommonHeader *) datacopy; - uint8_t packettype = rtcpheader->packettype; - - if (packettype >= 200 && packettype <= 204) - isrtp = false; - } - } - - pack = new RTPRawPacket(datacopy, recvlen, addr, curtime, isrtp); - if (pack == 0) - { - delete addr; - delete[] datacopy; - return ERR_RTP_OUTOFMEM; - } - rawpacketlist.push_back(pack); - } - } - } - } while (dataavailable); - - return 0; -} - -int RTPUDPv4Transmitter::ProcessAddAcceptIgnoreEntry(uint32_t ip, uint16_t port) -{ - acceptignoreinfo.GotoElement(ip); - if (acceptignoreinfo.HasCurrentElement()) // An entry for this IP address already exists - { - PortInfo *portinf = acceptignoreinfo.GetCurrentElement(); - - if (port == 0) // select all ports - { - portinf->all = true; - portinf->portlist.clear(); - } - else if (!portinf->all) - { - std::list::const_iterator it, begin, end; - - begin = portinf->portlist.begin(); - end = portinf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == port) // already in list - return 0; - } - portinf->portlist.push_front(port); - } - } - else // got to create an entry for this IP address - { - PortInfo *portinf; - int status; - - portinf = new PortInfo(); - if (port == 0) // select all ports - portinf->all = true; - else - portinf->portlist.push_front(port); - - status = acceptignoreinfo.AddElement(ip, portinf); - if (status < 0) - { - delete portinf; - return status; - } - } - - return 0; -} - -void RTPUDPv4Transmitter::ClearAcceptIgnoreInfo() -{ - acceptignoreinfo.GotoFirstElement(); - while (acceptignoreinfo.HasCurrentElement()) - { - PortInfo *inf; - - inf = acceptignoreinfo.GetCurrentElement(); - delete inf; - acceptignoreinfo.GotoNextElement(); - } - acceptignoreinfo.Clear(); -} - -int RTPUDPv4Transmitter::ProcessDeleteAcceptIgnoreEntry(uint32_t ip, uint16_t port) -{ - acceptignoreinfo.GotoElement(ip); - if (!acceptignoreinfo.HasCurrentElement()) - return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; - - PortInfo *inf; - - inf = acceptignoreinfo.GetCurrentElement(); - if (port == 0) // delete all entries - { - inf->all = false; - inf->portlist.clear(); - } - else // a specific port was selected - { - if (inf->all) // currently, all ports are selected. Add the one to remove to the list - { - // we have to check if the list doesn't contain the port already - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == port) // already in list: this means we already deleted the entry - return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; - } - inf->portlist.push_front(port); - } - else // check if we can find the port in the list - { - std::list::iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; ++it) - { - if (*it == port) // found it! - { - inf->portlist.erase(it); - return 0; - } - } - // didn't find it - return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; - } - } - return 0; -} - -bool RTPUDPv4Transmitter::ShouldAcceptData(uint32_t srcip, uint16_t srcport) -{ - if (receivemode == RTPTransmitter::AcceptSome) - { - PortInfo *inf; - - acceptignoreinfo.GotoElement(srcip); - if (!acceptignoreinfo.HasCurrentElement()) - return false; - - inf = acceptignoreinfo.GetCurrentElement(); - if (!inf->all) // only accept the ones in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return true; - } - return false; - } - else // accept all, except the ones in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return false; - } - return true; - } - } - else // IgnoreSome - { - PortInfo *inf; - - acceptignoreinfo.GotoElement(srcip); - if (!acceptignoreinfo.HasCurrentElement()) - return true; - - inf = acceptignoreinfo.GetCurrentElement(); - if (!inf->all) // ignore the ports in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return false; - } - return true; - } - else // ignore all, except the ones in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return true; - } - return false; - } - } - return true; -} - -int RTPUDPv4Transmitter::CreateLocalIPList() -{ - // first try to obtain the list from the network interface info - - if (!GetLocalIPList_Interfaces()) - { - // If this fails, we'll have to depend on DNS info - GetLocalIPList_DNS(); - } - AddLoopbackAddress(); - return 0; -} - -#ifdef RTP_SOCKETTYPE_WINSOCK - -bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces() -{ - unsigned char buffer[RTPUDPV4TRANS_IFREQBUFSIZE]; - DWORD outputsize; - DWORD numaddresses,i; - SOCKET_ADDRESS_LIST *addrlist; - - if (WSAIoctl(rtpsock,SIO_ADDRESS_LIST_QUERY,NULL,0,&buffer,RTPUDPV4TRANS_IFREQBUFSIZE,&outputsize,NULL,NULL)) - return false; - - addrlist = (SOCKET_ADDRESS_LIST *)buffer; - numaddresses = addrlist->iAddressCount; - for (i = 0; i < numaddresses; i++) - { - SOCKET_ADDRESS *sockaddr = &(addrlist->Address[i]); - if (sockaddr->iSockaddrLength == sizeof(struct sockaddr_in)) // IPv4 address - { - struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr->lpSockaddr; - - localIPs.push_back(ntohl(addr->sin_addr.s_addr)); - } - } - - if (localIPs.empty()) - return false; - - return true; -} - -#else // use either getifaddrs or ioctl - -#ifdef RTP_SUPPORT_IFADDRS - -bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces() -{ - struct ifaddrs *addrs, *tmp; - - getifaddrs(&addrs); - tmp = addrs; - - while (tmp != 0) - { - if (tmp->ifa_addr != 0 && tmp->ifa_addr->sa_family == AF_INET) - { - struct sockaddr_in *inaddr = (struct sockaddr_in *) tmp->ifa_addr; - localIPs.push_back(ntohl(inaddr->sin_addr.s_addr)); - } - tmp = tmp->ifa_next; - } - - freeifaddrs(addrs); - - if (localIPs.empty()) - return false; - return true; -} - -#else // user ioctl - -bool RTPUDPv4Transmitter::GetLocalIPList_Interfaces() -{ - int status; - char buffer[RTPUDPV4TRANS_IFREQBUFSIZE]; - struct ifconf ifc; - struct ifreq *ifr; - struct sockaddr *sa; - char *startptr,*endptr; - int remlen; - - ifc.ifc_len = RTPUDPV4TRANS_IFREQBUFSIZE; - ifc.ifc_buf = buffer; - status = ioctl(rtpsock,SIOCGIFCONF,&ifc); - if (status < 0) - return false; - - startptr = (char *)ifc.ifc_req; - endptr = startptr + ifc.ifc_len; - remlen = ifc.ifc_len; - while((startptr < endptr) && remlen >= (int)sizeof(struct ifreq)) - { - ifr = (struct ifreq *)startptr; - sa = &(ifr->ifr_addr); -#ifdef RTP_HAVE_SOCKADDR_LEN - if (sa->sa_len <= sizeof(struct sockaddr)) - { - if (sa->sa_len == sizeof(struct sockaddr_in) && sa->sa_family == PF_INET) - { - uint32_t ip; - struct sockaddr_in *addr = (struct sockaddr_in *)sa; - - ip = ntohl(addr->sin_addr.s_addr); - localIPs.push_back(ip); - } - remlen -= sizeof(struct ifreq); - startptr += sizeof(struct ifreq); - } - else - { - int l = sa->sa_len-sizeof(struct sockaddr)+sizeof(struct ifreq); - - remlen -= l; - startptr += l; - } -#else // don't have sa_len in struct sockaddr - if (sa->sa_family == PF_INET) - { - uint32_t ip; - struct sockaddr_in *addr = (struct sockaddr_in *)sa; - - ip = ntohl(addr->sin_addr.s_addr); - localIPs.push_back(ip); - } - remlen -= sizeof(struct ifreq); - startptr += sizeof(struct ifreq); - -#endif // RTP_HAVE_SOCKADDR_LEN - } - - if (localIPs.empty()) - return false; - return true; -} - -#endif // RTP_SUPPORT_IFADDRS - -#endif // RTP_SOCKETTYPE_WINSOCK - -void RTPUDPv4Transmitter::GetLocalIPList_DNS() -{ - struct hostent *he; - char name[1024]; - bool done; - int i, j; - - gethostname(name, 1023); - name[1023] = 0; - he = gethostbyname(name); - if (he == 0) - return; - - i = 0; - done = false; - while (!done) - { - if (he->h_addr_list[i] == NULL) - done = true; - else - { - uint32_t ip = 0; - - for (j = 0; j < 4; j++) - ip |= ((uint32_t) ((unsigned char) he->h_addr_list[i][j]) << ((3 - j) * 8)); - localIPs.push_back(ip); - i++; - } - } -} - -void RTPUDPv4Transmitter::AddLoopbackAddress() -{ - uint32_t loopbackaddr = (((uint32_t) 127) << 24) | ((uint32_t) 1); - std::list::const_iterator it; - bool found = false; - - for (it = localIPs.begin(); !found && it != localIPs.end(); it++) - { - if (*it == loopbackaddr) - found = true; - } - - if (!found) - localIPs.push_back(loopbackaddr); -} - -} // end namespace - diff --git a/qrtplib/rtpudpv4transmitter.h b/qrtplib/rtpudpv4transmitter.h deleted file mode 100644 index aa9abac8b..000000000 --- a/qrtplib/rtpudpv4transmitter.h +++ /dev/null @@ -1,488 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtpudpv4transmitter.h - */ - -#ifndef RTPUDPV4TRANSMITTER_H - -#define RTPUDPV4TRANSMITTER_H - -#include "rtpconfig.h" -#include "rtptransmitter.h" -#include "rtpipv4destination.h" -#include "rtphashtable.h" -#include "rtpkeyhashtable.h" -#include "rtpsocketutil.h" -#include "rtpabortdescriptors.h" -#include - -#include "util/export.h" - -#define RTPUDPV4TRANS_HASHSIZE 8317 -#define RTPUDPV4TRANS_DEFAULTPORTBASE 5000 - -#define RTPUDPV4TRANS_RTPRECEIVEBUFFER 32768 -#define RTPUDPV4TRANS_RTCPRECEIVEBUFFER 32768 -#define RTPUDPV4TRANS_RTPTRANSMITBUFFER 32768 -#define RTPUDPV4TRANS_RTCPTRANSMITBUFFER 32768 - -namespace qrtplib -{ - -/** Parameters for the UDP over IPv4 transmitter. */ -class QRTPLIB_API RTPUDPv4TransmissionParams: public RTPTransmissionParams -{ -public: - RTPUDPv4TransmissionParams(); - - /** Sets the IP address which is used to bind the sockets to \c ip. */ - void SetBindIP(uint32_t ip) - { - bindIP = ip; - } - - /** Sets the multicast interface IP address. */ - void SetMulticastInterfaceIP(uint32_t ip) - { - mcastifaceIP = ip; - } - - /** Sets the RTP portbase to \c pbase, which has to be an even number - * unless RTPUDPv4TransmissionParams::SetAllowOddPortbase was called; - * a port number of zero will cause a port to be chosen automatically. */ - void SetPortbase(uint16_t pbase) - { - portbase = pbase; - } - - /** Sets the multicast TTL to be used to \c mcastTTL. */ - void SetMulticastTTL(uint8_t mcastTTL) - { - multicastTTL = mcastTTL; - } - - /** Passes a list of IP addresses which will be used as the local IP addresses. */ - void SetLocalIPList(std::list &iplist) - { - localIPs = iplist; - } - - /** Clears the list of local IP addresses. - * Clears the list of local IP addresses. An empty list will make the transmission - * component itself determine the local IP addresses. - */ - void ClearLocalIPList() - { - localIPs.clear(); - } - - /** Returns the IP address which will be used to bind the sockets. */ - uint32_t GetBindIP() const - { - return bindIP; - } - - /** Returns the multicast interface IP address. */ - uint32_t GetMulticastInterfaceIP() const - { - return mcastifaceIP; - } - - /** Returns the RTP portbase which will be used (default is 5000). */ - uint16_t GetPortbase() const - { - return portbase; - } - - /** Returns the multicast TTL which will be used (default is 1). */ - uint8_t GetMulticastTTL() const - { - return multicastTTL; - } - - /** Returns the list of local IP addresses. */ - const std::list &GetLocalIPList() const - { - return localIPs; - } - - /** Sets the RTP socket's send buffer size. */ - void SetRTPSendBuffer(int s) - { - rtpsendbuf = s; - } - - /** Sets the RTP socket's receive buffer size. */ - void SetRTPReceiveBuffer(int s) - { - rtprecvbuf = s; - } - - /** Sets the RTCP socket's send buffer size. */ - void SetRTCPSendBuffer(int s) - { - rtcpsendbuf = s; - } - - /** Sets the RTCP socket's receive buffer size. */ - void SetRTCPReceiveBuffer(int s) - { - rtcprecvbuf = s; - } - - /** Enables or disables multiplexing RTCP traffic over the RTP channel, so that only a single port is used. */ - void SetRTCPMultiplexing(bool f) - { - rtcpmux = f; - } - - /** Can be used to allow the RTP port base to be any number, not just even numbers. */ - void SetAllowOddPortbase(bool f) - { - allowoddportbase = f; - } - - /** Force the RTCP socket to use a specific port, not necessarily one more than - * the RTP port (set this to zero to disable). */ - void SetForcedRTCPPort(uint16_t rtcpport) - { - forcedrtcpport = rtcpport; - } - - /** Use sockets that have already been created, no checks on port numbers - * will be done, and no buffer sizes will be set; you'll need to close - * the sockets yourself when done, it will **not** be done automatically. */ - void SetUseExistingSockets(SocketType rtpsocket, SocketType rtcpsocket) - { - rtpsock = rtpsocket; - rtcpsock = rtcpsocket; - useexistingsockets = true; - } - - /** If non null, the specified abort descriptors will be used to cancel - * the function that's waiting for packets to arrive; set to null (the default - * to let the transmitter create its own instance. */ - void SetCreatedAbortDescriptors(RTPAbortDescriptors *desc) - { - m_pAbortDesc = desc; - } - - /** Returns the RTP socket's send buffer size. */ - int GetRTPSendBuffer() const - { - return rtpsendbuf; - } - - /** Returns the RTP socket's receive buffer size. */ - int GetRTPReceiveBuffer() const - { - return rtprecvbuf; - } - - /** Returns the RTCP socket's send buffer size. */ - int GetRTCPSendBuffer() const - { - return rtcpsendbuf; - } - - /** Returns the RTCP socket's receive buffer size. */ - int GetRTCPReceiveBuffer() const - { - return rtcprecvbuf; - } - - /** Returns a flag indicating if RTCP traffic will be multiplexed over the RTP channel. */ - bool GetRTCPMultiplexing() const - { - return rtcpmux; - } - - /** If true, any RTP portbase will be allowed, not just even numbers. */ - bool GetAllowOddPortbase() const - { - return allowoddportbase; - } - - /** If non-zero, the specified port will be used to receive RTCP traffic. */ - uint16_t GetForcedRTCPPort() const - { - return forcedrtcpport; - } - - /** Returns true and fills in sockets if existing sockets were set - * using RTPUDPv4TransmissionParams::SetUseExistingSockets. */ - bool GetUseExistingSockets(SocketType &rtpsocket, SocketType &rtcpsocket) const - { - if (!useexistingsockets) - return false; - rtpsocket = rtpsock; - rtcpsocket = rtcpsock; - return true; - } - - /** If non-null, this RTPAbortDescriptors instance will be used internally, - * which can be useful when creating your own poll thread for multiple - * sessions. */ - RTPAbortDescriptors *GetCreatedAbortDescriptors() const - { - return m_pAbortDesc; - } -private: - uint16_t portbase; - uint32_t bindIP, mcastifaceIP; - std::list localIPs; - uint8_t multicastTTL; - int rtpsendbuf, rtprecvbuf; - int rtcpsendbuf, rtcprecvbuf; - bool rtcpmux; - bool allowoddportbase; - uint16_t forcedrtcpport; - - SocketType rtpsock, rtcpsock; - bool useexistingsockets; - - RTPAbortDescriptors *m_pAbortDesc; -}; - -inline RTPUDPv4TransmissionParams::RTPUDPv4TransmissionParams() : - RTPTransmissionParams(RTPTransmitter::IPv4UDPProto) -{ - portbase = RTPUDPV4TRANS_DEFAULTPORTBASE; - bindIP = 0; - multicastTTL = 1; - mcastifaceIP = 0; - rtpsendbuf = RTPUDPV4TRANS_RTPTRANSMITBUFFER; - rtprecvbuf = RTPUDPV4TRANS_RTPRECEIVEBUFFER; - rtcpsendbuf = RTPUDPV4TRANS_RTCPTRANSMITBUFFER; - rtcprecvbuf = RTPUDPV4TRANS_RTCPRECEIVEBUFFER; - rtcpmux = false; - allowoddportbase = false; - forcedrtcpport = 0; - useexistingsockets = false; - rtpsock = 0; - rtcpsock = 0; - m_pAbortDesc = 0; -} - -/** Additional information about the UDP over IPv4 transmitter. */ -class QRTPLIB_API RTPUDPv4TransmissionInfo: public RTPTransmissionInfo -{ -public: - RTPUDPv4TransmissionInfo(std::list iplist, SocketType rtpsock, SocketType rtcpsock, uint16_t rtpport, uint16_t rtcpport) : - RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto) - { - localIPlist = iplist; - rtpsocket = rtpsock; - rtcpsocket = rtcpsock; - m_rtpPort = rtpport; - m_rtcpPort = rtcpport; - } - - ~RTPUDPv4TransmissionInfo() - { - } - - /** Returns the list of IPv4 addresses the transmitter considers to be the local IP addresses. */ - std::list GetLocalIPList() const - { - return localIPlist; - } - - /** Returns the socket descriptor used for receiving and transmitting RTP packets. */ - SocketType GetRTPSocket() const - { - return rtpsocket; - } - - /** Returns the socket descriptor used for receiving and transmitting RTCP packets. */ - SocketType GetRTCPSocket() const - { - return rtcpsocket; - } - - /** Returns the port number that the RTP socket receives packets on. */ - uint16_t GetRTPPort() const - { - return m_rtpPort; - } - - /** Returns the port number that the RTCP socket receives packets on. */ - uint16_t GetRTCPPort() const - { - return m_rtcpPort; - } -private: - std::list localIPlist; - SocketType rtpsocket, rtcpsocket; - uint16_t m_rtpPort, m_rtcpPort; -}; - -class RTPUDPv4Trans_GetHashIndex_IPv4Dest -{ -public: - static int GetIndex(const RTPIPv4Destination &d) - { - return d.GetIP() % RTPUDPV4TRANS_HASHSIZE; - } -}; - -class RTPUDPv4Trans_GetHashIndex_uint32_t -{ -public: - static int GetIndex(const uint32_t &k) - { - return k % RTPUDPV4TRANS_HASHSIZE; - } -}; - -#define RTPUDPV4TRANS_HEADERSIZE (20+8) - -/** An UDP over IPv4 transmission component. - * This class inherits the RTPTransmitter interface and implements a transmission component - * which uses UDP over IPv4 to send and receive RTP and RTCP data. The component's parameters - * are described by the class RTPUDPv4TransmissionParams. The functions which have an RTPAddress - * argument require an argument of RTPIPv4Address. The GetTransmissionInfo member function - * returns an instance of type RTPUDPv4TransmissionInfo. - */ -class QRTPLIB_API RTPUDPv4Transmitter: public RTPTransmitter -{ -public: - RTPUDPv4Transmitter(); - ~RTPUDPv4Transmitter(); - - int Init(bool treadsafe); - int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams); - void Destroy(); - RTPTransmissionInfo *GetTransmissionInfo(); - void DeleteTransmissionInfo(RTPTransmissionInfo *inf); - - int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength); - bool ComesFromThisTransmitter(const RTPAddress *addr); - std::size_t GetHeaderOverhead() - { - return RTPUDPV4TRANS_HEADERSIZE; - } - - int Poll(); - int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0); - int AbortWait(); - - int SendRTPData(const void *data, std::size_t len); - int SendRTCPData(const void *data, std::size_t len); - - int AddDestination(const RTPAddress &addr); - int DeleteDestination(const RTPAddress &addr); - void ClearDestinations(); - - bool SupportsMulticasting(); - int JoinMulticastGroup(const RTPAddress &addr); - int LeaveMulticastGroup(const RTPAddress &addr); - void LeaveAllMulticastGroups(); - - int SetReceiveMode(RTPTransmitter::ReceiveMode m); - int AddToIgnoreList(const RTPAddress &addr); - int DeleteFromIgnoreList(const RTPAddress &addr); - void ClearIgnoreList(); - int AddToAcceptList(const RTPAddress &addr); - int DeleteFromAcceptList(const RTPAddress &addr); - void ClearAcceptList(); - int SetMaximumPacketSize(std::size_t s); - - bool NewDataAvailable(); - RTPRawPacket *GetNextPacket(); - -private: - int CreateLocalIPList(); - bool GetLocalIPList_Interfaces(); - void GetLocalIPList_DNS(); - void AddLoopbackAddress(); - void FlushPackets(); - int PollSocket(bool rtp); - int ProcessAddAcceptIgnoreEntry(uint32_t ip, uint16_t port); - int ProcessDeleteAcceptIgnoreEntry(uint32_t ip, uint16_t port); -#ifdef RTP_SUPPORT_IPV4MULTICAST - bool SetMulticastTTL(uint8_t ttl); -#endif // RTP_SUPPORT_IPV4MULTICAST - bool ShouldAcceptData(uint32_t srcip, uint16_t srcport); - void ClearAcceptIgnoreInfo(); - - int GetAutoSockets(uint32_t bindIP, bool allowOdd, bool rtcpMux, SocketType *pRtpSock, SocketType *pRtcpSock, uint16_t *pRtpPort, uint16_t *pRtcpPort); - static int GetIPv4SocketPort(SocketType s, uint16_t *pPort); - - bool init; - bool created; - bool waitingfordata; - SocketType rtpsock, rtcpsock; - uint32_t mcastifaceIP; - std::list localIPs; - uint16_t m_rtpPort, m_rtcpPort; - uint8_t multicastTTL; - RTPTransmitter::ReceiveMode receivemode; - - uint8_t *localhostname; - std::size_t localhostnamelength; - - RTPHashTable destinations; -#ifdef RTP_SUPPORT_IPV4MULTICAST - RTPHashTable multicastgroups; -#endif // RTP_SUPPORT_IPV4MULTICAST - std::list rawpacketlist; - - bool supportsmulticasting; - std::size_t maxpacksize; - - class PortInfo - { - public: - PortInfo() - { - all = false; - } - - bool all; - std::list portlist; - }; - - RTPKeyHashTable acceptignoreinfo; - - bool closesocketswhendone; - RTPAbortDescriptors m_abortDesc; - RTPAbortDescriptors *m_pAbortDesc; // in case an external one was specified - -}; - -} // end namespace - -#endif // RTPUDPV4TRANSMITTER_H - diff --git a/qrtplib/rtpudpv4transmitternobind.cpp b/qrtplib/rtpudpv4transmitternobind.cpp deleted file mode 100644 index e51ba491d..000000000 --- a/qrtplib/rtpudpv4transmitternobind.cpp +++ /dev/null @@ -1,1836 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -#include "rtpudpv4transmitternobind.h" -#include "rtprawpacket.h" -#include "rtpipv4address.h" -#include "rtptimeutilities.h" -#include "rtpdefines.h" -#include "rtpstructs.h" -#include "rtpsocketutilinternal.h" -#include "rtpinternalutils.h" -#include "rtpselect.h" -#include -#include -#include - -#include - -using namespace std; - -#define RTPUDPV4TRANSNOBIND_MAXPACKSIZE 65535 -#define RTPUDPV4TRANSNOBIND_IFREQBUFSIZE 8192 - -#define RTPUDPV4TRANSNOBIND_IS_MCASTADDR(x) (((x)&0xF0000000) == 0xE0000000) - -#define RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(socket,type,mcastip,status) {\ - struct ip_mreq mreq;\ - \ - mreq.imr_multiaddr.s_addr = htonl(mcastip);\ - mreq.imr_interface.s_addr = htonl(mcastifaceIP);\ - status = setsockopt(socket,IPPROTO_IP,type,(const char *)&mreq,sizeof(struct ip_mreq));\ - } - -#define CLOSESOCKETS do { \ - if (closesocketswhendone) \ - {\ - if (rtpsock != rtcpsock) \ - RTPCLOSE(rtcpsock); \ - RTPCLOSE(rtpsock); \ - } \ -} while(0) - -namespace qrtplib -{ - -RTPUDPv4TransmitterNoBind::RTPUDPv4TransmitterNoBind() : - init(false), created(false), waitingfordata(false), rtpsock(-1), rtcpsock(-1), mcastifaceIP(0), m_rtpPort(0), m_rtcpPort(0), multicastTTL(0), receivemode(AcceptAll), localhostname( - 0), localhostnamelength(0), supportsmulticasting(false), maxpacksize(0), closesocketswhendone(false), m_pAbortDesc(0) -{ -} - -RTPUDPv4TransmitterNoBind::~RTPUDPv4TransmitterNoBind() -{ - Destroy(); -} - -int RTPUDPv4TransmitterNoBind::Init(bool tsafe) -{ - if (init) - return ERR_RTP_UDPV4TRANS_ALREADYINIT; - - if (tsafe) - return ERR_RTP_NOTHREADSUPPORT; - - init = true; - return 0; -} - -int RTPUDPv4TransmitterNoBind::GetIPv4SocketPort(SocketType s, uint16_t *pPort) -{ - assert(pPort != 0); - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - - RTPSOCKLENTYPE size = sizeof(struct sockaddr_in); - if (getsockname(s, (struct sockaddr*) &addr, &size) != 0) - return ERR_RTP_UDPV4TRANS_CANTGETSOCKETPORT; - - if (addr.sin_family != AF_INET) - return ERR_RTP_UDPV4TRANS_NOTANIPV4SOCKET; - - uint16_t port = ntohs(addr.sin_port); - if (port == 0) - return ERR_RTP_UDPV4TRANS_SOCKETPORTNOTSET; - - int type = 0; - RTPSOCKLENTYPE length = sizeof(type); - - if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char*) &type, &length) != 0) - return ERR_RTP_UDPV4TRANS_CANTGETSOCKETTYPE; - - if (type != SOCK_DGRAM) - return ERR_RTP_UDPV4TRANS_INVALIDSOCKETTYPE; - - *pPort = port; - return 0; -} - -int RTPUDPv4TransmitterNoBind::GetAutoSockets(uint32_t bindIP, bool allowOdd, bool rtcpMux, SocketType *pRtpSock, SocketType *pRtcpSock, uint16_t *pRtpPort, uint16_t *pRtcpPort) -{ - const int maxAttempts = 1024; - int attempts = 0; - vector toClose; - - while (attempts++ < maxAttempts) - { - SocketType sock = socket(PF_INET, SOCK_DGRAM, 0); - if (sock == RTPSOCKERR) - { - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - - // First we get an automatically chosen port - - struct sockaddr_in addr; - memset(&addr, 0, sizeof(struct sockaddr_in)); - - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - { - RTPCLOSE(sock); - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return ERR_RTP_UDPV4TRANS_CANTGETVALIDSOCKET; - } - - uint16_t basePort = 0; - int status = GetIPv4SocketPort(sock, &basePort); - if (status < 0) - { - RTPCLOSE(sock); - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return status; - } - - if (rtcpMux) // only need one socket - { - if (basePort % 2 == 0 || allowOdd) - { - *pRtpSock = sock; - *pRtcpSock = sock; - *pRtpPort = basePort; - *pRtcpPort = basePort; - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - - return 0; - } - else - toClose.push_back(sock); - } - else - { - SocketType sock2 = socket(PF_INET, SOCK_DGRAM, 0); - if (sock2 == RTPSOCKERR) - { - RTPCLOSE(sock); - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - - // Try the next port or the previous port - uint16_t secondPort = basePort; - bool possiblyValid = false; - - if (basePort % 2 == 0) - { - secondPort++; - possiblyValid = true; - } - else if (basePort > 1) // avoid landing on port 0 - { - secondPort--; - possiblyValid = true; - } - - if (possiblyValid) - { - memset(&addr, 0, sizeof(struct sockaddr_in)); - - addr.sin_family = AF_INET; - addr.sin_port = htons(secondPort); - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(sock2, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) == 0) - { - // In this case, we have two consecutive port numbers, the lower of - // which is even - - if (basePort < secondPort) - { - *pRtpSock = sock; - *pRtcpSock = sock2; - *pRtpPort = basePort; - *pRtcpPort = secondPort; - } - else - { - *pRtpSock = sock2; - *pRtcpSock = sock; - *pRtpPort = secondPort; - *pRtcpPort = basePort; - } - - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - - return 0; - } - } - - toClose.push_back(sock); - toClose.push_back(sock2); - } - } - - for (std::size_t i = 0; i < toClose.size(); i++) - RTPCLOSE(toClose[i]); - - return ERR_RTP_UDPV4TRANS_TOOMANYATTEMPTSCHOOSINGSOCKET; -} - -int RTPUDPv4TransmitterNoBind::Create(std::size_t maximumpacketsize, const RTPTransmissionParams *transparams) -{ - const RTPUDPv4TransmissionNoBindParams *params, defaultparams; -// struct sockaddr_in addr; - RTPSOCKLENTYPE size; - int status; - - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (created) - { - - return ERR_RTP_UDPV4TRANS_ALREADYCREATED; - } - - // Obtain transmission parameters - - if (transparams == 0) - params = &defaultparams; - else - { - if (transparams->GetTransmissionProtocol() != RTPTransmitter::IPv4UDPProto) - { - - return ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS; - } - params = (const RTPUDPv4TransmissionNoBindParams *) transparams; - } - - if (params->GetUseExistingSockets(rtpsock, rtcpsock)) - { - closesocketswhendone = false; - - // Determine the port numbers. They are set to 0 if the sockets are not bound. - GetIPv4SocketPort(rtpsock, &m_rtpPort); - GetIPv4SocketPort(rtcpsock, &m_rtcpPort); - } - else - { - closesocketswhendone = true; - - if (params->GetPortbase() == 0) - { - int status = GetAutoSockets(params->GetBindIP(), params->GetAllowOddPortbase(), params->GetRTCPMultiplexing(), &rtpsock, &rtcpsock, &m_rtpPort, &m_rtcpPort); - if (status < 0) - { - - return status; - } - } - else - { - // Check if portbase is even (if necessary) - if (!params->GetAllowOddPortbase() && params->GetPortbase() % 2 != 0) - { - - return ERR_RTP_UDPV4TRANS_PORTBASENOTEVEN; - } - - // create sockets - - rtpsock = socket(PF_INET, SOCK_DGRAM, 0); - if (rtpsock == RTPSOCKERR) - { - - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - - // If we're multiplexing, we're just going to set the RTCP socket to equal the RTP socket - if (params->GetRTCPMultiplexing()) - rtcpsock = rtpsock; - else - { - rtcpsock = socket(PF_INET, SOCK_DGRAM, 0); - if (rtcpsock == RTPSOCKERR) - { - RTPCLOSE(rtpsock); - - return ERR_RTP_UDPV4TRANS_CANTCREATESOCKET; - } - } - - } - - // set socket buffer sizes - - size = params->GetRTPReceiveBuffer(); - if (setsockopt(rtpsock, SOL_SOCKET, SO_RCVBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTPRECEIVEBUF; - } - size = params->GetRTPSendBuffer(); - if (setsockopt(rtpsock, SOL_SOCKET, SO_SNDBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTPTRANSMITBUF; - } - - if (rtpsock != rtcpsock) // no need to set RTCP flags when multiplexing - { - size = params->GetRTCPReceiveBuffer(); - if (setsockopt(rtcpsock, SOL_SOCKET, SO_RCVBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTCPRECEIVEBUF; - } - size = params->GetRTCPSendBuffer(); - if (setsockopt(rtcpsock, SOL_SOCKET, SO_SNDBUF, (const char *) &size, sizeof(int)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTSETRTCPTRANSMITBUF; - } - } - } - - // Try to obtain local IP addresses - - localIPs = params->GetLocalIPList(); - if (localIPs.empty()) // User did not provide list of local IP addresses, calculate them - { - int status; - - if ((status = CreateLocalIPList()) < 0) - { - CLOSESOCKETS; - - return status; - } - } - -#ifdef RTP_SUPPORT_IPV4MULTICAST - if (SetMulticastTTL(params->GetMulticastTTL())) - supportsmulticasting = true; - else - supportsmulticasting = false; -#else // no multicast support enabled - supportsmulticasting = false; -#endif // RTP_SUPPORT_IPV4MULTICAST - - if (maximumpacketsize > RTPUDPV4TRANSNOBIND_MAXPACKSIZE) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - - if (!params->GetCreatedAbortDescriptors()) - { - if ((status = m_abortDesc.Init()) < 0) - { - CLOSESOCKETS; - - return status; - } - m_pAbortDesc = &m_abortDesc; - } - else - { - m_pAbortDesc = params->GetCreatedAbortDescriptors(); - if (!m_pAbortDesc->IsInitialized()) - { - CLOSESOCKETS; - - return ERR_RTP_ABORTDESC_NOTINIT; - } - } - - maxpacksize = maximumpacketsize; - multicastTTL = params->GetMulticastTTL(); - mcastifaceIP = params->GetMulticastInterfaceIP(); - receivemode = RTPTransmitter::AcceptAll; - - localhostname = 0; - localhostnamelength = 0; - - waitingfordata = false; - created = true; - - return 0; -} - -int RTPUDPv4TransmitterNoBind::BindSockets(const RTPTransmissionParams *transparams) -{ - if (transparams->GetTransmissionProtocol() != RTPTransmitter::IPv4UDPProto) - { - - return ERR_RTP_UDPV4TRANS_ILLEGALPARAMETERS; - } - - const RTPUDPv4TransmissionNoBindParams *params = (const RTPUDPv4TransmissionNoBindParams *) transparams; - - uint32_t bindIP = params->GetBindIP(); - m_rtpPort = params->GetPortbase(); - struct sockaddr_in addr; - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(params->GetPortbase()); - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(rtpsock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTBINDRTPSOCKET; - } - - if (rtpsock != rtcpsock) // no need to bind same socket twice when multiplexing - { - uint16_t rtpport = params->GetPortbase(); - uint16_t rtcpport = params->GetForcedRTCPPort(); - - if (rtcpport == 0) - { - rtcpport = rtpport; - if (rtcpport < 0xFFFF) - rtcpport++; - } - - memset(&addr, 0, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(rtcpport); - addr.sin_addr.s_addr = htonl(bindIP); - if (bind(rtcpsock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - { - CLOSESOCKETS; - - return ERR_RTP_UDPV4TRANS_CANTBINDRTCPSOCKET; - } - - m_rtcpPort = rtcpport; - } - else - m_rtcpPort = m_rtpPort; - - return 0; -} - -void RTPUDPv4TransmitterNoBind::Destroy() -{ - if (!init) - return; - - if (!created) - { - ; - return; - } - - if (localhostname) - { - delete[] localhostname; - localhostname = 0; - localhostnamelength = 0; - } - - CLOSESOCKETS; - destinations.Clear(); -#ifdef RTP_SUPPORT_IPV4MULTICAST - multicastgroups.Clear(); -#endif // RTP_SUPPORT_IPV4MULTICAST - FlushPackets(); - ClearAcceptIgnoreInfo(); - localIPs.clear(); - created = false; - - if (waitingfordata) - { - m_pAbortDesc->SendAbortSignal(); - m_abortDesc.Destroy(); // Doesn't do anything if not initialized - - // to make sure that the WaitForIncomingData function ended - - } - else - m_abortDesc.Destroy(); // Doesn't do anything if not initialized - -} - -RTPTransmissionInfo *RTPUDPv4TransmitterNoBind::GetTransmissionInfo() -{ - if (!init) - return 0; - - RTPTransmissionInfo *tinf = new RTPUDPv4TransmissionNoBindInfo(localIPs, rtpsock, rtcpsock, m_rtpPort, m_rtcpPort); - - return tinf; -} - -void RTPUDPv4TransmitterNoBind::DeleteTransmissionInfo(RTPTransmissionInfo *i) -{ - if (!init) - return; - - delete i; -} - -int RTPUDPv4TransmitterNoBind::GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - - if (localhostname == 0) - { - if (localIPs.empty()) - { - - return ERR_RTP_UDPV4TRANS_NOLOCALIPS; - } - - std::list::const_iterator it; - std::list hostnames; - - for (it = localIPs.begin(); it != localIPs.end(); it++) - { - bool founddouble = false; - bool foundentry = true; - - while (!founddouble && foundentry) - { - struct hostent *he; - uint8_t addr[4]; - uint32_t ip = (*it); - - addr[0] = (uint8_t) ((ip >> 24) & 0xFF); - addr[1] = (uint8_t) ((ip >> 16) & 0xFF); - addr[2] = (uint8_t) ((ip >> 8) & 0xFF); - addr[3] = (uint8_t) (ip & 0xFF); - he = gethostbyaddr((char *) addr, 4, AF_INET); - if (he != 0) - { - std::string hname = std::string(he->h_name); - std::list::const_iterator it; - - for (it = hostnames.begin(); !founddouble && it != hostnames.end(); it++) - if ((*it) == hname) - founddouble = true; - - if (!founddouble) - hostnames.push_back(hname); - - int i = 0; - while (!founddouble && he->h_aliases[i] != 0) - { - std::string hname = std::string(he->h_aliases[i]); - - for (it = hostnames.begin(); !founddouble && it != hostnames.end(); it++) - if ((*it) == hname) - founddouble = true; - - if (!founddouble) - { - hostnames.push_back(hname); - i++; - } - } - } - else - foundentry = false; - } - } - - bool found = false; - - if (!hostnames.empty()) // try to select the most appropriate hostname - { - std::list::const_iterator it; - - hostnames.sort(); - for (it = hostnames.begin(); !found && it != hostnames.end(); it++) - { - if ((*it).find('.') != std::string::npos) - { - found = true; - localhostnamelength = (*it).length(); - localhostname = new uint8_t[localhostnamelength + 1]; - if (localhostname == 0) - { - - return ERR_RTP_OUTOFMEM; - } - memcpy(localhostname, (*it).c_str(), localhostnamelength); - localhostname[localhostnamelength] = 0; - } - } - } - - if (!found) // use an IP address - { - uint32_t ip; - int len; - char str[16]; - - it = localIPs.begin(); - ip = (*it); - - RTP_SNPRINTF(str, 16, "%d.%d.%d.%d", (int) ((ip >> 24) & 0xFF), (int) ((ip >> 16) & 0xFF), (int) ((ip >> 8) & 0xFF), (int) (ip & 0xFF)); - len = strlen(str); - - localhostnamelength = len; - localhostname = new uint8_t[localhostnamelength + 1]; - if (localhostname == 0) - { - - return ERR_RTP_OUTOFMEM; - } - memcpy(localhostname, str, localhostnamelength); - localhostname[localhostnamelength] = 0; - } - } - - if ((*bufferlength) < localhostnamelength) - { - *bufferlength = localhostnamelength; // tell the application the required size of the buffer - - return ERR_RTP_TRANS_BUFFERLENGTHTOOSMALL; - } - - memcpy(buffer, localhostname, localhostnamelength); - *bufferlength = localhostnamelength; - - return 0; -} - -bool RTPUDPv4TransmitterNoBind::ComesFromThisTransmitter(const RTPAddress *addr) -{ - if (!init) - return false; - - if (addr == 0) - return false; - - bool v; - - if (created && addr->GetAddressType() == RTPAddress::IPv4Address) - { - const RTPIPv4Address *addr2 = (const RTPIPv4Address *) addr; - bool found = false; - std::list::const_iterator it; - - it = localIPs.begin(); - while (!found && it != localIPs.end()) - { - if (addr2->GetIP() == *it) - found = true; - else - ++it; - } - - if (!found) - v = false; - else - { - if (addr2->GetPort() == m_rtpPort || addr2->GetPort() == m_rtcpPort) // check for RTP port and RTCP port - v = true; - else - v = false; - } - } - else - v = false; - - return v; -} - -int RTPUDPv4TransmitterNoBind::Poll() -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - status = PollSocket(true); // poll RTP socket - if (rtpsock != rtcpsock) // no need to poll twice when multiplexing - { - if (status >= 0) - status = PollSocket(false); // poll RTCP socket - } - - return status; -} - -int RTPUDPv4TransmitterNoBind::WaitForIncomingData(const RTPTime &delay, bool *dataavailable) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (waitingfordata) - { - - return ERR_RTP_UDPV4TRANS_ALREADYWAITING; - } - - SocketType abortSocket = m_pAbortDesc->GetAbortSocket(); - - SocketType socks[3] = - { rtpsock, rtcpsock, abortSocket }; - int8_t readflags[3] = - { 0, 0, 0 }; - const int idxRTP = 0; - const int idxRTCP = 1; - const int idxAbort = 2; - - waitingfordata = true; - - int status = RTPSelect(socks, readflags, 3, delay); - if (status < 0) - { - waitingfordata = false; - - return status; - } - - waitingfordata = false; - if (!created) // destroy called - { - ; - - return 0; - } - - // if aborted, read from abort buffer - if (readflags[idxAbort]) - m_pAbortDesc->ReadSignallingByte(); - - if (dataavailable != 0) - { - if (readflags[idxRTP] || readflags[idxRTCP]) - *dataavailable = true; - else - *dataavailable = false; - } - - return 0; -} - -int RTPUDPv4TransmitterNoBind::AbortWait() -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (!waitingfordata) - { - - return ERR_RTP_UDPV4TRANS_NOTWAITING; - } - - m_pAbortDesc->SendAbortSignal(); - - return 0; -} - -int RTPUDPv4TransmitterNoBind::SendRTPData(const void *data, std::size_t len) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (len > maxpacksize) - { - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - - destinations.GotoFirstElement(); - while (destinations.HasCurrentElement()) - { - sendto(rtpsock, (const char *) data, len, 0, (const struct sockaddr *) destinations.GetCurrentElement().GetRTPSockAddr(), sizeof(struct sockaddr_in)); - destinations.GotoNextElement(); - } - - return 0; -} - -int RTPUDPv4TransmitterNoBind::SendRTCPData(const void *data, std::size_t len) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (len > maxpacksize) - { - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - - destinations.GotoFirstElement(); - while (destinations.HasCurrentElement()) - { - sendto(rtcpsock, (const char *) data, len, 0, (const struct sockaddr *) destinations.GetCurrentElement().GetRTCPSockAddr(), sizeof(struct sockaddr_in)); - destinations.GotoNextElement(); - } - - return 0; -} - -int RTPUDPv4TransmitterNoBind::AddDestination(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - - RTPIPv4Destination dest; - if (!RTPIPv4Destination::AddressToDestination(addr, dest)) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - int status = destinations.AddElement(dest); - - return status; -} - -int RTPUDPv4TransmitterNoBind::DeleteDestination(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - RTPIPv4Destination dest; - if (!RTPIPv4Destination::AddressToDestination(addr, dest)) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - int status = destinations.DeleteElement(dest); - - return status; -} - -void RTPUDPv4TransmitterNoBind::ClearDestinations() -{ - if (!init) - return; - - if (created) - destinations.Clear(); - -} - -bool RTPUDPv4TransmitterNoBind::SupportsMulticasting() -{ - if (!init) - return false; - - bool v; - - if (!created) - v = false; - else - v = supportsmulticasting; - - return v; -} - -#ifdef RTP_SUPPORT_IPV4MULTICAST - -int RTPUDPv4TransmitterNoBind::JoinMulticastGroup(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - uint32_t mcastIP = address.GetIP(); - - if (!RTPUDPV4TRANSNOBIND_IS_MCASTADDR(mcastIP)) - { - - return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS; - } - - status = multicastgroups.AddElement(mcastIP); - if (status >= 0) - { - RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(rtpsock, IP_ADD_MEMBERSHIP, mcastIP, status); - if (status != 0) - { - multicastgroups.DeleteElement(mcastIP); - - return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP; - } - - if (rtpsock != rtcpsock) // no need to join multicast group twice when multiplexing - { - RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(rtcpsock, IP_ADD_MEMBERSHIP, mcastIP, status); - if (status != 0) - { - RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(rtpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - multicastgroups.DeleteElement(mcastIP); - - return ERR_RTP_UDPV4TRANS_COULDNTJOINMULTICASTGROUP; - } - } - } - - return status; -} - -int RTPUDPv4TransmitterNoBind::LeaveMulticastGroup(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - uint32_t mcastIP = address.GetIP(); - - if (!RTPUDPV4TRANSNOBIND_IS_MCASTADDR(mcastIP)) - { - - return ERR_RTP_UDPV4TRANS_NOTAMULTICASTADDRESS; - } - - status = multicastgroups.DeleteElement(mcastIP); - if (status >= 0) - { - RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(rtpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - if (rtpsock != rtcpsock) // no need to leave multicast group twice when multiplexing - RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(rtcpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - - status = 0; - } - - return status; -} - -void RTPUDPv4TransmitterNoBind::LeaveAllMulticastGroups() -{ - if (!init) - return; - - if (created) - { - multicastgroups.GotoFirstElement(); - while (multicastgroups.HasCurrentElement()) - { - uint32_t mcastIP; - int status __attribute__((unused)) = 0; - - mcastIP = multicastgroups.GetCurrentElement(); - - RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(rtpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - if (rtpsock != rtcpsock) // no need to leave multicast group twice when multiplexing - RTPUDPV4TRANSNOBIND_MCASTMEMBERSHIP(rtcpsock, IP_DROP_MEMBERSHIP, mcastIP, status); - - multicastgroups.GotoNextElement(); - } - multicastgroups.Clear(); - } - -} - -#else // no multicast support - -int RTPUDPv4TransmitterNoBind::JoinMulticastGroup(const RTPAddress &addr) -{ - return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT; -} - -int RTPUDPv4Transmitter::LeaveMulticastGroup(const RTPAddress &addr) -{ - return ERR_RTP_UDPV4TRANS_NOMULTICASTSUPPORT; -} - -void RTPUDPv4TransmitterNoBind::LeaveAllMulticastGroups() -{ -} - -#endif // RTP_SUPPORT_IPV4MULTICAST - -int RTPUDPv4TransmitterNoBind::SetReceiveMode(RTPTransmitter::ReceiveMode m) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (m != receivemode) - { - receivemode = m; - acceptignoreinfo.Clear(); - } - - return 0; -} - -int RTPUDPv4TransmitterNoBind::AddToIgnoreList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::IgnoreSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessAddAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -int RTPUDPv4TransmitterNoBind::DeleteFromIgnoreList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::IgnoreSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -void RTPUDPv4TransmitterNoBind::ClearIgnoreList() -{ - if (!init) - return; - - if (created && receivemode == RTPTransmitter::IgnoreSome) - ClearAcceptIgnoreInfo(); - -} - -int RTPUDPv4TransmitterNoBind::AddToAcceptList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::AcceptSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessAddAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -int RTPUDPv4TransmitterNoBind::DeleteFromAcceptList(const RTPAddress &addr) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - int status; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (addr.GetAddressType() != RTPAddress::IPv4Address) - { - - return ERR_RTP_UDPV4TRANS_INVALIDADDRESSTYPE; - } - if (receivemode != RTPTransmitter::AcceptSome) - { - - return ERR_RTP_UDPV4TRANS_DIFFERENTRECEIVEMODE; - } - - const RTPIPv4Address &address = (const RTPIPv4Address &) addr; - status = ProcessDeleteAcceptIgnoreEntry(address.GetIP(), address.GetPort()); - - return status; -} - -void RTPUDPv4TransmitterNoBind::ClearAcceptList() -{ - if (!init) - return; - - if (created && receivemode == RTPTransmitter::AcceptSome) - ClearAcceptIgnoreInfo(); - -} - -int RTPUDPv4TransmitterNoBind::SetMaximumPacketSize(std::size_t s) -{ - if (!init) - return ERR_RTP_UDPV4TRANS_NOTINIT; - - if (!created) - { - - return ERR_RTP_UDPV4TRANS_NOTCREATED; - } - if (s > RTPUDPV4TRANSNOBIND_MAXPACKSIZE) - { - - return ERR_RTP_UDPV4TRANS_SPECIFIEDSIZETOOBIG; - } - maxpacksize = s; - - return 0; -} - -bool RTPUDPv4TransmitterNoBind::NewDataAvailable() -{ - if (!init) - return false; - - bool v; - - if (!created) - v = false; - else - { - if (rawpacketlist.empty()) - v = false; - else - v = true; - } - - return v; -} - -RTPRawPacket *RTPUDPv4TransmitterNoBind::GetNextPacket() -{ - if (!init) - return 0; - - RTPRawPacket *p; - - if (!created) - { - - return 0; - } - if (rawpacketlist.empty()) - { - - return 0; - } - - p = *(rawpacketlist.begin()); - rawpacketlist.pop_front(); - - return p; -} - -// Here the private functions start... - -#ifdef RTP_SUPPORT_IPV4MULTICAST -bool RTPUDPv4TransmitterNoBind::SetMulticastTTL(uint8_t ttl) -{ - int ttl2, status; - - ttl2 = (int) ttl; - status = setsockopt(rtpsock, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &ttl2, sizeof(int)); - if (status != 0) - return false; - - if (rtpsock != rtcpsock) // no need to set TTL twice when multiplexing - { - status = setsockopt(rtcpsock, IPPROTO_IP, IP_MULTICAST_TTL, (const char *) &ttl2, sizeof(int)); - if (status != 0) - return false; - } - return true; -} -#endif // RTP_SUPPORT_IPV4MULTICAST - -void RTPUDPv4TransmitterNoBind::FlushPackets() -{ - std::list::const_iterator it; - - for (it = rawpacketlist.begin(); it != rawpacketlist.end(); ++it) - delete *it; - rawpacketlist.clear(); -} - -int RTPUDPv4TransmitterNoBind::PollSocket(bool rtp) -{ - RTPSOCKLENTYPE fromlen; - int recvlen; - char packetbuffer[RTPUDPV4TRANSNOBIND_MAXPACKSIZE]; -#ifdef RTP_SOCKETTYPE_WINSOCK - SOCKET sock; - unsigned long len; -#else - std::size_t len; - int sock; -#endif // RTP_SOCKETTYPE_WINSOCK - struct sockaddr_in srcaddr; - bool dataavailable; - - if (rtp) - sock = rtpsock; - else - sock = rtcpsock; - - do - { - len = 0; - RTPIOCTL(sock, FIONREAD, &len); - - if (len <= 0) // make sure a packet of length zero is not queued - { - // An alternative workaround would be to just use non-blocking sockets. - // However, since the user does have access to the sockets and I do not - // know how this would affect anyone else's code, I chose to do it using - // an extra select call in case ioctl says the length is zero. - - int8_t isset = 0; - int status = RTPSelect(&sock, &isset, 1, RTPTime(0)); - if (status < 0) - return status; - - if (isset) - dataavailable = true; - else - dataavailable = false; - } - else - dataavailable = true; - - if (dataavailable) - { - RTPTime curtime = RTPTime::CurrentTime(); - fromlen = sizeof(struct sockaddr_in); - recvlen = recvfrom(sock, packetbuffer, RTPUDPV4TRANSNOBIND_MAXPACKSIZE, 0, (struct sockaddr *) &srcaddr, &fromlen); - if (recvlen > 0) - { - bool acceptdata; - - // got data, process it - if (receivemode == RTPTransmitter::AcceptAll) - acceptdata = true; - else - acceptdata = ShouldAcceptData(ntohl(srcaddr.sin_addr.s_addr), ntohs(srcaddr.sin_port)); - - if (acceptdata) - { - RTPRawPacket *pack; - RTPIPv4Address *addr; - uint8_t *datacopy; - - addr = new RTPIPv4Address(ntohl(srcaddr.sin_addr.s_addr), ntohs(srcaddr.sin_port)); - if (addr == 0) - return ERR_RTP_OUTOFMEM; - datacopy = new uint8_t[recvlen]; - if (datacopy == 0) - { - delete addr; - return ERR_RTP_OUTOFMEM; - } - memcpy(datacopy, packetbuffer, recvlen); - - bool isrtp = rtp; - if (rtpsock == rtcpsock) // check payload type when multiplexing - { - isrtp = true; - - if ((std::size_t) recvlen > sizeof(RTCPCommonHeader)) - { - RTCPCommonHeader *rtcpheader = (RTCPCommonHeader *) datacopy; - uint8_t packettype = rtcpheader->packettype; - - if (packettype >= 200 && packettype <= 204) - isrtp = false; - } - } - - pack = new RTPRawPacket(datacopy, recvlen, addr, curtime, isrtp); - if (pack == 0) - { - delete addr; - delete[] datacopy; - return ERR_RTP_OUTOFMEM; - } - rawpacketlist.push_back(pack); - } - } - } - } while (dataavailable); - - return 0; -} - -int RTPUDPv4TransmitterNoBind::ProcessAddAcceptIgnoreEntry(uint32_t ip, uint16_t port) -{ - acceptignoreinfo.GotoElement(ip); - if (acceptignoreinfo.HasCurrentElement()) // An entry for this IP address already exists - { - PortInfo *portinf = acceptignoreinfo.GetCurrentElement(); - - if (port == 0) // select all ports - { - portinf->all = true; - portinf->portlist.clear(); - } - else if (!portinf->all) - { - std::list::const_iterator it, begin, end; - - begin = portinf->portlist.begin(); - end = portinf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == port) // already in list - return 0; - } - portinf->portlist.push_front(port); - } - } - else // got to create an entry for this IP address - { - PortInfo *portinf; - int status; - - portinf = new PortInfo(); - if (port == 0) // select all ports - portinf->all = true; - else - portinf->portlist.push_front(port); - - status = acceptignoreinfo.AddElement(ip, portinf); - if (status < 0) - { - delete portinf; - return status; - } - } - - return 0; -} - -void RTPUDPv4TransmitterNoBind::ClearAcceptIgnoreInfo() -{ - acceptignoreinfo.GotoFirstElement(); - while (acceptignoreinfo.HasCurrentElement()) - { - PortInfo *inf; - - inf = acceptignoreinfo.GetCurrentElement(); - delete inf; - acceptignoreinfo.GotoNextElement(); - } - acceptignoreinfo.Clear(); -} - -int RTPUDPv4TransmitterNoBind::ProcessDeleteAcceptIgnoreEntry(uint32_t ip, uint16_t port) -{ - acceptignoreinfo.GotoElement(ip); - if (!acceptignoreinfo.HasCurrentElement()) - return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; - - PortInfo *inf; - - inf = acceptignoreinfo.GetCurrentElement(); - if (port == 0) // delete all entries - { - inf->all = false; - inf->portlist.clear(); - } - else // a specific port was selected - { - if (inf->all) // currently, all ports are selected. Add the one to remove to the list - { - // we have to check if the list doesn't contain the port already - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == port) // already in list: this means we already deleted the entry - return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; - } - inf->portlist.push_front(port); - } - else // check if we can find the port in the list - { - std::list::iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; ++it) - { - if (*it == port) // found it! - { - inf->portlist.erase(it); - return 0; - } - } - // didn't find it - return ERR_RTP_UDPV4TRANS_NOSUCHENTRY; - } - } - return 0; -} - -bool RTPUDPv4TransmitterNoBind::ShouldAcceptData(uint32_t srcip, uint16_t srcport) -{ - if (receivemode == RTPTransmitter::AcceptSome) - { - PortInfo *inf; - - acceptignoreinfo.GotoElement(srcip); - if (!acceptignoreinfo.HasCurrentElement()) - return false; - - inf = acceptignoreinfo.GetCurrentElement(); - if (!inf->all) // only accept the ones in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return true; - } - return false; - } - else // accept all, except the ones in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return false; - } - return true; - } - } - else // IgnoreSome - { - PortInfo *inf; - - acceptignoreinfo.GotoElement(srcip); - if (!acceptignoreinfo.HasCurrentElement()) - return true; - - inf = acceptignoreinfo.GetCurrentElement(); - if (!inf->all) // ignore the ports in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return false; - } - return true; - } - else // ignore all, except the ones in the list - { - std::list::const_iterator it, begin, end; - - begin = inf->portlist.begin(); - end = inf->portlist.end(); - for (it = begin; it != end; it++) - { - if (*it == srcport) - return true; - } - return false; - } - } - return true; -} - -int RTPUDPv4TransmitterNoBind::CreateLocalIPList() -{ - // first try to obtain the list from the network interface info - - if (!GetLocalIPList_Interfaces()) - { - // If this fails, we'll have to depend on DNS info - GetLocalIPList_DNS(); - } - AddLoopbackAddress(); - return 0; -} - -#ifdef RTP_SOCKETTYPE_WINSOCK - -bool RTPUDPv4TransmitterNoBind::GetLocalIPList_Interfaces() -{ - unsigned char buffer[RTPUDPV4TRANSNOBIND_IFREQBUFSIZE]; - DWORD outputsize; - DWORD numaddresses,i; - SOCKET_ADDRESS_LIST *addrlist; - - if (WSAIoctl(rtpsock,SIO_ADDRESS_LIST_QUERY,NULL,0,&buffer,RTPUDPV4TRANSNOBIND_IFREQBUFSIZE,&outputsize,NULL,NULL)) - return false; - - addrlist = (SOCKET_ADDRESS_LIST *)buffer; - numaddresses = addrlist->iAddressCount; - for (i = 0; i < numaddresses; i++) - { - SOCKET_ADDRESS *sockaddr = &(addrlist->Address[i]); - if (sockaddr->iSockaddrLength == sizeof(struct sockaddr_in)) // IPv4 address - { - struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr->lpSockaddr; - - localIPs.push_back(ntohl(addr->sin_addr.s_addr)); - } - } - - if (localIPs.empty()) - return false; - - return true; -} - -#else // use either getifaddrs or ioctl - -#ifdef RTP_SUPPORT_IFADDRS - -bool RTPUDPv4TransmitterNoBind::GetLocalIPList_Interfaces() -{ - struct ifaddrs *addrs, *tmp; - - getifaddrs(&addrs); - tmp = addrs; - - while (tmp != 0) - { - if (tmp->ifa_addr != 0 && tmp->ifa_addr->sa_family == AF_INET) - { - struct sockaddr_in *inaddr = (struct sockaddr_in *) tmp->ifa_addr; - localIPs.push_back(ntohl(inaddr->sin_addr.s_addr)); - } - tmp = tmp->ifa_next; - } - - freeifaddrs(addrs); - - if (localIPs.empty()) - return false; - return true; -} - -#else // user ioctl - -bool RTPUDPv4TransmitterNoBind::GetLocalIPList_Interfaces() -{ - int status; - char buffer[RTPUDPV4TRANSNOBIND_IFREQBUFSIZE]; - struct ifconf ifc; - struct ifreq *ifr; - struct sockaddr *sa; - char *startptr,*endptr; - int remlen; - - ifc.ifc_len = RTPUDPV4TRANSNOBIND_IFREQBUFSIZE; - ifc.ifc_buf = buffer; - status = ioctl(rtpsock,SIOCGIFCONF,&ifc); - if (status < 0) - return false; - - startptr = (char *)ifc.ifc_req; - endptr = startptr + ifc.ifc_len; - remlen = ifc.ifc_len; - while((startptr < endptr) && remlen >= (int)sizeof(struct ifreq)) - { - ifr = (struct ifreq *)startptr; - sa = &(ifr->ifr_addr); -#ifdef RTP_HAVE_SOCKADDR_LEN - if (sa->sa_len <= sizeof(struct sockaddr)) - { - if (sa->sa_len == sizeof(struct sockaddr_in) && sa->sa_family == PF_INET) - { - uint32_t ip; - struct sockaddr_in *addr = (struct sockaddr_in *)sa; - - ip = ntohl(addr->sin_addr.s_addr); - localIPs.push_back(ip); - } - remlen -= sizeof(struct ifreq); - startptr += sizeof(struct ifreq); - } - else - { - int l = sa->sa_len-sizeof(struct sockaddr)+sizeof(struct ifreq); - - remlen -= l; - startptr += l; - } -#else // don't have sa_len in struct sockaddr - if (sa->sa_family == PF_INET) - { - uint32_t ip; - struct sockaddr_in *addr = (struct sockaddr_in *)sa; - - ip = ntohl(addr->sin_addr.s_addr); - localIPs.push_back(ip); - } - remlen -= sizeof(struct ifreq); - startptr += sizeof(struct ifreq); - -#endif // RTP_HAVE_SOCKADDR_LEN - } - - if (localIPs.empty()) - return false; - return true; -} - -#endif // RTP_SUPPORT_IFADDRS - -#endif // RTP_SOCKETTYPE_WINSOCK - -void RTPUDPv4TransmitterNoBind::GetLocalIPList_DNS() -{ - struct hostent *he; - char name[1024]; - bool done; - int i, j; - - gethostname(name, 1023); - name[1023] = 0; - he = gethostbyname(name); - if (he == 0) - return; - - i = 0; - done = false; - while (!done) - { - if (he->h_addr_list[i] == NULL) - done = true; - else - { - uint32_t ip = 0; - - for (j = 0; j < 4; j++) - ip |= ((uint32_t) ((unsigned char) he->h_addr_list[i][j]) << ((3 - j) * 8)); - localIPs.push_back(ip); - i++; - } - } -} - -void RTPUDPv4TransmitterNoBind::AddLoopbackAddress() -{ - uint32_t loopbackaddr = (((uint32_t) 127) << 24) | ((uint32_t) 1); - std::list::const_iterator it; - bool found = false; - - for (it = localIPs.begin(); !found && it != localIPs.end(); it++) - { - if (*it == loopbackaddr) - found = true; - } - - if (!found) - localIPs.push_back(loopbackaddr); -} - -} // end namespace - diff --git a/qrtplib/rtpudpv4transmitternobind.h b/qrtplib/rtpudpv4transmitternobind.h deleted file mode 100644 index 5cef0a739..000000000 --- a/qrtplib/rtpudpv4transmitternobind.h +++ /dev/null @@ -1,492 +0,0 @@ -/* - - This file is a part of JRTPLIB - Copyright (c) 1999-2017 Jori Liesenborgs - - Contact: jori.liesenborgs@gmail.com - - This library was developed at the Expertise Centre for Digital Media - (http://www.edm.uhasselt.be), a research center of the Hasselt University - (http://www.uhasselt.be). The library is based upon work done for - my thesis at the School for Knowledge Technology (Belgium/The Netherlands). - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - - */ - -/** - * \file rtpudpv4transmitternobind.h - */ - -#ifndef RTPUDPV4TRANSMITTERNOBIND_H - -#define RTPUDPV4TRANSMITTERNOBIND_H - -#include "rtpconfig.h" -#include "rtptransmitter.h" -#include "rtpipv4destination.h" -#include "rtphashtable.h" -#include "rtpkeyhashtable.h" -#include "rtpsocketutil.h" -#include "rtpabortdescriptors.h" -#include - -#include "util/export.h" - -#define RTPUDPV4TRANSNOBIND_HASHSIZE 8317 -#define RTPUDPV4TRANSNOBIND_DEFAULTPORTBASE 5000 - -#define RTPUDPV4TRANSNOBIND_RTPRECEIVEBUFFER 32768 -#define RTPUDPV4TRANSNOBIND_RTCPRECEIVEBUFFER 32768 -#define RTPUDPV4TRANSNOBIND_RTPTRANSMITBUFFER 32768 -#define RTPUDPV4TRANSNOBIND_RTCPTRANSMITBUFFER 32768 - -namespace qrtplib -{ - -/** Parameters for the UDP over IPv4 transmitter that does not automatically bind sockets */ -class QRTPLIB_API RTPUDPv4TransmissionNoBindParams: public RTPTransmissionParams -{ -public: - RTPUDPv4TransmissionNoBindParams(); - - /** Sets the IP address which is used to bind the sockets to \c ip. */ - void SetBindIP(uint32_t ip) - { - bindIP = ip; - } - - /** Sets the multicast interface IP address. */ - void SetMulticastInterfaceIP(uint32_t ip) - { - mcastifaceIP = ip; - } - - /** Sets the RTP portbase to \c pbase, which has to be an even number - * unless RTPUDPv4TransmissionParams::SetAllowOddPortbase was called; - * a port number of zero will cause a port to be chosen automatically. */ - void SetPortbase(uint16_t pbase) - { - portbase = pbase; - } - - /** Sets the multicast TTL to be used to \c mcastTTL. */ - void SetMulticastTTL(uint8_t mcastTTL) - { - multicastTTL = mcastTTL; - } - - /** Passes a list of IP addresses which will be used as the local IP addresses. */ - void SetLocalIPList(std::list &iplist) - { - localIPs = iplist; - } - - /** Clears the list of local IP addresses. - * Clears the list of local IP addresses. An empty list will make the transmission - * component itself determine the local IP addresses. - */ - void ClearLocalIPList() - { - localIPs.clear(); - } - - /** Returns the IP address which will be used to bind the sockets. */ - uint32_t GetBindIP() const - { - return bindIP; - } - - /** Returns the multicast interface IP address. */ - uint32_t GetMulticastInterfaceIP() const - { - return mcastifaceIP; - } - - /** Returns the RTP portbase which will be used (default is 5000). */ - uint16_t GetPortbase() const - { - return portbase; - } - - /** Returns the multicast TTL which will be used (default is 1). */ - uint8_t GetMulticastTTL() const - { - return multicastTTL; - } - - /** Returns the list of local IP addresses. */ - const std::list &GetLocalIPList() const - { - return localIPs; - } - - /** Sets the RTP socket's send buffer size. */ - void SetRTPSendBuffer(int s) - { - rtpsendbuf = s; - } - - /** Sets the RTP socket's receive buffer size. */ - void SetRTPReceiveBuffer(int s) - { - rtprecvbuf = s; - } - - /** Sets the RTCP socket's send buffer size. */ - void SetRTCPSendBuffer(int s) - { - rtcpsendbuf = s; - } - - /** Sets the RTCP socket's receive buffer size. */ - void SetRTCPReceiveBuffer(int s) - { - rtcprecvbuf = s; - } - - /** Enables or disables multiplexing RTCP traffic over the RTP channel, so that only a single port is used. */ - void SetRTCPMultiplexing(bool f) - { - rtcpmux = f; - } - - /** Can be used to allow the RTP port base to be any number, not just even numbers. */ - void SetAllowOddPortbase(bool f) - { - allowoddportbase = f; - } - - /** Force the RTCP socket to use a specific port, not necessarily one more than - * the RTP port (set this to zero to disable). */ - void SetForcedRTCPPort(uint16_t rtcpport) - { - forcedrtcpport = rtcpport; - } - - /** Use sockets that have already been created, no checks on port numbers - * will be done, and no buffer sizes will be set; you'll need to close - * the sockets yourself when done, it will **not** be done automatically. */ - void SetUseExistingSockets(SocketType rtpsocket, SocketType rtcpsocket) - { - rtpsock = rtpsocket; - rtcpsock = rtcpsocket; - useexistingsockets = true; - } - - /** If non null, the specified abort descriptors will be used to cancel - * the function that's waiting for packets to arrive; set to null (the default - * to let the transmitter create its own instance. */ - void SetCreatedAbortDescriptors(RTPAbortDescriptors *desc) - { - m_pAbortDesc = desc; - } - - /** Returns the RTP socket's send buffer size. */ - int GetRTPSendBuffer() const - { - return rtpsendbuf; - } - - /** Returns the RTP socket's receive buffer size. */ - int GetRTPReceiveBuffer() const - { - return rtprecvbuf; - } - - /** Returns the RTCP socket's send buffer size. */ - int GetRTCPSendBuffer() const - { - return rtcpsendbuf; - } - - /** Returns the RTCP socket's receive buffer size. */ - int GetRTCPReceiveBuffer() const - { - return rtcprecvbuf; - } - - /** Returns a flag indicating if RTCP traffic will be multiplexed over the RTP channel. */ - bool GetRTCPMultiplexing() const - { - return rtcpmux; - } - - /** If true, any RTP portbase will be allowed, not just even numbers. */ - bool GetAllowOddPortbase() const - { - return allowoddportbase; - } - - /** If non-zero, the specified port will be used to receive RTCP traffic. */ - uint16_t GetForcedRTCPPort() const - { - return forcedrtcpport; - } - - /** Returns true and fills in sockets if existing sockets were set - * using RTPUDPv4TransmissionParams::SetUseExistingSockets. */ - bool GetUseExistingSockets(SocketType &rtpsocket, SocketType &rtcpsocket) const - { - if (!useexistingsockets) - return false; - rtpsocket = rtpsock; - rtcpsocket = rtcpsock; - return true; - } - - /** If non-null, this RTPAbortDescriptors instance will be used internally, - * which can be useful when creating your own poll thread for multiple - * sessions. */ - RTPAbortDescriptors *GetCreatedAbortDescriptors() const - { - return m_pAbortDesc; - } -private: - uint16_t portbase; - uint32_t bindIP, mcastifaceIP; - std::list localIPs; - uint8_t multicastTTL; - int rtpsendbuf, rtprecvbuf; - int rtcpsendbuf, rtcprecvbuf; - bool rtcpmux; - bool allowoddportbase; - uint16_t forcedrtcpport; - - SocketType rtpsock, rtcpsock; - bool useexistingsockets; - - RTPAbortDescriptors *m_pAbortDesc; -}; - -inline RTPUDPv4TransmissionNoBindParams::RTPUDPv4TransmissionNoBindParams() : - RTPTransmissionParams(RTPTransmitter::IPv4UDPProto) -{ - portbase = RTPUDPV4TRANSNOBIND_DEFAULTPORTBASE; - bindIP = 0; - multicastTTL = 1; - mcastifaceIP = 0; - rtpsendbuf = RTPUDPV4TRANSNOBIND_RTPTRANSMITBUFFER; - rtprecvbuf = RTPUDPV4TRANSNOBIND_RTPRECEIVEBUFFER; - rtcpsendbuf = RTPUDPV4TRANSNOBIND_RTCPTRANSMITBUFFER; - rtcprecvbuf = RTPUDPV4TRANSNOBIND_RTCPRECEIVEBUFFER; - rtcpmux = false; - allowoddportbase = false; - forcedrtcpport = 0; - useexistingsockets = false; - rtpsock = 0; - rtcpsock = 0; - m_pAbortDesc = 0; -} - -/** Additional information about the UDP over IPv4 transmitter that does not automatically bind sockets. */ -class QRTPLIB_API RTPUDPv4TransmissionNoBindInfo: public RTPTransmissionInfo -{ -public: - RTPUDPv4TransmissionNoBindInfo(const QHostAddress& ip, SocketType rtpsock, SocketType rtcpsock, uint16_t rtpport, uint16_t rtcpport) : - RTPTransmissionInfo(RTPTransmitter::IPv4UDPProto) - { - localIP = ip; - rtpsocket = rtpsock; - rtcpsocket = rtcpsock; - m_rtpPort = rtpport; - m_rtcpPort = rtcpport; - } - - ~RTPUDPv4TransmissionNoBindInfo() - { - } - - /** Returns the list of IPv4 addresses the transmitter considers to be the local IP addresses. */ - QHostAddress GetLocalIP() const - { - return localIP; - } - - /** Returns the socket descriptor used for receiving and transmitting RTP packets. */ - SocketType GetRTPSocket() const - { - return rtpsocket; - } - - /** Returns the socket descriptor used for receiving and transmitting RTCP packets. */ - SocketType GetRTCPSocket() const - { - return rtcpsocket; - } - - /** Returns the port number that the RTP socket receives packets on. */ - uint16_t GetRTPPort() const - { - return m_rtpPort; - } - - /** Returns the port number that the RTCP socket receives packets on. */ - uint16_t GetRTCPPort() const - { - return m_rtcpPort; - } -private: - QHostAddress localIP; - SocketType rtpsocket, rtcpsocket; - uint16_t m_rtpPort, m_rtcpPort; -}; - -class RTPUDPv4TransNoBind_GetHashIndex_IPv4Dest -{ -public: - static int GetIndex(const RTPIPv4Destination &d) - { - return d.GetIP() % RTPUDPV4TRANSNOBIND_HASHSIZE; - } -}; - -class RTPUDPv4TransNoBind_GetHashIndex_uint32_t -{ -public: - static int GetIndex(const uint32_t &k) - { - return k % RTPUDPV4TRANSNOBIND_HASHSIZE; - } -}; - -#define RTPUDPV4TRANSNOBIND_HEADERSIZE (20+8) - -/** An UDP over IPv4 transmission component. - * This class inherits the RTPTransmitter interface and implements a transmission component - * which uses UDP over IPv4 to send and receive RTP and RTCP data. The component's parameters - * are described by the class RTPUDPv4TransmissionNoBindParams. The functions which have an RTPAddress - * argument require an argument of RTPIPv4Address. The GetTransmissionInfo member function - * returns an instance of type RTPUDPv4TransmissionNoBindInfo. - * This flavor of a RTPUDPv4Transmitter class does not automatically bind sockets. Use the - * BindSockets method to do so. - */ -class QRTPLIB_API RTPUDPv4TransmitterNoBind: public RTPTransmitter -{ -public: - RTPUDPv4TransmitterNoBind(); - ~RTPUDPv4TransmitterNoBind(); - - int Init(bool treadsafe); - int Create(std::size_t maxpacksize, const RTPTransmissionParams *transparams); - /** Bind the RTP and RTCP sockets to ports defined in the transmission parameters */ - int BindSockets(const RTPTransmissionParams *transparams); - void Destroy(); - RTPTransmissionInfo *GetTransmissionInfo(); - void DeleteTransmissionInfo(RTPTransmissionInfo *inf); - - int GetLocalHostName(uint8_t *buffer, std::size_t *bufferlength); - bool ComesFromThisTransmitter(const RTPAddress *addr); - std::size_t GetHeaderOverhead() - { - return RTPUDPV4TRANSNOBIND_HEADERSIZE; - } - - int Poll(); - int WaitForIncomingData(const RTPTime &delay, bool *dataavailable = 0); - int AbortWait(); - - int SendRTPData(const void *data, std::size_t len); - int SendRTCPData(const void *data, std::size_t len); - - int AddDestination(const RTPAddress &addr); - int DeleteDestination(const RTPAddress &addr); - void ClearDestinations(); - - bool SupportsMulticasting(); - int JoinMulticastGroup(const RTPAddress &addr); - int LeaveMulticastGroup(const RTPAddress &addr); - void LeaveAllMulticastGroups(); - - int SetReceiveMode(RTPTransmitter::ReceiveMode m); - int AddToIgnoreList(const RTPAddress &addr); - int DeleteFromIgnoreList(const RTPAddress &addr); - void ClearIgnoreList(); - int AddToAcceptList(const RTPAddress &addr); - int DeleteFromAcceptList(const RTPAddress &addr); - void ClearAcceptList(); - int SetMaximumPacketSize(std::size_t s); - - bool NewDataAvailable(); - RTPRawPacket *GetNextPacket(); - -private: - int CreateLocalIPList(); - bool GetLocalIPList_Interfaces(); - void GetLocalIPList_DNS(); - void AddLoopbackAddress(); - void FlushPackets(); - int PollSocket(bool rtp); - int ProcessAddAcceptIgnoreEntry(uint32_t ip, uint16_t port); - int ProcessDeleteAcceptIgnoreEntry(uint32_t ip, uint16_t port); -#ifdef RTP_SUPPORT_IPV4MULTICAST - bool SetMulticastTTL(uint8_t ttl); -#endif // RTP_SUPPORT_IPV4MULTICAST - bool ShouldAcceptData(uint32_t srcip, uint16_t srcport); - void ClearAcceptIgnoreInfo(); - - int GetAutoSockets(uint32_t bindIP, bool allowOdd, bool rtcpMux, SocketType *pRtpSock, SocketType *pRtcpSock, uint16_t *pRtpPort, uint16_t *pRtcpPort); - static int GetIPv4SocketPort(SocketType s, uint16_t *pPort); - - bool init; - bool created; - bool waitingfordata; - SocketType rtpsock, rtcpsock; - uint32_t mcastifaceIP; - std::list localIPs; - uint16_t m_rtpPort, m_rtcpPort; - uint8_t multicastTTL; - RTPTransmitter::ReceiveMode receivemode; - - uint8_t *localhostname; - std::size_t localhostnamelength; - - RTPHashTable destinations; -#ifdef RTP_SUPPORT_IPV4MULTICAST - RTPHashTable multicastgroups; -#endif // RTP_SUPPORT_IPV4MULTICAST - std::list rawpacketlist; - - bool supportsmulticasting; - std::size_t maxpacksize; - - class PortInfo - { - public: - PortInfo() - { - all = false; - } - - bool all; - std::list portlist; - }; - - RTPKeyHashTable acceptignoreinfo; - - bool closesocketswhendone; - RTPAbortDescriptors m_abortDesc; - RTPAbortDescriptors *m_pAbortDesc; // in case an external one was specified - -}; - -} // end namespace - -#endif // RTPUDPV4TRANSMITTERNOBIND_H -