Changed UDP protocol to always utilize the source address validation.

This commit is contained in:
Rolf Ahrenberg 2012-04-02 00:35:32 +03:00
parent 9145fb8bb8
commit c475b26515
6 changed files with 31 additions and 41 deletions

View File

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

3
README
View File

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

View File

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

View File

@ -15,7 +15,6 @@
class cIptvProtocolUdp : public cIptvUdpSocket, public cIptvProtocolIf {
private:
char* streamAddr;
char* sourceAddr;
int streamPort;
public:

View File

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

View File

@ -11,9 +11,11 @@
#include <arpa/inet.h>
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 {