- add third_party src.
[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/base/messagequeue.h"
35 #include "talk/base/network.h"
36 #include "talk/base/scoped_ptr.h"
37 #include "talk/base/thread.h"
38 #include "talk/p2p/base/port.h"
39 #include "talk/p2p/base/portallocator.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) {}
58
59   RelayType type;
60   PortList ports;
61   RelayCredentials credentials;
62 };
63
64 class BasicPortAllocator : public PortAllocator {
65  public:
66   BasicPortAllocator(talk_base::NetworkManager* network_manager,
67                      talk_base::PacketSocketFactory* socket_factory);
68   explicit BasicPortAllocator(talk_base::NetworkManager* network_manager);
69   BasicPortAllocator(talk_base::NetworkManager* network_manager,
70                      talk_base::PacketSocketFactory* socket_factory,
71                      const talk_base::SocketAddress& stun_server);
72   BasicPortAllocator(talk_base::NetworkManager* network_manager,
73                      const talk_base::SocketAddress& stun_server,
74                      const talk_base::SocketAddress& relay_server_udp,
75                      const talk_base::SocketAddress& relay_server_tcp,
76                      const talk_base::SocketAddress& relay_server_ssl);
77   virtual ~BasicPortAllocator();
78
79   talk_base::NetworkManager* network_manager() { return network_manager_; }
80
81   // If socket_factory() is set to NULL each PortAllocatorSession
82   // creates its own socket factory.
83   talk_base::PacketSocketFactory* socket_factory() { return socket_factory_; }
84
85   const talk_base::SocketAddress& stun_address() const {
86     return stun_address_;
87   }
88
89   const std::vector<RelayServerConfig>& relays() const {
90     return relays_;
91   }
92   virtual void AddRelay(const RelayServerConfig& relay) {
93     relays_.push_back(relay);
94   }
95
96   virtual PortAllocatorSession* CreateSessionInternal(
97       const std::string& content_name,
98       int component,
99       const std::string& ice_ufrag,
100       const std::string& ice_pwd);
101
102  private:
103   void Construct();
104
105   talk_base::NetworkManager* network_manager_;
106   talk_base::PacketSocketFactory* socket_factory_;
107   const talk_base::SocketAddress stun_address_;
108   std::vector<RelayServerConfig> relays_;
109   bool allow_tcp_listen_;
110 };
111
112 struct PortConfiguration;
113 class AllocationSequence;
114
115 class BasicPortAllocatorSession : public PortAllocatorSession,
116                                   public talk_base::MessageHandler {
117  public:
118   BasicPortAllocatorSession(BasicPortAllocator* allocator,
119                             const std::string& content_name,
120                             int component,
121                             const std::string& ice_ufrag,
122                             const std::string& ice_pwd);
123   ~BasicPortAllocatorSession();
124
125   virtual BasicPortAllocator* allocator() { return allocator_; }
126   talk_base::Thread* network_thread() { return network_thread_; }
127   talk_base::PacketSocketFactory* socket_factory() { return socket_factory_; }
128
129   virtual void StartGettingPorts();
130   virtual void StopGettingPorts();
131   virtual bool IsGettingPorts() { return running_; }
132
133  protected:
134   // Starts the process of getting the port configurations.
135   virtual void GetPortConfigurations();
136
137   // Adds a port configuration that is now ready.  Once we have one for each
138   // network (or a timeout occurs), we will start allocating ports.
139   virtual void ConfigReady(PortConfiguration* config);
140
141   // MessageHandler.  Can be overriden if message IDs do not conflict.
142   virtual void OnMessage(talk_base::Message *message);
143
144  private:
145   class PortData {
146    public:
147     PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
148     PortData(Port* port, AllocationSequence* seq)
149     : port_(port), sequence_(seq), state_(STATE_INIT) {
150     }
151
152     Port* port() { return port_; }
153     AllocationSequence* sequence() { return sequence_; }
154     bool ready() const { return state_ == STATE_READY; }
155     bool complete() const {
156       // Returns true if candidate allocation has completed one way or another.
157       return ((state_ == STATE_COMPLETE) || (state_ == STATE_ERROR));
158     }
159
160     void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
161     void set_complete() {
162       ASSERT(state_ == STATE_READY);
163       state_ = STATE_COMPLETE;
164     }
165     void set_error() {
166       ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
167       state_ = STATE_ERROR;
168     }
169
170    private:
171     enum State {
172       STATE_INIT,      // No candidates allocated yet.
173       STATE_READY,     // At least one candidate is ready for process.
174       STATE_COMPLETE,  // All candidates allocated and ready for process.
175       STATE_ERROR      // Error in gathering candidates.
176     };
177     Port* port_;
178     AllocationSequence* sequence_;
179     State state_;
180   };
181
182   void OnConfigReady(PortConfiguration* config);
183   void OnConfigStop();
184   void AllocatePorts();
185   void OnAllocate();
186   void DoAllocate();
187   void OnNetworksChanged();
188   void OnAllocationSequenceObjectsCreated();
189   void DisableEquivalentPhases(talk_base::Network* network,
190                                PortConfiguration* config, uint32* flags);
191   void AddAllocatedPort(Port* port, AllocationSequence* seq,
192                         bool prepare_address);
193   void OnCandidateReady(Port* port, const Candidate& c);
194   void OnPortComplete(Port* port);
195   void OnPortError(Port* port);
196   void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
197   void OnPortDestroyed(PortInterface* port);
198   void OnShake();
199   void MaybeSignalCandidatesAllocationDone();
200   void OnPortAllocationComplete(AllocationSequence* seq);
201   PortData* FindPort(Port* port);
202
203   BasicPortAllocator* allocator_;
204   talk_base::Thread* network_thread_;
205   talk_base::scoped_ptr<talk_base::PacketSocketFactory> owned_socket_factory_;
206   talk_base::PacketSocketFactory* socket_factory_;
207   bool configuration_done_;
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 talk_base::MessageData {
221   talk_base::SocketAddress stun_address;
222   std::string username;
223   std::string password;
224
225   typedef std::vector<RelayServerConfig> RelayList;
226   RelayList relays;
227
228   PortConfiguration(const talk_base::SocketAddress& stun_address,
229                     const std::string& username,
230                     const std::string& password);
231
232   // Adds another relay server, with the given ports and modifier, to the list.
233   void AddRelay(const RelayServerConfig& config);
234
235   // Determines whether the given relay server supports the given protocol.
236   static bool SupportsProtocol(const RelayServerConfig& relay,
237                                ProtocolType type);
238 };
239
240 }  // namespace cricket
241
242 #endif  // TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_