Index: net/quic/quic_connection.cc |
diff --git a/net/quic/quic_connection.cc b/net/quic/quic_connection.cc |
index e29bea919c4daf89474f16761628c9958dcb10eb..74cc16b51a8cee316403c1b1a44ba78e408bb63c 100644 |
--- a/net/quic/quic_connection.cc |
+++ b/net/quic/quic_connection.cc |
@@ -75,6 +75,8 @@ class AckAlarm : public QuicAlarm::Delegate { |
private: |
QuicConnection* connection_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AckAlarm); |
}; |
// This alarm will be scheduled any time a data-bearing packet is sent out. |
@@ -93,6 +95,8 @@ class RetransmissionAlarm : public QuicAlarm::Delegate { |
private: |
QuicConnection* connection_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(RetransmissionAlarm); |
}; |
// An alarm that is scheduled when the sent scheduler requires a |
@@ -111,6 +115,8 @@ class SendAlarm : public QuicAlarm::Delegate { |
private: |
QuicConnection* connection_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SendAlarm); |
}; |
class TimeoutAlarm : public QuicAlarm::Delegate { |
@@ -127,6 +133,23 @@ class TimeoutAlarm : public QuicAlarm::Delegate { |
private: |
QuicConnection* connection_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(TimeoutAlarm); |
+}; |
+ |
+class PingAlarm : public QuicAlarm::Delegate { |
+ public: |
+ explicit PingAlarm(QuicConnection* connection) |
+ : connection_(connection) { |
+ } |
+ |
+ virtual QuicTime OnAlarm() OVERRIDE { |
+ connection_->SendPing(); |
+ return QuicTime::Zero(); |
+ } |
+ |
+ private: |
+ QuicConnection* connection_; |
}; |
QuicConnection::PacketType GetPacketType( |
@@ -191,6 +214,7 @@ QuicConnection::QuicConnection(QuicConnectionId connection_id, |
send_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
resume_writes_alarm_(helper->CreateAlarm(new SendAlarm(this))), |
timeout_alarm_(helper->CreateAlarm(new TimeoutAlarm(this))), |
+ ping_alarm_(helper->CreateAlarm(new PingAlarm(this))), |
debug_visitor_(NULL), |
packet_creator_(connection_id_, &framer_, random_generator_, is_server), |
packet_generator_(this, NULL, &packet_creator_), |
@@ -1060,6 +1084,7 @@ void QuicConnection::ProcessUdpPacket(const IPEndPoint& self_address, |
MaybeProcessUndecryptablePackets(); |
MaybeProcessRevivedPacket(); |
MaybeSendInResponseToPacket(); |
+ SetPingAlarm(); |
} |
void QuicConnection::OnCanWrite() { |
@@ -1409,6 +1434,7 @@ bool QuicConnection::OnPacketSent(WriteResult result) { |
if (transmission_type == NOT_RETRANSMISSION) { |
time_of_last_sent_new_packet_ = now; |
} |
+ SetPingAlarm(); |
DVLOG(1) << ENDPOINT << "time of last sent packet: " |
<< now.ToDebuggingValue(); |
@@ -1484,6 +1510,27 @@ void QuicConnection::UpdateStopWaiting(QuicStopWaitingFrame* stop_waiting) { |
stop_waiting->least_unacked - 1); |
} |
+void QuicConnection::SendPing() { |
+ if (retransmission_alarm_->IsSet()) { |
+ return; |
+ } |
+ if (version() <= QUIC_VERSION_17) { |
+ // TODO(rch): remove this when we remove version 17. |
+ // This is a horrible hideous hack which we should not support. |
+ IOVector data; |
+ char c_data[] = "C"; |
+ data.Append(c_data, 1); |
+ QuicConsumedData consumed_data = |
+ packet_generator_.ConsumeData(kCryptoStreamId, data, 0, false, NULL); |
+ if (consumed_data.bytes_consumed == 0) { |
+ DLOG(ERROR) << "Unable to send ping!?"; |
+ } |
+ } else { |
+ // TODO(rch): enable this when we merge version 18. |
+ // packet_generator_.AddControlFrame(QuicFrame(new QuicPingFrame)); |
+ } |
+} |
+ |
void QuicConnection::SendAck() { |
ack_alarm_->Cancel(); |
stop_waiting_count_ = 0; |
@@ -1808,6 +1855,20 @@ bool QuicConnection::CheckForTimeout() { |
return false; |
} |
+void QuicConnection::SetPingAlarm() { |
+ if (is_server_) { |
+ // Only clients send pings. |
+ return; |
+ } |
+ ping_alarm_->Cancel(); |
+ if (!visitor_->HasOpenDataStreams()) { |
+ // Don't send a ping unless there are open streams. |
+ return; |
+ } |
+ QuicTime::Delta ping_timeout = QuicTime::Delta::FromSeconds(kPingTimeoutSecs); |
+ ping_alarm_->Set(clock_->ApproximateNow().Add(ping_timeout)); |
+} |
+ |
QuicConnection::ScopedPacketBundler::ScopedPacketBundler( |
QuicConnection* connection, |
AckBundling send_ack) |