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 #define RTSP_BUFFER_SIZE 10000 // for incoming requests, and outgoing responses
00061
00062 class RTSPServer: public Medium {
00063 public:
00064 static RTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554,
00065 UserAuthenticationDatabase* authDatabase = NULL,
00066 unsigned reclamationTestSeconds = 65);
00067
00068
00069
00070
00071
00072
00073
00074 static Boolean lookupByName(UsageEnvironment& env, char const* name,
00075 RTSPServer*& resultServer);
00076
00077 void addServerMediaSession(ServerMediaSession* serverMediaSession);
00078 virtual ServerMediaSession* lookupServerMediaSession(char const* streamName);
00079 void removeServerMediaSession(ServerMediaSession* serverMediaSession);
00080 void removeServerMediaSession(char const* streamName);
00081
00082 char* rtspURL(ServerMediaSession const* serverMediaSession, int clientSocket = -1) const;
00083
00084
00085
00086
00087
00088
00089 char* rtspURLPrefix(int clientSocket = -1) const;
00090
00091
00092
00093
00094 UserAuthenticationDatabase* setAuthenticationDatabase(UserAuthenticationDatabase* newDB);
00095
00096
00097
00098 Boolean setUpTunnelingOverHTTP(Port httpPort);
00099
00100
00101
00102 portNumBits httpServerPortNum() const;
00103
00104 protected:
00105 RTSPServer(UsageEnvironment& env,
00106 int ourSocket, Port ourPort,
00107 UserAuthenticationDatabase* authDatabase,
00108 unsigned reclamationTestSeconds);
00109
00110 virtual ~RTSPServer();
00111
00112 static int setUpOurSocket(UsageEnvironment& env, Port& ourPort);
00113 virtual Boolean specialClientAccessCheck(int clientSocket, struct sockaddr_in& clientAddr,
00114 char const* urlSuffix);
00115
00116
00117
00118
00119 private:
00120 virtual Boolean isRTSPServer() const;
00121
00122 public:
00123
00124 class RTSPClientSession {
00125 public:
00126 RTSPClientSession(RTSPServer& ourServer, unsigned sessionId,
00127 int clientSocket, struct sockaddr_in clientAddr);
00128 virtual ~RTSPClientSession();
00129 protected:
00130
00131 virtual void handleCmd_bad(char const* cseq);
00132 virtual void handleCmd_notSupported(char const* cseq);
00133 virtual void handleCmd_notFound(char const* cseq);
00134 virtual void handleCmd_unsupportedTransport(char const* cseq);
00135 virtual void handleCmd_OPTIONS(char const* cseq);
00136 virtual void handleCmd_DESCRIBE(char const* cseq,
00137 char const* urlPreSuffix, char const* urlSuffix,
00138 char const* fullRequestStr);
00139 virtual void handleCmd_SETUP(char const* cseq,
00140 char const* urlPreSuffix, char const* urlSuffix,
00141 char const* fullRequestStr);
00142 virtual void handleCmd_withinSession(char const* cmdName,
00143 char const* urlPreSuffix, char const* urlSuffix,
00144 char const* cseq, char const* fullRequestStr);
00145 virtual void handleCmd_TEARDOWN(ServerMediaSubsession* subsession,
00146 char const* cseq);
00147 virtual void handleCmd_PLAY(ServerMediaSubsession* subsession,
00148 char const* cseq, char const* fullRequestStr);
00149 virtual void handleCmd_PAUSE(ServerMediaSubsession* subsession,
00150 char const* cseq);
00151 virtual void handleCmd_GET_PARAMETER(ServerMediaSubsession* subsession,
00152 char const* cseq, char const* fullRequestStr);
00153 virtual void handleCmd_SET_PARAMETER(ServerMediaSubsession* subsession,
00154 char const* cseq, char const* fullRequestStr);
00155
00156 virtual Boolean parseHTTPRequestString(char* resultCmdName, unsigned resultCmdNameMaxSize,
00157 char* urlSuffix, unsigned urlSuffixMaxSize,
00158 char* sessionCookie, unsigned sessionCookieMaxSize,
00159 char* acceptStr, unsigned acceptStrMaxSize);
00160 virtual void handleHTTPCmd_notSupported();
00161 virtual void handleHTTPCmd_notFound();
00162 virtual void handleHTTPCmd_TunnelingGET(char const* sessionCookie);
00163 virtual Boolean handleHTTPCmd_TunnelingPOST(char const* sessionCookie, unsigned char const* extraData, unsigned extraDataSize);
00164 virtual void handleHTTPCmd_StreamingGET(char const* urlSuffix, char const* fullRequestStr);
00165 protected:
00166 UsageEnvironment& envir() { return fOurServer.envir(); }
00167 void closeSockets();
00168 void reclaimStreamStates();
00169 void resetRequestBuffer();
00170 Boolean authenticationOK(char const* cmdName, char const* cseq,
00171 char const* urlSuffix,
00172 char const* fullRequestStr);
00173 Boolean isMulticast() const { return fIsMulticast; }
00174 static void incomingRequestHandler(void*, int );
00175 void incomingRequestHandler1();
00176 static void handleAlternativeRequestByte(void*, u_int8_t requestByte);
00177 void handleAlternativeRequestByte1(u_int8_t requestByte);
00178 void handleRequestBytes(int newBytesRead);
00179 void noteLiveness();
00180 static void noteClientLiveness(RTSPClientSession* clientSession);
00181 static void livenessTimeoutTask(RTSPClientSession* clientSession);
00182 void changeClientInputSocket(int newSocketNum, unsigned char const* extraData, unsigned extraDataSize);
00183 protected:
00184 RTSPServer& fOurServer;
00185 unsigned fOurSessionId;
00186 ServerMediaSession* fOurServerMediaSession;
00187 int fClientInputSocket, fClientOutputSocket;
00188 struct sockaddr_in fClientAddr;
00189 char* fSessionCookie;
00190 TaskToken fLivenessCheckTask;
00191 unsigned char fRequestBuffer[RTSP_BUFFER_SIZE];
00192 unsigned fRequestBytesAlreadySeen, fRequestBufferBytesLeft;
00193 unsigned char* fLastCRLF;
00194 unsigned fBase64RemainderCount;
00195 unsigned char fResponseBuffer[RTSP_BUFFER_SIZE];
00196 Boolean fIsMulticast, fSessionIsActive, fStreamAfterSETUP;
00197 Authenticator fCurrentAuthenticator;
00198 unsigned char fTCPStreamIdCount;
00199 unsigned fNumStreamStates;
00200 struct streamState {
00201 ServerMediaSubsession* subsession;
00202 void* streamToken;
00203 } * fStreamStates;
00204 unsigned fRecursionCount;
00205 };
00206
00207 protected:
00208
00209
00210 virtual RTSPClientSession*
00211 createNewClientSession(unsigned sessionId, int clientSocket, struct sockaddr_in clientAddr);
00212
00213
00214 class ServerMediaSessionIterator {
00215 public:
00216 ServerMediaSessionIterator(RTSPServer& server);
00217 virtual ~ServerMediaSessionIterator();
00218 ServerMediaSession* next();
00219 private:
00220 HashTable::Iterator* fOurIterator;
00221 ServerMediaSession* fNextPtr;
00222 };
00223
00224 private:
00225 static void incomingConnectionHandlerRTSP(void*, int );
00226 void incomingConnectionHandlerRTSP1();
00227
00228 static void incomingConnectionHandlerHTTP(void*, int );
00229 void incomingConnectionHandlerHTTP1();
00230
00231 void incomingConnectionHandler(int serverSocket);
00232
00233 private:
00234 friend class RTSPClientSession;
00235 friend class ServerMediaSessionIterator;
00236 int fRTSPServerSocket;
00237 Port fRTSPServerPort;
00238 int fHTTPServerSocket;
00239 Port fHTTPServerPort;
00240 HashTable* fClientSessionsForHTTPTunneling;
00241 UserAuthenticationDatabase* fAuthDB;
00242 unsigned fReclamationTestSeconds;
00243 HashTable* fServerMediaSessions;
00244 };
00245
00246 #endif