| OLD | NEW | 
|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "remoting/protocol/webrtc_transport.h" | 5 #include "remoting/protocol/webrtc_transport.h" | 
| 6 | 6 | 
| 7 #include <utility> | 7 #include <utility> | 
| 8 | 8 | 
| 9 #include "base/base64.h" | 9 #include "base/base64.h" | 
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" | 
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" | 
| 12 #include "base/macros.h" | 12 #include "base/macros.h" | 
|  | 13 #include "base/memory/ptr_util.h" | 
| 13 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" | 
| 14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" | 
| 15 #include "base/strings/string_split.h" | 16 #include "base/strings/string_split.h" | 
| 16 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" | 
| 17 #include "base/task_runner_util.h" | 18 #include "base/task_runner_util.h" | 
| 18 #include "base/thread_task_runner_handle.h" | 19 #include "base/thread_task_runner_handle.h" | 
| 19 #include "jingle/glue/thread_wrapper.h" | 20 #include "jingle/glue/thread_wrapper.h" | 
| 20 #include "remoting/protocol/authenticator.h" | 21 #include "remoting/protocol/authenticator.h" | 
| 21 #include "remoting/protocol/port_allocator_factory.h" | 22 #include "remoting/protocol/port_allocator_factory.h" | 
| 22 #include "remoting/protocol/stream_message_pipe_adapter.h" | 23 #include "remoting/protocol/stream_message_pipe_adapter.h" | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 62       SplitString(sdp, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 63       SplitString(sdp, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); | 
| 63   return base::JoinString(lines, "\n") + "\n"; | 64   return base::JoinString(lines, "\n") + "\n"; | 
| 64 } | 65 } | 
| 65 | 66 | 
| 66 // A webrtc::CreateSessionDescriptionObserver implementation used to receive the | 67 // A webrtc::CreateSessionDescriptionObserver implementation used to receive the | 
| 67 // results of creating descriptions for this end of the PeerConnection. | 68 // results of creating descriptions for this end of the PeerConnection. | 
| 68 class CreateSessionDescriptionObserver | 69 class CreateSessionDescriptionObserver | 
| 69     : public webrtc::CreateSessionDescriptionObserver { | 70     : public webrtc::CreateSessionDescriptionObserver { | 
| 70  public: | 71  public: | 
| 71   typedef base::Callback<void( | 72   typedef base::Callback<void( | 
| 72       scoped_ptr<webrtc::SessionDescriptionInterface> description, | 73       std::unique_ptr<webrtc::SessionDescriptionInterface> description, | 
| 73       const std::string& error)> ResultCallback; | 74       const std::string& error)> | 
|  | 75       ResultCallback; | 
| 74 | 76 | 
| 75   static CreateSessionDescriptionObserver* Create( | 77   static CreateSessionDescriptionObserver* Create( | 
| 76       const ResultCallback& result_callback) { | 78       const ResultCallback& result_callback) { | 
| 77     return new rtc::RefCountedObject<CreateSessionDescriptionObserver>( | 79     return new rtc::RefCountedObject<CreateSessionDescriptionObserver>( | 
| 78         result_callback); | 80         result_callback); | 
| 79   } | 81   } | 
| 80   void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { | 82   void OnSuccess(webrtc::SessionDescriptionInterface* desc) override { | 
| 81     base::ResetAndReturn(&result_callback_) | 83     base::ResetAndReturn(&result_callback_) | 
| 82         .Run(make_scoped_ptr(desc), std::string()); | 84         .Run(base::WrapUnique(desc), std::string()); | 
| 83   } | 85   } | 
| 84   void OnFailure(const std::string& error) override { | 86   void OnFailure(const std::string& error) override { | 
| 85     base::ResetAndReturn(&result_callback_).Run(nullptr, error); | 87     base::ResetAndReturn(&result_callback_).Run(nullptr, error); | 
| 86   } | 88   } | 
| 87 | 89 | 
| 88  protected: | 90  protected: | 
| 89   explicit CreateSessionDescriptionObserver( | 91   explicit CreateSessionDescriptionObserver( | 
| 90       const ResultCallback& result_callback) | 92       const ResultCallback& result_callback) | 
| 91       : result_callback_(result_callback) {} | 93       : result_callback_(result_callback) {} | 
| 92   ~CreateSessionDescriptionObserver() override {} | 94   ~CreateSessionDescriptionObserver() override {} | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 178 | 180 | 
| 179   webrtc::PeerConnectionInterface::IceServer stun_server; | 181   webrtc::PeerConnectionInterface::IceServer stun_server; | 
| 180   stun_server.urls.push_back("stun:stun.l.google.com:19302"); | 182   stun_server.urls.push_back("stun:stun.l.google.com:19302"); | 
| 181   webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; | 183   webrtc::PeerConnectionInterface::RTCConfiguration rtc_config; | 
| 182   rtc_config.servers.push_back(stun_server); | 184   rtc_config.servers.push_back(stun_server); | 
| 183 | 185 | 
| 184   webrtc::FakeConstraints constraints; | 186   webrtc::FakeConstraints constraints; | 
| 185   constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | 187   constraints.AddMandatory(webrtc::MediaConstraintsInterface::kEnableDtlsSrtp, | 
| 186                            webrtc::MediaConstraintsInterface::kValueTrue); | 188                            webrtc::MediaConstraintsInterface::kValueTrue); | 
| 187 | 189 | 
| 188   scoped_ptr<cricket::PortAllocator> port_allocator = | 190   std::unique_ptr<cricket::PortAllocator> port_allocator = | 
| 189       transport_context_->port_allocator_factory()->CreatePortAllocator( | 191       transport_context_->port_allocator_factory()->CreatePortAllocator( | 
| 190           transport_context_); | 192           transport_context_); | 
| 191   peer_connection_ = peer_connection_factory_->CreatePeerConnection( | 193   peer_connection_ = peer_connection_factory_->CreatePeerConnection( | 
| 192       rtc_config, &constraints, | 194       rtc_config, &constraints, | 
| 193       rtc::scoped_ptr<cricket::PortAllocator>(port_allocator.release()), | 195       rtc::scoped_ptr<cricket::PortAllocator>(port_allocator.release()), | 
| 194       nullptr, this); | 196       nullptr, this); | 
| 195 | 197 | 
| 196   outgoing_data_stream_adapter_.Initialize(peer_connection_); | 198   outgoing_data_stream_adapter_.Initialize(peer_connection_); | 
| 197   incoming_data_stream_adapter_.Initialize(peer_connection_); | 199   incoming_data_stream_adapter_.Initialize(peer_connection_); | 
| 198 | 200 | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 242       ignore_error = base::CommandLine::ForCurrentProcess()->HasSwitch( | 244       ignore_error = base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| 243           kDisableAuthenticationSwitchName); | 245           kDisableAuthenticationSwitchName); | 
| 244 #endif | 246 #endif | 
| 245       if (!ignore_error) { | 247       if (!ignore_error) { | 
| 246         Close(AUTHENTICATION_FAILED); | 248         Close(AUTHENTICATION_FAILED); | 
| 247         return true; | 249         return true; | 
| 248       } | 250       } | 
| 249     } | 251     } | 
| 250 | 252 | 
| 251     webrtc::SdpParseError error; | 253     webrtc::SdpParseError error; | 
| 252     scoped_ptr<webrtc::SessionDescriptionInterface> session_description( | 254     std::unique_ptr<webrtc::SessionDescriptionInterface> session_description( | 
| 253         webrtc::CreateSessionDescription(type, sdp, &error)); | 255         webrtc::CreateSessionDescription(type, sdp, &error)); | 
| 254     if (!session_description) { | 256     if (!session_description) { | 
| 255       LOG(ERROR) << "Failed to parse the session description: " | 257       LOG(ERROR) << "Failed to parse the session description: " | 
| 256                  << error.description << " line: " << error.line; | 258                  << error.description << " line: " << error.line; | 
| 257       return false; | 259       return false; | 
| 258     } | 260     } | 
| 259 | 261 | 
| 260     peer_connection_->SetRemoteDescription( | 262     peer_connection_->SetRemoteDescription( | 
| 261         SetSessionDescriptionObserver::Create( | 263         SetSessionDescriptionObserver::Create( | 
| 262             base::Bind(&WebrtcTransport::OnRemoteDescriptionSet, | 264             base::Bind(&WebrtcTransport::OnRemoteDescriptionSet, | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 276     std::string sdp_mlineindex_str = | 278     std::string sdp_mlineindex_str = | 
| 277         candidate_element->Attr(QName(std::string(), "sdpMLineIndex")); | 279         candidate_element->Attr(QName(std::string(), "sdpMLineIndex")); | 
| 278     int sdp_mlineindex; | 280     int sdp_mlineindex; | 
| 279     if (candidate_str.empty() || sdp_mid.empty() || | 281     if (candidate_str.empty() || sdp_mid.empty() || | 
| 280         !base::StringToInt(sdp_mlineindex_str, &sdp_mlineindex)) { | 282         !base::StringToInt(sdp_mlineindex_str, &sdp_mlineindex)) { | 
| 281       LOG(ERROR) << "Failed to parse incoming candidates."; | 283       LOG(ERROR) << "Failed to parse incoming candidates."; | 
| 282       return false; | 284       return false; | 
| 283     } | 285     } | 
| 284 | 286 | 
| 285     webrtc::SdpParseError error; | 287     webrtc::SdpParseError error; | 
| 286     scoped_ptr<webrtc::IceCandidateInterface> candidate( | 288     std::unique_ptr<webrtc::IceCandidateInterface> candidate( | 
| 287         webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, candidate_str, | 289         webrtc::CreateIceCandidate(sdp_mid, sdp_mlineindex, candidate_str, | 
| 288                                    &error)); | 290                                    &error)); | 
| 289     if (!candidate) { | 291     if (!candidate) { | 
| 290       LOG(ERROR) << "Failed to parse incoming candidate: " << error.description | 292       LOG(ERROR) << "Failed to parse incoming candidate: " << error.description | 
| 291                  << " line: " << error.line; | 293                  << " line: " << error.line; | 
| 292       return false; | 294       return false; | 
| 293     } | 295     } | 
| 294 | 296 | 
| 295     if (peer_connection_->signaling_state() == | 297     if (peer_connection_->signaling_state() == | 
| 296         webrtc::PeerConnectionInterface::kStable) { | 298         webrtc::PeerConnectionInterface::kStable) { | 
| 297       if (!peer_connection_->AddIceCandidate(candidate.get())) { | 299       if (!peer_connection_->AddIceCandidate(candidate.get())) { | 
| 298         LOG(ERROR) << "Failed to add incoming ICE candidate."; | 300         LOG(ERROR) << "Failed to add incoming ICE candidate."; | 
| 299         return false; | 301         return false; | 
| 300       } | 302       } | 
| 301     } else { | 303     } else { | 
| 302       pending_incoming_candidates_.push_back(std::move(candidate)); | 304       pending_incoming_candidates_.push_back(std::move(candidate)); | 
| 303     } | 305     } | 
| 304   } | 306   } | 
| 305 | 307 | 
| 306   return true; | 308   return true; | 
| 307 } | 309 } | 
| 308 | 310 | 
| 309 void WebrtcTransport::OnLocalSessionDescriptionCreated( | 311 void WebrtcTransport::OnLocalSessionDescriptionCreated( | 
| 310     scoped_ptr<webrtc::SessionDescriptionInterface> description, | 312     std::unique_ptr<webrtc::SessionDescriptionInterface> description, | 
| 311     const std::string& error) { | 313     const std::string& error) { | 
| 312   DCHECK(thread_checker_.CalledOnValidThread()); | 314   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 313 | 315 | 
| 314   if (!peer_connection_) | 316   if (!peer_connection_) | 
| 315     return; | 317     return; | 
| 316 | 318 | 
| 317   if (!description) { | 319   if (!description) { | 
| 318     LOG(ERROR) << "PeerConnection offer creation failed: " << error; | 320     LOG(ERROR) << "PeerConnection offer creation failed: " << error; | 
| 319     Close(CHANNEL_CONNECTION_ERROR); | 321     Close(CHANNEL_CONNECTION_ERROR); | 
| 320     return; | 322     return; | 
| 321   } | 323   } | 
| 322 | 324 | 
| 323   std::string description_sdp; | 325   std::string description_sdp; | 
| 324   if (!description->ToString(&description_sdp)) { | 326   if (!description->ToString(&description_sdp)) { | 
| 325     LOG(ERROR) << "Failed to serialize description."; | 327     LOG(ERROR) << "Failed to serialize description."; | 
| 326     Close(CHANNEL_CONNECTION_ERROR); | 328     Close(CHANNEL_CONNECTION_ERROR); | 
| 327     return; | 329     return; | 
| 328   } | 330   } | 
| 329   description_sdp = NormalizeSessionDescription(description_sdp); | 331   description_sdp = NormalizeSessionDescription(description_sdp); | 
| 330 | 332 | 
| 331   // Format and send the session description to the peer. | 333   // Format and send the session description to the peer. | 
| 332   scoped_ptr<XmlElement> transport_info( | 334   std::unique_ptr<XmlElement> transport_info( | 
| 333       new XmlElement(QName(kTransportNamespace, "transport"), true)); | 335       new XmlElement(QName(kTransportNamespace, "transport"), true)); | 
| 334   XmlElement* offer_tag = | 336   XmlElement* offer_tag = | 
| 335       new XmlElement(QName(kTransportNamespace, "session-description")); | 337       new XmlElement(QName(kTransportNamespace, "session-description")); | 
| 336   transport_info->AddElement(offer_tag); | 338   transport_info->AddElement(offer_tag); | 
| 337   offer_tag->SetAttr(QName(std::string(), "type"), description->type()); | 339   offer_tag->SetAttr(QName(std::string(), "type"), description->type()); | 
| 338   offer_tag->SetBodyText(description_sdp); | 340   offer_tag->SetBodyText(description_sdp); | 
| 339 | 341 | 
| 340   std::string digest; | 342   std::string digest; | 
| 341   digest.resize(handshake_hmac_.DigestLength()); | 343   digest.resize(handshake_hmac_.DigestLength()); | 
| 342   CHECK(handshake_hmac_.Sign(description->type() + " " + description_sdp, | 344   CHECK(handshake_hmac_.Sign(description->type() + " " + description_sdp, | 
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 453 | 455 | 
| 454 void WebrtcTransport::OnIceGatheringChange( | 456 void WebrtcTransport::OnIceGatheringChange( | 
| 455     webrtc::PeerConnectionInterface::IceGatheringState new_state) { | 457     webrtc::PeerConnectionInterface::IceGatheringState new_state) { | 
| 456   DCHECK(thread_checker_.CalledOnValidThread()); | 458   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 457 } | 459 } | 
| 458 | 460 | 
| 459 void WebrtcTransport::OnIceCandidate( | 461 void WebrtcTransport::OnIceCandidate( | 
| 460     const webrtc::IceCandidateInterface* candidate) { | 462     const webrtc::IceCandidateInterface* candidate) { | 
| 461   DCHECK(thread_checker_.CalledOnValidThread()); | 463   DCHECK(thread_checker_.CalledOnValidThread()); | 
| 462 | 464 | 
| 463   scoped_ptr<XmlElement> candidate_element( | 465   std::unique_ptr<XmlElement> candidate_element( | 
| 464       new XmlElement(QName(kTransportNamespace, "candidate"))); | 466       new XmlElement(QName(kTransportNamespace, "candidate"))); | 
| 465   std::string candidate_str; | 467   std::string candidate_str; | 
| 466   if (!candidate->ToString(&candidate_str)) { | 468   if (!candidate->ToString(&candidate_str)) { | 
| 467     LOG(ERROR) << "Failed to serialize local candidate."; | 469     LOG(ERROR) << "Failed to serialize local candidate."; | 
| 468     return; | 470     return; | 
| 469   } | 471   } | 
| 470   candidate_element->SetBodyText(candidate_str); | 472   candidate_element->SetBodyText(candidate_str); | 
| 471   candidate_element->SetAttr(QName(std::string(), "sdpMid"), | 473   candidate_element->SetAttr(QName(std::string(), "sdpMid"), | 
| 472                              candidate->sdp_mid()); | 474                              candidate->sdp_mid()); | 
| 473   candidate_element->SetAttr(QName(std::string(), "sdpMLineIndex"), | 475   candidate_element->SetAttr(QName(std::string(), "sdpMLineIndex"), | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 549   peer_connection_->Close(); | 551   peer_connection_->Close(); | 
| 550   peer_connection_ = nullptr; | 552   peer_connection_ = nullptr; | 
| 551   peer_connection_factory_ = nullptr; | 553   peer_connection_factory_ = nullptr; | 
| 552 | 554 | 
| 553   if (error != OK) | 555   if (error != OK) | 
| 554     event_handler_->OnWebrtcTransportError(error); | 556     event_handler_->OnWebrtcTransportError(error); | 
| 555 } | 557 } | 
| 556 | 558 | 
| 557 }  // namespace protocol | 559 }  // namespace protocol | 
| 558 }  // namespace remoting | 560 }  // namespace remoting | 
| OLD | NEW | 
|---|