[PR #5982] [MERGED] [client] Release wasm js.FuncOf callbacks in ssh and rdp paths #27244

Closed
opened 2026-08-05 07:08:25 -04:00 by saavagebueno · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/5982
Author: @lixmal
Created: 4/24/2026
Status: Merged
Merged: 5/26/2026
Merged by: @lixmal

Base: mainHead: wasm-js-func-release


📝 Commits (1)

  • b786534 Release js.FuncOf callbacks in wasm ssh and rdp to prevent leaks

📊 Changes

3 files changed (+122 additions, -43 deletions)

View changed files

📝 client/wasm/internal/rdp/cert_validation.go (+24 -9)
📝 client/wasm/internal/rdp/rdcleanpath.go (+78 -27)
📝 client/wasm/internal/ssh/handlers.go (+20 -7)

📄 Description

Describe your changes

js.FuncOf pins the Go closure in the syscall/js callback table until Release() is called. The existing WASM SSH / RDP code creates per-connection js.Func callbacks (write, resize, close, onGoMessage, onGoClose, the RDCleanPath per-proxy handshake handler, cert-validation then/catch) without ever releasing them, so each session permanently leaks the captured Go closure plus its JS wrapper. This PR releases them at the correct teardown point.

  • Store write / resize / close as named js.Func in SSH and release them when the read loop exits.
  • Track the per-proxy RDCleanPath handshake handler in a pending map, attach it to the connection on handshake, and release it alongside onGoMessage / onGoClose in cleanupConnection. Also delete the handleRDCleanPathWebSocket_<id> global and clean up destinations / pendingHandlers entries.
  • Release the cert-validation then / catch callbacks when the promise resolves. Channels made buffered so the defer Release is still safe on the timeout path.

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Internal WASM memory-management fix, no public-facing docs page.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

https://github.com/netbirdio/docs/pull/__

Summary by CodeRabbit

  • Bug Fixes
    • Prevented JS/WASM callback/resource leaks and made cleanup idempotent.
    • Improved WebSocket proxy handling to avoid stale or duplicated handlers during connection lifecycle.
    • Made certificate validation more tolerant by increasing its timeout and ensuring non-blocking resolution.
    • Made SSH session callbacks terminate safely so late calls no longer invoke released handlers.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbirdio/netbird/pull/5982 **Author:** [@lixmal](https://github.com/lixmal) **Created:** 4/24/2026 **Status:** ✅ Merged **Merged:** 5/26/2026 **Merged by:** [@lixmal](https://github.com/lixmal) **Base:** `main` ← **Head:** `wasm-js-func-release` --- ### 📝 Commits (1) - [`b786534`](https://github.com/netbirdio/netbird/commit/b786534b686890a8daa7404ba781251104a8aa4b) Release js.FuncOf callbacks in wasm ssh and rdp to prevent leaks ### 📊 Changes **3 files changed** (+122 additions, -43 deletions) <details> <summary>View changed files</summary> 📝 `client/wasm/internal/rdp/cert_validation.go` (+24 -9) 📝 `client/wasm/internal/rdp/rdcleanpath.go` (+78 -27) 📝 `client/wasm/internal/ssh/handlers.go` (+20 -7) </details> ### 📄 Description ## Describe your changes `js.FuncOf` pins the Go closure in the syscall/js callback table until `Release()` is called. The existing WASM SSH / RDP code creates per-connection `js.Func` callbacks (`write`, `resize`, `close`, `onGoMessage`, `onGoClose`, the RDCleanPath per-proxy handshake handler, cert-validation `then`/`catch`) without ever releasing them, so each session permanently leaks the captured Go closure plus its JS wrapper. This PR releases them at the correct teardown point. - Store `write` / `resize` / `close` as named `js.Func` in SSH and release them when the read loop exits. - Track the per-proxy RDCleanPath handshake handler in a pending map, attach it to the connection on handshake, and release it alongside `onGoMessage` / `onGoClose` in `cleanupConnection`. Also delete the `handleRDCleanPathWebSocket_<id>` global and clean up `destinations` / `pendingHandlers` entries. - Release the cert-validation `then` / `catch` callbacks when the promise resolves. Channels made buffered so the `defer Release` is still safe on the timeout path. ## Issue ticket number and link ## Stack <!-- branch-stack --> ### Checklist - [x] Is it a bug fix - [ ] Is a typo/documentation fix - [ ] Is a feature enhancement - [ ] It is a refactor - [ ] Created tests that fail without the change (if possible) > By submitting this pull request, you confirm that you have read and agree to the terms of the [Contributor License Agreement](https://github.com/netbirdio/netbird/blob/main/CONTRIBUTOR_LICENSE_AGREEMENT.md). ## Documentation Select exactly one: - [ ] I added/updated documentation for this change - [x] Documentation is **not needed** for this change (explain why) Internal WASM memory-management fix, no public-facing docs page. ### Docs PR URL (required if "docs added" is checked) Paste the PR link from https://github.com/netbirdio/docs here: https://github.com/netbirdio/docs/pull/__ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Prevented JS/WASM callback/resource leaks and made cleanup idempotent. * Improved WebSocket proxy handling to avoid stale or duplicated handlers during connection lifecycle. * Made certificate validation more tolerant by increasing its timeout and ensuring non-blocking resolution. * Made SSH session callbacks terminate safely so late calls no longer invoke released handlers. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
saavagebueno added the pull-request label 2026-08-05 07:08:25 -04:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#27244