[Live-devel] RTSPServer may stop sending data when tunnelling over TCP

Kirill Zhegulev kzhegulev at icontrol.com
Thu Apr 30 18:35:12 PDT 2015


Hi.

Noted this when using RTSP relay.

Use case (probably can be simplified):
- RTSP relay based on RTSPServer with RTP over TCP.
- Open connection (#1) and let it run. At this point relay connects to the source stream and starts forwarding packets.
- Open another connection (#2) to the same stream and close it once start receiving data.
- Open third connection (#3) to the same stream. It will likely be through the same socket descriptor as connection (#2). This is important for the scenario.
- 60 seconds after connection #2 was closed, server will stop sending data to connection #3. It won’t close the socket, it will just stop sending data.

Explanation.
- When RTSPServer::RTSPClientSession is created livenessTimeoutTask() is scheduled and it gets rescheduled while connection is on.
- 60 seconds after connection is closed livenessTimeoutTask() is executed. It will delete clientSession, which will call reclaimStreamStates(), which deletes stream. Eventually RTPInterface::removeStreamSocket() gets called with file descriptor from connection #2
- At that time this file descriptor belongs to connection #3 and tcpStreamRecord for connection #3 is removed from the list.

I assume that it is not expected that RTSPClientSession outlives RTSPClientConnection and suggest destroying them at the same time.

Something like this:

--- a/liveMedia/RTSPServer.cpp
+++ b/liveMedia/RTSPServer.cpp
@@ -433,7 +433,8 @@ RTSPServer::RTSPClientConnection
 ::RTSPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr)
   : fOurServer(ourServer), fIsActive(True),
     fClientInputSocket(clientSocket), fClientOutputSocket(clientSocket), fClientAddr(clientAddr),
-    fRecursionCount(0), fOurSessionCookie(NULL) {
+    fRecursionCount(0), fOurSessionCookie(NULL),
+    fConnectionSessions(HashTable::create(STRING_HASH_KEYS)) {
   // Add ourself to our 'client connections' table:
   fOurServer.fClientConnections->Add((char const*)this, this);
   
@@ -452,8 +453,19 @@ RTSPServer::RTSPClientConnection::~RTSPClientConnection() {
     fOurServer.fClientConnectionsForHTTPTunneling->Remove(fOurSessionCookie);
     delete[] fOurSessionCookie;
   }
+
+  HashTable::Iterator* iter = HashTable::Iterator::create(*fConnectionSessions);
+  RTSPServer::RTSPClientSession* clientSession;
+  char const* key;
+  while ((clientSession = (RTSPServer::RTSPClientSession*)(iter->next(key))) != NULL) {
+    clientSession = (RTSPServer::RTSPClientSession*)(fOurServer.fClientSessions->Lookup(key));
+    if (clientSession == NULL) continue;
+    delete clientSession;
+  }
+  delete iter;
   
   closeSockets();
+  delete fConnectionSessions;
 }
 
 // Special mechanism for handling our custom "REGISTER" command:
@@ -1029,6 +1041,7 @@ void RTSPServer::RTSPClientConnection::handleRequestBytes(int newBytesRead) {
            } while (sessionId == 0 || fOurServer.fClientSessions->Lookup(sessionIdStr) != NULL);
            clientSession = fOurServer.createNewClientSession(sessionId);
            fOurServer.fClientSessions->Add(sessionIdStr, clientSession);
+            fConnectionSessions->Add(sessionIdStr, clientSession);
          } else {
            areAuthenticated = False;
          }
diff --git a/liveMedia/include/RTSPServer.hh b/liveMedia/include/RTSPServer.hh
index c998e29..4d77b89 100644
--- a/liveMedia/include/RTSPServer.hh
+++ b/liveMedia/include/RTSPServer.hh
@@ -264,6 +264,7 @@ public: // should be protected, but some old compilers complain otherwise
     Authenticator fCurrentAuthenticator; // used if access control is needed
     char* fOurSessionCookie; // used for optional RTSP-over-HTTP tunneling
     unsigned fBase64RemainderCount; // used for optional RTSP-over-HTTP tunneling (possible values: 0,1,2,3)
+    HashTable* fConnectionSessions; // maps 'session id' strings to "RTSPClientSession" objects
   };
 
   // The state of an individual client session (using one or more sequential TCP connections) handled by a RTSP server:




More information about the live-devel mailing list