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) {} | |
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.
| |
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; | |
pthatcher1
2016/04/12 00:13:12
{}s please
mikescarlett
2016/04/12 19:28:17
Done.
| |
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 } | |
pthatcher1
2016/04/12 00:13:12
A helper method of VerfiyCertificateFingerprint(ce
mikescarlett
2016/04/12 19:28:17
Done.
| |
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; | |
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
| |
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()); | |
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
| |
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 |