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 20 matching lines...) Expand all Loading... |
31 static const int TURN_DEFAULT_PORT = 3478; | 31 static const int TURN_DEFAULT_PORT = 3478; |
32 static const int TURN_CHANNEL_NUMBER_START = 0x4000; | 32 static const int TURN_CHANNEL_NUMBER_START = 0x4000; |
33 static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000; // 5 minutes | 33 static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000; // 5 minutes |
34 | 34 |
35 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U; | 35 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U; |
36 | 36 |
37 // Retry at most twice (i.e. three different ALLOCATE requests) on | 37 // Retry at most twice (i.e. three different ALLOCATE requests) on |
38 // STUN_ERROR_ALLOCATION_MISMATCH error per rfc5766. | 38 // STUN_ERROR_ALLOCATION_MISMATCH error per rfc5766. |
39 static const size_t MAX_ALLOCATE_MISMATCH_RETRIES = 2; | 39 static const size_t MAX_ALLOCATE_MISMATCH_RETRIES = 2; |
40 | 40 |
| 41 static const int TURN_SUCCESS_RESULT_CODE = 0; |
| 42 |
41 inline bool IsTurnChannelData(uint16_t msg_type) { | 43 inline bool IsTurnChannelData(uint16_t msg_type) { |
42 return ((msg_type & 0xC000) == 0x4000); // MSB are 0b01 | 44 return ((msg_type & 0xC000) == 0x4000); // MSB are 0b01 |
43 } | 45 } |
44 | 46 |
45 static int GetRelayPreference(cricket::ProtocolType proto, bool secure) { | 47 static int GetRelayPreference(cricket::ProtocolType proto, bool secure) { |
46 int relay_preference = ICE_TYPE_PREFERENCE_RELAY; | 48 int relay_preference = ICE_TYPE_PREFERENCE_RELAY; |
47 if (proto == cricket::PROTO_TCP) { | 49 if (proto == cricket::PROTO_TCP) { |
48 relay_preference -= 1; | 50 relay_preference -= 1; |
49 if (secure) | 51 if (secure) |
50 relay_preference -= 1; | 52 relay_preference -= 1; |
(...skipping 79 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. | 132 // a channel for this remote destination to reduce the overhead of sending data. |
131 class TurnEntry : public sigslot::has_slots<> { | 133 class TurnEntry : public sigslot::has_slots<> { |
132 public: | 134 public: |
133 enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND }; | 135 enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND }; |
134 TurnEntry(TurnPort* port, int channel_id, | 136 TurnEntry(TurnPort* port, int channel_id, |
135 const rtc::SocketAddress& ext_addr); | 137 const rtc::SocketAddress& ext_addr); |
136 | 138 |
137 TurnPort* port() { return port_; } | 139 TurnPort* port() { return port_; } |
138 | 140 |
139 int channel_id() const { return channel_id_; } | 141 int channel_id() const { return channel_id_; } |
| 142 // For testing only. |
| 143 void set_channel_id(int channel_id) { channel_id_ = channel_id; } |
| 144 |
140 const rtc::SocketAddress& address() const { return ext_addr_; } | 145 const rtc::SocketAddress& address() const { return ext_addr_; } |
141 BindState state() const { return state_; } | 146 BindState state() const { return state_; } |
142 | 147 |
143 uint32_t destruction_timestamp() { return destruction_timestamp_; } | 148 uint32_t destruction_timestamp() { return destruction_timestamp_; } |
144 void set_destruction_timestamp(uint32_t destruction_timestamp) { | 149 void set_destruction_timestamp(uint32_t destruction_timestamp) { |
145 destruction_timestamp_ = destruction_timestamp; | 150 destruction_timestamp_ = destruction_timestamp; |
146 } | 151 } |
147 | 152 |
148 // Helper methods to send permission and channel bind requests. | 153 // Helper methods to send permission and channel bind requests. |
149 void SendCreatePermissionRequest(int delay); | 154 void SendCreatePermissionRequest(int delay); |
150 void SendChannelBindRequest(int delay); | 155 void SendChannelBindRequest(int delay); |
151 // Sends a packet to the given destination address. | 156 // Sends a packet to the given destination address. |
152 // This will wrap the packet in STUN if necessary. | 157 // This will wrap the packet in STUN if necessary. |
153 int Send(const void* data, size_t size, bool payload, | 158 int Send(const void* data, size_t size, bool payload, |
154 const rtc::PacketOptions& options); | 159 const rtc::PacketOptions& options); |
155 | 160 |
156 void OnCreatePermissionSuccess(); | 161 void OnCreatePermissionSuccess(); |
157 void OnCreatePermissionError(StunMessage* response, int code); | 162 void OnCreatePermissionError(StunMessage* response, int code); |
| 163 void OnCreatePermissionTimeout(); |
158 void OnChannelBindSuccess(); | 164 void OnChannelBindSuccess(); |
159 void OnChannelBindError(StunMessage* response, int code); | 165 void OnChannelBindError(StunMessage* response, int code); |
| 166 void OnChannelBindTimeout(); |
160 // Signal sent when TurnEntry is destroyed. | 167 // Signal sent when TurnEntry is destroyed. |
161 sigslot::signal1<TurnEntry*> SignalDestroyed; | 168 sigslot::signal1<TurnEntry*> SignalDestroyed; |
162 | 169 |
163 private: | 170 private: |
164 TurnPort* port_; | 171 TurnPort* port_; |
165 int channel_id_; | 172 int channel_id_; |
166 rtc::SocketAddress ext_addr_; | 173 rtc::SocketAddress ext_addr_; |
167 BindState state_; | 174 BindState state_; |
168 // A non-zero value indicates that this entry is scheduled to be destroyed. | 175 // 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 | 176 // 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) { | 464 if (Candidates()[index].type() == RELAY_PORT_TYPE) { |
458 ProxyConnection* conn = new ProxyConnection(this, index, address); | 465 ProxyConnection* conn = new ProxyConnection(this, index, address); |
459 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed); | 466 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed); |
460 AddConnection(conn); | 467 AddConnection(conn); |
461 return conn; | 468 return conn; |
462 } | 469 } |
463 } | 470 } |
464 return NULL; | 471 return NULL; |
465 } | 472 } |
466 | 473 |
| 474 bool TurnPort::DestroyConnection(const rtc::SocketAddress& address) { |
| 475 Connection* conn = GetConnection(address); |
| 476 if (conn != nullptr) { |
| 477 conn->Destroy(); |
| 478 return true; |
| 479 } |
| 480 return false; |
| 481 } |
| 482 |
467 int TurnPort::SetOption(rtc::Socket::Option opt, int value) { | 483 int TurnPort::SetOption(rtc::Socket::Option opt, int value) { |
468 if (!socket_) { | 484 if (!socket_) { |
469 // If socket is not created yet, these options will be applied during socket | 485 // If socket is not created yet, these options will be applied during socket |
470 // creation. | 486 // creation. |
471 socket_options_[opt] = value; | 487 socket_options_[opt] = value; |
472 return 0; | 488 return 0; |
473 } | 489 } |
474 return socket_->SetOption(opt, value); | 490 return socket_->SetOption(opt, value); |
475 } | 491 } |
476 | 492 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
691 "", // TCP canddiate type, empty for turn candidates. | 707 "", // TCP canddiate type, empty for turn candidates. |
692 RELAY_PORT_TYPE, | 708 RELAY_PORT_TYPE, |
693 GetRelayPreference(server_address_.proto, server_address_.secure), | 709 GetRelayPreference(server_address_.proto, server_address_.secure), |
694 server_priority_, true); | 710 server_priority_, true); |
695 } | 711 } |
696 | 712 |
697 void TurnPort::OnAllocateError() { | 713 void TurnPort::OnAllocateError() { |
698 // We will send SignalPortError asynchronously as this can be sent during | 714 // We will send SignalPortError asynchronously as this can be sent during |
699 // port initialization. This way it will not be blocking other port | 715 // port initialization. This way it will not be blocking other port |
700 // creation. | 716 // creation. |
701 thread()->Post(this, MSG_ERROR); | 717 thread()->Post(this, MSG_ALLOCATE_ERROR); |
| 718 } |
| 719 |
| 720 void TurnPort::Close() { |
| 721 // Stop the port from creating new connections. |
| 722 state_ = STATE_DISCONNECTED; |
| 723 // Delete all existing connections; stop sending data. |
| 724 for (auto kv : connections()) { |
| 725 kv.second->Destroy(); |
| 726 } |
702 } | 727 } |
703 | 728 |
704 void TurnPort::OnMessage(rtc::Message* message) { | 729 void TurnPort::OnMessage(rtc::Message* message) { |
705 if (message->message_id == MSG_ERROR) { | 730 switch (message->message_id) { |
706 SignalPortError(this); | 731 case MSG_ALLOCATE_ERROR: |
707 return; | 732 SignalPortError(this); |
708 } else if (message->message_id == MSG_ALLOCATE_MISMATCH) { | 733 break; |
709 OnAllocateMismatch(); | 734 case MSG_ALLOCATE_MISMATCH: |
710 return; | 735 OnAllocateMismatch(); |
711 } else if (message->message_id == MSG_TRY_ALTERNATE_SERVER) { | 736 break; |
712 if (server_address().proto == PROTO_UDP) { | 737 case MSG_TRY_ALTERNATE_SERVER: |
713 // Send another allocate request to alternate server, with the received | 738 if (server_address().proto == PROTO_UDP) { |
714 // realm and nonce values. | 739 // Send another allocate request to alternate server, with the received |
715 SendRequest(new TurnAllocateRequest(this), 0); | 740 // realm and nonce values. |
716 } else { | 741 SendRequest(new TurnAllocateRequest(this), 0); |
717 // Since it's TCP, we have to delete the connected socket and reconnect | 742 } else { |
718 // with the alternate server. PrepareAddress will send stun binding once | 743 // Since it's TCP, we have to delete the connected socket and reconnect |
719 // the new socket is connected. | 744 // with the alternate server. PrepareAddress will send stun binding once |
720 ASSERT(server_address().proto == PROTO_TCP); | 745 // the new socket is connected. |
721 ASSERT(!SharedSocket()); | 746 ASSERT(server_address().proto == PROTO_TCP); |
722 delete socket_; | 747 ASSERT(!SharedSocket()); |
723 socket_ = NULL; | 748 delete socket_; |
724 PrepareAddress(); | 749 socket_ = NULL; |
725 } | 750 PrepareAddress(); |
726 return; | 751 } |
| 752 break; |
| 753 default: |
| 754 Port::OnMessage(message); |
727 } | 755 } |
728 Port::OnMessage(message); | |
729 } | 756 } |
730 | 757 |
731 void TurnPort::OnAllocateRequestTimeout() { | 758 void TurnPort::OnAllocateRequestTimeout() { |
732 OnAllocateError(); | 759 OnAllocateError(); |
733 } | 760 } |
734 | 761 |
735 void TurnPort::HandleDataIndication(const char* data, size_t size, | 762 void TurnPort::HandleDataIndication(const char* data, size_t size, |
736 const rtc::PacketTime& packet_time) { | 763 const rtc::PacketTime& packet_time) { |
737 // Read in the message, and process according to RFC5766, Section 10.4. | 764 // Read in the message, and process according to RFC5766, Section 10.4. |
738 rtc::ByteBuffer buf(data, size); | 765 rtc::ByteBuffer buf(data, size); |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 thread(), | 988 thread(), |
962 rtc::Bind(&TurnPort::DestroyEntryIfNotCancelled, this, entry, timestamp), | 989 rtc::Bind(&TurnPort::DestroyEntryIfNotCancelled, this, entry, timestamp), |
963 TURN_PERMISSION_TIMEOUT); | 990 TURN_PERMISSION_TIMEOUT); |
964 } | 991 } |
965 | 992 |
966 void TurnPort::CancelEntryDestruction(TurnEntry* entry) { | 993 void TurnPort::CancelEntryDestruction(TurnEntry* entry) { |
967 ASSERT(entry->destruction_timestamp() != 0); | 994 ASSERT(entry->destruction_timestamp() != 0); |
968 entry->set_destruction_timestamp(0); | 995 entry->set_destruction_timestamp(0); |
969 } | 996 } |
970 | 997 |
| 998 bool TurnPort::SetEntryChannelId(const rtc::SocketAddress& address, |
| 999 int channel_id) { |
| 1000 TurnEntry* entry = FindEntry(address); |
| 1001 if (!entry) { |
| 1002 return false; |
| 1003 } |
| 1004 entry->set_channel_id(channel_id); |
| 1005 return true; |
| 1006 } |
| 1007 |
971 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port) | 1008 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port) |
972 : StunRequest(new TurnMessage()), | 1009 : StunRequest(new TurnMessage()), |
973 port_(port) { | 1010 port_(port) { |
974 } | 1011 } |
975 | 1012 |
976 void TurnAllocateRequest::Prepare(StunMessage* request) { | 1013 void TurnAllocateRequest::Prepare(StunMessage* request) { |
977 // Create the request as indicated in RFC 5766, Section 6.1. | 1014 // Create the request as indicated in RFC 5766, Section 6.1. |
978 request->SetType(TURN_ALLOCATE_REQUEST); | 1015 request->SetType(TURN_ALLOCATE_REQUEST); |
979 StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32( | 1016 StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32( |
980 STUN_ATTR_REQUESTED_TRANSPORT); | 1017 STUN_ATTR_REQUESTED_TRANSPORT); |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1174 const StunUInt32Attribute* lifetime_attr = | 1211 const StunUInt32Attribute* lifetime_attr = |
1175 response->GetUInt32(STUN_ATTR_TURN_LIFETIME); | 1212 response->GetUInt32(STUN_ATTR_TURN_LIFETIME); |
1176 if (!lifetime_attr) { | 1213 if (!lifetime_attr) { |
1177 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in " | 1214 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in " |
1178 << "refresh success response."; | 1215 << "refresh success response."; |
1179 return; | 1216 return; |
1180 } | 1217 } |
1181 | 1218 |
1182 // Schedule a refresh based on the returned lifetime value. | 1219 // Schedule a refresh based on the returned lifetime value. |
1183 port_->ScheduleRefresh(lifetime_attr->value()); | 1220 port_->ScheduleRefresh(lifetime_attr->value()); |
| 1221 port_->SignalTurnRefreshResult(port_, TURN_SUCCESS_RESULT_CODE); |
1184 } | 1222 } |
1185 | 1223 |
1186 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) { | 1224 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) { |
1187 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); | 1225 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); |
1188 | 1226 |
1189 LOG_J(LS_INFO, port_) << "Received TURN refresh error response" | |
1190 << ", id=" << rtc::hex_encode(id()) | |
1191 << ", code=" << error_code->code() | |
1192 << ", rtt=" << Elapsed(); | |
1193 | |
1194 if (error_code->code() == STUN_ERROR_STALE_NONCE) { | 1227 if (error_code->code() == STUN_ERROR_STALE_NONCE) { |
1195 if (port_->UpdateNonce(response)) { | 1228 if (port_->UpdateNonce(response)) { |
1196 // Send RefreshRequest immediately. | 1229 // Send RefreshRequest immediately. |
1197 port_->SendRequest(new TurnRefreshRequest(port_), 0); | 1230 port_->SendRequest(new TurnRefreshRequest(port_), 0); |
1198 } | 1231 } |
1199 } else { | 1232 } else { |
1200 LOG_J(LS_WARNING, port_) << "Received TURN refresh error response" | 1233 LOG_J(LS_WARNING, port_) << "Received TURN refresh error response" |
1201 << ", id=" << rtc::hex_encode(id()) | 1234 << ", id=" << rtc::hex_encode(id()) |
1202 << ", code=" << error_code->code() | 1235 << ", code=" << error_code->code() |
1203 << ", rtt=" << Elapsed(); | 1236 << ", rtt=" << Elapsed(); |
| 1237 port_->OnTurnRefreshError(); |
| 1238 port_->SignalTurnRefreshResult(port_, error_code->code()); |
1204 } | 1239 } |
1205 } | 1240 } |
1206 | 1241 |
1207 void TurnRefreshRequest::OnTimeout() { | 1242 void TurnRefreshRequest::OnTimeout() { |
1208 LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id()); | 1243 LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id()); |
| 1244 port_->OnTurnRefreshError(); |
1209 } | 1245 } |
1210 | 1246 |
1211 TurnCreatePermissionRequest::TurnCreatePermissionRequest( | 1247 TurnCreatePermissionRequest::TurnCreatePermissionRequest( |
1212 TurnPort* port, TurnEntry* entry, | 1248 TurnPort* port, TurnEntry* entry, |
1213 const rtc::SocketAddress& ext_addr) | 1249 const rtc::SocketAddress& ext_addr) |
1214 : StunRequest(new TurnMessage()), | 1250 : StunRequest(new TurnMessage()), |
1215 port_(port), | 1251 port_(port), |
1216 entry_(entry), | 1252 entry_(entry), |
1217 ext_addr_(ext_addr) { | 1253 ext_addr_(ext_addr) { |
1218 entry_->SignalDestroyed.connect( | 1254 entry_->SignalDestroyed.connect( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 << ", code=" << error_code->code() | 1287 << ", code=" << error_code->code() |
1252 << ", rtt=" << Elapsed(); | 1288 << ", rtt=" << Elapsed(); |
1253 if (entry_) { | 1289 if (entry_) { |
1254 entry_->OnCreatePermissionError(response, error_code->code()); | 1290 entry_->OnCreatePermissionError(response, error_code->code()); |
1255 } | 1291 } |
1256 } | 1292 } |
1257 | 1293 |
1258 void TurnCreatePermissionRequest::OnTimeout() { | 1294 void TurnCreatePermissionRequest::OnTimeout() { |
1259 LOG_J(LS_WARNING, port_) << "TURN create permission timeout " | 1295 LOG_J(LS_WARNING, port_) << "TURN create permission timeout " |
1260 << rtc::hex_encode(id()); | 1296 << rtc::hex_encode(id()); |
| 1297 if (entry_) { |
| 1298 entry_->OnCreatePermissionTimeout(); |
| 1299 } |
1261 } | 1300 } |
1262 | 1301 |
1263 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) { | 1302 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) { |
1264 ASSERT(entry_ == entry); | 1303 ASSERT(entry_ == entry); |
1265 entry_ = NULL; | 1304 entry_ = NULL; |
1266 } | 1305 } |
1267 | 1306 |
1268 TurnChannelBindRequest::TurnChannelBindRequest( | 1307 TurnChannelBindRequest::TurnChannelBindRequest( |
1269 TurnPort* port, TurnEntry* entry, | 1308 TurnPort* port, TurnEntry* entry, |
1270 int channel_id, const rtc::SocketAddress& ext_addr) | 1309 int channel_id, const rtc::SocketAddress& ext_addr) |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1318 << ", code=" << error_code->code() | 1357 << ", code=" << error_code->code() |
1319 << ", rtt=" << Elapsed(); | 1358 << ", rtt=" << Elapsed(); |
1320 if (entry_) { | 1359 if (entry_) { |
1321 entry_->OnChannelBindError(response, error_code->code()); | 1360 entry_->OnChannelBindError(response, error_code->code()); |
1322 } | 1361 } |
1323 } | 1362 } |
1324 | 1363 |
1325 void TurnChannelBindRequest::OnTimeout() { | 1364 void TurnChannelBindRequest::OnTimeout() { |
1326 LOG_J(LS_WARNING, port_) << "TURN channel bind timeout " | 1365 LOG_J(LS_WARNING, port_) << "TURN channel bind timeout " |
1327 << rtc::hex_encode(id()); | 1366 << rtc::hex_encode(id()); |
| 1367 if (entry_) { |
| 1368 entry_->OnChannelBindTimeout(); |
| 1369 } |
1328 } | 1370 } |
1329 | 1371 |
1330 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) { | 1372 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) { |
1331 ASSERT(entry_ == entry); | 1373 ASSERT(entry_ == entry); |
1332 entry_ = NULL; | 1374 entry_ = NULL; |
1333 } | 1375 } |
1334 | 1376 |
1335 TurnEntry::TurnEntry(TurnPort* port, int channel_id, | 1377 TurnEntry::TurnEntry(TurnPort* port, int channel_id, |
1336 const rtc::SocketAddress& ext_addr) | 1378 const rtc::SocketAddress& ext_addr) |
1337 : port_(port), | 1379 : port_(port), |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1378 buf.WriteUInt16(static_cast<uint16_t>(size)); | 1420 buf.WriteUInt16(static_cast<uint16_t>(size)); |
1379 buf.WriteBytes(reinterpret_cast<const char*>(data), size); | 1421 buf.WriteBytes(reinterpret_cast<const char*>(data), size); |
1380 } | 1422 } |
1381 return port_->Send(buf.Data(), buf.Length(), options); | 1423 return port_->Send(buf.Data(), buf.Length(), options); |
1382 } | 1424 } |
1383 | 1425 |
1384 void TurnEntry::OnCreatePermissionSuccess() { | 1426 void TurnEntry::OnCreatePermissionSuccess() { |
1385 LOG_J(LS_INFO, port_) << "Create permission for " | 1427 LOG_J(LS_INFO, port_) << "Create permission for " |
1386 << ext_addr_.ToSensitiveString() | 1428 << ext_addr_.ToSensitiveString() |
1387 << " succeeded"; | 1429 << " succeeded"; |
1388 // For success result code will be 0. | 1430 port_->SignalCreatePermissionResult(port_, ext_addr_, |
1389 port_->SignalCreatePermissionResult(port_, ext_addr_, 0); | 1431 TURN_SUCCESS_RESULT_CODE); |
1390 | 1432 |
1391 // If |state_| is STATE_BOUND, the permission will be refreshed | 1433 // If |state_| is STATE_BOUND, the permission will be refreshed |
1392 // by ChannelBindRequest. | 1434 // by ChannelBindRequest. |
1393 if (state_ != STATE_BOUND) { | 1435 if (state_ != STATE_BOUND) { |
1394 // Refresh the permission request about 1 minute before the permission | 1436 // Refresh the permission request about 1 minute before the permission |
1395 // times out. | 1437 // times out. |
1396 int delay = TURN_PERMISSION_TIMEOUT - 60000; | 1438 int delay = TURN_PERMISSION_TIMEOUT - 60000; |
1397 SendCreatePermissionRequest(delay); | 1439 SendCreatePermissionRequest(delay); |
1398 LOG_J(LS_INFO, port_) << "Scheduled create-permission-request in " | 1440 LOG_J(LS_INFO, port_) << "Scheduled create-permission-request in " |
1399 << delay << "ms."; | 1441 << delay << "ms."; |
1400 } | 1442 } |
1401 } | 1443 } |
1402 | 1444 |
1403 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) { | 1445 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) { |
1404 if (code == STUN_ERROR_STALE_NONCE) { | 1446 if (code == STUN_ERROR_STALE_NONCE) { |
1405 if (port_->UpdateNonce(response)) { | 1447 if (port_->UpdateNonce(response)) { |
1406 SendCreatePermissionRequest(0); | 1448 SendCreatePermissionRequest(0); |
1407 } | 1449 } |
1408 } else { | 1450 } else { |
| 1451 port_->DestroyConnection(ext_addr_); |
1409 // Send signal with error code. | 1452 // Send signal with error code. |
1410 port_->SignalCreatePermissionResult(port_, ext_addr_, code); | 1453 port_->SignalCreatePermissionResult(port_, ext_addr_, code); |
1411 Connection* c = port_->GetConnection(ext_addr_); | 1454 Connection* c = port_->GetConnection(ext_addr_); |
1412 if (c) { | 1455 if (c) { |
1413 LOG_J(LS_ERROR, c) << "Received TURN CreatePermission error response, " | 1456 LOG_J(LS_ERROR, c) << "Received TURN CreatePermission error response, " |
1414 << "code=" << code << "; killing connection."; | 1457 << "code=" << code << "; killing connection."; |
1415 c->FailAndDestroy(); | 1458 c->FailAndDestroy(); |
1416 } | 1459 } |
1417 } | 1460 } |
1418 } | 1461 } |
1419 | 1462 |
| 1463 void TurnEntry::OnCreatePermissionTimeout() { |
| 1464 port_->DestroyConnection(ext_addr_); |
| 1465 } |
| 1466 |
1420 void TurnEntry::OnChannelBindSuccess() { | 1467 void TurnEntry::OnChannelBindSuccess() { |
1421 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString() | 1468 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString() |
1422 << " succeeded"; | 1469 << " succeeded"; |
1423 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND); | 1470 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND); |
1424 state_ = STATE_BOUND; | 1471 state_ = STATE_BOUND; |
1425 } | 1472 } |
1426 | 1473 |
1427 void TurnEntry::OnChannelBindError(StunMessage* response, int code) { | 1474 void TurnEntry::OnChannelBindError(StunMessage* response, int code) { |
1428 // TODO(mallinath) - Implement handling of error response for channel | 1475 // If the channel bind fails due to errors other than STATE_NONCE, |
1429 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 | 1476 // we just destroy the connection and rely on ICE restart to re-establish |
| 1477 // the connection. |
1430 if (code == STUN_ERROR_STALE_NONCE) { | 1478 if (code == STUN_ERROR_STALE_NONCE) { |
1431 if (port_->UpdateNonce(response)) { | 1479 if (port_->UpdateNonce(response)) { |
1432 // Send channel bind request with fresh nonce. | 1480 // Send channel bind request with fresh nonce. |
1433 SendChannelBindRequest(0); | 1481 SendChannelBindRequest(0); |
1434 } | 1482 } |
| 1483 } else { |
| 1484 state_ = STATE_UNBOUND; |
| 1485 port_->DestroyConnection(ext_addr_); |
1435 } | 1486 } |
1436 } | 1487 } |
1437 | 1488 void TurnEntry::OnChannelBindTimeout() { |
| 1489 state_ = STATE_UNBOUND; |
| 1490 port_->DestroyConnection(ext_addr_); |
| 1491 } |
1438 } // namespace cricket | 1492 } // namespace cricket |
OLD | NEW |