Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: webrtc/p2p/base/p2ptransportchannel.cc

Issue 1207563002: Add flakiness check if there is no received packets in a certain period. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Address more comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 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
11 #include "webrtc/p2p/base/p2ptransportchannel.h" 11 #include "webrtc/p2p/base/p2ptransportchannel.h"
12 12
13 #include <set> 13 #include <set>
14 #include "webrtc/p2p/base/common.h" 14 #include "webrtc/p2p/base/common.h"
15 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE. 15 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE.
16 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE. 16 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE.
17 #include "webrtc/base/common.h" 17 #include "webrtc/base/common.h"
18 #include "webrtc/base/crc32.h" 18 #include "webrtc/base/crc32.h"
19 #include "webrtc/base/logging.h" 19 #include "webrtc/base/logging.h"
20 #include "webrtc/base/stringencode.h" 20 #include "webrtc/base/stringencode.h"
21 21
22 namespace { 22 namespace {
23 23
24 // messages for queuing up work for ourselves 24 // messages for queuing up work for ourselves
25 enum { 25 enum {
26 MSG_SORT = 1, 26 MSG_SORT = 1,
27 MSG_PING, 27 MSG_PING,
28 MSG_CHECK_RECEIVING
28 }; 29 };
29 30
30 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) 31 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers)
31 // for pinging. When the socket is writable, we will use only 1 Kbps because 32 // for pinging. When the socket is writable, we will use only 1 Kbps because
32 // we don't want to degrade the quality on a modem. These numbers should work 33 // we don't want to degrade the quality on a modem. These numbers should work
33 // well on a 28.8K modem, which is the slowest connection on which the voice 34 // well on a 28.8K modem, which is the slowest connection on which the voice
34 // quality is reasonable at all. 35 // quality is reasonable at all.
35 static const uint32 PING_PACKET_SIZE = 60 * 8; 36 static const uint32 PING_PACKET_SIZE = 60 * 8;
36 static const uint32 WRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 1000; // 480ms 37 static const uint32 WRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 1000; // 480ms
37 static const uint32 UNWRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 10000; // 50ms 38 static const uint32 UNWRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 10000; // 50ms
38 39
39 // If there is a current writable connection, then we will also try hard to 40 // If there is a current writable connection, then we will also try hard to
40 // make sure it is pinged at this rate. 41 // make sure it is pinged at this rate.
41 static const uint32 MAX_CURRENT_WRITABLE_DELAY = 900; // 2*WRITABLE_DELAY - bit 42 static const uint32 MAX_CURRENT_WRITABLE_DELAY = 900; // 2*WRITABLE_DELAY - bit
42 43
44 static const int MIN_CHECK_RECEIVING_DELAY = 50; // ms
45
43 // The minimum improvement in RTT that justifies a switch. 46 // The minimum improvement in RTT that justifies a switch.
44 static const double kMinImprovement = 10; 47 static const double kMinImprovement = 10;
45 48
46 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, 49 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port,
47 cricket::PortInterface* origin_port) { 50 cricket::PortInterface* origin_port) {
48 if (!origin_port) 51 if (!origin_port)
49 return cricket::PortInterface::ORIGIN_MESSAGE; 52 return cricket::PortInterface::ORIGIN_MESSAGE;
50 else if (port == origin_port) 53 else if (port == origin_port)
51 return cricket::PortInterface::ORIGIN_THIS_PORT; 54 return cricket::PortInterface::ORIGIN_THIS_PORT;
52 else 55 else
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 waiting_for_signaling_(false), 189 waiting_for_signaling_(false),
187 error_(0), 190 error_(0),
188 best_connection_(NULL), 191 best_connection_(NULL),
189 pending_best_connection_(NULL), 192 pending_best_connection_(NULL),
190 sort_dirty_(false), 193 sort_dirty_(false),
191 was_writable_(false), 194 was_writable_(false),
192 protocol_type_(ICEPROTO_HYBRID), 195 protocol_type_(ICEPROTO_HYBRID),
193 remote_ice_mode_(ICEMODE_FULL), 196 remote_ice_mode_(ICEMODE_FULL),
194 ice_role_(ICEROLE_UNKNOWN), 197 ice_role_(ICEROLE_UNKNOWN),
195 tiebreaker_(0), 198 tiebreaker_(0),
196 remote_candidate_generation_(0) { 199 remote_candidate_generation_(0),
200 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5),
201 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) {
197 } 202 }
198 203
199 P2PTransportChannel::~P2PTransportChannel() { 204 P2PTransportChannel::~P2PTransportChannel() {
200 ASSERT(worker_thread_ == rtc::Thread::Current()); 205 ASSERT(worker_thread_ == rtc::Thread::Current());
201 206
202 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) 207 for (uint32 i = 0; i < allocator_sessions_.size(); ++i)
203 delete allocator_sessions_[i]; 208 delete allocator_sessions_[i];
204 } 209 }
205 210
206 // Add the allocator session to our list so that we know which sessions 211 // Add the allocator session to our list so that we know which sessions
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 // Therefore we need to keep track of the remote ice restart so 352 // Therefore we need to keep track of the remote ice restart so
348 // newer connections are prioritized over the older. 353 // newer connections are prioritized over the older.
349 ++remote_candidate_generation_; 354 ++remote_candidate_generation_;
350 } 355 }
351 } 356 }
352 357
353 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { 358 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
354 remote_ice_mode_ = mode; 359 remote_ice_mode_ = mode;
355 } 360 }
356 361
362 void P2PTransportChannel::set_receiving_timeout(int receiving_timeout_ms) {
363 receiving_timeout_ = receiving_timeout_ms;
364 check_receiving_delay_ =
365 std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10);
366 }
367
357 // Go into the state of processing candidates, and running in general 368 // Go into the state of processing candidates, and running in general
358 void P2PTransportChannel::Connect() { 369 void P2PTransportChannel::Connect() {
359 ASSERT(worker_thread_ == rtc::Thread::Current()); 370 ASSERT(worker_thread_ == rtc::Thread::Current());
360 if (ice_ufrag_.empty() || ice_pwd_.empty()) { 371 if (ice_ufrag_.empty() || ice_pwd_.empty()) {
361 ASSERT(false); 372 ASSERT(false);
362 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " 373 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the "
363 << "ice_pwd_ are not set."; 374 << "ice_pwd_ are not set.";
364 return; 375 return;
365 } 376 }
366 377
367 // Kick off an allocator session 378 // Kick off an allocator session
368 Allocate(); 379 Allocate();
369 380
370 // Start pinging as the ports come in. 381 // Start pinging as the ports come in.
371 thread()->Post(this, MSG_PING); 382 thread()->Post(this, MSG_PING);
383
384 thread()->PostDelayed(
385 check_receiving_delay_, this, MSG_CHECK_RECEIVING);
372 } 386 }
373 387
374 // A new port is available, attempt to make connections for it 388 // A new port is available, attempt to make connections for it
375 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session, 389 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session,
376 PortInterface* port) { 390 PortInterface* port) {
377 ASSERT(worker_thread_ == rtc::Thread::Current()); 391 ASSERT(worker_thread_ == rtc::Thread::Current());
378 392
379 // Set in-effect options on the new port 393 // Set in-effect options on the new port
380 for (OptionMap::const_iterator it = options_.begin(); 394 for (OptionMap::const_iterator it = options_.begin();
381 it != options_.end(); 395 it != options_.end();
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 Connection* old_best_connection = best_connection_; 1074 Connection* old_best_connection = best_connection_;
1061 best_connection_ = conn; 1075 best_connection_ = conn;
1062 if (best_connection_) { 1076 if (best_connection_) {
1063 if (old_best_connection) { 1077 if (old_best_connection) {
1064 LOG_J(LS_INFO, this) << "Previous best connection: " 1078 LOG_J(LS_INFO, this) << "Previous best connection: "
1065 << old_best_connection->ToString(); 1079 << old_best_connection->ToString();
1066 } 1080 }
1067 LOG_J(LS_INFO, this) << "New best connection: " 1081 LOG_J(LS_INFO, this) << "New best connection: "
1068 << best_connection_->ToString(); 1082 << best_connection_->ToString();
1069 SignalRouteChange(this, best_connection_->remote_candidate()); 1083 SignalRouteChange(this, best_connection_->remote_candidate());
1084 // When it just switched to a best connection, set receiving to true.
1085 set_receiving(true);
1070 } else { 1086 } else {
1071 LOG_J(LS_INFO, this) << "No best connection"; 1087 LOG_J(LS_INFO, this) << "No best connection";
1072 } 1088 }
1073 } 1089 }
1074 1090
1075 void P2PTransportChannel::UpdateChannelState() { 1091 void P2PTransportChannel::UpdateChannelState() {
1076 // The Handle* functions already set the writable state. We'll just double- 1092 // The Handle* functions already set the writable state. We'll just double-
1077 // check it here. 1093 // check it here.
1078 bool writable = ((best_connection_ != NULL) && 1094 bool writable = ((best_connection_ != NULL) &&
1079 (best_connection_->write_state() == 1095 (best_connection_->write_state() ==
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 1157
1142 // Handle any queued up requests 1158 // Handle any queued up requests
1143 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { 1159 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) {
1144 switch (pmsg->message_id) { 1160 switch (pmsg->message_id) {
1145 case MSG_SORT: 1161 case MSG_SORT:
1146 OnSort(); 1162 OnSort();
1147 break; 1163 break;
1148 case MSG_PING: 1164 case MSG_PING:
1149 OnPing(); 1165 OnPing();
1150 break; 1166 break;
1167 case MSG_CHECK_RECEIVING:
1168 OnCheckReceiving();
1169 break;
1151 default: 1170 default:
1152 ASSERT(false); 1171 ASSERT(false);
1153 break; 1172 break;
1154 } 1173 }
1155 } 1174 }
1156 1175
1157 // Handle queued up sort request 1176 // Handle queued up sort request
1158 void P2PTransportChannel::OnSort() { 1177 void P2PTransportChannel::OnSort() {
1159 // Resort the connections based on the new statistics. 1178 // Resort the connections based on the new statistics.
1160 SortConnections(); 1179 SortConnections();
1161 } 1180 }
1162 1181
1163 // Handle queued up ping request 1182 // Handle queued up ping request
1164 void P2PTransportChannel::OnPing() { 1183 void P2PTransportChannel::OnPing() {
1165 // Make sure the states of the connections are up-to-date (since this affects 1184 // Make sure the states of the connections are up-to-date (since this affects
1166 // which ones are pingable). 1185 // which ones are pingable).
1167 UpdateConnectionStates(); 1186 UpdateConnectionStates();
1168 1187
1169 // Find the oldest pingable connection and have it do a ping. 1188 // Find the oldest pingable connection and have it do a ping.
1170 Connection* conn = FindNextPingableConnection(); 1189 Connection* conn = FindNextPingableConnection();
1171 if (conn) 1190 if (conn)
1172 PingConnection(conn); 1191 PingConnection(conn);
1173 1192
1174 // Post ourselves a message to perform the next ping. 1193 // Post ourselves a message to perform the next ping.
1175 uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY; 1194 uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY;
1176 thread()->PostDelayed(delay, this, MSG_PING); 1195 thread()->PostDelayed(delay, this, MSG_PING);
1177 } 1196 }
1178 1197
1198 void P2PTransportChannel::OnCheckReceiving() {
1199 // Check receiving only if the best connection has received data packets
1200 // because we want to detect not receiving any packets only after the media
1201 // have started flowing.
1202 if (best_connection_ && best_connection_->recv_total_bytes() > 0) {
1203 bool receiving = rtc::Time() <=
1204 best_connection_->last_received() + receiving_timeout_;
1205 set_receiving(receiving);
1206 }
1207
1208 thread()->PostDelayed(check_receiving_delay_, this, MSG_CHECK_RECEIVING);
1209 }
1210
1179 // Is the connection in a state for us to even consider pinging the other side? 1211 // Is the connection in a state for us to even consider pinging the other side?
1180 // We consider a connection pingable even if it's not connected because that's 1212 // We consider a connection pingable even if it's not connected because that's
1181 // how a TCP connection is kicked into reconnecting on the active side. 1213 // how a TCP connection is kicked into reconnecting on the active side.
1182 bool P2PTransportChannel::IsPingable(Connection* conn) { 1214 bool P2PTransportChannel::IsPingable(Connection* conn) {
1183 const Candidate& remote = conn->remote_candidate(); 1215 const Candidate& remote = conn->remote_candidate();
1184 // We should never get this far with an empty remote ufrag. 1216 // We should never get this far with an empty remote ufrag.
1185 ASSERT(!remote.username().empty()); 1217 ASSERT(!remote.username().empty());
1186 if (remote.username().empty() || remote.password().empty()) { 1218 if (remote.username().empty() || remote.password().empty()) {
1187 // If we don't have an ICE ufrag and pwd, there's no way we can ping. 1219 // If we don't have an ICE ufrag and pwd, there's no way we can ping.
1188 return false; 1220 return false;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1371 SignalReadPacket(this, data, len, packet_time, 0); 1403 SignalReadPacket(this, data, len, packet_time, 0);
1372 } 1404 }
1373 1405
1374 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1406 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
1375 if (connection == best_connection_ && writable()) { 1407 if (connection == best_connection_ && writable()) {
1376 SignalReadyToSend(this); 1408 SignalReadyToSend(this);
1377 } 1409 }
1378 } 1410 }
1379 1411
1380 } // namespace cricket 1412 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698