tls: native pipe / splice between TLS and another native stream or fd
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 30/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- javascript, node.js
- Lĩnh vực
- networking, security
Hướng nghiên cứu
Bắt đầu với TLSWrap và hành vi pipe/splice hiện có của net.Socket được mô tả trong issue, sau đó lần theo entry point của phiên tls.connect. Xác định thiết kế và ngữ nghĩa ownership cho việc bridging fd native trước khi triển khai. Được xem là hoàn tất khi việc chuyển tiếp duplex không sử dụng các JavaScript handler cho từng chunk, truyền backpressure, giữ nguyên thiết lập phiên và đáp ứng các tiêu chí forwarding và benchmark đã nêu.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
What is the problem this feature will solve?
net.Socket supports efficient kernel-level forwarding patterns (socket.pipe(), socket.pause()/resume() with native backpressure). There is no TLS equivalent — forwarding cleartext through TLSSocket always goes through the streams layer:
TCP (encrypted) → TLSWrap::ClearOut → JS Readable → user pump → JS Writable → sink
For full-duplex bridges (TLS ↔ TUN fd, TLS ↔ pipe, TLS ↔ another TCP socket), userland must:
- Implement two pumps (encrypt direction + decrypt direction) in JavaScript or duplicate logic in a native addon
- Manually coordinate backpressure (pause/resume, 'drain', TUN poll pause) across heterogeneous endpoints
- Absorb per-chunk copies and event-loop latency from TLSWrap (see related issues on SetImmediate deferral and read copies)
net has splice-style optimizations between fds; TLSWrap sits in the middle with no supported way to wire cleartext directly to a native sink/source while keeping session setup in Node.
This forces ecosystem projects (VPN helpers, transparent proxies, iOS tunnel tooling) to ship custom OpenSSL forwarders instead of composing built-in APIs.
What is the feature you are proposing to solve the problem?
Add native TLS pipe/splice primitives that pump cleartext between an established TLSSocket (or tls.connect session) and another native I/O endpoint without per-chunk JavaScript involvement.
Proposed API (sketch):
import tls from 'node:tls';
import net from 'node:net';
const tcp = await net.connect({ port });
const tlsSocket = await tls.connect({ socket: tcp, ... });
// Duplex: TLS cleartext ↔ numeric fd (TUN, pipe, etc.)
const handle = tlsSocket.spliceTo({
fd: tunFd,
direction: 'duplex', // 'in' | 'out' | 'duplex'
});
handle.start();
await handle.stop(); // idempotent cleanup
// Or one-shot helper:
await tlsSocket.pipeToNative(tunFd, { direction: 'duplex' });
Implementation outline (on TLSWrap):
- Decrypt path (TLS → sink): SSL_read loop → write cleartext to sink fd; on EAGAIN/EWOULDBLOCK, pause uv_read_start on the underlying TCP stream until sink is writable (native backpressure, not socket.pause() in JS).
- Encrypt path (source → TLS): read cleartext from source fd → SSL_write → EncOut → TCP; stall source read when SSL_write or TCP send buffer is full.
- Reuse existing TLSWrap session, handshake, cert/PSK options — only the payload pump is native.
- Clear ownership semantics for fds (caller retains TUN; bridge does not close unless autoClose: true).
Relation to other proposals:
- Lighter-weight than full tls.createBridge() when one side is already a TLSSocket and the other is an fd.
- Complements zero-copy onread for users who still want one direction in JS.
Success criteria:
- Bidirectional MTU-sized forwarding without socket.on('data') handlers.
- Backpressure propagates correctly (no unbounded buffering in pending_cleartext_input_ / userland).
- Benchmark shows lower CPU and event-loop utilization vs. an equivalent JS pump.
What alternatives have you considered?
- socket.pipe(otherSocket) through TLSSocket — Still routes every byte through JS streams; does not splice to raw fds; no TLS-aware backpressure.
- duplex streams + pipeline() — Same V8-boundary and allocation costs; popular but not a performance solution.
- tls.createBridge() (separate proposal) — Higher-level API that may subsume this for fd targets; spliceTo is a narrower addition for users who already have a TLSSocket and want fd bridging only.
- Custom N-API OpenSSL forwarder — Proven in production (e.g. iOS tunnel addons) but duplicates TLSWrap and OpenSSL linkage in every consumer.
- node:child_process + socat/openssl s_client — Operational hack, not embeddable in Node apps.
- Document manual pump patterns only — Insufficient; the gap is missing native wiring in TLSWrap, not developer skill.
- Ngôn ngữ chính
- JavaScript
- Star
- 122k
- Fork
- 37.4k
- Merge trung bình
- 4 ngày 3 giờ
- Pull request đã merge (30 ngày)
- 279
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của nodejs/node
-
doc
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
build
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
-
feature request
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
Theme loads third-party resources on every page (jsdelivr web font, cdnjs Font Awesome) – GDPR Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
docToolchain/docToolchain#1705 ·
-
Timezone select lists one option per character; duplicate "Failed" reason; shared tracker popover id Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
nightscout/nocturne#1414 ·
-
bug v2
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
modelcontextprotocol/inspector#2458 · 1 bình luận ·
-
Mend: dependency security vulnerability status: needs triage 🕵️♀️
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
carbon-design-system/ibm-products#9907 ·