Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / client / basicportallocator.h
1 /*
2  * libjingle
3  * Copyright 2004--2005, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #ifndef TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
29 #define TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
30
31 #include <string>
32 #include <vector>
33
34 #include "talk/p2p/base/port.h"
35 #include "talk/p2p/base/portallocator.h"
36 #include "webrtc/base/messagequeue.h"
37 #include "webrtc/base/network.h"
38 #include "webrtc/base/scoped_ptr.h"
39 #include "webrtc/base/thread.h"
40
41 namespace cricket {
42
43 struct RelayCredentials {
44   RelayCredentials() {}
45   RelayCredentials(const std::string& username,
46                    const std::string& password)
47       : username(username),
48         password(password) {
49   }
50
51   std::string username;
52   std::string password;
53 };
54
55 typedef std::vector<ProtocolAddress> PortList;
56 struct RelayServerConfig {
57   RelayServerConfig(RelayType type) : type(type), priority(0) {}
58
59   RelayType type;
60   PortList ports;
61   RelayCredentials credentials;
62   int priority;
63 };
64
65 class BasicPortAllocator : public PortAllocator {
66  public:
67   BasicPortAllocator(rtc::NetworkManager* network_manager,
68                      rtc::PacketSocketFactory* socket_factory);
69   explicit BasicPortAllocator(rtc::NetworkManager* network_manager);
70   BasicPortAllocator(rtc::NetworkManager* network_manager,
71                      rtc::PacketSocketFactory* socket_factory,
72                      const ServerAddresses& stun_servers);
73   BasicPortAllocator(rtc::NetworkManager* network_manager,
74                      const ServerAddresses& stun_servers,
75                      const rtc::SocketAddress& relay_server_udp,
76                      const rtc::SocketAddress& relay_server_tcp,
77                      const rtc::SocketAddress& relay_server_ssl);
78   virtual ~BasicPortAllocator();
79
80   rtc::NetworkManager* network_manager() { return network_manager_; }
81
82   // If socket_factory() is set to NULL each PortAllocatorSession
83   // creates its own socket factory.
84   rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
85
86   const ServerAddresses& stun_servers() const {
87     return stun_servers_;
88   }
89
90   const std::vector<RelayServerConfig>& relays() const {
91     return relays_;
92   }
93   virtual void AddRelay(const RelayServerConfig& relay) {
94     relays_.push_back(relay);
95   }
96
97   virtual PortAllocatorSession* CreateSessionInternal(
98       const std::string& content_name,
99       int component,
100       const std::string& ice_ufrag,
101       const std::string& ice_pwd);
102
103  private:
104   void Construct();
105
106   rtc::NetworkManager* network_manager_;
107   rtc::PacketSocketFactory* socket_factory_;
108   const ServerAddresses stun_servers_;
109   std::vector<RelayServerConfig> relays_;
110   bool allow_tcp_listen_;
111 };
112
113 struct PortConfiguration;
114 class AllocationSequence;
115
116 class BasicPortAllocatorSession : public PortAllocatorSession,
117                                   public rtc::MessageHandler {
118  public:
119   BasicPortAllocatorSession(BasicPortAllocator* allocator,
120                             const std::string& content_name,
121                             int component,
122                             const std::string& ice_ufrag,
123                             const std::string& ice_pwd);
124   ~BasicPortAllocatorSession();
125
126   virtual BasicPortAllocator* allocator() { return allocator_; }
127   rtc::Thread* network_thread() { return network_thread_; }
128   rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
129
130   virtual void StartGettingPorts();
131   virtual void StopGettingPorts();
132   virtual bool IsGettingPorts() { return running_; }
133
134  protected:
135   // Starts the process of getting the port configurations.
136   virtual void GetPortConfigurations();
137
138   // Adds a port configuration that is now ready.  Once we have one for each
139   // network (or a timeout occurs), we will start allocating ports.
140   virtual void ConfigReady(PortConfiguration* config);
141
142   // MessageHandler.  Can be overriden if message IDs do not conflict.
143   virtual void OnMessage(rtc::Message *message);
144
145  private:
146   class PortData {
147    public:
148     PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
149     PortData(Port* port, AllocationSequence* seq)
150     : port_(port), sequence_(seq), state_(STATE_INIT) {
151     }
152
153     Port* port() { return port_; }
154     AllocationSequence* sequence() { return sequence_; }
155     bool ready() const { return state_ == STATE_READY; }
156     bool complete() const {
157       // Returns true if candidate allocation has completed one way or another.
158       return ((state_ == STATE_COMPLETE) || (state_ == STATE_ERROR));
159     }
160
161     void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
162     void set_complete() {
163       ASSERT(state_ == STATE_READY);
164       state_ = STATE_COMPLETE;
165     }
166     void set_error() {
167       ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
168       state_ = STATE_ERROR;
169     }
170
171    private:
172     enum State {
173       STATE_INIT,      // No candidates allocated yet.
174       STATE_READY,     // At least one candidate is ready for process.
175       STATE_COMPLETE,  // All candidates allocated and ready for process.
176       STATE_ERROR      // Error in gathering candidates.
177     };
178     Port* port_;
179     AllocationSequence* sequence_;
180     State state_;
181   };
182
183   void OnConfigReady(PortConfiguration* config);
184   void OnConfigStop();
185   void AllocatePorts();
186   void OnAllocate();
187   void DoAllocate();
188   void OnNetworksChanged();
189   void OnAllocationSequenceObjectsCreated();
190   void DisableEquivalentPhases(rtc::Network* network,
191                                PortConfiguration* config, uint32* flags);
192   void AddAllocatedPort(Port* port, AllocationSequence* seq,
193                         bool prepare_address);
194   void OnCandidateReady(Port* port, const Candidate& c);
195   void OnPortComplete(Port* port);
196   void OnPortError(Port* port);
197   void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
198   void OnPortDestroyed(PortInterface* port);
199   void OnShake();
200   void MaybeSignalCandidatesAllocationDone();
201   void OnPortAllocationComplete(AllocationSequence* seq);
202   PortData* FindPort(Port* port);
203
204   BasicPortAllocator* allocator_;
205   rtc::Thread* network_thread_;
206   rtc::scoped_ptr<rtc::PacketSocketFactory> owned_socket_factory_;
207   rtc::PacketSocketFactory* socket_factory_;
208   bool allocation_started_;
209   bool network_manager_started_;
210   bool running_;  // set when StartGetAllPorts is called
211   bool allocation_sequences_created_;
212   std::vector<PortConfiguration*> configs_;
213   std::vector<AllocationSequence*> sequences_;
214   std::vector<PortData> ports_;
215
216   friend class AllocationSequence;
217 };
218
219 // Records configuration information useful in creating ports.
220 struct PortConfiguration : public rtc::MessageData {
221   // TODO(jiayl): remove |stun_address| when Chrome is updated.
222   rtc::SocketAddress stun_address;
223   ServerAddresses stun_servers;
224   std::string username;
225   std::string password;
226
227   typedef std::vector<RelayServerConfig> RelayList;
228   RelayList relays;
229
230   // TODO(jiayl): remove this ctor when Chrome is updated.
231   PortConfiguration(const rtc::SocketAddress& stun_address,
232                     const std::string& username,
233                     const std::string& password);
234
235   PortConfiguration(const ServerAddresses& stun_servers,
236                     const std::string& username,
237                     const std::string& password);
238
239   // TODO(jiayl): remove when |stun_address| is removed.
240   ServerAddresses StunServers();
241
242   // Adds another relay server, with the given ports and modifier, to the list.
243   void AddRelay(const RelayServerConfig& config);
244
245   // Determines whether the given relay server supports the given protocol.
246   bool SupportsProtocol(const RelayServerConfig& relay,
247                         ProtocolType type) const;
248   bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
249   // Helper method returns the server addresses for the matching RelayType and
250   // Protocol type.
251   ServerAddresses GetRelayServerAddresses(
252       RelayType turn_type, ProtocolType type) const;
253 };
254
255 }  // namespace cricket
256
257 #endif  // TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_