Make it possible to specify the rtp and rtcp ports

this makes it possible to use the satip through a
NAT (e.g. a docker bridged network)
This commit is contained in:
chriszero 2016-01-07 20:56:39 +01:00
parent 6e9b43b0d8
commit 6e9b5fc414
7 changed files with 59 additions and 7 deletions

5
README
View File

@ -56,6 +56,11 @@ vdr -P 'satip -s <ipaddress>|<model>|<description>;...'
vdr -P 'satip -s 192.168.0.1|DVBS2-2,DVBT2-2|Octo1'
vdr -P 'satip -s 192.168.0.1|DVBS2-4|Octo1;192.168.0.2|DVBT2-4|Octo2'
The plugin accepts a "--portrange" (-p) command-line parameter, that can
be used to manually specify the RTP & RTCP port range and therefore
enables using the plugin through a NAT (e.g. Docker bridged network).
A minimum of 2 ports per device is required.
SAT>IP satellite positions (aka. signal sources) shall be defined via
sources.conf. If the source description begins with a number, it's used
as SAT>IP signal source selection parameter. A special number zero can

View File

@ -17,6 +17,8 @@ cSatipConfig::cSatipConfig(void)
ciExtensionM(0),
eitScanM(1),
useBytesM(1),
portRangeStartM(0),
portRangeStopM(0),
detachedModeM(false),
disableServerQuirksM(false),
useSingleModelServersM(false)

View File

@ -19,6 +19,8 @@ private:
unsigned int ciExtensionM;
unsigned int eitScanM;
unsigned int useBytesM;
unsigned int portRangeStartM;
unsigned int portRangeStopM;
bool detachedModeM;
bool disableServerQuirksM;
bool useSingleModelServersM;
@ -74,6 +76,8 @@ public:
int GetDisabledSources(unsigned int indexP) const;
unsigned int GetDisabledFiltersCount(void) const;
int GetDisabledFilters(unsigned int indexP) const;
unsigned int GetPortRangeStart(void) const { return portRangeStartM; }
unsigned int GetPortRangeStop(void) const { return portRangeStopM; }
void SetOperatingMode(unsigned int operatingModeP) { operatingModeM = operatingModeP; }
void SetTraceMode(unsigned int modeP) { traceModeM = (modeP & eTraceModeMask); }
@ -86,6 +90,8 @@ public:
void SetUseSingleModelServers(bool onOffP) { useSingleModelServersM = onOffP; }
void SetDisabledSources(unsigned int indexP, int sourceP);
void SetDisabledFilters(unsigned int indexP, int numberP);
void SetPortRangeStart(unsigned int rangeStartP) { portRangeStartM = rangeStartP; }
void SetPortRangeStop(unsigned int rangeStopP) { portRangeStopM = rangeStopP; }
};
extern cSatipConfig SatipConfig;

40
satip.c
View File

@ -35,6 +35,7 @@ private:
unsigned int deviceCountM;
cSatipDiscoverServers *serversM;
void ParseServer(const char *paramP);
void ParsePortRange(const char *paramP);
int ParseCicams(const char *valueP, int *cicamsP);
int ParseSources(const char *valueP, int *sourcesP);
int ParseFilters(const char *valueP, int *filtersP);
@ -87,7 +88,9 @@ const char *cPluginSatip::CommandLineHelp(void)
" define hard-coded SAT>IP server(s)\n"
" -D, --detach set the detached mode on\n"
" -S, --single set the single model server mode on\n"
" -n, --noquirks disable all the server quirks\n";
" -n, --noquirks disable all the server quirks\n"
" -p, --portrange=<start>-<end> set a range of ports used for the RT[C]P server\n"
" a minimum of 2 ports per device is required.\n";
}
bool cPluginSatip::ProcessArgs(int argc, char *argv[])
@ -98,6 +101,7 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
{ "devices", required_argument, NULL, 'd' },
{ "trace", required_argument, NULL, 't' },
{ "server", required_argument, NULL, 's' },
{ "portrange",required_argument, NULL, 'p' },
{ "detach", no_argument, NULL, 'D' },
{ "single", no_argument, NULL, 'S' },
{ "noquirks", no_argument, NULL, 'n' },
@ -105,8 +109,9 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
};
cString server;
cString portrange;
int c;
while ((c = getopt_long(argc, argv, "d:t:s:DSn", long_options, NULL)) != -1) {
while ((c = getopt_long(argc, argv, "d:t:s:p:DSn", long_options, NULL)) != -1) {
switch (c) {
case 'd':
deviceCountM = strtol(optarg, NULL, 0);
@ -126,10 +131,15 @@ bool cPluginSatip::ProcessArgs(int argc, char *argv[])
case 'n':
SatipConfig.SetDisableServerQuirks(true);
break;
case 'p':
portrange = optarg;
break;
default:
return false;
}
}
if (!isempty(*portrange))
ParsePortRange(portrange);
// this must be done after all parameters are parsed
if (!isempty(*server))
ParseServer(*server);
@ -255,6 +265,32 @@ void cPluginSatip::ParseServer(const char *paramP)
FREE_POINTER(p);
}
void cPluginSatip::ParsePortRange(const char *paramP)
{
char *s, *p = skipspace(paramP);
char *r = strtok_r(p, "-", &s);
unsigned int rangeStart = 0;
unsigned int rangeStop = 0;
if (r) {
rangeStart = strtol(r, NULL, 0);
r = strtok_r(NULL, "-", &s);
}
if (r)
rangeStop = strtol(r, NULL, 0);
else {
error("Port range argument not valid '%s'", paramP);
rangeStart = 0;
rangeStop = 0;
}
if (rangeStop - rangeStart + 1 < deviceCountM * 2) {
error("The given port range is to small: %d < %d!", rangeStop - rangeStart + 1, deviceCountM * 2);
rangeStart = 0;
rangeStop = 0;
}
SatipConfig.SetPortRangeStart(rangeStart);
SatipConfig.SetPortRangeStop(rangeStop);
}
int cPluginSatip::ParseCicams(const char *valueP, int *cicamsP)
{
debug1("%s (%s,)", __PRETTY_FUNCTION__, valueP);

View File

@ -34,7 +34,7 @@ cSatipSocket::~cSatipSocket()
Close();
}
bool cSatipSocket::Open(const int portP)
bool cSatipSocket::Open(const int portP, const bool reuseAddrP)
{
// Bind to the socket if it is not active already
if (socketDescM < 0) {
@ -46,7 +46,7 @@ bool cSatipSocket::Open(const int portP)
ERROR_IF_FUNC(fcntl(socketDescM, F_SETFL, O_NONBLOCK), "fcntl(O_NONBLOCK)",
Close(), return false);
// Allow multiple sockets to use the same PORT number
int yes = 1;
int yes = reuseAddrP;
ERROR_IF_FUNC(setsockopt(socketDescM, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0,
"setsockopt(SO_REUSEADDR)", Close(), return false);
// Bind socket

View File

@ -19,7 +19,7 @@ private:
public:
cSatipSocket();
virtual ~cSatipSocket();
bool Open(const int portP = 0);
bool Open(const int portP = 0, const bool reuseAddrP = false);
virtual void Close(void);
int Fd(void) { return socketDescM; }
int Port(void) { return socketPortM; }

View File

@ -50,12 +50,15 @@ cSatipTuner::cSatipTuner(cSatipDeviceIf &deviceP, unsigned int packetLenP)
debug1("%s (, %d) [device %d]", __PRETTY_FUNCTION__, packetLenP, deviceIdM);
// Open sockets
int i = 100;
int i = SatipConfig.GetPortRangeStart() ? SatipConfig.GetPortRangeStop() - SatipConfig.GetPortRangeStart() - 1 : 100;
int port = SatipConfig.GetPortRangeStart();
while (i-- > 0) {
if (rtpM.Open(0) && rtcpM.Open(rtpM.Port() + 1))
if (rtpM.Open(port) && rtcpM.Open(rtpM.Port() + 1))
break;
rtpM.Close();
rtcpM.Close();
if (SatipConfig.GetPortRangeStart())
++port;
}
if ((rtpM.Port() <= 0) || (rtcpM.Port() <= 0)) {
error("Cannot open required RTP/RTCP ports [device %d]", deviceIdM);