librats 2.2.0 → 2.3.1

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 (28) hide show
  1. package/lib/index.d.ts +30 -2
  2. package/lib/index.js +16 -1
  3. package/native-src/CMakeLists.txt +45 -3
  4. package/native-src/src/librats/bindings/rats.cpp +56 -3
  5. package/native-src/src/librats/bindings/rats.h +62 -1
  6. package/native-src/src/librats/core/types.cpp +1 -1
  7. package/native-src/src/librats/core/types.h +9 -6
  8. package/native-src/src/librats/node/config.h +9 -2
  9. package/native-src/src/librats/node/node.cpp +20 -5
  10. package/native-src/src/librats/node/node.h +26 -6
  11. package/native-src/src/librats/node/peer_network.h +19 -2
  12. package/native-src/src/librats/peer/peer.h +17 -6
  13. package/native-src/src/librats/security/noise_security.cpp +2 -0
  14. package/native-src/src/librats/security/plaintext_security.h +1 -0
  15. package/native-src/src/librats/security/session.h +7 -0
  16. package/native-src/src/librats/storage/storage.cpp +434 -213
  17. package/native-src/src/librats/storage/storage.h +163 -19
  18. package/native-src/src/librats/subsystems/file_transfer.cpp +1 -1
  19. package/native-src/src/librats/subsystems/pubsub.cpp +1 -1
  20. package/native-src/src/librats/subsystems/reconnection.cpp +1 -1
  21. package/native-src/src/librats/subsystems/relay.cpp +2 -1
  22. package/native-src/src/librats/transport/connection.cpp +40 -8
  23. package/native-src/src/librats/transport/connection.h +12 -2
  24. package/native-src/src/librats/util/logger.h +37 -5
  25. package/native-src/src/librats/util/network_monitor.cpp +14 -0
  26. package/native-src/src/librats/util/network_utils.cpp +10 -1
  27. package/package.json +1 -1
  28. package/src/librats_node.cpp +50 -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);
@@ -226,6 +229,13 @@ RatsNode::RatsNode(const Napi::CallbackInfo& info)
226
229
  c.transport_fallback_ms =
227
230
  cfg.Get("transportFallbackMs").As<Napi::Number>().Uint32Value();
228
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
+
229
239
  node_ = rats_create_config(&c);
230
240
  } else {
231
241
  int port = 0;
@@ -259,6 +269,7 @@ RatsNode::~RatsNode() {
259
269
  void RatsNode::Teardown() {
260
270
  if (on_connected_) on_connected_->release();
261
271
  if (on_disconnected_) on_disconnected_->release();
272
+ if (on_writable_) on_writable_->release();
262
273
  if (on_file_offer_) on_file_offer_->release();
263
274
  if (on_file_progress_) on_file_progress_->release();
264
275
  if (on_file_complete_) on_file_complete_->release();
@@ -435,6 +446,19 @@ Napi::Value RatsNode::Send(const Napi::CallbackInfo& info) {
435
446
  return env.Undefined();
436
447
  }
437
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
+
438
462
  Napi::Value RatsNode::Broadcast(const Napi::CallbackInfo& info) {
439
463
  RATS_REQUIRE_NODE(info.Env().Undefined());
440
464
  Napi::Env env = info.Env();
@@ -508,6 +532,29 @@ void RatsNode::OnPeerDisconnected(const Napi::CallbackInfo& info) {
508
532
  }
509
533
  on_disconnected_ = std::make_unique<CbContext>();
510
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");
511
558
  auto trampoline = [](void* user, const char* peer_id) {
512
559
  auto* c = static_cast<CbContext*>(user);
513
560
  std::string peer = peer_id ? peer_id : "";
@@ -515,7 +562,7 @@ void RatsNode::OnPeerDisconnected(const Napi::CallbackInfo& info) {
515
562
  js.Call({Napi::String::New(env, peer)});
516
563
  });
517
564
  };
518
- 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()));
519
566
  }
520
567
 
521
568
  // ---------------------------------------------------------------------------
@@ -1002,10 +1049,12 @@ Napi::Object RatsNode::Init(Napi::Env env, Napi::Object exports) {
1002
1049
  // raw channel messaging
1003
1050
  InstanceMethod("send", &RatsNode::Send),
1004
1051
  InstanceMethod("broadcast", &RatsNode::Broadcast),
1052
+ InstanceMethod("peerWritable", &RatsNode::PeerWritable),
1005
1053
  InstanceMethod("on", &RatsNode::On),
1006
1054
  // peer events
1007
1055
  InstanceMethod("onPeerConnected", &RatsNode::OnPeerConnected),
1008
1056
  InstanceMethod("onPeerDisconnected", &RatsNode::OnPeerDisconnected),
1057
+ InstanceMethod("onPeerWritable", &RatsNode::OnPeerWritable),
1009
1058
  // discovery / NAT
1010
1059
  InstanceMethod("enableDht", &RatsNode::EnableDht),
1011
1060
  InstanceMethod("enableMdns", &RatsNode::EnableMdns),