[Live-devel] client port validation
Eric Pronovost
epronovost at videowave.ca
Tue Feb 24 07:05:50 PST 2015
An RTSP client application that connects to my RTSP server is launched in
multi instances. However, it always start with client_port 9000.
SETUP rtsp://192.168.0.60:9395/live005/sub.sdp/track1 RTSP/1.0
CSeq: 2
Transport: RTP/AVP;unicast;client_port=9000-9001
etc...
When the first instance is launched, it works with port 9000. The second
instance is then launched and tries port 9000 again. It doesn't work, so a
TEARDOWN is performed. The problem is that the teardown of the second
instance is stopping the video of the first instance.
By debugging, I discovered that, inside StreamState::endPlaying(), the
following call:
if (fRTPgs != NULL) fRTPgs->removeDestination(dests->addr, dests->rtpPort);
if (fRTCPgs != NULL) fRTCPgs->removeDestination(dests->addr,
dests->rtcpPort);
will stop the video from the first instance, since the ports are the same.
I coded the following workaround:
In ::handleCmd_SETUP(), before the call
to subsession->getStreamParameters(), I added a custom function that checks
if the address/ports are already in use:
bool bAlreadyInUse =
subsession->destinationsAlreadyInUse(ourClientConnection->fClientAddr.sin_addr.s_addr,
clientRTPPort, clientRTCPPort, tcpSocketNum, rtpChannelId, rtcpChannelId,
destinationAddress);
if (bAlreadyInUse)
break;
Here's the code to my custom function:
bool OnDemandServerMediaSubsession::destinationsAlreadyInUse(netAddressBits
clientAddress, Port const& clientRTPPort,
Port const& clientRTCPPort,
int tcpSocketNum,
unsigned char rtpChannelId,
unsigned char rtcpChannelId,
netAddressBits& destinationAddress)
{
if (tcpSocketNum >= 0) // TCP
return false;
if (destinationAddress == 0) destinationAddress = clientAddress;
struct in_addr destinationAddr; destinationAddr.s_addr =
destinationAddress;
Destinations* destinations;
if (tcpSocketNum < 0) { // UDP
destinations = new Destinations(destinationAddr, clientRTPPort,
clientRTCPPort);
}
else { // TCP
destinations = new Destinations(tcpSocketNum, rtpChannelId,
rtcpChannelId);
}
HashTable::Iterator* iter =
HashTable::Iterator::create(*fDestinationsHashTable);
Destinations* dests;
char const* key; // dummy
bool bAlreadyExist = false;
while ((dests = (Destinations*)(iter->next(key))) != NULL)
{
if (dests->addr.S_un.S_addr == destinations->addr.S_un.S_addr)
{
if ((dests->rtcpPort.num() == destinations->rtcpPort.num()) ||
(dests->rtpPort.num() == destinations->rtpPort.num()))
bAlreadyExist = true;
}
}
delete iter;
return bAlreadyExist;
}
With this workaround, the second instance won't stop the video of the first
instance, and it will receive RTSP/1.0 454 Session Not Found.
I consider this as a patch, not sure what the best solution should be...
any suggestions?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20150224/f6f2fc64/attachment.html>
More information about the live-devel
mailing list