Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(221)

Side by Side Diff: webrtc/p2p/base/turnport.cc

Issue 1247573002: Fix a Turn TCP port issue. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/turnport.h ('k') | webrtc/p2p/base/turnport_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2012 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
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 TurnPort::TurnPort(rtc::Thread* thread, 165 TurnPort::TurnPort(rtc::Thread* thread,
166 rtc::PacketSocketFactory* factory, 166 rtc::PacketSocketFactory* factory,
167 rtc::Network* network, 167 rtc::Network* network,
168 rtc::AsyncPacketSocket* socket, 168 rtc::AsyncPacketSocket* socket,
169 const std::string& username, 169 const std::string& username,
170 const std::string& password, 170 const std::string& password,
171 const ProtocolAddress& server_address, 171 const ProtocolAddress& server_address,
172 const RelayCredentials& credentials, 172 const RelayCredentials& credentials,
173 int server_priority, 173 int server_priority,
174 const std::string& origin) 174 const std::string& origin)
175 : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(), 175 : Port(thread,
176 username, password), 176 factory,
177 network,
178 socket->GetLocalAddress().ipaddr(),
179 username,
180 password),
177 server_address_(server_address), 181 server_address_(server_address),
178 credentials_(credentials), 182 credentials_(credentials),
179 socket_(socket), 183 socket_(socket),
180 resolver_(NULL), 184 resolver_(NULL),
181 error_(0), 185 error_(0),
182 request_manager_(thread), 186 request_manager_(thread),
183 next_channel_number_(TURN_CHANNEL_NUMBER_START), 187 next_channel_number_(TURN_CHANNEL_NUMBER_START),
184 connected_(false), 188 state_(STATE_CONNECTING),
185 server_priority_(server_priority), 189 server_priority_(server_priority),
186 allocate_mismatch_retries_(0) { 190 allocate_mismatch_retries_(0) {
187 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket); 191 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
188 request_manager_.set_origin(origin); 192 request_manager_.set_origin(origin);
189 } 193 }
190 194
191 TurnPort::TurnPort(rtc::Thread* thread, 195 TurnPort::TurnPort(rtc::Thread* thread,
192 rtc::PacketSocketFactory* factory, 196 rtc::PacketSocketFactory* factory,
193 rtc::Network* network, 197 rtc::Network* network,
194 const rtc::IPAddress& ip, 198 const rtc::IPAddress& ip,
195 uint16 min_port, 199 uint16 min_port,
196 uint16 max_port, 200 uint16 max_port,
197 const std::string& username, 201 const std::string& username,
198 const std::string& password, 202 const std::string& password,
199 const ProtocolAddress& server_address, 203 const ProtocolAddress& server_address,
200 const RelayCredentials& credentials, 204 const RelayCredentials& credentials,
201 int server_priority, 205 int server_priority,
202 const std::string& origin) 206 const std::string& origin)
203 : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port, 207 : Port(thread,
204 username, password), 208 RELAY_PORT_TYPE,
209 factory,
210 network,
211 ip,
212 min_port,
213 max_port,
214 username,
215 password),
205 server_address_(server_address), 216 server_address_(server_address),
206 credentials_(credentials), 217 credentials_(credentials),
207 socket_(NULL), 218 socket_(NULL),
208 resolver_(NULL), 219 resolver_(NULL),
209 error_(0), 220 error_(0),
210 request_manager_(thread), 221 request_manager_(thread),
211 next_channel_number_(TURN_CHANNEL_NUMBER_START), 222 next_channel_number_(TURN_CHANNEL_NUMBER_START),
212 connected_(false), 223 state_(STATE_CONNECTING),
213 server_priority_(server_priority), 224 server_priority_(server_priority),
214 allocate_mismatch_retries_(0) { 225 allocate_mismatch_retries_(0) {
215 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket); 226 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
216 request_manager_.set_origin(origin); 227 request_manager_.set_origin(origin);
217 } 228 }
218 229
219 TurnPort::~TurnPort() { 230 TurnPort::~TurnPort() {
220 // TODO(juberti): Should this even be necessary? 231 // TODO(juberti): Should this even be necessary?
221 232
222 // release the allocation by sending a refresh with 233 // release the allocation by sending a refresh with
223 // lifetime 0. 234 // lifetime 0.
224 if (connected_) { 235 if (ready()) {
225 TurnRefreshRequest bye(this); 236 TurnRefreshRequest bye(this);
226 bye.set_lifetime(0); 237 bye.set_lifetime(0);
227 SendRequest(&bye, 0); 238 SendRequest(&bye, 0);
228 } 239 }
229 240
230 while (!entries_.empty()) { 241 while (!entries_.empty()) {
231 DestroyEntry(entries_.front()->address()); 242 DestroyEntry(entries_.front()->address());
232 } 243 }
233 if (resolver_) { 244 if (resolver_) {
234 resolver_->Destroy(false); 245 resolver_->Destroy(false);
(...skipping 19 matching lines...) Expand all
254 if (!server_address_.address.port()) { 265 if (!server_address_.address.port()) {
255 // We will set default TURN port, if no port is set in the address. 266 // We will set default TURN port, if no port is set in the address.
256 server_address_.address.SetPort(TURN_DEFAULT_PORT); 267 server_address_.address.SetPort(TURN_DEFAULT_PORT);
257 } 268 }
258 269
259 if (server_address_.address.IsUnresolved()) { 270 if (server_address_.address.IsUnresolved()) {
260 ResolveTurnAddress(server_address_.address); 271 ResolveTurnAddress(server_address_.address);
261 } else { 272 } else {
262 // If protocol family of server address doesn't match with local, return. 273 // If protocol family of server address doesn't match with local, return.
263 if (!IsCompatibleAddress(server_address_.address)) { 274 if (!IsCompatibleAddress(server_address_.address)) {
264 LOG(LS_ERROR) << "Server IP address family does not match with " 275 LOG(LS_ERROR) << "IP address family does not match: "
265 << "local host address family type"; 276 << "server: " << server_address_.address.family()
277 << "local: " << ip().family();
266 OnAllocateError(); 278 OnAllocateError();
267 return; 279 return;
268 } 280 }
269 281
270 // Insert the current address to prevent redirection pingpong. 282 // Insert the current address to prevent redirection pingpong.
271 attempted_server_addresses_.insert(server_address_.address); 283 attempted_server_addresses_.insert(server_address_.address);
272 284
273 LOG_J(LS_INFO, this) << "Trying to connect to TURN server via " 285 LOG_J(LS_INFO, this) << "Trying to connect to TURN server via "
274 << ProtoToString(server_address_.proto) << " @ " 286 << ProtoToString(server_address_.proto) << " @ "
275 << server_address_.address.ToSensitiveString(); 287 << server_address_.address.ToSensitiveString();
276 if (!CreateTurnClientSocket()) { 288 if (!CreateTurnClientSocket()) {
289 LOG(LS_ERROR) << "Failed to create TURN client socket";
277 OnAllocateError(); 290 OnAllocateError();
278 } else if (server_address_.proto == PROTO_UDP) { 291 return;
292 }
293 if (server_address_.proto == PROTO_UDP) {
279 // If its UDP, send AllocateRequest now. 294 // If its UDP, send AllocateRequest now.
280 // For TCP and TLS AllcateRequest will be sent by OnSocketConnect. 295 // For TCP and TLS AllcateRequest will be sent by OnSocketConnect.
281 SendRequest(new TurnAllocateRequest(this), 0); 296 SendRequest(new TurnAllocateRequest(this), 0);
282 } 297 }
283 } 298 }
284 } 299 }
285 300
286 bool TurnPort::CreateTurnClientSocket() { 301 bool TurnPort::CreateTurnClientSocket() {
287 ASSERT(!socket_ || SharedSocket()); 302 ASSERT(!socket_ || SharedSocket());
288 303
(...skipping 23 matching lines...) Expand all
312 socket_->SetOption(iter->first, iter->second); 327 socket_->SetOption(iter->first, iter->second);
313 } 328 }
314 329
315 if (!SharedSocket()) { 330 if (!SharedSocket()) {
316 // If socket is shared, AllocationSequence will receive the packet. 331 // If socket is shared, AllocationSequence will receive the packet.
317 socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket); 332 socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket);
318 } 333 }
319 334
320 socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend); 335 socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend);
321 336
337 // TCP port is ready to send stun requests after the socket is connected,
338 // while UDP port is ready to do so once the socket is created.
322 if (server_address_.proto == PROTO_TCP) { 339 if (server_address_.proto == PROTO_TCP) {
323 socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect); 340 socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect);
324 socket_->SignalClose.connect(this, &TurnPort::OnSocketClose); 341 socket_->SignalClose.connect(this, &TurnPort::OnSocketClose);
342 } else {
343 state_ = STATE_CONNECTED;
325 } 344 }
326 return true; 345 return true;
327 } 346 }
328 347
329 void TurnPort::OnSocketConnect(rtc::AsyncPacketSocket* socket) { 348 void TurnPort::OnSocketConnect(rtc::AsyncPacketSocket* socket) {
330 ASSERT(server_address_.proto == PROTO_TCP); 349 ASSERT(server_address_.proto == PROTO_TCP);
331 // Do not use this port if the socket bound to a different address than 350 // Do not use this port if the socket bound to a different address than
332 // the one we asked for. This is seen in Chrome, where TCP sockets cannot be 351 // the one we asked for. This is seen in Chrome, where TCP sockets cannot be
333 // given a binding address, and the platform is expected to pick the 352 // given a binding address, and the platform is expected to pick the
334 // correct local address. 353 // correct local address.
(...skipping 18 matching lines...) Expand all
353 } else { 372 } else {
354 LOG(LS_WARNING) << "Socket is bound to a different address:" 373 LOG(LS_WARNING) << "Socket is bound to a different address:"
355 << socket->GetLocalAddress().ipaddr().ToString() 374 << socket->GetLocalAddress().ipaddr().ToString()
356 << ", rather then the local port:" << ip().ToString() 375 << ", rather then the local port:" << ip().ToString()
357 << ". Discarding TURN port."; 376 << ". Discarding TURN port.";
358 OnAllocateError(); 377 OnAllocateError();
359 return; 378 return;
360 } 379 }
361 } 380 }
362 381
382 state_ = STATE_CONNECTED; // It is ready to send stun requests.
363 if (server_address_.address.IsUnresolved()) { 383 if (server_address_.address.IsUnresolved()) {
364 server_address_.address = socket_->GetRemoteAddress(); 384 server_address_.address = socket_->GetRemoteAddress();
365 } 385 }
366 386
367 LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress() 387 LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress()
368 << " using tcp."; 388 << " using tcp.";
369 SendRequest(new TurnAllocateRequest(this), 0); 389 SendRequest(new TurnAllocateRequest(this), 0);
370 } 390 }
371 391
372 void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) { 392 void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) {
373 LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error; 393 LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error;
374 ASSERT(socket == socket_); 394 ASSERT(socket == socket_);
375 if (!connected_) { 395 if (!ready()) {
376 OnAllocateError(); 396 OnAllocateError();
377 } 397 }
378 connected_ = false; 398 request_manager_.Clear();
399 state_ = STATE_DISCONNECTED;
379 } 400 }
380 401
381 void TurnPort::OnAllocateMismatch() { 402 void TurnPort::OnAllocateMismatch() {
382 if (allocate_mismatch_retries_ >= MAX_ALLOCATE_MISMATCH_RETRIES) { 403 if (allocate_mismatch_retries_ >= MAX_ALLOCATE_MISMATCH_RETRIES) {
383 LOG_J(LS_WARNING, this) << "Giving up on the port after " 404 LOG_J(LS_WARNING, this) << "Giving up on the port after "
384 << allocate_mismatch_retries_ 405 << allocate_mismatch_retries_
385 << " retries for STUN_ERROR_ALLOCATION_MISMATCH"; 406 << " retries for STUN_ERROR_ALLOCATION_MISMATCH";
386 OnAllocateError(); 407 OnAllocateError();
387 return; 408 return;
388 } 409 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 int TurnPort::GetError() { 476 int TurnPort::GetError() {
456 return error_; 477 return error_;
457 } 478 }
458 479
459 int TurnPort::SendTo(const void* data, size_t size, 480 int TurnPort::SendTo(const void* data, size_t size,
460 const rtc::SocketAddress& addr, 481 const rtc::SocketAddress& addr,
461 const rtc::PacketOptions& options, 482 const rtc::PacketOptions& options,
462 bool payload) { 483 bool payload) {
463 // Try to find an entry for this specific address; we should have one. 484 // Try to find an entry for this specific address; we should have one.
464 TurnEntry* entry = FindEntry(addr); 485 TurnEntry* entry = FindEntry(addr);
465 ASSERT(entry != NULL);
466 if (!entry) { 486 if (!entry) {
487 LOG(LS_ERROR) << "Did not find the TurnEntry for address " << addr;
467 return 0; 488 return 0;
468 } 489 }
469 490
470 if (!connected()) { 491 if (!ready()) {
471 error_ = EWOULDBLOCK; 492 error_ = EWOULDBLOCK;
472 return SOCKET_ERROR; 493 return SOCKET_ERROR;
473 } 494 }
474 495
475 // Send the actual contents to the server using the usual mechanism. 496 // Send the actual contents to the server using the usual mechanism.
476 int sent = entry->Send(data, size, payload, options); 497 int sent = entry->Send(data, size, payload, options);
477 if (sent <= 0) { 498 if (sent <= 0) {
478 return SOCKET_ERROR; 499 return SOCKET_ERROR;
479 } 500 }
480 501
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 !StunMessage::ValidateMessageIntegrity(data, size, hash())) { 550 !StunMessage::ValidateMessageIntegrity(data, size, hash())) {
530 LOG_J(LS_WARNING, this) << "Received TURN message with invalid " 551 LOG_J(LS_WARNING, this) << "Received TURN message with invalid "
531 << "message integrity, msg_type=" << msg_type; 552 << "message integrity, msg_type=" << msg_type;
532 return; 553 return;
533 } 554 }
534 request_manager_.CheckResponse(data, size); 555 request_manager_.CheckResponse(data, size);
535 } 556 }
536 } 557 }
537 558
538 void TurnPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) { 559 void TurnPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
539 if (connected_) { 560 if (ready()) {
540 Port::OnReadyToSend(); 561 Port::OnReadyToSend();
541 } 562 }
542 } 563 }
543 564
544 565
545 // Update current server address port with the alternate server address port. 566 // Update current server address port with the alternate server address port.
546 bool TurnPort::SetAlternateServer(const rtc::SocketAddress& address) { 567 bool TurnPort::SetAlternateServer(const rtc::SocketAddress& address) {
547 // Check if we have seen this address before and reject if we did. 568 // Check if we have seen this address before and reject if we did.
548 AttemptedServerSet::iterator iter = attempted_server_addresses_.find(address); 569 AttemptedServerSet::iterator iter = attempted_server_addresses_.find(address);
549 if (iter != attempted_server_addresses_.end()) { 570 if (iter != attempted_server_addresses_.end()) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 // Signal needs both resolved and unresolved address. After signal is sent 630 // Signal needs both resolved and unresolved address. After signal is sent
610 // we can copy resolved address back into |server_address_|. 631 // we can copy resolved address back into |server_address_|.
611 SignalResolvedServerAddress(this, server_address_.address, 632 SignalResolvedServerAddress(this, server_address_.address,
612 resolved_address); 633 resolved_address);
613 server_address_.address = resolved_address; 634 server_address_.address = resolved_address;
614 PrepareAddress(); 635 PrepareAddress();
615 } 636 }
616 637
617 void TurnPort::OnSendStunPacket(const void* data, size_t size, 638 void TurnPort::OnSendStunPacket(const void* data, size_t size,
618 StunRequest* request) { 639 StunRequest* request) {
640 ASSERT(connected());
619 rtc::PacketOptions options(DefaultDscpValue()); 641 rtc::PacketOptions options(DefaultDscpValue());
620 if (Send(data, size, options) < 0) { 642 if (Send(data, size, options) < 0) {
621 LOG_J(LS_ERROR, this) << "Failed to send TURN message, err=" 643 LOG_J(LS_ERROR, this) << "Failed to send TURN message, err="
622 << socket_->GetError(); 644 << socket_->GetError();
623 } 645 }
624 } 646 }
625 647
626 void TurnPort::OnStunAddress(const rtc::SocketAddress& address) { 648 void TurnPort::OnStunAddress(const rtc::SocketAddress& address) {
627 // STUN Port will discover STUN candidate, as it's supplied with first TURN 649 // STUN Port will discover STUN candidate, as it's supplied with first TURN
628 // server address. 650 // server address.
629 // Why not using this address? - P2PTransportChannel will start creating 651 // Why not using this address? - P2PTransportChannel will start creating
630 // connections after first candidate, which means it could start creating the 652 // connections after first candidate, which means it could start creating the
631 // connections before TURN candidate added. For that to handle, we need to 653 // connections before TURN candidate added. For that to handle, we need to
632 // supply STUN candidate from this port to UDPPort, and TurnPort should have 654 // supply STUN candidate from this port to UDPPort, and TurnPort should have
633 // handle to UDPPort to pass back the address. 655 // handle to UDPPort to pass back the address.
634 } 656 }
635 657
636 void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address, 658 void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,
637 const rtc::SocketAddress& stun_address) { 659 const rtc::SocketAddress& stun_address) {
638 connected_ = true; 660 state_ = STATE_READY;
639 661
640 rtc::SocketAddress related_address = stun_address; 662 rtc::SocketAddress related_address = stun_address;
641 if (!(candidate_filter() & CF_REFLEXIVE)) { 663 if (!(candidate_filter() & CF_REFLEXIVE)) {
642 // If candidate filter only allows relay type of address, empty raddr to 664 // If candidate filter only allows relay type of address, empty raddr to
643 // avoid local address leakage. 665 // avoid local address leakage.
644 related_address = rtc::EmptySocketAddressWithFamily(stun_address.family()); 666 related_address = rtc::EmptySocketAddressWithFamily(stun_address.family());
645 } 667 }
646 668
647 // For relayed candidate, Base is the candidate itself. 669 // For relayed candidate, Base is the candidate itself.
648 AddAddress(address, // Candidate address. 670 AddAddress(address, // Candidate address.
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 const rtc::SocketAddress& ext_addr) 1282 const rtc::SocketAddress& ext_addr)
1261 : port_(port), 1283 : port_(port),
1262 channel_id_(channel_id), 1284 channel_id_(channel_id),
1263 ext_addr_(ext_addr), 1285 ext_addr_(ext_addr),
1264 state_(STATE_UNBOUND) { 1286 state_(STATE_UNBOUND) {
1265 // Creating permission for |ext_addr_|. 1287 // Creating permission for |ext_addr_|.
1266 SendCreatePermissionRequest(); 1288 SendCreatePermissionRequest();
1267 } 1289 }
1268 1290
1269 void TurnEntry::SendCreatePermissionRequest() { 1291 void TurnEntry::SendCreatePermissionRequest() {
1270 port_->SendRequest(new TurnCreatePermissionRequest( 1292 if (port_->connected()) {
juberti1 2015/07/31 06:04:42 Might be better to return NULL from CreateConnecti
honghaiz3 2015/07/31 15:39:36 Done. This is a different version I prepared yeste
1271 port_, this, ext_addr_), 0); 1293 port_->SendRequest(new TurnCreatePermissionRequest(port_, this, ext_addr_),
1294 0);
1295 }
1272 } 1296 }
1273 1297
1274 void TurnEntry::SendChannelBindRequest(int delay) { 1298 void TurnEntry::SendChannelBindRequest(int delay) {
1275 port_->SendRequest(new TurnChannelBindRequest( 1299 port_->SendRequest(new TurnChannelBindRequest(
1276 port_, this, channel_id_, ext_addr_), delay); 1300 port_, this, channel_id_, ext_addr_), delay);
1277 } 1301 }
1278 1302
1279 int TurnEntry::Send(const void* data, size_t size, bool payload, 1303 int TurnEntry::Send(const void* data, size_t size, bool payload,
1280 const rtc::PacketOptions& options) { 1304 const rtc::PacketOptions& options) {
1281 rtc::ByteBuffer buf; 1305 rtc::ByteBuffer buf;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 1360 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3
1337 if (code == STUN_ERROR_STALE_NONCE) { 1361 if (code == STUN_ERROR_STALE_NONCE) {
1338 if (port_->UpdateNonce(response)) { 1362 if (port_->UpdateNonce(response)) {
1339 // Send channel bind request with fresh nonce. 1363 // Send channel bind request with fresh nonce.
1340 SendChannelBindRequest(0); 1364 SendChannelBindRequest(0);
1341 } 1365 }
1342 } 1366 }
1343 } 1367 }
1344 1368
1345 } // namespace cricket 1369 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/turnport.h ('k') | webrtc/p2p/base/turnport_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698