| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #ifndef WEBRTC_P2P_STUNPROBER_STUNPROBER_H_ | 11 #ifndef WEBRTC_P2P_STUNPROBER_STUNPROBER_H_ |
| 12 #define WEBRTC_P2P_STUNPROBER_STUNPROBER_H_ | 12 #define WEBRTC_P2P_STUNPROBER_STUNPROBER_H_ |
| 13 | 13 |
| 14 #include <set> | 14 #include <set> |
| 15 #include <string> | 15 #include <string> |
| 16 #include <vector> | 16 #include <vector> |
| 17 | 17 |
| 18 #include "webrtc/base/asyncinvoker.h" |
| 18 #include "webrtc/base/basictypes.h" | 19 #include "webrtc/base/basictypes.h" |
| 19 #include "webrtc/base/bytebuffer.h" | 20 #include "webrtc/base/bytebuffer.h" |
| 20 #include "webrtc/base/callback.h" | 21 #include "webrtc/base/callback.h" |
| 21 #include "webrtc/base/ipaddress.h" | 22 #include "webrtc/base/ipaddress.h" |
| 23 #include "webrtc/base/network.h" |
| 22 #include "webrtc/base/scoped_ptr.h" | 24 #include "webrtc/base/scoped_ptr.h" |
| 23 #include "webrtc/base/socketaddress.h" | 25 #include "webrtc/base/socketaddress.h" |
| 26 #include "webrtc/base/thread.h" |
| 24 #include "webrtc/base/thread_checker.h" | 27 #include "webrtc/base/thread_checker.h" |
| 25 #include "webrtc/typedefs.h" | 28 #include "webrtc/typedefs.h" |
| 26 | 29 |
| 30 namespace rtc { |
| 31 class AsyncPacketSocket; |
| 32 class PacketSocketFactory; |
| 33 class Thread; |
| 34 class NetworkManager; |
| 35 } // namespace rtc |
| 36 |
| 27 namespace stunprober { | 37 namespace stunprober { |
| 28 | 38 |
| 39 class StunProber; |
| 40 |
| 29 static const int kMaxUdpBufferSize = 1200; | 41 static const int kMaxUdpBufferSize = 1200; |
| 30 | 42 |
| 31 typedef rtc::Callback1<void, int> AsyncCallback; | 43 typedef rtc::Callback2<void, StunProber*, int> AsyncCallback; |
| 32 | 44 |
| 33 enum NatType { | 45 enum NatType { |
| 34 NATTYPE_INVALID, | 46 NATTYPE_INVALID, |
| 35 NATTYPE_NONE, // Not behind a NAT. | 47 NATTYPE_NONE, // Not behind a NAT. |
| 36 NATTYPE_UNKNOWN, // Behind a NAT but type can't be determine. | 48 NATTYPE_UNKNOWN, // Behind a NAT but type can't be determine. |
| 37 NATTYPE_SYMMETRIC, // Behind a symmetric NAT. | 49 NATTYPE_SYMMETRIC, // Behind a symmetric NAT. |
| 38 NATTYPE_NON_SYMMETRIC // Behind a non-symmetric NAT. | 50 NATTYPE_NON_SYMMETRIC // Behind a non-symmetric NAT. |
| 39 }; | 51 }; |
| 40 | 52 |
| 41 class HostNameResolverInterface { | 53 class StunProber : public sigslot::has_slots<> { |
| 42 public: | |
| 43 HostNameResolverInterface() {} | |
| 44 | |
| 45 // Resolve should allow re-entry as |callback| could trigger another | |
| 46 // Resolve(). | |
| 47 virtual void Resolve(const rtc::SocketAddress& addr, | |
| 48 std::vector<rtc::SocketAddress>* addresses, | |
| 49 AsyncCallback callback) = 0; | |
| 50 | |
| 51 virtual ~HostNameResolverInterface() {} | |
| 52 | |
| 53 private: | |
| 54 DISALLOW_COPY_AND_ASSIGN(HostNameResolverInterface); | |
| 55 }; | |
| 56 | |
| 57 // Chrome has client and server socket. Client socket supports Connect but not | |
| 58 // Bind. Server is opposite. | |
| 59 class SocketInterface { | |
| 60 public: | |
| 61 enum { | |
| 62 IO_PENDING = -1, | |
| 63 FAILED = -2, | |
| 64 }; | |
| 65 SocketInterface() {} | |
| 66 virtual void Close() = 0; | |
| 67 virtual ~SocketInterface() {} | |
| 68 | |
| 69 private: | |
| 70 DISALLOW_COPY_AND_ASSIGN(SocketInterface); | |
| 71 }; | |
| 72 | |
| 73 class ClientSocketInterface : public SocketInterface { | |
| 74 public: | |
| 75 ClientSocketInterface() {} | |
| 76 // Even though we have SendTo and RecvFrom, if Connect is not called first, | |
| 77 // getsockname will only return 0.0.0.0. | |
| 78 virtual int Connect(const rtc::SocketAddress& addr) = 0; | |
| 79 | |
| 80 virtual int GetLocalAddress(rtc::SocketAddress* local_address) = 0; | |
| 81 | |
| 82 private: | |
| 83 DISALLOW_COPY_AND_ASSIGN(ClientSocketInterface); | |
| 84 }; | |
| 85 | |
| 86 class ServerSocketInterface : public SocketInterface { | |
| 87 public: | |
| 88 ServerSocketInterface() {} | |
| 89 | |
| 90 virtual int SendTo(const rtc::SocketAddress& addr, | |
| 91 char* buf, | |
| 92 size_t buf_len, | |
| 93 AsyncCallback callback) = 0; | |
| 94 | |
| 95 // If the returned value is positive, it means that buf has been | |
| 96 // sent. Otherwise, it should return IO_PENDING. Callback will be invoked | |
| 97 // after the data is successfully read into buf. | |
| 98 virtual int RecvFrom(char* buf, | |
| 99 size_t buf_len, | |
| 100 rtc::SocketAddress* addr, | |
| 101 AsyncCallback callback) = 0; | |
| 102 | |
| 103 private: | |
| 104 DISALLOW_COPY_AND_ASSIGN(ServerSocketInterface); | |
| 105 }; | |
| 106 | |
| 107 class SocketFactoryInterface { | |
| 108 public: | |
| 109 SocketFactoryInterface() {} | |
| 110 // To provide a chance to prepare the sockets that we need. This is | |
| 111 // implemented for chrome renderer process as the socket needs to be ready to | |
| 112 // use in browser process. | |
| 113 virtual void Prepare(size_t total_client_socket, | |
| 114 size_t total_server_socket, | |
| 115 AsyncCallback callback) { | |
| 116 callback(0); | |
| 117 } | |
| 118 virtual ClientSocketInterface* CreateClientSocket() = 0; | |
| 119 virtual ServerSocketInterface* CreateServerSocket( | |
| 120 size_t send_buffer_size, | |
| 121 size_t receive_buffer_size) = 0; | |
| 122 virtual ~SocketFactoryInterface() {} | |
| 123 | |
| 124 private: | |
| 125 DISALLOW_COPY_AND_ASSIGN(SocketFactoryInterface); | |
| 126 }; | |
| 127 | |
| 128 class TaskRunnerInterface { | |
| 129 public: | |
| 130 TaskRunnerInterface() {} | |
| 131 virtual void PostTask(rtc::Callback0<void>, uint32_t delay_ms) = 0; | |
| 132 virtual ~TaskRunnerInterface() {} | |
| 133 | |
| 134 private: | |
| 135 DISALLOW_COPY_AND_ASSIGN(TaskRunnerInterface); | |
| 136 }; | |
| 137 | |
| 138 class StunProber { | |
| 139 public: | 54 public: |
| 140 enum Status { // Used in UMA_HISTOGRAM_ENUMERATION. | 55 enum Status { // Used in UMA_HISTOGRAM_ENUMERATION. |
| 141 SUCCESS, // Successfully received bytes from the server. | 56 SUCCESS, // Successfully received bytes from the server. |
| 142 GENERIC_FAILURE, // Generic failure. | 57 GENERIC_FAILURE, // Generic failure. |
| 143 RESOLVE_FAILED, // Host resolution failed. | 58 RESOLVE_FAILED, // Host resolution failed. |
| 144 WRITE_FAILED, // Sending a message to the server failed. | 59 WRITE_FAILED, // Sending a message to the server failed. |
| 145 READ_FAILED, // Reading the reply from the server failed. | 60 READ_FAILED, // Reading the reply from the server failed. |
| 146 }; | 61 }; |
| 147 | 62 |
| 148 struct Stats { | 63 struct Stats { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 160 // mode. Share mode only makes sense when we have multiple IP resolved and | 75 // mode. Share mode only makes sense when we have multiple IP resolved and |
| 161 // successfully probed. | 76 // successfully probed. |
| 162 bool shared_socket_mode = false; | 77 bool shared_socket_mode = false; |
| 163 | 78 |
| 164 std::string host_ip; | 79 std::string host_ip; |
| 165 | 80 |
| 166 // If the srflx_addrs has more than 1 element, the NAT is symmetric. | 81 // If the srflx_addrs has more than 1 element, the NAT is symmetric. |
| 167 std::set<std::string> srflx_addrs; | 82 std::set<std::string> srflx_addrs; |
| 168 }; | 83 }; |
| 169 | 84 |
| 170 // StunProber is not thread safe. It's task_runner's responsibility to ensure | 85 StunProber(rtc::PacketSocketFactory* socket_factory, |
| 171 // all calls happen sequentially. | 86 rtc::Thread* thread, |
| 172 StunProber(HostNameResolverInterface* host_name_resolver, | 87 const rtc::NetworkManager::NetworkList& networks); |
| 173 SocketFactoryInterface* socket_factory, | |
| 174 TaskRunnerInterface* task_runner); | |
| 175 virtual ~StunProber(); | 88 virtual ~StunProber(); |
| 176 | 89 |
| 177 // Begin performing the probe test against the |servers|. If | 90 // Begin performing the probe test against the |servers|. If |
| 178 // |shared_socket_mode| is false, each request will be done with a new socket. | 91 // |shared_socket_mode| is false, each request will be done with a new socket. |
| 179 // Otherwise, a unique socket will be used for a single round of requests | 92 // Otherwise, a unique socket will be used for a single round of requests |
| 180 // against all resolved IPs. No single socket will be used against a given IP | 93 // against all resolved IPs. No single socket will be used against a given IP |
| 181 // more than once. The interval of requests will be as close to the requested | 94 // more than once. The interval of requests will be as close to the requested |
| 182 // inter-probe interval |stun_ta_interval_ms| as possible. After sending out | 95 // inter-probe interval |stun_ta_interval_ms| as possible. After sending out |
| 183 // the last scheduled request, the probe will wait |timeout_ms| for request | 96 // the last scheduled request, the probe will wait |timeout_ms| for request |
| 184 // responses and then call |finish_callback|. |requests_per_ip| indicates how | 97 // responses and then call |finish_callback|. |requests_per_ip| indicates how |
| (...skipping 11 matching lines...) Expand all Loading... |
| 196 // Method to retrieve the Stats once |finish_callback| is invoked. Returning | 109 // Method to retrieve the Stats once |finish_callback| is invoked. Returning |
| 197 // false when the result is inconclusive, for example, whether it's behind a | 110 // false when the result is inconclusive, for example, whether it's behind a |
| 198 // NAT or not. | 111 // NAT or not. |
| 199 bool GetStats(Stats* stats) const; | 112 bool GetStats(Stats* stats) const; |
| 200 | 113 |
| 201 private: | 114 private: |
| 202 // A requester tracks the requests and responses from a single socket to many | 115 // A requester tracks the requests and responses from a single socket to many |
| 203 // STUN servers. | 116 // STUN servers. |
| 204 class Requester; | 117 class Requester; |
| 205 | 118 |
| 206 void OnServerResolved(int index, int result); | 119 bool ResolveServerName(const rtc::SocketAddress& addr); |
| 120 void OnServerResolved(rtc::AsyncResolverInterface* resolver); |
| 121 |
| 122 void OnSocketReady(rtc::AsyncPacketSocket* socket, |
| 123 const rtc::SocketAddress& addr); |
| 207 | 124 |
| 208 bool Done() { | 125 bool Done() { |
| 209 return num_request_sent_ >= requests_per_ip_ * all_servers_ips_.size(); | 126 return num_request_sent_ >= requests_per_ip_ * all_servers_addrs_.size(); |
| 210 } | 127 } |
| 211 | 128 |
| 212 int GetTotalClientSockets() { return 1; } | 129 size_t total_socket_required() { |
| 213 int GetTotalServerSockets() { | 130 return (shared_socket_mode_ ? 1 : all_servers_addrs_.size()) * |
| 214 return static_cast<int>( | 131 requests_per_ip_; |
| 215 (shared_socket_mode_ ? 1 : all_servers_ips_.size()) * requests_per_ip_); | |
| 216 } | 132 } |
| 217 | 133 |
| 218 bool SendNextRequest(); | 134 bool SendNextRequest(); |
| 219 | 135 |
| 220 // Will be invoked in 1ms intervals and schedule the next request from the | 136 // Will be invoked in 1ms intervals and schedule the next request from the |
| 221 // |current_requester_| if the time has passed for another request. | 137 // |current_requester_| if the time has passed for another request. |
| 222 void MaybeScheduleStunRequests(); | 138 void MaybeScheduleStunRequests(); |
| 223 | 139 |
| 224 // End the probe with the given |status|. Invokes |fininsh_callback|, which | 140 // End the probe with the given |status|. Invokes |fininsh_callback|, which |
| 225 // may destroy the class. | 141 // may destroy the class. |
| 226 void End(StunProber::Status status, int result); | 142 void End(StunProber::Status status); |
| 227 | |
| 228 // Create a socket, connect to the first resolved server, and return the | |
| 229 // result of getsockname(). All Requesters will bind to this name. We do this | |
| 230 // because if a socket is not bound nor connected, getsockname will return | |
| 231 // 0.0.0.0. We can't connect to a single STUN server IP either as that will | |
| 232 // fail subsequent requests in shared mode. | |
| 233 int GetLocalAddress(rtc::IPAddress* addr); | |
| 234 | 143 |
| 235 Requester* CreateRequester(); | 144 Requester* CreateRequester(); |
| 236 | 145 |
| 237 Requester* current_requester_ = nullptr; | 146 Requester* current_requester_ = nullptr; |
| 238 | 147 |
| 239 // The time when the next request should go out. | 148 // The time when the next request should go out. |
| 240 uint64 next_request_time_ms_ = 0; | 149 uint64 next_request_time_ms_ = 0; |
| 241 | 150 |
| 242 // Total requests sent so far. | 151 // Total requests sent so far. |
| 243 uint32 num_request_sent_ = 0; | 152 uint32 num_request_sent_ = 0; |
| 244 | 153 |
| 245 bool shared_socket_mode_ = false; | 154 bool shared_socket_mode_ = false; |
| 246 | 155 |
| 247 // How many requests should be done against each resolved IP. | 156 // How many requests should be done against each resolved IP. |
| 248 uint32 requests_per_ip_ = 0; | 157 uint32 requests_per_ip_ = 0; |
| 249 | 158 |
| 250 // Milliseconds to pause between each STUN request. | 159 // Milliseconds to pause between each STUN request. |
| 251 int interval_ms_; | 160 int interval_ms_; |
| 252 | 161 |
| 253 // Timeout period after the last request is sent. | 162 // Timeout period after the last request is sent. |
| 254 int timeout_ms_; | 163 int timeout_ms_; |
| 255 | 164 |
| 256 // STUN server name to be resolved. | 165 // STUN server name to be resolved. |
| 257 std::vector<rtc::SocketAddress> servers_; | 166 std::vector<rtc::SocketAddress> servers_; |
| 258 | 167 |
| 259 // The local address that each probing socket will be bound to. | 168 // Weak references. |
| 260 rtc::IPAddress local_addr_; | 169 rtc::PacketSocketFactory* socket_factory_; |
| 170 rtc::Thread* thread_; |
| 261 | 171 |
| 262 // Owned pointers. | 172 // Accumulate all resolved addresses. |
| 263 rtc::scoped_ptr<SocketFactoryInterface> socket_factory_; | 173 std::vector<rtc::SocketAddress> all_servers_addrs_; |
| 264 rtc::scoped_ptr<HostNameResolverInterface> resolver_; | |
| 265 rtc::scoped_ptr<TaskRunnerInterface> task_runner_; | |
| 266 | |
| 267 // Addresses filled out by HostNameResolver for a single server. | |
| 268 std::vector<rtc::SocketAddress> resolved_ips_; | |
| 269 | |
| 270 // Accumulate all resolved IPs. | |
| 271 std::vector<rtc::SocketAddress> all_servers_ips_; | |
| 272 | 174 |
| 273 // Caller-supplied callback executed when testing is completed, called by | 175 // Caller-supplied callback executed when testing is completed, called by |
| 274 // End(). | 176 // End(). |
| 275 AsyncCallback finished_callback_; | 177 AsyncCallback finished_callback_; |
| 276 | 178 |
| 277 // The set of STUN probe sockets and their state. | 179 // The set of STUN probe sockets and their state. |
| 278 std::vector<Requester*> requesters_; | 180 std::vector<Requester*> requesters_; |
| 279 | 181 |
| 280 rtc::ThreadChecker thread_checker_; | 182 rtc::ThreadChecker thread_checker_; |
| 281 | 183 |
| 184 // Temporary storage for created sockets. |
| 185 std::vector<rtc::AsyncPacketSocket*> sockets_; |
| 186 // This tracks how many of the sockets are ready. |
| 187 size_t total_ready_sockets_ = 0; |
| 188 |
| 189 rtc::AsyncInvoker invoker_; |
| 190 |
| 191 rtc::NetworkManager::NetworkList networks_; |
| 192 |
| 282 DISALLOW_COPY_AND_ASSIGN(StunProber); | 193 DISALLOW_COPY_AND_ASSIGN(StunProber); |
| 283 }; | 194 }; |
| 284 | 195 |
| 285 } // namespace stunprober | 196 } // namespace stunprober |
| 286 | 197 |
| 287 #endif // WEBRTC_P2P_STUNPROBER_STUNPROBER_H_ | 198 #endif // WEBRTC_P2P_STUNPROBER_STUNPROBER_H_ |
| OLD | NEW |