Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / dtlstransportchannel.h
1 /*
2  * libjingle
3  * Copyright 2011, Google Inc.
4  * Copyright 2011, RTFM, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright notice,
12  *     this list of conditions and the following disclaimer in the documentation
13  *     and/or other materials provided with the distribution.
14  *  3. The name of the author may not be used to endorse or promote products
15  *     derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #ifndef TALK_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
30 #define TALK_P2P_BASE_DTLSTRANSPORTCHANNEL_H_
31
32 #include <string>
33 #include <vector>
34
35 #include "talk/p2p/base/transportchannelimpl.h"
36 #include "webrtc/base/buffer.h"
37 #include "webrtc/base/scoped_ptr.h"
38 #include "webrtc/base/sslstreamadapter.h"
39 #include "webrtc/base/stream.h"
40
41 namespace cricket {
42
43 // A bridge between a packet-oriented/channel-type interface on
44 // the bottom and a StreamInterface on the top.
45 class StreamInterfaceChannel : public rtc::StreamInterface,
46                                public sigslot::has_slots<> {
47  public:
48   StreamInterfaceChannel(rtc::Thread* owner, TransportChannel* channel)
49       : channel_(channel),
50         state_(rtc::SS_OPEN),
51         fifo_(kFifoSize, owner) {
52     fifo_.SignalEvent.connect(this, &StreamInterfaceChannel::OnEvent);
53   }
54
55   // Push in a packet; this gets pulled out from Read().
56   bool OnPacketReceived(const char* data, size_t size);
57
58   // Implementations of StreamInterface
59   virtual rtc::StreamState GetState() const { return state_; }
60   virtual void Close() { state_ = rtc::SS_CLOSED; }
61   virtual rtc::StreamResult Read(void* buffer, size_t buffer_len,
62                                        size_t* read, int* error);
63   virtual rtc::StreamResult Write(const void* data, size_t data_len,
64                                         size_t* written, int* error);
65
66  private:
67   static const size_t kFifoSize = 8192;
68
69   // Forward events
70   virtual void OnEvent(rtc::StreamInterface* stream, int sig, int err);
71
72   TransportChannel* channel_;  // owned by DtlsTransportChannelWrapper
73   rtc::StreamState state_;
74   rtc::FifoBuffer fifo_;
75
76   DISALLOW_COPY_AND_ASSIGN(StreamInterfaceChannel);
77 };
78
79
80 // This class provides a DTLS SSLStreamAdapter inside a TransportChannel-style
81 // packet-based interface, wrapping an existing TransportChannel instance
82 // (e.g a P2PTransportChannel)
83 // Here's the way this works:
84 //
85 //   DtlsTransportChannelWrapper {
86 //       SSLStreamAdapter* dtls_ {
87 //           StreamInterfaceChannel downward_ {
88 //               TransportChannelImpl* channel_;
89 //           }
90 //       }
91 //   }
92 //
93 //   - Data which comes into DtlsTransportChannelWrapper from the underlying
94 //     channel_ via OnReadPacket() is checked for whether it is DTLS
95 //     or not, and if it is, is passed to DtlsTransportChannelWrapper::
96 //     HandleDtlsPacket, which pushes it into to downward_.
97 //     dtls_ is listening for events on downward_, so it immediately calls
98 //     downward_->Read().
99 //
100 //   - Data written to DtlsTransportChannelWrapper is passed either to
101 //      downward_ or directly to channel_, depending on whether DTLS is
102 //     negotiated and whether the flags include PF_SRTP_BYPASS
103 //
104 //   - The SSLStreamAdapter writes to downward_->Write()
105 //     which translates it into packet writes on channel_.
106 class DtlsTransportChannelWrapper : public TransportChannelImpl {
107  public:
108     enum State {
109       STATE_NONE,      // No state or rejected.
110       STATE_OFFERED,   // Our identity has been set.
111       STATE_ACCEPTED,  // The other side sent a fingerprint.
112       STATE_STARTED,   // We are negotiating.
113       STATE_OPEN,      // Negotiation complete.
114       STATE_CLOSED     // Connection closed.
115     };
116
117   // The parameters here are:
118   // transport -- the DtlsTransport that created us
119   // channel -- the TransportChannel we are wrapping
120   DtlsTransportChannelWrapper(Transport* transport,
121                               TransportChannelImpl* channel);
122   virtual ~DtlsTransportChannelWrapper();
123
124   virtual void SetIceRole(IceRole role) {
125     channel_->SetIceRole(role);
126   }
127   virtual IceRole GetIceRole() const {
128     return channel_->GetIceRole();
129   }
130   virtual size_t GetConnectionCount() const {
131     return channel_->GetConnectionCount();
132   }
133   virtual bool SetLocalIdentity(rtc::SSLIdentity *identity);
134   virtual bool GetLocalIdentity(rtc::SSLIdentity** identity) const;
135
136   virtual bool SetRemoteFingerprint(const std::string& digest_alg,
137                                     const uint8* digest,
138                                     size_t digest_len);
139   virtual bool IsDtlsActive() const { return dtls_state_ != STATE_NONE; }
140
141   // Called to send a packet (via DTLS, if turned on).
142   virtual int SendPacket(const char* data, size_t size,
143                          const rtc::PacketOptions& options,
144                          int flags);
145
146   // TransportChannel calls that we forward to the wrapped transport.
147   virtual int SetOption(rtc::Socket::Option opt, int value) {
148     return channel_->SetOption(opt, value);
149   }
150   virtual int GetError() {
151     return channel_->GetError();
152   }
153   virtual bool GetStats(ConnectionInfos* infos) {
154     return channel_->GetStats(infos);
155   }
156   virtual const std::string SessionId() const {
157     return channel_->SessionId();
158   }
159
160   // Set up the ciphers to use for DTLS-SRTP. If this method is not called
161   // before DTLS starts, or |ciphers| is empty, SRTP keys won't be negotiated.
162   // This method should be called before SetupDtls.
163   virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers);
164
165   // Find out which DTLS-SRTP cipher was negotiated
166   virtual bool GetSrtpCipher(std::string* cipher);
167
168   virtual bool GetSslRole(rtc::SSLRole* role) const;
169   virtual bool SetSslRole(rtc::SSLRole role);
170
171   // Once DTLS has been established, this method retrieves the certificate in
172   // use by the remote peer, for use in external identity verification.
173   virtual bool GetRemoteCertificate(rtc::SSLCertificate** cert) const;
174
175   // Once DTLS has established (i.e., this channel is writable), this method
176   // extracts the keys negotiated during the DTLS handshake, for use in external
177   // encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
178   // See the SSLStreamAdapter documentation for info on the specific parameters.
179   virtual bool ExportKeyingMaterial(const std::string& label,
180                                     const uint8* context,
181                                     size_t context_len,
182                                     bool use_context,
183                                     uint8* result,
184                                     size_t result_len) {
185     return (dtls_.get()) ? dtls_->ExportKeyingMaterial(label, context,
186                                                        context_len,
187                                                        use_context,
188                                                        result, result_len)
189         : false;
190   }
191
192   // TransportChannelImpl calls.
193   virtual Transport* GetTransport() {
194     return transport_;
195   }
196   virtual void SetIceTiebreaker(uint64 tiebreaker) {
197     channel_->SetIceTiebreaker(tiebreaker);
198   }
199   virtual bool GetIceProtocolType(IceProtocolType* type) const {
200     return channel_->GetIceProtocolType(type);
201   }
202   virtual void SetIceProtocolType(IceProtocolType type) {
203     channel_->SetIceProtocolType(type);
204   }
205   virtual void SetIceCredentials(const std::string& ice_ufrag,
206                                  const std::string& ice_pwd) {
207     channel_->SetIceCredentials(ice_ufrag, ice_pwd);
208   }
209   virtual void SetRemoteIceCredentials(const std::string& ice_ufrag,
210                                        const std::string& ice_pwd) {
211     channel_->SetRemoteIceCredentials(ice_ufrag, ice_pwd);
212   }
213   virtual void SetRemoteIceMode(IceMode mode) {
214     channel_->SetRemoteIceMode(mode);
215   }
216
217   virtual void Connect();
218   virtual void Reset();
219
220   virtual void OnSignalingReady() {
221     channel_->OnSignalingReady();
222   }
223   virtual void OnCandidate(const Candidate& candidate) {
224     channel_->OnCandidate(candidate);
225   }
226
227   // Needed by DtlsTransport.
228   TransportChannelImpl* channel() { return channel_; }
229
230  private:
231   void OnReadableState(TransportChannel* channel);
232   void OnWritableState(TransportChannel* channel);
233   void OnReadPacket(TransportChannel* channel, const char* data, size_t size,
234                     const rtc::PacketTime& packet_time, int flags);
235   void OnReadyToSend(TransportChannel* channel);
236   void OnDtlsEvent(rtc::StreamInterface* stream_, int sig, int err);
237   bool SetupDtls();
238   bool MaybeStartDtls();
239   bool HandleDtlsPacket(const char* data, size_t size);
240   void OnRequestSignaling(TransportChannelImpl* channel);
241   void OnCandidateReady(TransportChannelImpl* channel, const Candidate& c);
242   void OnCandidatesAllocationDone(TransportChannelImpl* channel);
243   void OnRoleConflict(TransportChannelImpl* channel);
244   void OnRouteChange(TransportChannel* channel, const Candidate& candidate);
245   void OnConnectionRemoved(TransportChannelImpl* channel);
246
247   Transport* transport_;  // The transport_ that created us.
248   rtc::Thread* worker_thread_;  // Everything should occur on this thread.
249   TransportChannelImpl* channel_;  // Underlying channel, owned by transport_.
250   rtc::scoped_ptr<rtc::SSLStreamAdapter> dtls_;  // The DTLS stream
251   StreamInterfaceChannel* downward_;  // Wrapper for channel_, owned by dtls_.
252   std::vector<std::string> srtp_ciphers_;  // SRTP ciphers to use with DTLS.
253   State dtls_state_;
254   rtc::SSLIdentity* local_identity_;
255   rtc::SSLRole ssl_role_;
256   rtc::Buffer remote_fingerprint_value_;
257   std::string remote_fingerprint_algorithm_;
258
259   DISALLOW_COPY_AND_ASSIGN(DtlsTransportChannelWrapper);
260 };
261
262 }  // namespace cricket
263
264 #endif  // TALK_P2P_BASE_DTLSTRANSPORTCHANNEL_H_