OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 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 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 if (!needs_ice_restart_) { | 271 if (!needs_ice_restart_) { |
272 needs_ice_restart_ = true; | 272 needs_ice_restart_ = true; |
273 LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid(); | 273 LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid(); |
274 } | 274 } |
275 } | 275 } |
276 | 276 |
277 bool JsepTransport::NeedsIceRestart() const { | 277 bool JsepTransport::NeedsIceRestart() const { |
278 return needs_ice_restart_; | 278 return needs_ice_restart_; |
279 } | 279 } |
280 | 280 |
281 void JsepTransport::GetSslRole(rtc::SSLRole* ssl_role) const { | 281 rtc::Optional<rtc::SSLRole> JsepTransport::GetSslRole() const { |
282 RTC_DCHECK(ssl_role); | 282 return ssl_role_; |
283 *ssl_role = secure_role_; | |
284 } | 283 } |
285 | 284 |
286 bool JsepTransport::GetStats(TransportStats* stats) { | 285 bool JsepTransport::GetStats(TransportStats* stats) { |
287 stats->transport_name = mid(); | 286 stats->transport_name = mid(); |
288 stats->channel_stats.clear(); | 287 stats->channel_stats.clear(); |
289 for (auto& kv : channels_) { | 288 for (auto& kv : channels_) { |
290 DtlsTransportInternal* dtls_transport = kv.second; | 289 DtlsTransportInternal* dtls_transport = kv.second; |
291 TransportChannelStats substats; | 290 TransportChannelStats substats; |
292 substats.component = kv.first; | 291 substats.component = kv.first; |
293 dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite); | 292 dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 if (certificate_) { | 334 if (certificate_) { |
336 ret = dtls_transport->SetLocalCertificate(certificate_); | 335 ret = dtls_transport->SetLocalCertificate(certificate_); |
337 RTC_DCHECK(ret); | 336 RTC_DCHECK(ret); |
338 } | 337 } |
339 return ret; | 338 return ret; |
340 } | 339 } |
341 | 340 |
342 bool JsepTransport::ApplyRemoteTransportDescription( | 341 bool JsepTransport::ApplyRemoteTransportDescription( |
343 DtlsTransportInternal* dtls_transport, | 342 DtlsTransportInternal* dtls_transport, |
344 std::string* error_desc) { | 343 std::string* error_desc) { |
345 // Currently, all ICE-related calls still go through this DTLS channel. But | |
346 // that will change once we get rid of TransportChannelImpl, and the DTLS | |
347 // channel interface no longer includes ICE-specific methods. Then this class | |
348 // will need to call dtls->ice()->SetIceRole(), for example, assuming the Dtls | |
349 // interface will expose its inner ICE channel. | |
350 dtls_transport->ice_transport()->SetRemoteIceParameters( | 344 dtls_transport->ice_transport()->SetRemoteIceParameters( |
351 remote_description_->GetIceParameters()); | 345 remote_description_->GetIceParameters()); |
352 dtls_transport->ice_transport()->SetRemoteIceMode( | 346 dtls_transport->ice_transport()->SetRemoteIceMode( |
353 remote_description_->ice_mode); | 347 remote_description_->ice_mode); |
354 return true; | 348 return true; |
355 } | 349 } |
356 | 350 |
357 bool JsepTransport::ApplyNegotiatedTransportDescription( | 351 bool JsepTransport::ApplyNegotiatedTransportDescription( |
358 DtlsTransportInternal* dtls_transport, | 352 DtlsTransportInternal* dtls_transport, |
359 std::string* error_desc) { | 353 std::string* error_desc) { |
360 // Set SSL role. Role must be set before fingerprint is applied, which | 354 // Set SSL role. Role must be set before fingerprint is applied, which |
361 // initiates DTLS setup. | 355 // initiates DTLS setup. |
362 if (!dtls_transport->SetSslRole(secure_role_)) { | 356 if (ssl_role_ && !dtls_transport->SetSslRole(*ssl_role_)) { |
363 return BadTransportDescription("Failed to set SSL role for the channel.", | 357 return BadTransportDescription("Failed to set SSL role for the channel.", |
364 error_desc); | 358 error_desc); |
365 } | 359 } |
366 // Apply remote fingerprint. | 360 // Apply remote fingerprint. |
367 if (!dtls_transport->SetRemoteFingerprint( | 361 if (!dtls_transport->SetRemoteFingerprint( |
368 remote_fingerprint_->algorithm, | 362 remote_fingerprint_->algorithm, |
369 reinterpret_cast<const uint8_t*>(remote_fingerprint_->digest.data()), | 363 reinterpret_cast<const uint8_t*>(remote_fingerprint_->digest.data()), |
370 remote_fingerprint_->digest.size())) { | 364 remote_fingerprint_->digest.size())) { |
371 return BadTransportDescription("Failed to apply remote fingerprint.", | 365 return BadTransportDescription("Failed to apply remote fingerprint.", |
372 error_desc); | 366 error_desc); |
373 } | 367 } |
374 return true; | 368 return true; |
375 } | 369 } |
376 | 370 |
377 bool JsepTransport::NegotiateTransportDescription(ContentAction local_role, | 371 bool JsepTransport::NegotiateTransportDescription( |
378 std::string* error_desc) { | 372 ContentAction local_description_type, |
373 std::string* error_desc) { | |
379 if (!local_description_ || !remote_description_) { | 374 if (!local_description_ || !remote_description_) { |
380 const std::string msg = | 375 const std::string msg = |
381 "Applying an answer transport description " | 376 "Applying an answer transport description " |
382 "without applying any offer."; | 377 "without applying any offer."; |
383 return BadTransportDescription(msg, error_desc); | 378 return BadTransportDescription(msg, error_desc); |
384 } | 379 } |
385 rtc::SSLFingerprint* local_fp = | 380 rtc::SSLFingerprint* local_fp = |
386 local_description_->identity_fingerprint.get(); | 381 local_description_->identity_fingerprint.get(); |
387 rtc::SSLFingerprint* remote_fp = | 382 rtc::SSLFingerprint* remote_fp = |
388 remote_description_->identity_fingerprint.get(); | 383 remote_description_->identity_fingerprint.get(); |
389 if (remote_fp && local_fp) { | 384 if (remote_fp && local_fp) { |
390 remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); | 385 remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); |
391 if (!NegotiateRole(local_role, &secure_role_, error_desc)) { | 386 if (!NegotiateRole(local_description_type, error_desc)) { |
392 return false; | 387 return false; |
393 } | 388 } |
394 } else if (local_fp && (local_role == CA_ANSWER)) { | 389 } else if (local_fp && (local_description_type == CA_ANSWER)) { |
395 return BadTransportDescription( | 390 return BadTransportDescription( |
396 "Local fingerprint supplied when caller didn't offer DTLS.", | 391 "Local fingerprint supplied when caller didn't offer DTLS.", |
397 error_desc); | 392 error_desc); |
398 } else { | 393 } else { |
399 // We are not doing DTLS | 394 // We are not doing DTLS |
400 remote_fingerprint_.reset(new rtc::SSLFingerprint("", nullptr, 0)); | 395 remote_fingerprint_.reset(new rtc::SSLFingerprint("", nullptr, 0)); |
401 } | 396 } |
402 // Now that we have negotiated everything, push it downward. | 397 // Now that we have negotiated everything, push it downward. |
403 // Note that we cache the result so that if we have race conditions | 398 // Note that we cache the result so that if we have race conditions |
404 // between future SetRemote/SetLocal invocations and new channel | 399 // between future SetRemote/SetLocal invocations and new channel |
405 // creation, we have the negotiation state saved until a new | 400 // creation, we have the negotiation state saved until a new |
406 // negotiation happens. | 401 // negotiation happens. |
407 for (const auto& kv : channels_) { | 402 for (const auto& kv : channels_) { |
408 if (!ApplyNegotiatedTransportDescription(kv.second, error_desc)) { | 403 if (!ApplyNegotiatedTransportDescription(kv.second, error_desc)) { |
409 return false; | 404 return false; |
410 } | 405 } |
411 } | 406 } |
412 return true; | 407 return true; |
413 } | 408 } |
414 | 409 |
415 bool JsepTransport::NegotiateRole(ContentAction local_role, | 410 bool JsepTransport::NegotiateRole(ContentAction local_description_type, |
416 rtc::SSLRole* ssl_role, | 411 std::string* error_desc) { |
417 std::string* error_desc) const { | |
418 RTC_DCHECK(ssl_role); | |
419 if (!local_description_ || !remote_description_) { | 412 if (!local_description_ || !remote_description_) { |
420 const std::string msg = | 413 const std::string msg = |
421 "Local and Remote description must be set before " | 414 "Local and Remote description must be set before " |
422 "transport descriptions are negotiated"; | 415 "transport descriptions are negotiated"; |
423 return BadTransportDescription(msg, error_desc); | 416 return BadTransportDescription(msg, error_desc); |
424 } | 417 } |
425 | 418 |
426 // From RFC 4145, section-4.1, The following are the values that the | 419 // From RFC 4145, section-4.1, The following are the values that the |
427 // 'setup' attribute can take in an offer/answer exchange: | 420 // 'setup' attribute can take in an offer/answer exchange: |
428 // Offer Answer | 421 // Offer Answer |
(...skipping 14 matching lines...) Expand all Loading... | |
443 // latency. setup:active allows the answer and the DTLS handshake to | 436 // latency. setup:active allows the answer and the DTLS handshake to |
444 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever | 437 // occur in parallel. Thus, setup:active is RECOMMENDED. Whichever |
445 // party is active MUST initiate a DTLS handshake by sending a | 438 // party is active MUST initiate a DTLS handshake by sending a |
446 // ClientHello over each flow (host/port quartet). | 439 // ClientHello over each flow (host/port quartet). |
447 // IOW - actpass and passive modes should be treated as server and | 440 // IOW - actpass and passive modes should be treated as server and |
448 // active as client. | 441 // active as client. |
449 ConnectionRole local_connection_role = local_description_->connection_role; | 442 ConnectionRole local_connection_role = local_description_->connection_role; |
450 ConnectionRole remote_connection_role = remote_description_->connection_role; | 443 ConnectionRole remote_connection_role = remote_description_->connection_role; |
451 | 444 |
452 bool is_remote_server = false; | 445 bool is_remote_server = false; |
453 if (local_role == CA_OFFER) { | 446 if (local_description_type == CA_OFFER) { |
454 if (local_connection_role != CONNECTIONROLE_ACTPASS) { | 447 if (local_connection_role != CONNECTIONROLE_ACTPASS) { |
455 return BadTransportDescription( | 448 return BadTransportDescription( |
456 "Offerer must use actpass value for setup attribute.", error_desc); | 449 "Offerer must use actpass value for setup attribute.", error_desc); |
457 } | 450 } |
458 | 451 |
459 if (remote_connection_role == CONNECTIONROLE_ACTIVE || | 452 if (remote_connection_role == CONNECTIONROLE_ACTIVE || |
460 remote_connection_role == CONNECTIONROLE_PASSIVE || | 453 remote_connection_role == CONNECTIONROLE_PASSIVE || |
461 remote_connection_role == CONNECTIONROLE_NONE) { | 454 remote_connection_role == CONNECTIONROLE_NONE) { |
462 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); | 455 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); |
463 } else { | 456 } else { |
464 const std::string msg = | 457 const std::string msg = |
465 "Answerer must use either active or passive value " | 458 "Answerer must use either active or passive value " |
466 "for setup attribute."; | 459 "for setup attribute."; |
467 return BadTransportDescription(msg, error_desc); | 460 return BadTransportDescription(msg, error_desc); |
468 } | 461 } |
469 // If remote is NONE or ACTIVE it will act as client. | 462 // If remote is NONE or ACTIVE it will act as client. |
470 } else { | 463 } else { |
471 if (remote_connection_role != CONNECTIONROLE_ACTPASS && | 464 if (remote_connection_role != CONNECTIONROLE_ACTPASS && |
472 remote_connection_role != CONNECTIONROLE_NONE) { | 465 remote_connection_role != CONNECTIONROLE_NONE) { |
473 return BadTransportDescription( | 466 // Accept a remote role attribute that's not "actpass", but matches the |
474 "Offerer must use actpass value for setup attribute.", error_desc); | 467 // current negotiated role. This is allowed by dtls-sdp, though our |
pthatcher1
2017/03/25 03:30:01
What's "dtls-sdp"? An RFC a draft? Being more sp
Taylor Brandstetter
2017/03/27 21:39:28
Added link and section number.
| |
468 // implementation will never generate such an offer as it's not | |
469 // recommended. | |
470 if (!ssl_role_ || | |
471 (*ssl_role_ == rtc::SSL_CLIENT && | |
472 remote_connection_role == CONNECTIONROLE_ACTIVE) || | |
473 (*ssl_role_ == rtc::SSL_SERVER && | |
474 remote_connection_role == CONNECTIONROLE_PASSIVE)) { | |
475 return BadTransportDescription( | |
476 "Offerer must use actpass value or current negotiated role for " | |
477 "setup attribute.", | |
478 error_desc); | |
479 } | |
475 } | 480 } |
476 | 481 |
477 if (local_connection_role == CONNECTIONROLE_ACTIVE || | 482 if (local_connection_role == CONNECTIONROLE_ACTIVE || |
478 local_connection_role == CONNECTIONROLE_PASSIVE) { | 483 local_connection_role == CONNECTIONROLE_PASSIVE) { |
479 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); | 484 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); |
480 } else { | 485 } else { |
481 const std::string msg = | 486 const std::string msg = |
482 "Answerer must use either active or passive value " | 487 "Answerer must use either active or passive value " |
483 "for setup attribute."; | 488 "for setup attribute."; |
484 return BadTransportDescription(msg, error_desc); | 489 return BadTransportDescription(msg, error_desc); |
485 } | 490 } |
486 | 491 |
487 // If local is passive, local will act as server. | 492 // If local is passive, local will act as server. |
488 } | 493 } |
489 | 494 |
490 *ssl_role = is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER; | 495 ssl_role_.emplace(is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER); |
491 return true; | 496 return true; |
492 } | 497 } |
493 | 498 |
494 } // namespace cricket | 499 } // namespace cricket |
OLD | NEW |