[Live-devel] Groupsock handling in OnDemandServerMediaSubsession.cpp

David BERTRAND bidibulle at operamail.com
Wed Jun 14 08:50:39 PDT 2006


Hi Ross,

I'm facing a problem with groupsock creation in a class derived from OnDemandServerMediaSubsession. I know you normally don't give support on modified code but as I guess the issue also resides in the original code too, I will try to catch your interest anyway :-) 
Those problems mainly occur under heavy load when a RTSP server receives lots of unicast requests from clients. 

Basically, we are in the getStreamParameters method and fReuseFirstSource is false so for each new request we are supposed to create a new groupsock for the RTP destination and a new groupsock for the RTCP destination. The RTP port must have an even number and the RTCP port is supposed to be RTP port + 1. If the RTP port is not even a new trial is done and the old port number is for sure not used because kept for a while in rtpGroupsock_old

Extract from the code :
[...]    
while (1) {
      rtpGroupsock = new Groupsock(envir(), dummyAddr, 0, 255);
      if (!getSourcePort(envir(), rtpGroupsock->socketNum(), serverRTPPort)) break;
      serverRTPPortNum = ntohs(serverRTPPort.num());

      // If the port number's even, we're done:
      if ((serverRTPPortNum&1) == 0) break;
      // Try again (while keeping the old 'groupsock' around, so that we get
      // a different socket number next time):
      delete rtpGroupsock_old;
      rtpGroupsock_old = rtpGroupsock;
    }
    delete rtpGroupsock_old;
[...]

My problem was that if the RTP port is not even for two consecutive times, the first failed port number is not kept in rtpGroupsock_old anymore and will be used again. So, a new failed port and the previous one (also failed) available again --> loop of failed trials.

So I tried to optimize this algorithm. In case of failed port number, I call the Groupsock constructor with a "preferred" (even !) port number, which value is previous_trial_port + 1. But the problem is that liveMedia code was designed to support multicast, the socket options are such that you can bind twice on the same port number (SO_REUSEADDR and SO_REUSEPOR are True, see this in GroupSockHelper::setupDatagramSocket()). Therefore I can have my RTP ports shared for several sessions which is something I certainly don't want. 
I tried to modified the socket options in GroupSockHelper and I got what I wanted. So the question is, do you follow my analysis and agree with the issue ? If yes, how can we get a satisfying result ? If the solution is to modify the socket options this is currently not possible in runtime as the SO_REUSEPORT and SO_REUSEADDR are always true because the reuseFlag is hardcoded to value 1. What about giving this reuseFlag in Groupsock constructor ?

Thanks in advance for your feedback,
David

-- 
_______________________________________________
Surf the Web in a faster, safer and easier way:
Download Opera 8 at http://www.opera.com

Powered by Outblaze



More information about the live-devel mailing list