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