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

          Line data    Source code
       1             : #include "source/common/network/win32_socket_handle_impl.h"
       2             : 
       3             : #include "envoy/buffer/buffer.h"
       4             : 
       5             : #include "source/common/api/os_sys_calls_impl.h"
       6             : #include "source/common/common/utility.h"
       7             : #include "source/common/event/file_event_impl.h"
       8             : #include "source/common/network/address_impl.h"
       9             : 
      10             : #include "absl/container/fixed_array.h"
      11             : #include "absl/types/optional.h"
      12             : 
      13             : using Envoy::Api::SysCallIntResult;
      14             : using Envoy::Api::SysCallSizeResult;
      15             : 
      16             : namespace Envoy {
      17             : namespace Network {
      18             : 
      19             : Api::IoCallUint64Result Win32SocketHandleImpl::readv(uint64_t max_length, Buffer::RawSlice* slices,
      20           0 :                                                      uint64_t num_slice) {
      21           0 :   if (peek_buffer_.length() != 0) {
      22           0 :     return readvFromPeekBuffer(max_length, slices, num_slice);
      23           0 :   }
      24             : 
      25           0 :   auto result = IoSocketHandleImpl::readv(max_length, slices, num_slice);
      26           0 :   reEnableEventBasedOnIOResult(result, Event::FileReadyType::Read);
      27           0 :   return result;
      28           0 : }
      29             : 
      30             : Api::IoCallUint64Result Win32SocketHandleImpl::read(Buffer::Instance& buffer,
      31           0 :                                                     absl::optional<uint64_t> max_length_opt) {
      32           0 :   if (peek_buffer_.length() != 0) {
      33           0 :     return readFromPeekBuffer(buffer, max_length_opt.value_or(UINT64_MAX));
      34           0 :   }
      35             : 
      36           0 :   auto result = IoSocketHandleImpl::read(buffer, max_length_opt);
      37           0 :   reEnableEventBasedOnIOResult(result, Event::FileReadyType::Read);
      38           0 :   return result;
      39           0 : }
      40             : 
      41             : Api::IoCallUint64Result Win32SocketHandleImpl::writev(const Buffer::RawSlice* slices,
      42           0 :                                                       uint64_t num_slice) {
      43           0 :   auto result = IoSocketHandleImpl::writev(slices, num_slice);
      44           0 :   reEnableEventBasedOnIOResult(result, Event::FileReadyType::Write);
      45           0 :   return result;
      46           0 : }
      47             : 
      48           0 : Api::IoCallUint64Result Win32SocketHandleImpl::write(Buffer::Instance& buffer) {
      49           0 :   Api::IoCallUint64Result result = IoSocketHandleImpl::write(buffer);
      50           0 :   reEnableEventBasedOnIOResult(result, Event::FileReadyType::Write);
      51           0 :   return result;
      52           0 : }
      53             : 
      54             : Api::IoCallUint64Result Win32SocketHandleImpl::sendmsg(const Buffer::RawSlice* slices,
      55             :                                                        uint64_t num_slice, int flags,
      56             :                                                        const Address::Ip* self_ip,
      57           0 :                                                        const Address::Instance& peer_address) {
      58             : 
      59           0 :   Api::IoCallUint64Result result =
      60           0 :       IoSocketHandleImpl::sendmsg(slices, num_slice, flags, self_ip, peer_address);
      61           0 :   reEnableEventBasedOnIOResult(result, Event::FileReadyType::Write);
      62           0 :   return result;
      63           0 : }
      64             : 
      65             : Api::IoCallUint64Result Win32SocketHandleImpl::recvmsg(Buffer::RawSlice* slices,
      66             :                                                        const uint64_t num_slice, uint32_t self_port,
      67           0 :                                                        RecvMsgOutput& output) {
      68           0 :   Api::IoCallUint64Result result =
      69           0 :       IoSocketHandleImpl::recvmsg(slices, num_slice, self_port, output);
      70           0 :   reEnableEventBasedOnIOResult(result, Event::FileReadyType::Read);
      71           0 :   return result;
      72           0 : }
      73             : 
      74             : Api::IoCallUint64Result Win32SocketHandleImpl::recvmmsg(RawSliceArrays& slices, uint32_t self_port,
      75           0 :                                                         RecvMsgOutput& output) {
      76           0 :   Api::IoCallUint64Result result = IoSocketHandleImpl::recvmmsg(slices, self_port, output);
      77           0 :   reEnableEventBasedOnIOResult(result, Event::FileReadyType::Read);
      78           0 :   return result;
      79           0 : }
      80             : 
      81           0 : Api::IoCallUint64Result Win32SocketHandleImpl::recv(void* buffer, size_t length, int flags) {
      82           0 :   if (flags & MSG_PEEK) {
      83           0 :     return emulatePeek(buffer, length);
      84           0 :   }
      85             : 
      86           0 :   if (peek_buffer_.length() == 0) {
      87           0 :     Api::IoCallUint64Result result = IoSocketHandleImpl::recv(buffer, length, flags);
      88           0 :     reEnableEventBasedOnIOResult(result, Event::FileReadyType::Read);
      89           0 :     return result;
      90           0 :   } else {
      91           0 :     return readFromPeekBuffer(buffer, length);
      92           0 :   }
      93           0 : }
      94             : 
      95           0 : Api::IoCallUint64Result Win32SocketHandleImpl::emulatePeek(void* buffer, size_t length) {
      96             :   // If there's not enough data in the peek buffer, try reading more.
      97           0 :   if (length > peek_buffer_.length()) {
      98             :     // The caller is responsible for calling with the larger size
      99             :     // in cases it needs to do so it can't rely on transparent event activation.
     100             :     // So in this case we should activate read again unless the read blocked.
     101           0 :     Api::IoCallUint64Result peek_result = drainToPeekBuffer(length);
     102             : 
     103             :     //  Some error happened.
     104           0 :     if (!peek_result.ok()) {
     105           0 :       if (peek_result.wouldBlock() && file_event_) {
     106           0 :         file_event_->registerEventIfEmulatedEdge(Event::FileReadyType::Read);
     107           0 :         if (peek_buffer_.length() == 0) {
     108           0 :           return peek_result;
     109           0 :         }
     110           0 :       } else {
     111           0 :         return peek_result;
     112           0 :       }
     113           0 :     }
     114           0 :   }
     115             : 
     116           0 :   return peekFromPeekBuffer(buffer, length);
     117           0 : }
     118             : 
     119             : void Win32SocketHandleImpl::reEnableEventBasedOnIOResult(const Api::IoCallUint64Result& result,
     120           0 :                                                          uint32_t event) {
     121           0 :   if (result.wouldBlock() && file_event_) {
     122           0 :     file_event_->registerEventIfEmulatedEdge(event);
     123           0 :   }
     124           0 : }
     125             : 
     126           0 : Api::IoCallUint64Result Win32SocketHandleImpl::drainToPeekBuffer(size_t length) {
     127           0 :   size_t total_bytes_read = 0;
     128           0 :   while (peek_buffer_.length() < length) {
     129           0 :     Buffer::Reservation reservation = peek_buffer_.reserveForRead();
     130           0 :     uint64_t bytes_to_read = std::min<uint64_t>(
     131           0 :         static_cast<uint64_t>(length - peek_buffer_.length()), reservation.length());
     132           0 :     Api::IoCallUint64Result result =
     133           0 :         IoSocketHandleImpl::readv(bytes_to_read, reservation.slices(), reservation.numSlices());
     134           0 :     uint64_t bytes_to_commit = result.ok() ? result.return_value_ : 0;
     135           0 :     reservation.commit(bytes_to_commit);
     136           0 :     total_bytes_read += bytes_to_commit;
     137           0 :     if (!result.ok() || bytes_to_commit == 0) {
     138           0 :       return result;
     139           0 :     }
     140           0 :   }
     141           0 :   return {total_bytes_read, Api::IoError::none()};
     142           0 : }
     143             : 
     144           0 : Api::IoCallUint64Result Win32SocketHandleImpl::readFromPeekBuffer(void* buffer, size_t length) {
     145           0 :   uint64_t copy_size = std::min(peek_buffer_.length(), static_cast<uint64_t>(length));
     146           0 :   peek_buffer_.copyOut(0, copy_size, buffer);
     147           0 :   peek_buffer_.drain(copy_size);
     148           0 :   return {copy_size, Api::IoError::none()};
     149           0 : }
     150             : 
     151             : Api::IoCallUint64Result Win32SocketHandleImpl::readvFromPeekBuffer(uint64_t max_length,
     152             :                                                                    Buffer::RawSlice* slices,
     153           0 :                                                                    uint64_t num_slice) {
     154           0 :   uint64_t bytes_read = peek_buffer_.copyOutToSlices(max_length, slices, num_slice);
     155           0 :   peek_buffer_.drain(bytes_read);
     156           0 :   return {bytes_read, Api::IoError::none()};
     157           0 : }
     158             : 
     159             : Api::IoCallUint64Result Win32SocketHandleImpl::readFromPeekBuffer(Buffer::Instance& buffer,
     160           0 :                                                                   size_t length) {
     161           0 :   auto length_to_move = std::min(peek_buffer_.length(), static_cast<uint64_t>(length));
     162           0 :   buffer.move(peek_buffer_, length_to_move);
     163           0 :   return {length_to_move, Api::IoError::none()};
     164           0 : }
     165             : 
     166           0 : Api::IoCallUint64Result Win32SocketHandleImpl::peekFromPeekBuffer(void* buffer, size_t length) {
     167           0 :   uint64_t copy_size = std::min(peek_buffer_.length(), static_cast<uint64_t>(length));
     168           0 :   peek_buffer_.copyOut(0, copy_size, buffer);
     169           0 :   return {copy_size, Api::IoError::none()};
     170           0 : }
     171             : 
     172             : void Win32SocketHandleImpl::initializeFileEvent(Event::Dispatcher& dispatcher,
     173             :                                                 Event::FileReadyCb cb,
     174           0 :                                                 Event::FileTriggerType trigger, uint32_t events) {
     175           0 :   IoSocketHandleImpl::initializeFileEvent(dispatcher, cb, trigger, events);
     176             :   // Activate the file event directly when we have the data in the peek_buffer_.
     177           0 :   if ((events & Event::FileReadyType::Read) && peek_buffer_.length() > 0) {
     178           0 :     activateFileEvents(Event::FileReadyType::Read);
     179           0 :   }
     180           0 : }
     181             : 
     182           0 : void Win32SocketHandleImpl::enableFileEvents(uint32_t events) {
     183           0 :   IoSocketHandleImpl::enableFileEvents(events);
     184             :   // Activate the file event directly when we have the data in the peek_buffer_.
     185           0 :   if ((events & Event::FileReadyType::Read) && peek_buffer_.length() > 0) {
     186           0 :     activateFileEvents(Event::FileReadyType::Read);
     187           0 :   }
     188           0 : }
     189             : 
     190             : } // namespace Network
     191             : } // namespace Envoy

Generated by: LCOV version 1.15