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.
Files changed (40) hide show
  1. package/README.md +9 -0
  2. package/lib/index.d.ts +51 -6
  3. package/lib/index.js +42 -3
  4. package/native-src/CMakeLists.txt +13 -0
  5. package/native-src/src/librats/bindings/rats.cpp +90 -6
  6. package/native-src/src/librats/bindings/rats.h +92 -3
  7. package/native-src/src/librats/core/types.cpp +4 -3
  8. package/native-src/src/librats/core/types.h +25 -12
  9. package/native-src/src/librats/node/circuit_service.h +84 -0
  10. package/native-src/src/librats/node/config.h +9 -2
  11. package/native-src/src/librats/node/node.cpp +59 -5
  12. package/native-src/src/librats/node/node.h +38 -7
  13. package/native-src/src/librats/node/peer_network.h +19 -2
  14. package/native-src/src/librats/peer/peer.h +17 -6
  15. package/native-src/src/librats/peer/peer_table.cpp +41 -8
  16. package/native-src/src/librats/security/noise_security.cpp +2 -0
  17. package/native-src/src/librats/security/plaintext_security.h +1 -0
  18. package/native-src/src/librats/security/session.h +7 -0
  19. package/native-src/src/librats/storage/storage.cpp +434 -213
  20. package/native-src/src/librats/storage/storage.h +163 -19
  21. package/native-src/src/librats/subsystems/file_transfer.cpp +1 -1
  22. package/native-src/src/librats/subsystems/hole_punch.cpp +81 -8
  23. package/native-src/src/librats/subsystems/hole_punch.h +24 -0
  24. package/native-src/src/librats/subsystems/pubsub.cpp +1 -1
  25. package/native-src/src/librats/subsystems/reconnection.cpp +1 -1
  26. package/native-src/src/librats/subsystems/relay.cpp +1143 -0
  27. package/native-src/src/librats/subsystems/relay.h +211 -0
  28. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  29. package/native-src/src/librats/transport/connection.cpp +40 -8
  30. package/native-src/src/librats/transport/connection.h +12 -2
  31. package/native-src/src/librats/transport/reactor.cpp +56 -8
  32. package/native-src/src/librats/transport/reactor.h +38 -0
  33. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  34. package/native-src/src/librats/transport/relay_link.h +303 -0
  35. package/native-src/src/librats/util/logger.h +37 -5
  36. package/native-src/src/librats/util/network_monitor.cpp +14 -0
  37. package/native-src/src/librats/util/network_utils.cpp +10 -1
  38. package/native-src/src/librats/wire/frame.h +1 -0
  39. package/package.json +1 -1
  40. package/src/librats_node.cpp +76 -1
@@ -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, rats_on_peer_disconnected(node_, trampoline, on_disconnected_.get()));
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),