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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 const rtc::SocketAddress& address() const { return ext_addr_; } | 140 const rtc::SocketAddress& address() const { return ext_addr_; } |
141 BindState state() const { return state_; } | 141 BindState state() const { return state_; } |
142 | 142 |
| 143 uint32_t destruction_timestamp() { return destruction_timestamp_; } |
| 144 void set_destruction_timestamp(uint32_t destruction_timestamp) { |
| 145 destruction_timestamp_ = destruction_timestamp; |
| 146 } |
| 147 |
143 // Helper methods to send permission and channel bind requests. | 148 // Helper methods to send permission and channel bind requests. |
144 void SendCreatePermissionRequest(int delay); | 149 void SendCreatePermissionRequest(int delay); |
145 void SendChannelBindRequest(int delay); | 150 void SendChannelBindRequest(int delay); |
146 // Sends a packet to the given destination address. | 151 // Sends a packet to the given destination address. |
147 // This will wrap the packet in STUN if necessary. | 152 // This will wrap the packet in STUN if necessary. |
148 int Send(const void* data, size_t size, bool payload, | 153 int Send(const void* data, size_t size, bool payload, |
149 const rtc::PacketOptions& options); | 154 const rtc::PacketOptions& options); |
150 | 155 |
151 void OnCreatePermissionSuccess(); | 156 void OnCreatePermissionSuccess(); |
152 void OnCreatePermissionError(StunMessage* response, int code); | 157 void OnCreatePermissionError(StunMessage* response, int code); |
153 void OnChannelBindSuccess(); | 158 void OnChannelBindSuccess(); |
154 void OnChannelBindError(StunMessage* response, int code); | 159 void OnChannelBindError(StunMessage* response, int code); |
155 // Signal sent when TurnEntry is destroyed. | 160 // Signal sent when TurnEntry is destroyed. |
156 sigslot::signal1<TurnEntry*> SignalDestroyed; | 161 sigslot::signal1<TurnEntry*> SignalDestroyed; |
157 | 162 |
158 private: | 163 private: |
159 TurnPort* port_; | 164 TurnPort* port_; |
160 int channel_id_; | 165 int channel_id_; |
161 rtc::SocketAddress ext_addr_; | 166 rtc::SocketAddress ext_addr_; |
162 BindState state_; | 167 BindState state_; |
| 168 // 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 |
| 170 // event actually fires, the TurnEntry will be destroyed only if the |
| 171 // timestamp here matches the one in the firing event. |
| 172 uint32_t destruction_timestamp_ = 0; |
163 }; | 173 }; |
164 | 174 |
165 TurnPort::TurnPort(rtc::Thread* thread, | 175 TurnPort::TurnPort(rtc::Thread* thread, |
166 rtc::PacketSocketFactory* factory, | 176 rtc::PacketSocketFactory* factory, |
167 rtc::Network* network, | 177 rtc::Network* network, |
168 rtc::AsyncPacketSocket* socket, | 178 rtc::AsyncPacketSocket* socket, |
169 const std::string& username, | 179 const std::string& username, |
170 const std::string& password, | 180 const std::string& password, |
171 const ProtocolAddress& server_address, | 181 const ProtocolAddress& server_address, |
172 const RelayCredentials& credentials, | 182 const RelayCredentials& credentials, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 242 |
233 // release the allocation by sending a refresh with | 243 // release the allocation by sending a refresh with |
234 // lifetime 0. | 244 // lifetime 0. |
235 if (ready()) { | 245 if (ready()) { |
236 TurnRefreshRequest bye(this); | 246 TurnRefreshRequest bye(this); |
237 bye.set_lifetime(0); | 247 bye.set_lifetime(0); |
238 SendRequest(&bye, 0); | 248 SendRequest(&bye, 0); |
239 } | 249 } |
240 | 250 |
241 while (!entries_.empty()) { | 251 while (!entries_.empty()) { |
242 DestroyEntry(entries_.front()->address()); | 252 DestroyEntry(entries_.front()); |
243 } | 253 } |
244 if (resolver_) { | 254 if (resolver_) { |
245 resolver_->Destroy(false); | 255 resolver_->Destroy(false); |
246 } | 256 } |
247 if (!SharedSocket()) { | 257 if (!SharedSocket()) { |
248 delete socket_; | 258 delete socket_; |
249 } | 259 } |
250 } | 260 } |
251 | 261 |
252 rtc::SocketAddress TurnPort::GetLocalAddress() const { | 262 rtc::SocketAddress TurnPort::GetLocalAddress() const { |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 | 441 |
432 if (!IsCompatibleAddress(address.address())) { | 442 if (!IsCompatibleAddress(address.address())) { |
433 return NULL; | 443 return NULL; |
434 } | 444 } |
435 | 445 |
436 if (state_ == STATE_DISCONNECTED) { | 446 if (state_ == STATE_DISCONNECTED) { |
437 return NULL; | 447 return NULL; |
438 } | 448 } |
439 | 449 |
440 // Create an entry, if needed, so we can get our permissions set up correctly. | 450 // Create an entry, if needed, so we can get our permissions set up correctly. |
441 CreateEntry(address.address()); | 451 CreateOrRefreshEntry(address.address()); |
442 | 452 |
443 // A TURN port will have two candiates, STUN and TURN. STUN may not | 453 // A TURN port will have two candiates, STUN and TURN. STUN may not |
444 // present in all cases. If present stun candidate will be added first | 454 // present in all cases. If present stun candidate will be added first |
445 // and TURN candidate later. | 455 // and TURN candidate later. |
446 for (size_t index = 0; index < Candidates().size(); ++index) { | 456 for (size_t index = 0; index < Candidates().size(); ++index) { |
447 if (Candidates()[index].type() == RELAY_PORT_TYPE) { | 457 if (Candidates()[index].type() == RELAY_PORT_TYPE) { |
448 ProxyConnection* conn = new ProxyConnection(this, index, address); | 458 ProxyConnection* conn = new ProxyConnection(this, index, address); |
449 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed); | 459 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed); |
450 AddConnection(conn); | 460 AddConnection(conn); |
451 return conn; | 461 return conn; |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 // with the alternate server. PrepareAddress will send stun binding once | 716 // with the alternate server. PrepareAddress will send stun binding once |
707 // the new socket is connected. | 717 // the new socket is connected. |
708 ASSERT(server_address().proto == PROTO_TCP); | 718 ASSERT(server_address().proto == PROTO_TCP); |
709 ASSERT(!SharedSocket()); | 719 ASSERT(!SharedSocket()); |
710 delete socket_; | 720 delete socket_; |
711 socket_ = NULL; | 721 socket_ = NULL; |
712 PrepareAddress(); | 722 PrepareAddress(); |
713 } | 723 } |
714 return; | 724 return; |
715 } | 725 } |
716 | |
717 Port::OnMessage(message); | 726 Port::OnMessage(message); |
718 } | 727 } |
719 | 728 |
720 void TurnPort::OnAllocateRequestTimeout() { | 729 void TurnPort::OnAllocateRequestTimeout() { |
721 OnAllocateError(); | 730 OnAllocateError(); |
722 } | 731 } |
723 | 732 |
724 void TurnPort::HandleDataIndication(const char* data, size_t size, | 733 void TurnPort::HandleDataIndication(const char* data, size_t size, |
725 const rtc::PacketTime& packet_time) { | 734 const rtc::PacketTime& packet_time) { |
726 // Read in the message, and process according to RFC5766, Section 10.4. | 735 // Read in the message, and process according to RFC5766, Section 10.4. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 | 900 |
892 static bool MatchesChannelId(TurnEntry* e, int id) { | 901 static bool MatchesChannelId(TurnEntry* e, int id) { |
893 return e->channel_id() == id; | 902 return e->channel_id() == id; |
894 } | 903 } |
895 TurnEntry* TurnPort::FindEntry(int channel_id) const { | 904 TurnEntry* TurnPort::FindEntry(int channel_id) const { |
896 EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(), | 905 EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(), |
897 std::bind2nd(std::ptr_fun(MatchesChannelId), channel_id)); | 906 std::bind2nd(std::ptr_fun(MatchesChannelId), channel_id)); |
898 return (it != entries_.end()) ? *it : NULL; | 907 return (it != entries_.end()) ? *it : NULL; |
899 } | 908 } |
900 | 909 |
901 TurnEntry* TurnPort::CreateEntry(const rtc::SocketAddress& addr) { | 910 void TurnPort::CreateOrRefreshEntry(const rtc::SocketAddress& addr) { |
902 ASSERT(FindEntry(addr) == NULL); | 911 TurnEntry* entry = FindEntry(addr); |
903 TurnEntry* entry = new TurnEntry(this, next_channel_number_++, addr); | 912 if (entry == nullptr) { |
904 entries_.push_back(entry); | 913 entry = new TurnEntry(this, next_channel_number_++, addr); |
905 return entry; | 914 entries_.push_back(entry); |
| 915 } else { |
| 916 // The channel binding request for the entry will be refreshed automatically |
| 917 // until the entry is destroyed. |
| 918 CancelEntryDestruction(entry); |
| 919 } |
906 } | 920 } |
907 | 921 |
908 void TurnPort::DestroyEntry(const rtc::SocketAddress& addr) { | 922 void TurnPort::DestroyEntry(TurnEntry* entry) { |
909 TurnEntry* entry = FindEntry(addr); | |
910 ASSERT(entry != NULL); | 923 ASSERT(entry != NULL); |
911 entry->SignalDestroyed(entry); | 924 entry->SignalDestroyed(entry); |
912 entries_.remove(entry); | 925 entries_.remove(entry); |
913 delete entry; | 926 delete entry; |
914 } | 927 } |
915 | 928 |
| 929 void TurnPort::DestroyEntryIfNotCancelled(TurnEntry* entry, |
| 930 uint32_t timestamp) { |
| 931 bool cancelled = timestamp != entry->destruction_timestamp(); |
| 932 if (!cancelled) { |
| 933 DestroyEntry(entry); |
| 934 } |
| 935 } |
| 936 |
916 void TurnPort::OnConnectionDestroyed(Connection* conn) { | 937 void TurnPort::OnConnectionDestroyed(Connection* conn) { |
917 // Destroying TurnEntry for the connection, which is already destroyed. | 938 // Schedule an event to destroy TurnEntry for the connection, which is |
918 DestroyEntry(conn->remote_candidate().address()); | 939 // already destroyed. |
| 940 const rtc::SocketAddress& remote_address = conn->remote_candidate().address(); |
| 941 TurnEntry* entry = FindEntry(remote_address); |
| 942 ASSERT(entry != NULL); |
| 943 ScheduleEntryDestruction(entry); |
| 944 } |
| 945 |
| 946 void TurnPort::ScheduleEntryDestruction(TurnEntry* entry) { |
| 947 ASSERT(entry->destruction_timestamp() == 0); |
| 948 uint32_t timestamp = rtc::Time(); |
| 949 entry->set_destruction_timestamp(timestamp); |
| 950 invoker_.AsyncInvokeDelayed<void>( |
| 951 thread(), |
| 952 rtc::Bind(&TurnPort::DestroyEntryIfNotCancelled, this, entry, timestamp), |
| 953 TURN_PERMISSION_TIMEOUT); |
| 954 } |
| 955 |
| 956 void TurnPort::CancelEntryDestruction(TurnEntry* entry) { |
| 957 ASSERT(entry->destruction_timestamp() != 0); |
| 958 entry->set_destruction_timestamp(0); |
919 } | 959 } |
920 | 960 |
921 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port) | 961 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port) |
922 : StunRequest(new TurnMessage()), | 962 : StunRequest(new TurnMessage()), |
923 port_(port) { | 963 port_(port) { |
924 } | 964 } |
925 | 965 |
926 void TurnAllocateRequest::Prepare(StunMessage* request) { | 966 void TurnAllocateRequest::Prepare(StunMessage* request) { |
927 // Create the request as indicated in RFC 5766, Section 6.1. | 967 // Create the request as indicated in RFC 5766, Section 6.1. |
928 request->SetType(TURN_ALLOCATE_REQUEST); | 968 request->SetType(TURN_ALLOCATE_REQUEST); |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 | 1413 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 |
1374 if (code == STUN_ERROR_STALE_NONCE) { | 1414 if (code == STUN_ERROR_STALE_NONCE) { |
1375 if (port_->UpdateNonce(response)) { | 1415 if (port_->UpdateNonce(response)) { |
1376 // Send channel bind request with fresh nonce. | 1416 // Send channel bind request with fresh nonce. |
1377 SendChannelBindRequest(0); | 1417 SendChannelBindRequest(0); |
1378 } | 1418 } |
1379 } | 1419 } |
1380 } | 1420 } |
1381 | 1421 |
1382 } // namespace cricket | 1422 } // namespace cricket |
OLD | NEW |