From 013efdde25fc4660a1ef6d51a4ebf6a864499b28 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sun, 22 May 2022 20:18:23 -0700 Subject: [PATCH] [wpinet] Wrap a number of newer libuv features (#4260) --- wpinet/src/main/native/cpp/uv/Stream.cpp | 10 +++++++ wpinet/src/main/native/cpp/uv/Tcp.cpp | 11 ++++++++ wpinet/src/main/native/cpp/uv/Udp.cpp | 11 ++++++++ .../main/native/include/wpinet/uv/Stream.h | 28 +++++++++++++++++++ .../src/main/native/include/wpinet/uv/Tcp.h | 8 ++++++ .../src/main/native/include/wpinet/uv/Timer.h | 9 ++++++ .../src/main/native/include/wpinet/uv/Udp.h | 20 +++++++++++++ 7 files changed, 97 insertions(+) diff --git a/wpinet/src/main/native/cpp/uv/Stream.cpp b/wpinet/src/main/native/cpp/uv/Stream.cpp index 94fd48b61c..3b00040b1c 100644 --- a/wpinet/src/main/native/cpp/uv/Stream.cpp +++ b/wpinet/src/main/native/cpp/uv/Stream.cpp @@ -106,4 +106,14 @@ int Stream::TryWrite(span bufs) { return val; } +int Stream::TryWrite2(span bufs, Stream& send) { + int val = uv_try_write2(GetRawStream(), bufs.data(), bufs.size(), + send.GetRawStream()); + if (val < 0) { + this->ReportError(val); + return 0; + } + return val; +} + } // namespace wpi::uv diff --git a/wpinet/src/main/native/cpp/uv/Tcp.cpp b/wpinet/src/main/native/cpp/uv/Tcp.cpp index db17876781..ae01683467 100644 --- a/wpinet/src/main/native/cpp/uv/Tcp.cpp +++ b/wpinet/src/main/native/cpp/uv/Tcp.cpp @@ -167,4 +167,15 @@ void Tcp::Connect6(std::string_view ip, unsigned int port, } } +void Tcp::CloseReset() { + if (!IsClosing()) { + uv_tcp_close_reset(GetRaw(), [](uv_handle_t* handle) { + Tcp& h = *static_cast(handle->data); + h.closed(); + h.Release(); // free ourselves + }); + ForceClosed(); + } +} + } // namespace wpi::uv diff --git a/wpinet/src/main/native/cpp/uv/Udp.cpp b/wpinet/src/main/native/cpp/uv/Udp.cpp index 28e7901c12..2e58020100 100644 --- a/wpinet/src/main/native/cpp/uv/Udp.cpp +++ b/wpinet/src/main/native/cpp/uv/Udp.cpp @@ -117,6 +117,17 @@ void Udp::SetMembership(std::string_view multicastAddr, interfaceAddrBuf.c_str(), membership); } +void Udp::SetSourceMembership(std::string_view multicastAddr, + std::string_view interfaceAddr, + std::string_view sourceAddr, + uv_membership membership) { + SmallString<128> multicastAddrBuf{multicastAddr}; + SmallString<128> interfaceAddrBuf{interfaceAddr}; + SmallString<128> sourceAddrBuf{sourceAddr}; + Invoke(&uv_udp_set_source_membership, GetRaw(), multicastAddrBuf.c_str(), + interfaceAddrBuf.c_str(), sourceAddrBuf.c_str(), membership); +} + void Udp::SetMulticastInterface(std::string_view interfaceAddr) { SmallString<128> interfaceAddrBuf{interfaceAddr}; Invoke(&uv_udp_set_multicast_interface, GetRaw(), interfaceAddrBuf.c_str()); diff --git a/wpinet/src/main/native/include/wpinet/uv/Stream.h b/wpinet/src/main/native/include/wpinet/uv/Stream.h index d9dd6d5486..6aa77c82ec 100644 --- a/wpinet/src/main/native/include/wpinet/uv/Stream.h +++ b/wpinet/src/main/native/include/wpinet/uv/Stream.h @@ -211,6 +211,34 @@ class Stream : public Handle { return TryWrite({bufs.begin(), bufs.end()}); } + /** + * Same as TryWrite() and extended write function for sending handles over a + * pipe. + * + * Try to send a handle is not supported on Windows, where it returns + * UV_EAGAIN. + * + * @param bufs The buffers to be written to the stream. + * @param send send stream + * @return Number of bytes written. + */ + int TryWrite2(span bufs, Stream& send); + + /** + * Same as TryWrite() and extended write function for sending handles over a + * pipe. + * + * Try to send a handle is not supported on Windows, where it returns + * UV_EAGAIN. + * + * @param bufs The buffers to be written to the stream. + * @param send send stream + * @return Number of bytes written. + */ + int TryWrite2(std::initializer_list bufs, Stream& send) { + return TryWrite2({bufs.begin(), bufs.end()}, send); + } + /** * Check if the stream is readable. * @return True if the stream is readable, false otherwise. diff --git a/wpinet/src/main/native/include/wpinet/uv/Tcp.h b/wpinet/src/main/native/include/wpinet/uv/Tcp.h index 97cb71cb7e..dc554dbf2a 100644 --- a/wpinet/src/main/native/include/wpinet/uv/Tcp.h +++ b/wpinet/src/main/native/include/wpinet/uv/Tcp.h @@ -338,6 +338,14 @@ class Tcp final : public NetworkStreamImpl { void Connect6(std::string_view ip, unsigned int port, std::function callback); + /** + * Resets a TCP connection by sending a RST packet. This is accomplished by + * setting the SO_LINGER socket option with a linger interval of zero and then + * calling Close(). Due to some platform inconsistencies, mixing of + * Shutdown() and CloseReset() calls is not allowed. + */ + void CloseReset(); + private: Tcp* DoAccept() override; diff --git a/wpinet/src/main/native/include/wpinet/uv/Timer.h b/wpinet/src/main/native/include/wpinet/uv/Timer.h index 51b5483ca4..4a1cf545de 100644 --- a/wpinet/src/main/native/include/wpinet/uv/Timer.h +++ b/wpinet/src/main/native/include/wpinet/uv/Timer.h @@ -125,6 +125,15 @@ class Timer final : public HandleImpl { */ Time GetRepeat() const { return Time{uv_timer_get_repeat(GetRaw())}; } + /** + * Get the timer due value or 0 if it has expired. The time is relative to + * uv_now(). + * + * @return Timer due value in milliseconds (as a + * `std::chrono::duration`). + */ + Time GetDueIn() const { return Time{uv_timer_get_due_in(GetRaw())}; } + /** * Signal generated when the timeout event occurs. */ diff --git a/wpinet/src/main/native/include/wpinet/uv/Udp.h b/wpinet/src/main/native/include/wpinet/uv/Udp.h index f3ba2ec077..e6ccb53ded 100644 --- a/wpinet/src/main/native/include/wpinet/uv/Udp.h +++ b/wpinet/src/main/native/include/wpinet/uv/Udp.h @@ -172,6 +172,19 @@ class Udp final : public HandleImpl { void SetMembership(std::string_view multicastAddr, std::string_view interfaceAddr, uv_membership membership); + /** + * Set membership for a source-specific multicast group. + * + * @param multicastAddr Multicast address to set membership for + * @param interfaceAddr Interface address + * @param sourceAddr Source address + * @param membership Should be UV_JOIN_GROUP or UV_LEAVE_GROUP + */ + void SetSourceMembership(std::string_view multicastAddr, + std::string_view interfaceAddr, + std::string_view sourceAddr, + uv_membership membership); + /** * Set IP multicast loop flag. Makes multicast packets loop back to local * sockets. @@ -353,6 +366,13 @@ class Udp final : public HandleImpl { */ void StopRecv() { Invoke(&uv_udp_recv_stop, GetRaw()); } + /** + * Returns true if the UDP handle was created with the UV_UDP_RECVMMSG flag + * and the platform supports recvmmsg(2), false otherwise. + * @return True if the UDP handle is using recvmmsg. + */ + bool IsUsingRecvmmsg() const { return uv_udp_using_recvmmsg(GetRaw()); } + /** * Gets the amount of queued bytes waiting to be sent. * @return Amount of queued bytes waiting to be sent.