blob: 4a35d82fa861ff9320210163d192a49d47a04302 [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"
[email protected]f002abb2013-06-28 02:30:2110#include "base/time/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]90499482013-06-01 00:39:5061 int rv = socket_->Write(buf.get(),
62 packet.length(),
[email protected]ed26f1722012-12-22 01:23:5763 base::Bind(&QuicConnectionHelper::OnWriteComplete,
64 weak_factory_.GetWeakPtr()));
65 if (rv >= 0) {
66 *error = 0;
67 } else {
68 *error = rv;
69 rv = -1;
70 }
71 return rv;
[email protected]1d197ef52012-11-07 20:41:2972}
73
[email protected]ccc66e8a2013-03-26 08:26:1474bool QuicConnectionHelper::IsWriteBlockedDataBuffered() {
75 // Chrome sockets' Write() methods buffer the data until the Write is
76 // permitted.
77 return true;
78}
79
80bool QuicConnectionHelper::IsWriteBlocked(int error) {
81 return error == ERR_IO_PENDING;
82}
83
[email protected]c995c572013-01-18 05:43:2084void QuicConnectionHelper::SetRetransmissionAlarm(QuicTime::Delta delay) {
85 if (!retransmission_alarm_registered_) {
[email protected]516f6f82013-01-14 23:31:1786 task_runner_->PostDelayedTask(
87 FROM_HERE,
[email protected]c995c572013-01-18 05:43:2088 base::Bind(&QuicConnectionHelper::OnRetransmissionAlarm,
[email protected]516f6f82013-01-14 23:31:1789 weak_factory_.GetWeakPtr()),
90 base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
91 }
[email protected]1d197ef52012-11-07 20:41:2992}
93
[email protected]89503262013-01-17 02:08:5594void QuicConnectionHelper::SetAckAlarm(QuicTime::Delta delay) {
95 if (!ack_alarm_registered_) {
96 task_runner_->PostDelayedTask(
97 FROM_HERE,
98 base::Bind(&QuicConnectionHelper::OnAckAlarm,
99 weak_factory_.GetWeakPtr()),
100 base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
101 }
102 ack_alarm_registered_ = true;
103 ack_alarm_time_ = clock_->Now().Add(delay);
104}
105
106void QuicConnectionHelper::ClearAckAlarm() {
[email protected]c995c572013-01-18 05:43:20107 ack_alarm_time_ = QuicTime::Zero();
[email protected]89503262013-01-17 02:08:55108}
109
[email protected]ccc66e8a2013-03-26 08:26:14110void QuicConnectionHelper::SetSendAlarm(QuicTime alarm_time) {
[email protected]1d197ef52012-11-07 20:41:29111 send_alarm_registered_ = true;
112 task_runner_->PostDelayedTask(
113 FROM_HERE,
114 base::Bind(&QuicConnectionHelper::OnSendAlarm,
115 weak_factory_.GetWeakPtr()),
[email protected]ccc66e8a2013-03-26 08:26:14116 base::TimeDelta::FromMicroseconds(
117 alarm_time.Subtract(QuicTime::Zero()).ToMicroseconds()));
[email protected]1d197ef52012-11-07 20:41:29118}
119
[email protected]2a960e02012-11-11 14:48:10120void QuicConnectionHelper::SetTimeoutAlarm(QuicTime::Delta delay) {
[email protected]b064310782013-05-30 21:12:17121 // CheckForTimeout will call SetTimeoutAlarm for the remaining time if alarm
122 // goes off before the delay.
123 if (timeout_alarm_registered_)
124 return;
[email protected]1d197ef52012-11-07 20:41:29125 timeout_alarm_registered_ = true;
126 task_runner_->PostDelayedTask(
127 FROM_HERE,
128 base::Bind(&QuicConnectionHelper::OnTimeoutAlarm,
129 weak_factory_.GetWeakPtr()),
[email protected]2a960e02012-11-11 14:48:10130 base::TimeDelta::FromMicroseconds(delay.ToMicroseconds()));
[email protected]1d197ef52012-11-07 20:41:29131}
132
133bool QuicConnectionHelper::IsSendAlarmSet() {
134 return send_alarm_registered_;
135}
136
137void QuicConnectionHelper::UnregisterSendAlarmIfRegistered() {
138 send_alarm_registered_ = false;
139}
140
[email protected]c995c572013-01-18 05:43:20141void QuicConnectionHelper::OnRetransmissionAlarm() {
142 QuicTime when = connection_->OnRetransmissionTimeout();
143 if (!when.IsInitialized()) {
144 SetRetransmissionAlarm(clock_->Now().Subtract(when));
[email protected]516f6f82013-01-14 23:31:17145 }
[email protected]1d197ef52012-11-07 20:41:29146}
147
148void QuicConnectionHelper::OnSendAlarm() {
149 if (send_alarm_registered_) {
150 send_alarm_registered_ = false;
151 connection_->OnCanWrite();
152 }
153}
154
155void QuicConnectionHelper::OnTimeoutAlarm() {
156 timeout_alarm_registered_ = false;
157 connection_->CheckForTimeout();
158}
159
[email protected]89503262013-01-17 02:08:55160void QuicConnectionHelper::OnAckAlarm() {
161 ack_alarm_registered_ = false;
162 // Alarm may have been cleared.
163 if (!ack_alarm_time_.IsInitialized()) {
164 return;
165 }
166
167 // Alarm may have been reset to a later time.
168 if (clock_->Now() < ack_alarm_time_) {
169 SetAckAlarm(ack_alarm_time_.Subtract(clock_->Now()));
170 return;
171 }
172
[email protected]c995c572013-01-18 05:43:20173 ack_alarm_time_ = QuicTime::Zero();
[email protected]89503262013-01-17 02:08:55174 connection_->SendAck();
175}
176
[email protected]acf24742012-11-14 07:28:24177void QuicConnectionHelper::OnWriteComplete(int result) {
178 // TODO(rch): Inform the connection about the result.
179 connection_->OnCanWrite();
180}
181
[email protected]1d197ef52012-11-07 20:41:29182} // namespace net