| /* |
| * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include "webrtc/p2p/quic/quictransport.h" |
| |
| #include "webrtc/p2p/base/p2ptransportchannel.h" |
| |
| namespace cricket { |
| |
| QuicTransport::QuicTransport( |
| const std::string& name, |
| PortAllocator* allocator, |
| const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) |
| : Transport(name, allocator), local_certificate_(certificate) {} |
| |
| QuicTransport::~QuicTransport() { |
| DestroyAllChannels(); |
| } |
| |
| void QuicTransport::SetLocalCertificate( |
| const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
| local_certificate_ = certificate; |
| } |
| bool QuicTransport::GetLocalCertificate( |
| rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { |
| if (!local_certificate_) { |
| return false; |
| } |
| *certificate = local_certificate_; |
| return true; |
| } |
| |
| bool QuicTransport::ApplyLocalTransportDescription( |
| TransportChannelImpl* channel, |
| std::string* error_desc) { |
| rtc::SSLFingerprint* local_fp = |
| local_description()->identity_fingerprint.get(); |
| if (!VerifyCertificateFingerprint(local_certificate_.get(), local_fp, |
| error_desc)) { |
| return false; |
| } |
| if (!channel->SetLocalCertificate(local_certificate_)) { |
| return BadTransportDescription("Failed to set local identity.", error_desc); |
| } |
| return Transport::ApplyLocalTransportDescription(channel, error_desc); |
| } |
| |
| bool QuicTransport::NegotiateTransportDescription(ContentAction action, |
| std::string* error_desc) { |
| if (!local_description() || !remote_description()) { |
| const std::string msg = |
| "Local and Remote description must be set before " |
| "transport descriptions are negotiated"; |
| return BadTransportDescription(msg, error_desc); |
| } |
| rtc::SSLFingerprint* local_fp = |
| local_description()->identity_fingerprint.get(); |
| rtc::SSLFingerprint* remote_fp = |
| remote_description()->identity_fingerprint.get(); |
| if (!local_fp || !remote_fp) { |
| return BadTransportDescription("Fingerprints must be supplied for QUIC.", |
| error_desc); |
| } |
| remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); |
| if (!NegotiateRole(action, &local_role_, error_desc)) { |
| return false; |
| } |
| // Now run the negotiation for the Transport class. |
| return Transport::NegotiateTransportDescription(action, error_desc); |
| } |
| |
| QuicTransportChannel* QuicTransport::CreateTransportChannel(int component) { |
| P2PTransportChannel* ice_channel = |
| new P2PTransportChannel(name(), component, port_allocator()); |
| return new QuicTransportChannel(ice_channel); |
| } |
| |
| void QuicTransport::DestroyTransportChannel(TransportChannelImpl* channel) { |
| delete channel; |
| } |
| |
| bool QuicTransport::GetSslRole(rtc::SSLRole* ssl_role) const { |
| ASSERT(ssl_role != NULL); |
| *ssl_role = local_role_; |
| return true; |
| } |
| |
| bool QuicTransport::ApplyNegotiatedTransportDescription( |
| TransportChannelImpl* channel, |
| std::string* error_desc) { |
| // Set ssl role and remote fingerprint. These are required for QUIC setup. |
| if (!channel->SetSslRole(local_role_)) { |
| return BadTransportDescription("Failed to set ssl role for the channel.", |
| error_desc); |
| } |
| // Apply remote fingerprint. |
| if (!channel->SetRemoteFingerprint( |
| remote_fingerprint_->algorithm, |
| reinterpret_cast<const uint8_t*>(remote_fingerprint_->digest.data()), |
| remote_fingerprint_->digest.size())) { |
| return BadTransportDescription("Failed to apply remote fingerprint.", |
| error_desc); |
| } |
| return Transport::ApplyNegotiatedTransportDescription(channel, error_desc); |
| } |
| |
| } // namespace cricket |