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:
authorJames M Snell <jasnell@gmail.com>2021-03-25 22:19:30 +0300
committerJames M Snell <jasnell@gmail.com>2021-04-02 16:16:40 +0300
commit0b90d352948393e5f92ceb2ef749c643b1002a68 (patch)
treeaf799b4214eb4d855b6582fadc0f17d2e724ac84 /src/node_sockaddr.cc
parentfb9257f6597f0581592826d236cfc7196afebaca (diff)
net: add SocketAddress class
Signed-off-by: James M Snell <jasnell@gmail.com> PR-URL: https://github.com/nodejs/node/pull/37917 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'src/node_sockaddr.cc')
-rw-r--r--src/node_sockaddr.cc143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/node_sockaddr.cc b/src/node_sockaddr.cc
index 653047cc593..e745589b125 100644
--- a/src/node_sockaddr.cc
+++ b/src/node_sockaddr.cc
@@ -3,6 +3,7 @@
#include "base64-inl.h"
#include "base_object-inl.h"
#include "memory_tracker-inl.h"
+#include "node_errors.h"
#include "uv.h"
#include <memory>
@@ -15,9 +16,11 @@ using v8::Array;
using v8::Context;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
+using v8::Int32;
using v8::Local;
using v8::MaybeLocal;
using v8::Object;
+using v8::Uint32;
using v8::Value;
namespace {
@@ -752,6 +755,8 @@ void SocketAddressBlockListWrap::Initialize(
GetConstructorTemplate(env),
Environment::SetConstructorFunctionFlag::NONE);
+ SocketAddressBase::Initialize(env, target);
+
NODE_DEFINE_CONSTANT(target, AF_INET);
NODE_DEFINE_CONSTANT(target, AF_INET6);
}
@@ -768,6 +773,144 @@ void SocketAddressBlockListWrap::TransferData::MemoryInfo(
blocklist_->MemoryInfo(tracker);
}
+bool SocketAddressBase::HasInstance(Environment* env, Local<Value> value) {
+ return GetConstructorTemplate(env)->HasInstance(value);
+}
+
+Local<FunctionTemplate> SocketAddressBase::GetConstructorTemplate(
+ Environment* env) {
+ Local<FunctionTemplate> tmpl = env->socketaddress_constructor_template();
+ if (tmpl.IsEmpty()) {
+ tmpl = env->NewFunctionTemplate(New);
+ tmpl->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SocketAddress"));
+ tmpl->InstanceTemplate()->SetInternalFieldCount(
+ SocketAddressBase::kInternalFieldCount);
+ tmpl->Inherit(BaseObject::GetConstructorTemplate(env));
+ env->SetProtoMethod(tmpl, "detail", Detail);
+ env->SetProtoMethod(tmpl, "legacyDetail", LegacyDetail);
+ env->SetProtoMethodNoSideEffect(tmpl, "flowlabel", GetFlowLabel);
+ env->set_socketaddress_constructor_template(tmpl);
+ }
+ return tmpl;
+}
+
+void SocketAddressBase::Initialize(Environment* env, Local<Object> target) {
+ env->SetConstructorFunction(
+ target,
+ "SocketAddress",
+ GetConstructorTemplate(env),
+ Environment::SetConstructorFunctionFlag::NONE);
+}
+
+BaseObjectPtr<SocketAddressBase> SocketAddressBase::Create(
+ Environment* env,
+ std::shared_ptr<SocketAddress> address) {
+ Local<Object> obj;
+ if (!GetConstructorTemplate(env)
+ ->InstanceTemplate()
+ ->NewInstance(env->context()).ToLocal(&obj)) {
+ return BaseObjectPtr<SocketAddressBase>();
+ }
+
+ return MakeBaseObject<SocketAddressBase>(env, obj, std::move(address));
+}
+
+void SocketAddressBase::New(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(args.IsConstructCall());
+ CHECK(args[0]->IsString()); // address
+ CHECK(args[1]->IsInt32()); // port
+ CHECK(args[2]->IsInt32()); // family
+ CHECK(args[3]->IsUint32()); // flow label
+
+ Utf8Value address(env->isolate(), args[0]);
+ int32_t port = args[1].As<Int32>()->Value();
+ int32_t family = args[2].As<Int32>()->Value();
+ uint32_t flow_label = args[3].As<Uint32>()->Value();
+
+ std::shared_ptr<SocketAddress> addr = std::make_shared<SocketAddress>();
+
+ if (!SocketAddress::New(family, *address, port, addr.get()))
+ return THROW_ERR_INVALID_ADDRESS(env);
+
+ addr->set_flow_label(flow_label);
+
+ new SocketAddressBase(env, args.This(), std::move(addr));
+}
+
+void SocketAddressBase::Detail(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK(args[0]->IsObject());
+ Local<Object> detail = args[0].As<Object>();
+
+ SocketAddressBase* base;
+ ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder());
+
+ Local<Value> address;
+ if (!ToV8Value(env->context(), base->address_->address()).ToLocal(&address))
+ return;
+
+ if (detail->Set(env->context(), env->address_string(), address).IsJust() &&
+ detail->Set(
+ env->context(),
+ env->port_string(),
+ Int32::New(env->isolate(), base->address_->port())).IsJust() &&
+ detail->Set(
+ env->context(),
+ env->family_string(),
+ Int32::New(env->isolate(), base->address_->family())).IsJust() &&
+ detail->Set(
+ env->context(),
+ env->flowlabel_string(),
+ Uint32::New(env->isolate(), base->address_->flow_label()))
+ .IsJust()) {
+ args.GetReturnValue().Set(detail);
+ }
+}
+
+void SocketAddressBase::GetFlowLabel(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ SocketAddressBase* base;
+ ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder());
+ args.GetReturnValue().Set(base->address_->flow_label());
+}
+
+void SocketAddressBase::LegacyDetail(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ SocketAddressBase* base;
+ ASSIGN_OR_RETURN_UNWRAP(&base, args.Holder());
+ args.GetReturnValue().Set(base->address_->ToJS(env));
+}
+
+SocketAddressBase::SocketAddressBase(
+ Environment* env,
+ Local<Object> wrap,
+ std::shared_ptr<SocketAddress> address)
+ : BaseObject(env, wrap),
+ address_(std::move(address)) {
+ MakeWeak();
+}
+
+void SocketAddressBase::MemoryInfo(MemoryTracker* tracker) const {
+ tracker->TrackField("address", address_);
+}
+
+std::unique_ptr<worker::TransferData>
+SocketAddressBase::CloneForMessaging() const {
+ return std::make_unique<TransferData>(this);
+}
+
+void SocketAddressBase::TransferData::MemoryInfo(MemoryTracker* tracker) const {
+ tracker->TrackField("address", address_);
+}
+
+BaseObjectPtr<BaseObject> SocketAddressBase::TransferData::Deserialize(
+ Environment* env,
+ v8::Local<v8::Context> context,
+ std::unique_ptr<worker::TransferData> self) {
+ return SocketAddressBase::Create(env, std::move(address_));
+}
+
} // namespace node
NODE_MODULE_CONTEXT_AWARE_INTERNAL(