diff --git a/HISTORY b/HISTORY index 5324faa..9569d30 100644 --- a/HISTORY +++ b/HISTORY @@ -164,3 +164,5 @@ VDR Plugin 'iptv' Revision History - Updated for vdr-1.7.27. - Fixed some channel switching bugs. - Added support for a service interface. +- Changed UDP protocol to always utilize the source address + validation. diff --git a/README b/README index 796f436..61a82fc 100644 --- a/README +++ b/README @@ -161,9 +161,6 @@ Notes: - EIT scanning functionality can be disabled for all IPTV channels by applying the "disable_eitscan" patch to the VDR. -- Source address validation can be enabled for UDP protocol separated by - adding the source address after a ';' character: "U=239.192.0.1;239.192.0.2" - - Section id and pid scanners should be disabled after the correct data is found. This can be made via VDR's channel editor. diff --git a/protocoludp.c b/protocoludp.c index bfe3b65..03cd8e6 100644 --- a/protocoludp.c +++ b/protocoludp.c @@ -20,7 +20,6 @@ cIptvProtocolUdp::cIptvProtocolUdp() : streamAddr(strdup("")), - sourceAddr(strdup("")), streamPort(0) { debug("cIptvProtocolUdp::cIptvProtocolUdp()\n"); @@ -33,33 +32,31 @@ cIptvProtocolUdp::~cIptvProtocolUdp() cIptvProtocolUdp::Close(); // Free allocated memory free(streamAddr); - free(sourceAddr); } bool cIptvProtocolUdp::Open(void) { - debug("cIptvProtocolUdp::Open(): sourceAddr=%s streamAddr=%s\n", sourceAddr, streamAddr); - OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); + debug("cIptvProtocolUdp::Open(): streamAddr=%s\n", streamAddr); + OpenSocket(streamPort, inet_addr(streamAddr)); if (!isempty(streamAddr)) { // Join a new multicast group - JoinMulticast(inet_addr(streamAddr)); + JoinMulticast(); } return true; } bool cIptvProtocolUdp::Close(void) { - debug("cIptvProtocolUdp::Close(): sourceAddr=%s streamAddr=%s\n", sourceAddr, streamAddr); + debug("cIptvProtocolUdp::Close(): streamAddr=%s\n", streamAddr); if (!isempty(streamAddr)) { // Drop the multicast group - OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); - DropMulticast(inet_addr(streamAddr)); + OpenSocket(streamPort, inet_addr(streamAddr)); + DropMulticast(); } // Close the socket CloseSocket(); // Do NOT reset stream and source addresses //streamAddr = strcpyrealloc(streamAddr, ""); - //sourceAddr = strcpyrealloc(sourceAddr, ""); //streamPort = 0; return true; } @@ -75,23 +72,16 @@ bool cIptvProtocolUdp::Set(const char* Location, const int Parameter, const int if (!isempty(Location)) { // Drop the multicast group if (!isempty(streamAddr)) { - OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); - DropMulticast(inet_addr(streamAddr)); + OpenSocket(streamPort, inet_addr(streamAddr)); + DropMulticast(); } // Update stream address and port streamAddr = strcpyrealloc(streamAddr, Location); - char *p = strstr(streamAddr, ";"); - if (p) { - sourceAddr = strcpyrealloc(sourceAddr, p + 1); - *p = 0; - } - else - sourceAddr = strcpyrealloc(sourceAddr, ""); streamPort = Parameter; // Join a new multicast group if (!isempty(streamAddr)) { - OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr)); - JoinMulticast(inet_addr(streamAddr)); + OpenSocket(streamPort, inet_addr(streamAddr)); + JoinMulticast(); } } return true; diff --git a/protocoludp.h b/protocoludp.h index 5831bab..0a8fcca 100644 --- a/protocoludp.h +++ b/protocoludp.h @@ -15,7 +15,6 @@ class cIptvProtocolUdp : public cIptvUdpSocket, public cIptvProtocolIf { private: char* streamAddr; - char* sourceAddr; int streamPort; public: diff --git a/socket.c b/socket.c index 8708d14..3477362 100644 --- a/socket.c +++ b/socket.c @@ -18,8 +18,8 @@ #include "socket.h" cIptvSocket::cIptvSocket() -: socketDesc(-1), - socketPort(0), +: socketPort(0), + socketDesc(-1), isActive(false) { debug("cIptvSocket::cIptvSocket()\n"); @@ -89,7 +89,7 @@ void cIptvSocket::CloseSocket(void) // UDP socket class cIptvUdpSocket::cIptvUdpSocket() -: sourceAddr(INADDR_ANY) +: streamAddr(INADDR_ANY) { debug("cIptvUdpSocket::cIptvUdpSocket()\n"); } @@ -99,28 +99,28 @@ cIptvUdpSocket::~cIptvUdpSocket() debug("cIptvUdpSocket::~cIptvUdpSocket()\n"); } -bool cIptvUdpSocket::OpenSocket(const int Port, const in_addr_t SourceAddr) +bool cIptvUdpSocket::OpenSocket(const int Port, const in_addr_t StreamAddr) { debug("cIptvUdpSocket::OpenSocket()\n"); - sourceAddr = SourceAddr; + streamAddr = StreamAddr; return cIptvSocket::OpenSocket(Port, true); } void cIptvUdpSocket::CloseSocket(void) { debug("cIptvUdpSocket::CloseSocket()\n"); - sourceAddr = INADDR_ANY; + streamAddr = INADDR_ANY; cIptvSocket::CloseSocket(); } -bool cIptvUdpSocket::JoinMulticast(const in_addr_t StreamAddr) +bool cIptvUdpSocket::JoinMulticast(void) { debug("cIptvUdpSocket::JoinMulticast()\n"); // Check if socket exists if (!isActive && (socketDesc >= 0)) { // Join a new multicast group struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = StreamAddr; + mreq.imr_multiaddr.s_addr = streamAddr; mreq.imr_interface.s_addr = htonl(INADDR_ANY); ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_ADD_MEMBERSHIP)", return false); // Update multicasting flag @@ -129,14 +129,14 @@ bool cIptvUdpSocket::JoinMulticast(const in_addr_t StreamAddr) return true; } -bool cIptvUdpSocket::DropMulticast(const in_addr_t StreamAddr) +bool cIptvUdpSocket::DropMulticast(void) { debug("cIptvUdpSocket::DropMulticast()\n"); // Check if socket exists if (isActive && (socketDesc >= 0)) { // Drop the existing multicast group struct ip_mreq mreq; - mreq.imr_multiaddr.s_addr = StreamAddr; + mreq.imr_multiaddr.s_addr = streamAddr; mreq.imr_interface.s_addr = htonl(INADDR_ANY); ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_DROP_MEMBERSHIP)", return false); // Update multicasting flag @@ -180,10 +180,10 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen) } else if (len > 0) { // Process auxiliary received data and validate source address - for (cmsg = CMSG_FIRSTHDR(&msgh); (sourceAddr != INADDR_ANY) && (cmsg != NULL); cmsg = CMSG_NXTHDR(&msgh, cmsg)) { + for (cmsg = CMSG_FIRSTHDR(&msgh); (streamAddr != INADDR_ANY) && (cmsg != NULL); cmsg = CMSG_NXTHDR(&msgh, cmsg)) { if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) { struct in_pktinfo *i = (struct in_pktinfo *)CMSG_DATA(cmsg); - if (i->ipi_addr.s_addr != sourceAddr) { + if (i->ipi_addr.s_addr != streamAddr) { //debug("Discard packet due to invalid source address: %s", inet_ntoa(i->ipi_addr)); return 0; } diff --git a/socket.h b/socket.h index 14bd75a..b912a27 100644 --- a/socket.h +++ b/socket.h @@ -11,9 +11,11 @@ #include class cIptvSocket { +private: + int socketPort; + protected: int socketDesc; - int socketPort; struct sockaddr_in sockAddr; bool isActive; @@ -28,16 +30,16 @@ public: class cIptvUdpSocket : public cIptvSocket { private: - in_addr_t sourceAddr; + in_addr_t streamAddr; public: cIptvUdpSocket(); virtual ~cIptvUdpSocket(); virtual int Read(unsigned char* BufferAddr, unsigned int BufferLen); - bool OpenSocket(const int Port, const in_addr_t SourceAddr = INADDR_ANY); + bool OpenSocket(const int Port, const in_addr_t StreamAddr = INADDR_ANY); void CloseSocket(void); - bool JoinMulticast(const in_addr_t StreamAddr); - bool DropMulticast(const in_addr_t StreamAddr); + bool JoinMulticast(void); + bool DropMulticast(void); }; class cIptvTcpSocket : public cIptvSocket {