00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _RTSP_SERVER_HH
00022 #define _RTSP_SERVER_HH
00023
00024 #ifndef _SERVER_MEDIA_SESSION_HH
00025 #include "ServerMediaSession.hh"
00026 #endif
00027 #ifndef _NET_ADDRESS_HH
00028 #include <NetAddress.hh>
00029 #endif
00030 #ifndef _DIGEST_AUTHENTICATION_HH
00031 #include "DigestAuthentication.hh"
00032 #endif
00033
00034
00035
00036 class UserAuthenticationDatabase {
00037 public:
00038 UserAuthenticationDatabase(char const* realm = NULL,
00039 Boolean passwordsAreMD5 = False);
00040
00041
00042
00043 virtual ~UserAuthenticationDatabase();
00044
00045 virtual void addUserRecord(char const* username, char const* password);
00046 virtual void removeUserRecord(char const* username);
00047
00048 virtual char const* lookupPassword(char const* username);
00049
00050
00051 char const* realm() { return fRealm; }
00052 Boolean passwordsAreMD5() { return fPasswordsAreMD5; }
00053
00054 protected:
00055 HashTable* fTable;
00056 char* fRealm;
00057 Boolean fPasswordsAreMD5;
00058 };
00059
00060 #ifndef RTSP_BUFFER_SIZE
00061 #define RTSP_BUFFER_SIZE 10000 // for incoming requests, and outgoing responses
00062 #endif
00063
00064 class RTSPServer: public Medium {
00065 public:
00066 static RTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554,
00067 UserAuthenticationDatabase* authDatabase = NULL,
00068 unsigned reclamationTestSeconds = 65);
00069
00070
00071
00072
00073
00074
00075
00076 static Boolean lookupByName(UsageEnvironment& env, char const* name,
00077 RTSPServer*& resultServer);
00078
00079 void addServerMediaSession(ServerMediaSession* serverMediaSession);
00080
00081 virtual ServerMediaSession* lookupServerMediaSession(char const* streamName);
00082
00083 void removeServerMediaSession(ServerMediaSession* serverMediaSession);
00084
00085
00086
00087
00088
00089 void removeServerMediaSession(char const* streamName);
00090
00091
00092 void closeAllClientSessionsForServerMediaSession(ServerMediaSession* serverMediaSession);
00093
00094
00095 void closeAllClientSessionsForServerMediaSession(char const* streamName);
00096
00097
00098 void deleteServerMediaSession(ServerMediaSession* serverMediaSession);
00099
00100
00101 void deleteServerMediaSession(char const* streamName);
00102
00103
00104
00105 char* rtspURL(ServerMediaSession const* serverMediaSession, int clientSocket = -1) const;
00106
00107
00108
00109
00110
00111
00112 char* rtspURLPrefix(int clientSocket = -1) const;
00113
00114
00115
00116
00117 UserAuthenticationDatabase* setAuthenticationDatabase(UserAuthenticationDatabase* newDB);
00118
00119
00120
00121 Boolean setUpTunnelingOverHTTP(Port httpPort);
00122
00123
00124
00125 portNumBits httpServerPortNum() const;
00126
00127 protected:
00128 RTSPServer(UsageEnvironment& env,
00129 int ourSocket, Port ourPort,
00130 UserAuthenticationDatabase* authDatabase,
00131 unsigned reclamationTestSeconds);
00132
00133 virtual ~RTSPServer();
00134
00135 static int setUpOurSocket(UsageEnvironment& env, Port& ourPort);
00136
00137 virtual Boolean specialClientAccessCheck(int clientSocket, struct sockaddr_in& clientAddr,
00138 char const* urlSuffix);
00139
00140
00141 virtual Boolean specialClientUserAccessCheck(int clientSocket, struct sockaddr_in& clientAddr,
00142 char const* urlSuffix, char const *username);
00143
00144
00145
00146
00147 private:
00148 virtual Boolean isRTSPServer() const;
00149
00150 public:
00151 class RTSPClientSession;
00152
00153 class RTSPClientConnection {
00154 public:
00155 RTSPClientConnection(RTSPServer& ourServer, int clientSocket, struct sockaddr_in clientAddr);
00156 virtual ~RTSPClientConnection();
00157 protected:
00158 friend class RTSPClientSession;
00159
00160 virtual void handleCmd_OPTIONS();
00161 virtual void handleCmd_GET_PARAMETER(char const* fullRequestStr);
00162 virtual void handleCmd_SET_PARAMETER(char const* fullRequestStr);
00163 virtual void handleCmd_DESCRIBE(char const* urlPreSuffix, char const* urlSuffix,
00164 char const* fullRequestStr);
00165 virtual void handleCmd_bad();
00166 virtual void handleCmd_notSupported();
00167 virtual void handleCmd_notFound();
00168 virtual void handleCmd_sessionNotFound();
00169 virtual void handleCmd_unsupportedTransport();
00170
00171 virtual Boolean parseHTTPRequestString(char* resultCmdName, unsigned resultCmdNameMaxSize,
00172 char* urlSuffix, unsigned urlSuffixMaxSize,
00173 char* sessionCookie, unsigned sessionCookieMaxSize,
00174 char* acceptStr, unsigned acceptStrMaxSize);
00175 virtual void handleHTTPCmd_notSupported();
00176 virtual void handleHTTPCmd_notFound();
00177 virtual void handleHTTPCmd_TunnelingGET(char const* sessionCookie);
00178 virtual Boolean handleHTTPCmd_TunnelingPOST(char const* sessionCookie, unsigned char const* extraData, unsigned extraDataSize);
00179 virtual void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* fullRequestStr);
00180 protected:
00181 UsageEnvironment& envir() { return fOurServer.envir(); }
00182 void resetRequestBuffer();
00183 void closeSockets();
00184 static void incomingRequestHandler(void*, int );
00185 void incomingRequestHandler1();
00186 static void handleAlternativeRequestByte(void*, u_int8_t requestByte);
00187 void handleAlternativeRequestByte1(u_int8_t requestByte);
00188 void handleRequestBytes(int newBytesRead);
00189 Boolean authenticationOK(char const* cmdName, char const* urlSuffix, char const* fullRequestStr);
00190 void changeClientInputSocket(int newSocketNum, unsigned char const* extraData, unsigned extraDataSize);
00191
00192
00193 void setRTSPResponse(char const* responseStr);
00194 void setRTSPResponse(char const* responseStr, u_int32_t sessionId);
00195 void setRTSPResponse(char const* responseStr, char const* contentStr);
00196 void setRTSPResponse(char const* responseStr, u_int32_t sessionId, char const* contentStr);
00197 protected:
00198 RTSPServer& fOurServer;
00199 Boolean fIsActive;
00200 int fClientInputSocket, fClientOutputSocket;
00201 struct sockaddr_in fClientAddr;
00202 unsigned char fRequestBuffer[RTSP_BUFFER_SIZE];
00203 unsigned fRequestBytesAlreadySeen, fRequestBufferBytesLeft;
00204 unsigned char* fLastCRLF;
00205 unsigned char fResponseBuffer[RTSP_BUFFER_SIZE];
00206 unsigned fRecursionCount;
00207 char const* fCurrentCSeq;
00208 Authenticator fCurrentAuthenticator;
00209 char* fOurSessionCookie;
00210 unsigned fBase64RemainderCount;
00211 };
00212
00213
00214 class RTSPClientSession {
00215 public:
00216 RTSPClientSession(RTSPServer& ourServer, u_int32_t sessionId);
00217 virtual ~RTSPClientSession();
00218 protected:
00219 friend class RTSPServer;
00220 friend class RTSPClientConnection;
00221
00222 virtual void handleCmd_SETUP(RTSPClientConnection* ourClientConnection,
00223 char const* urlPreSuffix, char const* urlSuffix, char const* fullRequestStr);
00224 virtual void handleCmd_withinSession(RTSPClientConnection* ourClientConnection,
00225 char const* cmdName,
00226 char const* urlPreSuffix, char const* urlSuffix,
00227 char const* fullRequestStr);
00228 virtual void handleCmd_TEARDOWN(RTSPClientConnection* ourClientConnection,
00229 ServerMediaSubsession* subsession);
00230 virtual void handleCmd_PLAY(RTSPClientConnection* ourClientConnection,
00231 ServerMediaSubsession* subsession, char const* fullRequestStr);
00232 virtual void handleCmd_PAUSE(RTSPClientConnection* ourClientConnection,
00233 ServerMediaSubsession* subsession);
00234 virtual void handleCmd_GET_PARAMETER(RTSPClientConnection* ourClientConnection,
00235 ServerMediaSubsession* subsession, char const* fullRequestStr);
00236 virtual void handleCmd_SET_PARAMETER(RTSPClientConnection* ourClientConnection,
00237 ServerMediaSubsession* subsession, char const* fullRequestStr);
00238 protected:
00239 UsageEnvironment& envir() { return fOurServer.envir(); }
00240 void reclaimStreamStates();
00241 Boolean isMulticast() const { return fIsMulticast; }
00242 void noteLiveness();
00243 static void noteClientLiveness(RTSPClientSession* clientSession);
00244 static void livenessTimeoutTask(RTSPClientSession* clientSession);
00245 protected:
00246 RTSPServer& fOurServer;
00247 u_int32_t fOurSessionId;
00248 ServerMediaSession* fOurServerMediaSession;
00249 Boolean fIsMulticast, fStreamAfterSETUP;
00250 unsigned char fTCPStreamIdCount;
00251 Boolean usesTCPTransport() const { return fTCPStreamIdCount > 0; }
00252 TaskToken fLivenessCheckTask;
00253 unsigned fNumStreamStates;
00254 struct streamState {
00255 ServerMediaSubsession* subsession;
00256 void* streamToken;
00257 } * fStreamStates;
00258 };
00259
00260 protected:
00261
00262
00263 virtual RTSPClientConnection*
00264 createNewClientConnection(int clientSocket, struct sockaddr_in clientAddr);
00265
00266
00267
00268 virtual RTSPClientSession*
00269 createNewClientSession(u_int32_t sessionId);
00270
00271
00272 class ServerMediaSessionIterator {
00273 public:
00274 ServerMediaSessionIterator(RTSPServer& server);
00275 virtual ~ServerMediaSessionIterator();
00276 ServerMediaSession* next();
00277 private:
00278 HashTable::Iterator* fOurIterator;
00279 };
00280
00281 private:
00282 static void incomingConnectionHandlerRTSP(void*, int );
00283 void incomingConnectionHandlerRTSP1();
00284
00285 static void incomingConnectionHandlerHTTP(void*, int );
00286 void incomingConnectionHandlerHTTP1();
00287
00288 void incomingConnectionHandler(int serverSocket);
00289
00290 private:
00291 friend class RTSPClientConnection;
00292 friend class RTSPClientSession;
00293 friend class ServerMediaSessionIterator;
00294 int fRTSPServerSocket;
00295 Port fRTSPServerPort;
00296 int fHTTPServerSocket;
00297 Port fHTTPServerPort;
00298 HashTable* fServerMediaSessions;
00299 HashTable* fClientConnections;
00300 HashTable* fClientConnectionsForHTTPTunneling;
00301
00302 HashTable* fClientSessions;
00303 UserAuthenticationDatabase* fAuthDB;
00304 unsigned fReclamationTestSeconds;
00305 };
00306
00307 #endif