Bool16 RTPSessionOutput::IsUDP() { if (fTransportInitialized) return fIsUDP; QTSS_RTPSessionState* theState = NULL; UInt32 theLen = 0; (void)QTSS_GetValuePtr(fClientSession, qtssCliSesState, 0, (void**)&theState, &theLen); if (*theState != qtssPlayingState) return true; QTSS_RTPStreamObject *theStreamPtr = NULL; QTSS_RTPTransportType *theTransportTypePtr = NULL; for (SInt16 z = 0; QTSS_GetValuePtr(fClientSession, qtssCliSesStreamObjects, z, (void**)&theStreamPtr, &theLen) == QTSS_NoErr; z++) { (void) QTSS_GetValuePtr(*theStreamPtr, qtssRTPStrTransportType, 0, (void**) &theTransportTypePtr, &theLen); if (theTransportTypePtr && *theTransportTypePtr == qtssRTPTransportTypeUDP) { fIsUDP = true; break; // treat entire session UDP } else { fIsUDP = false; } } //if (fIsUDP) printf("RTPSessionOutput::RTPSessionOutput Standard UDP client\n"); //else printf("RTPSessionOutput::RTPSessionOutput Buffered Client\n"); fTransportInitialized = true; return fIsUDP; }
Bool16 RTPSessionOutput::PacketAlreadySent(QTSS_RTPStreamObject *theStreamPtr, UInt32 inFlags, UInt64* packetIDPtr) { Assert(theStreamPtr); Assert(packetIDPtr); UInt32 theLen = 0; UInt64 *lastPacketIDPtr = NULL; Bool16 packetSent = false; if (inFlags & qtssWriteFlagsIsRTP) { if ( (QTSS_NoErr == QTSS_GetValuePtr(*theStreamPtr, sLastRTPPacketIDAttr, 0, (void**)&lastPacketIDPtr, &theLen)) && (*packetIDPtr <= *lastPacketIDPtr) ) { //printf("RTPSessionOutput::WritePacket Don't send RTP packet id =%qu\n", *packetIDPtr); packetSent = true; } } else if (inFlags & qtssWriteFlagsIsRTCP) { if ( QTSS_NoErr == QTSS_GetValuePtr(*theStreamPtr, sLastRTCPPacketIDAttr, 0, (void**)&lastPacketIDPtr, &theLen) && (*packetIDPtr <= *lastPacketIDPtr) ) { //printf("RTPSessionOutput::WritePacket Don't send RTCP packet id =%qu last packet sent id =%qu\n", *packetIDPtr,*lastPacketIDPtr); packetSent = true; } } return packetSent; }
char* QTSSModuleUtils::GetFullPath( QTSS_RTSPRequestObject inRequest, QTSS_AttributeID whichFileType, UInt32* outLen, StrPtrLen* suffix) { Assert(outLen != NULL); (void)QTSS_LockObject(inRequest); // Get the proper file path attribute. This may return an error if // the file type is qtssFilePathTrunc attr, because there may be no path // once its truncated. That's ok. In that case, we just won't append a path. StrPtrLen theFilePath; (void)QTSS_GetValuePtr(inRequest, whichFileType, 0, (void**)(void*)&theFilePath.Ptr, &theFilePath.Len); StrPtrLen theRootDir; QTSS_Error theErr = QTSS_GetValuePtr(inRequest, qtssRTSPReqRootDir, 0, (void**)(void*)&theRootDir.Ptr, &theRootDir.Len); Assert(theErr == QTSS_NoErr); //trim off extra / characters before concatenating // so root/ + /path instead of becoming root//path is now root/path as it should be. if (theRootDir.Len && theRootDir.Ptr[theRootDir.Len -1] == kPathDelimiterChar && theFilePath.Len && theFilePath.Ptr[0] == kPathDelimiterChar) { char *thePathEnd = &(theFilePath.Ptr[theFilePath.Len]); while (theFilePath.Ptr != thePathEnd) { if (*theFilePath.Ptr != kPathDelimiterChar) break; theFilePath.Ptr ++; theFilePath.Len --; } } //construct a full path out of the root dir path for this request, //and the url path. *outLen = theFilePath.Len + theRootDir.Len + 2; if (suffix != NULL) *outLen += suffix->Len; char* theFullPath = NEW char[*outLen]; //write all the pieces of the path into this new buffer. StringFormatter thePathFormatter(theFullPath, *outLen); thePathFormatter.Put(theRootDir); thePathFormatter.Put(theFilePath); if (suffix != NULL) thePathFormatter.Put(*suffix); thePathFormatter.PutTerminator(); *outLen = *outLen - 2; (void)QTSS_UnlockObject(inRequest); return theFullPath; }
QTSS_Error Authorize(QTSS_StandardRTSP_Params* inParams) { static Bool16 sTrue = true; Bool16* isFirstRequest = NULL; UInt32* theIPAddr = NULL; UInt32 theLen = 0; // Only do anything if this is the first request (void)QTSS_GetValuePtr(inParams->inRTSPSession, sIsFirstRequestAttr, 0, (void**)&isFirstRequest, &theLen); if (isFirstRequest != NULL) return QTSS_NoErr; // Get the IP address of this client. (void)QTSS_GetValuePtr(inParams->inRTSPSession, qtssRTSPSesRemoteAddr, 0, (void**)&theIPAddr, &theLen); if ((theIPAddr == NULL) || (theLen != sizeof(UInt32))) { Assert(0); return QTSS_NoErr; } IPAddrTableKey theKey(*theIPAddr); // This must be atomic OSMutexLocker locker(sMutex); // Check to see if this client currently has a connection open. IPAddrTableElem* theElem = sHashTable->Map(&theKey); if (theElem == NULL) { // Client doesn't have a connetion open currently. Create a map element, // and add it into the map. theElem = NEW IPAddrTableElem(*theIPAddr); sHashTable->Add(theElem); } // Check to see if this client has too many connections open. If it does, // return an error, otherwise, allow the connection and increment the // refcount. if (theElem->GetRefCount() >= sNumConnsPerIP) return QTSSModuleUtils::SendErrorResponse(inParams->inRTSPRequest, qtssClientForbidden, sTooManyConnectionsErr); else theElem->IncrementRefCount(); // Mark the request so we'll know subsequent ones aren't the first. // Note that we only do this if we've successfully added this client to our map. // That way, we only remove it in SessionClosing if we've added it. (void)QTSS_SetValue(inParams->inRTSPSession, sIsFirstRequestAttr, 0, &sTrue, sizeof(sTrue)); return QTSS_NoErr; }
QTSS_Error ProcessRTSPRequest(QTSS_StandardRTSP_Params* inParams) { QTSS_RTSPMethod* theMethod = NULL; UInt32 theMethodLen = 0; if ((QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqMethod, 0, (void**)&theMethod, &theMethodLen) != QTSS_NoErr) || (theMethodLen != sizeof(QTSS_RTSPMethod))) { Assert(0); return QTSS_RequestFailed; } switch (*theMethod) { case qtssDescribeMethod: return DoDescribe(inParams); case qtssSetupMethod: return DoSetup(inParams); case qtssPlayMethod: return DoPlay(inParams); case qtssTeardownMethod: // Tell the server that this session should be killed, and send a TEARDOWN response (void)QTSS_Teardown(inParams->inClientSession); (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0); break; case qtssPauseMethod: (void)QTSS_Pause(inParams->inClientSession); (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0); break; default: break; } return QTSS_NoErr; }
Bool16 RTPSessionOutput::FilterPacket(QTSS_RTPStreamObject *theStreamPtr, StrPtrLen* inPacket) { UInt32* packetCountPtr = NULL; UInt32 theLen = 0; //see if we started sending and if so then just keep sending (reset on a play) QTSS_Error writeErr = QTSS_GetValuePtr(*theStreamPtr, sStreamPacketCountAttr, 0,(void**) &packetCountPtr,&theLen); if (writeErr == QTSS_NoErr && theLen > 0 && *packetCountPtr > 0) return false; Assert(theStreamPtr); Assert(inPacket); UInt16 seqnum = this->GetPacketSeqNumber(inPacket); UInt16 firstSeqNum = 0; theLen = sizeof(firstSeqNum); if ( QTSS_NoErr != QTSS_GetValue(*theStreamPtr, qtssRTPStrFirstSeqNumber, 0, &firstSeqNum, &theLen) ) return true; if ( seqnum < firstSeqNum ) { //printf("RTPSessionOutput::FilterPacket don't send packet = %u < first=%lu\n", seqnum, firstSeqNum); return true; } //printf("RTPSessionOutput::FilterPacket found first packet = %u \n", firstSeqNum); fPreFilter = false; return fPreFilter; }
Bool16 SessionListElement::Equal(QTSS_ClientSessionObject* inSessionPtr) { UInt32 *theSessionID = 0; UInt32 *inSessionID = 0; UInt32 theLen = 0; (void)QTSS_GetValuePtr(fSession, qtssCliSesCounterID, 0, (void **)&theSessionID, &theLen); Assert(theLen != 0); (void)QTSS_GetValuePtr(*inSessionPtr, qtssCliSesCounterID, 0, (void **)&inSessionID, &theLen); Assert(theLen != 0); if (*theSessionID == *inSessionID) return true; return false; }
Bool16 IsAuthentic(QTSS_Filter_Params* inParams,StringParser *fullRequestPtr) { Bool16 isAuthentic = false; if (!sAuthenticationEnabled) // no authentication { isAuthentic = true; } else // must authenticate { StrPtrLen theClientIPAddressStr; (void) QTSS_GetValuePtr(inParams->inRTSPSession, qtssRTSPSesRemoteAddrStr, 0, (void**)&theClientIPAddressStr.Ptr, &theClientIPAddressStr.Len); Bool16 isLocal = IPComponentStr(&theClientIPAddressStr).IsLocal(); StrPtrLen authenticateName; StrPtrLen authenticatePassword; StrPtrLen authType; Bool16 hasAuthentication = HasAuthentication(fullRequestPtr,&authenticateName,&authenticatePassword, &authType); if (hasAuthentication) { if (authType.Equal(sAuthRef)) { if (isLocal) isAuthentic = OSXAuthenticate(&authenticatePassword); } else isAuthentic = Authenticate(inParams->inRTSPRequest, &authenticateName,&authenticatePassword); } } // if (isAuthentic) // isAuthentic = AuthorizeAdminRequest(inParams->inRTSPRequest); (void) QTSS_SetValue(inParams->inRTSPRequest, sAuthenticatedID, 0, (void*)&isAuthentic, sizeof(isAuthentic)); return isAuthentic; }
/** * For the given RTSP session, will return true if the client is already flagged * as authenticated, false if they arent. if the value is not initialized, this * method will intitialize it. This is used to ensure a session is only authenticated * once. */ static Bool16 IsRTSPSessionAuthenticated(QTSS_RTSPSessionObject* theRTSPSession) { printf("QTSSIcecastAuthModule::IsRTSPSessionAuthenticated method start\n"); Bool16* alreadyAuthenticated = false; UInt32 theLen = 0; QTSS_Error getAlreadyAuthError = QTSS_GetValuePtr(*theRTSPSession, attrRtspSessionAuthenticated, 0, (void**)&alreadyAuthenticated, &theLen); //printf("QTSSIcecastAuthModule::IsRTSPSessionAuthenticated read value of already aythenticated: &i\n", alreadyAuthenticated); if (getAlreadyAuthError == QTSS_ValueNotFound) { // the value hasn't been set yet. initialize it to false, and return false. // TODO - check how to set a default variable (if possible), so we don't have to rely on this. Bool16 authenticated = false; (void)QTSS_SetValue(*theRTSPSession, attrRtspSessionAuthenticated, 0, &authenticated, sizeof(authenticated)); // we had to initialize, so def. not logged in return false; } else if (*alreadyAuthenticated) { // we are already logged in printf("QTSSIcecastAuthModule::IsRTSPSessionAuthenticated session already authenticated\n"); return true; } else if (!*alreadyAuthenticated && getAlreadyAuthError == QTSS_NoErr) { // we are not authed and there was no error, to return return false; } else { //printf("QTSSIcecastAuthModule::RTSPFilter ERROR while looking up not logged in\n"); PrintQTSSError("QTSSIcecastAuthModule::IsRTSPSessionAuthenticated", "while looking up not logged in", getAlreadyAuthError); return false; } }
QTSS_Error ProcessRTSPRequest(QTSS_StandardRTSP_Params* inParams) { QTSS_RTSPMethod* theMethod = NULL; UInt32 theLen = 0; if ((QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqMethod, 0, (void**)&theMethod, &theLen) != QTSS_NoErr) || (theLen != sizeof(QTSS_RTSPMethod))) { Assert(0); return QTSS_RequestFailed; } if (*theMethod == qtssDescribeMethod) return DoDescribe(inParams); if (*theMethod == qtssSetupMethod) return DoSetup(inParams); RTPSessionOutput** theOutput = NULL; QTSS_Error theErr = QTSS_GetValuePtr(inParams->inClientSession, sOutputAttr, 0, (void**)&theOutput, &theLen); if ((theErr != QTSS_NoErr) || (theLen != sizeof(RTPSessionOutput*))) // a broadcaster push session { if (*theMethod == qtssPlayMethod || *theMethod == qtssRecordMethod) return DoPlay(inParams, NULL); else return QTSS_RequestFailed; } switch (*theMethod) { case qtssPlayMethod: return DoPlay(inParams, (*theOutput)->GetReflectorSession()); case qtssTeardownMethod: // Tell the server that this session should be killed, and send a TEARDOWN response (void)QTSS_Teardown(inParams->inClientSession); (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0); break; case qtssPauseMethod: (void)QTSS_Pause(inParams->inClientSession); (void)QTSS_SendStandardRTSPResponse(inParams->inRTSPRequest, inParams->inClientSession, 0); break; default: break; } return QTSS_NoErr; }
kern_return_t GetServerName(QTSServerDNSName* outServerName) { StrPtrLen theDNSName; (void)QTSS_GetValuePtr(sServer, qtssSvrDefaultDNSName, 0, (void**)&theDNSName.Ptr, &theDNSName.Len); if (theDNSName.Ptr != NULL) ::strncpy(outServerName->dnsName, theDNSName.Ptr, kDNSNameSize); outServerName->dnsName[kDNSNameSize-1] = '\0'; return SCNoError; }
UInt32 SessionListElement::CurrentBitRate() { UInt32 *theBitRate = 0; UInt32 theLen = 0; (void)QTSS_GetValuePtr(fSession, qtssCliSesCurrentBitRate, 0, (void **)&theBitRate, &theLen); Assert(theLen != 0); return *theBitRate; }
QTSS_Error SessionClosing(QTSS_RTSPSession_Params* inParams) { UInt32* theIPAddr = NULL; Bool16* isFirstRequest = NULL; UInt32 theLen = 0; // Only remove this session from the map if it has been added in the first place (void)QTSS_GetValuePtr(inParams->inRTSPSession, sIsFirstRequestAttr, 0, (void**)&isFirstRequest, &theLen); if (isFirstRequest == NULL) return QTSS_NoErr; // Get the IP address of this client. (void)QTSS_GetValuePtr(inParams->inRTSPSession, qtssRTSPSesRemoteAddr, 0, (void**)&theIPAddr, &theLen); if ((theIPAddr == NULL) || (theLen != sizeof(UInt32))) { Assert(0); return QTSS_NoErr; } IPAddrTableKey theKey(*theIPAddr); // This must be atomic OSMutexLocker locker(sMutex); // Check to see if this client currently has a connection open. IPAddrTableElem* theElem = sHashTable->Map(&theKey); if (theElem == NULL) return QTSS_NoErr; //this may happen if there is another module denying connections // Decrement the refcount if (theElem->GetRefCount() > 0) theElem->DecrementRefCount(); // If the refcount is 0, remove this from the map, and delete it. if (theElem->GetRefCount() == 0) { sHashTable->Remove(theElem); delete theElem; } return QTSS_NoErr; }
QTSS_Error DestroySession(QTSS_ClientSessionClosing_Params* inParams) { FileSession** theFile = NULL; UInt32 theLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inParams->inClientSession, sFileSessionAttr, 0, (void**)&theFile, &theLen); if ((theErr != QTSS_NoErr) || (theLen != sizeof(FileSession*)) || (theFile == NULL)) return QTSS_RequestFailed; delete *theFile; return QTSS_NoErr; }
QTSS_Error AdviseFile(QTSS_AdviseFile_Params* inParams) { OSFileSource** theFile = NULL; UInt32 theLen = 0; (void)QTSS_GetValuePtr(inParams->inFileObject, sOSFileSourceAttr, 0, (void**)&theFile, &theLen); Assert(theLen == sizeof(OSFileSource*)); (*theFile)->Advise(inParams->inPosition, inParams->inSize); return QTSS_NoErr; }
time_t QTSSAccessLog::WriteLogHeader(FILE *inFile) { time_t calendarTime = QTSSRollingLog::WriteLogHeader(inFile); //format a date for the startup time char theDateBuffer[QTSSRollingLog::kMaxDateBufferSizeInBytes] = { 0 }; bool result = QTSSRollingLog::FormatDate(theDateBuffer, false); char tempBuffer[1024] = { 0 }; if (result) { StrPtrLen serverName; (void)QTSS_GetValuePtr(sServer, qtssSvrServerName, 0, (void**)&serverName.Ptr, &serverName.Len); StrPtrLen serverVersion; (void)QTSS_GetValuePtr(sServer, qtssSvrServerVersion, 0, (void**)&serverVersion.Ptr, &serverVersion.Len); qtss_sprintf(tempBuffer, sLogHeader, serverName.Ptr, serverVersion.Ptr, theDateBuffer, sLogTimeInGMT ? "GMT" : "local time"); this->WriteToLog(tempBuffer, !kAllowLogToRoll); } return calendarTime; }
void RTPSessionOutput::InitializeStreams() { UInt32 theLen = 0; QTSS_RTPStreamObject* theStreamPtr = NULL; UInt32 packetCountInitValue = 0; for (SInt16 z = 0; QTSS_GetValuePtr(fClientSession, qtssCliSesStreamObjects, z, (void**)&theStreamPtr, &theLen) == QTSS_NoErr; z++) { (void) QTSS_SetValue(*theStreamPtr, sStreamPacketCountAttr, 0, &packetCountInitValue, sizeof(UInt32)); } }
QTSS_Error CloseFile(QTSS_CloseFile_Params* inParams) { OSFileSource** theFile = NULL; EventContext** theContext = NULL; UInt32 theLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inParams->inFileObject, sOSFileSourceAttr, 0, (void**)&theFile, &theLen); Assert(theErr == QTSS_NoErr); theErr = QTSS_GetValuePtr(inParams->inFileObject, sEventContextAttr, 0, (void**)&theContext, &theLen); if (theErr == QTSS_NoErr) { // // If this file was opened up in async mode, there is an EventContext associated with it. // We should first make sure that the OSFileSource destructor doesn't close the FD // (the EventContext will do it), then close the EventContext (*theFile)->ResetFD(); delete *theContext; } delete *theFile; return QTSS_NoErr; }
void QTSSModuleUtils::LogError( QTSS_ErrorVerbosity inVerbosity, QTSS_AttributeID inTextMessage, UInt32 /*inErrNumber*/, char* inArgument, char* inArg2) { static char* sEmptyArg = ""; if (sMessages == NULL) return; // Retrieve the specified text message from the text messages dictionary. StrPtrLen theMessage; (void)QTSS_GetValuePtr(sMessages, inTextMessage, 0, (void**)(void*)&theMessage.Ptr, &theMessage.Len); if ((theMessage.Ptr == NULL) || (theMessage.Len == 0)) (void)QTSS_GetValuePtr(sMessages, qtssMsgNoMessage, 0, (void**)(void*)&theMessage.Ptr, &theMessage.Len); if ((theMessage.Ptr == NULL) || (theMessage.Len == 0)) return; // qtss_sprintf and ::strlen will crash if inArgument is NULL if (inArgument == NULL) inArgument = sEmptyArg; if (inArg2 == NULL) inArg2 = sEmptyArg; // Create a new string, and put the argument into the new string. UInt32 theMessageLen = theMessage.Len + ::strlen(inArgument) + ::strlen(inArg2); OSCharArrayDeleter theLogString(NEW char[theMessageLen + 1]); qtss_sprintf(theLogString.GetObject(), theMessage.Ptr, inArgument, inArg2); Assert(theMessageLen >= ::strlen(theLogString.GetObject())); (void)QTSS_Write(sErrorLog, theLogString.GetObject(), ::strlen(theLogString.GetObject()), NULL, inVerbosity); }
Bool16 RTPSessionOutput::IsPlaying() { QTSS_RTPSessionState* theState = NULL; UInt32 theLen = 0; if (!fClientSession) return false; (void)QTSS_GetValuePtr(fClientSession, qtssCliSesState, 0, (void**)&theState, &theLen); if (theLen == 0 || theState == NULL || *theState != qtssPlayingState) return false; return true; }
void InitializeDictionaryItems(QTSS_RTPStreamObject inStream) { UInt32* theValue = NULL; UInt32 theValueLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inStream, sNumLossesAboveTolAttr, 0, (void**)&theValue, &theValueLen); if (theErr != QTSS_NoErr) { // The dictionary parameters haven't been initialized yet. Just set them all to 0. (void)QTSS_SetValue(inStream, sNumLossesAboveTolAttr, 0, &theValueLen, sizeof(theValueLen)); (void)QTSS_SetValue(inStream, sNumLossesBelowTolAttr, 0, &theValueLen, sizeof(theValueLen)); (void)QTSS_SetValue(inStream, sNumWorsesAttr, 0, &theValueLen, sizeof(theValueLen)); } }
QTSS_Error ReadFile(QTSS_ReadFile_Params* inParams) { OSFileSource** theFile = NULL; UInt32 theLen = 0; (void)QTSS_GetValuePtr(inParams->inFileObject, sOSFileSourceAttr, 0, (void**)&theFile, &theLen); Assert(theLen == sizeof(OSFileSource*)); OS_Error osErr = (*theFile)->Read(inParams->inFilePosition, inParams->ioBuffer, inParams->inBufLen, inParams->outLenRead); if (osErr == EAGAIN) return QTSS_WouldBlock; else if (osErr != OS_NoErr) return QTSS_RequestFailed; else return QTSS_NoErr; }
QTSS_Error ProcessRTSPRequest(QTSS_StandardRTSP_Params* inParams) { QTSS_RTSPMethod* theMethod = NULL; UInt32 theLen = 0; if ((QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqMethod, 0, (void**)&theMethod, &theLen) != QTSS_NoErr) || (theLen != sizeof(QTSS_RTSPMethod))) { Assert(0); return QTSS_RequestFailed; } if (*theMethod == qtssDescribeMethod) return DoDescribe(inParams); return QTSS_NoErr; }
QTSS_Error DestroySession(QTSS_ClientSessionClosing_Params* inParams) { RTPSessionOutput** theOutput = NULL; ReflectorOutput* outputPtr = NULL; ReflectorSession* theSession = NULL; //UInt32 theLen = sizeof(theSession); //QTSS_Error theErr = QTSS_GetValue(inParams->inClientSession, sClientBroadcastSessionAttr, 0, &theSession, &theLen); if (/*theSession != NULL && */false) { //ReflectorSession* deletedSession = NULL; //theErr = QTSS_SetValue(inParams->inClientSession, sClientBroadcastSessionAttr, 0, &deletedSession, sizeof(deletedSession)); //SourceInfo* theSoureInfo = theSession->GetSourceInfo(); //if (theSoureInfo == NULL) // return QTSS_NoErr; // //UInt32 numStreams = theSession->GetNumStreams(); //SourceInfo::StreamInfo* theStreamInfo = NULL; // //for (UInt32 index = 0; index < numStreams; index++) //{ theStreamInfo = theSoureInfo->GetStreamInfo(index); // if (theStreamInfo != NULL) // theStreamInfo->fSetupToReceive = false; //} //theSession->RemoveSessionFromOutput(inParams->inClientSession); //RemoveOutput(NULL, theSession, 1); } else { UInt32 theLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inParams->inClientSession, sOutputAttr, 0, (void**)&theOutput, &theLen); if ((theErr != QTSS_NoErr) || (theLen != sizeof(RTPSessionOutput*)) || (theOutput == NULL)) return QTSS_RequestFailed; theSession = (*theOutput)->GetReflectorSession(); if (theOutput != NULL) outputPtr = (ReflectorOutput*) *theOutput; if (outputPtr != NULL) RemoveOutput(outputPtr, theSession, false); } return QTSS_NoErr; }
static void CallEndSession(QTSS_ClientSessionObject* theClientSession) { // action=listener_remove&server=myserver.com&port=8000&client=1&mount=/live&user=&pass=&duration=3600 // the duration SInt64* connectedTime = NULL; UInt32 connectedTimeLen = sizeof(connectedTime); (void)QTSS_GetValuePtr(*theClientSession, qtssCliSesTimeConnectedInMsec, 0, (void**)&connectedTime, &connectedTimeLen); qtss_printf("QTSSIcecastAuthModule::CallEndSession connected time in seconds %li\n", (*connectedTime / 1000)); long duration = (long)*connectedTime / 1000; // the mount point char mountPoint[128] = {0}; StrPtrLen mountPointStr(mountPoint,sizeof(mountPoint)); (void)QTSS_GetValue(*theClientSession, attrClientSessionMountPoint, 0, (void*)mountPointStr.Ptr, &mountPointStr.Len); printf("QTSSIcecastAuthModule::CallEndSession: mount point: %s\n", mountPoint); // TODO - we don't use this data on the remote end (yet), but implement - will probably need to copy // credentials into the client session from the RTSP session (annoying, but both aren't visible at all times) // // username and password // char* username = NULL; // (void)QTSS_GetValueAsString(theRTSPSession, attrRtspSessionProvidedUsername, 0, &username); // printf("QTSSIcecastAuthModule::CallEndSession: Provided username extracted from client session: %s\n", username); // // char* password = NULL; // (void)QTSS_GetValueAsString(theRTSPSession, attrRtspSessionProvidedPassword, 0, &password); // printf("QTSSIcecastAuthModule::CallEndSession: Provided password extracted from client session: %s\n", password); // ice session id char* iceSessID = NULL; QTSS_Error getSessErr = QTSS_GetValueAsString(*theClientSession, attrClientSessionFullSessionID, 0, &iceSessID); char postdata[512]; qtss_sprintf(postdata, "action=listener_remove&server=%s&port=554&client=%s&mount=%s&user=%s&pass=%s&duration=%li", hostname, iceSessID, mountPoint, "", "", duration); printf("QTSSIcecastAuthModule::CallAuthorizeSession: generated postdata: %s\n", postdata); printf("QTSSIcecastAuthModule::CallAuthorizeSession: i would post this to: %s\n", sEndSessionEndpoint); }
QTSS_Error PostProcess(QTSS_StandardRTSP_Params* inParams) { static UInt32 sZero = 0; UInt32* theStatus = NULL; UInt32 theLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqRealStatusCode, 0, (void**)&theStatus, &theLen); if (theErr != QTSS_NoErr) return theErr; QTSS_CliSesClosingReason theReason = qtssCliSesCloseClientTeardown; if ((*theStatus == 401) || (*theStatus == 403)) { LogRequest(inParams->inClientSession, NULL, &theReason); (void)QTSS_SetValue(inParams->inClientSession, sLoggedAuthorizationAttrID, 0, theStatus, sizeof(*theStatus)); } else (void)QTSS_SetValue(inParams->inClientSession, sLoggedAuthorizationAttrID, 0, &sZero, sizeof(sZero)); return theErr; }
/** * For the given RTSP request, check to see if we can bypass authentication - * currently filters for OPTIONS / request (these return no music to the listener, * so don't need to be authenticated - and at least the S60 RealPlayer sends this * request for / - so we need to let it through, and authenticate when it actually * requests a stream */ static Bool16 IsRequestMethodBypassable(QTSS_RTSPRequestObject* theRTSPRequest) { QTSS_RTSPMethod* theMethod = NULL; UInt32 theLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(*theRTSPRequest, qtssRTSPReqMethod, 0, (void**)&theMethod, &theLen); if ((theErr != QTSS_NoErr) || (theLen != sizeof(QTSS_RTSPMethod))) { return false; // an error occured, dont allow bypass } else { qtss_printf("QTSSIcecastAuthModule::IsRequestMethodBypassable the method is %i\n", *theMethod); if (*theMethod == qtssOptionsMethod) { // we can bypass this one return true; } else { // cant bypass return false; } } }
QTSS_Error RequestEventFile(QTSS_RequestEventFile_Params* inParams) { QTSS_ModuleState* theState = (QTSS_ModuleState*)OSThread::GetMainThreadData(); if (OSThread::GetCurrent() != NULL) theState = (QTSS_ModuleState*)OSThread::GetCurrent()->GetThreadData(); Assert(theState->curTask != NULL); EventContext** theContext = NULL; UInt32 theLen = 0; QTSS_Error theErr = QTSS_GetValuePtr(inParams->inFileObject, sEventContextAttr, 0, (void**)&theContext, &theLen); if (theErr == QTSS_NoErr) { // // This call only works if the file is async! (*theContext)->SetTask(theState->curTask); (*theContext)->RequestEvent(); return QTSS_NoErr; } return QTSS_RequestFailed; }
kern_return_t GetServerVersion(QTSServerVersionRec* outServerVersion) { Assert(outServerVersion != NULL); outServerVersion->serverVersion = 0x00000000; outServerVersion->serverControlAPIVersion = 0x00000000; StrPtrLen theServerVersion; (void)QTSS_GetValuePtr(sServer, qtssSvrServerVersion, 0, (void**)&theServerVersion.Ptr, &theServerVersion.Len); Assert(theServerVersion.Ptr != NULL); Assert(theServerVersion.Len > 0); if ((theServerVersion.Ptr != NULL) && (theServerVersion.Len > 0)) { // // Convert the server version string to a long. Look for and extract major, minor, very minor // revision number StringParser theVersionParser(&theServerVersion); outServerVersion->serverVersion = theVersionParser.ConsumeInteger(NULL); outServerVersion->serverVersion <<= 8; theVersionParser.ConsumeUntil(NULL, StringParser::sDigitMask); outServerVersion->serverVersion += theVersionParser.ConsumeInteger(NULL); outServerVersion->serverVersion <<= 8; theVersionParser.ConsumeUntil(NULL, StringParser::sDigitMask); outServerVersion->serverVersion += theVersionParser.ConsumeInteger(NULL); } // Get the API version out of the server as well UInt32 theVersionLen = sizeof(outServerVersion->serverControlAPIVersion); (void)QTSS_GetValue(sServer, qtssServerAPIVersion, 0, &outServerVersion->serverControlAPIVersion, &theVersionLen); return SCNoError; }
QTSS_ModulePrefsObject QTSSModuleUtils::GetModuleObjectByName(const StrPtrLen& inModuleName) { QTSS_ModuleObject theModule = NULL; UInt32 theLen = sizeof(theModule); for (int x = 0; QTSS_GetValue(sServer, qtssSvrModuleObjects, x, &theModule, &theLen) == QTSS_NoErr; x++) { Assert(theModule != NULL); Assert(theLen == sizeof(theModule)); StrPtrLen theName; QTSS_Error theErr = QTSS_GetValuePtr(theModule, qtssModName, 0, (void**)(void*)&theName.Ptr, &theName.Len); Assert(theErr == QTSS_NoErr); if (inModuleName.Equal(theName)) return theModule; #if DEBUG theModule = NULL; theLen = sizeof(theModule); #endif } return NULL; }