Skip to content

chore: use slim binary over dylib #210

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 6, 2025
Merged

Conversation

ethanndickson
Copy link
Member

@ethanndickson ethanndickson commented Jul 30, 2025

Closes #201.

This PR:

  • Replaces the dylib download with a slim binary download.
  • Removes signature validation checks that are inappropriate for the slim binary.
  • Replaces TunnelHandle with TunnelDaemon, an abstraction which runs posix_spawn on the slim binary, and manages the spawned process.
  • Adds tests for TunnelDaemon.

In a future PR:

  • Bump the minimum server version for Coder Desktop for macOS (to v2.25 once it's released)

@@ -69,7 +69,7 @@ actor Receiver<RecvMsg: Message> {
},
onCancel: {
self.logger.debug("async stream canceled")
self.dispatch.close()
self.dispatch.close(flags: [.stop])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes any currently running dispatch.read calls to supply their callback with an error which lets us actually end the read loop and cause the manager and all of it's children to be deallocated, including pipe file descriptors.
Previously we would leak pipes, but it didn't matter because the process would die each time.

Comment on lines -104 to -127
private static func validateInfo(infoPlist: [String: AnyObject], expectedVersion: String) throws(ValidationError) {
guard let plistIdent = infoPlist[infoIdentifierKey] as? String, plistIdent == expectedIdentifier else {
throw .invalidIdentifier(identifier: infoPlist[infoIdentifierKey] as? String)
}

guard let plistName = infoPlist[infoNameKey] as? String, plistName == expectedName else {
throw .invalidIdentifier(identifier: infoPlist[infoNameKey] as? String)
}

// Downloaded dylib must match the version of the server
guard let dylibVersion = infoPlist[infoShortVersionKey] as? String,
expectedVersion == dylibVersion
else {
throw .invalidVersion(version: infoPlist[infoShortVersionKey] as? String)
}

// Downloaded dylib must be at least the minimum Coder server version
guard let dylibVersion = infoPlist[infoShortVersionKey] as? String,
// x.compare(y) is .orderedDescending if x > y
minimumCoderVersion.compare(dylibVersion, options: .numeric) != .orderedDescending
else {
throw .belowMinimumCoderVersion
}
}
Copy link
Member Author

@ethanndickson ethanndickson Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunate, but because we don't build the slim binary with an external linker (previously xcode via cgo for the dylib) we can no longer create an info.plist section in the binary with -sectcreate. If we ever need to build the slim binary with cgo then we can add this back.

Copy link
Member Author

@ethanndickson ethanndickson Jul 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added another PR to check the version by exec'ing.

@ethanndickson ethanndickson marked this pull request as ready for review July 31, 2025 04:44
@ethanndickson ethanndickson self-assigned this Jul 31, 2025
@ethanndickson ethanndickson force-pushed the ethan/xpc-validation branch from 6687411 to ef370db Compare July 31, 2025 07:26
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from 479576a to e9e15db Compare July 31, 2025 07:26
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from e9e15db to c7602c2 Compare August 4, 2025 02:59
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from c7602c2 to f008801 Compare August 4, 2025 03:00
@ethanndickson ethanndickson force-pushed the ethan/xpc-validation branch 2 times, most recently from 8670f11 to be347a8 Compare August 4, 2025 03:03
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from f008801 to 847006f Compare August 4, 2025 03:03
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from 847006f to d9255bc Compare August 4, 2025 07:58
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from d9255bc to 4f29ff3 Compare August 4, 2025 08:05
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from 4f29ff3 to 5840bce Compare August 4, 2025 08:07
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR replaces the dylib-based tunnel implementation with a slim binary approach for the VPN functionality. It removes dylib-specific code and signature validation, introducing TunnelDaemon as a new abstraction that spawns and manages a binary process.

  • Replaces TunnelHandle with TunnelDaemon that uses posix_spawn to run a slim binary
  • Updates download and validation logic to work with binaries instead of dylibs
  • Removes dylib-specific signature validation and quarantine removal processes

Reviewed Changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/update-cask.sh Updates cleanup paths to include new binary locations
Coder-Desktop/project.yml Removes bridging header reference for dylib integration
Coder-Desktop/VPNLibTests/TunnelDaemonTests.swift Adds comprehensive tests for the new TunnelDaemon functionality
Coder-Desktop/VPNLib/XPC.swift Updates progress descriptions from "library" to "binary"
Coder-Desktop/VPNLib/Validate.swift Simplifies validation by removing dylib-specific checks
Coder-Desktop/VPNLib/TunnelDaemon.swift New implementation for managing tunnel binary process
Coder-Desktop/VPNLib/System.swift Adds system utilities for process spawning and monitoring
Coder-Desktop/Coder-DesktopHelper/TunnelHandle.swift Removes old dylib-based tunnel implementation
Coder-Desktop/Coder-DesktopHelper/Manager.swift Major refactor to use TunnelDaemon instead of TunnelHandle

Copy link
Member Author

ethanndickson commented Aug 6, 2025

Merge activity

  • Aug 6, 3:39 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Aug 6, 3:48 AM UTC: Graphite rebased this pull request as part of a merge.
  • Aug 6, 3:50 AM UTC: @ethanndickson merged this pull request with Graphite.

@ethanndickson ethanndickson changed the base branch from ethan/xpc-validation to graphite-base/210 August 6, 2025 03:45
@ethanndickson ethanndickson changed the base branch from graphite-base/210 to main August 6, 2025 03:47
@ethanndickson ethanndickson force-pushed the ethan/slim-over-dylib branch from a4bbf6b to 3267a06 Compare August 6, 2025 03:48
@ethanndickson ethanndickson merged commit 8c08563 into main Aug 6, 2025
4 checks passed
@ethanndickson ethanndickson deleted the ethan/slim-over-dylib branch August 6, 2025 03:50
ethanndickson added a commit that referenced this pull request Aug 6, 2025
This requirement is introduced by #210, as the `vpn-daemon` command on the macOS CLI isn't present on prior versions.

(2.24.3 isn't out yet, but when it does come out, it'll be compatible. 2.25 is out, and it's compatible)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Coder Connect cannot reach a Coder deployment behind a VPN
2 participants