Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8f00c6a

Browse files
committed
chore: use slim binary over dylib
1 parent6687411 commit8f00c6a

File tree

10 files changed

+473
-218
lines changed

10 files changed

+473
-218
lines changed

‎Coder-Desktop/Coder-DesktopHelper/Manager.swift‎

Lines changed: 62 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,41 @@ actor Manager {
77
letcfg:ManagerConfig
88
lettelemetryEnricher:TelemetryEnricher
99

10-
lettunnelHandle:TunnelHandle
10+
lettunnelDaemon:TunnelDaemon
1111
letspeaker:Speaker<Vpn_ManagerMessage,Vpn_TunnelMessage>
1212
varreadLoop:Task<Void,anyError>!
1313

14-
// /var/root/Downloads
14+
#if arch(arm64)
15+
privatestaticletbinaryName="coder-darwin-arm64"
16+
#else
17+
privatestaticletbinaryName="coder-darwin-amd64"
18+
#endif
19+
20+
// /var/root/Downloads/coder-darwin-{arm64,amd64}
1521
privateletdest=FileManager.default.urls(for:.downloadsDirectory, in:.userDomainMask)
16-
.first!.appending(path:"coder-vpn.dylib")
22+
.first!.appending(path:binaryName)
1723
privateletlogger=Logger(subsystem:Bundle.main.bundleIdentifier!, category:"manager")
1824

1925
// swiftlint:disable:next function_body_length
2026
init(cfg:ManagerConfig)asyncthrows(ManagerError){
2127
self.cfg= cfg
2228
telemetryEnricher=TelemetryEnricher()
23-
#if arch(arm64)
24-
letdylibPath= cfg.serverUrl.appending(path:"bin/coder-vpn-darwin-arm64.dylib")
25-
#elseif arch(x86_64)
26-
letdylibPath= cfg.serverUrl.appending(path:"bin/coder-vpn-darwin-amd64.dylib")
27-
#else
28-
fatalError("unknown architecture")
29-
#endif
29+
letclient=Client(url: cfg.serverUrl)
30+
letbuildInfo:BuildInfoResponse
31+
do{
32+
buildInfo=tryawait client.buildInfo()
33+
}catch{
34+
throw.serverInfo(error.description)
35+
}
36+
guardlet serverSemver= buildInfo.semverelse{
37+
throw.serverInfo("invalid version:\(buildInfo.version)")
38+
}
39+
guardSignatureValidator.minimumCoderVersion
40+
.compare(serverSemver, options:.numeric)!=.orderedDescending
41+
else{
42+
throw.belowMinimumCoderVersion(actualVersion: serverSemver)
43+
}
44+
letbinaryPath= cfg.serverUrl.appending(path:"bin").appending(path:Manager.binaryName)
3045
do{
3146
letsessionConfig=URLSessionConfiguration.default
3247
// The tunnel might be asked to start before the network interfaces have woken up from sleep
@@ -35,7 +50,7 @@ actor Manager {
3550
sessionConfig.timeoutIntervalForRequest=60
3651
sessionConfig.timeoutIntervalForResource=300
3752
tryawaitdownload(
38-
src:dylibPath,
53+
src:binaryPath,
3954
dest: dest,
4055
urlSession:URLSession(configuration: sessionConfig)
4156
){ progressin
@@ -45,48 +60,44 @@ actor Manager {
4560
throw.download(error)
4661
}
4762
pushProgress(stage:.validating)
48-
letclient=Client(url: cfg.serverUrl)
49-
letbuildInfo:BuildInfoResponse
5063
do{
51-
buildInfo=tryawait client.buildInfo()
64+
trySignatureValidator.validate(path: dest)
5265
}catch{
53-
throw.serverInfo(error.description)
54-
}
55-
guardlet semver= buildInfo.semverelse{
56-
throw.serverInfo("invalid version:\(buildInfo.version)")
66+
throw.validation(error)
5767
}
68+
69+
// Without this, the TUN fd isn't recognised as a socket in the
70+
// spawned process, and the tunnel fails to start.
5871
do{
59-
trySignatureValidator.validate(path: dest, expectedVersion: semver)
72+
tryunsetCloseOnExec(fd: cfg.tunFd)
6073
}catch{
61-
throw.validation(error)
74+
throw.cloexec(error)
6275
}
6376

6477
do{
65-
try tunnelHandle=TunnelHandle(dylibPath: dest)
78+
try tunnelDaemon=awaitTunnelDaemon(binaryPath: dest){ errin
79+
Task{try?awaitNEXPCServerDelegate.cancelProvider(error:
80+
makeNSError(suffix:"TunnelDaemon", desc:"Tunnel daemon:\(err.description)")
81+
)}
82+
}
6683
}catch{
6784
throw.tunnelSetup(error)
6885
}
6986
speaker=awaitSpeaker<Vpn_ManagerMessage,Vpn_TunnelMessage>(
70-
writeFD:tunnelHandle.writeHandle,
71-
readFD:tunnelHandle.readHandle
87+
writeFD:tunnelDaemon.writeHandle,
88+
readFD:tunnelDaemon.readHandle
7289
)
7390
do{
7491
tryawait speaker.handshake()
7592
}catch{
7693
throw.handshake(error)
7794
}
78-
do{
79-
tryawait tunnelHandle.openTunnelTask?.value
80-
}catchlet error asTunnelHandleError{
81-
logger.error("failed to wait for dylib to open tunnel:\(error, privacy:.public)")
82-
throw.tunnelSetup(error)
83-
}catch{
84-
fatalError("openTunnelTask must only throw TunnelHandleError")
85-
}
8695

8796
readLoop=Task{tryawaitrun()}
8897
}
8998

99+
deinit{ logger.debug("manager deinit")}
100+
90101
func run()asyncthrows{
91102
do{
92103
fortryawaitmin speaker{
@@ -99,14 +110,14 @@ actor Manager {
99110
}
100111
}catch{
101112
logger.error("tunnel read loop failed:\(error.localizedDescription, privacy:.public)")
102-
tryawaittunnelHandle.close()
113+
tryawaittunnelDaemon.close()
103114
tryawaitNEXPCServerDelegate.cancelProvider(error:
104115
makeNSError(suffix:"Manager", desc:"Tunnel read loop failed:\(error.localizedDescription)")
105116
)
106117
return
107118
}
108119
logger.info("tunnel read loop exited")
109-
tryawaittunnelHandle.close()
120+
tryawaittunnelDaemon.close()
110121
tryawaitNEXPCServerDelegate.cancelProvider(error:nil)
111122
}
112123

@@ -204,6 +215,12 @@ actor Manager {
204215
if !stopResp.success{
205216
throw.errorResponse(msg: stopResp.errorMessage)
206217
}
218+
do{
219+
tryawait tunnelDaemon.close()
220+
}catch{
221+
throw.tunnelFail(error)
222+
}
223+
readLoop.cancel()
207224
}
208225

209226
// Retrieves the current state of all peers,
@@ -239,17 +256,16 @@ struct ManagerConfig {
239256

240257
enumManagerError:Error{
241258
case download(DownloadError)
242-
case tunnelSetup(TunnelHandleError)
259+
case tunnelSetup(TunnelDaemonError)
243260
case handshake(HandshakeError)
244261
case validation(ValidationError)
245262
case incorrectResponse(Vpn_TunnelMessage)
263+
case cloexec(POSIXError)
246264
case failedRPC(anyError)
247265
case serverInfo(String)
248266
case errorResponse(msg:String)
249-
case noTunnelFileDescriptor
250-
case noApp
251-
case permissionDenied
252267
case tunnelFail(anyError)
268+
case belowMinimumCoderVersion(actualVersion:String)
253269

254270
vardescription:String{
255271
switchself{
@@ -261,6 +277,8 @@ enum ManagerError: Error {
261277
"Handshake error:\(err.localizedDescription)"
262278
caselet.validation(err):
263279
"Validation error:\(err.localizedDescription)"
280+
caselet.cloexec(err):
281+
"Failed to mark TUN fd as non-cloexec:\(err.localizedDescription)"
264282
case.incorrectResponse:
265283
"Received unexpected response over tunnel"
266284
caselet.failedRPC(err):
@@ -269,14 +287,13 @@ enum ManagerError: Error {
269287
msg
270288
caselet.errorResponse(msg):
271289
msg
272-
case.noTunnelFileDescriptor:
273-
"Could not find a tunnel file descriptor"
274-
case.noApp:
275-
"The VPN must be started with the app open during first-time setup."
276-
case.permissionDenied:
277-
"Permission was not granted to execute the CoderVPN dylib"
278290
caselet.tunnelFail(err):
279-
"Failed to communicate with dylib over tunnel:\(err.localizedDescription)"
291+
"Failed to communicate with daemon over tunnel:\(err.localizedDescription)"
292+
caselet.belowMinimumCoderVersion(actualVersion):
293+
"""
294+
The Coder deployment must be version\(SignatureValidator.minimumCoderVersion)
295+
or higher to use Coder Desktop. Current version:\(actualVersion)
296+
"""
280297
}
281298
}
282299

@@ -297,7 +314,7 @@ func writeVpnLog(_ log: Vpn_Log) {
297314
case.UNRECOGNIZED:.info
298315
}
299316
letlogger=Logger(
300-
subsystem:"\(Bundle.main.bundleIdentifier!).dylib",
317+
subsystem:"\(Bundle.main.bundleIdentifier!).daemon",
301318
category: log.loggerNames.joined(separator:".")
302319
)
303320
letfields= log.fields.map{"\($0.name):\($0.value)"}.joined(separator:",")

‎Coder-Desktop/Coder-DesktopHelper/TunnelHandle.swift‎

Lines changed: 0 additions & 116 deletions
This file was deleted.

‎Coder-Desktop/Coder-DesktopTests/LoginFormTests.swift‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ struct LoginTests {
134134
username:"admin"
135135
)
136136
letbuildInfo=BuildInfoResponse(
137-
version:"v2.20.0"
137+
version:"v2.24.2"
138138
)
139139

140140
tryMock(

‎Coder-Desktop/VPNLib/Download.swift‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ extension DownloadManager: URLSessionDownloadDelegate {
102102
return
103103
}
104104
guard httpResponse.statusCode!=304else{
105-
// We already have the latestdylib downloaded in dest
105+
// We already have the latestbinary downloaded in dest
106106
continuation.resume()
107107
return
108108
}

‎Coder-Desktop/VPNLib/Receiver.swift‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ actor Receiver<RecvMsg: Message> {
6969
},
7070
onCancel:{
7171
self.logger.debug("async stream canceled")
72-
self.dispatch.close()
72+
self.dispatch.close(flags:[.stop])
7373
}
7474
)
7575
}

‎Coder-Desktop/VPNLib/Speaker.swift‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ public actor Speaker<SendMsg: RPCMessage & Message, RecvMsg: RPCMessage & Messag
8686
}
8787
}
8888

89+
deinit{ logger.debug("speaker deinit")}
90+
8991
/// Does the VPN Protocol handshake and validates the result
9092
publicfunc handshake()asyncthrows(HandshakeError){
9193
lethndsh=Handshaker(writeFD: writeFD, dispatch: dispatch, queue: queue, role: role,
@@ -227,7 +229,7 @@ actor Handshaker {
227229
returntryvalidateHeader(theirsString)
228230
}catch{
229231
writeFD.closeFile()
230-
dispatch.close()
232+
dispatch.close(flags:[.stop])
231233
throw error
232234
}
233235
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp