Index: webrtc/p2p/quic/quictransport.cc |
diff --git a/webrtc/p2p/quic/quictransport.cc b/webrtc/p2p/quic/quictransport.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b747ec55edb9c0821fc6056e1fbe16b4191616a5 |
--- /dev/null |
+++ b/webrtc/p2p/quic/quictransport.cc |
@@ -0,0 +1,183 @@ |
+/* |
+ * 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), |
+ certificate_(certificate), |
+ secure_role_(rtc::SSL_CLIENT) {} |
pthatcher1
2016/04/12 00:13:12
You can do this in the .h:
secure_role_ = rtc::SS
mikescarlett
2016/04/12 19:28:17
Done.
|
+ |
+QuicTransport::~QuicTransport() { |
+ DestroyAllChannels(); // Must be called to avoid assertion error. |
+} |
+ |
+void QuicTransport::SetLocalCertificate( |
+ const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { |
+ certificate_ = certificate; |
+} |
+bool QuicTransport::GetLocalCertificate( |
+ rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { |
+ if (!certificate_) |
+ return false; |
pthatcher1
2016/04/12 00:13:12
{}s please
mikescarlett
2016/04/12 19:28:17
Done.
|
+ |
+ *certificate = certificate_; |
+ return true; |
+} |
+ |
+bool QuicTransport::ApplyLocalTransportDescription( |
+ TransportChannelImpl* channel, |
+ std::string* error_desc) { |
+ rtc::SSLFingerprint* local_fp = |
+ local_description()->identity_fingerprint.get(); |
+ |
+ if (local_fp) { |
+ // Sanity check local fingerprint. |
+ if (certificate_) { |
+ rtc::scoped_ptr<rtc::SSLFingerprint> local_fp_tmp( |
+ rtc::SSLFingerprint::Create(local_fp->algorithm, |
+ certificate_->identity())); |
+ ASSERT(local_fp_tmp.get() != NULL); |
+ if (!(*local_fp_tmp == *local_fp)) { |
+ std::ostringstream desc; |
+ desc << "Local fingerprint does not match identity. Expected: "; |
+ desc << local_fp_tmp->ToString(); |
+ desc << " Got: " << local_fp->ToString(); |
+ return BadTransportDescription(desc.str(), error_desc); |
+ } |
+ } else { |
+ return BadTransportDescription( |
+ "Local fingerprint provided but no identity available.", error_desc); |
+ } |
+ } else { |
+ certificate_ = nullptr; |
+ } |
pthatcher1
2016/04/12 00:13:12
A helper method of VerfiyCertificateFingerprint(ce
mikescarlett
2016/04/12 19:28:17
Done.
|
+ |
+ if (!channel->SetLocalCertificate(certificate_)) { |
+ return BadTransportDescription("Failed to set local identity.", error_desc); |
+ } |
+ |
+ return Transport::ApplyLocalTransportDescription(channel, error_desc); |
+} |
+ |
+bool QuicTransport::NegotiateTransportDescription(ContentAction local_role, |
+ 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* remote_fp = |
+ remote_description()->identity_fingerprint.get(); |
+ |
+ if (!remote_fp) { |
+ return BadTransportDescription("Remote fingerprint not supplied.", |
+ error_desc); |
+ } |
+ |
+ remote_fingerprint_.reset(new rtc::SSLFingerprint(*remote_fp)); |
+ |
+ // TODO(pthatcher): Move all the negotiation up into PeerConnection and |
+ // out of the Transport code. Just have a SetRole or similar method here. |
+ ConnectionRole local_connection_role = local_description()->connection_role; |
+ ConnectionRole remote_connection_role = remote_description()->connection_role; |
+ |
+ bool is_remote_server = false; |
+ if (local_role == CA_OFFER) { |
+ if (local_connection_role != CONNECTIONROLE_ACTPASS) { |
+ return BadTransportDescription( |
+ "Offerer must use actpass value for setup attribute.", error_desc); |
+ } |
+ |
+ if (remote_connection_role == CONNECTIONROLE_ACTIVE || |
+ remote_connection_role == CONNECTIONROLE_PASSIVE || |
+ remote_connection_role == CONNECTIONROLE_NONE) { |
+ is_remote_server = (remote_connection_role == CONNECTIONROLE_PASSIVE); |
+ } else { |
+ const std::string msg = |
+ "Answerer must use either active or passive value " |
+ "for setup attribute."; |
+ return BadTransportDescription(msg, error_desc); |
+ } |
+ // If remote is NONE or ACTIVE it will act as client. |
+ } else { |
+ if (remote_connection_role != CONNECTIONROLE_ACTPASS && |
+ remote_connection_role != CONNECTIONROLE_NONE) { |
+ return BadTransportDescription( |
+ "Offerer must use actpass value for setup attribute.", error_desc); |
+ } |
+ |
+ if (local_connection_role != CONNECTIONROLE_ACTIVE && |
+ local_connection_role != CONNECTIONROLE_PASSIVE) { |
+ const std::string msg = |
+ "Answerer must use either active or passive value " |
+ "for setup attribute."; |
+ return BadTransportDescription(msg, error_desc); |
+ } |
+ // If local is passive, local will act as server. |
+ is_remote_server = (local_connection_role == CONNECTIONROLE_ACTIVE); |
+ } |
+ |
+ secure_role_ = is_remote_server ? rtc::SSL_CLIENT : rtc::SSL_SERVER; |
pthatcher1
2016/04/12 00:13:12
A helper method NegotiateRole(local_description(),
mikescarlett
2016/04/12 19:28:17
I modified the method signature since local_descri
|
+ |
+ // Now run the negotiation for the Transport class. |
+ return Transport::NegotiateTransportDescription(local_role, error_desc); |
+} |
+ |
+QuicTransportChannel* QuicTransport::CreateTransportChannel(int component) { |
+ P2PTransportChannel* ice_channel = |
+ new P2PTransportChannel(name(), component, port_allocator()); |
+ QuicTransportChannel* quic_channel = new QuicTransportChannel(ice_channel); |
+ ice_channel_by_quic_channel_[quic_channel] = ice_channel; |
+ return quic_channel; |
+} |
+ |
+void QuicTransport::DestroyTransportChannel(TransportChannelImpl* channel) { |
+ const auto& kv = ice_channel_by_quic_channel_.find(channel); |
+ RTC_DCHECK(kv != ice_channel_by_quic_channel_.end()); |
pthatcher1
2016/04/12 00:13:12
Why do we have to store this? Why not just get th
mikescarlett
2016/04/12 19:28:17
That's fine. I implemented that but named the meth
|
+ delete kv->first; |
+ delete kv->second; |
+} |
+ |
+bool QuicTransport::GetSslRole(rtc::SSLRole* ssl_role) const { |
+ ASSERT(ssl_role != NULL); |
+ *ssl_role = secure_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(secure_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 |