OLD | NEW |
---|---|
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 Loading... | |
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 port_state_(DISCONNECTED), |
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 port_state_(DISCONNECTED), |
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 (connected()) { |
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 Loading... | |
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: " |
juberti1
2015/07/29 05:28:13
Address -> address
honghaiz3
2015/07/29 21:44:13
Done.
| |
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 |
301 void TurnPort::SendAllocateRequest(int delay) { | |
302 SendRequest(new TurnAllocateRequest(this), delay); | |
303 } | |
304 | |
286 bool TurnPort::CreateTurnClientSocket() { | 305 bool TurnPort::CreateTurnClientSocket() { |
287 ASSERT(!socket_ || SharedSocket()); | 306 ASSERT(!socket_ || SharedSocket()); |
288 | 307 |
289 if (server_address_.proto == PROTO_UDP && !SharedSocket()) { | 308 if (server_address_.proto == PROTO_UDP && !SharedSocket()) { |
290 socket_ = socket_factory()->CreateUdpSocket( | 309 socket_ = socket_factory()->CreateUdpSocket( |
291 rtc::SocketAddress(ip(), 0), min_port(), max_port()); | 310 rtc::SocketAddress(ip(), 0), min_port(), max_port()); |
292 } else if (server_address_.proto == PROTO_TCP) { | 311 } else if (server_address_.proto == PROTO_TCP) { |
293 ASSERT(!SharedSocket()); | 312 ASSERT(!SharedSocket()); |
294 int opts = rtc::PacketSocketFactory::OPT_STUN; | 313 int opts = rtc::PacketSocketFactory::OPT_STUN; |
295 // If secure bit is enabled in server address, use TLS over TCP. | 314 // If secure bit is enabled in server address, use TLS over TCP. |
(...skipping 16 matching lines...) Expand all Loading... | |
312 socket_->SetOption(iter->first, iter->second); | 331 socket_->SetOption(iter->first, iter->second); |
313 } | 332 } |
314 | 333 |
315 if (!SharedSocket()) { | 334 if (!SharedSocket()) { |
316 // If socket is shared, AllocationSequence will receive the packet. | 335 // If socket is shared, AllocationSequence will receive the packet. |
317 socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket); | 336 socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket); |
318 } | 337 } |
319 | 338 |
320 socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend); | 339 socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend); |
321 | 340 |
341 // TCP port becomes CONNECTING after the socket is connected, | |
juberti1
2015/07/29 05:28:13
The port becomes connecting after the socket is co
pthatcher1
2015/07/29 20:51:50
It's already like that in the existing code, where
honghaiz3
2015/07/29 21:44:13
If we change the name, we'd better change all thre
juberti1
2015/07/30 20:47:40
how about STATE_CONNECTING (init), STATE_CONNECTED
pthatcher1
2015/07/30 21:29:16
That sounds fine. The only strange part is that c
honghaiz3
2015/07/30 21:35:05
Well, I can change the method to ready() :)
STAT
| |
342 // while UDP port becomes CONNECTING once the socket is created. | |
322 if (server_address_.proto == PROTO_TCP) { | 343 if (server_address_.proto == PROTO_TCP) { |
323 socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect); | 344 socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect); |
324 socket_->SignalClose.connect(this, &TurnPort::OnSocketClose); | 345 socket_->SignalClose.connect(this, &TurnPort::OnSocketClose); |
346 } else { | |
347 port_state_ = CONNECTING; | |
325 } | 348 } |
326 return true; | 349 return true; |
327 } | 350 } |
328 | 351 |
329 void TurnPort::OnSocketConnect(rtc::AsyncPacketSocket* socket) { | 352 void TurnPort::OnSocketConnect(rtc::AsyncPacketSocket* socket) { |
330 ASSERT(server_address_.proto == PROTO_TCP); | 353 ASSERT(server_address_.proto == PROTO_TCP); |
331 // Do not use this port if the socket bound to a different address than | 354 // 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 | 355 // 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 | 356 // given a binding address, and the platform is expected to pick the |
334 // correct local address. | 357 // correct local address. |
(...skipping 18 matching lines...) Expand all Loading... | |
353 } else { | 376 } else { |
354 LOG(LS_WARNING) << "Socket is bound to a different address:" | 377 LOG(LS_WARNING) << "Socket is bound to a different address:" |
355 << socket->GetLocalAddress().ipaddr().ToString() | 378 << socket->GetLocalAddress().ipaddr().ToString() |
356 << ", rather then the local port:" << ip().ToString() | 379 << ", rather then the local port:" << ip().ToString() |
357 << ". Discarding TURN port."; | 380 << ". Discarding TURN port."; |
358 OnAllocateError(); | 381 OnAllocateError(); |
359 return; | 382 return; |
360 } | 383 } |
361 } | 384 } |
362 | 385 |
386 port_state_ = CONNECTING; // It is ready to send stun requests. | |
363 if (server_address_.address.IsUnresolved()) { | 387 if (server_address_.address.IsUnresolved()) { |
364 server_address_.address = socket_->GetRemoteAddress(); | 388 server_address_.address = socket_->GetRemoteAddress(); |
365 } | 389 } |
366 | 390 |
367 LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress() | 391 LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress() |
368 << " using tcp."; | 392 << " using tcp."; |
369 SendRequest(new TurnAllocateRequest(this), 0); | 393 SendRequest(new TurnAllocateRequest(this), 0); |
370 } | 394 } |
371 | 395 |
372 void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) { | 396 void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) { |
373 LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error; | 397 LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error; |
374 ASSERT(socket == socket_); | 398 ASSERT(socket == socket_); |
375 if (!connected_) { | 399 if (port_state_ == DISCONNECTED) { |
376 OnAllocateError(); | 400 OnAllocateError(); |
377 } | 401 } |
378 connected_ = false; | 402 port_state_ = DISCONNECTED; |
379 } | 403 } |
380 | 404 |
381 void TurnPort::OnAllocateMismatch() { | 405 void TurnPort::OnAllocateMismatch() { |
382 if (allocate_mismatch_retries_ >= MAX_ALLOCATE_MISMATCH_RETRIES) { | 406 if (allocate_mismatch_retries_ >= MAX_ALLOCATE_MISMATCH_RETRIES) { |
383 LOG_J(LS_WARNING, this) << "Giving up on the port after " | 407 LOG_J(LS_WARNING, this) << "Giving up on the port after " |
384 << allocate_mismatch_retries_ | 408 << allocate_mismatch_retries_ |
385 << " retries for STUN_ERROR_ALLOCATION_MISMATCH"; | 409 << " retries for STUN_ERROR_ALLOCATION_MISMATCH"; |
386 OnAllocateError(); | 410 OnAllocateError(); |
387 return; | 411 return; |
388 } | 412 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
455 int TurnPort::GetError() { | 479 int TurnPort::GetError() { |
456 return error_; | 480 return error_; |
457 } | 481 } |
458 | 482 |
459 int TurnPort::SendTo(const void* data, size_t size, | 483 int TurnPort::SendTo(const void* data, size_t size, |
460 const rtc::SocketAddress& addr, | 484 const rtc::SocketAddress& addr, |
461 const rtc::PacketOptions& options, | 485 const rtc::PacketOptions& options, |
462 bool payload) { | 486 bool payload) { |
463 // Try to find an entry for this specific address; we should have one. | 487 // Try to find an entry for this specific address; we should have one. |
464 TurnEntry* entry = FindEntry(addr); | 488 TurnEntry* entry = FindEntry(addr); |
465 ASSERT(entry != NULL); | |
466 if (!entry) { | 489 if (!entry) { |
490 LOG(LS_ERROR) << "Did not find the TurnEntry for address " << addr; | |
467 return 0; | 491 return 0; |
468 } | 492 } |
469 | 493 |
470 if (!connected()) { | 494 if (!connected()) { |
471 error_ = EWOULDBLOCK; | 495 error_ = EWOULDBLOCK; |
472 return SOCKET_ERROR; | 496 return SOCKET_ERROR; |
473 } | 497 } |
474 | 498 |
475 // Send the actual contents to the server using the usual mechanism. | 499 // Send the actual contents to the server using the usual mechanism. |
476 int sent = entry->Send(data, size, payload, options); | 500 int sent = entry->Send(data, size, payload, options); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
529 !StunMessage::ValidateMessageIntegrity(data, size, hash())) { | 553 !StunMessage::ValidateMessageIntegrity(data, size, hash())) { |
530 LOG_J(LS_WARNING, this) << "Received TURN message with invalid " | 554 LOG_J(LS_WARNING, this) << "Received TURN message with invalid " |
531 << "message integrity, msg_type=" << msg_type; | 555 << "message integrity, msg_type=" << msg_type; |
532 return; | 556 return; |
533 } | 557 } |
534 request_manager_.CheckResponse(data, size); | 558 request_manager_.CheckResponse(data, size); |
535 } | 559 } |
536 } | 560 } |
537 | 561 |
538 void TurnPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) { | 562 void TurnPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) { |
539 if (connected_) { | 563 if (connected()) { |
540 Port::OnReadyToSend(); | 564 Port::OnReadyToSend(); |
541 } | 565 } |
542 } | 566 } |
543 | 567 |
544 | 568 |
545 // Update current server address port with the alternate server address port. | 569 // Update current server address port with the alternate server address port. |
546 bool TurnPort::SetAlternateServer(const rtc::SocketAddress& address) { | 570 bool TurnPort::SetAlternateServer(const rtc::SocketAddress& address) { |
547 // Check if we have seen this address before and reject if we did. | 571 // Check if we have seen this address before and reject if we did. |
548 AttemptedServerSet::iterator iter = attempted_server_addresses_.find(address); | 572 AttemptedServerSet::iterator iter = attempted_server_addresses_.find(address); |
549 if (iter != attempted_server_addresses_.end()) { | 573 if (iter != attempted_server_addresses_.end()) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
609 // Signal needs both resolved and unresolved address. After signal is sent | 633 // Signal needs both resolved and unresolved address. After signal is sent |
610 // we can copy resolved address back into |server_address_|. | 634 // we can copy resolved address back into |server_address_|. |
611 SignalResolvedServerAddress(this, server_address_.address, | 635 SignalResolvedServerAddress(this, server_address_.address, |
612 resolved_address); | 636 resolved_address); |
613 server_address_.address = resolved_address; | 637 server_address_.address = resolved_address; |
614 PrepareAddress(); | 638 PrepareAddress(); |
615 } | 639 } |
616 | 640 |
617 void TurnPort::OnSendStunPacket(const void* data, size_t size, | 641 void TurnPort::OnSendStunPacket(const void* data, size_t size, |
618 StunRequest* request) { | 642 StunRequest* request) { |
643 if (port_state_ == DISCONNECTED) { | |
juberti1
2015/07/29 05:28:13
Could we just flush pending packets when the conne
pthatcher1
2015/07/29 20:51:50
We could add a StunRequestManager::RemoveAll that
honghaiz3
2015/07/29 21:44:13
Actually there is a request_manager_->Clear method
pthatcher1
2015/07/29 22:00:10
But if RequestManager called thread_->Clear(), I t
juberti1
2015/07/30 18:22:33
I think Clear() + a check during permission creati
honghaiz3
2015/07/30 18:38:27
That means we will keep all the changes on the Por
juberti1
2015/07/30 20:47:40
right. We would ASSERT if we get a packet when STA
honghaiz3
2015/07/31 00:17:06
Done.
| |
644 LOG(LS_WARNING) << "Dropping STUN request because port is disconnected"; | |
645 return; | |
646 } | |
619 rtc::PacketOptions options(DefaultDscpValue()); | 647 rtc::PacketOptions options(DefaultDscpValue()); |
620 if (Send(data, size, options) < 0) { | 648 if (Send(data, size, options) < 0) { |
621 LOG_J(LS_ERROR, this) << "Failed to send TURN message, err=" | 649 LOG_J(LS_ERROR, this) << "Failed to send TURN message, err=" |
622 << socket_->GetError(); | 650 << socket_->GetError(); |
623 } | 651 } |
624 } | 652 } |
625 | 653 |
626 void TurnPort::OnStunAddress(const rtc::SocketAddress& address) { | 654 void TurnPort::OnStunAddress(const rtc::SocketAddress& address) { |
627 // STUN Port will discover STUN candidate, as it's supplied with first TURN | 655 // STUN Port will discover STUN candidate, as it's supplied with first TURN |
628 // server address. | 656 // server address. |
629 // Why not using this address? - P2PTransportChannel will start creating | 657 // Why not using this address? - P2PTransportChannel will start creating |
630 // connections after first candidate, which means it could start creating the | 658 // connections after first candidate, which means it could start creating the |
631 // connections before TURN candidate added. For that to handle, we need to | 659 // 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 | 660 // supply STUN candidate from this port to UDPPort, and TurnPort should have |
633 // handle to UDPPort to pass back the address. | 661 // handle to UDPPort to pass back the address. |
634 } | 662 } |
635 | 663 |
636 void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address, | 664 void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address, |
637 const rtc::SocketAddress& stun_address) { | 665 const rtc::SocketAddress& stun_address) { |
638 connected_ = true; | 666 port_state_ = CONNECTED; |
639 | 667 |
640 rtc::SocketAddress related_address = stun_address; | 668 rtc::SocketAddress related_address = stun_address; |
641 if (!(candidate_filter() & CF_REFLEXIVE)) { | 669 if (!(candidate_filter() & CF_REFLEXIVE)) { |
642 // If candidate filter only allows relay type of address, empty raddr to | 670 // If candidate filter only allows relay type of address, empty raddr to |
643 // avoid local address leakage. | 671 // avoid local address leakage. |
644 related_address = rtc::EmptySocketAddressWithFamily(stun_address.family()); | 672 related_address = rtc::EmptySocketAddressWithFamily(stun_address.family()); |
645 } | 673 } |
646 | 674 |
647 // For relayed candidate, Base is the candidate itself. | 675 // For relayed candidate, Base is the candidate itself. |
648 AddAddress(address, // Candidate address. | 676 AddAddress(address, // Candidate address. |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1336 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 | 1364 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 |
1337 if (code == STUN_ERROR_STALE_NONCE) { | 1365 if (code == STUN_ERROR_STALE_NONCE) { |
1338 if (port_->UpdateNonce(response)) { | 1366 if (port_->UpdateNonce(response)) { |
1339 // Send channel bind request with fresh nonce. | 1367 // Send channel bind request with fresh nonce. |
1340 SendChannelBindRequest(0); | 1368 SendChannelBindRequest(0); |
1341 } | 1369 } |
1342 } | 1370 } |
1343 } | 1371 } |
1344 | 1372 |
1345 } // namespace cricket | 1373 } // namespace cricket |
OLD | NEW |