Skip to content

Commit

Permalink
Client-side ECN reporting
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Duke <martin.h.duke@gmail.com>
  • Loading branch information
martinduke committed May 7, 2024
1 parent b04f634 commit 3bd54c6
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
1 change: 0 additions & 1 deletion source/common/network/io_socket_handle_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ Api::IoCallUint64Result IoSocketHandleImpl::recvmsg(Buffer::RawSlice* slices,
// Get overflow, local address and gso_size from control message.
for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr); cmsg != nullptr;
cmsg = CMSG_NXTHDR(&hdr, cmsg)) {

if (output.msg_[0].local_address_ == nullptr) {
Address::InstanceConstSharedPtr addr = maybeGetDstAddressFromHeader(
*cmsg, self_port, fd_, socket_v6only_ || !udp_read_normalize_addresses_);
Expand Down
9 changes: 9 additions & 0 deletions source/common/network/utility.cc
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,7 @@ void passPayloadToProcessor(uint64_t bytes_read, Buffer::InstancePtr buffer,
peer_addess->asString(),
(local_address == nullptr ? "unknown" : local_address->asString()),
bytes_read));
printf("mhd calling udp_packet_processor.processPacket %u\n", tos);
udp_packet_processor.processPacket(std::move(local_address), std::move(peer_addess),
std::move(buffer), receive_time, tos);
}
Expand All @@ -627,6 +628,7 @@ Api::IoCallUint64Result readFromSocketRecvGro(IoHandle& handle,

Api::IoCallUint64Result result =
receiveMessage(max_rx_datagram_size_with_gro, buffer, output, handle, local_address);
printf("mhd readFromSocketRecvGro tos %u\n", output.msg_[0].tos_);

if (!result.ok() || output.msg_[0].truncated_and_dropped_) {
return result;
Expand All @@ -640,6 +642,7 @@ Api::IoCallUint64Result readFromSocketRecvGro(IoHandle& handle,
if (num_packets_read != nullptr) {
*num_packets_read += 1;
}
printf("mhd passing 1\n");
passPayloadToProcessor(result.return_value_, std::move(buffer),
std::move(output.msg_[0].peer_address_),
std::move(output.msg_[0].local_address_), udp_packet_processor,
Expand All @@ -657,6 +660,7 @@ Api::IoCallUint64Result readFromSocketRecvGro(IoHandle& handle,
if (num_packets_read != nullptr) {
*num_packets_read += 1;
}
printf("mhd passing 2\n");
passPayloadToProcessor(bytes_to_copy, std::move(sub_buffer), output.msg_[0].peer_address_,
output.msg_[0].local_address_, udp_packet_processor, receive_time,
output.msg_[0].tos_);
Expand Down Expand Up @@ -743,6 +747,7 @@ Api::IoCallUint64Result readFromSocketRecvMsg(IoHandle& handle,
ENVOY_LOG_MISC(trace, "starting recvmsg with max={}", udp_packet_processor.maxDatagramSize());
Api::IoCallUint64Result result =
receiveMessage(udp_packet_processor.maxDatagramSize(), buffer, output, handle, local_address);
printf("mhd readFromSocketRecvMsg tos %u\n", output.msg_[0].tos_);

if (!result.ok() || output.msg_[0].truncated_and_dropped_) {
return result;
Expand All @@ -767,13 +772,17 @@ Utility::readFromSocket(IoHandle& handle, const Address::Instance& local_address
UdpPacketProcessor& udp_packet_processor, MonotonicTime receive_time,
UdpRecvMsgMethod recv_msg_method, uint32_t* packets_dropped,
uint32_t* num_packets_read) {
printf("mhd readFromSocket\n");
if (recv_msg_method == UdpRecvMsgMethod::RecvMsgWithGro) {
printf("mhd Gro\n");
return readFromSocketRecvGro(handle, local_address, udp_packet_processor, receive_time,
packets_dropped, num_packets_read);
} else if (recv_msg_method == UdpRecvMsgMethod::RecvMmsg) {
printf("mhd recvmmmsg");
return readFromSocketRecvMmsg(handle, local_address, udp_packet_processor, receive_time,
packets_dropped, num_packets_read);
}
printf("mhd recvmsg");
return readFromSocketRecvMsg(handle, local_address, udp_packet_processor, receive_time,
packets_dropped, num_packets_read);
}
Expand Down
32 changes: 32 additions & 0 deletions test/common/quic/envoy_quic_client_session_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,39 @@ TEST_P(EnvoyQuicClientSessionTest, EcnReporting) {
rv = peer_socket_->setSocketOption(IPPROTO_IP, IP_TOS, &optval, sizeof(optval));
}
EXPECT_EQ(rv.return_value_, 0);
// This test uses ConstructEncryptedPacket() to build an ECN-marked server
// response. Unfortunately, that function uses the packet's destination
// connection ID regardless of whether it is a client or server packet. By
// setting the connection IDs to be the same, the keys will be correct.
quic_connection_->set_client_connection_id(quic_connection_->connection_id());
envoy_quic_session_->connect();
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);

// The first six bytes of a server hello, which is enough for the client to
// process the packet successfully.
char server_hello[] = { 0x02, 0x00, 0x00, 0x56, 0x03, 0x03, };
quic::QuicEncryptedPacket *packet = quic::test::ConstructEncryptedPacket(
quic_connection_->client_connection_id(), quic_connection_->connection_id(),
/*version_flag=*/true, /*reset_flag=*/false, /*packet_number=*/1,
std::string(server_hello, sizeof(server_hello)), /*full_padding=*/false,
quic::CONNECTION_ID_PRESENT, quic::CONNECTION_ID_PRESENT,
quic::PACKET_1BYTE_PACKET_NUMBER, &quic_version_,
quic::Perspective::IS_SERVER);

Buffer::RawSlice slice;
// packet->data() is const, so it has to be copied to send to sendmsg.
char buffer[100];
memcpy(buffer, packet->data(), packet->length());
slice.mem_ = buffer;
slice.len_ = packet->length();
quic::CrypterPair crypters;
quic::CryptoUtils::CreateInitialObfuscators(quic::Perspective::IS_CLIENT, GetParam(),
quic_connection_->connection_id(),
&crypters);
quic_connection_->InstallDecrypter(quic::ENCRYPTION_INITIAL, std::move(crypters.decrypter));

peer_socket_->ioHandle().sendmsg(&slice, 1, 0, peer_addr_->ip(), *self_addr_);
dispatcher_->run(Event::Dispatcher::RunType::NonBlock);
const quic::QuicConnectionStats& stats = quic_connection_->GetStats();
EXPECT_EQ(stats.num_ecn_marks_received.ect1, 1);
}
Expand Down

0 comments on commit 3bd54c6

Please sign in to comment.