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

Commit49d5c99

Browse files
committed
chore: run coder connect networking from launchdaemon
1 parentebcb698 commit49d5c99

17 files changed

+418
-392
lines changed

‎Coder-Desktop/Coder-Desktop/HelperService.swift‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import os
22
import ServiceManagement
33

4-
// Whilst the GUI app installs the helper, the System Extension communicates
5-
// with it over XPC
64
@MainActor
75
classHelperService:ObservableObject{
86
privateletlogger=Logger(subsystem:Bundle.main.bundleIdentifier!, category:"HelperService")

‎Coder-Desktop/Coder-Desktop/VPN/VPNService.swift‎

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ enum VPNServiceError: Error, Equatable {
5454
@MainActor
5555
finalclassCoderVPNService:NSObject,VPNService{
5656
varlogger=Logger(subsystem:Bundle.main.bundleIdentifier!, category:"vpn")
57-
lazyvarxpc:VPNXPCInterface=.init(vpn:self)
57+
lazyvarxpc:AppXPCListener=.init(vpn:self)
5858

5959
@PublishedvartunnelState:VPNServiceState=.disabled{
6060
didSet{
@@ -138,10 +138,10 @@ final class CoderVPNService: NSObject, VPNService {
138138
}
139139
}
140140

141-
func onExtensionPeerUpdate(_data:Data){
141+
func onExtensionPeerUpdate(_diff:Data){
142142
logger.info("network extension peer update")
143143
do{
144-
letmsg=tryVpn_PeerUpdate(serializedBytes:data)
144+
letmsg=tryVpn_PeerUpdate(serializedBytes:diff)
145145
debugPrint(msg)
146146
applyPeerUpdate(with: msg)
147147
}catch{
@@ -199,16 +199,18 @@ extension CoderVPNService {
199199
break
200200
// Non-connecting -> Connecting: Establish XPC
201201
case(_,.connecting):
202-
xpc.connect()
203-
xpc.ping()
202+
// Detached to run ASAP
203+
// TODO: Switch to `Task.immediate` once stable
204+
Task.detached{try?awaitself.xpc.ping()}
204205
tunnelState=.connecting
205206
// Non-connected -> Connected:
206207
// - Retrieve Peers
207208
// - Run `onStart` closure
208209
case(_,.connected):
209210
onStart?()
210-
xpc.connect()
211-
xpc.getPeerState()
211+
// Detached to run ASAP
212+
// TODO: Switch to `Task.immediate` once stable
213+
Task.detached{try?awaitself.xpc.getPeerState()}
212214
tunnelState=.connected
213215
// Any -> Reasserting
214216
case(_,.reasserting):

‎Coder-Desktop/Coder-Desktop/Views/LoginForm.swift‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,13 +190,13 @@ struct LoginForm: View {
190190
@discardableResult
191191
func validateURL(_ url:String)throws(LoginError)->URL{
192192
guardlet url=URL(string: url)else{
193-
throwLoginError.invalidURL
193+
throw.invalidURL
194194
}
195195
guard url.scheme=="https"else{
196-
throwLoginError.httpsRequired
196+
throw.httpsRequired
197197
}
198198
guard url.host!=nilelse{
199-
throwLoginError.noHost
199+
throw.noHost
200200
}
201201
return url
202202
}

‎Coder-Desktop/Coder-Desktop/XPCInterface.swift‎

Lines changed: 63 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -3,112 +3,100 @@ import NetworkExtension
33
import os
44
import VPNLib
55

6-
@objcfinalclassVPNXPCInterface:NSObject,VPNXPCClientCallbackProtocol,@uncheckedSendable{
6+
@objcfinalclassAppXPCListener:NSObject,AppXPCInterface,@uncheckedSendable{
77
privatevarsvc:CoderVPNService
8-
privateletlogger=Logger(subsystem:Bundle.main.bundleIdentifier!, category:"VPNXPCInterface")
9-
privatevarxpc:VPNXPCProtocol?
8+
privateletlogger=Logger(subsystem:Bundle.main.bundleIdentifier!, category:"AppXPCListener")
9+
privatevarconnection:NSXPCConnection?
1010

1111
init(vpn:CoderVPNService){
1212
svc= vpn
1313
super.init()
1414
}
1515

16-
func connect(){
17-
logger.debug("VPN xpc connect called")
18-
guard xpc==nilelse{
19-
logger.debug("VPN xpc already exists")
20-
return
16+
func connect()->NSXPCConnection{
17+
iflet connection{
18+
return connection
2119
}
22-
letnetworkExtDict=Bundle.main.object(forInfoDictionaryKey:"NetworkExtension")as?[String:Any]
23-
letmachServiceName=networkExtDict?["NEMachServiceName"]as?String
24-
letxpcConn=NSXPCConnection(machServiceName: machServiceName!)
25-
xpcConn.remoteObjectInterface=NSXPCInterface(with:VPNXPCProtocol.self)
26-
xpcConn.exportedInterface=NSXPCInterface(with:VPNXPCClientCallbackProtocol.self)
27-
guardlet proxy= xpcConn.remoteObjectProxyas?VPNXPCProtocolelse{
28-
fatalError("invalid xpc cast")
29-
}
30-
xpc= proxy
31-
32-
logger.debug("connecting to machServiceName:\(machServiceName!)")
3320

34-
xpcConn.exportedObject=self
35-
xpcConn.invalidationHandler={[logger]in
21+
letconnection=NSXPCConnection(
22+
machServiceName: helperAppMachServiceName,
23+
options:.privileged
24+
)
25+
connection.remoteObjectInterface=NSXPCInterface(with:HelperAppXPCInterface.self)
26+
connection.exportedInterface=NSXPCInterface(with:AppXPCInterface.self)
27+
connection.exportedObject=self
28+
connection.invalidationHandler={
3629
Task{@MainActorin
37-
logger.error("VPNXPC connection invalidated.")
38-
self.xpc=nil
39-
self.connect()
30+
self.logger.error("XPC connection invalidated")
31+
self.connection=nil
32+
_=self.connect()
4033
}
4134
}
42-
xpcConn.interruptionHandler={[logger]in
35+
connection.interruptionHandler={
4336
Task{@MainActorin
44-
logger.error("VPNXPC connection interrupted.")
45-
self.xpc=nil
46-
self.connect()
37+
self.logger.error("XPC connection interrupted")
38+
self.connection=nil
39+
_=self.connect()
4740
}
4841
}
49-
xpcConn.resume()
42+
connection.resume()
43+
self.connection= connection
44+
return connection
5045
}
5146

52-
func ping(){
53-
xpc?.ping{
54-
Task{@MainActorin
55-
self.logger.info("Connected to NE over XPC")
47+
func ping()asyncthrows{
48+
letconn=connect()
49+
returntryawaitwithCheckedThrowingContinuation{ continuationin
50+
guardlet proxy= conn.remoteObjectProxyWithErrorHandler({ errin
51+
self.logger.error("failed to connect to HelperXPC\(err.localizedDescription, privacy:.public)")
52+
continuation.resume(throwing: err)
53+
})as?HelperAppXPCInterfaceelse{
54+
self.logger.error("failed to get proxy for HelperXPC")
55+
continuation.resume(throwing:XPCError.wrongProxyType)
56+
return
57+
}
58+
proxy.ping{
59+
Task{@MainActorin
60+
self.logger.info("Connected to Helper over XPC")
61+
continuation.resume()
62+
}
5663
}
5764
}
5865
}
5966

60-
func getPeerState(){
61-
xpc?.getPeerState{ datain
62-
Task{@MainActorin
63-
self.svc.onExtensionPeerState(data)
67+
func getPeerState()asyncthrows{
68+
letconn=connect()
69+
returntryawaitwithCheckedThrowingContinuation{ continuationin
70+
guardlet proxy= conn.remoteObjectProxyWithErrorHandler({ errin
71+
self.logger.error("failed to connect to HelperXPC\(err.localizedDescription, privacy:.public)")
72+
continuation.resume(throwing: err)
73+
})as?HelperAppXPCInterfaceelse{
74+
self.logger.error("failed to get proxy for HelperXPC")
75+
continuation.resume(throwing:XPCError.wrongProxyType)
76+
return
77+
}
78+
proxy.getPeerState{ datain
79+
Task{@MainActorin
80+
self.svc.onExtensionPeerState(data)
81+
continuation.resume()
82+
}
6483
}
6584
}
6685
}
6786

68-
func onPeerUpdate(_ data:Data){
87+
func onPeerUpdate(_ diff:Data, reply:@escaping()->Void){
88+
letreply=CompletionWrapper(reply)
6989
Task{@MainActorin
70-
svc.onExtensionPeerUpdate(data)
90+
svc.onExtensionPeerUpdate(diff)
91+
reply()
7192
}
7293
}
7394

74-
func onProgress(stage:ProgressStage, downloadProgress:DownloadProgress?){
95+
func onProgress(stage:ProgressStage, downloadProgress:DownloadProgress?, reply:@escaping()->Void){
96+
letreply=CompletionWrapper(reply)
7597
Task{@MainActorin
7698
svc.onProgress(stage: stage, downloadProgress: downloadProgress)
77-
}
78-
}
79-
80-
// The NE has verified the dylib and knows better than Gatekeeper
81-
func removeQuarantine(path:String, reply:@escaping(Bool)->Void){
82-
letreply=CallbackWrapper(reply)
83-
Task{@MainActorin
84-
letprompt="""
85-
Coder Desktop wants to execute code downloaded from\
86-
\(svc.serverAddress??"the Coder deployment"). The code has been\
87-
verified to be signed by Coder.
88-
"""
89-
letsource="""
90-
do shell script"xattr -d com.apple.quarantine\(path)"\
91-
with prompt"\(prompt)"\
92-
with administrator privileges
93-
"""
94-
letsuccess=awaitwithCheckedContinuation{ continuationin
95-
guardlet script=NSAppleScript(source: source)else{
96-
continuation.resume(returning:false)
97-
return
98-
}
99-
// Run on a background thread
100-
Task.detached{
101-
varerror:NSDictionary?
102-
script.executeAndReturnError(&error)
103-
iflet error{
104-
self.logger.error("AppleScript error:\(error)")
105-
continuation.resume(returning:false)
106-
}else{
107-
continuation.resume(returning:true)
108-
}
109-
}
110-
}
111-
reply(success)
99+
reply()
112100
}
113101
}
114102
}

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

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp