OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
| 3 * |
| 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 |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include "webrtc/p2p/quic/quictransport.h" |
| 12 |
| 13 #include "webrtc/p2p/base/p2ptransportchannel.h" |
| 14 |
| 15 namespace cricket { |
| 16 |
| 17 QuicTransport::QuicTransport( |
| 18 const std::string& name, |
| 19 PortAllocator* allocator, |
| 20 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) |
| 21 : Transport(name, allocator), |
| 22 certificate_(certificate), |
| 23 secure_role_(rtc::SSL_CLIENT) {} |
| 24 |
| 25 QuicTransport::~QuicTransport() { |
| 26 DestroyAllChannels(); // Must be called to avoid assertion error. |
| 27 } |
| 28 |
| 29 void QuicTransport::SetLocalCertificate( |
| 30 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
| 31 certificate_ = certificate; |
| 32 } |
| 33 bool QuicTransport::GetLocalCertificate( |
| 34 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { |
| 35 if (!certificate_) |
| 36 return false; |
| 37 |
| 38 *certificate = certificate_; |
| 39 return true; |
| 40 } |
| 41 |
| 42 bool QuicTransport::ApplyLocalTransportDescription( |
| 43 TransportChannelImpl* channel, |
| 44 std::string* error_desc) { |
| 45 rtc::SSLFingerprint* local_fp = |
| 46 local_description()->identity_fingerprint.get(); |
| 47 |
| 48 if (local_fp) { |
| 49 // Sanity check local fingerprint. |
| 50 if (certificate_) { |
| 51 rtc::scoped_ptr<rtc::SSLFingerprint> local_fp_tmp( |
| 52 rtc::SSLFingerprint::Create(local_fp->algorithm, |
| 53 certificate_->identity())); |
| 54 ASSERT(local_fp_tmp.get() != NULL); |
| 55 if (!(*local_fp_tmp == *local_fp)) { |
| 56 std::ostringstream desc; |
| 57 desc << "Local fingerprint does not match identity. Expected: "; |
| 58 desc << local_fp_tmp->ToString(); |
| 59 desc << " Got: " << local_fp->ToString(); |
| 60 return BadTransportDescription(desc.str(), error_desc); |
| 61 } |
| 62 } else { |
| 63 return BadTransportDescription( |
| 64 "Local fingerprint provided but no identity available.", error_desc); |
| 65 } |
| 66 } else { |
| 67 certificate_ = nullptr; |
| 68 } |
| 69 |
| 70 if (!channel->SetLocalCertificate(certificate_)) { |
| 71 return BadTransportDescription("Failed to set local identity.", error_desc); |
| 72 } |
| 73 |
| 74 return Transport::ApplyLocalTransportDescription(channel, error_desc); |
| 75 } |
| 76 |
| 77 bool QuicTransport::NegotiateTransportDescription(ContentAction local_role, |
| 78 std::string* error_desc) { |
| 79 if (!local_description() || !remote_description()) { |
| 80 const std::string msg = |
| 81 "Local and Remote description must be set before " |
| 82 "transport descriptions are negotiated"; |
| 83 return BadTransportDescription(msg, error_desc); |
| 84 } |
| 85 |
| 86 rtc::SSLFingerprint* remote_fp = |
| 87 remote_description()->identity_fingerprint.get(); |
| 88 |
| 89 if (!remote_fp) { |
| 90 return BadTransportDescription("Remote fingerprint not supplied.", |
| 91 error_desc); |
| 92 } |
| 93 |
| 94 remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); |
| 95 |
| 96 // TODO(pthatcher): Move all the negotiation up into PeerConnection and |
| 97 // out of the Transport code. Just have a SetRole or similar method here. |
| 98 ConnectionRole local_connection_role = local_description()->connection_role; |
| 99 ConnectionRole remote_connection_role = remote_description()->connection_role; |
| 100 |
| 101 bool is_remote_server = false; |
| 102 if (local_role == CA_OFFER) { |
| 103 if (local_connection_role != CONNECTIONROLE_ACTPASS) { |
| 104 return BadTransportDescription( |
| 105 "Offerer must use actpass value for setup attribute.", error_desc); |
| 106 } |
| 107 |
| 108 if (remote_connection_role == CONNECTIONROLE_ACTIVE || |
| 109 remote_connection_role == CONNECTIONROLE_PASSIVE || |
| 110 remote_connection_role == CONNECTIONROLE_NONE) { |
| 111 is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); |
| 112 } else { |
| 113 const std::string msg = |
| 114 "Answerer must use either active or passive value " |
| 115 "for setup attribute."; |
| 116 return BadTransportDescription(msg, error_desc); |
| 117 } |
| 118 // If remote is NONE or ACTIVE it will act as client. |
| 119 } else { |
| 120 if (remote_connection_role != CONNECTIONROLE_ACTPASS && |
| 121 remote_connection_role != CONNECTIONROLE_NONE) { |
| 122 return BadTransportDescription( |
| 123 "Offerer must use actpass value for setup attribute.", error_desc); |
| 124 } |
| 125 |
| 126 if (local_connection_role != CONNECTIONROLE_ACTIVE && |
| 127 local_connection_role != CONNECTIONROLE_PASSIVE) { |
| 128 const std::string msg = |
| 129 "Answerer must use either active or passive value " |
| 130 "for setup attribute."; |
| 131 return BadTransportDescription(msg, error_desc); |
| 132 } |
| 133 // If local is passive, local will act as server. |
| 134 is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); |
| 135 } |
| 136 |
| 137 secure_role_ = is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER; |
| 138 |
| 139 // Now run the negotiation for the Transport class. |
| 140 return Transport::NegotiateTransportDescription(local_role, error_desc); |
| 141 } |
| 142 |
| 143 QuicTransportChannel* QuicTransport::CreateTransportChannel(int component) { |
| 144 P2PTransportChannel* ice_channel = |
| 145 new P2PTransportChannel(name(), component, port_allocator()); |
| 146 QuicTransportChannel* quic_channel = new QuicTransportChannel(ice_channel); |
| 147 ice_channel_by_quic_channel_[quic_channel] = ice_channel; |
| 148 return quic_channel; |
| 149 } |
| 150 |
| 151 void QuicTransport::DestroyTransportChannel(TransportChannelImpl* channel) { |
| 152 const auto& kv = ice_channel_by_quic_channel_.find(channel); |
| 153 RTC_DCHECK(kv != ice_channel_by_quic_channel_.end()); |
| 154 delete kv->first; |
| 155 delete kv->second; |
| 156 } |
| 157 |
| 158 bool QuicTransport::GetSslRole(rtc::SSLRole* ssl_role) const { |
| 159 ASSERT(ssl_role != NULL); |
| 160 *ssl_role = secure_role_; |
| 161 return true; |
| 162 } |
| 163 |
| 164 bool QuicTransport::ApplyNegotiatedTransportDescription( |
| 165 TransportChannelImpl* channel, |
| 166 std::string* error_desc) { |
| 167 // Set ssl role and remote fingerprint. These are required for QUIC setup. |
| 168 if (!channel->SetSslRole(secure_role_)) { |
| 169 return BadTransportDescription("Failed to set ssl role for the channel.", |
| 170 error_desc); |
| 171 } |
| 172 // Apply remote fingerprint. |
| 173 if (!channel->SetRemoteFingerprint( |
| 174 remote_fingerprint_->algorithm, |
| 175 reinterpret_cast<const uint8_t*>(remote_fingerprint_->digest.data()), |
| 176 remote_fingerprint_->digest.size())) { |
| 177 return BadTransportDescription("Failed to apply remote fingerprint.", |
| 178 error_desc); |
| 179 } |
| 180 return Transport::ApplyNegotiatedTransportDescription(channel, error_desc); |
| 181 } |
| 182 |
| 183 } // namespace cricket |
OLD | NEW |