| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 } | 87 } |
| 88 | 88 |
| 89 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper( | 89 DtlsTransportChannelWrapper::DtlsTransportChannelWrapper( |
| 90 Transport* transport, | 90 Transport* transport, |
| 91 TransportChannelImpl* channel) | 91 TransportChannelImpl* channel) |
| 92 : TransportChannelImpl(channel->transport_name(), channel->component()), | 92 : TransportChannelImpl(channel->transport_name(), channel->component()), |
| 93 transport_(transport), | 93 transport_(transport), |
| 94 worker_thread_(rtc::Thread::Current()), | 94 worker_thread_(rtc::Thread::Current()), |
| 95 channel_(channel), | 95 channel_(channel), |
| 96 downward_(NULL), | 96 downward_(NULL), |
| 97 dtls_state_(STATE_NONE), | |
| 98 ssl_role_(rtc::SSL_CLIENT), | 97 ssl_role_(rtc::SSL_CLIENT), |
| 99 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10) { | 98 ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_10) { |
| 100 channel_->SignalWritableState.connect(this, | 99 channel_->SignalWritableState.connect(this, |
| 101 &DtlsTransportChannelWrapper::OnWritableState); | 100 &DtlsTransportChannelWrapper::OnWritableState); |
| 102 channel_->SignalReadPacket.connect(this, | 101 channel_->SignalReadPacket.connect(this, |
| 103 &DtlsTransportChannelWrapper::OnReadPacket); | 102 &DtlsTransportChannelWrapper::OnReadPacket); |
| 104 channel_->SignalSentPacket.connect( | 103 channel_->SignalSentPacket.connect( |
| 105 this, &DtlsTransportChannelWrapper::OnSentPacket); | 104 this, &DtlsTransportChannelWrapper::OnSentPacket); |
| 106 channel_->SignalReadyToSend.connect(this, | 105 channel_->SignalReadyToSend.connect(this, |
| 107 &DtlsTransportChannelWrapper::OnReadyToSend); | 106 &DtlsTransportChannelWrapper::OnReadyToSend); |
| 108 channel_->SignalGatheringState.connect( | 107 channel_->SignalGatheringState.connect( |
| 109 this, &DtlsTransportChannelWrapper::OnGatheringState); | 108 this, &DtlsTransportChannelWrapper::OnGatheringState); |
| 110 channel_->SignalCandidateGathered.connect( | 109 channel_->SignalCandidateGathered.connect( |
| 111 this, &DtlsTransportChannelWrapper::OnCandidateGathered); | 110 this, &DtlsTransportChannelWrapper::OnCandidateGathered); |
| 112 channel_->SignalRoleConflict.connect(this, | 111 channel_->SignalRoleConflict.connect(this, |
| 113 &DtlsTransportChannelWrapper::OnRoleConflict); | 112 &DtlsTransportChannelWrapper::OnRoleConflict); |
| 114 channel_->SignalRouteChange.connect(this, | 113 channel_->SignalRouteChange.connect(this, |
| 115 &DtlsTransportChannelWrapper::OnRouteChange); | 114 &DtlsTransportChannelWrapper::OnRouteChange); |
| 116 channel_->SignalConnectionRemoved.connect(this, | 115 channel_->SignalConnectionRemoved.connect(this, |
| 117 &DtlsTransportChannelWrapper::OnConnectionRemoved); | 116 &DtlsTransportChannelWrapper::OnConnectionRemoved); |
| 118 channel_->SignalReceivingState.connect(this, | 117 channel_->SignalReceivingState.connect(this, |
| 119 &DtlsTransportChannelWrapper::OnReceivingState); | 118 &DtlsTransportChannelWrapper::OnReceivingState); |
| 120 } | 119 } |
| 121 | 120 |
| 122 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() { | 121 DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() { |
| 123 } | 122 } |
| 124 | 123 |
| 125 void DtlsTransportChannelWrapper::Connect() { | 124 void DtlsTransportChannelWrapper::Connect() { |
| 126 // We should only get a single call to Connect. | 125 // We should only get a single call to Connect. |
| 127 ASSERT(dtls_state_ == STATE_NONE || | 126 ASSERT(dtls_state() == DTLS_TRANSPORT_NEW); |
| 128 dtls_state_ == STATE_OFFERED || | |
| 129 dtls_state_ == STATE_ACCEPTED); | |
| 130 channel_->Connect(); | 127 channel_->Connect(); |
| 131 } | 128 } |
| 132 | 129 |
| 133 bool DtlsTransportChannelWrapper::SetLocalCertificate( | 130 bool DtlsTransportChannelWrapper::SetLocalCertificate( |
| 134 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { | 131 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
| 135 if (dtls_state_ != STATE_NONE) { | 132 if (dtls_active_) { |
| 136 if (certificate == local_certificate_) { | 133 if (certificate == local_certificate_) { |
| 137 // This may happen during renegotiation. | 134 // This may happen during renegotiation. |
| 138 LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity"; | 135 LOG_J(LS_INFO, this) << "Ignoring identical DTLS identity"; |
| 139 return true; | 136 return true; |
| 140 } else { | 137 } else { |
| 141 LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state"; | 138 LOG_J(LS_ERROR, this) << "Can't change DTLS local identity in this state"; |
| 142 return false; | 139 return false; |
| 143 } | 140 } |
| 144 } | 141 } |
| 145 | 142 |
| 146 if (certificate) { | 143 if (certificate) { |
| 147 local_certificate_ = certificate; | 144 local_certificate_ = certificate; |
| 148 dtls_state_ = STATE_OFFERED; | 145 dtls_active_ = true; |
| 149 } else { | 146 } else { |
| 150 LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS"; | 147 LOG_J(LS_INFO, this) << "NULL DTLS identity supplied. Not doing DTLS"; |
| 151 } | 148 } |
| 152 | 149 |
| 153 return true; | 150 return true; |
| 154 } | 151 } |
| 155 | 152 |
| 156 rtc::scoped_refptr<rtc::RTCCertificate> | 153 rtc::scoped_refptr<rtc::RTCCertificate> |
| 157 DtlsTransportChannelWrapper::GetLocalCertificate() const { | 154 DtlsTransportChannelWrapper::GetLocalCertificate() const { |
| 158 return local_certificate_; | 155 return local_certificate_; |
| 159 } | 156 } |
| 160 | 157 |
| 161 bool DtlsTransportChannelWrapper::SetSslMaxProtocolVersion( | 158 bool DtlsTransportChannelWrapper::SetSslMaxProtocolVersion( |
| 162 rtc::SSLProtocolVersion version) { | 159 rtc::SSLProtocolVersion version) { |
| 163 if (dtls_state_ != STATE_NONE) { | 160 if (dtls_active_) { |
| 164 LOG(LS_ERROR) << "Not changing max. protocol version " | 161 LOG(LS_ERROR) << "Not changing max. protocol version " |
| 165 << "while DTLS is negotiating"; | 162 << "while DTLS is negotiating"; |
| 166 return false; | 163 return false; |
| 167 } | 164 } |
| 168 | 165 |
| 169 ssl_max_version_ = version; | 166 ssl_max_version_ = version; |
| 170 return true; | 167 return true; |
| 171 } | 168 } |
| 172 | 169 |
| 173 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) { | 170 bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) { |
| 174 if (dtls_state_ == STATE_OPEN) { | 171 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) { |
| 175 if (ssl_role_ != role) { | 172 if (ssl_role_ != role) { |
| 176 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup."; | 173 LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup."; |
| 177 return false; | 174 return false; |
| 178 } | 175 } |
| 179 return true; | 176 return true; |
| 180 } | 177 } |
| 181 | 178 |
| 182 ssl_role_ = role; | 179 ssl_role_ = role; |
| 183 return true; | 180 return true; |
| 184 } | 181 } |
| 185 | 182 |
| 186 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const { | 183 bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const { |
| 187 *role = ssl_role_; | 184 *role = ssl_role_; |
| 188 return true; | 185 return true; |
| 189 } | 186 } |
| 190 | 187 |
| 191 bool DtlsTransportChannelWrapper::GetSslCipherSuite(int* cipher) { | 188 bool DtlsTransportChannelWrapper::GetSslCipherSuite(int* cipher) { |
| 192 if (dtls_state_ != STATE_OPEN) { | 189 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) { |
| 193 return false; | 190 return false; |
| 194 } | 191 } |
| 195 | 192 |
| 196 return dtls_->GetSslCipherSuite(cipher); | 193 return dtls_->GetSslCipherSuite(cipher); |
| 197 } | 194 } |
| 198 | 195 |
| 199 bool DtlsTransportChannelWrapper::SetRemoteFingerprint( | 196 bool DtlsTransportChannelWrapper::SetRemoteFingerprint( |
| 200 const std::string& digest_alg, | 197 const std::string& digest_alg, |
| 201 const uint8_t* digest, | 198 const uint8_t* digest, |
| 202 size_t digest_len) { | 199 size_t digest_len) { |
| 203 rtc::Buffer remote_fingerprint_value(digest, digest_len); | 200 rtc::Buffer remote_fingerprint_value(digest, digest_len); |
| 204 | 201 |
| 205 if (dtls_state_ != STATE_NONE && | 202 if (dtls_active_ && remote_fingerprint_value_ == remote_fingerprint_value && |
| 206 remote_fingerprint_value_ == remote_fingerprint_value && | |
| 207 !digest_alg.empty()) { | 203 !digest_alg.empty()) { |
| 208 // This may happen during renegotiation. | 204 // This may happen during renegotiation. |
| 209 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; | 205 LOG_J(LS_INFO, this) << "Ignoring identical remote DTLS fingerprint"; |
| 210 return true; | 206 return true; |
| 211 } | 207 } |
| 212 | 208 |
| 213 // Allow SetRemoteFingerprint with a NULL digest even if SetLocalCertificate | 209 // Allow SetRemoteFingerprint with a NULL digest even if SetLocalCertificate |
| 214 // hasn't been called. | 210 // hasn't been called. |
| 215 if (dtls_state_ > STATE_OFFERED || | 211 if (dtls_ || (!dtls_active_ && !digest_alg.empty())) { |
| 216 (dtls_state_ == STATE_NONE && !digest_alg.empty())) { | |
| 217 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; | 212 LOG_J(LS_ERROR, this) << "Can't set DTLS remote settings in this state."; |
| 218 return false; | 213 return false; |
| 219 } | 214 } |
| 220 | 215 |
| 221 if (digest_alg.empty()) { | 216 if (digest_alg.empty()) { |
| 222 LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; | 217 LOG_J(LS_INFO, this) << "Other side didn't support DTLS."; |
| 223 dtls_state_ = STATE_NONE; | 218 dtls_active_ = false; |
| 224 return true; | 219 return true; |
| 225 } | 220 } |
| 226 | 221 |
| 227 // At this point we know we are doing DTLS | 222 // At this point we know we are doing DTLS |
| 228 remote_fingerprint_value_ = remote_fingerprint_value.Pass(); | 223 remote_fingerprint_value_ = remote_fingerprint_value.Pass(); |
| 229 remote_fingerprint_algorithm_ = digest_alg; | 224 remote_fingerprint_algorithm_ = digest_alg; |
| 230 | 225 |
| 231 if (!SetupDtls()) { | 226 if (!SetupDtls()) { |
| 232 dtls_state_ = STATE_CLOSED; | 227 set_dtls_state(DTLS_TRANSPORT_FAILED); |
| 233 return false; | 228 return false; |
| 234 } | 229 } |
| 235 | 230 |
| 236 dtls_state_ = STATE_ACCEPTED; | |
| 237 return true; | 231 return true; |
| 238 } | 232 } |
| 239 | 233 |
| 240 bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate( | 234 bool DtlsTransportChannelWrapper::GetRemoteSSLCertificate( |
| 241 rtc::SSLCertificate** cert) const { | 235 rtc::SSLCertificate** cert) const { |
| 242 if (!dtls_) | 236 if (!dtls_) { |
| 243 return false; | 237 return false; |
| 238 } |
| 244 | 239 |
| 245 return dtls_->GetPeerCertificate(cert); | 240 return dtls_->GetPeerCertificate(cert); |
| 246 } | 241 } |
| 247 | 242 |
| 248 bool DtlsTransportChannelWrapper::SetupDtls() { | 243 bool DtlsTransportChannelWrapper::SetupDtls() { |
| 249 StreamInterfaceChannel* downward = new StreamInterfaceChannel(channel_); | 244 StreamInterfaceChannel* downward = new StreamInterfaceChannel(channel_); |
| 250 | 245 |
| 251 dtls_.reset(rtc::SSLStreamAdapter::Create(downward)); | 246 dtls_.reset(rtc::SSLStreamAdapter::Create(downward)); |
| 252 if (!dtls_) { | 247 if (!dtls_) { |
| 253 LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter."; | 248 LOG_J(LS_ERROR, this) << "Failed to create DTLS adapter."; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 270 return false; | 265 return false; |
| 271 } | 266 } |
| 272 | 267 |
| 273 // Set up DTLS-SRTP, if it's been enabled. | 268 // Set up DTLS-SRTP, if it's been enabled. |
| 274 if (!srtp_ciphers_.empty()) { | 269 if (!srtp_ciphers_.empty()) { |
| 275 if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) { | 270 if (!dtls_->SetDtlsSrtpCiphers(srtp_ciphers_)) { |
| 276 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; | 271 LOG_J(LS_ERROR, this) << "Couldn't set DTLS-SRTP ciphers."; |
| 277 return false; | 272 return false; |
| 278 } | 273 } |
| 279 } else { | 274 } else { |
| 280 LOG_J(LS_INFO, this) << "Not using DTLS."; | 275 LOG_J(LS_INFO, this) << "Not using DTLS-SRTP."; |
| 281 } | 276 } |
| 282 | 277 |
| 283 LOG_J(LS_INFO, this) << "DTLS setup complete."; | 278 LOG_J(LS_INFO, this) << "DTLS setup complete."; |
| 284 return true; | 279 return true; |
| 285 } | 280 } |
| 286 | 281 |
| 287 bool DtlsTransportChannelWrapper::SetSrtpCiphers( | 282 bool DtlsTransportChannelWrapper::SetSrtpCiphers( |
| 288 const std::vector<std::string>& ciphers) { | 283 const std::vector<std::string>& ciphers) { |
| 289 if (srtp_ciphers_ == ciphers) | 284 if (srtp_ciphers_ == ciphers) { |
| 290 return true; | 285 return true; |
| 286 } |
| 291 | 287 |
| 292 if (dtls_state_ == STATE_STARTED) { | 288 if (dtls_state() == DTLS_TRANSPORT_CONNECTING) { |
| 293 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; | 289 LOG(LS_WARNING) << "Ignoring new SRTP ciphers while DTLS is negotiating"; |
| 294 return true; | 290 return true; |
| 295 } | 291 } |
| 296 | 292 |
| 297 if (dtls_state_ == STATE_OPEN) { | 293 if (dtls_state() == DTLS_TRANSPORT_CONNECTED) { |
| 298 // We don't support DTLS renegotiation currently. If new set of srtp ciphers | 294 // We don't support DTLS renegotiation currently. If new set of srtp ciphers |
| 299 // are different than what's being used currently, we will not use it. | 295 // are different than what's being used currently, we will not use it. |
| 300 // So for now, let's be happy (or sad) with a warning message. | 296 // So for now, let's be happy (or sad) with a warning message. |
| 301 std::string current_srtp_cipher; | 297 std::string current_srtp_cipher; |
| 302 if (!dtls_->GetDtlsSrtpCipher(¤t_srtp_cipher)) { | 298 if (!dtls_->GetDtlsSrtpCipher(¤t_srtp_cipher)) { |
| 303 LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel"; | 299 LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel"; |
| 304 return false; | 300 return false; |
| 305 } | 301 } |
| 306 const std::vector<std::string>::const_iterator iter = | 302 const std::vector<std::string>::const_iterator iter = |
| 307 std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher); | 303 std::find(ciphers.begin(), ciphers.end(), current_srtp_cipher); |
| 308 if (iter == ciphers.end()) { | 304 if (iter == ciphers.end()) { |
| 309 std::string requested_str; | 305 std::string requested_str; |
| 310 for (size_t i = 0; i < ciphers.size(); ++i) { | 306 for (size_t i = 0; i < ciphers.size(); ++i) { |
| 311 requested_str.append(" "); | 307 requested_str.append(" "); |
| 312 requested_str.append(ciphers[i]); | 308 requested_str.append(ciphers[i]); |
| 313 requested_str.append(" "); | 309 requested_str.append(" "); |
| 314 } | 310 } |
| 315 LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS " | 311 LOG(LS_WARNING) << "Ignoring new set of SRTP ciphers, as DTLS " |
| 316 << "renegotiation is not supported currently " | 312 << "renegotiation is not supported currently " |
| 317 << "current cipher = " << current_srtp_cipher << " and " | 313 << "current cipher = " << current_srtp_cipher << " and " |
| 318 << "requested = " << "[" << requested_str << "]"; | 314 << "requested = " << "[" << requested_str << "]"; |
| 319 } | 315 } |
| 320 return true; | 316 return true; |
| 321 } | 317 } |
| 322 | 318 |
| 323 if (dtls_state_ != STATE_NONE && | 319 if (!VERIFY(dtls_state() == DTLS_TRANSPORT_NEW)) { |
| 324 dtls_state_ != STATE_OFFERED && | |
| 325 dtls_state_ != STATE_ACCEPTED) { | |
| 326 ASSERT(false); | |
| 327 return false; | 320 return false; |
| 328 } | 321 } |
| 329 | 322 |
| 330 srtp_ciphers_ = ciphers; | 323 srtp_ciphers_ = ciphers; |
| 331 return true; | 324 return true; |
| 332 } | 325 } |
| 333 | 326 |
| 334 bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(std::string* cipher) { | 327 bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(std::string* cipher) { |
| 335 if (dtls_state_ != STATE_OPEN) { | 328 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) { |
| 336 return false; | 329 return false; |
| 337 } | 330 } |
| 338 | 331 |
| 339 return dtls_->GetDtlsSrtpCipher(cipher); | 332 return dtls_->GetDtlsSrtpCipher(cipher); |
| 340 } | 333 } |
| 341 | 334 |
| 342 | 335 |
| 343 // Called from upper layers to send a media packet. | 336 // Called from upper layers to send a media packet. |
| 344 int DtlsTransportChannelWrapper::SendPacket( | 337 int DtlsTransportChannelWrapper::SendPacket( |
| 345 const char* data, size_t size, | 338 const char* data, size_t size, |
| 346 const rtc::PacketOptions& options, int flags) { | 339 const rtc::PacketOptions& options, int flags) { |
| 347 int result = -1; | 340 if (!dtls_active_) { |
| 341 // Not doing DTLS. |
| 342 return channel_->SendPacket(data, size, options); |
| 343 } |
| 348 | 344 |
| 349 switch (dtls_state_) { | 345 switch (dtls_state()) { |
| 350 case STATE_OFFERED: | 346 case DTLS_TRANSPORT_NEW: |
| 351 // We don't know if we are doing DTLS yet, so we can't send a packet. | 347 // Can't send data until the connection is active. |
| 352 // TODO(ekr@rtfm.com): assert here? | 348 // TODO(ekr@rtfm.com): assert here if dtls_ is NULL? |
| 353 result = -1; | 349 return -1; |
| 354 break; | 350 case DTLS_TRANSPORT_CONNECTING: |
| 355 | 351 // Can't send data until the connection is active. |
| 356 case STATE_STARTED: | 352 return -1; |
| 357 case STATE_ACCEPTED: | 353 case DTLS_TRANSPORT_CONNECTED: |
| 358 // Can't send data until the connection is active | |
| 359 result = -1; | |
| 360 break; | |
| 361 | |
| 362 case STATE_OPEN: | |
| 363 if (flags & PF_SRTP_BYPASS) { | 354 if (flags & PF_SRTP_BYPASS) { |
| 364 ASSERT(!srtp_ciphers_.empty()); | 355 ASSERT(!srtp_ciphers_.empty()); |
| 365 if (!IsRtpPacket(data, size)) { | 356 if (!IsRtpPacket(data, size)) { |
| 366 result = -1; | 357 return -1; |
| 367 break; | |
| 368 } | 358 } |
| 369 | 359 |
| 370 result = channel_->SendPacket(data, size, options); | 360 return channel_->SendPacket(data, size, options); |
| 371 } else { | 361 } else { |
| 372 result = (dtls_->WriteAll(data, size, NULL, NULL) == | 362 return (dtls_->WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS) |
| 373 rtc::SR_SUCCESS) ? static_cast<int>(size) : -1; | 363 ? static_cast<int>(size) |
| 364 : -1; |
| 374 } | 365 } |
| 375 break; | 366 case DTLS_TRANSPORT_FAILED: |
| 376 // Not doing DTLS. | 367 case DTLS_TRANSPORT_CLOSED: |
| 377 case STATE_NONE: | 368 // Can't send anything when we're closed. |
| 378 result = channel_->SendPacket(data, size, options); | 369 return -1; |
| 379 break; | 370 default: |
| 380 | 371 ASSERT(false); |
| 381 case STATE_CLOSED: // Can't send anything when we're closed. | |
| 382 return -1; | 372 return -1; |
| 383 } | 373 } |
| 384 | |
| 385 return result; | |
| 386 } | 374 } |
| 387 | 375 |
| 388 // The state transition logic here is as follows: | 376 // The state transition logic here is as follows: |
| 389 // (1) If we're not doing DTLS-SRTP, then the state is just the | 377 // (1) If we're not doing DTLS-SRTP, then the state is just the |
| 390 // state of the underlying impl() | 378 // state of the underlying impl() |
| 391 // (2) If we're doing DTLS-SRTP: | 379 // (2) If we're doing DTLS-SRTP: |
| 392 // - Prior to the DTLS handshake, the state is neither receiving nor | 380 // - Prior to the DTLS handshake, the state is neither receiving nor |
| 393 // writable | 381 // writable |
| 394 // - When the impl goes writable for the first time we | 382 // - When the impl goes writable for the first time we |
| 395 // start the DTLS handshake | 383 // start the DTLS handshake |
| 396 // - Once the DTLS handshake completes, the state is that of the | 384 // - Once the DTLS handshake completes, the state is that of the |
| 397 // impl again | 385 // impl again |
| 398 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) { | 386 void DtlsTransportChannelWrapper::OnWritableState(TransportChannel* channel) { |
| 399 ASSERT(rtc::Thread::Current() == worker_thread_); | 387 ASSERT(rtc::Thread::Current() == worker_thread_); |
| 400 ASSERT(channel == channel_); | 388 ASSERT(channel == channel_); |
| 401 LOG_J(LS_VERBOSE, this) | 389 LOG_J(LS_VERBOSE, this) |
| 402 << "DTLSTransportChannelWrapper: channel writable state changed to " | 390 << "DTLSTransportChannelWrapper: channel writable state changed to " |
| 403 << channel_->writable(); | 391 << channel_->writable(); |
| 404 | 392 |
| 405 switch (dtls_state_) { | 393 if (!dtls_active_) { |
| 406 case STATE_NONE: | 394 // Not doing DTLS. |
| 407 case STATE_OPEN: | 395 // Note: SignalWritableState fired by set_writable. |
| 396 set_writable(channel_->writable()); |
| 397 return; |
| 398 } |
| 399 |
| 400 switch (dtls_state()) { |
| 401 case DTLS_TRANSPORT_NEW: |
| 402 // This should never fail: |
| 403 // Because we are operating in a nonblocking mode and all |
| 404 // incoming packets come in via OnReadPacket(), which rejects |
| 405 // packets in this state, the incoming queue must be empty. We |
| 406 // ignore write errors, thus any errors must be because of |
| 407 // configuration and therefore are our fault. |
| 408 // Note that in non-debug configurations, failure in |
| 409 // MaybeStartDtls() changes the state to DTLS_TRANSPORT_FAILED. |
| 410 VERIFY(MaybeStartDtls()); |
| 411 break; |
| 412 case DTLS_TRANSPORT_CONNECTED: |
| 413 // Note: SignalWritableState fired by set_writable. |
| 408 set_writable(channel_->writable()); | 414 set_writable(channel_->writable()); |
| 409 // Note: SignalWritableState fired by set_writable. | |
| 410 break; | 415 break; |
| 411 | 416 case DTLS_TRANSPORT_CONNECTING: |
| 412 case STATE_OFFERED: | 417 // Do nothing. |
| 413 // Do nothing | |
| 414 break; | 418 break; |
| 415 | 419 case DTLS_TRANSPORT_FAILED: |
| 416 case STATE_ACCEPTED: | 420 case DTLS_TRANSPORT_CLOSED: |
| 417 if (!MaybeStartDtls()) { | 421 // Should not happen. Do nothing. |
| 418 // This should never happen: | |
| 419 // Because we are operating in a nonblocking mode and all | |
| 420 // incoming packets come in via OnReadPacket(), which rejects | |
| 421 // packets in this state, the incoming queue must be empty. We | |
| 422 // ignore write errors, thus any errors must be because of | |
| 423 // configuration and therefore are our fault. | |
| 424 // Note that in non-debug configurations, failure in | |
| 425 // MaybeStartDtls() changes the state to STATE_CLOSED. | |
| 426 ASSERT(false); | |
| 427 } | |
| 428 break; | |
| 429 | |
| 430 case STATE_STARTED: | |
| 431 // Do nothing | |
| 432 break; | |
| 433 | |
| 434 case STATE_CLOSED: | |
| 435 // Should not happen. Do nothing | |
| 436 break; | 422 break; |
| 437 } | 423 } |
| 438 } | 424 } |
| 439 | 425 |
| 440 void DtlsTransportChannelWrapper::OnReceivingState(TransportChannel* channel) { | 426 void DtlsTransportChannelWrapper::OnReceivingState(TransportChannel* channel) { |
| 441 ASSERT(rtc::Thread::Current() == worker_thread_); | 427 ASSERT(rtc::Thread::Current() == worker_thread_); |
| 442 ASSERT(channel == channel_); | 428 ASSERT(channel == channel_); |
| 443 LOG_J(LS_VERBOSE, this) | 429 LOG_J(LS_VERBOSE, this) |
| 444 << "DTLSTransportChannelWrapper: channel receiving state changed to " | 430 << "DTLSTransportChannelWrapper: channel receiving state changed to " |
| 445 << channel_->receiving(); | 431 << channel_->receiving(); |
| 446 if (dtls_state_ == STATE_NONE || dtls_state_ == STATE_OPEN) { | 432 if (!dtls_active_ || dtls_state() == DTLS_TRANSPORT_CONNECTED) { |
| 447 // Note: SignalReceivingState fired by set_receiving. | 433 // Note: SignalReceivingState fired by set_receiving. |
| 448 set_receiving(channel_->receiving()); | 434 set_receiving(channel_->receiving()); |
| 449 } | 435 } |
| 450 } | 436 } |
| 451 | 437 |
| 452 void DtlsTransportChannelWrapper::OnReadPacket( | 438 void DtlsTransportChannelWrapper::OnReadPacket( |
| 453 TransportChannel* channel, const char* data, size_t size, | 439 TransportChannel* channel, const char* data, size_t size, |
| 454 const rtc::PacketTime& packet_time, int flags) { | 440 const rtc::PacketTime& packet_time, int flags) { |
| 455 ASSERT(rtc::Thread::Current() == worker_thread_); | 441 ASSERT(rtc::Thread::Current() == worker_thread_); |
| 456 ASSERT(channel == channel_); | 442 ASSERT(channel == channel_); |
| 457 ASSERT(flags == 0); | 443 ASSERT(flags == 0); |
| 458 | 444 |
| 459 switch (dtls_state_) { | 445 if (!dtls_active_) { |
| 460 case STATE_NONE: | 446 // Not doing DTLS. |
| 461 // We are not doing DTLS | 447 SignalReadPacket(this, data, size, packet_time, 0); |
| 462 SignalReadPacket(this, data, size, packet_time, 0); | 448 return; |
| 449 } |
| 450 |
| 451 switch (dtls_state()) { |
| 452 case DTLS_TRANSPORT_NEW: |
| 453 if (dtls_) { |
| 454 // Drop packets received before DTLS has actually started. |
| 455 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started."; |
| 456 } else { |
| 457 // Currently drop the packet, but we might in future |
| 458 // decide to take this as evidence that the other |
| 459 // side is ready to do DTLS and start the handshake |
| 460 // on our end. |
| 461 LOG_J(LS_WARNING, this) << "Received packet before we know if we are " |
| 462 << "doing DTLS or not; dropping."; |
| 463 } |
| 463 break; | 464 break; |
| 464 | 465 |
| 465 case STATE_OFFERED: | 466 case DTLS_TRANSPORT_CONNECTING: |
| 466 // Currently drop the packet, but we might in future | 467 case DTLS_TRANSPORT_CONNECTED: |
| 467 // decide to take this as evidence that the other | |
| 468 // side is ready to do DTLS and start the handshake | |
| 469 // on our end | |
| 470 LOG_J(LS_WARNING, this) << "Received packet before we know if we are " | |
| 471 << "doing DTLS or not; dropping."; | |
| 472 break; | |
| 473 | |
| 474 case STATE_ACCEPTED: | |
| 475 // Drop packets received before DTLS has actually started | |
| 476 LOG_J(LS_INFO, this) << "Dropping packet received before DTLS started."; | |
| 477 break; | |
| 478 | |
| 479 case STATE_STARTED: | |
| 480 case STATE_OPEN: | |
| 481 // We should only get DTLS or SRTP packets; STUN's already been demuxed. | 468 // We should only get DTLS or SRTP packets; STUN's already been demuxed. |
| 482 // Is this potentially a DTLS packet? | 469 // Is this potentially a DTLS packet? |
| 483 if (IsDtlsPacket(data, size)) { | 470 if (IsDtlsPacket(data, size)) { |
| 484 if (!HandleDtlsPacket(data, size)) { | 471 if (!HandleDtlsPacket(data, size)) { |
| 485 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; | 472 LOG_J(LS_ERROR, this) << "Failed to handle DTLS packet."; |
| 486 return; | 473 return; |
| 487 } | 474 } |
| 488 } else { | 475 } else { |
| 489 // Not a DTLS packet; our handshake should be complete by now. | 476 // Not a DTLS packet; our handshake should be complete by now. |
| 490 if (dtls_state_ != STATE_OPEN) { | 477 if (dtls_state() != DTLS_TRANSPORT_CONNECTED) { |
| 491 LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS " | 478 LOG_J(LS_ERROR, this) << "Received non-DTLS packet before DTLS " |
| 492 << "complete."; | 479 << "complete."; |
| 493 return; | 480 return; |
| 494 } | 481 } |
| 495 | 482 |
| 496 // And it had better be a SRTP packet. | 483 // And it had better be a SRTP packet. |
| 497 if (!IsRtpPacket(data, size)) { | 484 if (!IsRtpPacket(data, size)) { |
| 498 LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet."; | 485 LOG_J(LS_ERROR, this) << "Received unexpected non-DTLS packet."; |
| 499 return; | 486 return; |
| 500 } | 487 } |
| 501 | 488 |
| 502 // Sanity check. | 489 // Sanity check. |
| 503 ASSERT(!srtp_ciphers_.empty()); | 490 ASSERT(!srtp_ciphers_.empty()); |
| 504 | 491 |
| 505 // Signal this upwards as a bypass packet. | 492 // Signal this upwards as a bypass packet. |
| 506 SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS); | 493 SignalReadPacket(this, data, size, packet_time, PF_SRTP_BYPASS); |
| 507 } | 494 } |
| 508 break; | 495 break; |
| 509 case STATE_CLOSED: | 496 case DTLS_TRANSPORT_FAILED: |
| 510 // This shouldn't be happening. Drop the packet | 497 case DTLS_TRANSPORT_CLOSED: |
| 498 // This shouldn't be happening. Drop the packet. |
| 511 break; | 499 break; |
| 512 } | 500 } |
| 513 } | 501 } |
| 514 | 502 |
| 515 void DtlsTransportChannelWrapper::OnSentPacket( | 503 void DtlsTransportChannelWrapper::OnSentPacket( |
| 516 TransportChannel* channel, | 504 TransportChannel* channel, |
| 517 const rtc::SentPacket& sent_packet) { | 505 const rtc::SentPacket& sent_packet) { |
| 518 ASSERT(rtc::Thread::Current() == worker_thread_); | 506 ASSERT(rtc::Thread::Current() == worker_thread_); |
| 519 | 507 |
| 520 SignalSentPacket(this, sent_packet); | 508 SignalSentPacket(this, sent_packet); |
| 521 } | 509 } |
| 522 | 510 |
| 523 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) { | 511 void DtlsTransportChannelWrapper::OnReadyToSend(TransportChannel* channel) { |
| 524 if (writable()) { | 512 if (writable()) { |
| 525 SignalReadyToSend(this); | 513 SignalReadyToSend(this); |
| 526 } | 514 } |
| 527 } | 515 } |
| 528 | 516 |
| 529 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls, | 517 void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls, |
| 530 int sig, int err) { | 518 int sig, int err) { |
| 531 ASSERT(rtc::Thread::Current() == worker_thread_); | 519 ASSERT(rtc::Thread::Current() == worker_thread_); |
| 532 ASSERT(dtls == dtls_.get()); | 520 ASSERT(dtls == dtls_.get()); |
| 533 if (sig & rtc::SE_OPEN) { | 521 if (sig & rtc::SE_OPEN) { |
| 534 // This is the first time. | 522 // This is the first time. |
| 535 LOG_J(LS_INFO, this) << "DTLS handshake complete."; | 523 LOG_J(LS_INFO, this) << "DTLS handshake complete."; |
| 536 if (dtls_->GetState() == rtc::SS_OPEN) { | 524 if (dtls_->GetState() == rtc::SS_OPEN) { |
| 537 // The check for OPEN shouldn't be necessary but let's make | 525 // The check for OPEN shouldn't be necessary but let's make |
| 538 // sure we don't accidentally frob the state if it's closed. | 526 // sure we don't accidentally frob the state if it's closed. |
| 539 dtls_state_ = STATE_OPEN; | 527 set_dtls_state(DTLS_TRANSPORT_CONNECTED); |
| 540 set_writable(true); | 528 set_writable(true); |
| 541 } | 529 } |
| 542 } | 530 } |
| 543 if (sig & rtc::SE_READ) { | 531 if (sig & rtc::SE_READ) { |
| 544 char buf[kMaxDtlsPacketLen]; | 532 char buf[kMaxDtlsPacketLen]; |
| 545 size_t read; | 533 size_t read; |
| 546 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { | 534 if (dtls_->Read(buf, sizeof(buf), &read, NULL) == rtc::SR_SUCCESS) { |
| 547 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); | 535 SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0); |
| 548 } | 536 } |
| 549 } | 537 } |
| 550 if (sig & rtc::SE_CLOSE) { | 538 if (sig & rtc::SE_CLOSE) { |
| 551 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. | 539 ASSERT(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself. |
| 540 set_writable(false); |
| 552 if (!err) { | 541 if (!err) { |
| 553 LOG_J(LS_INFO, this) << "DTLS channel closed"; | 542 LOG_J(LS_INFO, this) << "DTLS channel closed"; |
| 543 set_dtls_state(DTLS_TRANSPORT_CLOSED); |
| 554 } else { | 544 } else { |
| 555 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; | 545 LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err; |
| 546 set_dtls_state(DTLS_TRANSPORT_FAILED); |
| 556 } | 547 } |
| 557 set_writable(false); | |
| 558 dtls_state_ = STATE_CLOSED; | |
| 559 } | 548 } |
| 560 } | 549 } |
| 561 | 550 |
| 562 bool DtlsTransportChannelWrapper::MaybeStartDtls() { | 551 bool DtlsTransportChannelWrapper::MaybeStartDtls() { |
| 563 if (channel_->writable()) { | 552 if (dtls_ && channel_->writable()) { |
| 564 if (dtls_->StartSSLWithPeer()) { | 553 if (dtls_->StartSSLWithPeer()) { |
| 565 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; | 554 LOG_J(LS_ERROR, this) << "Couldn't start DTLS handshake"; |
| 566 dtls_state_ = STATE_CLOSED; | 555 set_dtls_state(DTLS_TRANSPORT_FAILED); |
| 567 return false; | 556 return false; |
| 568 } | 557 } |
| 569 LOG_J(LS_INFO, this) | 558 LOG_J(LS_INFO, this) |
| 570 << "DtlsTransportChannelWrapper: Started DTLS handshake"; | 559 << "DtlsTransportChannelWrapper: Started DTLS handshake"; |
| 571 | 560 set_dtls_state(DTLS_TRANSPORT_CONNECTING); |
| 572 dtls_state_ = STATE_STARTED; | |
| 573 } | 561 } |
| 574 return true; | 562 return true; |
| 575 } | 563 } |
| 576 | 564 |
| 577 // Called from OnReadPacket when a DTLS packet is received. | 565 // Called from OnReadPacket when a DTLS packet is received. |
| 578 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, | 566 bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data, |
| 579 size_t size) { | 567 size_t size) { |
| 580 // Sanity check we're not passing junk that | 568 // Sanity check we're not passing junk that |
| 581 // just looks like DTLS. | 569 // just looks like DTLS. |
| 582 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); | 570 const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 SignalRouteChange(this, candidate); | 611 SignalRouteChange(this, candidate); |
| 624 } | 612 } |
| 625 | 613 |
| 626 void DtlsTransportChannelWrapper::OnConnectionRemoved( | 614 void DtlsTransportChannelWrapper::OnConnectionRemoved( |
| 627 TransportChannelImpl* channel) { | 615 TransportChannelImpl* channel) { |
| 628 ASSERT(channel == channel_); | 616 ASSERT(channel == channel_); |
| 629 SignalConnectionRemoved(this); | 617 SignalConnectionRemoved(this); |
| 630 } | 618 } |
| 631 | 619 |
| 632 } // namespace cricket | 620 } // namespace cricket |
| OLD | NEW |