blob: ec2866ee1168018212bb507e0ecc732aa2d53b0c [file] [log] [blame]
[email protected]1d197ef52012-11-07 20:41:291// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/quic/quic_connection_helper.h"
6
7#include "base/location.h"
8#include "base/logging.h"
9#include "base/task_runner.h"
10#include "base/time.h"
[email protected]acf24742012-11-14 07:28:2411#include "net/base/io_buffer.h"
[email protected]ccc66e8a2013-03-26 08:26:1412#include "net/base/net_errors.h"
[email protected]1d197ef52012-11-07 20:41:2913#include "net/quic/quic_utils.h"
14
15namespace net {
16
17QuicConnectionHelper::QuicConnectionHelper(base::TaskRunner* task_runner,
[email protected]97693d12012-11-16 16:05:0018 const QuicClock* clock,
[email protected]9558c5d32012-12-22 00:08:1419 QuicRandom* random_generator,
[email protected]1d197ef52012-11-07 20:41:2920 DatagramClientSocket* socket)
[email protected]aa249b52013-04-30 01:04:3221 : weak_factory_(this),
[email protected]1d197ef52012-11-07 20:41:2922 task_runner_(task_runner),
23 socket_(socket),
24 clock_(clock),
[email protected]9558c5d32012-12-22 00:08:1425 random_generator_(random_generator),
[email protected]1d197ef52012-11-07 20:41:2926 send_alarm_registered_(false),
[email protected]516f6f82013-01-14 23:31:1727 timeout_alarm_registered_(false),
[email protected]c995c572013-01-18 05:43:2028 retransmission_alarm_registered_(false),
29 retransmission_alarm_running_(false),
[email protected]89503262013-01-17 02:08:5530 ack_alarm_registered_(false),
[email protected]c995c572013-01-18 05:43:2031 ack_alarm_time_(QuicTime::Zero()) {
[email protected]1d197ef52012-11-07 20:41:2932}
33
34QuicConnectionHelper::~QuicConnectionHelper() {
35}
36
37void QuicConnectionHelper::SetConnection(QuicConnection* connection) {
38 connection_ = connection;
39}
40
[email protected]97693d12012-11-16 16:05:0041const QuicClock* QuicConnectionHelper::GetClock() const {
[email protected]1d197ef52012-11-07 20:41:2942 return clock_;
43}
44
[email protected]9558c5d32012-12-22 00:08:1445QuicRandom* QuicConnectionHelper::GetRandomGenerator() {
46 return random_generator_;
47}
48
[email protected]1d197ef52012-11-07 20:41:2949int QuicConnectionHelper::WritePacketToWire(
[email protected]1d197ef52012-11-07 20:41:2950 const QuicEncryptedPacket& packet,
[email protected]1d197ef52012-11-07 20:41:2951 int* error) {
52 if (connection_->ShouldSimulateLostPacket()) {
[email protected]044ac2b2012-11-13 21:41:0653 DLOG(INFO) << "Dropping packet due to fake packet loss.";
[email protected]1d197ef52012-11-07 20:41:2954 *error = 0;
55 return packet.length();
56 }
57
[email protected]acf24742012-11-14 07:28:2458 scoped_refptr<StringIOBuffer> buf(
59 new StringIOBuffer(std::string(packet.data(),
60 packet.length())));
[email protected]ed26f1722012-12-22 01:23:5761 int rv = socket_->Write(buf, packet.length(),
62 base::Bind(&QuicConnectionHelper::OnWriteComplete,
63 weak_factory_.GetWeakPtr()));
64 if (rv >= 0) {
65 *error = 0;
66 } else {
67 *error = rv;
68 rv = -1;
69 }
70 return rv;
[email protected]1d197ef52012-11-07 20:41:2971}
72
[email protected]ccc66e8a2013-03-26 08:26:1473bool QuicConnectionHelper::IsWriteBlockedDataBuffered() {
74 // Chrome sockets' Write() methods buffer the data until the Write is
75 // permitted.
76 return true;
77}
78
79bool QuicConnectionHelper::IsWriteBlocked(int error) {
80 return error == ERR_IO_PENDING;
81}
82
[email protected]c995c572013-01-18 05:43:2083void QuicConnectionHelper::SetRetransmissionAlarm(QuicTime::Delta delay) {
84 if (!retransmission_alarm_registered_) {
[email protected]516f6f82013-01-14 23:31:1785 task_runner_->PostDelayedTask(
86 FROM_HERE,
[email protected]c995c572013-01-18 05:43:2087 base::Bind(&QuicConnectionHelper::OnRetransmissionAlarm,
[email protected]516f6f82013-01-14 23:31:1788 weak_factory_.GetWeakPtr()),
89 base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
90 }
[email protected]1d197ef52012-11-07 20:41:2991}
92
[email protected]89503262013-01-17 02:08:5593void QuicConnectionHelper::SetAckAlarm(QuicTime::Delta delay) {
94 if (!ack_alarm_registered_) {
95 task_runner_->PostDelayedTask(
96 FROM_HERE,
97 base::Bind(&QuicConnectionHelper::OnAckAlarm,
98 weak_factory_.GetWeakPtr()),
99 base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
100 }
101 ack_alarm_registered_ = true;
102 ack_alarm_time_ = clock_->Now().Add(delay);
103}
104
105void QuicConnectionHelper::ClearAckAlarm() {
[email protected]c995c572013-01-18 05:43:20106 ack_alarm_time_ = QuicTime::Zero();
[email protected]89503262013-01-17 02:08:55107}
108
[email protected]ccc66e8a2013-03-26 08:26:14109void QuicConnectionHelper::SetSendAlarm(QuicTime alarm_time) {
[email protected]1d197ef52012-11-07 20:41:29110 send_alarm_registered_ = true;
111 task_runner_->PostDelayedTask(
112 FROM_HERE,
113 base::Bind(&QuicConnectionHelper::OnSendAlarm,
114 weak_factory_.GetWeakPtr()),
[email protected]ccc66e8a2013-03-26 08:26:14115 base::TimeDelta::FromMicroseconds(
116 alarm_time.Subtract(QuicTime::Zero()).ToMicroseconds()));
[email protected]1d197ef52012-11-07 20:41:29117}
118
[email protected]2a960e02012-11-11 14:48:10119void QuicConnectionHelper::SetTimeoutAlarm(QuicTime::Delta delay) {
[email protected]b064310782013-05-30 21:12:17120 // CheckForTimeout will call SetTimeoutAlarm for the remaining time if alarm
121 // goes off before the delay.
122 if (timeout_alarm_registered_)
123 return;
[email protected]1d197ef52012-11-07 20:41:29124 timeout_alarm_registered_ = true;
125 task_runner_->PostDelayedTask(
126 FROM_HERE,
127 base::Bind(&QuicConnectionHelper::OnTimeoutAlarm,
128 weak_factory_.GetWeakPtr()),
[email protected]2a960e02012-11-11 14:48:10129 base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
[email protected]1d197ef52012-11-07 20:41:29130}
131
132bool QuicConnectionHelper::IsSendAlarmSet() {
133 return send_alarm_registered_;
134}
135
136void QuicConnectionHelper::UnregisterSendAlarmIfRegistered() {
137 send_alarm_registered_ = false;
138}
139
[email protected]c995c572013-01-18 05:43:20140void QuicConnectionHelper::OnRetransmissionAlarm() {
141 QuicTime when = connection_->OnRetransmissionTimeout();
142 if (!when.IsInitialized()) {
143 SetRetransmissionAlarm(clock_->Now().Subtract(when));
[email protected]516f6f82013-01-14 23:31:17144 }
[email protected]1d197ef52012-11-07 20:41:29145}
146
147void QuicConnectionHelper::OnSendAlarm() {
148 if (send_alarm_registered_) {
149 send_alarm_registered_ = false;
150 connection_->OnCanWrite();
151 }
152}
153
154void QuicConnectionHelper::OnTimeoutAlarm() {
155 timeout_alarm_registered_ = false;
156 connection_->CheckForTimeout();
157}
158
[email protected]89503262013-01-17 02:08:55159void QuicConnectionHelper::OnAckAlarm() {
160 ack_alarm_registered_ = false;
161 // Alarm may have been cleared.
162 if (!ack_alarm_time_.IsInitialized()) {
163 return;
164 }
165
166 // Alarm may have been reset to a later time.
167 if (clock_->Now() < ack_alarm_time_) {
168 SetAckAlarm(ack_alarm_time_.Subtract(clock_->Now()));
169 return;
170 }
171
[email protected]c995c572013-01-18 05:43:20172 ack_alarm_time_ = QuicTime::Zero();
[email protected]89503262013-01-17 02:08:55173 connection_->SendAck();
174}
175
[email protected]acf24742012-11-14 07:28:24176void QuicConnectionHelper::OnWriteComplete(int result) {
177 // TODO(rch): Inform the connection about the result.
178 connection_->OnCanWrite();
179}
180
[email protected]1d197ef52012-11-07 20:41:29181} // namespace net