Refactor PerPacketOptions for QuicWriter. From the bug:
per_packet_options_ was originally designed as a vehicle for platforms to get specific instructions to their corresponding QuicWriters via a QuicConnection that didn't understand the semantics of those instructions. Therefore, it is passed to QuicConnection as a piece of memory of which the platform retains ownership.
Over time, other instructions specific to QuicConnection have appeared in this struct, as it provides a vehicle to send information to QuicWriter without changing APIs. But this violates the intent of the struct, makes Quiche functions reliant on a piece of memory owned by the platform, and is bug prone (e.g., if the platform provides the same piece of memory for all connections in a dispatcher, the outcome will be very bad).
PiperOrigin-RevId: 534577370
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_base.cc b/quiche/quic/core/batch_writer/quic_batch_writer_base.cc
index 4a94c71..fae805f 100644
--- a/quiche/quic/core/batch_writer/quic_batch_writer_base.cc
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_base.cc
@@ -18,9 +18,10 @@
WriteResult QuicBatchWriterBase::WritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions* options) {
- const WriteResult result =
- InternalWritePacket(buffer, buf_len, self_address, peer_address, options);
+ const QuicSocketAddress& peer_address, PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
+ const WriteResult result = InternalWritePacket(buffer, buf_len, self_address,
+ peer_address, options, params);
if (IsWriteBlockedStatus(result.status)) {
write_blocked_ = true;
@@ -31,14 +32,15 @@
WriteResult QuicBatchWriterBase::InternalWritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions* options) {
+ const QuicSocketAddress& peer_address, PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
if (buf_len > kMaxOutgoingPacketSize) {
return WriteResult(WRITE_STATUS_MSG_TOO_BIG, EMSGSIZE);
}
ReleaseTime release_time{0, QuicTime::Delta::Zero()};
if (SupportsReleaseTime()) {
- release_time = GetReleaseTime(options);
+ release_time = GetReleaseTime(params);
if (release_time.release_time_offset >= QuicTime::Delta::Zero()) {
QUIC_SERVER_HISTOGRAM_TIMES(
"batch_writer_positive_release_time_offset",
@@ -55,7 +57,7 @@
}
const CanBatchResult can_batch_result =
- CanBatch(buffer, buf_len, self_address, peer_address, options,
+ CanBatch(buffer, buf_len, self_address, peer_address, options, params,
release_time.actual_release_time);
bool buffered = false;
@@ -64,7 +66,7 @@
if (can_batch_result.can_batch) {
QuicBatchWriterBuffer::PushResult push_result =
batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
- peer_address, options,
+ peer_address, options, params,
release_time.actual_release_time);
if (push_result.succeeded) {
buffered = true;
@@ -111,7 +113,7 @@
if (!buffered) {
QuicBatchWriterBuffer::PushResult push_result =
batch_buffer_->PushBufferedWrite(buffer, buf_len, self_address,
- peer_address, options,
+ peer_address, options, params,
release_time.actual_release_time);
buffered = push_result.succeeded;
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_base.h b/quiche/quic/core/batch_writer/quic_batch_writer_base.h
index a5a1e38..a33b8e2 100644
--- a/quiche/quic/core/batch_writer/quic_batch_writer_base.h
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_base.h
@@ -32,7 +32,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
bool IsWriteBlocked() const final { return write_blocked_; }
@@ -78,7 +79,7 @@
QuicTime::Delta release_time_offset = QuicTime::Delta::Zero();
};
virtual ReleaseTime GetReleaseTime(
- const PerPacketOptions* /*options*/) const {
+ const QuicPacketWriterParams& /*params*/) const {
QUICHE_DCHECK(false)
<< "Should not be called since release time is unsupported.";
return ReleaseTime{0, QuicTime::Delta::Zero()};
@@ -101,6 +102,7 @@
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
const PerPacketOptions* options,
+ const QuicPacketWriterParams& params,
uint64_t release_time) const = 0;
struct QUIC_EXPORT_PRIVATE FlushImplResult {
@@ -129,7 +131,8 @@
WriteResult InternalWritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options);
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params);
// Calls FlushImpl() and check its post condition.
FlushImplResult CheckedFlush();
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc
index ac7ddd7..d283e2b 100644
--- a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.cc
@@ -54,7 +54,7 @@
QuicBatchWriterBuffer::PushResult QuicBatchWriterBuffer::PushBufferedWrite(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address, const PerPacketOptions* options,
- uint64_t release_time) {
+ const QuicPacketWriterParams& params, uint64_t release_time) {
QUICHE_DCHECK(Invariants());
QUICHE_DCHECK_LE(buf_len, kMaxOutgoingPacketSize);
@@ -84,7 +84,7 @@
}
buffered_writes_.emplace_back(
next_write_location, buf_len, self_address, peer_address,
- options ? options->Clone() : std::unique_ptr<PerPacketOptions>(),
+ options ? options->Clone() : std::unique_ptr<PerPacketOptions>(), params,
release_time);
QUICHE_DCHECK(Invariants());
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h
index 2369401..62282a3 100644
--- a/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer.h
@@ -44,6 +44,7 @@
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
const PerPacketOptions* options,
+ const QuicPacketWriterParams& params,
uint64_t release_time);
void UndoLastPush();
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc b/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
index e081a79..ffa88f0 100644
--- a/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_buffer_test.cc
@@ -52,7 +52,8 @@
void CheckBufferedWriteContent(int buffered_write_index, char buffer_content,
size_t buf_len, const QuicIpAddress& self_addr,
const QuicSocketAddress& peer_addr,
- const PerPacketOptions* options) {
+ const PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& params) {
const BufferedWrite& buffered_write =
batch_buffer_->buffered_writes()[buffered_write_index];
EXPECT_EQ(buf_len, buffered_write.buf_len);
@@ -64,12 +65,8 @@
}
EXPECT_EQ(self_addr, buffered_write.self_address);
EXPECT_EQ(peer_addr, buffered_write.peer_address);
- if (options == nullptr) {
- EXPECT_EQ(nullptr, buffered_write.options);
- } else {
- EXPECT_EQ(options->release_time_delay,
- buffered_write.options->release_time_delay);
- }
+ EXPECT_EQ(params.release_time_delay,
+ buffered_write.params.release_time_delay);
}
protected:
@@ -141,7 +138,8 @@
<< ", batch_buffer=" << batch_buffer_->DebugString());
auto push_result = batch_buffer_->PushBufferedWrite(
- buffer, buf_len, self_addr_, peer_addr_, nullptr, release_time_);
+ buffer, buf_len, self_addr_, peer_addr_, nullptr,
+ QuicPacketWriterParams(), release_time_);
if (!push_result.succeeded) {
++num_push_failures;
}
@@ -160,49 +158,51 @@
TEST_F(QuicBatchWriterBufferTest, MixedPushes) {
// First, a in-place push.
char* buffer = batch_buffer_->GetNextWriteLocation();
+ QuicPacketWriterParams params;
auto push_result = batch_buffer_->PushBufferedWrite(
FillPacketBuffer('A', buffer), kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr, release_time_);
+ peer_addr_, nullptr, params, release_time_);
EXPECT_TRUE(push_result.succeeded);
EXPECT_FALSE(push_result.buffer_copied);
CheckBufferedWriteContent(0, 'A', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
+ peer_addr_, nullptr, params);
// Then a push with external buffer.
push_result = batch_buffer_->PushBufferedWrite(
FillPacketBuffer('B'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
- nullptr, release_time_);
+ nullptr, params, release_time_);
EXPECT_TRUE(push_result.succeeded);
EXPECT_TRUE(push_result.buffer_copied);
CheckBufferedWriteContent(1, 'B', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
+ peer_addr_, nullptr, params);
// Then another in-place push.
buffer = batch_buffer_->GetNextWriteLocation();
push_result = batch_buffer_->PushBufferedWrite(
FillPacketBuffer('C', buffer), kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr, release_time_);
+ peer_addr_, nullptr, params, release_time_);
EXPECT_TRUE(push_result.succeeded);
EXPECT_FALSE(push_result.buffer_copied);
CheckBufferedWriteContent(2, 'C', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
+ peer_addr_, nullptr, params);
// Then another push with external buffer.
push_result = batch_buffer_->PushBufferedWrite(
FillPacketBuffer('D'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
- nullptr, release_time_);
+ nullptr, params, release_time_);
EXPECT_TRUE(push_result.succeeded);
EXPECT_TRUE(push_result.buffer_copied);
CheckBufferedWriteContent(3, 'D', kDefaultMaxPacketSize, self_addr_,
- peer_addr_, nullptr);
+ peer_addr_, nullptr, params);
}
TEST_F(QuicBatchWriterBufferTest, PopAll) {
const int kNumBufferedWrites = 10;
+ QuicPacketWriterParams params;
for (int i = 0; i < kNumBufferedWrites; ++i) {
EXPECT_TRUE(batch_buffer_
->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
- self_addr_, peer_addr_, nullptr,
+ self_addr_, peer_addr_, nullptr, params,
release_time_)
.succeeded);
}
@@ -217,11 +217,12 @@
TEST_F(QuicBatchWriterBufferTest, PopPartial) {
const int kNumBufferedWrites = 10;
+ QuicPacketWriterParams params;
for (int i = 0; i < kNumBufferedWrites; ++i) {
EXPECT_TRUE(batch_buffer_
- ->PushBufferedWrite(FillPacketBuffer('A' + i),
- kDefaultMaxPacketSize - i, self_addr_,
- peer_addr_, nullptr, release_time_)
+ ->PushBufferedWrite(
+ FillPacketBuffer('A' + i), kDefaultMaxPacketSize - i,
+ self_addr_, peer_addr_, nullptr, params, release_time_)
.succeeded);
}
@@ -239,7 +240,7 @@
kDefaultMaxPacketSize - kNumBufferedWrites + expect_size_after_pop;
for (size_t j = 0; j < expect_size_after_pop; ++j) {
CheckBufferedWriteContent(j, first_write_content + j, first_write_len - j,
- self_addr_, peer_addr_, nullptr);
+ self_addr_, peer_addr_, nullptr, params);
}
}
}
@@ -248,13 +249,14 @@
// First, a in-place push.
char* buffer = batch_buffer_->GetNextWriteLocation();
const size_t first_packet_len = 2;
+ QuicPacketWriterParams params;
auto push_result = batch_buffer_->PushBufferedWrite(
FillPacketBuffer('A', buffer, first_packet_len), first_packet_len,
- self_addr_, peer_addr_, nullptr, release_time_);
+ self_addr_, peer_addr_, nullptr, params, release_time_);
EXPECT_TRUE(push_result.succeeded);
EXPECT_FALSE(push_result.buffer_copied);
CheckBufferedWriteContent(0, 'A', first_packet_len, self_addr_, peer_addr_,
- nullptr);
+ nullptr, params);
// Simulate the case where the writer wants to do another in-place push, but
// can't do so because it can't be batched with the first buffer.
@@ -269,11 +271,11 @@
// Now the second push.
push_result = batch_buffer_->PushBufferedWrite(
FillPacketBuffer('B', buffer, second_packet_len), second_packet_len,
- self_addr_, peer_addr_, nullptr, release_time_);
+ self_addr_, peer_addr_, nullptr, params, release_time_);
EXPECT_TRUE(push_result.succeeded);
EXPECT_TRUE(push_result.buffer_copied);
CheckBufferedWriteContent(0, 'B', second_packet_len, self_addr_, peer_addr_,
- nullptr);
+ nullptr, params);
}
} // namespace
diff --git a/quiche/quic/core/batch_writer/quic_batch_writer_test.h b/quiche/quic/core/batch_writer/quic_batch_writer_test.h
index ebbb917..d42867f 100644
--- a/quiche/quic/core/batch_writer/quic_batch_writer_test.h
+++ b/quiche/quic/core/batch_writer/quic_batch_writer_test.h
@@ -195,7 +195,7 @@
result = GetWriter()->WritePacket(&packet_buffer_[0], this_packet_size,
self_address_.host(), peer_address_,
- nullptr);
+ nullptr, QuicPacketWriterParams());
ASSERT_EQ(WRITE_STATUS_OK, result.status) << strerror(result.error_code);
bytes_flushed += result.bytes_written;
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc b/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc
index b6d6200..512e51f 100644
--- a/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer.cc
@@ -49,8 +49,8 @@
QuicGsoBatchWriter::CanBatchResult QuicGsoBatchWriter::CanBatch(
const char* /*buffer*/, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, const PerPacketOptions* options,
- uint64_t release_time) const {
+ const QuicSocketAddress& peer_address, const PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& params, uint64_t release_time) const {
// If there is nothing buffered already, this write will be included in this
// batch.
if (buffered_writes().empty()) {
@@ -70,9 +70,9 @@
const BufferedWrite& first = buffered_writes().front();
const BufferedWrite& last = buffered_writes().back();
// Whether this packet can be sent without delay, regardless of release time.
- const bool can_burst = !SupportsReleaseTime() || !options ||
- options->release_time_delay.IsZero() ||
- options->allow_burst;
+ const bool can_burst = !SupportsReleaseTime() ||
+ params.release_time_delay.IsZero() ||
+ params.allow_burst;
size_t max_segments = MaxSegments(first.buf_len);
bool can_batch =
buffered_writes().size() < max_segments && // [0]
@@ -96,18 +96,14 @@
}
QuicGsoBatchWriter::ReleaseTime QuicGsoBatchWriter::GetReleaseTime(
- const PerPacketOptions* options) const {
+ const QuicPacketWriterParams& params) const {
QUICHE_DCHECK(SupportsReleaseTime());
- if (options == nullptr) {
- return {0, QuicTime::Delta::Zero()};
- }
-
const uint64_t now = NowInNanosForReleaseTime();
const uint64_t ideal_release_time =
- now + options->release_time_delay.ToMicroseconds() * 1000;
+ now + params.release_time_delay.ToMicroseconds() * 1000;
- if ((options->release_time_delay.IsZero() || options->allow_burst) &&
+ if ((params.release_time_delay.IsZero() || params.allow_burst) &&
!buffered_writes().empty() &&
// If release time of buffered packets is in the past, flush buffered
// packets and buffer this packet at the ideal release time.
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer.h b/quiche/quic/core/batch_writer/quic_gso_batch_writer.h
index 17657fc..96ccc76 100644
--- a/quiche/quic/core/batch_writer/quic_gso_batch_writer.h
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer.h
@@ -25,6 +25,7 @@
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
const PerPacketOptions* options,
+ const QuicPacketWriterParams& params,
uint64_t release_time) const override;
FlushImplResult FlushImpl() override;
@@ -36,7 +37,8 @@
int fd, clockid_t clockid_for_release_time,
ReleaseTimeForceEnabler enabler);
- ReleaseTime GetReleaseTime(const PerPacketOptions* options) const override;
+ ReleaseTime GetReleaseTime(
+ const QuicPacketWriterParams& params) const override;
// Get the current time in nanos from |clockid_for_release_time_|.
virtual uint64_t NowInNanosForReleaseTime() const;
diff --git a/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc b/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc
index efe4c71..c4c0406 100644
--- a/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc
+++ b/quiche/quic/core/batch_writer/quic_gso_batch_writer_test.cc
@@ -75,7 +75,7 @@
other.peer_address,
other.options ? other.options->Clone()
: std::unique_ptr<PerPacketOptions>(),
- other.release_time) {}
+ QuicPacketWriterParams(), other.release_time) {}
};
// Pointed to by all instances of |BatchCriteriaTestData|. Content not used.
@@ -87,7 +87,7 @@
uint64_t release_time, bool can_batch, bool must_flush)
: buffered_write(unused_packet_buffer, buf_len, self_address,
peer_address, std::unique_ptr<PerPacketOptions>(),
- release_time),
+ QuicPacketWriterParams(), release_time),
can_batch(can_batch),
must_flush(must_flush) {}
@@ -203,13 +203,14 @@
protected:
WriteResult WritePacket(QuicGsoBatchWriter* writer, size_t packet_size) {
return writer->WritePacket(&packet_buffer_[0], packet_size, self_address_,
- peer_address_, nullptr);
+ peer_address_, nullptr,
+ QuicPacketWriterParams());
}
- WriteResult WritePacketWithOptions(QuicGsoBatchWriter* writer,
- PerPacketOptions* options) {
+ WriteResult WritePacketWithParams(QuicGsoBatchWriter* writer,
+ QuicPacketWriterParams& params) {
return writer->WritePacket(&packet_buffer_[0], 1350, self_address_,
- peer_address_, options);
+ peer_address_, nullptr, params);
}
QuicIpAddress self_address_ = QuicIpAddress::Any4();
@@ -239,13 +240,13 @@
for (size_t j = 0; j < test_data_table.size(); ++j) {
const BatchCriteriaTestData& test_data = test_data_table[j];
SCOPED_TRACE(testing::Message() << "i=" << i << ", j=" << j);
- TestPerPacketOptions options;
- options.release_time_delay = QuicTime::Delta::FromMicroseconds(
+ QuicPacketWriterParams params;
+ params.release_time_delay = QuicTime::Delta::FromMicroseconds(
test_data.buffered_write.release_time);
TestQuicGsoBatchWriter::CanBatchResult result = writer->CanBatch(
test_data.buffered_write.buffer, test_data.buffered_write.buf_len,
test_data.buffered_write.self_address,
- test_data.buffered_write.peer_address, &options,
+ test_data.buffered_write.peer_address, nullptr, params,
test_data.buffered_write.release_time);
ASSERT_EQ(test_data.can_batch, result.can_batch);
@@ -257,8 +258,8 @@
test_data.buffered_write.buffer,
test_data.buffered_write.buf_len,
test_data.buffered_write.self_address,
- test_data.buffered_write.peer_address, &options,
- test_data.buffered_write.release_time)
+ test_data.buffered_write.peer_address, nullptr,
+ params, test_data.buffered_write.release_time)
.succeeded);
}
}
@@ -379,32 +380,27 @@
ASSERT_EQ(0u, writer.buffered_writes().size());
}
-TEST_F(QuicGsoBatchWriterTest, ReleaseTimeNullOptions) {
- auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
- EXPECT_EQ(0u, writer->GetReleaseTime(nullptr).actual_release_time);
-}
-
TEST_F(QuicGsoBatchWriterTest, ReleaseTime) {
const WriteResult write_buffered(WRITE_STATUS_OK, 0);
auto writer = TestQuicGsoBatchWriter::NewInstanceWithReleaseTimeSupport();
- TestPerPacketOptions options;
- EXPECT_TRUE(options.release_time_delay.IsZero());
- EXPECT_FALSE(options.allow_burst);
+ QuicPacketWriterParams params;
+ EXPECT_TRUE(params.release_time_delay.IsZero());
+ EXPECT_FALSE(params.allow_burst);
EXPECT_EQ(MillisToNanos(1),
- writer->GetReleaseTime(&options).actual_release_time);
+ writer->GetReleaseTime(params).actual_release_time);
// The 1st packet has no delay.
- WriteResult result = WritePacketWithOptions(writer.get(), &options);
+ WriteResult result = WritePacketWithParams(writer.get(), params);
ASSERT_EQ(write_buffered, result);
EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
// The 2nd packet has some delay, but allows burst.
- options.release_time_delay = QuicTime::Delta::FromMilliseconds(3);
- options.allow_burst = true;
- result = WritePacketWithOptions(writer.get(), &options);
+ params.release_time_delay = QuicTime::Delta::FromMilliseconds(3);
+ params.allow_burst = true;
+ result = WritePacketWithParams(writer.get(), params);
ASSERT_EQ(write_buffered, result);
EXPECT_EQ(MillisToNanos(1), writer->buffered_writes().back().release_time);
EXPECT_EQ(result.send_time_offset, QuicTime::Delta::FromMilliseconds(-3));
@@ -417,16 +413,16 @@
errno = 0;
return 0;
}));
- options.release_time_delay = QuicTime::Delta::FromMilliseconds(5);
- options.allow_burst = false;
- result = WritePacketWithOptions(writer.get(), &options);
+ params.release_time_delay = QuicTime::Delta::FromMilliseconds(5);
+ params.allow_burst = false;
+ result = WritePacketWithParams(writer.get(), params);
ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 2700), result);
EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
// The 4th packet has same delay, but allows burst.
- options.allow_burst = true;
- result = WritePacketWithOptions(writer.get(), &options);
+ params.allow_burst = true;
+ result = WritePacketWithParams(writer.get(), params);
ASSERT_EQ(write_buffered, result);
EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
@@ -439,19 +435,19 @@
errno = 0;
return 0;
}));
- options.allow_burst = true;
+ params.allow_burst = true;
EXPECT_EQ(MillisToNanos(6),
- writer->GetReleaseTime(&options).actual_release_time);
+ writer->GetReleaseTime(params).actual_release_time);
ASSERT_EQ(WriteResult(WRITE_STATUS_OK, 3000),
writer->WritePacket(&packet_buffer_[0], 300, self_address_,
- peer_address_, &options));
+ peer_address_, nullptr, params));
EXPECT_TRUE(writer->buffered_writes().empty());
// Pretend 1ms has elapsed and the 6th packet has 1ms less delay. In other
// words, the release time should still be the same as packets 3-5.
writer->ForceReleaseTimeMs(2);
- options.release_time_delay = QuicTime::Delta::FromMilliseconds(4);
- result = WritePacketWithOptions(writer.get(), &options);
+ params.release_time_delay = QuicTime::Delta::FromMilliseconds(4);
+ result = WritePacketWithParams(writer.get(), params);
ASSERT_EQ(write_buffered, result);
EXPECT_EQ(MillisToNanos(6), writer->buffered_writes().back().release_time);
EXPECT_EQ(result.send_time_offset, QuicTime::Delta::Zero());
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
index 8568e26..0c724b2 100644
--- a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.cc
@@ -14,7 +14,8 @@
const char* /*buffer*/, size_t /*buf_len*/,
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& /*peer_address*/,
- const PerPacketOptions* /*options*/, uint64_t /*release_time*/) const {
+ const PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& /*params*/, uint64_t /*release_time*/) const {
return CanBatchResult(/*can_batch=*/true, /*must_flush=*/false);
}
diff --git a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
index 04a1b28..9dda5dd 100644
--- a/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
+++ b/quiche/quic/core/batch_writer/quic_sendmmsg_batch_writer.h
@@ -19,6 +19,7 @@
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
const PerPacketOptions* options,
+ const QuicPacketWriterParams& params,
uint64_t release_time) const override;
FlushImplResult FlushImpl() override;
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index 44e3abe..d4e442f 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -31,6 +31,7 @@
#include "quiche/quic/core/quic_error_codes.h"
#include "quiche/quic/core/quic_framer.h"
#include "quiche/quic/core/quic_packet_creator.h"
+#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_packet_writer_wrapper.h"
#include "quiche/quic/core/quic_packets.h"
#include "quiche/quic/core/quic_session.h"
@@ -947,6 +948,7 @@
std::vector<std::string> received_webtransport_unidirectional_streams_;
bool use_preferred_address_ = false;
QuicSocketAddress server_preferred_address_;
+ QuicPacketWriterParams packet_writer_params_;
};
// Run all end to end tests with all supported versions.
@@ -3206,15 +3208,17 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override {
if (self_address_to_overwrite_.IsInitialized()) {
// Send the same packet on the overwriting address before sending on the
// actual self address.
- QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address_to_overwrite_, peer_address, options);
+ QuicPacketWriterWrapper::WritePacket(buffer, buf_len,
+ self_address_to_overwrite_,
+ peer_address, options, params);
}
return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
+ peer_address, options, params);
}
void set_self_address_to_overwrite(const QuicIpAddress& self_address) {
@@ -3996,7 +4000,8 @@
server_thread_->Pause();
auto client_address = client_connection->self_address();
server_writer_->WritePacket(packet->data(), packet->length(),
- server_address_.host(), client_address, nullptr);
+ server_address_.host(), client_address, nullptr,
+ packet_writer_params_);
server_thread_->Resume();
// The request should fail.
@@ -4038,7 +4043,8 @@
server_thread_->Pause();
auto client_address = client_connection->self_address();
server_writer_->WritePacket(packet->data(), packet->length(),
- server_address_.host(), client_address, nullptr);
+ server_address_.host(), client_address, nullptr,
+ packet_writer_params_);
server_thread_->Resume();
// The request should fail. IETF stateless reset does not include connection
@@ -4087,7 +4093,7 @@
client_writer_->WritePacket(
packet->data(), packet->length(),
client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
+ server_address_, nullptr, packet_writer_params_);
// The connection should be unaffected.
SendSynchronousFooRequestAndCheckResponse();
@@ -4119,7 +4125,8 @@
server_thread_->Pause();
server_writer_->WritePacket(
packet->data(), packet->length(), server_address_.host(),
- client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+ client_->client()->network_helper()->GetLatestClientAddress(), nullptr,
+ packet_writer_params_);
server_thread_->Resume();
// The connection should be unaffected.
@@ -4149,10 +4156,11 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- quic::PerPacketOptions* options) override {
+ quic::PerPacketOptions* options,
+ const quic::QuicPacketWriterParams& params) override {
if (!intercept_enabled_) {
return PacketDroppingTestWriter::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
+ buffer, buf_len, self_address, peer_address, options, params);
}
PacketHeaderFormat format;
QuicLongHeaderType long_packet_type;
@@ -4177,16 +4185,19 @@
intercept_enabled_ = false;
server_thread_->Resume();
// Pass the client-sent packet through.
- return WritePacket(buffer, buf_len, self_address, peer_address, options);
+ return WritePacket(buffer, buf_len, self_address, peer_address, options,
+ params);
}
// Send a version negotiation packet.
std::unique_ptr<QuicEncryptedPacket> packet(
QuicFramer::BuildVersionNegotiationPacket(
destination_connection_id, source_connection_id, /*ietf_quic=*/true,
has_length_prefix, supported_versions_));
+ QuicPacketWriterParams default_params;
server_writer_->WritePacket(
packet->data(), packet->length(), peer_address.host(),
- client_->client()->network_helper()->GetLatestClientAddress(), nullptr);
+ client_->client()->network_helper()->GetLatestClientAddress(), nullptr,
+ default_params);
// Drop the client-sent packet but pretend it was sent.
return WriteResult(WRITE_STATUS_OK, buf_len);
}
@@ -4248,7 +4259,7 @@
client_writer_->WritePacket(
&packet[0], sizeof(packet),
client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
+ server_address_, nullptr, packet_writer_params_);
EXPECT_TRUE(server_thread_->WaitUntil(
[&] {
return QuicDispatcherPeer::GetAndClearLastError(
@@ -4295,7 +4306,7 @@
client_writer_->WritePacket(
reinterpret_cast<const char*>(packet), sizeof(packet),
client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
+ server_address_, nullptr, packet_writer_params_);
EXPECT_TRUE(server_thread_->WaitUntil(
[&] {
@@ -4331,7 +4342,7 @@
client_writer_->WritePacket(
damaged_packet.data(), damaged_packet.length(),
client_->client()->network_helper()->GetLatestClientAddress().host(),
- server_address_, nullptr);
+ server_address_, nullptr, packet_writer_params_);
// Give the server time to process the packet.
absl::SleepFor(absl::Seconds(1));
// This error is sent to the connection's OnError (which ignores it), so the
@@ -5261,10 +5272,11 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override {
if (!hold_next_packet_) {
- return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
+ return QuicPacketWriterWrapper::WritePacket(
+ buffer, buf_len, self_address, peer_address, options, params);
}
QUIC_DLOG(INFO) << "Packet is held by the writer";
packet_content_ = std::string(buffer, buf_len);
@@ -5286,7 +5298,7 @@
ASSERT_EQ(WRITE_STATUS_OK,
QuicPacketWriterWrapper::WritePacket(
packet_content_.data(), packet_content_.length(),
- self_address_, peer_address_, options_.release())
+ self_address_, peer_address_, options_.release(), params_)
.status);
packet_content_.clear();
}
@@ -5297,6 +5309,7 @@
QuicIpAddress self_address_;
QuicSocketAddress peer_address_;
std::unique_ptr<PerPacketOptions> options_;
+ QuicPacketWriterParams params_;
};
TEST_P(EndToEndTest, ClientValidateNewNetwork) {
@@ -5849,9 +5862,10 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- quic::PerPacketOptions* options) override {
+ quic::PerPacketOptions* options,
+ const quic::QuicPacketWriterParams& params) override {
const WriteResult result = QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
+ buffer, buf_len, self_address, peer_address, options, params);
const uint8_t type_byte = buffer[0];
if (!error_returned_ && (type_byte & FLAGS_LONG_HEADER) &&
TypeByteIsServerHello(type_byte)) {
@@ -5924,7 +5938,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- quic::PerPacketOptions* options) override {
+ quic::PerPacketOptions* options,
+ const quic::QuicPacketWriterParams& params) override {
const uint8_t type_byte = buffer[0];
if (type_byte & FLAGS_LONG_HEADER) {
@@ -5939,7 +5954,7 @@
return WriteResult(WRITE_STATUS_ERROR, *MessageTooBigErrorCode());
}
return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
+ peer_address, options, params);
}
private:
@@ -6076,14 +6091,15 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override {
if (num_packets_to_copy_ > 0) {
num_packets_to_copy_--;
packets_.push_back(
QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
}
return PacketDroppingTestWriter::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
+ peer_address, options, params);
}
std::vector<std::unique_ptr<QuicEncryptedPacket>>& packets() {
@@ -7097,9 +7113,7 @@
EXPECT_EQ(ecn->ect0, 0);
EXPECT_EQ(ecn->ect1, 0);
EXPECT_EQ(ecn->ce, 0);
- TestPerPacketOptions options;
- client_connection->set_per_packet_options(&options);
- options.ecn_codepoint = ECN_NOT_ECT;
+ client_connection->set_ecn_codepoint(ECN_NOT_ECT);
client_->SendSynchronousRequest("/foo");
EXPECT_EQ(ecn->ect0, 0);
EXPECT_EQ(ecn->ect1, 0);
@@ -7119,9 +7133,7 @@
EXPECT_EQ(ecn->ect0, 0);
EXPECT_EQ(ecn->ect1, 0);
EXPECT_EQ(ecn->ce, 0);
- TestPerPacketOptions options;
- client_connection->set_per_packet_options(&options);
- options.ecn_codepoint = ECN_ECT0;
+ client_connection->set_ecn_codepoint(ECN_ECT0);
client_->SendSynchronousRequest("/foo");
if (!GetQuicRestartFlag(quic_receive_ecn) ||
!GetQuicRestartFlag(quic_quiche_ecn_sockets) ||
@@ -7147,9 +7159,7 @@
EXPECT_EQ(ecn->ect0, 0);
EXPECT_EQ(ecn->ect1, 0);
EXPECT_EQ(ecn->ce, 0);
- TestPerPacketOptions options;
- client_connection->set_per_packet_options(&options);
- options.ecn_codepoint = ECN_ECT1;
+ client_connection->set_ecn_codepoint(ECN_ECT1);
client_->SendSynchronousRequest("/foo");
if (!GetQuicRestartFlag(quic_receive_ecn) ||
!GetQuicRestartFlag(quic_quiche_ecn_sockets) ||
@@ -7175,9 +7185,7 @@
EXPECT_EQ(ecn->ect0, 0);
EXPECT_EQ(ecn->ect1, 0);
EXPECT_EQ(ecn->ce, 0);
- TestPerPacketOptions options;
- client_connection->set_per_packet_options(&options);
- options.ecn_codepoint = ECN_CE;
+ client_connection->set_ecn_codepoint(ECN_CE);
client_->SendSynchronousRequest("/foo");
if (!GetQuicRestartFlag(quic_receive_ecn) ||
!GetQuicRestartFlag(quic_quiche_ecn_sockets) ||
@@ -7202,9 +7210,7 @@
QuicEcnCounts* ecn = QuicSentPacketManagerPeer::GetPeerEcnCounts(
QuicConnectionPeer::GetSentPacketManager(server_connection),
APPLICATION_DATA);
- TestPerPacketOptions options;
- options.ecn_codepoint = ECN_ECT1;
- server_connection->set_per_packet_options(&options);
+ server_connection->set_ecn_codepoint(ECN_ECT1);
client_->SendSynchronousRequest("/foo");
// A second request provides a packet for the client ACKs to go with.
client_->SendSynchronousRequest("/foo");
diff --git a/quiche/quic/core/http/quic_spdy_session_test.cc b/quiche/quic/core/http/quic_spdy_session_test.cc
index e778864..6c98257 100644
--- a/quiche/quic/core/http/quic_spdy_session_test.cc
+++ b/quiche/quic/core/http/quic_spdy_session_test.cc
@@ -523,7 +523,7 @@
void CompleteHandshake() {
if (VersionHasIetfQuicFrames(transport_version())) {
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
}
if (connection_->version().UsesTls() &&
@@ -791,7 +791,7 @@
TEST_P(QuicSpdySessionTestServer,
DebugDFatalIfMarkingClosedStreamWriteBlocked) {
CompleteHandshake();
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
@@ -822,7 +822,7 @@
static_cast<QuicSession*>(&session_), QuicUtils::GetMaxStreamCount());
QuicStreamsBlockedFrame frame;
frame.stream_count = QuicUtils::GetMaxStreamCount();
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(_));
session_.OnStreamsBlockedFrame(frame);
@@ -860,7 +860,7 @@
// Expect that we only send one packet, the writes from different streams
// should be bundled together.
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
@@ -926,7 +926,7 @@
// Drive packet writer manually.
EXPECT_CALL(*writer_, IsWriteBlocked()).WillRepeatedly(Return(true));
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _)).Times(0);
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
@@ -1078,7 +1078,7 @@
return;
}
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
EXPECT_CALL(*connection_, SendControlFrame(_))
@@ -1118,7 +1118,7 @@
StrictMock<MockHttp3DebugVisitor> debug_visitor;
session_.set_debug_visitor(&debug_visitor);
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
// Send max stream id (currently 32 bits).
EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
@@ -1161,7 +1161,7 @@
GetNthClientInitiatedBidirectionalStreamId(transport_version(), 0);
EXPECT_TRUE(session_.GetOrCreateStream(kTestStreamId));
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
// Send max stream id (currently 32 bits).
EXPECT_CALL(debug_visitor, OnGoAwayFrameSent(/* stream_id = */ 0xfffffffc));
@@ -1268,7 +1268,7 @@
// In HTTP/3, Qpack stream will send data on stream reset and cause packet to
// be flushed.
if (VersionUsesHttp3(transport_version())) {
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
}
EXPECT_CALL(*connection_, SendControlFrame(_));
@@ -1503,7 +1503,7 @@
EXPECT_CALL(*connection_, OnStreamReset(stream->id(), _));
EXPECT_CALL(*connection_, SendControlFrame(_));
} else {
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
}
QuicRstStreamFrame rst_frame(kInvalidControlFrameId, stream->id(),
@@ -1782,7 +1782,7 @@
CompleteHandshake();
TestStream* stream = session_.CreateOutgoingBidirectionalStream();
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
// Write headers with FIN set to close write side of stream.
// Header block does not matter.
@@ -2838,7 +2838,7 @@
session_.OnSetting(SETTINGS_MAX_FIELD_SECTION_SIZE, 5);
EXPECT_EQ(5u, session_.max_outbound_header_list_size());
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
QpackEncoder* qpack_encoder = session_.qpack_encoder();
EXPECT_EQ(0u, QpackEncoderPeer::maximum_blocked_streams(qpack_encoder));
@@ -3065,7 +3065,7 @@
QuicUtils::StreamIdDelta(transport_version())));
// Close connection.
- EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer_, WritePacket(_, _, _, _, _, _))
.WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
EXPECT_CALL(*connection_, CloseConnection(QUIC_NO_ERROR, _, _))
.WillOnce(
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index 3e575f2..6fd85b7 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -3251,7 +3251,7 @@
QuicTime QuicConnection::CalculatePacketSentTime() {
const QuicTime now = clock_->Now();
- if (!supports_release_time_ || per_packet_options_ == nullptr) {
+ if (!supports_release_time_) {
// Don't change the release delay.
return now;
}
@@ -3261,8 +3261,8 @@
// Release before |now| is impossible.
QuicTime next_release_time =
std::max(now, next_release_time_result.release_time);
- per_packet_options_->release_time_delay = next_release_time - now;
- per_packet_options_->allow_burst = next_release_time_result.allow_burst;
+ packet_writer_params_.release_time_delay = next_release_time - now;
+ packet_writer_params_.allow_burst = next_release_time_result.allow_burst;
return next_release_time;
}
@@ -3929,7 +3929,7 @@
return;
}
QUIC_DVLOG(1) << ENDPOINT << "ECN feedback is invalid, stop marking.";
- ClearEcnCodepoint();
+ packet_writer_params_.ecn_codepoint = ECN_NOT_ECT;
}
std::unique_ptr<QuicSelfIssuedConnectionIdManager>
@@ -4073,7 +4073,8 @@
QuicEcnCodepoint QuicConnection::GetEcnCodepointToSend(
const QuicSocketAddress& destination_address) const {
- const QuicEcnCodepoint original_codepoint = GetNextEcnCodepoint();
+ const QuicEcnCodepoint original_codepoint =
+ packet_writer_params_.ecn_codepoint;
if (disable_ecn_codepoint_validation_) {
return original_codepoint;
}
@@ -4106,24 +4107,16 @@
return original_codepoint;
}
-void QuicConnection::ClearEcnCodepoint() { MaybeSetEcnCodepoint(ECN_NOT_ECT); }
-
-void QuicConnection::MaybeSetEcnCodepoint(QuicEcnCodepoint ecn_codepoint) {
- if (per_packet_options_ != nullptr) {
- per_packet_options_->ecn_codepoint = ecn_codepoint;
- }
-}
-
WriteResult QuicConnection::SendPacketToWriter(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
const QuicSocketAddress& destination_address, QuicPacketWriter* writer,
const QuicEcnCodepoint ecn_codepoint) {
- QuicEcnCodepoint original_codepoint = GetNextEcnCodepoint();
+ QuicPacketWriterParams params = packet_writer_params_;
+ params.ecn_codepoint = ecn_codepoint;
last_ecn_codepoint_sent_ = ecn_codepoint;
- MaybeSetEcnCodepoint(ecn_codepoint);
- WriteResult result = writer->WritePacket(
- buffer, buf_len, self_address, destination_address, per_packet_options_);
- MaybeSetEcnCodepoint(original_codepoint);
+ WriteResult result =
+ writer->WritePacket(buffer, buf_len, self_address, destination_address,
+ per_packet_options_, params);
return result;
}
@@ -4231,7 +4224,7 @@
if (!HasQueuedData() && !retransmission_alarm_->IsSet()) {
SetRetransmissionAlarm();
}
- if (GetNextEcnCodepoint() == ECN_NOT_ECT ||
+ if (packet_writer_params_.ecn_codepoint == ECN_NOT_ECT ||
default_path_.ecn_marked_packet_acked) {
return;
}
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index 8274be2..a89e915 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -1319,6 +1319,20 @@
return sent_server_preferred_address_;
}
+ // Sets the ECN marking for all outgoing packets, assuming that the congestion
+ // control supports that codepoint. QuicConnection will revert to sending
+ // ECN_NOT_ECT if there is evidence the path is dropping ECN-marked packets,
+ // or if the peer provides invalid ECN feedback.
+ void set_ecn_codepoint(QuicEcnCodepoint ecn_codepoint) {
+ if (GetQuicReloadableFlag(quic_send_ect1)) {
+ packet_writer_params_.ecn_codepoint = ecn_codepoint;
+ }
+ }
+
+ QuicEcnCodepoint ecn_codepoint() const {
+ return packet_writer_params_.ecn_codepoint;
+ }
+
protected:
// Calls cancel() on all the alarms owned by this connection.
void CancelAllAlarms();
@@ -1985,25 +1999,10 @@
// Returns true if |address| is known server address.
bool IsKnownServerAddress(const QuicSocketAddress& address) const;
- // Retrieves the ECN codepoint stored in per_packet_options_, unless the flag
- // is not set.
- QuicEcnCodepoint GetNextEcnCodepoint() const {
- return (per_packet_options_ != nullptr &&
- GetQuicReloadableFlag(quic_send_ect1))
- ? per_packet_options_->ecn_codepoint
- : ECN_NOT_ECT;
- }
-
// Retrieves the ECN codepoint to be sent on the next packet.
QuicEcnCodepoint GetEcnCodepointToSend(
const QuicSocketAddress& destination_address) const;
- // Sets the ECN codepoint to Not-ECT.
- void ClearEcnCodepoint();
-
- // Set the ECN codepoint, but only if set_per_packet_options has been called.
- void MaybeSetEcnCodepoint(QuicEcnCodepoint ecn_codepoint);
-
// Writes the packet to |writer| with the ECN mark specified in
// |ecn_codepoint|. Will also set last_ecn_sent_ appropriately.
WriteResult SendPacketToWriter(const char* buffer, size_t buf_len,
@@ -2033,6 +2032,7 @@
QuicConnectionHelperInterface* helper_; // Not owned.
QuicAlarmFactory* alarm_factory_; // Not owned.
PerPacketOptions* per_packet_options_; // Not owned.
+ QuicPacketWriterParams packet_writer_params_;
QuicPacketWriter* writer_; // Owned or not depending on |owns_writer_|.
bool owns_writer_;
// Encryption level for new packets. Should only be changed via
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 5db68ba..4e326fd 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -17110,10 +17110,8 @@
TEST_P(QuicConnectionTest, EcnCodepointsRejected) {
SetQuicReloadableFlag(quic_send_ect1, true);
- TestPerPacketOptions per_packet_options;
- connection_.set_per_packet_options(&per_packet_options);
for (QuicEcnCodepoint ecn : {ECN_NOT_ECT, ECN_ECT0, ECN_ECT1, ECN_CE}) {
- per_packet_options.ecn_codepoint = ecn;
+ connection_.set_ecn_codepoint(ecn);
if (ecn == ECN_ECT0) {
EXPECT_CALL(*send_algorithm_, SupportsECT0()).WillOnce(Return(false));
} else if (ecn == ECN_ECT1) {
@@ -17121,17 +17119,15 @@
}
EXPECT_CALL(connection_, OnSerializedPacket(_));
SendPing();
- EXPECT_EQ(per_packet_options.ecn_codepoint, ecn);
+ EXPECT_EQ(connection_.ecn_codepoint(), ecn);
EXPECT_EQ(writer_->last_ecn_sent(), ECN_NOT_ECT);
}
}
TEST_P(QuicConnectionTest, EcnCodepointsAccepted) {
SetQuicReloadableFlag(quic_send_ect1, true);
- TestPerPacketOptions per_packet_options;
- connection_.set_per_packet_options(&per_packet_options);
for (QuicEcnCodepoint ecn : {ECN_NOT_ECT, ECN_ECT0, ECN_ECT1, ECN_CE}) {
- per_packet_options.ecn_codepoint = ecn;
+ connection_.set_ecn_codepoint(ecn);
if (ecn == ECN_ECT0) {
EXPECT_CALL(*send_algorithm_, SupportsECT0()).WillOnce(Return(true));
} else if (ecn == ECN_ECT1) {
@@ -17143,34 +17139,30 @@
if (ecn == ECN_CE) {
expected_codepoint = ECN_NOT_ECT;
}
- EXPECT_EQ(per_packet_options.ecn_codepoint, ecn);
+ EXPECT_EQ(connection_.ecn_codepoint(), ecn);
EXPECT_EQ(writer_->last_ecn_sent(), expected_codepoint);
}
}
TEST_P(QuicConnectionTest, EcnCodepointsRejectedIfFlagIsFalse) {
SetQuicReloadableFlag(quic_send_ect1, false);
- TestPerPacketOptions per_packet_options;
- connection_.set_per_packet_options(&per_packet_options);
for (QuicEcnCodepoint ecn : {ECN_NOT_ECT, ECN_ECT0, ECN_ECT1, ECN_CE}) {
- per_packet_options.ecn_codepoint = ecn;
+ connection_.set_ecn_codepoint(ecn);
EXPECT_CALL(connection_, OnSerializedPacket(_));
SendPing();
- EXPECT_EQ(per_packet_options.ecn_codepoint, ECN_NOT_ECT);
+ EXPECT_EQ(connection_.ecn_codepoint(), ECN_NOT_ECT);
EXPECT_EQ(writer_->last_ecn_sent(), ECN_NOT_ECT);
}
}
TEST_P(QuicConnectionTest, EcnValidationDisabled) {
SetQuicReloadableFlag(quic_send_ect1, true);
- TestPerPacketOptions per_packet_options;
- connection_.set_per_packet_options(&per_packet_options);
QuicConnectionPeer::DisableEcnCodepointValidation(&connection_);
for (QuicEcnCodepoint ecn : {ECN_NOT_ECT, ECN_ECT0, ECN_ECT1, ECN_CE}) {
- per_packet_options.ecn_codepoint = ecn;
+ connection_.set_ecn_codepoint(ecn);
EXPECT_CALL(connection_, OnSerializedPacket(_));
SendPing();
- EXPECT_EQ(per_packet_options.ecn_codepoint, ecn);
+ EXPECT_EQ(connection_.ecn_codepoint(), ecn);
EXPECT_EQ(writer_->last_ecn_sent(), ecn);
}
}
@@ -17178,26 +17170,22 @@
TEST_P(QuicConnectionTest, RtoDisablesEcnMarking) {
SetQuicReloadableFlag(quic_send_ect1, true);
EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillRepeatedly(Return(true));
- TestPerPacketOptions per_packet_options;
- per_packet_options.ecn_codepoint = ECN_ECT1;
- connection_.set_per_packet_options(&per_packet_options);
+ connection_.set_ecn_codepoint(ECN_ECT1);
QuicPacketCreatorPeer::SetPacketNumber(
QuicConnectionPeer::GetPacketCreator(&connection_), 1);
SendPing();
connection_.OnRetransmissionTimeout();
EXPECT_EQ(writer_->last_ecn_sent(), ECN_NOT_ECT);
- EXPECT_EQ(per_packet_options.ecn_codepoint, ECN_ECT1);
+ EXPECT_EQ(connection_.ecn_codepoint(), ECN_ECT1);
// On 2nd RTO, QUIC abandons ECN.
connection_.OnRetransmissionTimeout();
EXPECT_EQ(writer_->last_ecn_sent(), ECN_NOT_ECT);
- EXPECT_EQ(per_packet_options.ecn_codepoint, ECN_NOT_ECT);
+ EXPECT_EQ(connection_.ecn_codepoint(), ECN_NOT_ECT);
}
TEST_P(QuicConnectionTest, RtoDoesntDisableEcnMarkingIfEcnAcked) {
EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillRepeatedly(Return(true));
- TestPerPacketOptions per_packet_options;
- per_packet_options.ecn_codepoint = ECN_ECT1;
- connection_.set_per_packet_options(&per_packet_options);
+ connection_.set_ecn_codepoint(ECN_ECT1);
QuicPacketCreatorPeer::SetPacketNumber(
QuicConnectionPeer::GetPacketCreator(&connection_), 1);
if (!GetQuicReloadableFlag(quic_send_ect1)) {
@@ -17213,18 +17201,17 @@
QuicEcnCodepoint expected_codepoint =
GetQuicReloadableFlag(quic_send_ect1) ? ECN_ECT1 : ECN_NOT_ECT;
EXPECT_EQ(writer_->last_ecn_sent(), expected_codepoint);
- EXPECT_EQ(per_packet_options.ecn_codepoint, expected_codepoint);
+ EXPECT_EQ(connection_.ecn_codepoint(), expected_codepoint);
connection_.OnRetransmissionTimeout();
EXPECT_EQ(writer_->last_ecn_sent(), expected_codepoint);
- EXPECT_EQ(per_packet_options.ecn_codepoint, expected_codepoint);
+ EXPECT_EQ(connection_.ecn_codepoint(), expected_codepoint);
}
TEST_P(QuicConnectionTest, InvalidFeedbackCancelsEcn) {
+ SetQuicReloadableFlag(quic_send_ect1, true);
EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillRepeatedly(Return(true));
- TestPerPacketOptions per_packet_options;
- per_packet_options.ecn_codepoint = ECN_ECT1;
- connection_.set_per_packet_options(&per_packet_options);
- EXPECT_EQ(per_packet_options.ecn_codepoint, ECN_ECT1);
+ connection_.set_ecn_codepoint(ECN_ECT1);
+ EXPECT_EQ(connection_.ecn_codepoint(), ECN_ECT1);
if (!GetQuicReloadableFlag(quic_send_ect1)) {
EXPECT_QUIC_BUG(connection_.OnInvalidEcnFeedback(),
"Unexpected call to OnInvalidEcnFeedback\\(\\)\\.");
@@ -17232,15 +17219,13 @@
} else {
connection_.OnInvalidEcnFeedback();
}
- EXPECT_EQ(per_packet_options.ecn_codepoint, ECN_NOT_ECT);
+ EXPECT_EQ(connection_.ecn_codepoint(), ECN_NOT_ECT);
}
TEST_P(QuicConnectionTest, StateMatchesSentEcn) {
SetQuicReloadableFlag(quic_send_ect1, true);
EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillRepeatedly(Return(true));
- TestPerPacketOptions per_packet_options;
- per_packet_options.ecn_codepoint = ECN_ECT1;
- connection_.set_per_packet_options(&per_packet_options);
+ connection_.set_ecn_codepoint(ECN_ECT1);
SendPing();
QuicSentPacketManager* sent_packet_manager =
QuicConnectionPeer::GetSentPacketManager(&connection_);
@@ -17256,9 +17241,7 @@
}
SetQuicReloadableFlag(quic_send_ect1, true);
EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillRepeatedly(Return(true));
- TestPerPacketOptions per_packet_options;
- per_packet_options.ecn_codepoint = ECN_ECT1;
- connection_.set_per_packet_options(&per_packet_options);
+ connection_.set_ecn_codepoint(ECN_ECT1);
// All these steps are necessary to send an INITIAL ping and save it to be
// coalesced, instead of just calling SendPing() and sending it immediately.
char buffer[1000];
@@ -17272,7 +17255,7 @@
creator_->set_encryption_level(ENCRYPTION_FORWARD_SECURE);
EXPECT_CALL(*send_algorithm_, SupportsECT0()).WillRepeatedly(Return(true));
// If not for the line below, these packets would coalesce.
- per_packet_options.ecn_codepoint = ECN_ECT0;
+ connection_.set_ecn_codepoint(ECN_ECT0);
EXPECT_EQ(writer_->packets_write_attempts(), 0);
SendPing();
EXPECT_EQ(writer_->packets_write_attempts(), 2);
@@ -17282,14 +17265,12 @@
TEST_P(QuicConnectionTest, BufferedPacketRetainsOldEcn) {
SetQuicReloadableFlag(quic_send_ect1, true);
EXPECT_CALL(*send_algorithm_, SupportsECT1()).WillRepeatedly(Return(true));
- TestPerPacketOptions per_packet_options;
- per_packet_options.ecn_codepoint = ECN_ECT1;
- connection_.set_per_packet_options(&per_packet_options);
+ connection_.set_ecn_codepoint(ECN_ECT1);
writer_->SetWriteBlocked();
EXPECT_CALL(visitor_, OnWriteBlocked()).Times(2);
SendPing();
EXPECT_CALL(*send_algorithm_, SupportsECT0()).WillRepeatedly(Return(true));
- per_packet_options.ecn_codepoint = ECN_ECT0;
+ connection_.set_ecn_codepoint(ECN_ECT0);
writer_->SetWritable();
connection_.OnCanWrite();
EXPECT_EQ(writer_->last_ecn_sent(), ECN_ECT1);
diff --git a/quiche/quic/core/quic_crypto_stream_test.cc b/quiche/quic/core/quic_crypto_stream_test.cc
index 76f840b..70928ae 100644
--- a/quiche/quic/core/quic_crypto_stream_test.cc
+++ b/quiche/quic/core/quic_crypto_stream_test.cc
@@ -133,7 +133,7 @@
Perspective::IS_CLIENT)),
session_(connection_, /*create_mock_crypto_stream=*/false) {
EXPECT_CALL(*static_cast<MockPacketWriter*>(connection_->writer()),
- WritePacket(_, _, _, _, _))
+ WritePacket(_, _, _, _, _, _))
.WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 0)));
stream_ = new MockQuicCryptoStream(&session_);
session_.SetCryptoStream(stream_);
diff --git a/quiche/quic/core/quic_default_packet_writer.cc b/quiche/quic/core/quic_default_packet_writer.cc
index 7eac827..6d45217 100644
--- a/quiche/quic/core/quic_default_packet_writer.cc
+++ b/quiche/quic/core/quic_default_packet_writer.cc
@@ -15,14 +15,13 @@
WriteResult QuicDefaultPacketWriter::WritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions* options) {
+ const QuicSocketAddress& peer_address, PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& params) {
QUICHE_DCHECK(!write_blocked_);
QuicUdpPacketInfo packet_info;
packet_info.SetPeerAddress(peer_address);
packet_info.SetSelfIp(self_address);
- if (options != nullptr) {
- packet_info.SetEcnCodepoint(options->ecn_codepoint);
- }
+ packet_info.SetEcnCodepoint(params.ecn_codepoint);
WriteResult result =
QuicUdpSocketApi().WritePacket(fd_, buffer, buf_len, packet_info);
if (IsWriteBlockedStatus(result.status)) {
diff --git a/quiche/quic/core/quic_default_packet_writer.h b/quiche/quic/core/quic_default_packet_writer.h
index 718f8eb..c513362 100644
--- a/quiche/quic/core/quic_default_packet_writer.h
+++ b/quiche/quic/core/quic_default_packet_writer.h
@@ -28,7 +28,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
bool IsWriteBlocked() const override;
void SetWritable() override;
absl::optional<int> MessageTooBigErrorCode() const override;
diff --git a/quiche/quic/core/quic_dispatcher_test.cc b/quiche/quic/core/quic_dispatcher_test.cc
index ff2516a..37d6185 100644
--- a/quiche/quic/core/quic_dispatcher_test.cc
+++ b/quiche/quic/core/quic_dispatcher_test.cc
@@ -1544,7 +1544,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& /*self_client_address*/,
const QuicSocketAddress& /*peer_client_address*/,
- PerPacketOptions* /*options*/) override {
+ PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& /*params*/) override {
packets_.push_back(
QuicEncryptedPacket(buffer, buf_len, /*owns_buffer=*/false).Clone());
return WriteResult(WRITE_STATUS_OK, buf_len);
@@ -1877,7 +1878,8 @@
WriteResult WritePacket(const char* /*buffer*/, size_t /*buf_len*/,
const QuicIpAddress& /*self_client_address*/,
const QuicSocketAddress& /*peer_client_address*/,
- PerPacketOptions* /*options*/) override {
+ PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& /*params*/) override {
// It would be quite possible to actually implement this method here with
// the fake blocked status, but it would be significantly more work in
// Chromium, and since it's not called anyway, don't bother.
diff --git a/quiche/quic/core/quic_linux_socket_utils.h b/quiche/quic/core/quic_linux_socket_utils.h
index de80dfd..8d53e47 100644
--- a/quiche/quic/core/quic_linux_socket_utils.h
+++ b/quiche/quic/core/quic_linux_socket_utils.h
@@ -109,18 +109,19 @@
const QuicSocketAddress& peer_address)
: BufferedWrite(buffer, buf_len, self_address, peer_address,
std::unique_ptr<PerPacketOptions>(),
- /*release_time=*/0) {}
+ QuicPacketWriterParams(), /*release_time=*/0) {}
BufferedWrite(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
std::unique_ptr<PerPacketOptions> options,
- uint64_t release_time)
+ const QuicPacketWriterParams& params, uint64_t release_time)
: buffer(buffer),
buf_len(buf_len),
self_address(self_address),
peer_address(peer_address),
options(std::move(options)),
+ params(params),
release_time(release_time) {}
const char* buffer; // Not owned.
@@ -128,6 +129,7 @@
QuicIpAddress self_address;
QuicSocketAddress peer_address;
std::unique_ptr<PerPacketOptions> options;
+ QuicPacketWriterParams params;
// The release time according to the owning packet writer's clock, which is
// often not a QuicClock. Calculated from packet writer's Now() and the
diff --git a/quiche/quic/core/quic_packet_writer.h b/quiche/quic/core/quic_packet_writer.h
index 3e6cb21..c3b3fab 100644
--- a/quiche/quic/core/quic_packet_writer.h
+++ b/quiche/quic/core/quic_packet_writer.h
@@ -18,7 +18,11 @@
struct WriteResult;
-struct QUIC_EXPORT_PRIVATE PerPacketOptions {
+// This class allows a platform to pass instructions to an associated child of
+// QuicWriter without intervening QUIC code understanding anything about its
+// contents.
+class QUIC_EXPORT_PRIVATE PerPacketOptions {
+ public:
virtual ~PerPacketOptions() {}
// Returns a heap-allocated copy of |this|.
@@ -29,7 +33,10 @@
// This method is declared pure virtual in order to ensure the subclasses
// would not forget to override it.
virtual std::unique_ptr<PerPacketOptions> Clone() const = 0;
+};
+// The owner of QuicPacketWriter can pass control information via this struct.
+struct QUIC_EXPORT_PRIVATE QuicPacketWriterParams {
// Specifies ideal release time delay for this packet.
QuicTime::Delta release_time_delay = QuicTime::Delta::Zero();
// Whether it is allowed to send this packet without |release_time_delay|.
@@ -107,7 +114,8 @@
virtual WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) = 0;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) = 0;
// Returns true if the network socket is not writable.
virtual bool IsWriteBlocked() const = 0;
diff --git a/quiche/quic/core/quic_packet_writer_wrapper.cc b/quiche/quic/core/quic_packet_writer_wrapper.cc
index c040c91..c3b4b28 100644
--- a/quiche/quic/core/quic_packet_writer_wrapper.cc
+++ b/quiche/quic/core/quic_packet_writer_wrapper.cc
@@ -14,9 +14,10 @@
WriteResult QuicPacketWriterWrapper::WritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions* options) {
+ const QuicSocketAddress& peer_address, PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
return writer_->WritePacket(buffer, buf_len, self_address, peer_address,
- options);
+ options, params);
}
bool QuicPacketWriterWrapper::IsWriteBlocked() const {
diff --git a/quiche/quic/core/quic_packet_writer_wrapper.h b/quiche/quic/core/quic_packet_writer_wrapper.h
index 3afeaf1..7d43fdc 100644
--- a/quiche/quic/core/quic_packet_writer_wrapper.h
+++ b/quiche/quic/core/quic_packet_writer_wrapper.h
@@ -27,7 +27,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
bool IsWriteBlocked() const override;
void SetWritable() override;
absl::optional<int> MessageTooBigErrorCode() const override;
diff --git a/quiche/quic/core/quic_path_validator.cc b/quiche/quic/core/quic_path_validator.cc
index 48c21d2..3185664 100644
--- a/quiche/quic/core/quic_path_validator.cc
+++ b/quiche/quic/core/quic_path_validator.cc
@@ -169,7 +169,7 @@
<< path_context_->peer_address();
path_context_->WriterToUse()->WritePacket(
buffer, buf_len, path_context_->self_address().host(),
- path_context_->peer_address(), nullptr);
+ path_context_->peer_address(), nullptr, QuicPacketWriterParams());
}
} // namespace quic
diff --git a/quiche/quic/core/quic_session_test.cc b/quiche/quic/core/quic_session_test.cc
index bdf74b3..9bcbf71 100644
--- a/quiche/quic/core/quic_session_test.cc
+++ b/quiche/quic/core/quic_session_test.cc
@@ -1170,7 +1170,7 @@
// Expect that we only send one packet, the writes from different streams
// should be bundled together.
- EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _));
EXPECT_CALL(*send_algorithm, OnApplicationLimited(_));
@@ -1238,7 +1238,7 @@
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true));
- EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _, _)).Times(0);
TestStream* stream2 = session_.CreateOutgoingBidirectionalStream();
@@ -1415,7 +1415,7 @@
connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
- EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
EXPECT_CALL(*connection_, SendControlFrame(_))
@@ -1471,7 +1471,7 @@
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
- EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _))
+ EXPECT_CALL(*writer, WritePacket(_, _, _, new_peer_address, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
EXPECT_CALL(*connection_, SendConnectivityProbingPacket(_, _))
@@ -3123,7 +3123,7 @@
CompleteHandshake();
MockPacketWriter* writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(session_.connection()));
- EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
// Set a small connection level flow control limit.
const uint64_t kWindow = 36;
diff --git a/quiche/quic/core/quic_time_wait_list_manager.cc b/quiche/quic/core/quic_time_wait_list_manager.cc
index d479973..484d35e 100644
--- a/quiche/quic/core/quic_time_wait_list_manager.cc
+++ b/quiche/quic/core/quic_time_wait_list_manager.cc
@@ -377,7 +377,7 @@
WriteResult result = writer_->WritePacket(
queued_packet->packet()->data(), queued_packet->packet()->length(),
queued_packet->self_address().host(), queued_packet->peer_address(),
- nullptr);
+ nullptr, QuicPacketWriterParams());
// If using a batch writer and the packet is buffered, flush it.
if (writer_->IsBatchMode() && result.status == WRITE_STATUS_OK &&
diff --git a/quiche/quic/core/quic_time_wait_list_manager_test.cc b/quiche/quic/core/quic_time_wait_list_manager_test.cc
index eef0b99..9b2f36f 100644
--- a/quiche/quic/core/quic_time_wait_list_manager_test.cc
+++ b/quiche/quic/core/quic_time_wait_list_manager_test.cc
@@ -236,7 +236,7 @@
connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/false,
/*use_length_prefix=*/false, AllSupportedVersions()));
EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
+ peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
time_wait_list_manager_.SendVersionNegotiationPacket(
@@ -253,7 +253,7 @@
connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
/*use_length_prefix=*/false, AllSupportedVersions()));
EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
+ peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
time_wait_list_manager_.SendVersionNegotiationPacket(
@@ -269,7 +269,7 @@
connection_id_, EmptyQuicConnectionId(), /*ietf_quic=*/true,
/*use_length_prefix=*/true, AllSupportedVersions()));
EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
+ peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
time_wait_list_manager_.SendVersionNegotiationPacket(
@@ -286,7 +286,7 @@
connection_id_, TestConnectionId(0x33), /*ietf_quic=*/true,
/*use_length_prefix=*/true, AllSupportedVersions()));
EXPECT_CALL(writer_, WritePacket(_, packet->length(), self_address_.host(),
- peer_address_, _))
+ peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
time_wait_list_manager_.SendVersionNegotiationPacket(
@@ -307,7 +307,7 @@
QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
&termination_packets);
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
+ self_address_.host(), peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
ProcessPacket(connection_id_);
@@ -327,7 +327,7 @@
QuicTimeWaitListManager::SEND_CONNECTION_CLOSE_PACKETS,
&termination_packets);
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
+ self_address_.host(), peer_address_, _, _))
.Times(2)
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
@@ -339,7 +339,7 @@
AddConnectionId(connection_id_,
QuicTimeWaitListManager::SEND_STATELESS_RESET);
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
@@ -353,7 +353,7 @@
EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
for (int packet_number = 1; packet_number < 101; ++packet_number) {
if ((packet_number & (packet_number - 1)) == 0) {
- EXPECT_CALL(writer_, WritePacket(_, _, _, _, _))
+ EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
}
ProcessPacket(connection_id_);
@@ -373,7 +373,7 @@
AddStatelessConnectionId(connection_id_);
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
ProcessPacket(connection_id_);
@@ -468,14 +468,14 @@
connection_id, EmptyQuicConnectionId(), /*packet_number=*/234));
// Let first write through.
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.With(Args<0, 1>(PublicResetPacketEq(connection_id)))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
ProcessPacket(connection_id);
// write block for the next packet.
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.With(Args<0, 1>(PublicResetPacketEq(connection_id)))
.WillOnce(DoAll(Assign(&writer_is_blocked_, true),
Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
@@ -492,7 +492,7 @@
QuicTimeWaitListManager::SEND_STATELESS_RESET);
std::unique_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
other_connection_id, EmptyQuicConnectionId(), /*packet_number=*/23423));
- EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0);
+ EXPECT_CALL(writer_, WritePacket(_, _, _, _, _, _)).Times(0);
EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
ProcessPacket(other_connection_id);
EXPECT_EQ(2u, time_wait_list_manager_.num_connections());
@@ -500,11 +500,11 @@
// Now expect all the write blocked public reset packets to be sent again.
writer_is_blocked_ = false;
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.With(Args<0, 1>(PublicResetPacketEq(connection_id)))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.With(Args<0, 1>(PublicResetPacketEq(other_connection_id)))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, packet->length())));
time_wait_list_manager_.OnBlockedWriterCanWrite();
@@ -527,7 +527,7 @@
EXPECT_EQ(1u, time_wait_list_manager_.num_connections());
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
+ self_address_.host(), peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
ProcessPacket(connection_id_);
@@ -653,7 +653,7 @@
// Termination packet is not encrypted, instead, send stateless reset.
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.With(Args<0, 1>(PublicResetPacketEq(connection_id_)))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0)));
// Processes IETF short header packet.
@@ -677,7 +677,7 @@
TimeWaitConnectionInfo(/*ietf_quic=*/true, &termination_packets,
{connection_id_}));
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
+ self_address_.host(), peer_address_, _, _))
.WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1)));
// Processes IETF short header packet.
@@ -707,7 +707,7 @@
active_connection_ids, QuicTime::Delta::Zero()));
EXPECT_CALL(writer_, WritePacket(_, kConnectionCloseLength,
- self_address_.host(), peer_address_, _))
+ self_address_.host(), peer_address_, _, _))
.Times(2)
.WillRepeatedly(Return(WriteResult(WRITE_STATUS_OK, 1)));
// Processes IETF short header packet.
@@ -743,7 +743,7 @@
.Times(testing::AnyNumber());
// Write block for the next packets.
EXPECT_CALL(writer_,
- WritePacket(_, _, self_address_.host(), peer_address_, _))
+ WritePacket(_, _, self_address_.host(), peer_address_, _, _))
.With(Args<0, 1>(PublicResetPacketEq(TestConnectionId(1))))
.WillOnce(DoAll(Assign(&writer_is_blocked_, true),
Return(WriteResult(WRITE_STATUS_BLOCKED, EAGAIN))));
diff --git a/quiche/quic/masque/masque_encapsulated_client.cc b/quiche/quic/masque/masque_encapsulated_client.cc
index d384363..34adde4 100644
--- a/quiche/quic/masque/masque_encapsulated_client.cc
+++ b/quiche/quic/masque/masque_encapsulated_client.cc
@@ -78,7 +78,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& /*self_address*/,
const QuicSocketAddress& peer_address,
- PerPacketOptions* /*options*/) override {
+ PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& /*params*/) override {
QUICHE_DCHECK(peer_address.IsInitialized());
QUIC_DVLOG(1) << "MasquePacketWriter trying to write " << buf_len
<< " bytes to " << peer_address;
diff --git a/quiche/quic/qbone/qbone_session_test.cc b/quiche/quic/qbone/qbone_session_test.cc
index 1a9d023..ab92c1c 100644
--- a/quiche/quic/qbone/qbone_session_test.cc
+++ b/quiche/quic/qbone/qbone_session_test.cc
@@ -355,11 +355,12 @@
// Hook everything up!
MockPacketWriter* client_writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(client_peer_->connection()));
- ON_CALL(*client_writer, WritePacket(_, _, _, _, _))
+ ON_CALL(*client_writer, WritePacket(_, _, _, _, _, _))
.WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
+ PerPacketOptions* option,
+ const QuicPacketWriterParams& params) {
char* copy = new char[1024 * 1024];
memcpy(copy, buffer, buf_len);
runner_.Schedule([this, copy, buf_len] {
@@ -373,11 +374,12 @@
}));
MockPacketWriter* server_writer = static_cast<MockPacketWriter*>(
QuicConnectionPeer::GetWriter(server_peer_->connection()));
- ON_CALL(*server_writer, WritePacket(_, _, _, _, _))
+ ON_CALL(*server_writer, WritePacket(_, _, _, _, _, _))
.WillByDefault(Invoke([this](const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
char* copy = new char[1024 * 1024];
memcpy(copy, buffer, buf_len);
runner_.Schedule([this, copy, buf_len] {
diff --git a/quiche/quic/qbone/qbone_stream_test.cc b/quiche/quic/qbone/qbone_stream_test.cc
index b7cc198..16052bc 100644
--- a/quiche/quic/qbone/qbone_stream_test.cc
+++ b/quiche/quic/qbone/qbone_stream_test.cc
@@ -101,7 +101,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override {
return WriteResult(WRITE_STATUS_ERROR, 0);
}
diff --git a/quiche/quic/test_tools/bad_packet_writer.cc b/quiche/quic/test_tools/bad_packet_writer.cc
index 1e146c4..7961fe8 100644
--- a/quiche/quic/test_tools/bad_packet_writer.cc
+++ b/quiche/quic/test_tools/bad_packet_writer.cc
@@ -17,13 +17,14 @@
WriteResult BadPacketWriter::WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
if (error_code_ == 0 || packet_causing_write_error_ > 0) {
if (packet_causing_write_error_ > 0) {
--packet_causing_write_error_;
}
return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
+ peer_address, options, params);
}
// It's time to cause write error.
int error_code = error_code_;
diff --git a/quiche/quic/test_tools/bad_packet_writer.h b/quiche/quic/test_tools/bad_packet_writer.h
index bcf12f5..5f3da24 100644
--- a/quiche/quic/test_tools/bad_packet_writer.h
+++ b/quiche/quic/test_tools/bad_packet_writer.h
@@ -21,7 +21,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
private:
size_t packet_causing_write_error_;
diff --git a/quiche/quic/test_tools/first_flight.cc b/quiche/quic/test_tools/first_flight.cc
index dcdeac3..a0b93fb 100644
--- a/quiche/quic/test_tools/first_flight.cc
+++ b/quiche/quic/test_tools/first_flight.cc
@@ -75,11 +75,14 @@
void OnDelegatedPacket(const char* buffer, size_t buf_len,
const QuicIpAddress& /*self_client_address*/,
const QuicSocketAddress& /*peer_client_address*/,
- PerPacketOptions* /*options*/) override {
+ PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& params) override {
packets_.emplace_back(
QuicReceivedPacket(buffer, buf_len,
connection_helper_.GetClock()->ApproximateNow(),
- /*owns_buffer=*/false)
+ /*owns_buffer=*/false, /*ttl=*/0, /*ttl_valid=*/true,
+ /*packet_headers=*/nullptr, /*headers_length=*/0,
+ /*owns_header_buffer=*/false, params.ecn_codepoint)
.Clone());
}
diff --git a/quiche/quic/test_tools/first_flight.h b/quiche/quic/test_tools/first_flight.h
index 3896031..948511a 100644
--- a/quiche/quic/test_tools/first_flight.h
+++ b/quiche/quic/test_tools/first_flight.h
@@ -31,7 +31,8 @@
virtual void OnDelegatedPacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_client_address,
const QuicSocketAddress& peer_client_address,
- PerPacketOptions* options) = 0;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) = 0;
};
// |delegate| MUST be valid for the duration of the DelegatedPacketWriter's
@@ -62,9 +63,10 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_client_address,
const QuicSocketAddress& peer_client_address,
- PerPacketOptions* options) override {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override {
delegate_->OnDelegatedPacket(buffer, buf_len, self_client_address,
- peer_client_address, options);
+ peer_client_address, options, params);
return WriteResult(WRITE_STATUS_OK, buf_len);
}
diff --git a/quiche/quic/test_tools/limited_mtu_test_writer.cc b/quiche/quic/test_tools/limited_mtu_test_writer.cc
index fa46be1..8f9bc1c 100644
--- a/quiche/quic/test_tools/limited_mtu_test_writer.cc
+++ b/quiche/quic/test_tools/limited_mtu_test_writer.cc
@@ -13,14 +13,15 @@
WriteResult LimitedMtuTestWriter::WritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions* options) {
+ const QuicSocketAddress& peer_address, PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
if (buf_len > mtu_) {
// Drop the packet.
return WriteResult(WRITE_STATUS_OK, buf_len);
}
return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
+ peer_address, options, params);
}
} // namespace test
diff --git a/quiche/quic/test_tools/limited_mtu_test_writer.h b/quiche/quic/test_tools/limited_mtu_test_writer.h
index 96cc828..e046872 100644
--- a/quiche/quic/test_tools/limited_mtu_test_writer.h
+++ b/quiche/quic/test_tools/limited_mtu_test_writer.h
@@ -24,7 +24,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
private:
QuicByteCount mtu_;
diff --git a/quiche/quic/test_tools/packet_dropping_test_writer.cc b/quiche/quic/test_tools/packet_dropping_test_writer.cc
index 69aae14..ac9625f 100644
--- a/quiche/quic/test_tools/packet_dropping_test_writer.cc
+++ b/quiche/quic/test_tools/packet_dropping_test_writer.cc
@@ -88,7 +88,8 @@
WriteResult PacketDroppingTestWriter::WritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions* options) {
+ const QuicSocketAddress& peer_address, PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
++num_calls_to_write_;
ReleaseOldPackets();
@@ -157,7 +158,7 @@
}
delayed_packets_.push_back(
DelayedWrite(buffer, buf_len, self_address, peer_address,
- std::move(delayed_options), send_time));
+ std::move(delayed_options), params, send_time));
cur_buffer_size_ += buf_len;
// Set the alarm if it's not yet set.
@@ -169,7 +170,7 @@
}
return QuicPacketWriterWrapper::WritePacket(buffer, buf_len, self_address,
- peer_address, options);
+ peer_address, options, params);
}
bool PacketDroppingTestWriter::IsWriteBlocked() const {
@@ -207,7 +208,7 @@
// Grab the next one off the queue and send it.
QuicPacketWriterWrapper::WritePacket(
iter->buffer.data(), iter->buffer.length(), iter->self_address,
- iter->peer_address, iter->options.get());
+ iter->peer_address, iter->options.get(), iter->params);
QUICHE_DCHECK_GE(cur_buffer_size_, iter->buffer.length());
cur_buffer_size_ -= iter->buffer.length();
delayed_packets_.erase(iter);
@@ -239,11 +240,13 @@
PacketDroppingTestWriter::DelayedWrite::DelayedWrite(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- std::unique_ptr<PerPacketOptions> options, QuicTime send_time)
+ std::unique_ptr<PerPacketOptions> options,
+ const QuicPacketWriterParams& params, QuicTime send_time)
: buffer(buffer, buf_len),
self_address(self_address),
peer_address(peer_address),
options(std::move(options)),
+ params(params),
send_time(send_time) {}
PacketDroppingTestWriter::DelayedWrite::~DelayedWrite() = default;
diff --git a/quiche/quic/test_tools/packet_dropping_test_writer.h b/quiche/quic/test_tools/packet_dropping_test_writer.h
index a7e91d3..dd83cb3 100644
--- a/quiche/quic/test_tools/packet_dropping_test_writer.h
+++ b/quiche/quic/test_tools/packet_dropping_test_writer.h
@@ -49,7 +49,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
bool IsWriteBlocked() const override;
@@ -142,7 +143,8 @@
DelayedWrite(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- std::unique_ptr<PerPacketOptions> options, QuicTime send_time);
+ std::unique_ptr<PerPacketOptions> options,
+ const QuicPacketWriterParams& params, QuicTime send_time);
DelayedWrite(const DelayedWrite&) = delete;
DelayedWrite(DelayedWrite&&) = default;
DelayedWrite& operator=(const DelayedWrite&) = delete;
@@ -153,6 +155,7 @@
QuicIpAddress self_address;
QuicSocketAddress peer_address;
std::unique_ptr<PerPacketOptions> options;
+ QuicPacketWriterParams params;
QuicTime send_time;
};
diff --git a/quiche/quic/test_tools/packet_reordering_writer.cc b/quiche/quic/test_tools/packet_reordering_writer.cc
index 8eb8573..12ff9b4 100644
--- a/quiche/quic/test_tools/packet_reordering_writer.cc
+++ b/quiche/quic/test_tools/packet_reordering_writer.cc
@@ -13,18 +13,19 @@
WriteResult PacketReorderingWriter::WritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions* options) {
+ const QuicSocketAddress& peer_address, PerPacketOptions* options,
+ const QuicPacketWriterParams& params) {
if (!delay_next_) {
QUIC_VLOG(2) << "Writing a non-delayed packet";
WriteResult wr = QuicPacketWriterWrapper::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
+ buffer, buf_len, self_address, peer_address, options, params);
--num_packets_to_wait_;
if (num_packets_to_wait_ == 0) {
QUIC_VLOG(2) << "Writing a delayed packet";
// It's time to write the delayed packet.
QuicPacketWriterWrapper::WritePacket(
delayed_data_.data(), delayed_data_.length(), delayed_self_address_,
- delayed_peer_address_, delayed_options_.get());
+ delayed_peer_address_, delayed_options_.get(), delayed_params_);
}
return wr;
}
@@ -37,6 +38,7 @@
if (options != nullptr) {
delayed_options_ = options->Clone();
}
+ delayed_params_ = params;
delay_next_ = false;
return WriteResult(WRITE_STATUS_OK, buf_len);
}
diff --git a/quiche/quic/test_tools/packet_reordering_writer.h b/quiche/quic/test_tools/packet_reordering_writer.h
index 53204c5..fb77c0d 100644
--- a/quiche/quic/test_tools/packet_reordering_writer.h
+++ b/quiche/quic/test_tools/packet_reordering_writer.h
@@ -5,6 +5,7 @@
#ifndef QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
#define QUICHE_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
+#include "quiche/quic/core/quic_packet_writer.h"
#include "quiche/quic/core/quic_packet_writer_wrapper.h"
namespace quic {
@@ -25,7 +26,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
void SetDelay(size_t num_packets_to_wait);
@@ -36,6 +38,7 @@
QuicIpAddress delayed_self_address_;
QuicSocketAddress delayed_peer_address_;
std::unique_ptr<PerPacketOptions> delayed_options_;
+ QuicPacketWriterParams delayed_params_;
};
} // namespace test
diff --git a/quiche/quic/test_tools/quic_test_utils.cc b/quiche/quic/test_tools/quic_test_utils.cc
index e622ed8..e04f0ca 100644
--- a/quiche/quic/test_tools/quic_test_utils.cc
+++ b/quiche/quic/test_tools/quic_test_utils.cc
@@ -1301,10 +1301,10 @@
}
}
-WriteResult TestPacketWriter::WritePacket(const char* buffer, size_t buf_len,
- const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address,
- PerPacketOptions* options) {
+WriteResult TestPacketWriter::WritePacket(
+ const char* buffer, size_t buf_len, const QuicIpAddress& self_address,
+ const QuicSocketAddress& peer_address, PerPacketOptions* /*options*/,
+ const QuicPacketWriterParams& params) {
last_write_source_address_ = self_address;
last_write_peer_address_ = peer_address;
// If the buffer is allocated from the pool, return it back to the pool.
@@ -1377,7 +1377,7 @@
bytes_buffered_ += last_packet_size_;
return WriteResult(WRITE_STATUS_OK, 0);
}
- last_ecn_sent_ = (options == nullptr) ? ECN_NOT_ECT : options->ecn_codepoint;
+ last_ecn_sent_ = params.ecn_codepoint;
return WriteResult(WRITE_STATUS_OK, last_packet_size_);
}
diff --git a/quiche/quic/test_tools/quic_test_utils.h b/quiche/quic/test_tools/quic_test_utils.h
index 7b5667a..e368259 100644
--- a/quiche/quic/test_tools/quic_test_utils.h
+++ b/quiche/quic/test_tools/quic_test_utils.h
@@ -1185,7 +1185,8 @@
MOCK_METHOD(WriteResult, WritePacket,
(const char*, size_t buf_len, const QuicIpAddress& self_address,
- const QuicSocketAddress& peer_address, PerPacketOptions*),
+ const QuicSocketAddress& peer_address, PerPacketOptions*,
+ const QuicPacketWriterParams&),
(override));
MOCK_METHOD(bool, IsWriteBlocked, (), (const, override));
MOCK_METHOD(void, SetWritable, (), (override));
@@ -1832,7 +1833,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
bool ShouldWriteFail() { return write_should_fail_; }
@@ -2177,13 +2179,6 @@
return result;
}
-struct TestPerPacketOptions : PerPacketOptions {
- public:
- std::unique_ptr<quic::PerPacketOptions> Clone() const override {
- return std::make_unique<TestPerPacketOptions>(*this);
- }
-};
-
} // namespace test
} // namespace quic
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint_base.cc b/quiche/quic/test_tools/simulator/quic_endpoint_base.cc
index d466c96..3ff517a 100644
--- a/quiche/quic/test_tools/simulator/quic_endpoint_base.cc
+++ b/quiche/quic/test_tools/simulator/quic_endpoint_base.cc
@@ -122,7 +122,8 @@
WriteResult QuicEndpointBase::Writer::WritePacket(
const char* buffer, size_t buf_len, const QuicIpAddress& /*self_address*/,
- const QuicSocketAddress& /*peer_address*/, PerPacketOptions* options) {
+ const QuicSocketAddress& /*peer_address*/, PerPacketOptions* options,
+ const QuicPacketWriterParams& /*params*/) {
QUICHE_DCHECK(!IsWriteBlocked());
QUICHE_DCHECK(options == nullptr);
QUICHE_DCHECK(buf_len <= kMaxOutgoingPacketSize);
diff --git a/quiche/quic/test_tools/simulator/quic_endpoint_base.h b/quiche/quic/test_tools/simulator/quic_endpoint_base.h
index 540b285..c734b81 100644
--- a/quiche/quic/test_tools/simulator/quic_endpoint_base.h
+++ b/quiche/quic/test_tools/simulator/quic_endpoint_base.h
@@ -79,7 +79,8 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override;
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override;
bool IsWriteBlocked() const override;
void SetWritable() override;
absl::optional<int> MessageTooBigErrorCode() const override;
diff --git a/quiche/quic/tools/quic_client_default_network_helper.cc b/quiche/quic/tools/quic_client_default_network_helper.cc
index 424b8b9..9c1e4e5 100644
--- a/quiche/quic/tools/quic_client_default_network_helper.cc
+++ b/quiche/quic/tools/quic_client_default_network_helper.cc
@@ -30,9 +30,10 @@
WriteResult WritePacket(const char* buffer, size_t buf_len,
const QuicIpAddress& self_address,
const QuicSocketAddress& peer_address,
- PerPacketOptions* options) override {
+ PerPacketOptions* options,
+ const QuicPacketWriterParams& params) override {
WriteResult result = QuicDefaultPacketWriter::WritePacket(
- buffer, buf_len, self_address, peer_address, options);
+ buffer, buf_len, self_address, peer_address, options, params);
if (IsWriteBlockedStatus(result.status)) {
bool success = event_loop_->RearmSocket(fd(), kSocketEventWritable);
QUICHE_DCHECK(success);