bool InboundRTMPSDiscriminatorProtocol::BindSSL(IOBuffer &buffer) { //1. Create the RTMP protocol BaseProtocol *pRTMP = new InboundRTMPProtocol(); if (!pRTMP->Initialize(GetCustomParameters())) { FATAL("Unable to create RTMP protocol"); pRTMP->EnqueueForDelete(); return false; } //2. Destroy the link BaseProtocol *pFar = _pFarProtocol; pFar->ResetNearProtocol(); ResetFarProtocol(); //3. Create the new links pFar->SetNearProtocol(pRTMP); pRTMP->SetFarProtocol(pFar); //4. Set the application pRTMP->SetApplication(GetApplication()); //5. Enqueue for delete this protocol EnqueueForDelete(); //6. Process the data if (!pRTMP->SignalInputData(buffer)) { FATAL("Unable to process data"); pRTMP->EnqueueForDelete(); } return true; }
bool OutboundRTMPProtocol::PerformHandshake(IOBuffer &buffer) { switch (_rtmpState) { case RTMP_STATE_NOT_INITIALIZED: { _encrypted = (VariantType) _customParameters[CONF_PROTOCOL] == V_STRING && _customParameters[CONF_PROTOCOL] == CONF_PROTOCOL_OUTBOUND_RTMPE; _usedScheme = _encrypted ? 1 : 0; if ((VariantType) _customParameters[CONF_PROTOCOL] == V_STRING && _customParameters[CONF_PROTOCOL] == CONF_PROTOCOL_OUTBOUND_RTMPE) { return PerformHandshakeStage1(true); } else { return PerformHandshakeStage1(false); } } case RTMP_STATE_CLIENT_REQUEST_SENT: { if (GETAVAILABLEBYTESCOUNT(buffer) < 3073) return true; if (!PerformHandshakeStage2(buffer, _encrypted)) { FATAL("Unable to handshake"); return false; } if (_pFarProtocol != NULL) { if (!_pFarProtocol->EnqueueForOutbound()) { FATAL("Unable to signal output data"); return false; } } if (_pKeyIn != NULL && _pKeyOut != NULL) { //insert the RTMPE protocol in the current protocol stack BaseProtocol *pFarProtocol = GetFarProtocol(); RTMPEProtocol *pRTMPE = new RTMPEProtocol(_pKeyIn, _pKeyOut, GETAVAILABLEBYTESCOUNT(_outputBuffer)); ResetFarProtocol(); pFarProtocol->SetNearProtocol(pRTMPE); pRTMPE->SetNearProtocol(this); //FINEST("New protocol chain: %s", STR(*pFarProtocol)); } if (!buffer.Ignore(3073)) { FATAL("Unable to ignore 3073 bytes"); return false; } _handshakeCompleted = true; return true; } default: { FATAL("Invalid RTMP state: %d", _rtmpState); return false; } } }
bool InboundRTMPProtocol::PerformHandshake(IOBuffer &buffer) { switch (_rtmpState) { case RTMP_STATE_NOT_INITIALIZED: { if (GETAVAILABLEBYTESCOUNT(buffer) < 1537) { return true; } uint8_t handshakeType = GETIBPOINTER(buffer)[0]; if (!buffer.Ignore(1)) { FATAL("Unable to ignore one byte"); return false; } _currentFPVersion = ENTOHLP(GETIBPOINTER(buffer) + 4); switch (handshakeType) { case 3: //plain { return PerformHandshake(buffer, false); } case 6: //encrypted { return PerformHandshake(buffer, true); } default: { FATAL("Handshake type not implemented: %hhu", handshakeType); return false; } } } case RTMP_STATE_SERVER_RESPONSE_SENT: { if (GETAVAILABLEBYTESCOUNT(buffer) < 1536) { return true; } else { //ignore the client's last handshake part if (!buffer.Ignore(1536)) { FATAL("Unable to ignore inbound data"); return false; } _handshakeCompleted = true; _rtmpState = RTMP_STATE_DONE; if (_pKeyIn != NULL && _pKeyOut != NULL) { //insert the RTMPE protocol in the current protocol stack BaseProtocol *pFarProtocol = GetFarProtocol(); RTMPEProtocol *pRTMPE = new RTMPEProtocol(_pKeyIn, _pKeyOut); ResetFarProtocol(); pFarProtocol->SetNearProtocol(pRTMPE); pRTMPE->SetNearProtocol(this); FINEST("New protocol chain: %s", STR(*pFarProtocol)); //decrypt the leftovers RC4(_pKeyIn, GETAVAILABLEBYTESCOUNT(buffer), GETIBPOINTER(buffer), GETIBPOINTER(buffer)); } return true; } } default: { FATAL("Invalid RTMP state: %d", _rtmpState); return false; } } }