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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 // a channel for this remote destination to reduce the overhead of sending data. | 130 // a channel for this remote destination to reduce the overhead of sending data. |
131 class TurnEntry : public sigslot::has_slots<> { | 131 class TurnEntry : public sigslot::has_slots<> { |
132 public: | 132 public: |
133 enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND }; | 133 enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND }; |
134 TurnEntry(TurnPort* port, int channel_id, | 134 TurnEntry(TurnPort* port, int channel_id, |
135 const rtc::SocketAddress& ext_addr); | 135 const rtc::SocketAddress& ext_addr); |
136 | 136 |
137 TurnPort* port() { return port_; } | 137 TurnPort* port() { return port_; } |
138 | 138 |
139 int channel_id() const { return channel_id_; } | 139 int channel_id() const { return channel_id_; } |
140 // For testing only. | |
141 void set_channel_id(int channel_id) { channel_id_ = channel_id; } | |
142 | |
140 const rtc::SocketAddress& address() const { return ext_addr_; } | 143 const rtc::SocketAddress& address() const { return ext_addr_; } |
141 BindState state() const { return state_; } | 144 BindState state() const { return state_; } |
142 | 145 |
143 uint32_t destruction_timestamp() { return destruction_timestamp_; } | 146 uint32_t destruction_timestamp() { return destruction_timestamp_; } |
144 void set_destruction_timestamp(uint32_t destruction_timestamp) { | 147 void set_destruction_timestamp(uint32_t destruction_timestamp) { |
145 destruction_timestamp_ = destruction_timestamp; | 148 destruction_timestamp_ = destruction_timestamp; |
146 } | 149 } |
147 | 150 |
148 // Helper methods to send permission and channel bind requests. | 151 // Helper methods to send permission and channel bind requests. |
149 void SendCreatePermissionRequest(int delay); | 152 void SendCreatePermissionRequest(int delay); |
150 void SendChannelBindRequest(int delay); | 153 void SendChannelBindRequest(int delay); |
151 // Sends a packet to the given destination address. | 154 // Sends a packet to the given destination address. |
152 // This will wrap the packet in STUN if necessary. | 155 // This will wrap the packet in STUN if necessary. |
153 int Send(const void* data, size_t size, bool payload, | 156 int Send(const void* data, size_t size, bool payload, |
154 const rtc::PacketOptions& options); | 157 const rtc::PacketOptions& options); |
155 | 158 |
156 void OnCreatePermissionSuccess(); | 159 void OnCreatePermissionSuccess(); |
157 void OnCreatePermissionError(StunMessage* response, int code); | 160 void OnCreatePermissionError(StunMessage* response, int code); |
161 void OnCreatePermissionTimeout(); | |
158 void OnChannelBindSuccess(); | 162 void OnChannelBindSuccess(); |
159 void OnChannelBindError(StunMessage* response, int code); | 163 void OnChannelBindError(StunMessage* response, int code); |
164 void OnChannelBindTimeout(); | |
160 // Signal sent when TurnEntry is destroyed. | 165 // Signal sent when TurnEntry is destroyed. |
161 sigslot::signal1<TurnEntry*> SignalDestroyed; | 166 sigslot::signal1<TurnEntry*> SignalDestroyed; |
162 | 167 |
163 private: | 168 private: |
164 TurnPort* port_; | 169 TurnPort* port_; |
165 int channel_id_; | 170 int channel_id_; |
166 rtc::SocketAddress ext_addr_; | 171 rtc::SocketAddress ext_addr_; |
167 BindState state_; | 172 BindState state_; |
168 // A non-zero value indicates that this entry is scheduled to be destroyed. | 173 // A non-zero value indicates that this entry is scheduled to be destroyed. |
169 // It is also used as an ID of the event scheduling. When the destruction | 174 // It is also used as an ID of the event scheduling. When the destruction |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
457 if (Candidates()[index].type() == RELAY_PORT_TYPE) { | 462 if (Candidates()[index].type() == RELAY_PORT_TYPE) { |
458 ProxyConnection* conn = new ProxyConnection(this, index, address); | 463 ProxyConnection* conn = new ProxyConnection(this, index, address); |
459 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed); | 464 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed); |
460 AddConnection(conn); | 465 AddConnection(conn); |
461 return conn; | 466 return conn; |
462 } | 467 } |
463 } | 468 } |
464 return NULL; | 469 return NULL; |
465 } | 470 } |
466 | 471 |
472 void TurnPort::DestroyConnection(const rtc::SocketAddress& address) { | |
pthatcher1
2015/12/08 20:04:20
Should it return a bool of whether or not it was d
honghaiz3
2015/12/10 17:58:30
Done
| |
473 Connection* conn = GetConnection(address); | |
474 if (conn != nullptr) { | |
475 conn->Destroy(); | |
476 } | |
477 } | |
478 | |
467 int TurnPort::SetOption(rtc::Socket::Option opt, int value) { | 479 int TurnPort::SetOption(rtc::Socket::Option opt, int value) { |
468 if (!socket_) { | 480 if (!socket_) { |
469 // If socket is not created yet, these options will be applied during socket | 481 // If socket is not created yet, these options will be applied during socket |
470 // creation. | 482 // creation. |
471 socket_options_[opt] = value; | 483 socket_options_[opt] = value; |
472 return 0; | 484 return 0; |
473 } | 485 } |
474 return socket_->SetOption(opt, value); | 486 return socket_->SetOption(opt, value); |
475 } | 487 } |
476 | 488 |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
689 "", // TCP canddiate type, empty for turn candidates. | 701 "", // TCP canddiate type, empty for turn candidates. |
690 RELAY_PORT_TYPE, | 702 RELAY_PORT_TYPE, |
691 GetRelayPreference(server_address_.proto, server_address_.secure), | 703 GetRelayPreference(server_address_.proto, server_address_.secure), |
692 server_priority_, true); | 704 server_priority_, true); |
693 } | 705 } |
694 | 706 |
695 void TurnPort::OnAllocateError() { | 707 void TurnPort::OnAllocateError() { |
696 // We will send SignalPortError asynchronously as this can be sent during | 708 // We will send SignalPortError asynchronously as this can be sent during |
697 // port initialization. This way it will not be blocking other port | 709 // port initialization. This way it will not be blocking other port |
698 // creation. | 710 // creation. |
699 thread()->Post(this, MSG_ERROR); | 711 thread()->Post(this, MSG_ALLOCATE_ERROR); |
712 } | |
713 | |
714 void TurnPort::OnTurnRefreshError() { | |
715 // Stop the port from creating new connections. | |
716 state_ = STATE_DISCONNECTED; | |
717 // Delete all existing connections; stop sending data. | |
718 for (auto kv : connections()) { | |
719 kv.second->Destroy(); | |
720 } | |
pthatcher1
2015/12/08 20:04:20
Should we have a TunrPort::Close method that does
honghaiz3
2015/12/10 17:58:30
Done.
| |
700 } | 721 } |
701 | 722 |
702 void TurnPort::OnMessage(rtc::Message* message) { | 723 void TurnPort::OnMessage(rtc::Message* message) { |
703 if (message->message_id == MSG_ERROR) { | 724 switch (message->message_id) { |
704 SignalPortError(this); | 725 case MSG_ALLOCATE_ERROR: |
705 return; | 726 SignalPortError(this); |
706 } else if (message->message_id == MSG_ALLOCATE_MISMATCH) { | 727 break; |
707 OnAllocateMismatch(); | 728 case MSG_ALLOCATE_MISMATCH: |
708 return; | 729 OnAllocateMismatch(); |
709 } else if (message->message_id == MSG_TRY_ALTERNATE_SERVER) { | 730 break; |
710 if (server_address().proto == PROTO_UDP) { | 731 case MSG_TRY_ALTERNATE_SERVER: |
711 // Send another allocate request to alternate server, with the received | 732 if (server_address().proto == PROTO_UDP) { |
712 // realm and nonce values. | 733 // Send another allocate request to alternate server, with the received |
713 SendRequest(new TurnAllocateRequest(this), 0); | 734 // realm and nonce values. |
714 } else { | 735 SendRequest(new TurnAllocateRequest(this), 0); |
715 // Since it's TCP, we have to delete the connected socket and reconnect | 736 } else { |
716 // with the alternate server. PrepareAddress will send stun binding once | 737 // Since it's TCP, we have to delete the connected socket and reconnect |
717 // the new socket is connected. | 738 // with the alternate server. PrepareAddress will send stun binding once |
718 ASSERT(server_address().proto == PROTO_TCP); | 739 // the new socket is connected. |
719 ASSERT(!SharedSocket()); | 740 ASSERT(server_address().proto == PROTO_TCP); |
720 delete socket_; | 741 ASSERT(!SharedSocket()); |
721 socket_ = NULL; | 742 delete socket_; |
722 PrepareAddress(); | 743 socket_ = NULL; |
723 } | 744 PrepareAddress(); |
724 return; | 745 } |
746 break; | |
747 default: | |
748 Port::OnMessage(message); | |
725 } | 749 } |
726 Port::OnMessage(message); | |
727 } | 750 } |
728 | 751 |
729 void TurnPort::OnAllocateRequestTimeout() { | 752 void TurnPort::OnAllocateRequestTimeout() { |
730 OnAllocateError(); | 753 OnAllocateError(); |
731 } | 754 } |
732 | 755 |
733 void TurnPort::HandleDataIndication(const char* data, size_t size, | 756 void TurnPort::HandleDataIndication(const char* data, size_t size, |
734 const rtc::PacketTime& packet_time) { | 757 const rtc::PacketTime& packet_time) { |
735 // Read in the message, and process according to RFC5766, Section 10.4. | 758 // Read in the message, and process according to RFC5766, Section 10.4. |
736 rtc::ByteBuffer buf(data, size); | 759 rtc::ByteBuffer buf(data, size); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
951 thread(), | 974 thread(), |
952 rtc::Bind(&TurnPort::DestroyEntryIfNotCancelled, this, entry, timestamp), | 975 rtc::Bind(&TurnPort::DestroyEntryIfNotCancelled, this, entry, timestamp), |
953 TURN_PERMISSION_TIMEOUT); | 976 TURN_PERMISSION_TIMEOUT); |
954 } | 977 } |
955 | 978 |
956 void TurnPort::CancelEntryDestruction(TurnEntry* entry) { | 979 void TurnPort::CancelEntryDestruction(TurnEntry* entry) { |
957 ASSERT(entry->destruction_timestamp() != 0); | 980 ASSERT(entry->destruction_timestamp() != 0); |
958 entry->set_destruction_timestamp(0); | 981 entry->set_destruction_timestamp(0); |
959 } | 982 } |
960 | 983 |
984 bool TurnPort::SetEntryChannelId(const rtc::SocketAddress& address, | |
985 int channel_id) { | |
986 TurnEntry* entry = FindEntry(address); | |
pthatcher1
2015/12/08 20:04:19
Can we just make FindEntry callable by the unit te
honghaiz3
2015/12/10 17:58:30
If we do that, we will need to make TurnEntry acce
| |
987 if (!entry) { | |
988 return false; | |
989 } | |
990 entry->set_channel_id(channel_id); | |
991 return true; | |
992 } | |
993 | |
961 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port) | 994 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port) |
962 : StunRequest(new TurnMessage()), | 995 : StunRequest(new TurnMessage()), |
963 port_(port) { | 996 port_(port) { |
964 } | 997 } |
965 | 998 |
966 void TurnAllocateRequest::Prepare(StunMessage* request) { | 999 void TurnAllocateRequest::Prepare(StunMessage* request) { |
967 // Create the request as indicated in RFC 5766, Section 6.1. | 1000 // Create the request as indicated in RFC 5766, Section 6.1. |
968 request->SetType(TURN_ALLOCATE_REQUEST); | 1001 request->SetType(TURN_ALLOCATE_REQUEST); |
969 StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32( | 1002 StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32( |
970 STUN_ATTR_REQUESTED_TRANSPORT); | 1003 STUN_ATTR_REQUESTED_TRANSPORT); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1164 const StunUInt32Attribute* lifetime_attr = | 1197 const StunUInt32Attribute* lifetime_attr = |
1165 response->GetUInt32(STUN_ATTR_TURN_LIFETIME); | 1198 response->GetUInt32(STUN_ATTR_TURN_LIFETIME); |
1166 if (!lifetime_attr) { | 1199 if (!lifetime_attr) { |
1167 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in " | 1200 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in " |
1168 << "refresh success response."; | 1201 << "refresh success response."; |
1169 return; | 1202 return; |
1170 } | 1203 } |
1171 | 1204 |
1172 // Schedule a refresh based on the returned lifetime value. | 1205 // Schedule a refresh based on the returned lifetime value. |
1173 port_->ScheduleRefresh(lifetime_attr->value()); | 1206 port_->ScheduleRefresh(lifetime_attr->value()); |
1207 // Result code 0 means the refresh request is successful. | |
1208 port_->SignalTurnRefreshResult(port_, 0); | |
pthatcher1
2015/12/08 20:04:19
Can we make a name constant for it? kTurnRefreshS
honghaiz3
2015/12/10 17:58:30
used name RESULT_SUCCESS_CODE. also used this for
| |
1174 } | 1209 } |
1175 | 1210 |
1176 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) { | 1211 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) { |
1177 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); | 1212 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); |
1178 | 1213 |
1179 LOG_J(LS_INFO, port_) << "Received TURN refresh error response" | |
1180 << ", id=" << rtc::hex_encode(id()) | |
1181 << ", code=" << error_code->code() | |
1182 << ", rtt=" << Elapsed(); | |
1183 | |
1184 if (error_code->code() == STUN_ERROR_STALE_NONCE) { | 1214 if (error_code->code() == STUN_ERROR_STALE_NONCE) { |
1185 if (port_->UpdateNonce(response)) { | 1215 if (port_->UpdateNonce(response)) { |
1186 // Send RefreshRequest immediately. | 1216 // Send RefreshRequest immediately. |
1187 port_->SendRequest(new TurnRefreshRequest(port_), 0); | 1217 port_->SendRequest(new TurnRefreshRequest(port_), 0); |
1188 } | 1218 } |
1189 } else { | 1219 } else { |
1190 LOG_J(LS_WARNING, port_) << "Received TURN refresh error response" | 1220 LOG_J(LS_WARNING, port_) << "Received TURN refresh error response" |
1191 << ", id=" << rtc::hex_encode(id()) | 1221 << ", id=" << rtc::hex_encode(id()) |
1192 << ", code=" << error_code->code() | 1222 << ", code=" << error_code->code() |
1193 << ", rtt=" << Elapsed(); | 1223 << ", rtt=" << Elapsed(); |
1224 port_->OnTurnRefreshError(); | |
1225 port_->SignalTurnRefreshResult(port_, error_code->code()); | |
1194 } | 1226 } |
1195 } | 1227 } |
1196 | 1228 |
1197 void TurnRefreshRequest::OnTimeout() { | 1229 void TurnRefreshRequest::OnTimeout() { |
1198 LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id()); | 1230 LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id()); |
1231 port_->OnTurnRefreshError(); | |
1199 } | 1232 } |
1200 | 1233 |
1201 TurnCreatePermissionRequest::TurnCreatePermissionRequest( | 1234 TurnCreatePermissionRequest::TurnCreatePermissionRequest( |
1202 TurnPort* port, TurnEntry* entry, | 1235 TurnPort* port, TurnEntry* entry, |
1203 const rtc::SocketAddress& ext_addr) | 1236 const rtc::SocketAddress& ext_addr) |
1204 : StunRequest(new TurnMessage()), | 1237 : StunRequest(new TurnMessage()), |
1205 port_(port), | 1238 port_(port), |
1206 entry_(entry), | 1239 entry_(entry), |
1207 ext_addr_(ext_addr) { | 1240 ext_addr_(ext_addr) { |
1208 entry_->SignalDestroyed.connect( | 1241 entry_->SignalDestroyed.connect( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1241 << ", code=" << error_code->code() | 1274 << ", code=" << error_code->code() |
1242 << ", rtt=" << Elapsed(); | 1275 << ", rtt=" << Elapsed(); |
1243 if (entry_) { | 1276 if (entry_) { |
1244 entry_->OnCreatePermissionError(response, error_code->code()); | 1277 entry_->OnCreatePermissionError(response, error_code->code()); |
1245 } | 1278 } |
1246 } | 1279 } |
1247 | 1280 |
1248 void TurnCreatePermissionRequest::OnTimeout() { | 1281 void TurnCreatePermissionRequest::OnTimeout() { |
1249 LOG_J(LS_WARNING, port_) << "TURN create permission timeout " | 1282 LOG_J(LS_WARNING, port_) << "TURN create permission timeout " |
1250 << rtc::hex_encode(id()); | 1283 << rtc::hex_encode(id()); |
1284 if (entry_) { | |
1285 entry_->OnCreatePermissionTimeout(); | |
1286 } | |
1251 } | 1287 } |
1252 | 1288 |
1253 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) { | 1289 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) { |
1254 ASSERT(entry_ == entry); | 1290 ASSERT(entry_ == entry); |
1255 entry_ = NULL; | 1291 entry_ = NULL; |
1256 } | 1292 } |
1257 | 1293 |
1258 TurnChannelBindRequest::TurnChannelBindRequest( | 1294 TurnChannelBindRequest::TurnChannelBindRequest( |
1259 TurnPort* port, TurnEntry* entry, | 1295 TurnPort* port, TurnEntry* entry, |
1260 int channel_id, const rtc::SocketAddress& ext_addr) | 1296 int channel_id, const rtc::SocketAddress& ext_addr) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1308 << ", code=" << error_code->code() | 1344 << ", code=" << error_code->code() |
1309 << ", rtt=" << Elapsed(); | 1345 << ", rtt=" << Elapsed(); |
1310 if (entry_) { | 1346 if (entry_) { |
1311 entry_->OnChannelBindError(response, error_code->code()); | 1347 entry_->OnChannelBindError(response, error_code->code()); |
1312 } | 1348 } |
1313 } | 1349 } |
1314 | 1350 |
1315 void TurnChannelBindRequest::OnTimeout() { | 1351 void TurnChannelBindRequest::OnTimeout() { |
1316 LOG_J(LS_WARNING, port_) << "TURN channel bind timeout " | 1352 LOG_J(LS_WARNING, port_) << "TURN channel bind timeout " |
1317 << rtc::hex_encode(id()); | 1353 << rtc::hex_encode(id()); |
1354 if (entry_) { | |
1355 entry_->OnChannelBindTimeout(); | |
1356 } | |
1318 } | 1357 } |
1319 | 1358 |
1320 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) { | 1359 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) { |
1321 ASSERT(entry_ == entry); | 1360 ASSERT(entry_ == entry); |
1322 entry_ = NULL; | 1361 entry_ = NULL; |
1323 } | 1362 } |
1324 | 1363 |
1325 TurnEntry::TurnEntry(TurnPort* port, int channel_id, | 1364 TurnEntry::TurnEntry(TurnPort* port, int channel_id, |
1326 const rtc::SocketAddress& ext_addr) | 1365 const rtc::SocketAddress& ext_addr) |
1327 : port_(port), | 1366 : port_(port), |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1389 << delay << "ms."; | 1428 << delay << "ms."; |
1390 } | 1429 } |
1391 } | 1430 } |
1392 | 1431 |
1393 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) { | 1432 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) { |
1394 if (code == STUN_ERROR_STALE_NONCE) { | 1433 if (code == STUN_ERROR_STALE_NONCE) { |
1395 if (port_->UpdateNonce(response)) { | 1434 if (port_->UpdateNonce(response)) { |
1396 SendCreatePermissionRequest(0); | 1435 SendCreatePermissionRequest(0); |
1397 } | 1436 } |
1398 } else { | 1437 } else { |
1438 port_->DestroyConnection(ext_addr_); | |
1399 // Send signal with error code. | 1439 // Send signal with error code. |
1400 port_->SignalCreatePermissionResult(port_, ext_addr_, code); | 1440 port_->SignalCreatePermissionResult(port_, ext_addr_, code); |
1401 } | 1441 } |
1402 } | 1442 } |
1403 | 1443 |
1444 void TurnEntry::OnCreatePermissionTimeout() { | |
1445 port_->DestroyConnection(ext_addr_); | |
1446 } | |
1447 | |
1404 void TurnEntry::OnChannelBindSuccess() { | 1448 void TurnEntry::OnChannelBindSuccess() { |
1405 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString() | 1449 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString() |
1406 << " succeeded"; | 1450 << " succeeded"; |
1407 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND); | 1451 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND); |
1408 state_ = STATE_BOUND; | 1452 state_ = STATE_BOUND; |
1409 } | 1453 } |
1410 | 1454 |
1411 void TurnEntry::OnChannelBindError(StunMessage* response, int code) { | 1455 void TurnEntry::OnChannelBindError(StunMessage* response, int code) { |
1412 // TODO(mallinath) - Implement handling of error response for channel | 1456 // If the channel bind fails due to errors other than STATE_NONCE, |
1413 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 | 1457 // we just destroy the connection and rely on ICE restart to re-establish |
1458 // the connection. | |
1414 if (code == STUN_ERROR_STALE_NONCE) { | 1459 if (code == STUN_ERROR_STALE_NONCE) { |
1415 if (port_->UpdateNonce(response)) { | 1460 if (port_->UpdateNonce(response)) { |
1416 // Send channel bind request with fresh nonce. | 1461 // Send channel bind request with fresh nonce. |
1417 SendChannelBindRequest(0); | 1462 SendChannelBindRequest(0); |
1418 } | 1463 } |
1464 } else { | |
1465 state_ = STATE_UNBOUND; | |
1466 port_->DestroyConnection(ext_addr_); | |
1419 } | 1467 } |
1420 } | 1468 } |
1421 | 1469 void TurnEntry::OnChannelBindTimeout() { |
1470 state_ = STATE_UNBOUND; | |
1471 port_->DestroyConnection(ext_addr_); | |
1472 } | |
1422 } // namespace cricket | 1473 } // namespace cricket |
OLD | NEW |