3 * Copyright 2004--2005, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 #ifndef TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
29 #define TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_
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"
43 struct RelayCredentials {
45 RelayCredentials(const std::string& username,
46 const std::string& password)
55 typedef std::vector<ProtocolAddress> PortList;
56 struct RelayServerConfig {
57 RelayServerConfig(RelayType type) : type(type), priority(0) {}
61 RelayCredentials credentials;
65 class BasicPortAllocator : public PortAllocator {
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();
80 rtc::NetworkManager* network_manager() { return network_manager_; }
82 // If socket_factory() is set to NULL each PortAllocatorSession
83 // creates its own socket factory.
84 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
86 const ServerAddresses& stun_servers() const {
90 const std::vector<RelayServerConfig>& relays() const {
93 virtual void AddRelay(const RelayServerConfig& relay) {
94 relays_.push_back(relay);
97 virtual PortAllocatorSession* CreateSessionInternal(
98 const std::string& content_name,
100 const std::string& ice_ufrag,
101 const std::string& ice_pwd);
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_;
113 struct PortConfiguration;
114 class AllocationSequence;
116 class BasicPortAllocatorSession : public PortAllocatorSession,
117 public rtc::MessageHandler {
119 BasicPortAllocatorSession(BasicPortAllocator* allocator,
120 const std::string& content_name,
122 const std::string& ice_ufrag,
123 const std::string& ice_pwd);
124 ~BasicPortAllocatorSession();
126 virtual BasicPortAllocator* allocator() { return allocator_; }
127 rtc::Thread* network_thread() { return network_thread_; }
128 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
130 virtual void StartGettingPorts();
131 virtual void StopGettingPorts();
132 virtual bool IsGettingPorts() { return running_; }
135 // Starts the process of getting the port configurations.
136 virtual void GetPortConfigurations();
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);
142 // MessageHandler. Can be overriden if message IDs do not conflict.
143 virtual void OnMessage(rtc::Message *message);
148 PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
149 PortData(Port* port, AllocationSequence* seq)
150 : port_(port), sequence_(seq), state_(STATE_INIT) {
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));
161 void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
162 void set_complete() {
163 ASSERT(state_ == STATE_READY);
164 state_ = STATE_COMPLETE;
167 ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
168 state_ = STATE_ERROR;
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.
179 AllocationSequence* sequence_;
183 void OnConfigReady(PortConfiguration* config);
185 void AllocatePorts();
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);
200 void MaybeSignalCandidatesAllocationDone();
201 void OnPortAllocationComplete(AllocationSequence* seq);
202 PortData* FindPort(Port* port);
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_;
216 friend class AllocationSequence;
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;
227 typedef std::vector<RelayServerConfig> RelayList;
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);
235 PortConfiguration(const ServerAddresses& stun_servers,
236 const std::string& username,
237 const std::string& password);
239 // TODO(jiayl): remove when |stun_address| is removed.
240 ServerAddresses StunServers();
242 // Adds another relay server, with the given ports and modifier, to the list.
243 void AddRelay(const RelayServerConfig& config);
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
251 ServerAddresses GetRelayServerAddresses(
252 RelayType turn_type, ProtocolType type) const;
255 } // namespace cricket
257 #endif // TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_