mirror of
https://github.com/rofafor/vdr-plugin-iptv.git
synced 2023-10-10 13:37:03 +02:00
Changed UDP protocol to always utilize the source address validation.
This commit is contained in:
parent
9145fb8bb8
commit
c475b26515
2
HISTORY
2
HISTORY
@ -164,3 +164,5 @@ VDR Plugin 'iptv' Revision History
|
|||||||
- Updated for vdr-1.7.27.
|
- Updated for vdr-1.7.27.
|
||||||
- Fixed some channel switching bugs.
|
- Fixed some channel switching bugs.
|
||||||
- Added support for a service interface.
|
- Added support for a service interface.
|
||||||
|
- Changed UDP protocol to always utilize the source address
|
||||||
|
validation.
|
||||||
|
3
README
3
README
@ -161,9 +161,6 @@ Notes:
|
|||||||
- EIT scanning functionality can be disabled for all IPTV channels by applying
|
- EIT scanning functionality can be disabled for all IPTV channels by applying
|
||||||
the "disable_eitscan" patch to the VDR.
|
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
|
- Section id and pid scanners should be disabled after the correct data is
|
||||||
found. This can be made via VDR's channel editor.
|
found. This can be made via VDR's channel editor.
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
cIptvProtocolUdp::cIptvProtocolUdp()
|
cIptvProtocolUdp::cIptvProtocolUdp()
|
||||||
: streamAddr(strdup("")),
|
: streamAddr(strdup("")),
|
||||||
sourceAddr(strdup("")),
|
|
||||||
streamPort(0)
|
streamPort(0)
|
||||||
{
|
{
|
||||||
debug("cIptvProtocolUdp::cIptvProtocolUdp()\n");
|
debug("cIptvProtocolUdp::cIptvProtocolUdp()\n");
|
||||||
@ -33,33 +32,31 @@ cIptvProtocolUdp::~cIptvProtocolUdp()
|
|||||||
cIptvProtocolUdp::Close();
|
cIptvProtocolUdp::Close();
|
||||||
// Free allocated memory
|
// Free allocated memory
|
||||||
free(streamAddr);
|
free(streamAddr);
|
||||||
free(sourceAddr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cIptvProtocolUdp::Open(void)
|
bool cIptvProtocolUdp::Open(void)
|
||||||
{
|
{
|
||||||
debug("cIptvProtocolUdp::Open(): sourceAddr=%s streamAddr=%s\n", sourceAddr, streamAddr);
|
debug("cIptvProtocolUdp::Open(): streamAddr=%s\n", streamAddr);
|
||||||
OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
|
OpenSocket(streamPort, inet_addr(streamAddr));
|
||||||
if (!isempty(streamAddr)) {
|
if (!isempty(streamAddr)) {
|
||||||
// Join a new multicast group
|
// Join a new multicast group
|
||||||
JoinMulticast(inet_addr(streamAddr));
|
JoinMulticast();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cIptvProtocolUdp::Close(void)
|
bool cIptvProtocolUdp::Close(void)
|
||||||
{
|
{
|
||||||
debug("cIptvProtocolUdp::Close(): sourceAddr=%s streamAddr=%s\n", sourceAddr, streamAddr);
|
debug("cIptvProtocolUdp::Close(): streamAddr=%s\n", streamAddr);
|
||||||
if (!isempty(streamAddr)) {
|
if (!isempty(streamAddr)) {
|
||||||
// Drop the multicast group
|
// Drop the multicast group
|
||||||
OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
|
OpenSocket(streamPort, inet_addr(streamAddr));
|
||||||
DropMulticast(inet_addr(streamAddr));
|
DropMulticast();
|
||||||
}
|
}
|
||||||
// Close the socket
|
// Close the socket
|
||||||
CloseSocket();
|
CloseSocket();
|
||||||
// Do NOT reset stream and source addresses
|
// Do NOT reset stream and source addresses
|
||||||
//streamAddr = strcpyrealloc(streamAddr, "");
|
//streamAddr = strcpyrealloc(streamAddr, "");
|
||||||
//sourceAddr = strcpyrealloc(sourceAddr, "");
|
|
||||||
//streamPort = 0;
|
//streamPort = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -75,23 +72,16 @@ bool cIptvProtocolUdp::Set(const char* Location, const int Parameter, const int
|
|||||||
if (!isempty(Location)) {
|
if (!isempty(Location)) {
|
||||||
// Drop the multicast group
|
// Drop the multicast group
|
||||||
if (!isempty(streamAddr)) {
|
if (!isempty(streamAddr)) {
|
||||||
OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
|
OpenSocket(streamPort, inet_addr(streamAddr));
|
||||||
DropMulticast(inet_addr(streamAddr));
|
DropMulticast();
|
||||||
}
|
}
|
||||||
// Update stream address and port
|
// Update stream address and port
|
||||||
streamAddr = strcpyrealloc(streamAddr, Location);
|
streamAddr = strcpyrealloc(streamAddr, Location);
|
||||||
char *p = strstr(streamAddr, ";");
|
|
||||||
if (p) {
|
|
||||||
sourceAddr = strcpyrealloc(sourceAddr, p + 1);
|
|
||||||
*p = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sourceAddr = strcpyrealloc(sourceAddr, "");
|
|
||||||
streamPort = Parameter;
|
streamPort = Parameter;
|
||||||
// Join a new multicast group
|
// Join a new multicast group
|
||||||
if (!isempty(streamAddr)) {
|
if (!isempty(streamAddr)) {
|
||||||
OpenSocket(streamPort, isempty(sourceAddr) ? INADDR_ANY : inet_addr(sourceAddr));
|
OpenSocket(streamPort, inet_addr(streamAddr));
|
||||||
JoinMulticast(inet_addr(streamAddr));
|
JoinMulticast();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
class cIptvProtocolUdp : public cIptvUdpSocket, public cIptvProtocolIf {
|
class cIptvProtocolUdp : public cIptvUdpSocket, public cIptvProtocolIf {
|
||||||
private:
|
private:
|
||||||
char* streamAddr;
|
char* streamAddr;
|
||||||
char* sourceAddr;
|
|
||||||
int streamPort;
|
int streamPort;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
24
socket.c
24
socket.c
@ -18,8 +18,8 @@
|
|||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
|
||||||
cIptvSocket::cIptvSocket()
|
cIptvSocket::cIptvSocket()
|
||||||
: socketDesc(-1),
|
: socketPort(0),
|
||||||
socketPort(0),
|
socketDesc(-1),
|
||||||
isActive(false)
|
isActive(false)
|
||||||
{
|
{
|
||||||
debug("cIptvSocket::cIptvSocket()\n");
|
debug("cIptvSocket::cIptvSocket()\n");
|
||||||
@ -89,7 +89,7 @@ void cIptvSocket::CloseSocket(void)
|
|||||||
|
|
||||||
// UDP socket class
|
// UDP socket class
|
||||||
cIptvUdpSocket::cIptvUdpSocket()
|
cIptvUdpSocket::cIptvUdpSocket()
|
||||||
: sourceAddr(INADDR_ANY)
|
: streamAddr(INADDR_ANY)
|
||||||
{
|
{
|
||||||
debug("cIptvUdpSocket::cIptvUdpSocket()\n");
|
debug("cIptvUdpSocket::cIptvUdpSocket()\n");
|
||||||
}
|
}
|
||||||
@ -99,28 +99,28 @@ cIptvUdpSocket::~cIptvUdpSocket()
|
|||||||
debug("cIptvUdpSocket::~cIptvUdpSocket()\n");
|
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");
|
debug("cIptvUdpSocket::OpenSocket()\n");
|
||||||
sourceAddr = SourceAddr;
|
streamAddr = StreamAddr;
|
||||||
return cIptvSocket::OpenSocket(Port, true);
|
return cIptvSocket::OpenSocket(Port, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cIptvUdpSocket::CloseSocket(void)
|
void cIptvUdpSocket::CloseSocket(void)
|
||||||
{
|
{
|
||||||
debug("cIptvUdpSocket::CloseSocket()\n");
|
debug("cIptvUdpSocket::CloseSocket()\n");
|
||||||
sourceAddr = INADDR_ANY;
|
streamAddr = INADDR_ANY;
|
||||||
cIptvSocket::CloseSocket();
|
cIptvSocket::CloseSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cIptvUdpSocket::JoinMulticast(const in_addr_t StreamAddr)
|
bool cIptvUdpSocket::JoinMulticast(void)
|
||||||
{
|
{
|
||||||
debug("cIptvUdpSocket::JoinMulticast()\n");
|
debug("cIptvUdpSocket::JoinMulticast()\n");
|
||||||
// Check if socket exists
|
// Check if socket exists
|
||||||
if (!isActive && (socketDesc >= 0)) {
|
if (!isActive && (socketDesc >= 0)) {
|
||||||
// Join a new multicast group
|
// Join a new multicast group
|
||||||
struct ip_mreq mreq;
|
struct ip_mreq mreq;
|
||||||
mreq.imr_multiaddr.s_addr = StreamAddr;
|
mreq.imr_multiaddr.s_addr = streamAddr;
|
||||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
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);
|
ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_ADD_MEMBERSHIP)", return false);
|
||||||
// Update multicasting flag
|
// Update multicasting flag
|
||||||
@ -129,14 +129,14 @@ bool cIptvUdpSocket::JoinMulticast(const in_addr_t StreamAddr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cIptvUdpSocket::DropMulticast(const in_addr_t StreamAddr)
|
bool cIptvUdpSocket::DropMulticast(void)
|
||||||
{
|
{
|
||||||
debug("cIptvUdpSocket::DropMulticast()\n");
|
debug("cIptvUdpSocket::DropMulticast()\n");
|
||||||
// Check if socket exists
|
// Check if socket exists
|
||||||
if (isActive && (socketDesc >= 0)) {
|
if (isActive && (socketDesc >= 0)) {
|
||||||
// Drop the existing multicast group
|
// Drop the existing multicast group
|
||||||
struct ip_mreq mreq;
|
struct ip_mreq mreq;
|
||||||
mreq.imr_multiaddr.s_addr = StreamAddr;
|
mreq.imr_multiaddr.s_addr = streamAddr;
|
||||||
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
|
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);
|
ERROR_IF_RET(setsockopt(socketDesc, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0, "setsockopt(IP_DROP_MEMBERSHIP)", return false);
|
||||||
// Update multicasting flag
|
// Update multicasting flag
|
||||||
@ -180,10 +180,10 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
|
|||||||
}
|
}
|
||||||
else if (len > 0) {
|
else if (len > 0) {
|
||||||
// Process auxiliary received data and validate source address
|
// 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)) {
|
if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
|
||||||
struct in_pktinfo *i = (struct in_pktinfo *)CMSG_DATA(cmsg);
|
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));
|
//debug("Discard packet due to invalid source address: %s", inet_ntoa(i->ipi_addr));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
12
socket.h
12
socket.h
@ -11,9 +11,11 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
class cIptvSocket {
|
class cIptvSocket {
|
||||||
|
private:
|
||||||
|
int socketPort;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int socketDesc;
|
int socketDesc;
|
||||||
int socketPort;
|
|
||||||
struct sockaddr_in sockAddr;
|
struct sockaddr_in sockAddr;
|
||||||
bool isActive;
|
bool isActive;
|
||||||
|
|
||||||
@ -28,16 +30,16 @@ public:
|
|||||||
|
|
||||||
class cIptvUdpSocket : public cIptvSocket {
|
class cIptvUdpSocket : public cIptvSocket {
|
||||||
private:
|
private:
|
||||||
in_addr_t sourceAddr;
|
in_addr_t streamAddr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
cIptvUdpSocket();
|
cIptvUdpSocket();
|
||||||
virtual ~cIptvUdpSocket();
|
virtual ~cIptvUdpSocket();
|
||||||
virtual int Read(unsigned char* BufferAddr, unsigned int BufferLen);
|
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);
|
void CloseSocket(void);
|
||||||
bool JoinMulticast(const in_addr_t StreamAddr);
|
bool JoinMulticast(void);
|
||||||
bool DropMulticast(const in_addr_t StreamAddr);
|
bool DropMulticast(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cIptvTcpSocket : public cIptvSocket {
|
class cIptvTcpSocket : public cIptvSocket {
|
||||||
|
Loading…
Reference in New Issue
Block a user