• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
RelayCredentialsRelayCredentials44   RelayCredentials() {}
RelayCredentialsRelayCredentials45   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 {
RelayServerConfigRelayServerConfig57   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 
network_manager()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.
socket_factory()84   rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
85 
stun_servers()86   const ServerAddresses& stun_servers() const {
87     return stun_servers_;
88   }
89 
relays()90   const std::vector<RelayServerConfig>& relays() const {
91     return relays_;
92   }
AddRelay(const RelayServerConfig & relay)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 
allocator()126   virtual BasicPortAllocator* allocator() { return allocator_; }
network_thread()127   rtc::Thread* network_thread() { return network_thread_; }
socket_factory()128   rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
129 
130   virtual void StartGettingPorts();
131   virtual void StopGettingPorts();
IsGettingPorts()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:
PortData()148     PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
PortData(Port * port,AllocationSequence * seq)149     PortData(Port* port, AllocationSequence* seq)
150     : port_(port), sequence_(seq), state_(STATE_INIT) {
151     }
152 
port()153     Port* port() { return port_; }
sequence()154     AllocationSequence* sequence() { return sequence_; }
ready()155     bool ready() const { return state_ == STATE_READY; }
complete()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 
set_ready()161     void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
set_complete()162     void set_complete() {
163       state_ = STATE_COMPLETE;
164     }
set_error()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(rtc::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   bool CheckCandidateFilter(const Candidate& c);
204 
205   BasicPortAllocator* allocator_;
206   rtc::Thread* network_thread_;
207   rtc::scoped_ptr<rtc::PacketSocketFactory> owned_socket_factory_;
208   rtc::PacketSocketFactory* socket_factory_;
209   bool allocation_started_;
210   bool network_manager_started_;
211   bool running_;  // set when StartGetAllPorts is called
212   bool allocation_sequences_created_;
213   std::vector<PortConfiguration*> configs_;
214   std::vector<AllocationSequence*> sequences_;
215   std::vector<PortData> ports_;
216 
217   friend class AllocationSequence;
218 };
219 
220 // Records configuration information useful in creating ports.
221 struct PortConfiguration : public rtc::MessageData {
222   // TODO(jiayl): remove |stun_address| when Chrome is updated.
223   rtc::SocketAddress stun_address;
224   ServerAddresses stun_servers;
225   std::string username;
226   std::string password;
227 
228   typedef std::vector<RelayServerConfig> RelayList;
229   RelayList relays;
230 
231   // TODO(jiayl): remove this ctor when Chrome is updated.
232   PortConfiguration(const rtc::SocketAddress& stun_address,
233                     const std::string& username,
234                     const std::string& password);
235 
236   PortConfiguration(const ServerAddresses& stun_servers,
237                     const std::string& username,
238                     const std::string& password);
239 
240   // TODO(jiayl): remove when |stun_address| is removed.
241   ServerAddresses StunServers();
242 
243   // Adds another relay server, with the given ports and modifier, to the list.
244   void AddRelay(const RelayServerConfig& config);
245 
246   // Determines whether the given relay server supports the given protocol.
247   bool SupportsProtocol(const RelayServerConfig& relay,
248                         ProtocolType type) const;
249   bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
250   // Helper method returns the server addresses for the matching RelayType and
251   // Protocol type.
252   ServerAddresses GetRelayServerAddresses(
253       RelayType turn_type, ProtocolType type) const;
254 };
255 
256 }  // namespace cricket
257 
258 #endif  // TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
259