Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-10-09 19:56:21 +0300
committerMyles Borins <mylesborins@google.com>2020-03-05 00:30:30 +0300
commit4dc59b91a71099f054e9ece5fb05657b1b916af6 (patch)
tree26bd9f5ad594c7b0996cb4cf8adc6fa05a298f00 /src/udp_wrap.h
parent478450d6b320c9c904bff12d871a62fd7e8bab33 (diff)
dgram: make UDPWrap more reusable
Allow using the handle more directly for I/O in other parts of the codebase. Originally landed in the QUIC repo Original review metadata: ``` PR-URL: https://github.com/nodejs/quic/pull/165 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> ``` Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: https://github.com/nodejs/node/pull/31871 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src/udp_wrap.h')
-rw-r--r--src/udp_wrap.h116
1 files changed, 111 insertions, 5 deletions
diff --git a/src/udp_wrap.h b/src/udp_wrap.h
index 2026dd1dee1..7afd9784b0a 100644
--- a/src/udp_wrap.h
+++ b/src/udp_wrap.h
@@ -25,14 +25,101 @@
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#include "handle_wrap.h"
+#include "req_wrap.h"
#include "uv.h"
#include "v8.h"
namespace node {
-class Environment;
+class UDPWrapBase;
-class UDPWrap: public HandleWrap {
+// A listener that can be attached to an `UDPWrapBase` object and generally
+// manages its I/O activity. This is similar to `StreamListener`.
+class UDPListener {
+ public:
+ virtual ~UDPListener();
+
+ // Called right before data is received from the socket. Must return a
+ // buffer suitable for reading data into, that is then passed to OnRecv.
+ virtual uv_buf_t OnAlloc(size_t suggested_size) = 0;
+
+ // Called right after data is received from the socket, and includes
+ // information about the source address. If `nread` is negative, an error
+ // has occurred, and it represents a libuv error code.
+ virtual void OnRecv(ssize_t nread,
+ const uv_buf_t& buf,
+ const sockaddr* addr,
+ unsigned int flags) = 0;
+
+ // Called when an asynchronous request for writing data is created.
+ // The `msg_size` value contains the total size of the data to be sent,
+ // but may be ignored by the implementation of this Method.
+ // The return value is later passed to OnSendDone.
+ virtual ReqWrap<uv_udp_send_t>* CreateSendWrap(size_t msg_size) = 0;
+
+ // Called when an asynchronous request for writing data has finished.
+ // If status is negative, an error has occurred, and it represents a libuv
+ // error code.
+ virtual void OnSendDone(ReqWrap<uv_udp_send_t>* wrap, int status) = 0;
+
+ // Optional callback that is called after the socket has been bound.
+ virtual void OnAfterBind() {}
+
+ inline UDPWrapBase* udp() const { return wrap_; }
+
+ protected:
+ UDPWrapBase* wrap_ = nullptr;
+
+ friend class UDPWrapBase;
+};
+
+class UDPWrapBase {
+ public:
+ // While UDPWrapBase itself does not extend from HandleWrap, classes
+ // derived from it will (like UDPWrap)
+ enum InternalFields {
+ kUDPWrapBaseField = HandleWrap::kInternalFieldCount,
+ kInternalFieldCount
+ };
+ virtual ~UDPWrapBase();
+
+ // Start emitting OnAlloc() + OnRecv() events on the listener.
+ virtual int RecvStart() = 0;
+
+ // Stop emitting OnAlloc() + OnRecv() events on the listener.
+ virtual int RecvStop() = 0;
+
+ // Send a chunk of data over this socket. This may call CreateSendWrap()
+ // on the listener if an async transmission is necessary.
+ virtual ssize_t Send(uv_buf_t* bufs,
+ size_t nbufs,
+ const sockaddr* addr) = 0;
+
+ // Stores the sockaddr for the peer in `name`.
+ virtual int GetPeerName(sockaddr* name, int* namelen) = 0;
+
+ // Stores the sockaddr for the local socket in `name`.
+ virtual int GetSockName(sockaddr* name, int* namelen) = 0;
+
+ // Returns an AsyncWrap object with the same lifetime as this object.
+ virtual AsyncWrap* GetAsyncWrap() = 0;
+
+ void set_listener(UDPListener* listener);
+ UDPListener* listener() const;
+
+ static UDPWrapBase* FromObject(v8::Local<v8::Object> obj);
+
+ static void RecvStart(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void RecvStop(const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t);
+
+ private:
+ UDPListener* listener_ = nullptr;
+};
+
+class UDPWrap final : public HandleWrap,
+ public UDPWrapBase,
+ public UDPListener {
public:
enum SocketType {
SOCKET
@@ -51,8 +138,6 @@ class UDPWrap: public HandleWrap {
static void Connect6(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Send6(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Disconnect(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void RecvStart(const v8::FunctionCallbackInfo<v8::Value>& args);
- static void RecvStop(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddMembership(const v8::FunctionCallbackInfo<v8::Value>& args);
static void DropMembership(const v8::FunctionCallbackInfo<v8::Value>& args);
static void AddSourceSpecificMembership(
@@ -68,6 +153,25 @@ class UDPWrap: public HandleWrap {
static void SetTTL(const v8::FunctionCallbackInfo<v8::Value>& args);
static void BufferSize(const v8::FunctionCallbackInfo<v8::Value>& args);
+ // UDPListener implementation
+ uv_buf_t OnAlloc(size_t suggested_size) override;
+ void OnRecv(ssize_t nread,
+ const uv_buf_t& buf,
+ const sockaddr* addr,
+ unsigned int flags) override;
+ ReqWrap<uv_udp_send_t>* CreateSendWrap(size_t msg_size) override;
+ void OnSendDone(ReqWrap<uv_udp_send_t>* wrap, int status) override;
+
+ // UDPWrapBase implementation
+ int RecvStart() override;
+ int RecvStop() override;
+ ssize_t Send(uv_buf_t* bufs,
+ size_t nbufs,
+ const sockaddr* addr) override;
+ int GetPeerName(sockaddr* name, int* namelen) override;
+ int GetSockName(sockaddr* name, int* namelen) override;
+ AsyncWrap* GetAsyncWrap() override;
+
static v8::MaybeLocal<v8::Object> Instantiate(Environment* env,
AsyncWrap* parent,
SocketType type);
@@ -99,7 +203,6 @@ class UDPWrap: public HandleWrap {
static void OnAlloc(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf);
- static void OnSend(uv_udp_send_t* req, int status);
static void OnRecv(uv_udp_t* handle,
ssize_t nread,
const uv_buf_t* buf,
@@ -107,6 +210,9 @@ class UDPWrap: public HandleWrap {
unsigned int flags);
uv_udp_t handle_;
+
+ bool current_send_has_callback_;
+ v8::Local<v8::Object> current_send_req_wrap_;
};
} // namespace node