diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp index 1a2c14ff79fa740e01e4853b410ce5bb7bf1e1a0..d9f88f1b55a5dbdcbd7d7c9fcf35a7aa5fda20e8 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.cpp @@ -190,6 +190,29 @@ void AudioRtpFactory::stop (void) } } +void AudioRtpFactory::updateDestinationIpAddress (void) +{ + _debug ("Updating IP address"); + if (_rtpSession == NULL) { + throw AudioRtpFactoryException ("_rtpSession was null when trying to update IP address"); + } + + switch (_rtpSessionType) { + + case Sdes: + static_cast<AudioSrtpSession *> (_rtpSession)->updateDestinationIpAddress(); + break; + + case Symmetric: + static_cast<AudioSymmetricRtpSession *> (_rtpSession)->updateDestinationIpAddress(); + break; + + case Zrtp: + static_cast<AudioZrtpSession *> (_rtpSession)->updateDestinationIpAddress(); + break; + } +} + sfl::AudioZrtpSession * AudioRtpFactory::getAudioZrtpSession() { if ( (_rtpSessionType == Zrtp) && (_rtpSessionType != NULL)) { diff --git a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h index 401087fbfb64e149b6be65ae641fa2873bb42219..664bf3ae2cda5b2ae39804f6bfbcfc7b757413a7 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpFactory.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpFactory.h @@ -82,6 +82,12 @@ namespace sfl { * @param None */ void stop(); + + /** + * Update current RTP destination address with one stored in call + * @param None + */ + void updateDestinationIpAddress (void); /** * @param None diff --git a/sflphone-common/src/audio/audiortp/AudioRtpSession.h b/sflphone-common/src/audio/audiortp/AudioRtpSession.h index e1d8b536cb87083deb612096b4f2ab2e4d0c1442..d168cb8d750fef943960ef2e3b1c7999002a4bc3 100644 --- a/sflphone-common/src/audio/audiortp/AudioRtpSession.h +++ b/sflphone-common/src/audio/audiortp/AudioRtpSession.h @@ -66,7 +66,12 @@ namespace sfl { virtual void run (); int startRtpThread(); - + + /** + * Used mostly when receiving a reinvite + */ + void updateDestinationIpAddress(void); + private: void initBuffers(void); @@ -98,6 +103,16 @@ namespace sfl { // it amounts to the same as doing // start() with no semaphore at all. ost::Semaphore * _mainloopSemaphore; + + // Main destination address for this rtp session. + // Stored in case or reINVITE, which may require to forget + // this destination and update a new one. + ost::InetHostAddress _remote_ip; + + // Main destination port for this rtp session. + // Stored in case reINVITE, which may require to forget + // this destination and update a new one + unsigned short _remote_port; AudioCodec * _audiocodec; @@ -292,20 +307,36 @@ namespace sfl { } _debug ("Setting IP address for the RTP session\n"); - - ost::InetHostAddress remote_ip (_ca->getLocalSDP()->get_remote_ip().c_str()); + + // Store remote ip in case we would need to forget current destination + _remote_ip = ost::InetHostAddress(_ca->getLocalSDP()->get_remote_ip().c_str()); _debug ("Init audio RTP session: remote ip %s\n", _ca->getLocalSDP()->get_remote_ip().data()); - if (!remote_ip) { + if (!_remote_ip) { _debug ("Target IP address [%s] is not correct!\n", _ca->getLocalSDP()->get_remote_ip().data()); return; } - if (! static_cast<D*>(this)->addDestination (remote_ip, (unsigned short) _ca->getLocalSDP()->get_remote_audio_port())) { + // Store remote port in case we would need to forget current destination + _remote_port = (unsigned short) _ca->getLocalSDP()->get_remote_audio_port(); + + if (! static_cast<D*>(this)->addDestination (_remote_ip, _remote_port)) { _debug ("Can't add destination to session!\n"); return; } } + + template <typename D> + void AudioRtpSession<D>::updateDestinationIpAddress(void) + { + // Destination address are stored in a list in ccrtp + // This method clear off this entry + static_cast<D*>(this)->forgetDestination(_remote_ip, _remote_port); + + // new destination is stored in call + // we just need to recall this method + setDestinationIpAddress(); + } template <typename D> int AudioRtpSession<D>::processDataEncode(void) diff --git a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp index 6411b39531661ad5c0cb4ac880fa2d40eee4f95b..e1579e7f3120af2c258933e9992b15e932fdc52a 100644 --- a/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp +++ b/sflphone-common/src/audio/audiortp/AudioSrtpSession.cpp @@ -47,15 +47,15 @@ AudioSrtpSession::AudioSrtpSession (ManagerImpl * manager, SIPCall * sipcall) : ost::SymmetricRTPSession (ost::InetHostAddress (sipcall->getLocalIp().c_str()), sipcall->getLocalAudioPort()), AudioRtpSession<AudioSrtpSession> (manager, sipcall) { - _debug ("***************** Initialize AudioSrtpSession *********************"); + + // Initialize local Crypto context initializeLocalMasterKey(); initializeLocalMasterSalt(); - // initializeRemoteCryptoContext(); initializeLocalCryptoContext(); + // Set local crypto context in ccrtp _localCryptoCtx->deriveSrtpKeys(0); - // setInQueueCryptoContext(_remoteCryptoCtx); setOutQueueCryptoContext(_localCryptoCtx); } @@ -76,6 +76,7 @@ std::string AudioSrtpSession::getLocalCryptoInfo() { srtp_keys += getBase64ConcatenatedKeys(); srtp_keys.append("|2^20|1:32"); + // generate crypto attribute std::string crypto = tag.append(" "); crypto += crypto_suite.append(" "); crypto += srtp_keys; @@ -105,8 +106,10 @@ void AudioSrtpSession::initializeLocalMasterKey(void) // @TODO key may have different length depending on cipher suite _localMasterKeyLength = 16; + // Allocate memory for key unsigned char *random_key = new unsigned char[_localMasterKeyLength]; + // Generate ryptographically strong pseudo-random bytes int err; if((err = RAND_bytes(random_key, _localMasterKeyLength)) != 1) _debug("Error occured while generating cryptographically strong pseudo-random key"); @@ -129,20 +132,16 @@ void AudioSrtpSession::initializeLocalMasterSalt(void) // @TODO key may have different length depending on cipher suite _localMasterSaltLength = 14; + // Allocate memory for key unsigned char *random_key = new unsigned char[_localMasterSaltLength]; + // Generate ryptographically strong pseudo-random bytes int err; if((err = RAND_bytes(random_key, _localMasterSaltLength)) != 1) _debug("Error occured while generating cryptographically strong pseudo-random key"); memcpy(_localMasterSalt, random_key, _localMasterSaltLength); - printf("Local Salt: "); - for(int i = 0; i < _localMasterSaltLength; i++){ - printf("%d", _localMasterSalt[i]); - } - printf("\n"); - return; } @@ -151,9 +150,12 @@ void AudioSrtpSession::initializeLocalMasterSalt(void) std::string AudioSrtpSession::getBase64ConcatenatedKeys() { - // concatenate master and salt + // compute concatenated master and salt length int concatLength = _localMasterKeyLength + _localMasterSaltLength; + uint8 concatKeys[concatLength]; + + // concatenate keys memcpy((void*)concatKeys, (void*)_localMasterKey, _localMasterKeyLength); memcpy((void*)(concatKeys + _localMasterKeyLength), (void*)_localMasterSalt, _localMasterSaltLength); @@ -188,18 +190,6 @@ void AudioSrtpSession::unBase64ConcatenatedKeys(std::string base64keys) memcpy((void*)_remoteMasterKey, (void*)output, _remoteMasterKeyLength); memcpy((void*)_remoteMasterSalt, (void*)(output + _remoteMasterKeyLength), _remoteMasterSaltLength); - printf("Remote Master: "); - for(int i = 0; i < _remoteMasterKeyLength; i++){ - printf("%d", _remoteMasterKey[i]); - } - printf("\n"); - - printf("Remote Salt: "); - for(int i = 0; i < _remoteMasterSaltLength; i++){ - printf("%d", _remoteMasterSalt[i]); - } - printf("\n"); - free(output); }