diff --git a/Sources/OpenVPNAdapter/OpenVPNAdapter.mm b/Sources/OpenVPNAdapter/OpenVPNAdapter.mm index a5c4e01..8d4795c 100644 --- a/Sources/OpenVPNAdapter/OpenVPNAdapter.mm +++ b/Sources/OpenVPNAdapter/OpenVPNAdapter.mm @@ -172,6 +172,7 @@ - (BOOL)addIPV4Address:(NSString *)address subnetMask:(NSString *)subnetMask gateway:(NSString *)gateway { self.networkSettingsBuilder.ipv4DefaultGateway = gateway; + [self.networkSettingsBuilder.ipv4LocalAddresses addObject:address]; [self.networkSettingsBuilder.ipv4SubnetMasks addObject:subnetMask]; @@ -180,6 +181,7 @@ - (BOOL)addIPV6Address:(NSString *)address prefixLength:(NSNumber *)prefixLength gateway:(NSString *)gateway { self.networkSettingsBuilder.ipv6DefaultGateway = gateway; + [self.networkSettingsBuilder.ipv6LocalAddresses addObject:address]; [self.networkSettingsBuilder.ipv6NetworkPrefixLengths addObject:prefixLength]; @@ -188,34 +190,78 @@ - (BOOL)addIPV4Route:(NEIPv4Route *)route { route.gatewayAddress = self.networkSettingsBuilder.ipv4DefaultGateway; - [self.networkSettingsBuilder.ipv4IncludedRoutes addObject:route]; - return YES; + NSUInteger index = [self.networkSettingsBuilder.ipv4IncludedRoutes indexOfObjectPassingTest:^BOOL(NEIPv4Route *obj, NSUInteger idx, BOOL *stop) { + return [obj.destinationAddress isEqualToString:route.destinationAddress] && + [obj.destinationSubnetMask isEqualToString:route.destinationSubnetMask]; + }]; + + if (index == NSNotFound) { + [self.networkSettingsBuilder.ipv4IncludedRoutes addObject:route]; + return YES; + } else { + return NO; + } } - (BOOL)addIPV6Route:(NEIPv6Route *)route { route.gatewayAddress = self.networkSettingsBuilder.ipv6DefaultGateway; - [self.networkSettingsBuilder.ipv6IncludedRoutes addObject:route]; - return YES; + NSUInteger index = [self.networkSettingsBuilder.ipv6IncludedRoutes indexOfObjectPassingTest:^BOOL(NEIPv6Route *obj, NSUInteger idx, BOOL *stop) { + return [obj.destinationAddress isEqualToString:route.destinationAddress] && + obj.destinationNetworkPrefixLength == route.destinationNetworkPrefixLength; + }]; + + if (index == NSNotFound) { + [self.networkSettingsBuilder.ipv6IncludedRoutes addObject:route]; + return YES; + } else { + return NO; + } } - (BOOL)excludeIPV4Route:(NEIPv4Route *)route { - [self.networkSettingsBuilder.ipv4ExcludedRoutes addObject:route]; - return YES; + NSUInteger index = [self.networkSettingsBuilder.ipv4ExcludedRoutes indexOfObjectPassingTest:^BOOL(NEIPv4Route *obj, NSUInteger idx, BOOL *stop) { + return [obj.destinationAddress isEqualToString:route.destinationAddress] && + [obj.destinationSubnetMask isEqualToString:route.destinationSubnetMask]; + }]; + + if (index == NSNotFound) { + [self.networkSettingsBuilder.ipv4ExcludedRoutes addObject:route]; + return YES; + } else { + return NO; + } } - (BOOL)excludeIPV6Route:(NEIPv6Route *)route { - [self.networkSettingsBuilder.ipv6ExcludedRoutes addObject:route]; - return YES; + NSUInteger index = [self.networkSettingsBuilder.ipv6ExcludedRoutes indexOfObjectPassingTest:^BOOL(NEIPv6Route *obj, NSUInteger idx, BOOL *stop) { + return [obj.destinationAddress isEqualToString:route.destinationAddress] && + obj.destinationNetworkPrefixLength == route.destinationNetworkPrefixLength; + }]; + + if (index == NSNotFound) { + [self.networkSettingsBuilder.ipv6ExcludedRoutes addObject:route]; + return YES; + } else { + return NO; + } } - (BOOL)addDNS:(NSString *)dns { + if ([self.networkSettingsBuilder.dnsServers containsObject:dns]) { + return NO; + } + [self.networkSettingsBuilder.dnsServers addObject:dns]; return YES; } - (BOOL)addSearchDomain:(NSString *)domain { + if ([self.networkSettingsBuilder.searchDomains containsObject:domain]) { + return NO; + } + [self.networkSettingsBuilder.searchDomains addObject:domain]; return YES; } @@ -231,6 +277,10 @@ } - (BOOL)addProxyBypassHost:(NSString *)bypassHost { + if ([self.networkSettingsBuilder.proxyExceptionList containsObject:bypassHost]) { + return NO; + } + [self.networkSettingsBuilder.proxyExceptionList addObject:bypassHost]; return YES; } diff --git a/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.h b/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.h index d56b5fb..63903d2 100644 --- a/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.h +++ b/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.h @@ -33,10 +33,10 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) NSMutableArray *ipv6IncludedRoutes; @property (nonatomic, readonly) NSMutableArray *ipv6ExcludedRoutes; -@property (nonatomic, readonly) NSMutableSet *dnsServers; -@property (nonatomic, readonly) NSMutableSet *searchDomains; +@property (nonatomic, readonly) NSMutableArray *dnsServers; +@property (nonatomic, readonly) NSMutableArray *searchDomains; -@property (nonatomic, readonly) NSMutableSet *proxyExceptionList; +@property (nonatomic, readonly) NSMutableArray *proxyExceptionList; @property (nonatomic) BOOL autoProxyConfigurationEnabled; @property (nonatomic, copy, nullable) NSURL *proxyAutoConfigurationURL; diff --git a/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.m b/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.m index c70843a..f95433c 100644 --- a/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.m +++ b/Sources/OpenVPNAdapter/OpenVPNNetworkSettingsBuilder.m @@ -14,8 +14,6 @@ @interface OpenVPNNetworkSettingsBuilder () -// TODO: Use NSHashTable for routes to avoid duplicates - @property (nonatomic) NSMutableArray *ipv4LocalAddresses; @property (nonatomic) NSMutableArray *ipv4SubnetMasks; @property (nonatomic) NSMutableArray *ipv4IncludedRoutes; @@ -26,10 +24,10 @@ @property (nonatomic) NSMutableArray *ipv6IncludedRoutes; @property (nonatomic) NSMutableArray *ipv6ExcludedRoutes; -@property (nonatomic) NSMutableSet *dnsServers; -@property (nonatomic) NSMutableSet *searchDomains; +@property (nonatomic) NSMutableArray *dnsServers; +@property (nonatomic) NSMutableArray *searchDomains; -@property (nonatomic) NSMutableSet *proxyExceptionList; +@property (nonatomic) NSMutableArray *proxyExceptionList; @end @@ -67,8 +65,8 @@ } if (self.dnsServers.ovpn_isNotEmpty) { - NEDNSSettings *dnsSettings = [[NEDNSSettings alloc] initWithServers:self.dnsServers.allObjects]; - dnsSettings.searchDomains = self.searchDomains.allObjects; + NEDNSSettings *dnsSettings = [[NEDNSSettings alloc] initWithServers:self.dnsServers]; + dnsSettings.searchDomains = self.searchDomains; networkSettings.DNSSettings = dnsSettings; } @@ -77,7 +75,7 @@ proxySettings.autoProxyConfigurationEnabled = self.autoProxyConfigurationEnabled; proxySettings.proxyAutoConfigurationURL = self.proxyAutoConfigurationURL; - proxySettings.exceptionList = self.proxyExceptionList.allObjects; + proxySettings.exceptionList = self.proxyExceptionList; proxySettings.HTTPServer = self.httpProxyServer; proxySettings.HTTPEnabled = self.httpProxyServerEnabled; proxySettings.HTTPSServer = self.httpsProxyServer; @@ -133,18 +131,18 @@ return _ipv6ExcludedRoutes; } -- (NSMutableSet *)dnsServers { - if (!_dnsServers) { _dnsServers = [[NSMutableSet alloc] init]; } +- (NSMutableArray *)dnsServers { + if (!_dnsServers) { _dnsServers = [[NSMutableArray alloc] init]; } return _dnsServers; } -- (NSMutableSet *)searchDomains { - if (!_searchDomains) { _searchDomains = [[NSMutableSet alloc] init]; } +- (NSMutableArray *)searchDomains { + if (!_searchDomains) { _searchDomains = [[NSMutableArray alloc] init]; } return _searchDomains; } -- (NSMutableSet *)proxyExceptionList { - if (!_proxyExceptionList) { _proxyExceptionList = [[NSMutableSet alloc] init]; } +- (NSMutableArray *)proxyExceptionList { + if (!_proxyExceptionList) { _proxyExceptionList = [[NSMutableArray alloc] init]; } return _proxyExceptionList; }