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