Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package live555 for openSUSE:Factory checked in at 2026-06-03 20:21:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/live555 (Old) and /work/SRC/openSUSE:Factory/.live555.new.1937 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "live555" Wed Jun 3 20:21:22 2026 rev:46 rq:1356652 version:2026.06.01 Changes: -------- --- /work/SRC/openSUSE:Factory/live555/live555.changes 2026-06-01 17:58:59.885861705 +0200 +++ /work/SRC/openSUSE:Factory/.live555.new.1937/live555.changes 2026-06-03 20:22:18.072886614 +0200 @@ -1,0 +2,29 @@ +Tue Jun 2 07:30:31 UTC 2026 - Dominique Leuenberger <[email protected]> + +- Update to version 2026.06.01: + + Updated the "RTSPServer" implementation of the "SETUP" command + to make it more robust if subclassed code reimplements + "lookupServerMediaSession()" as an asynchronous operation. + +------------------------------------------------------------------- +Mon Jun 1 07:46:54 UTC 2026 - Dirk Müller <[email protected]> + +- update to 2026.05.30: + * Updated the "RTSPServer" implementation some more to make it + more robust if subclassed code reimplements + "lookpServerMediaSession()" as an asynchronous operation. + * Added an (integer) index to identify each server's + 'client connection', and changed the "fClientConnections" table + to be indexed by this id. + * In the "RTSPServer" implementation, removed the + "fOurClientConnection" member variable. + This had been left over from when the RTSP "SETUP" command had + been implemented as a single, synchronous function. + Now that "SETUP" is implemented using multiple functions, + possibly asynchronously (depending upon how + "lookpServerMediaSession()" is implemented), this member + variable was potentially dangerous if more than one "SETUP" is + performed concurrently on the same client connection, or on + separate client connections. + +------------------------------------------------------------------- Old: ---- live.2026.05.28.tar.gz New: ---- live.2026.06.01.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ live555.spec ++++++ --- /var/tmp/diff_new_pack.HZJXoZ/_old 2026-06-03 20:22:19.108929593 +0200 +++ /var/tmp/diff_new_pack.HZJXoZ/_new 2026-06-03 20:22:19.108929593 +0200 @@ -17,10 +17,10 @@ # -%define lmdmaj 118 +%define lmdmaj 119 Name: live555 -Version: 2026.05.28 +Version: 2026.06.01 Release: 0 Summary: LIVE555 Streaming Media License: LGPL-2.1-only ++++++ live.2026.05.28.tar.gz -> live.2026.06.01.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh new/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh --- old/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh 2026-05-28 14:43:06.000000000 +0200 +++ new/live/BasicUsageEnvironment/include/BasicUsageEnvironment_version.hh 2026-06-01 11:12:14.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _BASICUSAGEENVIRONMENT_VERSION_HH #define _BASICUSAGEENVIRONMENT_VERSION_HH -#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.05.28" -#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT 1779926400 +#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.06.01" +#define BASICUSAGEENVIRONMENT_LIBRARY_VERSION_INT 1780272000 extern char const* const BasicUsageEnvironmentLibraryVersionStr; extern int const BasicUsageEnvironmentLibraryVersionInt; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/UsageEnvironment/include/UsageEnvironment_version.hh new/live/UsageEnvironment/include/UsageEnvironment_version.hh --- old/live/UsageEnvironment/include/UsageEnvironment_version.hh 2026-05-28 14:43:06.000000000 +0200 +++ new/live/UsageEnvironment/include/UsageEnvironment_version.hh 2026-06-01 11:12:14.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _USAGEENVIRONMENT_VERSION_HH #define _USAGEENVIRONMENT_VERSION_HH -#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.05.28" -#define USAGEENVIRONMENT_LIBRARY_VERSION_INT 1779926400 +#define USAGEENVIRONMENT_LIBRARY_VERSION_STRING "2026.06.01" +#define USAGEENVIRONMENT_LIBRARY_VERSION_INT 1780272000 extern char const* const UsageEnvironmentLibraryVersionStr; extern int const UsageEnvironmentLibraryVersionInt; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/config.linux-with-shared-libraries new/live/config.linux-with-shared-libraries --- old/live/config.linux-with-shared-libraries 2026-05-28 14:43:18.000000000 +0200 +++ new/live/config.linux-with-shared-libraries 2026-06-01 11:12:24.000000000 +0200 @@ -3,8 +3,8 @@ # At least one interface changes, or is removed => CURRENT += 1; REVISION = 0; AGE = 0 # One or more interfaces were added, but no existing interfaces were changed or removed => CURRENT += 1; REVISION = 0; AGE += 1 -libliveMedia_VERSION_CURRENT=118 -libliveMedia_VERSION_REVISION=1 +libliveMedia_VERSION_CURRENT=119 +libliveMedia_VERSION_REVISION=2 libliveMedia_VERSION_AGE=0 libliveMedia_LIB_SUFFIX=so.$(shell expr $(libliveMedia_VERSION_CURRENT) - $(libliveMedia_VERSION_AGE)).$(libliveMedia_VERSION_AGE).$(libliveMedia_VERSION_REVISION) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/groupsock/include/groupsock_version.hh new/live/groupsock/include/groupsock_version.hh --- old/live/groupsock/include/groupsock_version.hh 2026-05-28 14:43:06.000000000 +0200 +++ new/live/groupsock/include/groupsock_version.hh 2026-06-01 11:12:14.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _GROUPSOCK_VERSION_HH #define _GROUPSOCK_VERSION_HH -#define GROUPSOCK_LIBRARY_VERSION_STRING "2026.05.28" -#define GROUPSOCK_LIBRARY_VERSION_INT 1779926400 +#define GROUPSOCK_LIBRARY_VERSION_STRING "2026.06.01" +#define GROUPSOCK_LIBRARY_VERSION_INT 1780272000 extern char const* const groupsockLibraryVersionStr; extern int const groupsockLibraryVersionInt; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/GenericMediaServer.cpp new/live/liveMedia/GenericMediaServer.cpp --- old/live/liveMedia/GenericMediaServer.cpp 2026-05-28 14:43:06.000000000 +0200 +++ new/live/liveMedia/GenericMediaServer.cpp 2026-06-01 11:12:14.000000000 +0200 @@ -54,9 +54,9 @@ void (GenericMediaServer::*fMemberFunc)(ServerMediaSession*); }; -static void lsmsMemberFunctionCompletionFunc(void* clientData, ServerMediaSession* sessionLookedUp) { +static void lsmsMemberFunctionCompletionFunc(void* clientData, ServerMediaSession* smsLookedUp) { lsmsMemberFunctionRecord* memberFunctionRecord = (lsmsMemberFunctionRecord*)clientData; - (memberFunctionRecord->fServer->*(memberFunctionRecord->fMemberFunc))(sessionLookedUp); + (memberFunctionRecord->fServer->*(memberFunctionRecord->fMemberFunc))(smsLookedUp); delete memberFunctionRecord; } @@ -259,6 +259,8 @@ ////////// GenericMediaServer::ClientConnection implementation ////////// +static u_int32_t lastClientConnectionId = 0; // identifies each connection (can wrap around) + GenericMediaServer::ClientConnection ::ClientConnection(GenericMediaServer& ourServer, int clientSocket, struct sockaddr_storage const& clientAddr, @@ -267,7 +269,10 @@ fInputTLS = fOutputTLS = &fTLS; // Add ourself to our 'client connections' table: - fOurServer.fClientConnections->Add((char const*)this, this); + do { + fConnectionId = ++lastClientConnectionId; + } while (fOurServer.fClientConnections->Lookup((char const*)fConnectionId) != NULL); + fOurServer.fClientConnections->Add((char const*)fConnectionId, this); if (useTLS) { // Perform extra processing to handle a TLS connection: @@ -286,7 +291,7 @@ GenericMediaServer::ClientConnection::~ClientConnection() { // Remove ourself from the server's 'client connections' hash table before we go: - fOurServer.fClientConnections->Remove((char const*)this); + fOurServer.fClientConnections->Remove((char const*)fConnectionId); closeSockets(); } @@ -333,6 +338,11 @@ fRequestBufferBytesLeft = sizeof fRequestBuffer; } +GenericMediaServer::ClientConnection* GenericMediaServer +::lookupClientConnection(u_int32_t connectionId) const { + return (class ClientConnection*)(fClientConnections->Lookup((char const*)connectionId)); +} + ////////// GenericMediaServer::ClientSession implementation ////////// diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/RTSPServer.cpp new/live/liveMedia/RTSPServer.cpp --- old/live/liveMedia/RTSPServer.cpp 2026-05-28 14:43:06.000000000 +0200 +++ new/live/liveMedia/RTSPServer.cpp 2026-06-01 11:12:14.000000000 +0200 @@ -376,6 +376,23 @@ setRTSPResponse("200 OK"); } +// A class used to implement "DESCRIBE" (possibly asynchronously). It consists of +// a "RTSPServer" (reference), and an id for a "RTSPClientConnection". + +class ServerConnectionPair { +public: + ServerConnectionPair(RTSPServer& server, u_int32_t connectionId) + : fServer(server), fConnectionId(connectionId) {} + ~ServerConnectionPair() {} + + RTSPServer& server() const { return fServer; } + u_int32_t connectionId() const { return fConnectionId; } + +private: + RTSPServer& fServer; + u_int32_t fConnectionId; +}; + void RTSPServer::RTSPClientConnection ::handleCmd_DESCRIBE(char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr) { char urlTotalSuffix[2*RTSP_PARAM_STRING_MAX]; @@ -393,13 +410,22 @@ // for "application/sdp", because that's what we're sending back ##### // Begin by looking up the "ServerMediaSession" object for the specified "urlTotalSuffix": - fOurServer.lookupServerMediaSession(urlTotalSuffix, DESCRIBELookupCompletionFunction, this); + ServerConnectionPair* scPair = new ServerConnectionPair(fOurRTSPServer, id()); + fOurServer.lookupServerMediaSession(urlTotalSuffix, DESCRIBELookupCompletionFunction, scPair); } void RTSPServer::RTSPClientConnection -::DESCRIBELookupCompletionFunction(void* clientData, ServerMediaSession* sessionLookedUp) { - RTSPServer::RTSPClientConnection* connection = (RTSPServer::RTSPClientConnection*)clientData; - connection->handleCmd_DESCRIBE_afterLookup(sessionLookedUp); +::DESCRIBELookupCompletionFunction(void* clientData, ServerMediaSession* smsLookedUp) { + ServerConnectionPair* scPair = (ServerConnectionPair*)clientData; + RTSPServer& server = scPair->server(); + u_int32_t connectionId = scPair->connectionId(); + RTSPClientConnection* ourClientConnection + = (RTSPClientConnection*)(server.lookupClientConnection(connectionId)); + + if (ourClientConnection != NULL) { + ourClientConnection->handleCmd_DESCRIBE_afterLookup(smsLookedUp); + } + delete scPair; } void RTSPServer::RTSPClientConnection @@ -1247,11 +1273,13 @@ ::RTSPClientSession(RTSPServer& ourServer, u_int32_t sessionId) : GenericMediaServer::ClientSession(ourServer, sessionId), fOurRTSPServer(ourServer), fIsMulticast(False), fStreamAfterSETUP(False), - fTCPStreamIdCount(0), fNumStreamStates(0), fStreamStates(NULL) { + fTCPStreamIdCount(0), fNumStreamStates(0), fStreamStates(NULL), + fURLPreSuffix(NULL), fURLSuffix(NULL), fFullRequestStr(NULL), fTrackId(NULL) { } RTSPServer::RTSPClientSession::~RTSPClientSession() { reclaimStreamStates(); + delete[] fTrackId; delete[] fFullRequestStr; delete[] fURLSuffix; delete[] fURLPreSuffix; } void RTSPServer::RTSPClientSession::deleteStreamByTrack(unsigned trackNum) { @@ -1364,6 +1392,26 @@ return True; } +// A class used to implement "SETUP (possibly asynchronously). It consists of +// a "RTSPServer" (reference), a "RTSPClientSession" id, +// and an id for a "RTSPClientConnection". + +class ServerSessionConnectionTriple { +public: + ServerSessionConnectionTriple(RTSPServer& server, u_int32_t sessionId, u_int32_t connectionId) + : fServer(server), fSessionId(sessionId), fConnectionId(connectionId) {} + ~ServerSessionConnectionTriple() {} + + RTSPServer& server() const { return fServer; } + u_int32_t sessionId() const { return fSessionId; } + u_int32_t connectionId() const { return fConnectionId; } + +private: + RTSPServer& fServer; + u_int32_t fSessionId; + u_int32_t fConnectionId; +}; + void RTSPServer::RTSPClientSession ::handleCmd_SETUP(RTSPServer::RTSPClientConnection* ourClientConnection, char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr) { @@ -1372,27 +1420,45 @@ // in the special case where we have only a single track. I.e., in this case, we also handle: // "urlPreSuffix" is empty and "urlSuffix" is the session (stream) name, or // "urlPreSuffix" concatenated with "urlSuffix" (with "/" inbetween) is the session (stream) name. - fOurClientConnection = ourClientConnection; - fURLPreSuffix = urlPreSuffix; fURLSuffix = urlSuffix; fFullRequestStr = fullRequestStr; - fTrackId = urlSuffix; // in the normal case + delete[] fURLPreSuffix; fURLPreSuffix = strDup(urlPreSuffix); + delete[] fURLSuffix; fURLSuffix = strDup(urlSuffix); + delete[] fFullRequestStr; fFullRequestStr = strDup(fullRequestStr); + delete[] fTrackId; fTrackId = strDup(urlSuffix); // in the normal case // Begin by checking whether the specified stream name exists: char const* streamName = urlPreSuffix; // in the normal case - fOurServer.lookupServerMediaSession(streamName, SETUPLookupCompletionFunction1, this, + ServerSessionConnectionTriple* sscTriple + = new ServerSessionConnectionTriple(fOurRTSPServer, fOurSessionId, ourClientConnection->id()); + fOurServer.lookupServerMediaSession(streamName, SETUPLookupCompletionFunction1, sscTriple, fOurServerMediaSession == NULL); } void RTSPServer::RTSPClientSession -::SETUPLookupCompletionFunction1(void* clientData, ServerMediaSession* sessionLookedUp) { - RTSPServer::RTSPClientSession* session = (RTSPServer::RTSPClientSession*)clientData; - session->handleCmd_SETUP_afterLookup1(sessionLookedUp); +::SETUPLookupCompletionFunction1(void* clientData, ServerMediaSession* smsLookedUp) { + ServerSessionConnectionTriple* sscTriple = (ServerSessionConnectionTriple*)clientData; + RTSPServer& server = sscTriple->server(); + + u_int32_t sessionId = sscTriple->sessionId(); + RTSPClientSession* session = (RTSPClientSession*)(server.lookupClientSession(sessionId)); + + if (session != NULL) { + u_int32_t connectionId = sscTriple->connectionId(); + RTSPClientConnection* ourClientConnection + = (RTSPClientConnection*)(server.lookupClientConnection(connectionId)); + + if (ourClientConnection != NULL) { + session->handleCmd_SETUP_afterLookup1(ourClientConnection, smsLookedUp); + } + } + delete sscTriple; } void RTSPServer::RTSPClientSession -::handleCmd_SETUP_afterLookup1(ServerMediaSession* sms) { +::handleCmd_SETUP_afterLookup1(RTSPClientConnection* ourClientConnection, + ServerMediaSession* sms) { if (sms != NULL) { // The lookup succeeded; continue working with the returned "ServerMediaSession": - handleCmd_SETUP_afterLookup2(sms); + handleCmd_SETUP_afterLookup2(ourClientConnection, sms); return; } @@ -1407,30 +1473,47 @@ sprintf(concatenatedStreamName, "%s/%s", fURLPreSuffix, fURLSuffix); streamName = concatenatedStreamName; } - fTrackId = NULL; + delete[] fTrackId; fTrackId = NULL; // Check again: - fOurServer.lookupServerMediaSession(streamName, SETUPLookupCompletionFunction2, this, - fOurServerMediaSession == NULL); + ServerSessionConnectionTriple* sscTriple + = new ServerSessionConnectionTriple(fOurRTSPServer, fOurSessionId, ourClientConnection->id()); + fOurServer.lookupServerMediaSession(streamName, SETUPLookupCompletionFunction2, + sscTriple, fOurServerMediaSession == NULL); delete[] concatenatedStreamName; } void RTSPServer::RTSPClientSession -::SETUPLookupCompletionFunction2(void* clientData, ServerMediaSession* sessionLookedUp) { - RTSPServer::RTSPClientSession* session = (RTSPServer::RTSPClientSession*)clientData; - session->handleCmd_SETUP_afterLookup2(sessionLookedUp); +::SETUPLookupCompletionFunction2(void* clientData, ServerMediaSession* smsLookedUp) { + ServerSessionConnectionTriple* sscTriple = (ServerSessionConnectionTriple*)clientData; + RTSPServer& server = sscTriple->server(); + + u_int32_t sessionId = sscTriple->sessionId(); + RTSPClientSession* session = (RTSPClientSession*)(server.lookupClientSession(sessionId)); + + if (session != NULL) { + u_int32_t connectionId = sscTriple->connectionId(); + RTSPClientConnection* ourClientConnection + = (RTSPClientConnection*)(server.lookupClientConnection(connectionId)); + + if (ourClientConnection != NULL) { + session->handleCmd_SETUP_afterLookup2(ourClientConnection, smsLookedUp); + } + } + delete sscTriple; } void RTSPServer::RTSPClientSession -::handleCmd_SETUP_afterLookup2(ServerMediaSession* sms) { +::handleCmd_SETUP_afterLookup2(RTSPClientConnection* ourClientConnection, + ServerMediaSession* sms) { do { if (sms == NULL) { if (fOurServerMediaSession == NULL) { // The client asked for a stream that doesn't exist (and this session descriptor has not been used before): - fOurClientConnection->handleCmd_notFound(); + ourClientConnection->handleCmd_notFound(); } else { // The client asked for a stream that doesn't exist, but using a stream id for a stream that does exist. Bad request: - fOurClientConnection->handleCmd_bad(); + ourClientConnection->handleCmd_bad(); } break; } else { @@ -1440,7 +1523,7 @@ fOurServerMediaSession->incrementReferenceCount(); } else if (sms != fOurServerMediaSession) { // The client asked for a stream that's different from the one originally requested for this stream id. Bad request: - fOurClientConnection->handleCmd_bad(); + ourClientConnection->handleCmd_bad(); break; } } @@ -1481,14 +1564,14 @@ } if (trackNum >= fNumStreamStates) { // The specified track id doesn't exist, so this request fails: - fOurClientConnection->handleCmd_notFound(); + ourClientConnection->handleCmd_notFound(); break; } } else { // Weird case: there was no track id in the URL. // This works only if we have only one subsession: if (fNumStreamStates != 1 || fStreamStates[0].subsession == NULL) { - fOurClientConnection->handleCmd_bad(); + ourClientConnection->handleCmd_bad(); break; } trackNum = 0; @@ -1517,7 +1600,7 @@ clientRTPPortNum, clientRTCPPortNum, rtpChannelId, rtcpChannelId); if ((streamingMode == RTP_TCP && rtpChannelId == 0xFF) || - (streamingMode != RTP_TCP && fOurClientConnection->fClientOutputSocket != fOurClientConnection->fClientInputSocket)) { + (streamingMode != RTP_TCP && ourClientConnection->fClientOutputSocket != ourClientConnection->fClientInputSocket)) { // An anomolous situation, caused by a buggy client. Either: // 1/ TCP streaming was requested, but with no "interleaving=" fields. (QuickTime Player sometimes does this.), or // 2/ TCP streaming was not requested, but we're doing RTSP-over-HTTP tunneling (which implies TCP streaming). @@ -1547,7 +1630,7 @@ // Then, get server parameters from the 'subsession': if (streamingMode == RTP_TCP) { // Note that we'll be streaming over the RTSP TCP connection: - fStreamStates[trackNum].tcpSocketNum = fOurClientConnection->fClientOutputSocket; + fStreamStates[trackNum].tcpSocketNum = ourClientConnection->fClientOutputSocket; fOurRTSPServer.noteTCPStreamingOnSocket(fStreamStates[trackNum].tcpSocketNum, this, trackNum); } struct sockaddr_storage destinationAddress = nullAddress(); @@ -1574,14 +1657,14 @@ // Make sure that we transmit on the same interface that's used by the client // (in case we're a multi-homed server): struct sockaddr_storage sourceAddr; SOCKLEN_T namelen = sizeof sourceAddr; - getsockname(fOurClientConnection->fClientInputSocket, (struct sockaddr*)&sourceAddr, &namelen); + getsockname(ourClientConnection->fClientInputSocket, (struct sockaddr*)&sourceAddr, &namelen); - subsession->getStreamParameters(fOurSessionId, fOurClientConnection->fClientAddr, + subsession->getStreamParameters(fOurSessionId, ourClientConnection->fClientAddr, clientRTPPort, clientRTCPPort, streamingMode == RTP_TCP ? fStreamStates[trackNum].tcpSocketNum : -1, rtpChannelId, rtcpChannelId, - &fOurClientConnection->fTLS, + &ourClientConnection->fTLS, destinationAddress, destinationTTL, fIsMulticast, serverRTPPort, serverRTCPPort, fStreamStates[trackNum].streamToken); @@ -1597,13 +1680,13 @@ if (fIsMulticast) { switch (streamingMode) { case RTP_UDP: { - snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, + snprintf((char*)ourClientConnection->fResponseBuffer, sizeof ourClientConnection->fResponseBuffer, "RTSP/1.0 200 OK\r\n" "CSeq: %s\r\n" "%s" "Transport: RTP/%s;multicast;destination=%s;source=%s;port=%d-%d;ttl=%d\r\n" "Session: %08X%s\r\n\r\n", - fOurClientConnection->fCurrentCSeq, + ourClientConnection->fCurrentCSeq, dateHeader(), fOurRTSPServer.fWeServeSRTP ? "SAVP" : "AVP", destAddrStr.val(), sourceAddrStr.val(), ntohs(serverRTPPort.num()), ntohs(serverRTCPPort.num()), destinationTTL, @@ -1612,17 +1695,17 @@ } case RTP_TCP: { // multicast streams can't be sent via TCP - fOurClientConnection->handleCmd_unsupportedTransport(); + ourClientConnection->handleCmd_unsupportedTransport(); break; } case RAW_UDP: { - snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, + snprintf((char*)ourClientConnection->fResponseBuffer, sizeof ourClientConnection->fResponseBuffer, "RTSP/1.0 200 OK\r\n" "CSeq: %s\r\n" "%s" "Transport: %s;multicast;destination=%s;source=%s;port=%d;ttl=%d\r\n" "Session: %08X%s\r\n\r\n", - fOurClientConnection->fCurrentCSeq, + ourClientConnection->fCurrentCSeq, dateHeader(), streamingModeString, destAddrStr.val(), sourceAddrStr.val(), ntohs(serverRTPPort.num()), destinationTTL, fOurSessionId, timeoutParameterString); @@ -1632,13 +1715,13 @@ } else { switch (streamingMode) { case RTP_UDP: { - snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, + snprintf((char*)ourClientConnection->fResponseBuffer, sizeof ourClientConnection->fResponseBuffer, "RTSP/1.0 200 OK\r\n" "CSeq: %s\r\n" "%s" "Transport: RTP/%s;unicast;destination=%s;source=%s;client_port=%d-%d;server_port=%d-%d\r\n" "Session: %08X%s\r\n\r\n", - fOurClientConnection->fCurrentCSeq, + ourClientConnection->fCurrentCSeq, dateHeader(), fOurRTSPServer.fWeServeSRTP ? "SAVP" : "AVP", destAddrStr.val(), sourceAddrStr.val(), ntohs(clientRTPPort.num()), ntohs(clientRTCPPort.num()), ntohs(serverRTPPort.num()), ntohs(serverRTCPPort.num()), @@ -1647,15 +1730,15 @@ } case RTP_TCP: { if (!fOurRTSPServer.fAllowStreamingRTPOverTCP) { - fOurClientConnection->handleCmd_unsupportedTransport(); + ourClientConnection->handleCmd_unsupportedTransport(); } else { - snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, + snprintf((char*)ourClientConnection->fResponseBuffer, sizeof ourClientConnection->fResponseBuffer, "RTSP/1.0 200 OK\r\n" "CSeq: %s\r\n" "%s" "Transport: RTP/AVP/TCP;unicast;destination=%s;source=%s;interleaved=%d-%d\r\n" "Session: %08X%s\r\n\r\n", - fOurClientConnection->fCurrentCSeq, + ourClientConnection->fCurrentCSeq, dateHeader(), destAddrStr.val(), sourceAddrStr.val(), rtpChannelId, rtcpChannelId, fOurSessionId, timeoutParameterString); @@ -1663,13 +1746,13 @@ break; } case RAW_UDP: { - snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, + snprintf((char*)ourClientConnection->fResponseBuffer, sizeof ourClientConnection->fResponseBuffer, "RTSP/1.0 200 OK\r\n" "CSeq: %s\r\n" "%s" "Transport: %s;unicast;destination=%s;source=%s;client_port=%d;server_port=%d\r\n" "Session: %08X%s\r\n\r\n", - fOurClientConnection->fCurrentCSeq, + ourClientConnection->fCurrentCSeq, dateHeader(), streamingModeString, destAddrStr.val(), sourceAddrStr.val(), ntohs(clientRTPPort.num()), ntohs(serverRTPPort.num()), fOurSessionId, timeoutParameterString); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/authenticationOK new/live/liveMedia/authenticationOK --- old/live/liveMedia/authenticationOK 2026-05-28 14:43:06.000000000 +0200 +++ new/live/liveMedia/authenticationOK 1970-01-01 01:00:00.000000000 +0100 @@ -1,33 +0,0 @@ -RTSPServer.cpp: fOurClientConnection->handleCmd_notFound(); -RTSPServer.cpp: fOurClientConnection->handleCmd_bad(); -RTSPServer.cpp: fOurClientConnection->handleCmd_bad(); -RTSPServer.cpp: fOurClientConnection->handleCmd_notFound(); -RTSPServer.cpp: fOurClientConnection->handleCmd_bad(); -RTSPServer.cpp: (streamingMode != RTP_TCP && fOurClientConnection->fClientOutputSocket != fOurClientConnection->fClientInputSocket)) { -RTSPServer.cpp: fStreamStates[trackNum].tcpSocketNum = fOurClientConnection->fClientOutputSocket; -RTSPServer.cpp: getsockname(fOurClientConnection->fClientInputSocket, (struct sockaddr*)&sourceAddr, &namelen); -RTSPServer.cpp: subsession->getStreamParameters(fOurSessionId, fOurClientConnection->fClientAddr, -RTSPServer.cpp: &fOurClientConnection->fTLS, -RTSPServer.cpp: snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, -RTSPServer.cpp: fOurClientConnection->fCurrentCSeq, -RTSPServer.cpp: fOurClientConnection->handleCmd_unsupportedTransport(); -RTSPServer.cpp: snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, -RTSPServer.cpp: fOurClientConnection->fCurrentCSeq, -RTSPServer.cpp: snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, -RTSPServer.cpp: fOurClientConnection->fCurrentCSeq, -RTSPServer.cpp: fOurClientConnection->handleCmd_unsupportedTransport(); -RTSPServer.cpp: snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, -RTSPServer.cpp: fOurClientConnection->fCurrentCSeq, -RTSPServer.cpp: snprintf((char*)fOurClientConnection->fResponseBuffer, sizeof fOurClientConnection->fResponseBuffer, -RTSPServer.cpp: fOurClientConnection->fCurrentCSeq, -RTSPServer.cpp: ourClientConnection->handleCmd_notSupported(); -RTSPServer.cpp: ourClientConnection->handleCmd_notFound(); -RTSPServer.cpp: ourClientConnection->handleCmd_notFound(); -RTSPServer.cpp: ourClientConnection->handleCmd_notFound(); -RTSPServer.cpp: if (!ourClientConnection->authenticationOK("TEARDOWN", "", fullRequestStr)) return; -RTSPServer.cpp: = fOurRTSPServer.rtspURL(fOurServerMediaSession, ourClientConnection->fClientInputSocket); -RTSPServer.cpp: if (!ourClientConnection->authenticationOK("PLAY", rtspURL, fullRequestStr)) return; -RTSPServer.cpp: snprintf((char*)ourClientConnection->fResponseBuffer, sizeof ourClientConnection->fResponseBuffer, -RTSPServer.cpp: ourClientConnection->fCurrentCSeq, -RTSPServer.cpp: if (!ourClientConnection->authenticationOK("PAUSE", "", fullRequestStr)) return; -RTSPServer.cpp: if (!fOurClientConnection->authenticationOK("SET_PARAMETER", "", fullRequestStr)) return; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/GenericMediaServer.hh new/live/liveMedia/include/GenericMediaServer.hh --- old/live/liveMedia/include/GenericMediaServer.hh 2026-05-28 14:43:06.000000000 +0200 +++ new/live/liveMedia/include/GenericMediaServer.hh 2026-06-01 11:12:14.000000000 +0200 @@ -39,7 +39,7 @@ // Typedef for a handler function that gets called when "lookupServerMediaSession()" // (defined below) completes: typedef void lookupServerMediaSessionCompletionFunc(void* clientData, - ServerMediaSession* sessionLookedUp); + ServerMediaSession* smsLookedUp); class GenericMediaServer: public Medium { public: @@ -101,6 +101,9 @@ public: // should be protected, but some old compilers complain otherwise // The state of a TCP connection used by a client: class ClientConnection { + public: + unsigned id() const { return fConnectionId; } + protected: ClientConnection(GenericMediaServer& ourServer, int clientSocket, struct sockaddr_storage const& clientAddr, @@ -119,6 +122,7 @@ friend class GenericMediaServer; friend class ClientSession; friend class RTSPServer; // needed to make some broken Windows compilers work; remove this in the future when we end support for Windows + unsigned fConnectionId; GenericMediaServer& fOurServer; int fOurSocket; struct sockaddr_storage fClientAddr; @@ -132,6 +136,8 @@ ServerTLSState* fOutputTLS; // ditto }; + ClientConnection* lookupClientConnection(u_int32_t connectionId) const; + // The state of an individual client session (using one or more sequential TCP connections) handled by a server: class ClientSession { protected: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/RTSPServer.hh new/live/liveMedia/include/RTSPServer.hh --- old/live/liveMedia/include/RTSPServer.hh 2026-05-28 14:43:06.000000000 +0200 +++ new/live/liveMedia/include/RTSPServer.hh 2026-06-01 11:12:14.000000000 +0200 @@ -185,7 +185,7 @@ virtual void handleCmd_GET_PARAMETER(char const* fullRequestStr); // when operating on the entire server virtual void handleCmd_SET_PARAMETER(char const* fullRequestStr); // when operating on the entire server virtual void handleCmd_DESCRIBE(char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr); - static void DESCRIBELookupCompletionFunction(void* clientData, ServerMediaSession* sessionLookedUp); + static void DESCRIBELookupCompletionFunction(void* clientData, ServerMediaSession* smsLookedUp); virtual void handleCmd_DESCRIBE_afterLookup(ServerMediaSession* session); virtual void handleCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/, char const* url, char const* urlSuffix, char const* fullRequestStr, @@ -253,10 +253,12 @@ // Make the handler functions for each command virtual, to allow subclasses to redefine them: virtual void handleCmd_SETUP(RTSPClientConnection* ourClientConnection, char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr); - static void SETUPLookupCompletionFunction1(void* clientData, ServerMediaSession* sessionLookedUp); - virtual void handleCmd_SETUP_afterLookup1(ServerMediaSession* sms); - static void SETUPLookupCompletionFunction2(void* clientData, ServerMediaSession* sessionLookedUp); - virtual void handleCmd_SETUP_afterLookup2(ServerMediaSession* sms); + static void SETUPLookupCompletionFunction1(void* clientData, ServerMediaSession* smsLookedUp); + virtual void handleCmd_SETUP_afterLookup1(RTSPClientConnection* ourClientConnection, + ServerMediaSession* sms); + static void SETUPLookupCompletionFunction2(void* clientData, ServerMediaSession* smsLookedUp); + virtual void handleCmd_SETUP_afterLookup2(RTSPClientConnection* ourClientConnection, + ServerMediaSession* sms); virtual void handleCmd_withinSession(RTSPClientConnection* ourClientConnection, char const* cmdName, char const* urlPreSuffix, char const* urlSuffix, @@ -295,7 +297,6 @@ } * fStreamStates; // Member variables used to implement "handleCmd_SETUP()": - RTSPServer::RTSPClientConnection* fOurClientConnection; char const* fURLPreSuffix; char const* fURLSuffix; char const* fFullRequestStr; char const* fTrackId; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/live/liveMedia/include/liveMedia_version.hh new/live/liveMedia/include/liveMedia_version.hh --- old/live/liveMedia/include/liveMedia_version.hh 2026-05-28 14:43:06.000000000 +0200 +++ new/live/liveMedia/include/liveMedia_version.hh 2026-06-01 11:12:14.000000000 +0200 @@ -19,8 +19,8 @@ #ifndef _LIVEMEDIA_VERSION_HH #define _LIVEMEDIA_VERSION_HH -#define LIVEMEDIA_LIBRARY_VERSION_STRING "2026.05.28" -#define LIVEMEDIA_LIBRARY_VERSION_INT 1779926400 +#define LIVEMEDIA_LIBRARY_VERSION_STRING "2026.06.01" +#define LIVEMEDIA_LIBRARY_VERSION_INT 1780272000 extern char const* const liveMediaLibraryVersionStr; extern int const liveMediaLibraryVersionInt;
