1 // Copyright 2011 Google Inc. All Rights Reserved.
4 #ifndef TALK_P2P_CLIENT_CONNECTIVITYCHECKER_H_
5 #define TALK_P2P_CLIENT_CONNECTIVITYCHECKER_H_
10 #include "talk/p2p/base/basicpacketsocketfactory.h"
11 #include "talk/p2p/client/httpportallocator.h"
12 #include "webrtc/base/basictypes.h"
13 #include "webrtc/base/messagehandler.h"
14 #include "webrtc/base/network.h"
15 #include "webrtc/base/proxyinfo.h"
16 #include "webrtc/base/scoped_ptr.h"
17 #include "webrtc/base/sigslot.h"
18 #include "webrtc/base/socketaddress.h"
21 class AsyncHttpRequest;
22 class AutoDetectProxy;
23 class BasicPacketSocketFactory;
25 class PacketSocketFactory;
27 class TestHttpPortAllocatorSession;
32 class HttpPortAllocator;
34 class PortAllocatorSession;
35 struct PortConfiguration;
39 // Contains details about a discovered firewall that are of interest
40 // when debugging call failures.
45 // TODO: List of current port mappings.
48 // Contains details about a specific connect attempt.
51 : rtt(-1), error(0) {}
52 // Time when the connection was initiated. Needed for calculating
53 // the round trip time.
55 // Round trip time in milliseconds or -1 for failed connection.
57 // Error code representing low level errors like socket errors.
61 // Identifier for a network interface and proxy address pair.
63 NicId(const rtc::IPAddress& ip,
64 const rtc::SocketAddress& proxy_address)
66 proxy_address(proxy_address) {
69 rtc::SocketAddress proxy_address;
72 // Comparator implementation identifying unique network interface and
73 // proxy address pairs.
74 class NicIdComparator {
76 int compare(const NicId &first, const NicId &second) const {
77 if (first.ip == second.ip) {
78 // Compare proxy address.
79 if (first.proxy_address == second.proxy_address) {
82 return first.proxy_address < second.proxy_address? -1 : 1;
85 return first.ip < second.ip ? -1 : 1;
88 bool operator()(const NicId &first, const NicId &second) const {
89 return (compare(first, second) < 0);
93 // Contains information of a network interface and proxy address pair.
97 rtc::ProxyInfo proxy_info;
98 rtc::SocketAddress external_address;
99 ServerAddresses stun_server_addresses;
100 rtc::SocketAddress media_server_address;
107 FirewallInfo firewall;
110 // Holds the result of the connectivity check.
111 class NicMap : public std::map<NicId, NicInfo, NicIdComparator> {
114 class TestHttpPortAllocatorSession : public HttpPortAllocatorSession {
116 TestHttpPortAllocatorSession(
117 HttpPortAllocator* allocator,
118 const std::string& content_name,
120 const std::string& ice_ufrag,
121 const std::string& ice_pwd,
122 const std::vector<rtc::SocketAddress>& stun_hosts,
123 const std::vector<std::string>& relay_hosts,
124 const std::string& relay_token,
125 const std::string& user_agent)
126 : HttpPortAllocatorSession(
127 allocator, content_name, component, ice_ufrag, ice_pwd, stun_hosts,
128 relay_hosts, relay_token, user_agent) {
130 void set_proxy(const rtc::ProxyInfo& proxy) {
134 void ConfigReady(PortConfiguration* config);
136 void OnRequestDone(rtc::SignalThread* data);
138 sigslot::signal4<const std::string&, const std::string&,
139 const PortConfiguration*,
140 const rtc::ProxyInfo&> SignalConfigReady;
141 sigslot::signal1<rtc::AsyncHttpRequest*> SignalRequestDone;
144 rtc::ProxyInfo proxy_;
147 // Runs a request/response check on all network interface and proxy
148 // address combinations. The check is considered done either when all
149 // checks has been successful or when the check times out.
150 class ConnectivityChecker
151 : public rtc::MessageHandler, public sigslot::has_slots<> {
153 ConnectivityChecker(rtc::Thread* worker,
154 const std::string& jid,
155 const std::string& session_id,
156 const std::string& user_agent,
157 const std::string& relay_token,
158 const std::string& connection);
159 virtual ~ConnectivityChecker();
161 // Virtual for gMock.
162 virtual bool Initialize();
163 virtual void Start();
165 // MessageHandler implementation.
166 virtual void OnMessage(rtc::Message *msg);
168 // Instruct checker to stop and wait until that's done.
169 // Virtual for gMock.
170 virtual void Stop() {
174 const NicMap& GetResults() const {
178 void set_timeout_ms(uint32 timeout) {
179 timeout_ms_ = timeout;
182 void set_stun_address(const rtc::SocketAddress& stun_address) {
183 stun_address_ = stun_address;
186 const std::string& connection() const {
190 const std::string& jid() const {
194 const std::string& session_id() const {
198 // Context: Main Thread. Signalled when the connectivity check is complete.
199 sigslot::signal1<ConnectivityChecker*> SignalCheckDone;
202 // Can be overridden for test.
203 virtual rtc::NetworkManager* CreateNetworkManager() {
204 return new rtc::BasicNetworkManager();
206 virtual rtc::BasicPacketSocketFactory* CreateSocketFactory(
207 rtc::Thread* thread) {
208 return new rtc::BasicPacketSocketFactory(thread);
210 virtual HttpPortAllocator* CreatePortAllocator(
211 rtc::NetworkManager* network_manager,
212 const std::string& user_agent,
213 const std::string& relay_token);
214 virtual StunPort* CreateStunPort(
215 const std::string& username, const std::string& password,
216 const PortConfiguration* config, rtc::Network* network);
217 virtual RelayPort* CreateRelayPort(
218 const std::string& username, const std::string& password,
219 const PortConfiguration* config, rtc::Network* network);
220 virtual void InitiateProxyDetection();
221 virtual void SetProxyInfo(const rtc::ProxyInfo& info);
222 virtual rtc::ProxyInfo GetProxyInfo() const;
224 rtc::Thread* worker() {
229 bool AddNic(const rtc::IPAddress& ip,
230 const rtc::SocketAddress& proxy_address);
231 void AllocatePorts();
232 void AllocateRelayPorts();
233 void CheckNetworks();
234 void CreateRelayPorts(
235 const std::string& username, const std::string& password,
236 const PortConfiguration* config, const rtc::ProxyInfo& proxy_info);
238 // Must be called by the worker thread.
241 void OnRequestDone(rtc::AsyncHttpRequest* request);
242 void OnRelayPortComplete(Port* port);
243 void OnStunPortComplete(Port* port);
244 void OnRelayPortError(Port* port);
245 void OnStunPortError(Port* port);
246 void OnNetworksChanged();
247 void OnProxyDetect(rtc::SignalThread* thread);
249 const std::string& username, const std::string& password,
250 const PortConfiguration* config, const rtc::ProxyInfo& proxy);
251 void OnConfigWithProxyReady(const PortConfiguration*);
252 void RegisterHttpStart(int port);
253 rtc::Thread* worker_;
255 std::string session_id_;
256 std::string user_agent_;
257 std::string relay_token_;
258 std::string connection_;
259 rtc::AutoDetectProxy* proxy_detect_;
260 rtc::scoped_ptr<rtc::NetworkManager> network_manager_;
261 rtc::scoped_ptr<rtc::BasicPacketSocketFactory> socket_factory_;
262 rtc::scoped_ptr<HttpPortAllocator> port_allocator_;
264 std::vector<Port*> ports_;
265 std::vector<PortAllocatorSession*> sessions_;
267 rtc::SocketAddress stun_address_;
272 } // namespace cricket
274 #endif // TALK_P2P_CLIENT_CONNECTIVITYCHECKER_H_