-
Notifications
You must be signed in to change notification settings - Fork 48
/
PacketTunnelProvider.m
133 lines (107 loc) · 4.05 KB
/
PacketTunnelProvider.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//
// PacketTunnelProvider.m
// PacketTunnel
//
// Created by oort on 2018/6/20.
// Copyright © 2018年 oort_vpn. All rights reserved.
//
#import "PacketTunnelProvider.h"
#import "NEPacketTunnelFlow+NEPacketTunnelFlow_Extension.h"
@implementation PacketTunnelProvider
-(OpenVPNAdapter*)vpnAdapter{
if(!_vpnAdapter){
_vpnAdapter = [[OpenVPNAdapter alloc] init];
_vpnAdapter.delegate = self;
}
return _vpnAdapter;
}
-(OpenVPNReachability*)openVpnReach{
if(!_openVpnReach){
_openVpnReach = [[OpenVPNReachability alloc] init];
}
return _openVpnReach;
}
-(void)handleAppMessage:(NSData *)messageData completionHandler:(void (^)(NSData * _Nullable))completionHandler{
}
-(void)startTunnelWithOptions:(NSDictionary<NSString *,NSObject *> *)options completionHandler:(void (^)(NSError * _Nullable))completionHandler{
NETunnelProviderProtocol *proto = (NETunnelProviderProtocol*)self.protocolConfiguration;
if(!proto){
return;
}
NSDictionary<NSString *,id> *provider = proto.providerConfiguration;
NSData * fileContent = provider[@"ovpn"];
OpenVPNConfiguration *openVpnConfiguration = [[OpenVPNConfiguration alloc] init];
openVpnConfiguration.fileContent = fileContent;
NSError *error;
OpenVPNProperties *properties = [self.vpnAdapter applyConfiguration:openVpnConfiguration error:&error];
if(error){
return;
}
if(!properties.autologin){
OpenVPNCredentials *credentials = [[OpenVPNCredentials alloc] init];
credentials.username = [NSString stringWithFormat:@"%@",[options objectForKey:@"username"]];
credentials.password = [NSString stringWithFormat:@"%@",[options objectForKey:@"password"]];
[self.vpnAdapter provideCredentials:credentials error:&error];
if(error){
return;
}
}
[self.openVpnReach startTrackingWithCallback:^(OpenVPNReachabilityStatus status) {
if(status==OpenVPNReachabilityStatusNotReachable){
[self.vpnAdapter reconnectAfterTimeInterval:5];
}
}];
[self.vpnAdapter connect];
self.startHandler = completionHandler;
}
-(void)stopTunnelWithReason:(NEProviderStopReason)reason completionHandler:(void (^)(void))completionHandler{
if ([self.openVpnReach isTracking]) {
[self.openVpnReach stopTracking];
}
[self.vpnAdapter disconnect];
self.stopHandler = completionHandler;
}
-(void)openVPNAdapter:(OpenVPNAdapter *)openVPNAdapter handleError:(NSError *)error{
BOOL isOpen = (BOOL)[error userInfo][OpenVPNAdapterErrorFatalKey];
if(isOpen){
if (self.openVpnReach.isTracking) {
[self.openVpnReach stopTracking];
}
self.startHandler(error);
self.startHandler = nil;
}
}
-(void)openVPNAdapterDidReceiveClockTick:(OpenVPNAdapter *)openVPNAdapter{
}
-(void)openVPNAdapter:(OpenVPNAdapter *)openVPNAdapter handleEvent:(OpenVPNAdapterEvent)event message:(NSString *)message{
switch (event) {
case OpenVPNAdapterEventConnected:
if(self.reasserting){
self.reasserting = false;
}
self.startHandler(nil);
self.startHandler = nil;
break;
case OpenVPNAdapterEventDisconnected:
if (self.openVpnReach.isTracking) {
[self.openVpnReach stopTracking];
}
self.stopHandler();
self.stopHandler = nil;
break;
case OpenVPNAdapterEventReconnecting:
self.reasserting = true;
break;
default:
break;
}
}
-(void)openVPNAdapter:(OpenVPNAdapter *)openVPNAdapter configureTunnelWithNetworkSettings:(NEPacketTunnelNetworkSettings *)networkSettings completionHandler:(void (^)(id<OpenVPNAdapterPacketFlow> _Nullable))completionHandler{
__weak __typeof(self) weak_self = self;
[self setTunnelNetworkSettings:networkSettings completionHandler:^(NSError * _Nullable error) {
if(!error){
completionHandler(weak_self.packetFlow);
}
}];
}
@end