[Live-devel] RTSP server hang

Jeremy Noring jnoring at logitech.com
Mon Jun 14 08:23:17 PDT 2010


On Sun, Jun 13, 2010 at 7:16 PM, Ross Finlayson <finlayson at live555.com>wrote:

I.e., you should be able to remove the following code from the
> implementation of "readSocket()" in "groupsock/GroupsockHelper.cpp" (line
> 265):
>
>    int result = blockUntilReadable(env, socket, timeout);
>    if (timeout != NULL && result == 0) {
>      bytesRead = 0;
>      break;
>    } else if (result <= 0) {
>      break;
>    }
>
> and I think everything will work OK (only more efficiently!).
>
> So give this a try.  If you run into any problems, let us know.  (If not,
> I'll remove this code from the next release of the software.)


I had read about this on the mailing list, but I was wary to disable entire
functions.  So I ended up neutering one specific place that called
readSocket to have a null timeout;  I added a five second timeout:

Boolean Groupsock::handleRead(unsigned char* buffer, unsigned bufferMaxSize,
                  unsigned& bytesRead,
                  struct sockaddr_in& fromAddress) {
  // Read data from the socket, and relay it across any attached tunnels
  //##### later make this code more general - independent of tunnels

  bytesRead = 0;

  int maxBytesToRead = bufferMaxSize - TunnelEncapsulationTrailerMaxSize;
  timeval to;
  to.tv_sec = 5;
  to.tv_usec = 0;
  int numBytes = readSocket(env(), socketNum(),
                buffer, maxBytesToRead, fromAddress, &to);
  if (numBytes < 0) {
    if (DebugLevel >= 0) { // this is a fatal error
      env().setResultMsg("Groupsock read failed: ",
             env().getResultMsg());
    }
    return False;
  }

...and the server no longer hangs.  In general, given how the code works
with a dedicated worker thread, I think there should _never_ be anything
that can potentially block for any substantial amount of time (i.e. all
infinite timeout calls should be removed).

On a related note, here's one other hack I had to add to prevent crashing:

void RTSPServer::RTSPClientSession::handleAlternativeRequestByte1(u_int8_t
requestByte) {
  // Add this character to our buffer; then try to handle the data that we
have buffered so far:
  if (fRequestBufferBytesLeft == 0) return;
  if (fRequestBytesAlreadySeen >= RTSP_BUFFER_SIZE ) return;    // hack:
don't let us overflow fRequestBuffer, and there's some bug
                                                                // with
sessions containing multiple subsessions, when streaming over
                                                                // TCP that
causes this to fail miserably.
  fRequestBuffer[fRequestBytesAlreadySeen] = requestByte;
  handleRequestBytes(1);
}

...I previously reported this.  When there are multiple sessions being
streamed that contain both audio and video (i.e. multiple subsessions) over
TCP, sometimes the server will crash with an access violation by walking off
the end of fRequestBuffer.  I do not understand the crash; I do know that
this code prevents it.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.live555.com/pipermail/live-devel/attachments/20100614/be63e608/attachment.html>


More information about the live-devel mailing list