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/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"
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) {}
61 RelayCredentials credentials;
64 class BasicPortAllocator : public PortAllocator {
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();
79 talk_base::NetworkManager* network_manager() { return network_manager_; }
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_; }
85 const talk_base::SocketAddress& stun_address() const {
89 const std::vector<RelayServerConfig>& relays() const {
92 virtual void AddRelay(const RelayServerConfig& relay) {
93 relays_.push_back(relay);
96 virtual PortAllocatorSession* CreateSessionInternal(
97 const std::string& content_name,
99 const std::string& ice_ufrag,
100 const std::string& ice_pwd);
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_;
112 struct PortConfiguration;
113 class AllocationSequence;
115 class BasicPortAllocatorSession : public PortAllocatorSession,
116 public talk_base::MessageHandler {
118 BasicPortAllocatorSession(BasicPortAllocator* allocator,
119 const std::string& content_name,
121 const std::string& ice_ufrag,
122 const std::string& ice_pwd);
123 ~BasicPortAllocatorSession();
125 virtual BasicPortAllocator* allocator() { return allocator_; }
126 talk_base::Thread* network_thread() { return network_thread_; }
127 talk_base::PacketSocketFactory* socket_factory() { return socket_factory_; }
129 virtual void StartGettingPorts();
130 virtual void StopGettingPorts();
131 virtual bool IsGettingPorts() { return running_; }
134 // Starts the process of getting the port configurations.
135 virtual void GetPortConfigurations();
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);
141 // MessageHandler. Can be overriden if message IDs do not conflict.
142 virtual void OnMessage(talk_base::Message *message);
147 PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
148 PortData(Port* port, AllocationSequence* seq)
149 : port_(port), sequence_(seq), state_(STATE_INIT) {
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));
160 void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
161 void set_complete() {
162 ASSERT(state_ == STATE_READY);
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(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);
199 void MaybeSignalCandidatesAllocationDone();
200 void OnPortAllocationComplete(AllocationSequence* seq);
201 PortData* FindPort(Port* port);
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_;
216 friend class AllocationSequence;
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;
225 typedef std::vector<RelayServerConfig> RelayList;
228 PortConfiguration(const talk_base::SocketAddress& stun_address,
229 const std::string& username,
230 const std::string& password);
232 // Adds another relay server, with the given ports and modifier, to the list.
233 void AddRelay(const RelayServerConfig& config);
235 // Determines whether the given relay server supports the given protocol.
236 static bool SupportsProtocol(const RelayServerConfig& relay,
240 } // namespace cricket
242 #endif // TALK_P2P_CLIENT_BASICPORTALLOCATOR_H_