OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #ifndef WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_ | 11 #ifndef WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_ |
12 #define WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_ | 12 #define WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_ |
13 | 13 |
14 #include <memory> | 14 #include <memory> |
15 #include <string> | 15 #include <string> |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "webrtc/base/buffer.h" | 18 #include "webrtc/base/buffer.h" |
19 #include "webrtc/base/bufferqueue.h" | 19 #include "webrtc/base/bufferqueue.h" |
20 #include "webrtc/base/constructormagic.h" | 20 #include "webrtc/base/constructormagic.h" |
21 #include "webrtc/base/sslstreamadapter.h" | 21 #include "webrtc/base/sslstreamadapter.h" |
22 #include "webrtc/base/stream.h" | 22 #include "webrtc/base/stream.h" |
23 #include "webrtc/p2p/base/dtlstransportinternal.h" | |
24 #include "webrtc/p2p/base/icetransportinternal.h" | 23 #include "webrtc/p2p/base/icetransportinternal.h" |
| 24 #include "webrtc/p2p/base/transportchannelimpl.h" |
25 | 25 |
26 namespace rtc { | 26 namespace rtc { |
27 class PacketTransportInterface; | 27 class PacketTransportInterface; |
28 } | 28 } |
29 | 29 |
30 namespace cricket { | 30 namespace cricket { |
31 | 31 |
32 // A bridge between a packet-oriented/transport-type interface on | 32 // A bridge between a packet-oriented/transport-type interface on |
33 // the bottom and a StreamInterface on the top. | 33 // the bottom and a StreamInterface on the top. |
34 class StreamInterfaceChannel : public rtc::StreamInterface { | 34 class StreamInterfaceChannel : public rtc::StreamInterface { |
35 public: | 35 public: |
36 explicit StreamInterfaceChannel(IceTransportInternal* ice_transport); | 36 explicit StreamInterfaceChannel(IceTransportInternal* channel); |
37 | 37 |
38 // Push in a packet; this gets pulled out from Read(). | 38 // Push in a packet; this gets pulled out from Read(). |
39 bool OnPacketReceived(const char* data, size_t size); | 39 bool OnPacketReceived(const char* data, size_t size); |
40 | 40 |
41 // Implementations of StreamInterface | 41 // Implementations of StreamInterface |
42 rtc::StreamState GetState() const override { return state_; } | 42 rtc::StreamState GetState() const override { return state_; } |
43 void Close() override; | 43 void Close() override; |
44 rtc::StreamResult Read(void* buffer, | 44 rtc::StreamResult Read(void* buffer, |
45 size_t buffer_len, | 45 size_t buffer_len, |
46 size_t* read, | 46 size_t* read, |
47 int* error) override; | 47 int* error) override; |
48 rtc::StreamResult Write(const void* data, | 48 rtc::StreamResult Write(const void* data, |
49 size_t data_len, | 49 size_t data_len, |
50 size_t* written, | 50 size_t* written, |
51 int* error) override; | 51 int* error) override; |
52 | 52 |
53 private: | 53 private: |
54 IceTransportInternal* ice_transport_; // owned by DtlsTransport | 54 IceTransportInternal* channel_; // owned by DtlsTransportChannelWrapper |
55 rtc::StreamState state_; | 55 rtc::StreamState state_; |
56 rtc::BufferQueue packets_; | 56 rtc::BufferQueue packets_; |
57 | 57 |
58 RTC_DISALLOW_COPY_AND_ASSIGN(StreamInterfaceChannel); | 58 RTC_DISALLOW_COPY_AND_ASSIGN(StreamInterfaceChannel); |
59 }; | 59 }; |
60 | 60 |
61 | 61 |
62 // This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style | 62 // This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style |
63 // packet-based interface, wrapping an existing TransportChannel instance | 63 // packet-based interface, wrapping an existing TransportChannel instance |
64 // (e.g a P2PTransportChannel) | 64 // (e.g a P2PTransportChannel) |
65 // Here's the way this works: | 65 // Here's the way this works: |
66 // | 66 // |
67 // DtlsTransport { | 67 // DtlsTransportChannelWrapper { |
68 // SSLStreamAdapter* dtls_ { | 68 // SSLStreamAdapter* dtls_ { |
69 // StreamInterfaceChannel downward_ { | 69 // StreamInterfaceChannel downward_ { |
70 // IceTransportInternal* ice_transport_; | 70 // TransportChannelImpl* channel_; |
71 // } | 71 // } |
72 // } | 72 // } |
73 // } | 73 // } |
74 // | 74 // |
75 // - Data which comes into DtlsTransport from the underlying | 75 // - Data which comes into DtlsTransportChannelWrapper from the underlying |
76 // ice_transport_ via OnReadPacket() is checked for whether it is DTLS | 76 // channel_ via OnReadPacket() is checked for whether it is DTLS |
77 // or not, and if it is, is passed to DtlsTransport::HandleDtlsPacket, | 77 // or not, and if it is, is passed to DtlsTransportChannelWrapper:: |
78 // which pushes it into to downward_. dtls_ is listening for events on | 78 // HandleDtlsPacket, which pushes it into to downward_. |
79 // downward_, so it immediately calls downward_->Read(). | 79 // dtls_ is listening for events on downward_, so it immediately calls |
| 80 // downward_->Read(). |
80 // | 81 // |
81 // - Data written to DtlsTransport is passed either to downward_ or directly | 82 // - Data written to DtlsTransportChannelWrapper is passed either to |
82 // to ice_transport_, depending on whether DTLS is negotiated and whether | 83 // downward_ or directly to channel_, depending on whether DTLS is |
83 // the flags include PF_SRTP_BYPASS | 84 // negotiated and whether the flags include PF_SRTP_BYPASS |
84 // | 85 // |
85 // - The SSLStreamAdapter writes to downward_->Write() which translates it | 86 // - The SSLStreamAdapter writes to downward_->Write() |
86 // into packet writes on ice_transport_. | 87 // which translates it into packet writes on channel_. |
87 class DtlsTransport : public DtlsTransportInternal { | 88 class DtlsTransportChannelWrapper : public TransportChannelImpl { |
88 public: | 89 public: |
89 // The parameters here is: | 90 // The parameters here are: |
90 // ice_transport -- the ice transport we are wrapping | 91 // channel -- the TransportChannel we are wrapping |
91 explicit DtlsTransport(IceTransportInternal* ice_transport); | 92 explicit DtlsTransportChannelWrapper(IceTransportInternal* channel); |
92 ~DtlsTransport() override; | 93 ~DtlsTransportChannelWrapper() override; |
93 | 94 |
94 DtlsTransportState dtls_state() const override { return dtls_state_; } | 95 void SetIceRole(IceRole role) override { channel_->SetIceRole(role); } |
95 | 96 IceRole GetIceRole() const override { return channel_->GetIceRole(); } |
96 const std::string& transport_name() const override { return transport_name_; } | |
97 | |
98 int component() const override { return component_; } | |
99 | |
100 // Returns false if no local certificate was set, or if the peer doesn't | |
101 // support DTLS. | |
102 bool IsDtlsActive() const override { return dtls_active_; } | |
103 | |
104 bool SetLocalCertificate( | 97 bool SetLocalCertificate( |
105 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override; | 98 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override; |
106 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override; | 99 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override; |
107 | 100 |
108 bool SetRemoteFingerprint(const std::string& digest_alg, | 101 bool SetRemoteFingerprint(const std::string& digest_alg, |
109 const uint8_t* digest, | 102 const uint8_t* digest, |
110 size_t digest_len) override; | 103 size_t digest_len) override; |
111 | 104 |
| 105 // Returns false if no local certificate was set, or if the peer doesn't |
| 106 // support DTLS. |
| 107 bool IsDtlsActive() const override { return dtls_active_; } |
112 | 108 |
113 // Called to send a packet (via DTLS, if turned on). | 109 // Called to send a packet (via DTLS, if turned on). |
114 int SendPacket(const char* data, | 110 int SendPacket(const char* data, |
115 size_t size, | 111 size_t size, |
116 const rtc::PacketOptions& options, | 112 const rtc::PacketOptions& options, |
117 int flags) override; | 113 int flags) override; |
118 | 114 |
| 115 // TransportChannel calls that we forward to the wrapped transport. |
| 116 int SetOption(rtc::Socket::Option opt, int value) override { |
| 117 return channel_->SetOption(opt, value); |
| 118 } |
119 bool GetOption(rtc::Socket::Option opt, int* value) override { | 119 bool GetOption(rtc::Socket::Option opt, int* value) override { |
120 return ice_transport_->GetOption(opt, value); | 120 return channel_->GetOption(opt, value); |
| 121 } |
| 122 int GetError() override { return channel_->GetError(); } |
| 123 bool GetStats(ConnectionInfos* infos) override { |
| 124 return channel_->GetStats(infos); |
121 } | 125 } |
122 | 126 |
123 virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version); | 127 virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version); |
124 | 128 |
125 // Set up the ciphers to use for DTLS-SRTP. If this method is not called | 129 // Set up the ciphers to use for DTLS-SRTP. If this method is not called |
126 // before DTLS starts, or |ciphers| is empty, SRTP keys won't be negotiated. | 130 // before DTLS starts, or |ciphers| is empty, SRTP keys won't be negotiated. |
127 // This method should be called before SetupDtls. | 131 // This method should be called before SetupDtls. |
128 bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override; | 132 bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override; |
129 | 133 |
130 // Find out which DTLS-SRTP cipher was negotiated | 134 // Find out which DTLS-SRTP cipher was negotiated |
131 bool GetSrtpCryptoSuite(int* cipher) override; | 135 bool GetSrtpCryptoSuite(int* cipher) override; |
132 | 136 |
133 bool GetSslRole(rtc::SSLRole* role) const override; | 137 bool GetSslRole(rtc::SSLRole* role) const override; |
134 bool SetSslRole(rtc::SSLRole role) override; | 138 bool SetSslRole(rtc::SSLRole role) override; |
135 | 139 |
136 // Find out which DTLS cipher was negotiated | 140 // Find out which DTLS cipher was negotiated |
137 bool GetSslCipherSuite(int* cipher) override; | 141 bool GetSslCipherSuite(int* cipher) override; |
138 | 142 |
139 // Once DTLS has been established, this method retrieves the certificate in | 143 // Once DTLS has been established, this method retrieves the certificate in |
140 // use by the remote peer, for use in external identity verification. | 144 // use by the remote peer, for use in external identity verification. |
141 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate() const override; | 145 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate() const override; |
142 | 146 |
143 // Once DTLS has established (i.e., this ice_transport is writable), this | 147 // Once DTLS has established (i.e., this channel is writable), this method |
144 // method extracts the keys negotiated during the DTLS handshake, for use in | 148 // extracts the keys negotiated during the DTLS handshake, for use in external |
145 // external encryption. DTLS-SRTP uses this to extract the needed SRTP keys. | 149 // encryption. DTLS-SRTP uses this to extract the needed SRTP keys. |
146 // See the SSLStreamAdapter documentation for info on the specific parameters. | 150 // See the SSLStreamAdapter documentation for info on the specific parameters. |
147 bool ExportKeyingMaterial(const std::string& label, | 151 bool ExportKeyingMaterial(const std::string& label, |
148 const uint8_t* context, | 152 const uint8_t* context, |
149 size_t context_len, | 153 size_t context_len, |
150 bool use_context, | 154 bool use_context, |
151 uint8_t* result, | 155 uint8_t* result, |
152 size_t result_len) override { | 156 size_t result_len) override { |
153 return (dtls_.get()) ? dtls_->ExportKeyingMaterial(label, context, | 157 return (dtls_.get()) ? dtls_->ExportKeyingMaterial(label, context, |
154 context_len, | 158 context_len, |
155 use_context, | 159 use_context, |
156 result, result_len) | 160 result, result_len) |
157 : false; | 161 : false; |
158 } | 162 } |
159 | 163 |
160 IceTransportInternal* ice_transport() override { return ice_transport_; } | 164 // TransportChannelImpl calls. |
| 165 IceTransportState GetState() const override { return channel_->GetState(); } |
| 166 void SetIceTiebreaker(uint64_t tiebreaker) override { |
| 167 channel_->SetIceTiebreaker(tiebreaker); |
| 168 } |
| 169 void SetIceParameters(const IceParameters& ice_params) override { |
| 170 channel_->SetIceParameters(ice_params); |
| 171 } |
| 172 void SetRemoteIceParameters(const IceParameters& ice_params) override { |
| 173 channel_->SetRemoteIceParameters(ice_params); |
| 174 } |
| 175 void SetRemoteIceMode(IceMode mode) override { |
| 176 channel_->SetRemoteIceMode(mode); |
| 177 } |
| 178 |
| 179 void MaybeStartGathering() override { channel_->MaybeStartGathering(); } |
| 180 |
| 181 IceGatheringState gathering_state() const override { |
| 182 return channel_->gathering_state(); |
| 183 } |
| 184 |
| 185 void AddRemoteCandidate(const Candidate& candidate) override { |
| 186 channel_->AddRemoteCandidate(candidate); |
| 187 } |
| 188 void RemoveRemoteCandidate(const Candidate& candidate) override { |
| 189 channel_->RemoveRemoteCandidate(candidate); |
| 190 } |
| 191 |
| 192 void SetMetricsObserver(webrtc::MetricsObserverInterface* observer) override { |
| 193 channel_->SetMetricsObserver(observer); |
| 194 } |
| 195 |
| 196 void SetIceConfig(const IceConfig& config) override { |
| 197 channel_->SetIceConfig(config); |
| 198 } |
| 199 |
| 200 // Needed by DtlsTransport. |
| 201 IceTransportInternal* channel() { return channel_; } |
161 | 202 |
162 // For informational purposes. Tells if the DTLS handshake has finished. | 203 // For informational purposes. Tells if the DTLS handshake has finished. |
163 // This may be true even if writable() is false, if the remote fingerprint | 204 // This may be true even if writable() is false, if the remote fingerprint |
164 // has not yet been verified. | 205 // has not yet been verified. |
165 bool IsDtlsConnected(); | 206 bool IsDtlsConnected(); |
166 | 207 |
167 bool receiving() const override { return receiving_; } | |
168 | |
169 bool writable() const override { return writable_; } | |
170 | |
171 int GetError() override { return ice_transport_->GetError(); } | |
172 | |
173 int SetOption(rtc::Socket::Option opt, int value) override { | |
174 return ice_transport_->SetOption(opt, value); | |
175 } | |
176 | |
177 bool SetSrtpCiphers(const std::vector<std::string>& ciphers) override { | |
178 std::vector<int> crypto_suites; | |
179 for (const auto cipher : ciphers) { | |
180 crypto_suites.push_back(rtc::SrtpCryptoSuiteFromName(cipher)); | |
181 } | |
182 return SetSrtpCryptoSuites(crypto_suites); | |
183 } | |
184 | |
185 std::string ToString() const { | |
186 const char RECEIVING_ABBREV[2] = {'_', 'R'}; | |
187 const char WRITABLE_ABBREV[2] = {'_', 'W'}; | |
188 std::stringstream ss; | |
189 ss << "DtlsTransport[" << transport_name_ << "|" << component_ << "|" | |
190 << RECEIVING_ABBREV[receiving()] << WRITABLE_ABBREV[writable()] << "]"; | |
191 return ss.str(); | |
192 } | |
193 | |
194 private: | 208 private: |
195 void OnWritableState(rtc::PacketTransportInterface* transport); | 209 void OnWritableState(rtc::PacketTransportInterface* transport); |
196 void OnReadPacket(rtc::PacketTransportInterface* transport, | 210 void OnReadPacket(rtc::PacketTransportInterface* transport, |
197 const char* data, | 211 const char* data, |
198 size_t size, | 212 size_t size, |
199 const rtc::PacketTime& packet_time, | 213 const rtc::PacketTime& packet_time, |
200 int flags); | 214 int flags); |
201 void OnSentPacket(rtc::PacketTransportInterface* transport, | 215 void OnSentPacket(rtc::PacketTransportInterface* transport, |
202 const rtc::SentPacket& sent_packet); | 216 const rtc::SentPacket& sent_packet); |
203 void OnReadyToSend(rtc::PacketTransportInterface* transport); | 217 void OnReadyToSend(rtc::PacketTransportInterface* transport); |
204 void OnReceivingState(rtc::PacketTransportInterface* transport); | 218 void OnReceivingState(rtc::PacketTransportInterface* transport); |
205 void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err); | 219 void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err); |
206 bool SetupDtls(); | 220 bool SetupDtls(); |
207 void MaybeStartDtls(); | 221 void MaybeStartDtls(); |
208 bool HandleDtlsPacket(const char* data, size_t size); | 222 bool HandleDtlsPacket(const char* data, size_t size); |
| 223 void OnGatheringState(IceTransportInternal* channel); |
| 224 void OnCandidateGathered(IceTransportInternal* channel, const Candidate& c); |
| 225 void OnCandidatesRemoved(IceTransportInternal* channel, |
| 226 const Candidates& candidates); |
| 227 void OnRoleConflict(IceTransportInternal* channel); |
| 228 void OnRouteChange(IceTransportInternal* channel, const Candidate& candidate); |
| 229 void OnSelectedCandidatePairChanged( |
| 230 IceTransportInternal* channel, |
| 231 CandidatePairInterface* selected_candidate_pair, |
| 232 int last_sent_packet_id, |
| 233 bool ready_to_send); |
| 234 void OnChannelStateChanged(IceTransportInternal* channel); |
209 void OnDtlsHandshakeError(rtc::SSLHandshakeError error); | 235 void OnDtlsHandshakeError(rtc::SSLHandshakeError error); |
210 | 236 |
211 void set_receiving(bool receiving); | |
212 void set_writable(bool writable); | |
213 // Sets the DTLS state, signaling if necessary. | |
214 void set_dtls_state(DtlsTransportState state); | |
215 | |
216 std::string transport_name_; | |
217 int component_; | |
218 DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW; | |
219 rtc::Thread* network_thread_; // Everything should occur on this thread. | 237 rtc::Thread* network_thread_; // Everything should occur on this thread. |
220 // Underlying ice_transport, not owned by this class. | 238 // Underlying channel, not owned by this class. |
221 IceTransportInternal* const ice_transport_; | 239 IceTransportInternal* const channel_; |
222 std::unique_ptr<rtc::SSLStreamAdapter> dtls_; // The DTLS stream | 240 std::unique_ptr<rtc::SSLStreamAdapter> dtls_; // The DTLS stream |
223 StreamInterfaceChannel* | 241 StreamInterfaceChannel* downward_; // Wrapper for channel_, owned by dtls_. |
224 downward_; // Wrapper for ice_transport_, owned by dtls_. | |
225 std::vector<int> srtp_ciphers_; // SRTP ciphers to use with DTLS. | 242 std::vector<int> srtp_ciphers_; // SRTP ciphers to use with DTLS. |
226 bool dtls_active_ = false; | 243 bool dtls_active_ = false; |
227 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_; | 244 rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_; |
228 rtc::SSLRole ssl_role_; | 245 rtc::SSLRole ssl_role_; |
229 rtc::SSLProtocolVersion ssl_max_version_; | 246 rtc::SSLProtocolVersion ssl_max_version_; |
230 rtc::Buffer remote_fingerprint_value_; | 247 rtc::Buffer remote_fingerprint_value_; |
231 std::string remote_fingerprint_algorithm_; | 248 std::string remote_fingerprint_algorithm_; |
232 | 249 |
233 // Cached DTLS ClientHello packet that was received before we started the | 250 // Cached DTLS ClientHello packet that was received before we started the |
234 // DTLS handshake. This could happen if the hello was received before the | 251 // DTLS handshake. This could happen if the hello was received before the |
235 // ice transport became writable, or before a remote fingerprint was received. | 252 // transport channel became writable, or before a remote fingerprint was |
| 253 // received. |
236 rtc::Buffer cached_client_hello_; | 254 rtc::Buffer cached_client_hello_; |
237 | 255 |
238 bool receiving_ = false; | 256 RTC_DISALLOW_COPY_AND_ASSIGN(DtlsTransportChannelWrapper); |
239 bool writable_ = false; | |
240 | |
241 RTC_DISALLOW_COPY_AND_ASSIGN(DtlsTransport); | |
242 }; | 257 }; |
243 | 258 |
244 } // namespace cricket | 259 } // namespace cricket |
245 | 260 |
246 #endif // WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_ | 261 #endif // WEBRTC_P2P_BASE_DTLSTRANSPORTCHANNEL_H_ |
OLD | NEW |