react-native-nitro-net 0.1.5 → 0.2.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 (48) hide show
  1. package/README.md +56 -4
  2. package/android/libs/arm64-v8a/librust_c_net.so +0 -0
  3. package/android/libs/armeabi-v7a/librust_c_net.so +0 -0
  4. package/android/libs/x86/librust_c_net.so +0 -0
  5. package/android/libs/x86_64/librust_c_net.so +0 -0
  6. package/cpp/HybridNetDriver.hpp +68 -0
  7. package/cpp/HybridNetServerDriver.hpp +9 -0
  8. package/cpp/HybridNetSocketDriver.hpp +149 -0
  9. package/cpp/NetBindings.hpp +52 -1
  10. package/ios/Frameworks/RustCNet.xcframework/Info.plist +5 -5
  11. package/ios/Frameworks/RustCNet.xcframework/ios-arm64/RustCNet.framework/RustCNet +0 -0
  12. package/ios/Frameworks/RustCNet.xcframework/ios-arm64_x86_64-simulator/RustCNet.framework/RustCNet +0 -0
  13. package/lib/Net.nitro.d.ts +27 -1
  14. package/lib/Net.nitro.js +3 -1
  15. package/lib/index.d.ts +4 -3
  16. package/lib/index.js +47 -6
  17. package/lib/tls.d.ts +124 -0
  18. package/lib/tls.js +451 -0
  19. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.cpp +38 -1
  20. package/nitrogen/generated/android/c++/JHybridNetDriverSpec.hpp +8 -0
  21. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.cpp +4 -0
  22. package/nitrogen/generated/android/c++/JHybridNetServerDriverSpec.hpp +1 -0
  23. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.cpp +70 -0
  24. package/nitrogen/generated/android/c++/JHybridNetSocketDriverSpec.hpp +15 -0
  25. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetDriverSpec.kt +33 -0
  26. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetServerDriverSpec.kt +4 -0
  27. package/nitrogen/generated/android/kotlin/com/margelo/nitro/net/HybridNetSocketDriverSpec.kt +60 -0
  28. package/nitrogen/generated/ios/RustCNet-Swift-Cxx-Bridge.hpp +95 -44
  29. package/nitrogen/generated/ios/c++/HybridNetDriverSpecSwift.hpp +58 -0
  30. package/nitrogen/generated/ios/c++/HybridNetServerDriverSpecSwift.hpp +6 -0
  31. package/nitrogen/generated/ios/c++/HybridNetSocketDriverSpecSwift.hpp +109 -0
  32. package/nitrogen/generated/ios/swift/HybridNetDriverSpec.swift +8 -0
  33. package/nitrogen/generated/ios/swift/HybridNetDriverSpec_cxx.swift +118 -0
  34. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec.swift +1 -0
  35. package/nitrogen/generated/ios/swift/HybridNetServerDriverSpec_cxx.swift +25 -0
  36. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec.swift +15 -0
  37. package/nitrogen/generated/ios/swift/HybridNetSocketDriverSpec_cxx.swift +278 -0
  38. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.cpp +8 -0
  39. package/nitrogen/generated/shared/c++/HybridNetDriverSpec.hpp +9 -0
  40. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.cpp +1 -0
  41. package/nitrogen/generated/shared/c++/HybridNetServerDriverSpec.hpp +1 -0
  42. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.cpp +15 -0
  43. package/nitrogen/generated/shared/c++/HybridNetSocketDriverSpec.hpp +16 -0
  44. package/package.json +5 -3
  45. package/react-native-nitro-net.podspec +1 -3
  46. package/src/Net.nitro.ts +27 -1
  47. package/src/index.ts +18 -9
  48. package/src/tls.ts +532 -0
package/README.md CHANGED
@@ -5,9 +5,11 @@ Node.js `net` API implementation for React Native using [Nitro Modules](https://
5
5
  ## Features
6
6
 
7
7
  * 🚀 **High Performance**: Built on top of Rust's `tokio` asynchronous runtime.
8
- * 🤝 **Node.js Compatible**: Implements the standard `net` API including `Socket` (Duplex stream) and `Server`.
8
+ * 🤝 **Node.js Compatible**: Implements standard `net` and `tls` APIs including `Socket`, `Server`, `TLSSocket`, and `SecureContext`.
9
+ * 🛡️ **Modern Security**: TLS implementation powered by **Rustls 0.23** (Ring provider), supporting TLS 1.2 and 1.3.
10
+ * 🔒 **Full TLS Support**: Support for PEM/PFX certificates, encrypted private keys, SNI, Session tickets, and 100% Node.js API surface compatibility.
9
11
  * ⚡ **Nitro Modules**: Uses JSI for zero-overhead communication between JavaScript and Native code.
10
- * 🛡️ **Robust & Stable**: Advanced fixes for common networking issues like port reuse, deadlocks, and DNS reliability.
12
+ * 🛡️ **Robust & Stable**: Advanced fixes for port reuse, deadlocks, and DNS reliability.
11
13
  * 📱 **Cross-Platform**: Supports both iOS and Android.
12
14
 
13
15
  ## Installation
@@ -30,7 +32,7 @@ cd ios && pod install
30
32
 
31
33
  This library uses a high-performance three-layer architecture:
32
34
 
33
- 1. **JavaScript Layer**: Provides the high-level Node.js compatible `net.Socket` (Duplex) and `net.Server` APIs using `readable-stream` and `EventEmitter`.
35
+ 1. **JavaScript Layer**: Provides high-level Node.js compatible `net` and `tls` APIs using `readable-stream` and `EventEmitter`.
34
36
  2. **C++ Bridge (Nitro)**: Handles the zero-copy orchestration between JS and Rust using Nitro Hybrid Objects and JSI.
35
37
  3. **Rust Core**: Implements the actual networking logic using the **Tokio** asynchronous runtime, providing memory safety and high concurrency.
36
38
 
@@ -73,6 +75,31 @@ server.listen(0, '127.0.0.1', () => {
73
75
  });
74
76
  ```
75
77
 
78
+ ### TLS (Secure Socket)
79
+
80
+ ```typescript
81
+ import { tls } from 'react-native-nitro-net';
82
+
83
+ // Client connection
84
+ const socket = tls.connect({
85
+ host: 'example.com',
86
+ port: 443,
87
+ servername: 'example.com', // SNI
88
+ }, () => {
89
+ console.log('Securely connected!');
90
+ console.log('Protocol:', socket.getProtocol());
91
+ });
92
+
93
+ // Server with PFX
94
+ const server = tls.createServer({
95
+ pfx: fs.readFileSync('server.pfx'),
96
+ passphrase: 'your-password'
97
+ }, (socket) => {
98
+ socket.write('Secure hello!');
99
+ });
100
+ server.listen(443);
101
+ ```
102
+
76
103
  ## Stability Improvements
77
104
 
78
105
  We have implemented several critical fixes to ensure production-grade stability:
@@ -82,6 +109,11 @@ We have implemented several critical fixes to ensure production-grade stability:
82
109
  * **DNS Reliability**: Automatically retries all resolved IP addresses if the first one fails to connect.
83
110
  * **Resource Management**: Strict protective shutdown logic in Rust to prevent socket and Unix domain socket file leaks.
84
111
 
112
+ ## Compatibility Notes
113
+
114
+ > [!IMPORTANT]
115
+ > **`Server.close()` Behavior**: Unlike Node.js's default behavior where `server.close()` only stops accepting new connections, this implementation **immediately destroys all active connections** when `close()` is called. This ensures clean resource release and is more intuitive for mobile applications.
116
+
85
117
  ## API Reference
86
118
 
87
119
  ### `net.Socket`
@@ -97,6 +129,20 @@ We have implemented several critical fixes to ensure production-grade stability:
97
129
 
98
130
  **Events**: `connect`, `ready`, `data`, `error`, `close`, `timeout`, `lookup`.
99
131
 
132
+ ### `tls.TLSSocket`
133
+ *Extends `net.Socket`*
134
+
135
+ | Property / Method | Description |
136
+ | --- | --- |
137
+ | `authorized` | `true` if peer certificate is verified. |
138
+ | `getProtocol()` | Returns negotiated TLS version (e.g., "TLSv1.3"). |
139
+ | `getCipher()` | Returns current cipher information. |
140
+ | `getPeerCertificate()`| Returns detailed JSON of the peer certificate. |
141
+ | `getSession()` | Returns the session ticket for resumption. |
142
+ | `encrypted` | Always `true`. |
143
+
144
+ **Events**: `secureConnect`, `session`, `keylog`, `OCSPResponse`.
145
+
100
146
  ### Global APIs
101
147
 
102
148
  | Method | Description |
@@ -110,12 +156,18 @@ We have implemented several critical fixes to ensure production-grade stability:
110
156
  | Method | Description |
111
157
  | --- | --- |
112
158
  | `listen(options)` | Start listening. Supports `port: 0` for dynamic allocation. |
113
- | `close()` | Stops the server from accepting new connections. |
159
+ | `close()` | Stops the server and **destroys all active connections**. |
114
160
  | `address()` | Returns the bound address (crucial for dynamic ports). |
115
161
  | `getConnections(cb)`| Get count of active connections. |
116
162
 
117
163
  **Events**: `listening`, `connection`, `error`, `close`.
118
164
 
165
+ ### `tls.Server`
166
+ *Extends `net.Server`*
167
+
168
+ Supported methods: `listen`, `close`, `addContext`, `setTicketKeys`, `getTicketKeys`.
169
+ **Events**: `secureConnection`, `keylog`, `newSession`.
170
+
119
171
  ## Debugging
120
172
 
121
173
  Enable verbose logging to see the internal data flow across JS, C++, and Rust:
Binary file
@@ -4,11 +4,16 @@
4
4
  #include "HybridNetServerDriver.hpp"
5
5
  #include "HybridNetSocketDriver.hpp"
6
6
  #include "NetManager.hpp"
7
+ #include <NitroModules/ArrayBuffer.hpp>
8
+ #include <optional>
9
+ #include <string>
7
10
 
8
11
  namespace margelo {
9
12
  namespace nitro {
10
13
  namespace net {
11
14
 
15
+ using namespace margelo::nitro;
16
+
12
17
  class HybridNetDriver : public HybridNetDriverSpec {
13
18
  public:
14
19
  HybridNetDriver() : HybridObject(TAG) {}
@@ -31,6 +36,69 @@ public:
31
36
  return std::make_shared<HybridNetServerDriver>();
32
37
  }
33
38
 
39
+ double
40
+ createSecureContext(const std::string &cert, const std::string &key,
41
+ const std::optional<std::string> &passphrase) override {
42
+ return static_cast<double>(net_create_secure_context(
43
+ cert.c_str(), key.c_str(),
44
+ passphrase.has_value() ? passphrase.value().c_str() : nullptr));
45
+ }
46
+
47
+ double createEmptySecureContext() override {
48
+ return static_cast<double>(net_secure_context_create());
49
+ }
50
+
51
+ void addCACertToSecureContext(double scId, const std::string &ca) override {
52
+ net_secure_context_add_ca(static_cast<uint32_t>(scId), ca.c_str());
53
+ }
54
+
55
+ void addContextToSecureContext(
56
+ double scId, const std::string &hostname, const std::string &cert,
57
+ const std::string &key,
58
+ const std::optional<std::string> &passphrase) override {
59
+ net_secure_context_add_context(
60
+ static_cast<uint32_t>(scId), hostname.c_str(), cert.c_str(),
61
+ key.c_str(),
62
+ passphrase.has_value() ? passphrase.value().c_str() : nullptr);
63
+ }
64
+
65
+ void
66
+ setPFXToSecureContext(double scId, const std::shared_ptr<ArrayBuffer> &pfx,
67
+ const std::optional<std::string> &passphrase) override {
68
+ if (pfx) {
69
+ net_secure_context_set_pfx(
70
+ static_cast<uint32_t>(scId), pfx->data(), pfx->size(),
71
+ passphrase.has_value() ? passphrase.value().c_str() : nullptr);
72
+ }
73
+ }
74
+
75
+ void setOCSPResponseToSecureContext(
76
+ double scId, const std::shared_ptr<ArrayBuffer> &ocsp) override {
77
+ if (ocsp) {
78
+ net_secure_context_set_ocsp_response(static_cast<uint32_t>(scId),
79
+ ocsp->data(), ocsp->size());
80
+ }
81
+ }
82
+
83
+ std::optional<std::shared_ptr<ArrayBuffer>>
84
+ getTicketKeys(double scId) override {
85
+ uint8_t buf[256];
86
+ size_t len = net_server_get_ticket_keys(static_cast<uint32_t>(scId), buf,
87
+ sizeof(buf));
88
+ if (len > 0) {
89
+ return ArrayBuffer::copy(buf, len);
90
+ }
91
+ return std::nullopt;
92
+ }
93
+
94
+ void setTicketKeys(double scId,
95
+ const std::shared_ptr<ArrayBuffer> &keys) override {
96
+ if (keys) {
97
+ net_server_set_ticket_keys(static_cast<uint32_t>(scId), keys->data(),
98
+ keys->size());
99
+ }
100
+ }
101
+
34
102
  void initWithConfig(const NetConfig &config) override {
35
103
  uint32_t workerThreads = config.workerThreads.value_or(0);
36
104
  NetManager::shared().initWithConfig(workerThreads);
@@ -49,6 +49,15 @@ public:
49
49
  ipv6Only.value_or(false), reusePort.value_or(false));
50
50
  }
51
51
 
52
+ void listenTLS(double port, double secureContextId,
53
+ std::optional<double> backlog, std::optional<bool> ipv6Only,
54
+ std::optional<bool> reusePort) override {
55
+ net_listen_tls(_id, static_cast<int>(port),
56
+ static_cast<int>(backlog.value_or(128)),
57
+ ipv6Only.value_or(false), reusePort.value_or(false),
58
+ static_cast<uint32_t>(secureContextId));
59
+ }
60
+
52
61
  void listenUnix(const std::string &path,
53
62
  std::optional<double> backlog) override {
54
63
  net_listen_unix(_id, path.c_str(), static_cast<int>(backlog.value_or(128)));
@@ -4,12 +4,15 @@
4
4
  #include "NetBindings.hpp"
5
5
  #include "NetManager.hpp"
6
6
  #include <NitroModules/ArrayBuffer.hpp>
7
+ #include <optional>
7
8
  #include <string>
8
9
 
9
10
  namespace margelo {
10
11
  namespace nitro {
11
12
  namespace net {
12
13
 
14
+ using namespace margelo::nitro;
15
+
13
16
  class HybridNetSocketDriver : public HybridNetSocketDriverSpec {
14
17
  public:
15
18
  HybridNetSocketDriver() : HybridObject(TAG) {
@@ -48,6 +51,111 @@ public:
48
51
  net_connect(_id, host.c_str(), static_cast<int>(port));
49
52
  }
50
53
 
54
+ void connectTLS(const std::string &host, double port,
55
+ const std::optional<std::string> &serverName,
56
+ std::optional<bool> rejectUnauthorized) override {
57
+ const char *sni = serverName.has_value() ? serverName->c_str() : nullptr;
58
+ bool ru = rejectUnauthorized.value_or(true);
59
+ net_connect_tls(_id, host.c_str(), static_cast<int>(port), sni,
60
+ static_cast<int>(ru));
61
+ }
62
+
63
+ void connectTLSWithContext(const std::string &host, double port,
64
+ const std::optional<std::string> &serverName,
65
+ std::optional<bool> rejectUnauthorized,
66
+ std::optional<double> secureContextId) override {
67
+ const char *sni = serverName.has_value() ? serverName->c_str() : nullptr;
68
+ bool ru = rejectUnauthorized.value_or(true);
69
+ if (secureContextId.has_value()) {
70
+ net_connect_tls_with_context(
71
+ _id, host.c_str(), static_cast<int>(port), sni, static_cast<int>(ru),
72
+ static_cast<uint32_t>(secureContextId.value()));
73
+ } else {
74
+ net_connect_tls(_id, host.c_str(), static_cast<int>(port), sni,
75
+ static_cast<int>(ru));
76
+ }
77
+ }
78
+
79
+ std::optional<std::string> getAuthorizationError() override {
80
+ char buf[1024];
81
+ size_t len = net_get_authorization_error(_id, buf, sizeof(buf));
82
+ if (len > 0) {
83
+ return std::string(buf);
84
+ }
85
+ return std::nullopt;
86
+ }
87
+
88
+ std::optional<std::string> getProtocol() override {
89
+ char buf[128];
90
+ size_t len = net_get_protocol(_id, buf, sizeof(buf));
91
+ if (len > 0) {
92
+ return std::string(buf);
93
+ }
94
+ return std::nullopt;
95
+ }
96
+
97
+ std::optional<std::string> getCipher() override {
98
+ char buf[256];
99
+ size_t len = net_get_cipher(_id, buf, sizeof(buf));
100
+ if (len > 0) {
101
+ return std::string(buf);
102
+ }
103
+ return std::nullopt;
104
+ }
105
+
106
+ std::optional<std::string> getALPN() override {
107
+ char buf[64];
108
+ size_t len = net_get_alpn(_id, buf, sizeof(buf));
109
+ if (len > 0) {
110
+ return std::string(buf);
111
+ }
112
+ return std::nullopt;
113
+ }
114
+
115
+ std::optional<std::string> getPeerCertificateJSON() override {
116
+ char buf[16384];
117
+ size_t len = net_get_peer_certificate_json(_id, buf, sizeof(buf));
118
+ if (len > 0) {
119
+ return std::string(buf, len);
120
+ }
121
+ return std::nullopt;
122
+ }
123
+
124
+ std::optional<std::string> getEphemeralKeyInfo() override {
125
+ char buf[512];
126
+ size_t len = net_get_ephemeral_key_info(_id, buf, sizeof(buf));
127
+ if (len > 0) {
128
+ return std::string(buf, len);
129
+ }
130
+ return std::nullopt;
131
+ }
132
+
133
+ std::optional<std::string> getSharedSigalgs() override {
134
+ char buf[1024];
135
+ size_t len = net_get_shared_sigalgs(_id, buf, sizeof(buf));
136
+ if (len > 0) {
137
+ return std::string(buf, len);
138
+ }
139
+ return std::nullopt;
140
+ }
141
+
142
+ bool isSessionReused() override { return net_is_session_reused(_id); }
143
+
144
+ std::optional<std::shared_ptr<ArrayBuffer>> getSession() override {
145
+ uint8_t buf[2048];
146
+ size_t len = net_get_session(_id, buf, sizeof(buf));
147
+ if (len > 0) {
148
+ return ArrayBuffer::copy(buf, len);
149
+ }
150
+ return std::nullopt;
151
+ }
152
+
153
+ void setSession(const std::shared_ptr<ArrayBuffer> &session) override {
154
+ if (session && session->size() > 0) {
155
+ net_set_session(_id, session->data(), session->size());
156
+ }
157
+ }
158
+
51
159
  void write(const std::shared_ptr<ArrayBuffer> &data) override {
52
160
  if (!data)
53
161
  return;
@@ -70,6 +178,8 @@ public:
70
178
  }
71
179
  }
72
180
 
181
+ void enableKeylog() override { net_socket_enable_keylog(_id); }
182
+
73
183
  void setNoDelay(bool enable) override { net_set_nodelay(_id, enable); }
74
184
 
75
185
  void setKeepAlive(bool enable, double delay) override {
@@ -107,6 +217,45 @@ public:
107
217
  net_connect_unix(_id, path.c_str());
108
218
  }
109
219
 
220
+ void connectUnixTLS(const std::string &path,
221
+ const std::optional<std::string> &serverName,
222
+ std::optional<bool> rejectUnauthorized) override {
223
+ #if !defined(__ANDROID__)
224
+ const char *sni = serverName.has_value() ? serverName->c_str() : "";
225
+ bool ru = rejectUnauthorized.value_or(true);
226
+ net_connect_unix_tls(_id, path.c_str(), sni, static_cast<int>(ru));
227
+ #else
228
+ // Unix TLS not supported on Android
229
+ (void)path;
230
+ (void)serverName;
231
+ (void)rejectUnauthorized;
232
+ #endif
233
+ }
234
+
235
+ void
236
+ connectUnixTLSWithContext(const std::string &path,
237
+ const std::optional<std::string> &serverName,
238
+ std::optional<bool> rejectUnauthorized,
239
+ std::optional<double> secureContextId) override {
240
+ #if !defined(__ANDROID__)
241
+ const char *sni = serverName.has_value() ? serverName->c_str() : "";
242
+ bool ru = rejectUnauthorized.value_or(true);
243
+ if (secureContextId.has_value()) {
244
+ net_connect_unix_tls_with_context(
245
+ _id, path.c_str(), sni, static_cast<int>(ru),
246
+ static_cast<uint32_t>(secureContextId.value()));
247
+ } else {
248
+ net_connect_unix_tls(_id, path.c_str(), sni, static_cast<int>(ru));
249
+ }
250
+ #else
251
+ // Unix TLS not supported on Android
252
+ (void)path;
253
+ (void)serverName;
254
+ (void)rejectUnauthorized;
255
+ (void)secureContextId;
256
+ #endif
257
+ }
258
+
110
259
  private:
111
260
  void onNativeEvent(int type, const uint8_t *data, size_t len) {
112
261
  if (!_onEvent)
@@ -21,11 +21,27 @@ void net_init_with_config(NetCallback callback, void *context,
21
21
  // Socket
22
22
  uint32_t net_create_socket();
23
23
  void net_connect(uint32_t id, const char *host, int port);
24
+ void net_connect_tls(uint32_t id, const char *host, int port,
25
+ const char *server_name, int reject_unauthorized);
26
+ void net_connect_tls_with_context(uint32_t id, const char *host, int port,
27
+ const char *server_name,
28
+ int reject_unauthorized,
29
+ uint32_t secure_context_id);
30
+ size_t net_get_authorization_error(uint32_t id, char *buf, size_t len);
31
+ size_t net_get_protocol(uint32_t id, char *buf, size_t len);
32
+ size_t net_get_cipher(uint32_t id, char *buf, size_t len);
33
+ size_t net_get_alpn(uint32_t id, char *buf, size_t len);
34
+ size_t net_get_peer_certificate_json(uint32_t id, char *buf, size_t len);
35
+ void net_socket_enable_keylog(uint32_t id);
24
36
  void net_write(uint32_t id, const uint8_t *data, size_t len);
25
37
  void net_close(uint32_t id);
26
38
  void net_destroy_socket(uint32_t id);
27
39
  void net_socket_reset_and_destroy(uint32_t id);
28
40
 
41
+ // Phase 13: Advanced TLS inspection
42
+ size_t net_get_ephemeral_key_info(uint32_t id, char *buf, size_t len);
43
+ size_t net_get_shared_sigalgs(uint32_t id, char *buf, size_t len);
44
+
29
45
  // New Options
30
46
  void net_set_nodelay(uint32_t id, bool enable);
31
47
  void net_set_keepalive(uint32_t id, bool enable, uint64_t delay_ms);
@@ -41,28 +57,63 @@ void net_pause(uint32_t id);
41
57
  void net_resume(uint32_t id);
42
58
  void net_shutdown(uint32_t id);
43
59
 
44
- // IPC
60
+ // IPC / Unix Domain Sockets
45
61
  void net_connect_unix(uint32_t id, const char *path);
46
62
  void net_listen_unix(uint32_t id, const char *path, int backlog);
47
63
 
64
+ #if !defined(__ANDROID__)
65
+ // Unix-only TLS functions (not available on Android)
66
+ void net_connect_unix_tls(uint32_t id, const char *path,
67
+ const char *server_name, int reject_unauthorized);
68
+ void net_connect_unix_tls_with_context(uint32_t id, const char *path,
69
+ const char *server_name,
70
+ int reject_unauthorized,
71
+ uint32_t secure_context_id);
72
+ #endif
73
+
48
74
  // Server
49
75
  uint32_t net_create_server();
50
76
  void net_listen(uint32_t id, int port, int backlog, bool ipv6_only,
51
77
  bool reuse_port);
78
+ void net_listen_tls(uint32_t id, int port, int backlog, bool ipv6_only,
79
+ bool reuse_port, uint32_t secure_context_id);
52
80
  void net_server_close(uint32_t id);
53
81
  void net_destroy_server(uint32_t id);
54
82
  void net_server_set_max_connections(uint32_t id, int max_connections);
55
83
  size_t net_get_server_local_address(uint32_t id, char *buf, size_t len);
84
+ uint32_t net_create_secure_context(const char *cert_pem, const char *key_pem,
85
+ const char *passphrase);
86
+ uint32_t net_secure_context_create();
87
+ void net_secure_context_add_ca(uint32_t sc_id, const char *ca_pem);
88
+ void net_secure_context_set_cert_key(uint32_t sc_id, const char *cert_pem,
89
+ const char *key_pem,
90
+ const char *passphrase);
91
+ void net_secure_context_add_context(uint32_t sc_id, const char *hostname,
92
+ const char *cert_pem, const char *key_pem,
93
+ const char *passphrase);
94
+ void net_secure_context_set_pfx(uint32_t sc_id, const uint8_t *data, size_t len,
95
+ const char *passphrase);
96
+ void net_secure_context_set_ocsp_response(uint32_t sc_id, const uint8_t *data,
97
+ size_t len);
56
98
  /// Listen on an existing file descriptor (handle)
57
99
  /// @param id Server ID
58
100
  /// @param fd File descriptor of an already-bound TCP listener
59
101
  /// @param backlog Listen backlog
60
102
  void net_listen_handle(uint32_t id, int fd, int backlog);
61
103
 
104
+ // Session
105
+ bool net_is_session_reused(uint32_t id);
106
+ size_t net_get_session(uint32_t id, uint8_t *buf, size_t len);
107
+ void net_set_session(uint32_t id, const uint8_t *ticket, size_t ticket_len);
108
+ size_t net_server_get_ticket_keys(uint32_t id, uint8_t *buf, size_t len);
109
+ void net_server_set_ticket_keys(uint32_t id, const uint8_t *keys, size_t len);
110
+
62
111
  // Event Types
63
112
  #define NET_EVENT_CONNECT 1
64
113
  #define NET_EVENT_DATA 2
65
114
  #define NET_EVENT_ERROR 3
66
115
  #define NET_EVENT_CLOSE 4
67
116
  #define NET_EVENT_CONNECTION 6
117
+ #define NET_EVENT_KEYLOG 10
118
+ #define NET_EVENT_OCSP 11
68
119
  }
@@ -8,32 +8,32 @@
8
8
  <key>BinaryPath</key>
9
9
  <string>RustCNet.framework/RustCNet</string>
10
10
  <key>LibraryIdentifier</key>
11
- <string>ios-arm64_x86_64-simulator</string>
11
+ <string>ios-arm64</string>
12
12
  <key>LibraryPath</key>
13
13
  <string>RustCNet.framework</string>
14
14
  <key>SupportedArchitectures</key>
15
15
  <array>
16
16
  <string>arm64</string>
17
- <string>x86_64</string>
18
17
  </array>
19
18
  <key>SupportedPlatform</key>
20
19
  <string>ios</string>
21
- <key>SupportedPlatformVariant</key>
22
- <string>simulator</string>
23
20
  </dict>
24
21
  <dict>
25
22
  <key>BinaryPath</key>
26
23
  <string>RustCNet.framework/RustCNet</string>
27
24
  <key>LibraryIdentifier</key>
28
- <string>ios-arm64</string>
25
+ <string>ios-arm64_x86_64-simulator</string>
29
26
  <key>LibraryPath</key>
30
27
  <string>RustCNet.framework</string>
31
28
  <key>SupportedArchitectures</key>
32
29
  <array>
33
30
  <string>arm64</string>
31
+ <string>x86_64</string>
34
32
  </array>
35
33
  <key>SupportedPlatform</key>
36
34
  <string>ios</string>
35
+ <key>SupportedPlatformVariant</key>
36
+ <string>simulator</string>
37
37
  </dict>
38
38
  </array>
39
39
  <key>CFBundlePackageType</key>
@@ -15,7 +15,9 @@ export declare enum NetSocketEvent {
15
15
  DRAIN = 5,
16
16
  TIMEOUT = 7,
17
17
  LOOKUP = 8,
18
- DEBUG = 9
18
+ SESSION = 9,
19
+ KEYLOG = 10,
20
+ OCSP = 11
19
21
  }
20
22
  export interface NetSocketDriver extends HybridObject<{
21
23
  ios: 'swift';
@@ -23,7 +25,21 @@ export interface NetSocketDriver extends HybridObject<{
23
25
  }> {
24
26
  readonly id: number;
25
27
  connect(host: string, port: number): void;
28
+ connectTLS(host: string, port: number, serverName?: string, rejectUnauthorized?: boolean): void;
29
+ connectTLSWithContext(host: string, port: number, serverName?: string, rejectUnauthorized?: boolean, secureContextId?: number): void;
30
+ getAuthorizationError(): string | undefined;
31
+ getProtocol(): string | undefined;
32
+ getCipher(): string | undefined;
33
+ getALPN(): string | undefined;
34
+ getPeerCertificateJSON(): string | undefined;
35
+ getEphemeralKeyInfo(): string | undefined;
36
+ getSharedSigalgs(): string | undefined;
37
+ isSessionReused(): boolean;
38
+ getSession(): ArrayBuffer | undefined;
39
+ setSession(session: ArrayBuffer): void;
26
40
  connectUnix(path: string): void;
41
+ connectUnixTLS(path: string, serverName?: string, rejectUnauthorized?: boolean): void;
42
+ connectUnixTLSWithContext(path: string, serverName?: string, rejectUnauthorized?: boolean, secureContextId?: number): void;
27
43
  write(data: ArrayBuffer): void;
28
44
  pause(): void;
29
45
  resume(): void;
@@ -31,6 +47,7 @@ export interface NetSocketDriver extends HybridObject<{
31
47
  setTimeout(timeout: number): void;
32
48
  destroy(): void;
33
49
  resetAndDestroy(): void;
50
+ enableKeylog(): void;
34
51
  setNoDelay(enable: boolean): void;
35
52
  setKeepAlive(enable: boolean, delay: number): void;
36
53
  getLocalAddress(): string;
@@ -49,6 +66,7 @@ export interface NetServerDriver extends HybridObject<{
49
66
  }> {
50
67
  onEvent: (event: number, data: ArrayBuffer) => void;
51
68
  listen(port: number, backlog?: number, ipv6Only?: boolean, reusePort?: boolean): void;
69
+ listenTLS(port: number, secureContextId: number, backlog?: number, ipv6Only?: boolean, reusePort?: boolean): void;
52
70
  listenUnix(path: string, backlog?: number): void;
53
71
  /**
54
72
  * Listen on an existing file descriptor (handle)
@@ -76,6 +94,14 @@ export interface NetDriver extends HybridObject<{
76
94
  }> {
77
95
  createSocket(id?: string): NetSocketDriver;
78
96
  createServer(): NetServerDriver;
97
+ createSecureContext(cert: string, key: string, passphrase?: string): number;
98
+ createEmptySecureContext(): number;
99
+ addCACertToSecureContext(scId: number, ca: string): void;
100
+ addContextToSecureContext(scId: number, hostname: string, cert: string, key: string, passphrase?: string): void;
101
+ setPFXToSecureContext(scId: number, pfx: ArrayBuffer, passphrase?: string): void;
102
+ setOCSPResponseToSecureContext(scId: number, ocsp: ArrayBuffer): void;
103
+ getTicketKeys(scId: number): ArrayBuffer | undefined;
104
+ setTicketKeys(scId: number, keys: ArrayBuffer): void;
79
105
  /**
80
106
  * Initialize the network module with custom configuration
81
107
  * Must be called before any other network operations
package/lib/Net.nitro.js CHANGED
@@ -10,7 +10,9 @@ var NetSocketEvent;
10
10
  NetSocketEvent[NetSocketEvent["DRAIN"] = 5] = "DRAIN";
11
11
  NetSocketEvent[NetSocketEvent["TIMEOUT"] = 7] = "TIMEOUT";
12
12
  NetSocketEvent[NetSocketEvent["LOOKUP"] = 8] = "LOOKUP";
13
- NetSocketEvent[NetSocketEvent["DEBUG"] = 9] = "DEBUG";
13
+ NetSocketEvent[NetSocketEvent["SESSION"] = 9] = "SESSION";
14
+ NetSocketEvent[NetSocketEvent["KEYLOG"] = 10] = "KEYLOG";
15
+ NetSocketEvent[NetSocketEvent["OCSP"] = 11] = "OCSP";
14
16
  })(NetSocketEvent || (exports.NetSocketEvent = NetSocketEvent = {}));
15
17
  var NetServerEvent;
16
18
  (function (NetServerEvent) {
package/lib/index.d.ts CHANGED
@@ -52,10 +52,10 @@ export interface SocketOptions extends DuplexOptions {
52
52
  remoteFamily?: string;
53
53
  }
54
54
  export declare class Socket extends Duplex {
55
- private _driver;
55
+ protected _driver: NetSocketDriver | undefined;
56
56
  connecting: boolean;
57
- private _connected;
58
- private _hadError;
57
+ protected _connected: boolean;
58
+ protected _hadError: boolean;
59
59
  remoteAddress?: string;
60
60
  remotePort?: number;
61
61
  remoteFamily?: string;
@@ -141,6 +141,7 @@ export declare class Server extends EventEmitter {
141
141
  export declare function createConnection(options: any, connectionListener?: () => void): Socket;
142
142
  export declare const connect: typeof createConnection;
143
143
  export declare function createServer(options?: any, connectionListener?: (socket: Socket) => void): Server;
144
+ export * as tls from './tls';
144
145
  export { isIP, isIPv4, isIPv6, getDefaultAutoSelectFamily, setDefaultAutoSelectFamily, setVerbose, initWithConfig, };
145
146
  export type { NetConfig };
146
147
  declare const _default: {