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

Commitef8832a

Browse files
committed
chore: run coder connect networking from launchdaemon
1 parent16c716d commitef8832a

18 files changed

+467
-425
lines changed

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,8 @@ extension CoderVPNService {
1212
func setupHelper()async{
1313
refreshHelperState()
1414
switch helperState{
15-
case.uninstalled,.failed:
16-
awaitinstallHelper()
17-
case.installed:
18-
uninstallHelper()
15+
case.uninstalled,.failed,.installed:
16+
awaituninstallHelper()
1917
awaitinstallHelper()
2018
case.requiresApproval,.installing:
2119
break
@@ -63,10 +61,10 @@ extension CoderVPNService {
6361
helperState=.failed(.unknown(lastUnknownError?.localizedDescription??"Unknown"))
6462
}
6563

66-
privatefunc uninstallHelper(){
64+
privatefunc uninstallHelper()async{
6765
letdaemon=SMAppService.daemon(plistName: plistName)
6866
do{
69-
try daemon.unregister()
67+
tryawaitdaemon.unregister()
7068
}catchlet error asNSError{
7169
helperState=.failed(.init(error: error))
7270
}catch{

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

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

6262
@PublishedvartunnelState:VPNServiceState=.disabled{
6363
didSet{
@@ -158,10 +158,10 @@ final class CoderVPNService: NSObject, VPNService {
158158
}
159159
}
160160

161-
func onExtensionPeerUpdate(_data:Data){
161+
func onExtensionPeerUpdate(_diff:Data){
162162
logger.info("network extension peer update")
163163
do{
164-
letmsg=tryVpn_PeerUpdate(serializedBytes:data)
164+
letmsg=tryVpn_PeerUpdate(serializedBytes:diff)
165165
debugPrint(msg)
166166
applyPeerUpdate(with: msg)
167167
}catch{
@@ -219,16 +219,18 @@ extension CoderVPNService {
219219
break
220220
// Non-connecting -> Connecting: Establish XPC
221221
case(_,.connecting):
222-
xpc.connect()
223-
xpc.ping()
222+
// Detached to run ASAP
223+
// TODO: Switch to `Task.immediate` once stable
224+
Task.detached{try?awaitself.xpc.ping()}
224225
tunnelState=.connecting
225226
// Non-connected -> Connected:
226227
// - Retrieve Peers
227228
// - Run `onStart` closure
228229
case(_,.connected):
229230
onStart?()
230-
xpc.connect()
231-
xpc.getPeerState()
231+
// Detached to run ASAP
232+
// TODO: Switch to `Task.immediate` once stable
233+
Task.detached{try?awaitself.xpc.getPeerState()}
232234
tunnelState=.connected
233235
// Any -> Reasserting
234236
case(_,.reasserting):

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,13 @@ struct LoginForm: View {
192192
@discardableResult
193193
func validateURL(_ url:String)throws(LoginError)->URL{
194194
guardlet url=URL(string: url)else{
195-
throwLoginError.invalidURL
195+
throw.invalidURL
196196
}
197197
guard url.scheme=="https"else{
198-
throwLoginError.httpsRequired
198+
throw.httpsRequired
199199
}
200200
guard url.host!=nilelse{
201-
throwLoginError.noHost
201+
throw.noHost
202202
}
203203
return url
204204
}

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

Lines changed: 67 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3,112 +3,98 @@ 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
36-
Task{@MainActorin
37-
logger.error("VPN XPC connection invalidated.")
38-
self.xpc=nil
39-
self.connect()
40-
}
41-
}
42-
xpcConn.interruptionHandler={[logger]in
43-
Task{@MainActorin
44-
logger.error("VPN XPC connection interrupted.")
45-
self.xpc=nil
46-
self.connect()
47-
}
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={
29+
self.logger.error("XPC connection invalidated")
30+
self.connection=nil
31+
_=self.connect()
4832
}
49-
xpcConn.resume()
50-
}
51-
52-
func ping(){
53-
xpc?.ping{
54-
Task{@MainActorin
55-
self.logger.info("Connected to NE over XPC")
56-
}
33+
connection.interruptionHandler={
34+
self.logger.error("XPC connection interrupted")
35+
self.connection=nil
36+
_=self.connect()
5737
}
38+
logger.info("connecting to\(helperAppMachServiceName)")
39+
connection.resume()
40+
self.connection= connection
41+
return connection
5842
}
5943

60-
funcgetPeerState(){
61-
xpc?.getPeerState{ datain
62-
Task{@MainActorin
63-
self.svc.onExtensionPeerState(data)
64-
}
44+
funconPeerUpdate(_ diff:Data, reply:@escaping()->Void){
45+
letreply=CompletionWrapper(reply)
46+
Task{@MainActorin
47+
svc.onExtensionPeerUpdate(diff)
48+
reply()
6549
}
6650
}
6751

68-
func onPeerUpdate(_ data:Data){
52+
func onProgress(stage:ProgressStage, downloadProgress:DownloadProgress?, reply:@escaping()->Void){
53+
letreply=CompletionWrapper(reply)
6954
Task{@MainActorin
70-
svc.onExtensionPeerUpdate(data)
55+
svc.onProgress(stage: stage, downloadProgress: downloadProgress)
56+
reply()
7157
}
7258
}
59+
}
7360

74-
func onProgress(stage:ProgressStage, downloadProgress:DownloadProgress?){
75-
Task{@MainActorin
76-
svc.onProgress(stage: stage, downloadProgress: downloadProgress)
61+
// These methods are called to request updatess from the Helper.
62+
extensionAppXPCListener{
63+
func ping()asyncthrows{
64+
letconn=connect()
65+
returntryawaitwithCheckedThrowingContinuation{ continuationin
66+
guardlet proxy= conn.remoteObjectProxyWithErrorHandler({ errin
67+
self.logger.error("failed to connect to HelperXPC\(err.localizedDescription, privacy:.public)")
68+
continuation.resume(throwing: err)
69+
})as?HelperAppXPCInterfaceelse{
70+
self.logger.error("failed to get proxy for HelperXPC")
71+
continuation.resume(throwing:XPCError.wrongProxyType)
72+
return
73+
}
74+
proxy.ping{
75+
self.logger.info("Connected to Helper over XPC")
76+
continuation.resume()
77+
}
7778
}
7879
}
7980

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-
}
81+
func getPeerState()asyncthrows{
82+
letconn=connect()
83+
returntryawaitwithCheckedThrowingContinuation{ continuationin
84+
guardlet proxy= conn.remoteObjectProxyWithErrorHandler({ errin
85+
self.logger.error("failed to connect to HelperXPC\(err.localizedDescription, privacy:.public)")
86+
continuation.resume(throwing: err)
87+
})as?HelperAppXPCInterfaceelse{
88+
self.logger.error("failed to get proxy for HelperXPC")
89+
continuation.resume(throwing:XPCError.wrongProxyType)
90+
return
91+
}
92+
proxy.getPeerState{ datain
93+
Task{@MainActorin
94+
self.svc.onExtensionPeerState(data)
10995
}
96+
continuation.resume()
11097
}
111-
reply(success)
11298
}
11399
}
114100
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp