/usr/include/liveMedia/RTSPServer.hh is in liblivemedia-dev 2018.02.18-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | /**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**********/
// "liveMedia"
// Copyright (c) 1996-2018 Live Networks, Inc. All rights reserved.
// A RTSP server
// C++ header
#ifndef _RTSP_SERVER_HH
#define _RTSP_SERVER_HH
#ifndef _GENERIC_MEDIA_SERVER_HH
#include "GenericMediaServer.hh"
#endif
#ifndef _DIGEST_AUTHENTICATION_HH
#include "DigestAuthentication.hh"
#endif
class RTSPServer: public GenericMediaServer {
public:
static RTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554,
UserAuthenticationDatabase* authDatabase = NULL,
unsigned reclamationSeconds = 65);
// If ourPort.num() == 0, we'll choose the port number
// Note: The caller is responsible for reclaiming "authDatabase"
// If "reclamationSeconds" > 0, then the "RTSPClientSession" state for
// each client will get reclaimed (and the corresponding RTP stream(s)
// torn down) if no RTSP commands - or RTCP "RR" packets - from the
// client are received in at least "reclamationSeconds" seconds.
static Boolean lookupByName(UsageEnvironment& env, char const* name,
RTSPServer*& resultServer);
typedef void (responseHandlerForREGISTER)(RTSPServer* rtspServer, unsigned requestId, int resultCode, char* resultString);
unsigned registerStream(ServerMediaSession* serverMediaSession,
char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum,
responseHandlerForREGISTER* responseHandler,
char const* username = NULL, char const* password = NULL,
Boolean receiveOurStreamViaTCP = False,
char const* proxyURLSuffix = NULL);
// 'Register' the stream represented by "serverMediaSession" with the given remote client (specifed by name and port number).
// This is done using our custom "REGISTER" RTSP command.
// The function returns a unique number that can be used to identify the request; this number is also passed to "responseHandler".
// When a response is received from the remote client (or the "REGISTER" request fails), the specified response handler
// (if non-NULL) is called. (Note that the "resultString" passed to the handler was dynamically allocated,
// and should be delete[]d by the handler after use.)
// If "receiveOurStreamViaTCP" is True, then we're requesting that the remote client access our stream using RTP/RTCP-over-TCP.
// (Otherwise, the remote client may choose regular RTP/RTCP-over-UDP streaming.)
// "proxyURLSuffix" (optional) is used only when the remote client is also a proxy server.
// It tells the proxy server the suffix that it should use in its "rtsp://" URL (when front-end clients access the stream)
typedef void (responseHandlerForDEREGISTER)(RTSPServer* rtspServer, unsigned requestId, int resultCode, char* resultString);
unsigned deregisterStream(ServerMediaSession* serverMediaSession,
char const* remoteClientNameOrAddress, portNumBits remoteClientPortNum,
responseHandlerForDEREGISTER* responseHandler,
char const* username = NULL, char const* password = NULL,
char const* proxyURLSuffix = NULL);
// Used to turn off a previous "registerStream()" - using our custom "DEREGISTER" RTSP command.
char* rtspURL(ServerMediaSession const* serverMediaSession, int clientSocket = -1) const;
// returns a "rtsp://" URL that could be used to access the
// specified session (which must already have been added to
// us using "addServerMediaSession()".
// This string is dynamically allocated; caller should delete[]
// (If "clientSocket" is non-negative, then it is used (by calling "getsockname()") to determine
// the IP address to be used in the URL.)
char* rtspURLPrefix(int clientSocket = -1) const;
// like "rtspURL()", except that it returns just the common prefix used by
// each session's "rtsp://" URL.
// This string is dynamically allocated; caller should delete[]
UserAuthenticationDatabase* setAuthenticationDatabase(UserAuthenticationDatabase* newDB);
// Changes the server's authentication database to "newDB", returning a pointer to the old database (if there was one).
// "newDB" may be NULL (you can use this to disable authentication at runtime, if desired).
void disableStreamingRTPOverTCP() {
fAllowStreamingRTPOverTCP = False;
}
Boolean setUpTunnelingOverHTTP(Port httpPort);
// (Attempts to) enable RTSP-over-HTTP tunneling on the specified port.
// Returns True iff the specified port can be used in this way (i.e., it's not already being used for a separate HTTP server).
// Note: RTSP-over-HTTP tunneling is described in
// http://mirror.informatimago.com/next/developer.apple.com/quicktime/icefloe/dispatch028.html
// and http://images.apple.com/br/quicktime/pdf/QTSS_Modules.pdf
portNumBits httpServerPortNum() const; // in host byte order. (Returns 0 if not present.)
protected:
RTSPServer(UsageEnvironment& env,
int ourSocket, Port ourPort,
UserAuthenticationDatabase* authDatabase,
unsigned reclamationSeconds);
// called only by createNew();
virtual ~RTSPServer();
virtual char const* allowedCommandNames(); // used to implement "RTSPClientConnection::handleCmd_OPTIONS()"
virtual Boolean weImplementREGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
char const* proxyURLSuffix, char*& responseStr);
// used to implement "RTSPClientConnection::handleCmd_REGISTER()"
// Note: "responseStr" is dynamically allocated (or NULL), and should be delete[]d after the call
virtual void implementCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
char const* url, char const* urlSuffix, int socketToRemoteServer,
Boolean deliverViaTCP, char const* proxyURLSuffix);
// used to implement "RTSPClientConnection::handleCmd_REGISTER()"
virtual UserAuthenticationDatabase* getAuthenticationDatabaseForCommand(char const* cmdName);
virtual Boolean specialClientAccessCheck(int clientSocket, struct sockaddr_in& clientAddr,
char const* urlSuffix);
// a hook that allows subclassed servers to do server-specific access checking
// on each client (e.g., based on client IP address), without using digest authentication.
virtual Boolean specialClientUserAccessCheck(int clientSocket, struct sockaddr_in& clientAddr,
char const* urlSuffix, char const *username);
// another hook that allows subclassed servers to do server-specific access checking
// - this time after normal digest authentication has already taken place (and would otherwise allow access).
// (This test can only be used to further restrict access, not to grant additional access.)
private: // redefined virtual functions
virtual Boolean isRTSPServer() const;
public: // should be protected, but some old compilers complain otherwise
// The state of a TCP connection used by a RTSP client:
class RTSPClientSession; // forward
class RTSPClientConnection: public GenericMediaServer::ClientConnection {
public:
// A data structure that's used to implement the "REGISTER" command:
class ParamsForREGISTER {
public:
ParamsForREGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
RTSPClientConnection* ourConnection, char const* url, char const* urlSuffix,
Boolean reuseConnection, Boolean deliverViaTCP, char const* proxyURLSuffix);
virtual ~ParamsForREGISTER();
private:
friend class RTSPClientConnection;
char const* fCmd;
RTSPClientConnection* fOurConnection;
char* fURL;
char* fURLSuffix;
Boolean fReuseConnection, fDeliverViaTCP;
char* fProxyURLSuffix;
};
protected: // redefined virtual functions:
virtual void handleRequestBytes(int newBytesRead);
protected:
RTSPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr);
virtual ~RTSPClientConnection();
friend class RTSPServer;
friend class RTSPClientSession;
// Make the handler functions for each command virtual, to allow subclasses to reimplement them, if necessary:
virtual void handleCmd_OPTIONS();
// You probably won't need to subclass/reimplement this function; reimplement "RTSPServer::allowedCommandNames()" instead.
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);
virtual void handleCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
char const* url, char const* urlSuffix, char const* fullRequestStr,
Boolean reuseConnection, Boolean deliverViaTCP, char const* proxyURLSuffix);
// You probably won't need to subclass/reimplement this function;
// reimplement "RTSPServer::weImplementREGISTER()" and "RTSPServer::implementCmd_REGISTER()" instead.
virtual void handleCmd_bad();
virtual void handleCmd_notSupported();
virtual void handleCmd_notFound();
virtual void handleCmd_sessionNotFound();
virtual void handleCmd_unsupportedTransport();
// Support for optional RTSP-over-HTTP tunneling:
virtual Boolean parseHTTPRequestString(char* resultCmdName, unsigned resultCmdNameMaxSize,
char* urlSuffix, unsigned urlSuffixMaxSize,
char* sessionCookie, unsigned sessionCookieMaxSize,
char* acceptStr, unsigned acceptStrMaxSize);
virtual void handleHTTPCmd_notSupported();
virtual void handleHTTPCmd_notFound();
virtual void handleHTTPCmd_OPTIONS();
virtual void handleHTTPCmd_TunnelingGET(char const* sessionCookie);
virtual Boolean handleHTTPCmd_TunnelingPOST(char const* sessionCookie, unsigned char const* extraData, unsigned extraDataSize);
virtual void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* fullRequestStr);
protected:
void resetRequestBuffer();
void closeSocketsRTSP();
static void handleAlternativeRequestByte(void*, u_int8_t requestByte);
void handleAlternativeRequestByte1(u_int8_t requestByte);
Boolean authenticationOK(char const* cmdName, char const* urlSuffix, char const* fullRequestStr);
void changeClientInputSocket(int newSocketNum, unsigned char const* extraData, unsigned extraDataSize);
// used to implement RTSP-over-HTTP tunneling
static void continueHandlingREGISTER(ParamsForREGISTER* params);
virtual void continueHandlingREGISTER1(ParamsForREGISTER* params);
// Shortcuts for setting up a RTSP response (prior to sending it):
void setRTSPResponse(char const* responseStr);
void setRTSPResponse(char const* responseStr, u_int32_t sessionId);
void setRTSPResponse(char const* responseStr, char const* contentStr);
void setRTSPResponse(char const* responseStr, u_int32_t sessionId, char const* contentStr);
RTSPServer& fOurRTSPServer; // same as ::fOurServer
int& fClientInputSocket; // aliased to ::fOurSocket
int fClientOutputSocket;
Boolean fIsActive;
unsigned char* fLastCRLF;
unsigned fRecursionCount;
char const* fCurrentCSeq;
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)
};
// The state of an individual client session (using one or more sequential TCP connections) handled by a RTSP server:
class RTSPClientSession: public GenericMediaServer::ClientSession {
protected:
RTSPClientSession(RTSPServer& ourServer, u_int32_t sessionId);
virtual ~RTSPClientSession();
friend class RTSPServer;
friend class RTSPClientConnection;
// 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);
virtual void handleCmd_withinSession(RTSPClientConnection* ourClientConnection,
char const* cmdName,
char const* urlPreSuffix, char const* urlSuffix,
char const* fullRequestStr);
virtual void handleCmd_TEARDOWN(RTSPClientConnection* ourClientConnection,
ServerMediaSubsession* subsession);
virtual void handleCmd_PLAY(RTSPClientConnection* ourClientConnection,
ServerMediaSubsession* subsession, char const* fullRequestStr);
virtual void handleCmd_PAUSE(RTSPClientConnection* ourClientConnection,
ServerMediaSubsession* subsession);
virtual void handleCmd_GET_PARAMETER(RTSPClientConnection* ourClientConnection,
ServerMediaSubsession* subsession, char const* fullRequestStr);
virtual void handleCmd_SET_PARAMETER(RTSPClientConnection* ourClientConnection,
ServerMediaSubsession* subsession, char const* fullRequestStr);
protected:
void deleteStreamByTrack(unsigned trackNum);
void reclaimStreamStates();
Boolean isMulticast() const { return fIsMulticast; }
// Shortcuts for setting up a RTSP response (prior to sending it):
void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr) { ourClientConnection->setRTSPResponse(responseStr); }
void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr, u_int32_t sessionId) { ourClientConnection->setRTSPResponse(responseStr, sessionId); }
void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr, char const* contentStr) { ourClientConnection->setRTSPResponse(responseStr, contentStr); }
void setRTSPResponse(RTSPClientConnection* ourClientConnection, char const* responseStr, u_int32_t sessionId, char const* contentStr) { ourClientConnection->setRTSPResponse(responseStr, sessionId, contentStr); }
protected:
RTSPServer& fOurRTSPServer; // same as ::fOurServer
Boolean fIsMulticast, fStreamAfterSETUP;
unsigned char fTCPStreamIdCount; // used for (optional) RTP/TCP
Boolean usesTCPTransport() const { return fTCPStreamIdCount > 0; }
unsigned fNumStreamStates;
struct streamState {
ServerMediaSubsession* subsession;
int tcpSocketNum;
void* streamToken;
} * fStreamStates;
};
protected: // redefined virtual functions
// If you subclass "RTSPClientConnection", then you must also redefine this virtual function in order
// to create new objects of your subclass:
virtual ClientConnection* createNewClientConnection(int clientSocket, struct sockaddr_in clientAddr);
protected:
// If you subclass "RTSPClientSession", then you must also redefine this virtual function in order
// to create new objects of your subclass:
virtual ClientSession* createNewClientSession(u_int32_t sessionId);
private:
static void incomingConnectionHandlerHTTP(void*, int /*mask*/);
void incomingConnectionHandlerHTTP();
void noteTCPStreamingOnSocket(int socketNum, RTSPClientSession* clientSession, unsigned trackNum);
void unnoteTCPStreamingOnSocket(int socketNum, RTSPClientSession* clientSession, unsigned trackNum);
void stopTCPStreamingOnSocket(int socketNum);
private:
friend class RTSPClientConnection;
friend class RTSPClientSession;
friend class RegisterRequestRecord;
friend class DeregisterRequestRecord;
int fHTTPServerSocket; // for optional RTSP-over-HTTP tunneling
Port fHTTPServerPort; // ditto
HashTable* fClientConnectionsForHTTPTunneling; // maps client-supplied 'session cookie' strings to "RTSPClientConnection"s
// (used only for optional RTSP-over-HTTP tunneling)
HashTable* fTCPStreamingDatabase;
// maps TCP socket numbers to ids of sessions that are streaming over it (RTP/RTCP-over-TCP)
HashTable* fPendingRegisterOrDeregisterRequests;
unsigned fRegisterOrDeregisterRequestCounter;
UserAuthenticationDatabase* fAuthDB;
Boolean fAllowStreamingRTPOverTCP; // by default, True
};
////////// A subclass of "RTSPServer" that implements the "REGISTER" command to set up proxying on the specified URL //////////
class RTSPServerWithREGISTERProxying: public RTSPServer {
public:
static RTSPServerWithREGISTERProxying* createNew(UsageEnvironment& env, Port ourPort = 554,
UserAuthenticationDatabase* authDatabase = NULL,
UserAuthenticationDatabase* authDatabaseForREGISTER = NULL,
unsigned reclamationSeconds = 65,
Boolean streamRTPOverTCP = False,
int verbosityLevelForProxying = 0,
char const* backEndUsername = NULL,
char const* backEndPassword = NULL);
protected:
RTSPServerWithREGISTERProxying(UsageEnvironment& env, int ourSocket, Port ourPort,
UserAuthenticationDatabase* authDatabase, UserAuthenticationDatabase* authDatabaseForREGISTER,
unsigned reclamationSeconds,
Boolean streamRTPOverTCP, int verbosityLevelForProxying,
char const* backEndUsername, char const* backEndPassword);
// called only by createNew();
virtual ~RTSPServerWithREGISTERProxying();
protected: // redefined virtual functions
virtual char const* allowedCommandNames();
virtual Boolean weImplementREGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
char const* proxyURLSuffix, char*& responseStr);
virtual void implementCmd_REGISTER(char const* cmd/*"REGISTER" or "DEREGISTER"*/,
char const* url, char const* urlSuffix, int socketToRemoteServer,
Boolean deliverViaTCP, char const* proxyURLSuffix);
virtual UserAuthenticationDatabase* getAuthenticationDatabaseForCommand(char const* cmdName);
private:
Boolean fStreamRTPOverTCP;
int fVerbosityLevelForProxying;
unsigned fRegisteredProxyCounter;
char* fAllowedCommandNames;
UserAuthenticationDatabase* fAuthDBForREGISTER;
char* fBackEndUsername;
char* fBackEndPassword;
};
// A special version of "parseTransportHeader()", used just for parsing the "Transport:" header
// in an incoming "REGISTER" command:
void parseTransportHeaderForREGISTER(char const* buf, // in
Boolean &reuseConnection, // out
Boolean& deliverViaTCP, // out
char*& proxyURLSuffix); // out
#endif
|