librats 2.1.4 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/lib/index.d.ts +51 -6
- package/lib/index.js +42 -3
- package/native-src/CMakeLists.txt +13 -0
- package/native-src/src/librats/bindings/rats.cpp +90 -6
- package/native-src/src/librats/bindings/rats.h +92 -3
- package/native-src/src/librats/core/types.cpp +4 -3
- package/native-src/src/librats/core/types.h +25 -12
- package/native-src/src/librats/node/circuit_service.h +84 -0
- package/native-src/src/librats/node/config.h +9 -2
- package/native-src/src/librats/node/node.cpp +59 -5
- package/native-src/src/librats/node/node.h +38 -7
- package/native-src/src/librats/node/peer_network.h +19 -2
- package/native-src/src/librats/peer/peer.h +17 -6
- package/native-src/src/librats/peer/peer_table.cpp +41 -8
- package/native-src/src/librats/security/noise_security.cpp +2 -0
- package/native-src/src/librats/security/plaintext_security.h +1 -0
- package/native-src/src/librats/security/session.h +7 -0
- package/native-src/src/librats/storage/storage.cpp +434 -213
- package/native-src/src/librats/storage/storage.h +163 -19
- package/native-src/src/librats/subsystems/file_transfer.cpp +1 -1
- package/native-src/src/librats/subsystems/hole_punch.cpp +81 -8
- package/native-src/src/librats/subsystems/hole_punch.h +24 -0
- package/native-src/src/librats/subsystems/pubsub.cpp +1 -1
- package/native-src/src/librats/subsystems/reconnection.cpp +1 -1
- package/native-src/src/librats/subsystems/relay.cpp +1143 -0
- package/native-src/src/librats/subsystems/relay.h +211 -0
- package/native-src/src/librats/subsystems/relay_service.h +46 -0
- package/native-src/src/librats/transport/connection.cpp +40 -8
- package/native-src/src/librats/transport/connection.h +12 -2
- package/native-src/src/librats/transport/reactor.cpp +56 -8
- package/native-src/src/librats/transport/reactor.h +38 -0
- package/native-src/src/librats/transport/relay_link.cpp +208 -0
- package/native-src/src/librats/transport/relay_link.h +303 -0
- package/native-src/src/librats/util/logger.h +37 -5
- package/native-src/src/librats/util/network_monitor.cpp +14 -0
- package/native-src/src/librats/util/network_utils.cpp +10 -1
- package/native-src/src/librats/wire/frame.h +1 -0
- package/package.json +1 -1
- package/src/librats_node.cpp +76 -1
package/src/librats_node.cpp
CHANGED
|
@@ -82,6 +82,7 @@ private:
|
|
|
82
82
|
// Single-slot callbacks (peer connect/disconnect, file offer/progress/complete).
|
|
83
83
|
std::unique_ptr<CbContext> on_connected_;
|
|
84
84
|
std::unique_ptr<CbContext> on_disconnected_;
|
|
85
|
+
std::unique_ptr<CbContext> on_writable_;
|
|
85
86
|
std::unique_ptr<CbContext> on_file_offer_;
|
|
86
87
|
std::unique_ptr<CbContext> on_file_progress_;
|
|
87
88
|
std::unique_ptr<CbContext> on_file_complete_;
|
|
@@ -120,11 +121,13 @@ private:
|
|
|
120
121
|
// ---- raw channel messaging ----
|
|
121
122
|
Napi::Value Send(const Napi::CallbackInfo& info);
|
|
122
123
|
Napi::Value Broadcast(const Napi::CallbackInfo& info);
|
|
124
|
+
Napi::Value PeerWritable(const Napi::CallbackInfo& info);
|
|
123
125
|
void On(const Napi::CallbackInfo& info);
|
|
124
126
|
|
|
125
127
|
// ---- peer events ----
|
|
126
128
|
void OnPeerConnected(const Napi::CallbackInfo& info);
|
|
127
129
|
void OnPeerDisconnected(const Napi::CallbackInfo& info);
|
|
130
|
+
void OnPeerWritable(const Napi::CallbackInfo& info);
|
|
128
131
|
|
|
129
132
|
// ---- discovery / NAT ----
|
|
130
133
|
void EnableDht(const Napi::CallbackInfo& info);
|
|
@@ -132,6 +135,8 @@ private:
|
|
|
132
135
|
void EnablePortMapping(const Napi::CallbackInfo& info);
|
|
133
136
|
void EnableHolePunch(const Napi::CallbackInfo& info);
|
|
134
137
|
Napi::Value PunchPeer(const Napi::CallbackInfo& info);
|
|
138
|
+
void EnableRelay(const Napi::CallbackInfo& info);
|
|
139
|
+
Napi::Value ConnectViaRelay(const Napi::CallbackInfo& info);
|
|
135
140
|
Napi::Value GetNatMapping(const Napi::CallbackInfo& info);
|
|
136
141
|
|
|
137
142
|
// ---- pub/sub ----
|
|
@@ -224,6 +229,13 @@ RatsNode::RatsNode(const Napi::CallbackInfo& info)
|
|
|
224
229
|
c.transport_fallback_ms =
|
|
225
230
|
cfg.Get("transportFallbackMs").As<Napi::Number>().Uint32Value();
|
|
226
231
|
|
|
232
|
+
// Bytes a peer may have queued before an app that keeps sending anyway has
|
|
233
|
+
// it dropped as a slow consumer. A quarter of it is where peerWritable()
|
|
234
|
+
// starts saying false, so lowering it makes backpressure felt sooner.
|
|
235
|
+
if (cfg.Has("sendQueueLimit"))
|
|
236
|
+
c.send_queue_limit =
|
|
237
|
+
static_cast<size_t>(cfg.Get("sendQueueLimit").As<Napi::Number>().Int64Value());
|
|
238
|
+
|
|
227
239
|
node_ = rats_create_config(&c);
|
|
228
240
|
} else {
|
|
229
241
|
int port = 0;
|
|
@@ -257,6 +269,7 @@ RatsNode::~RatsNode() {
|
|
|
257
269
|
void RatsNode::Teardown() {
|
|
258
270
|
if (on_connected_) on_connected_->release();
|
|
259
271
|
if (on_disconnected_) on_disconnected_->release();
|
|
272
|
+
if (on_writable_) on_writable_->release();
|
|
260
273
|
if (on_file_offer_) on_file_offer_->release();
|
|
261
274
|
if (on_file_progress_) on_file_progress_->release();
|
|
262
275
|
if (on_file_complete_) on_file_complete_->release();
|
|
@@ -433,6 +446,19 @@ Napi::Value RatsNode::Send(const Napi::CallbackInfo& info) {
|
|
|
433
446
|
return env.Undefined();
|
|
434
447
|
}
|
|
435
448
|
|
|
449
|
+
// send() only says the message was queued. This is how a JS caller learns it is
|
|
450
|
+
// outrunning the link — before the peer is dropped for it.
|
|
451
|
+
Napi::Value RatsNode::PeerWritable(const Napi::CallbackInfo& info) {
|
|
452
|
+
RATS_REQUIRE_NODE(info.Env().Undefined());
|
|
453
|
+
Napi::Env env = info.Env();
|
|
454
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
455
|
+
Napi::TypeError::New(env, "Expected peerId (string)").ThrowAsJavaScriptException();
|
|
456
|
+
return env.Undefined();
|
|
457
|
+
}
|
|
458
|
+
std::string peer = info[0].As<Napi::String>().Utf8Value();
|
|
459
|
+
return Napi::Boolean::New(env, rats_peer_writable(node_, peer.c_str()) != 0);
|
|
460
|
+
}
|
|
461
|
+
|
|
436
462
|
Napi::Value RatsNode::Broadcast(const Napi::CallbackInfo& info) {
|
|
437
463
|
RATS_REQUIRE_NODE(info.Env().Undefined());
|
|
438
464
|
Napi::Env env = info.Env();
|
|
@@ -506,6 +532,29 @@ void RatsNode::OnPeerDisconnected(const Napi::CallbackInfo& info) {
|
|
|
506
532
|
}
|
|
507
533
|
on_disconnected_ = std::make_unique<CbContext>();
|
|
508
534
|
on_disconnected_->init(env, info[0].As<Napi::Function>(), "on_peer_disconnected");
|
|
535
|
+
// Second argument is why the peer went: "RATS_CLOSE_SLOW_CONSUMER" is the one
|
|
536
|
+
// an application can act on (it was sending faster than the link drained).
|
|
537
|
+
// Callbacks that only declare (peerId) are unaffected.
|
|
538
|
+
auto trampoline = [](void* user, const char* peer_id, rats_close_reason_t reason) {
|
|
539
|
+
auto* c = static_cast<CbContext*>(user);
|
|
540
|
+
std::string peer = peer_id ? peer_id : "";
|
|
541
|
+
std::string why = rats_close_reason_str(reason);
|
|
542
|
+
c->tsfn.BlockingCall([peer, why](Napi::Env env, Napi::Function js) {
|
|
543
|
+
js.Call({Napi::String::New(env, peer), Napi::String::New(env, why)});
|
|
544
|
+
});
|
|
545
|
+
};
|
|
546
|
+
throw_on_error(env, rats_on_peer_disconnected(node_, trampoline, on_disconnected_.get()));
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
void RatsNode::OnPeerWritable(const Napi::CallbackInfo& info) {
|
|
550
|
+
RATS_REQUIRE_NODE();
|
|
551
|
+
Napi::Env env = info.Env();
|
|
552
|
+
if (info.Length() < 1 || !info[0].IsFunction()) {
|
|
553
|
+
Napi::TypeError::New(env, "Expected callback function").ThrowAsJavaScriptException();
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
on_writable_ = std::make_unique<CbContext>();
|
|
557
|
+
on_writable_->init(env, info[0].As<Napi::Function>(), "on_peer_writable");
|
|
509
558
|
auto trampoline = [](void* user, const char* peer_id) {
|
|
510
559
|
auto* c = static_cast<CbContext*>(user);
|
|
511
560
|
std::string peer = peer_id ? peer_id : "";
|
|
@@ -513,7 +562,7 @@ void RatsNode::OnPeerDisconnected(const Napi::CallbackInfo& info) {
|
|
|
513
562
|
js.Call({Napi::String::New(env, peer)});
|
|
514
563
|
});
|
|
515
564
|
};
|
|
516
|
-
throw_on_error(env,
|
|
565
|
+
throw_on_error(env, rats_on_peer_writable(node_, trampoline, on_writable_.get()));
|
|
517
566
|
}
|
|
518
567
|
|
|
519
568
|
// ---------------------------------------------------------------------------
|
|
@@ -570,6 +619,28 @@ Napi::Value RatsNode::PunchPeer(const Napi::CallbackInfo& info) {
|
|
|
570
619
|
return env.Undefined();
|
|
571
620
|
}
|
|
572
621
|
|
|
622
|
+
// Relaying. serveAsRelay (default false) also carries OTHER peers' connections,
|
|
623
|
+
// which spends real bandwidth — so it is opted into rather than assumed.
|
|
624
|
+
void RatsNode::EnableRelay(const Napi::CallbackInfo& info) {
|
|
625
|
+
RATS_REQUIRE_NODE();
|
|
626
|
+
int serve = 0;
|
|
627
|
+
if (info.Length() >= 1 && info[0].IsBoolean()) serve = info[0].As<Napi::Boolean>().Value() ? 1 : 0;
|
|
628
|
+
throw_on_error(info.Env(), rats_enable_relay(node_, serve));
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
// Reach a peer through a relay. Non-blocking: success arrives as onPeerConnected.
|
|
632
|
+
Napi::Value RatsNode::ConnectViaRelay(const Napi::CallbackInfo& info) {
|
|
633
|
+
RATS_REQUIRE_NODE(info.Env().Undefined());
|
|
634
|
+
Napi::Env env = info.Env();
|
|
635
|
+
if (info.Length() < 1 || !info[0].IsString()) {
|
|
636
|
+
Napi::TypeError::New(env, "Expected peerId (string)").ThrowAsJavaScriptException();
|
|
637
|
+
return env.Undefined();
|
|
638
|
+
}
|
|
639
|
+
std::string peer = info[0].As<Napi::String>().Utf8Value();
|
|
640
|
+
throw_on_error(env, rats_connect_via_relay(node_, peer.c_str()));
|
|
641
|
+
return env.Undefined();
|
|
642
|
+
}
|
|
643
|
+
|
|
573
644
|
// What the mesh has shown about this node's own NAT (a RATS_NAT_* value).
|
|
574
645
|
Napi::Value RatsNode::GetNatMapping(const Napi::CallbackInfo& info) {
|
|
575
646
|
RATS_REQUIRE_NODE(info.Env().Undefined());
|
|
@@ -978,16 +1049,20 @@ Napi::Object RatsNode::Init(Napi::Env env, Napi::Object exports) {
|
|
|
978
1049
|
// raw channel messaging
|
|
979
1050
|
InstanceMethod("send", &RatsNode::Send),
|
|
980
1051
|
InstanceMethod("broadcast", &RatsNode::Broadcast),
|
|
1052
|
+
InstanceMethod("peerWritable", &RatsNode::PeerWritable),
|
|
981
1053
|
InstanceMethod("on", &RatsNode::On),
|
|
982
1054
|
// peer events
|
|
983
1055
|
InstanceMethod("onPeerConnected", &RatsNode::OnPeerConnected),
|
|
984
1056
|
InstanceMethod("onPeerDisconnected", &RatsNode::OnPeerDisconnected),
|
|
1057
|
+
InstanceMethod("onPeerWritable", &RatsNode::OnPeerWritable),
|
|
985
1058
|
// discovery / NAT
|
|
986
1059
|
InstanceMethod("enableDht", &RatsNode::EnableDht),
|
|
987
1060
|
InstanceMethod("enableMdns", &RatsNode::EnableMdns),
|
|
988
1061
|
InstanceMethod("enablePortMapping", &RatsNode::EnablePortMapping),
|
|
989
1062
|
InstanceMethod("enableHolePunch", &RatsNode::EnableHolePunch),
|
|
990
1063
|
InstanceMethod("punchPeer", &RatsNode::PunchPeer),
|
|
1064
|
+
InstanceMethod("enableRelay", &RatsNode::EnableRelay),
|
|
1065
|
+
InstanceMethod("connectViaRelay", &RatsNode::ConnectViaRelay),
|
|
991
1066
|
InstanceMethod("natMapping", &RatsNode::GetNatMapping),
|
|
992
1067
|
// pub/sub
|
|
993
1068
|
InstanceMethod("enablePubsub", &RatsNode::EnablePubsub),
|