| 1750 | } |
| 1751 | |
| 1752 | WasiExpect<void> INode::sockRecvFrom(Span<Span<uint8_t>> RiData, |
| 1753 | __wasi_riflags_t RiFlags, |
| 1754 | __wasi_address_family_t *AddressFamilyPtr, |
| 1755 | Span<uint8_t> Address, uint16_t *PortPtr, |
| 1756 | __wasi_size_t &NRead, |
| 1757 | __wasi_roflags_t &RoFlags) const noexcept { |
| 1758 | EXPECTED_TRY(detail::ensureWSAStartup()); |
| 1759 | |
| 1760 | int SysRiFlags = 0; |
| 1761 | if (RiFlags & __WASI_RIFLAGS_RECV_PEEK) { |
| 1762 | SysRiFlags |= MSG_PEEK; |
| 1763 | } |
| 1764 | #if NTDDI_VERSION >= NTDDI_WS03 |
| 1765 | if (RiFlags & __WASI_RIFLAGS_RECV_WAITALL) { |
| 1766 | SysRiFlags |= MSG_WAITALL; |
| 1767 | } |
| 1768 | #endif |
| 1769 | |
| 1770 | std::size_t TotalBufSize = 0; |
| 1771 | for (auto &IOV : RiData) { |
| 1772 | TotalBufSize += IOV.size(); |
| 1773 | } |
| 1774 | |
| 1775 | std::vector<uint8_t> TotalBuf(TotalBufSize, 0); |
| 1776 | |
| 1777 | const bool NeedAddress = |
| 1778 | AddressFamilyPtr != nullptr || !Address.empty() || PortPtr != nullptr; |
| 1779 | Variant<sockaddr_storage, sockaddr_in, sockaddr_in6, sockaddr> SockAddr; |
| 1780 | int MaxAllowLength; |
| 1781 | if (NeedAddress) { |
| 1782 | MaxAllowLength = sizeof(SockAddr); |
| 1783 | } |
| 1784 | |
| 1785 | if (auto Res = recvfrom(Socket, reinterpret_cast<char *>(TotalBuf.data()), |
| 1786 | static_cast<int>(TotalBufSize), SysRiFlags, |
| 1787 | NeedAddress ? &SockAddr.get<sockaddr>() : nullptr, |
| 1788 | NeedAddress ? &MaxAllowLength : nullptr); |
| 1789 | unlikely(Res == SOCKET_ERROR_)) { |
| 1790 | return WasiUnexpect(detail::fromWSALastError()); |
| 1791 | } else { |
| 1792 | NRead = static_cast<__wasi_size_t>(Res); |
| 1793 | } |
| 1794 | |
| 1795 | if (NeedAddress) { |
| 1796 | switch (SockAddr.get<sockaddr_storage>().ss_family) { |
| 1797 | case AF_INET: { |
| 1798 | const auto &SockAddr4 = SockAddr.get<sockaddr_in>(); |
| 1799 | if (AddressFamilyPtr) { |
| 1800 | *AddressFamilyPtr = __WASI_ADDRESS_FAMILY_INET4; |
| 1801 | } |
| 1802 | if (Address.size() >= sizeof(in_addr)) { |
| 1803 | std::memcpy(Address.data(), &SockAddr4.sin_addr, sizeof(in_addr)); |
| 1804 | } |
| 1805 | if (PortPtr != nullptr) { |
| 1806 | *PortPtr = SockAddr4.sin_port; |
| 1807 | } |
| 1808 | break; |
| 1809 | } |
no test coverage detected