LCOV - code coverage report
Current view: top level - source/common/quic - udp_gso_batch_writer.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 73 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 9 0.0 %

          Line data    Source code
       1             : #include "source/common/quic/udp_gso_batch_writer.h"
       2             : 
       3             : #include "source/common/network/io_socket_error_impl.h"
       4             : #include "source/common/quic/envoy_quic_utils.h"
       5             : 
       6             : namespace Envoy {
       7             : namespace Quic {
       8             : namespace {
       9           0 : Api::IoCallUint64Result convertQuicWriteResult(quic::WriteResult quic_result, size_t payload_len) {
      10           0 :   switch (quic_result.status) {
      11           0 :   case quic::WRITE_STATUS_OK:
      12           0 :     if (quic_result.bytes_written == 0) {
      13           0 :       ENVOY_LOG_MISC(trace, "sendmsg successful, message buffered to send");
      14           0 :     } else {
      15           0 :       ENVOY_LOG_MISC(trace, "sendmsg successful, flushed bytes {}", quic_result.bytes_written);
      16           0 :     }
      17             :     // Return payload_len as rc & nullptr as error on success
      18           0 :     return {/*rc=*/payload_len,
      19           0 :             /*err=*/Api::IoError::none()};
      20           0 :   case quic::WRITE_STATUS_BLOCKED_DATA_BUFFERED:
      21             :     // Data was buffered, Return payload_len as rc & nullptr as error
      22           0 :     ENVOY_LOG_MISC(trace, "sendmsg blocked, message buffered to send");
      23           0 :     return {/*rc=*/payload_len,
      24           0 :             /*err=*/Api::IoError::none()};
      25           0 :   case quic::WRITE_STATUS_BLOCKED:
      26             :     // Writer blocked, return error
      27           0 :     ENVOY_LOG_MISC(trace, "sendmsg blocked, message not buffered");
      28           0 :     return {/*rc=*/0,
      29           0 :             /*err=*/Network::IoSocketError::getIoSocketEagainError()};
      30           0 :   default:
      31             :     // Write Failed, return {0 and error_code}
      32           0 :     ENVOY_LOG_MISC(trace, "sendmsg failed with error code {}",
      33           0 :                    static_cast<int>(quic_result.error_code));
      34           0 :     return {/*rc=*/0,
      35           0 :             /*err=*/Network::IoSocketError::create(quic_result.error_code)};
      36           0 :   }
      37           0 : }
      38             : 
      39             : } // namespace
      40             : 
      41             : // Initialize QuicGsoBatchWriter, set io_handle_ and stats_
      42             : UdpGsoBatchWriter::UdpGsoBatchWriter(Network::IoHandle& io_handle, Stats::Scope& scope)
      43           0 :     : quic::QuicGsoBatchWriter(io_handle.fdDoNotUse()), stats_(generateStats(scope)) {}
      44             : 
      45             : Api::IoCallUint64Result
      46             : UdpGsoBatchWriter::writePacket(const Buffer::Instance& buffer, const Network::Address::Ip* local_ip,
      47           0 :                                const Network::Address::Instance& peer_address) {
      48             :   // Convert received parameters to relevant forms
      49           0 :   quic::QuicSocketAddress peer_addr = envoyIpAddressToQuicSocketAddress(peer_address.ip());
      50           0 :   quic::QuicSocketAddress self_addr = envoyIpAddressToQuicSocketAddress(local_ip);
      51           0 :   ASSERT(buffer.getRawSlices().size() == 1);
      52           0 :   size_t payload_len = static_cast<size_t>(buffer.frontSlice().len_);
      53             : 
      54             :   // TODO(yugant): Currently we do not use PerPacketOptions with Quic, we may want to
      55             :   // specify this parameter here at a later stage.
      56           0 :   quic::QuicPacketWriterParams params;
      57           0 :   quic::WriteResult quic_result = WritePacket(static_cast<char*>(buffer.frontSlice().mem_),
      58           0 :                                               payload_len, self_addr.host(), peer_addr,
      59           0 :                                               /*quic::PerPacketOptions=*/nullptr, params);
      60           0 :   updateUdpGsoBatchWriterStats(quic_result);
      61             : 
      62           0 :   return convertQuicWriteResult(quic_result, payload_len);
      63           0 : }
      64             : 
      65           0 : uint64_t UdpGsoBatchWriter::getMaxPacketSize(const Network::Address::Instance& peer_address) const {
      66           0 :   quic::QuicSocketAddress peer_addr = envoyIpAddressToQuicSocketAddress(peer_address.ip());
      67           0 :   return static_cast<uint64_t>(GetMaxPacketSize(peer_addr));
      68           0 : }
      69             : 
      70             : Network::UdpPacketWriterBuffer
      71             : UdpGsoBatchWriter::getNextWriteLocation(const Network::Address::Ip* local_ip,
      72           0 :                                         const Network::Address::Instance& peer_address) {
      73           0 :   quic::QuicSocketAddress peer_addr = envoyIpAddressToQuicSocketAddress(peer_address.ip());
      74           0 :   quic::QuicSocketAddress self_addr = envoyIpAddressToQuicSocketAddress(local_ip);
      75           0 :   quic::QuicPacketBuffer quic_buf = GetNextWriteLocation(self_addr.host(), peer_addr);
      76           0 :   return {reinterpret_cast<uint8_t*>(quic_buf.buffer), Network::UdpMaxOutgoingPacketSize,
      77           0 :           quic_buf.release_buffer};
      78           0 : }
      79             : 
      80           0 : Api::IoCallUint64Result UdpGsoBatchWriter::flush() {
      81           0 :   quic::WriteResult quic_result = Flush();
      82           0 :   updateUdpGsoBatchWriterStats(quic_result);
      83             : 
      84           0 :   return convertQuicWriteResult(quic_result, /*payload_len=*/0);
      85           0 : }
      86             : 
      87           0 : void UdpGsoBatchWriter::updateUdpGsoBatchWriterStats(quic::WriteResult quic_result) {
      88           0 :   if (quic_result.status == quic::WRITE_STATUS_OK && quic_result.bytes_written > 0) {
      89           0 :     if (gso_size_ > 0u) {
      90           0 :       uint64_t num_pkts_in_batch =
      91           0 :           std::ceil(static_cast<float>(quic_result.bytes_written) / gso_size_);
      92           0 :       stats_.pkts_sent_per_batch_.recordValue(num_pkts_in_batch);
      93           0 :     }
      94           0 :     stats_.total_bytes_sent_.add(quic_result.bytes_written);
      95           0 :   }
      96           0 :   stats_.internal_buffer_size_.set(batch_buffer().SizeInUse());
      97           0 :   gso_size_ = buffered_writes().empty() ? 0u : buffered_writes().front().buf_len;
      98           0 : }
      99             : 
     100           0 : UdpGsoBatchWriterStats UdpGsoBatchWriter::generateStats(Stats::Scope& scope) {
     101           0 :   return {
     102           0 :       UDP_GSO_BATCH_WRITER_STATS(POOL_COUNTER(scope), POOL_GAUGE(scope), POOL_HISTOGRAM(scope))};
     103           0 : }
     104             : 
     105             : Network::UdpPacketWriterPtr
     106           0 : UdpGsoBatchWriterFactory::createUdpPacketWriter(Network::IoHandle& io_handle, Stats::Scope& scope) {
     107           0 :   return std::make_unique<UdpGsoBatchWriter>(io_handle, scope);
     108           0 : }
     109             : 
     110             : } // namespace Quic
     111             : } // namespace Envoy

Generated by: LCOV version 1.15