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 WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
29 #define WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
34 #include "webrtc/p2p/base/port.h"
35 #include "webrtc/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 state_ = STATE_COMPLETE;
166 ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
167 state_ = STATE_ERROR;
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.
178 AllocationSequence* sequence_;
182 void OnConfigReady(PortConfiguration* config);
184 void AllocatePorts();
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);
199 void MaybeSignalCandidatesAllocationDone();
200 void OnPortAllocationComplete(AllocationSequence* seq);
201 PortData* FindPort(Port* port);
203 bool CheckCandidateFilter(const Candidate& c);
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_;
217 friend class AllocationSequence;
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;
228 typedef std::vector<RelayServerConfig> RelayList;
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);
236 PortConfiguration(const ServerAddresses& stun_servers,
237 const std::string& username,
238 const std::string& password);
240 // TODO(jiayl): remove when |stun_address| is removed.
241 ServerAddresses StunServers();
243 // Adds another relay server, with the given ports and modifier, to the list.
244 void AddRelay(const RelayServerConfig& config);
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
252 ServerAddresses GetRelayServerAddresses(
253 RelayType turn_type, ProtocolType type) const;
256 } // namespace cricket
258 #endif // WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_