blob: 95b736d09880a1472da6379eb74562eef35980ec [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001// Copyright 2011 Google Inc. All Rights Reserved.
2
3
4#ifndef TALK_P2P_CLIENT_CONNECTIVITYCHECKER_H_
5#define TALK_P2P_CLIENT_CONNECTIVITYCHECKER_H_
6
7#include <map>
8#include <string>
9
10#include "talk/base/network.h"
11#include "talk/base/basictypes.h"
12#include "talk/base/messagehandler.h"
13#include "talk/base/proxyinfo.h"
14#include "talk/base/scoped_ptr.h"
15#include "talk/base/sigslot.h"
16#include "talk/base/socketaddress.h"
17#include "talk/p2p/base/basicpacketsocketfactory.h"
18#include "talk/p2p/client/httpportallocator.h"
19
20namespace talk_base {
21class AsyncHttpRequest;
22class AutoDetectProxy;
23class BasicPacketSocketFactory;
24class NetworkManager;
25class PacketSocketFactory;
26class SignalThread;
27class TestHttpPortAllocatorSession;
28class Thread;
29}
30
31namespace cricket {
32class HttpPortAllocator;
33class Port;
34class PortAllocatorSession;
35struct PortConfiguration;
36class RelayPort;
37class StunPort;
38
39// Contains details about a discovered firewall that are of interest
40// when debugging call failures.
41struct FirewallInfo {
42 std::string brand;
43 std::string model;
44
45 // TODO: List of current port mappings.
46};
47
48// Contains details about a specific connect attempt.
49struct ConnectInfo {
50 ConnectInfo()
51 : rtt(-1), error(0) {}
52 // Time when the connection was initiated. Needed for calculating
53 // the round trip time.
54 uint32 start_time_ms;
55 // Round trip time in milliseconds or -1 for failed connection.
56 int32 rtt;
57 // Error code representing low level errors like socket errors.
58 int error;
59};
60
61// Identifier for a network interface and proxy address pair.
62struct NicId {
63 NicId(const talk_base::IPAddress& ip,
64 const talk_base::SocketAddress& proxy_address)
65 : ip(ip),
66 proxy_address(proxy_address) {
67 }
68 talk_base::IPAddress ip;
69 talk_base::SocketAddress proxy_address;
70};
71
72// Comparator implementation identifying unique network interface and
73// proxy address pairs.
74class NicIdComparator {
75 public:
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) {
80 return 0;
81 } else {
82 return first.proxy_address < second.proxy_address? -1 : 1;
83 }
84 }
85 return first.ip < second.ip ? -1 : 1;
86 }
87
88 bool operator()(const NicId &first, const NicId &second) const {
89 return (compare(first, second) < 0);
90 }
91};
92
93// Contains information of a network interface and proxy address pair.
94struct NicInfo {
95 NicInfo() {}
96 talk_base::IPAddress ip;
97 talk_base::ProxyInfo proxy_info;
98 talk_base::SocketAddress external_address;
99 talk_base::SocketAddress stun_server_address;
100 talk_base::SocketAddress media_server_address;
101 ConnectInfo stun;
102 ConnectInfo http;
103 ConnectInfo https;
104 ConnectInfo udp;
105 ConnectInfo tcp;
106 ConnectInfo ssltcp;
107 FirewallInfo firewall;
108};
109
110// Holds the result of the connectivity check.
111class NicMap : public std::map<NicId, NicInfo, NicIdComparator> {
112};
113
114class TestHttpPortAllocatorSession : public HttpPortAllocatorSession {
115 public:
116 TestHttpPortAllocatorSession(
117 HttpPortAllocator* allocator,
118 const std::string& content_name,
119 int component,
120 const std::string& ice_ufrag,
121 const std::string& ice_pwd,
122 const std::vector<talk_base::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) {
129 }
130 void set_proxy(const talk_base::ProxyInfo& proxy) {
131 proxy_ = proxy;
132 }
133
134 void ConfigReady(PortConfiguration* config);
135
136 void OnRequestDone(talk_base::SignalThread* data);
137
138 sigslot::signal4<const std::string&, const std::string&,
139 const PortConfiguration*,
140 const talk_base::ProxyInfo&> SignalConfigReady;
141 sigslot::signal1<talk_base::AsyncHttpRequest*> SignalRequestDone;
142
143 private:
144 talk_base::ProxyInfo proxy_;
145};
146
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.
150class ConnectivityChecker
151 : public talk_base::MessageHandler, public sigslot::has_slots<> {
152 public:
153 ConnectivityChecker(talk_base::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();
160
161 // Virtual for gMock.
162 virtual bool Initialize();
163 virtual void Start();
164
165 // MessageHandler implementation.
166 virtual void OnMessage(talk_base::Message *msg);
167
168 // Instruct checker to stop and wait until that's done.
169 // Virtual for gMock.
170 virtual void Stop() {
171 worker_->Stop();
172 }
173
174 const NicMap& GetResults() const {
175 return nics_;
176 }
177
178 void set_timeout_ms(uint32 timeout) {
179 timeout_ms_ = timeout;
180 }
181
182 void set_stun_address(const talk_base::SocketAddress& stun_address) {
183 stun_address_ = stun_address;
184 }
185
186 const std::string& connection() const {
187 return connection_;
188 }
189
190 const std::string& jid() const {
191 return jid_;
192 }
193
194 const std::string& session_id() const {
195 return session_id_;
196 }
197
198 // Context: Main Thread. Signalled when the connectivity check is complete.
199 sigslot::signal1<ConnectivityChecker*> SignalCheckDone;
200
201 protected:
202 // Can be overridden for test.
203 virtual talk_base::NetworkManager* CreateNetworkManager() {
204 return new talk_base::BasicNetworkManager();
205 }
206 virtual talk_base::BasicPacketSocketFactory* CreateSocketFactory(
207 talk_base::Thread* thread) {
208 return new talk_base::BasicPacketSocketFactory(thread);
209 }
210 virtual HttpPortAllocator* CreatePortAllocator(
211 talk_base::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, talk_base::Network* network);
217 virtual RelayPort* CreateRelayPort(
218 const std::string& username, const std::string& password,
219 const PortConfiguration* config, talk_base::Network* network);
220 virtual void InitiateProxyDetection();
221 virtual void SetProxyInfo(const talk_base::ProxyInfo& info);
222 virtual talk_base::ProxyInfo GetProxyInfo() const;
223
224 talk_base::Thread* worker() {
225 return worker_;
226 }
227
228 private:
229 bool AddNic(const talk_base::IPAddress& ip,
230 const talk_base::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 talk_base::ProxyInfo& proxy_info);
237
238 // Must be called by the worker thread.
239 void CleanUp();
240
241 void OnRequestDone(talk_base::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(talk_base::SignalThread* thread);
248 void OnConfigReady(
249 const std::string& username, const std::string& password,
250 const PortConfiguration* config, const talk_base::ProxyInfo& proxy);
251 void OnConfigWithProxyReady(const PortConfiguration*);
252 void RegisterHttpStart(int port);
253 talk_base::Thread* worker_;
254 std::string jid_;
255 std::string session_id_;
256 std::string user_agent_;
257 std::string relay_token_;
258 std::string connection_;
259 talk_base::AutoDetectProxy* proxy_detect_;
260 talk_base::scoped_ptr<talk_base::NetworkManager> network_manager_;
261 talk_base::scoped_ptr<talk_base::BasicPacketSocketFactory> socket_factory_;
262 talk_base::scoped_ptr<HttpPortAllocator> port_allocator_;
263 NicMap nics_;
264 std::vector<Port*> ports_;
265 std::vector<PortAllocatorSession*> sessions_;
266 uint32 timeout_ms_;
267 talk_base::SocketAddress stun_address_;
268 talk_base::Thread* main_;
269 bool started_;
270};
271
272} // namespace cricket
273
274#endif // TALK_P2P_CLIENT_CONNECTIVITYCHECKER_H_