Problem solved! max. 350 Socket Problem

Wiese, Hendrik hendrik.wiese at siemens.com
Thu Jun 8 10:56:21 UTC 2006


Hello there,
 
we found the cause of our max. 350 sockets problem with Fedora Core 4
(mentioned few weeks ago). I hope I'm able to explain it understanably
(I'm from Germany):
 
we ran into this problem while initializing an RTP transfer. RTP needs
two UDP sockes per call, one for RTP packages and the other one for
RTCP. RFC says the RTCP port has to be just one number above the RTP
port (or else it must be mentioned in the SIP session). So, in our
software we tried to find two valid ports using a while loop. This while
loop takes two sockets and tries to bind the RTP socket to a port
starting with 5000 and the RTCP to 'RTP port number + 1' (e.g. 5001). If
port 5000 is available (bind succeeds), the while loop tries to bind
port 5001 for RTCP. If this port is available too (bind succeeds again),
the while loop ends and the call will be established. If the RTP port is
not available, the probed ports (RTP and RTCP) are increased by 2 and
the while loop starts over again. 
 
Now the problem is, if the probed RTP port is available and the RTCP
port is _NOT_ (bind for RTP is successful, but not for RTCP), the ports
are also increased by 2 and the while loop starts over, trying to bind
the already successfully bound RTP port to the increased portnumber
(e.g. 5002) _AGAIN_. And this bind fails with errno == EINVAL. 
 
Now we took netstat which told us that there is a process called
mDNSresponder which uses port 5353 (odd portnumber, needed by our RTCP
layer). So the while loop binds RTP socket successfully to 5352 but
binding RTCP to 5353 fails because it is already in use. The while loop
starts over and tries to bind the successfully bound RTP socket to port
5354. This bind() fails as mentioned above.
 
As a workaround we disable all processes using odd portnumbers above
5000. But this isn't really applicable... The funny thing is, if an even
portnumber greater or equal 5000 is already in use, the RTP bind fails
and - because we use a logical OR || in the while condition - the RTCP
bind isn't even executed. Tiny cause, huge effect...
 
So the "root" of this problem is that an already bound socket can't be
"re"-bound to another port. 
 
Well... if there is anybody out here who knows how to "re"- or "un"-bind
an already bound socket... would be great to know if it is possible and
how it is done. Or if there is another way to check if a port is already
in use (other then just trying to bind).
 
Thanks a lot! 
 
regards,
Hendrik Wiese




More information about the fedora-devel-list mailing list