Move TunnelKit errors specific to OpenVPN

Use local error domain in LZO to not depend on anything.
This commit is contained in:
Davide De Rosa 2021-11-23 18:32:59 +01:00
parent c7ffa79e91
commit 74f38d335b
16 changed files with 68 additions and 70 deletions

View File

@ -1 +0,0 @@

View File

@ -36,5 +36,5 @@
#import "Errors.h" #import "Errors.h"
NSString *const TunnelKitErrorDomain = @"TunnelKitNative"; NSString *const OpenVPNErrorDomain = @"TunnelKitOpenVPN";
NSString *const TunnelKitErrorKey = @"TunnelKitErrorKey"; NSString *const OpenVPNErrorKey = @"TunnelKitErrorKey";

View File

@ -36,27 +36,26 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
extern NSString *const TunnelKitErrorDomain; extern NSString *const OpenVPNErrorDomain;
extern NSString *const TunnelKitErrorKey; extern NSString *const OpenVPNErrorKey;
typedef NS_ENUM(NSInteger, TunnelKitErrorCode) { typedef NS_ENUM(NSInteger, OpenVPNErrorCode) {
TunnelKitErrorCodeCryptoRandomGenerator = 101, OpenVPNErrorCodeCryptoRandomGenerator = 101,
TunnelKitErrorCodeCryptoHMAC = 102, OpenVPNErrorCodeCryptoHMAC = 102,
TunnelKitErrorCodeCryptoEncryption = 103, OpenVPNErrorCodeCryptoEncryption = 103,
TunnelKitErrorCodeCryptoAlgorithm = 104, OpenVPNErrorCodeCryptoAlgorithm = 104,
TunnelKitErrorCodeTLSCertificateAuthority = 201, OpenVPNErrorCodeTLSCertificateAuthority = 201,
TunnelKitErrorCodeTLSHandshake = 202, OpenVPNErrorCodeTLSHandshake = 202,
TunnelKitErrorCodeTLSClientCertificate = 204, OpenVPNErrorCodeTLSClientCertificate = 204,
TunnelKitErrorCodeTLSClientKey = 205, OpenVPNErrorCodeTLSClientKey = 205,
TunnelKitErrorCodeTLSServerCertificate = 206, OpenVPNErrorCodeTLSServerCertificate = 206,
TunnelKitErrorCodeTLSServerEKU = 207, OpenVPNErrorCodeTLSServerEKU = 207,
TunnelKitErrorCodeTLSServerHost = 208, OpenVPNErrorCodeTLSServerHost = 208,
TunnelKitErrorCodeDataPathOverflow = 301, OpenVPNErrorCodeDataPathOverflow = 301,
TunnelKitErrorCodeDataPathPeerIdMismatch = 302, OpenVPNErrorCodeDataPathPeerIdMismatch = 302,
TunnelKitErrorCodeDataPathCompression = 303, OpenVPNErrorCodeDataPathCompression = 303
TunnelKitErrorCodeLZO = 401,
}; };
static inline NSError *TunnelKitErrorWithCode(TunnelKitErrorCode code) { static inline NSError *OpenVPNErrorWithCode(OpenVPNErrorCode code) {
return [NSError errorWithDomain:TunnelKitErrorDomain code:code userInfo:nil]; return [NSError errorWithDomain:OpenVPNErrorDomain code:code userInfo:nil];
} }

View File

@ -320,7 +320,7 @@ static const NSInteger CryptoAEADTagLength = 16;
if (hasPeerId) { if (hasPeerId) {
if (peerId != self.peerId) { if (peerId != self.peerId) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeDataPathPeerIdMismatch); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeDataPathPeerIdMismatch);
} }
return NO; return NO;
} }

View File

@ -109,7 +109,7 @@
if ([self.cipherAlgorithm hasSuffix:@"-cbc"]) { if ([self.cipherAlgorithm hasSuffix:@"-cbc"]) {
if (!self.digestAlgorithm) { if (!self.digestAlgorithm) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeCryptoAlgorithm); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoAlgorithm);
} }
return NO; return NO;
} }
@ -130,7 +130,7 @@
// not supported // not supported
else { else {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeCryptoAlgorithm); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoAlgorithm);
} }
return NO; return NO;
} }

View File

@ -151,7 +151,7 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
if (self.cipher) { if (self.cipher) {
if (RAND_bytes(outIV, self.cipherIVLength) != 1) { if (RAND_bytes(outIV, self.cipherIVLength) != 1) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeCryptoRandomGenerator); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoRandomGenerator);
} }
return NO; return NO;
} }
@ -214,7 +214,7 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, self.digestLength) != 0) { if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, self.digestLength) != 0) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeCryptoHMAC); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoHMAC);
} }
return NO; return NO;
} }
@ -239,7 +239,7 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, self.digestLength) != 0) { if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, self.digestLength) != 0) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeCryptoHMAC); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoHMAC);
} }
return NO; return NO;
} }
@ -358,7 +358,7 @@ const NSInteger CryptoCBCMaxHMACLength = 100;
if (hasPeerId) { if (hasPeerId) {
if (peerId != self.peerId) { if (peerId != self.peerId) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeDataPathPeerIdMismatch); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeDataPathPeerIdMismatch);
} }
return NO; return NO;
} }

View File

@ -194,7 +194,7 @@ static const NSInteger CryptoCTRTagLength = 32;
if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, CryptoCTRTagLength) != 0) { if (TUNNEL_CRYPTO_SUCCESS(code) && CRYPTO_memcmp(self.bufferDecHMAC, bytes, CryptoCTRTagLength) != 0) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeCryptoHMAC); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoHMAC);
} }
return NO; return NO;
} }

View File

@ -188,7 +188,7 @@
case DataPacketLZOCompress: case DataPacketLZOCompress:
if (!weakSelf.lzo) { // compressed packet unexpected if (!weakSelf.lzo) { // compressed packet unexpected
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeDataPathCompression); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeDataPathCompression);
} }
return NO; return NO;
} }
@ -199,7 +199,7 @@
if (compressionFraming == CompressionFramingNativeCompressV2) { if (compressionFraming == CompressionFramingNativeCompressV2) {
if (payload[1] != DataPacketV2Uncompressed) { if (payload[1] != DataPacketV2Uncompressed) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeDataPathCompression); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeDataPathCompression);
} }
return NO; return NO;
} }
@ -213,7 +213,7 @@
default: default:
// @"Expected NO_COMPRESS (found %X != %X)", payload[0], DataPacketNoCompress); // @"Expected NO_COMPRESS (found %X != %X)", payload[0], DataPacketNoCompress);
// if (error) { // if (error) {
// *error = TunnelKitErrorWithCode(TunnelKitErrorCodeDataPathCompression); // *error = OpenVPNErrorWithCode(OpenVPNErrorCodeDataPathCompression);
// } // }
// return NO; // return NO;
*payloadOffset = 0; *payloadOffset = 0;
@ -308,7 +308,7 @@
if (self.outPacketId > self.maxPacketId) { if (self.outPacketId > self.maxPacketId) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeDataPathOverflow); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeDataPathOverflow);
} }
return nil; return nil;
} }
@ -369,7 +369,7 @@
} }
if (packetId > self.maxPacketId) { if (packetId > self.maxPacketId) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeDataPathOverflow); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeDataPathOverflow);
} }
return nil; return nil;
} }

View File

@ -48,10 +48,10 @@ static const char *const TLSBoxServerEKU = "TLS Web Server Authentication";
int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) { int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
if (!ok) { if (!ok) {
NSError *error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSCertificateAuthority); NSError *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSCertificateAuthority);
[[NSNotificationCenter defaultCenter] postNotificationName:TLSBoxPeerVerificationErrorNotification [[NSNotificationCenter defaultCenter] postNotificationName:TLSBoxPeerVerificationErrorNotification
object:nil object:nil
userInfo:@{TunnelKitErrorKey: error}]; userInfo:@{OpenVPNErrorKey: error}];
} }
return ok; return ok;
} }
@ -208,7 +208,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
if (!SSL_CTX_load_verify_locations(self.ctx, [self.caPath cStringUsingEncoding:NSASCIIStringEncoding], NULL)) { if (!SSL_CTX_load_verify_locations(self.ctx, [self.caPath cStringUsingEncoding:NSASCIIStringEncoding], NULL)) {
ERR_print_errors_fp(stdout); ERR_print_errors_fp(stdout);
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSCertificateAuthority); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSCertificateAuthority);
} }
return NO; return NO;
} }
@ -217,7 +217,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
if (!SSL_CTX_use_certificate_file(self.ctx, [self.clientCertificatePath cStringUsingEncoding:NSASCIIStringEncoding], SSL_FILETYPE_PEM)) { if (!SSL_CTX_use_certificate_file(self.ctx, [self.clientCertificatePath cStringUsingEncoding:NSASCIIStringEncoding], SSL_FILETYPE_PEM)) {
ERR_print_errors_fp(stdout); ERR_print_errors_fp(stdout);
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSClientCertificate); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSClientCertificate);
} }
return NO; return NO;
} }
@ -226,7 +226,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
if (!SSL_CTX_use_PrivateKey_file(self.ctx, [self.clientKeyPath cStringUsingEncoding:NSASCIIStringEncoding], SSL_FILETYPE_PEM)) { if (!SSL_CTX_use_PrivateKey_file(self.ctx, [self.clientKeyPath cStringUsingEncoding:NSASCIIStringEncoding], SSL_FILETYPE_PEM)) {
ERR_print_errors_fp(stdout); ERR_print_errors_fp(stdout);
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSClientKey); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSClientKey);
} }
return NO; return NO;
} }
@ -246,7 +246,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
if (!SSL_do_handshake(self.ssl)) { if (!SSL_do_handshake(self.ssl)) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSHandshake); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSHandshake);
} }
return NO; return NO;
} }
@ -266,14 +266,14 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
if (self.checksEKU && ![self verifyEKUWithSSL:self.ssl]) { if (self.checksEKU && ![self verifyEKUWithSSL:self.ssl]) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSServerEKU); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSServerEKU);
} }
return nil; return nil;
} }
if (self.checksSANHost && ![self verifySANHostWithSSL:self.ssl]) { if (self.checksSANHost && ![self verifySANHostWithSSL:self.ssl]) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSServerHost); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSServerHost);
} }
return nil; return nil;
} }
@ -283,7 +283,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
} }
if ((ret < 0) && !BIO_should_retry(self.bioCipherTextOut)) { if ((ret < 0) && !BIO_should_retry(self.bioCipherTextOut)) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSHandshake); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSHandshake);
} }
} }
return nil; return nil;
@ -301,7 +301,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
} }
if ((ret < 0) && !BIO_should_retry(self.bioPlainText)) { if ((ret < 0) && !BIO_should_retry(self.bioPlainText)) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSHandshake); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSHandshake);
} }
} }
return NO; return NO;
@ -323,7 +323,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
const int ret = BIO_write(self.bioCipherTextIn, text, (int)length); const int ret = BIO_write(self.bioCipherTextIn, text, (int)length);
if (ret != length) { if (ret != length) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSHandshake); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSHandshake);
} }
return NO; return NO;
} }
@ -344,7 +344,7 @@ int TLSBoxVerifyPeer(int ok, X509_STORE_CTX *ctx) {
const int ret = BIO_write(self.bioPlainText, text, (int)length); const int ret = BIO_write(self.bioPlainText, text, (int)length);
if (ret != length) { if (ret != length) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeTLSHandshake); *error = OpenVPNErrorWithCode(OpenVPNErrorCodeTLSHandshake);
} }
return NO; return NO;
} }

View File

@ -41,7 +41,7 @@
#define TUNNEL_CRYPTO_RETURN_STATUS(ret)\ #define TUNNEL_CRYPTO_RETURN_STATUS(ret)\
if (ret <= 0) {\ if (ret <= 0) {\
if (error) {\ if (error) {\
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeCryptoEncryption);\ *error = OpenVPNErrorWithCode(OpenVPNErrorCodeCryptoEncryption);\
}\ }\
return NO;\ return NO;\
}\ }\

View File

@ -23,9 +23,10 @@
// along with TunnelKit. If not, see <http://www.gnu.org/licenses/>. // along with TunnelKit. If not, see <http://www.gnu.org/licenses/>.
// //
#import "StandardLZO.h"
#import "lib/minilzo.h" #import "lib/minilzo.h"
#import "Errors.h" NSString *const TunnelKitLZOErrorDomain = @"TunnelKitLZO";
#define HEAP_ALLOC(var,size) \ #define HEAP_ALLOC(var,size) \
lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
@ -68,7 +69,7 @@ static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
const int status = lzo1x_1_compress(data.bytes, data.length, dst.mutableBytes, &dstLength, wrkmem); const int status = lzo1x_1_compress(data.bytes, data.length, dst.mutableBytes, &dstLength, wrkmem);
if (status != LZO_E_OK) { if (status != LZO_E_OK) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeLZO); *error = [NSError errorWithDomain:TunnelKitLZOErrorDomain code:0 userInfo:nil];
} }
return nil; return nil;
} }
@ -90,7 +91,7 @@ static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS);
const int status = lzo1x_decompress_safe(bytes, length, self.decompressedBuffer.mutableBytes, &dstLength, NULL); const int status = lzo1x_decompress_safe(bytes, length, self.decompressedBuffer.mutableBytes, &dstLength, NULL);
if (status != LZO_E_OK) { if (status != LZO_E_OK) {
if (error) { if (error) {
*error = TunnelKitErrorWithCode(TunnelKitErrorCodeLZO); *error = [NSError errorWithDomain:TunnelKitLZOErrorDomain code:0 userInfo:nil];
} }
return nil; return nil;
} }

View File

@ -1 +0,0 @@
../../CTunnelKitCore/include/Errors.h

View File

@ -0,0 +1,3 @@
#import <Foundation/Foundation.h>
extern NSString *const TunnelKitLZOErrorDomain;

View File

@ -895,7 +895,7 @@ extension OpenVPNTunnelProvider {
} }
private func unifiedError(from error: Error) -> OpenVPNProviderError { private func unifiedError(from error: Error) -> OpenVPNProviderError {
if let te = error.tunnelKitErrorCode() { if let te = error.openVPNErrorCode() {
switch te { switch te {
case .cryptoRandomGenerator, .cryptoAlgorithm: case .cryptoRandomGenerator, .cryptoAlgorithm:
return .encryptionInitialization return .encryptionInitialization
@ -918,9 +918,6 @@ extension OpenVPNTunnelProvider {
case .dataPathCompression: case .dataPathCompression:
return .serverCompression return .serverCompression
case .LZO:
return .lzo
default: default:
break break
} }

View File

@ -24,19 +24,19 @@
// //
import Foundation import Foundation
import CTunnelKitCore import CTunnelKitOpenVPNCore
extension Error { extension Error {
public func isTunnelKitError() -> Bool { public func isOpenVPNError() -> Bool {
let te = self as NSError let te = self as NSError
return te.domain == TunnelKitErrorDomain return te.domain == OpenVPNErrorDomain
} }
public func tunnelKitErrorCode() -> TunnelKitErrorCode? { public func openVPNErrorCode() -> OpenVPNErrorCode? {
let te = self as NSError let te = self as NSError
guard te.domain == TunnelKitErrorDomain else { guard te.domain == OpenVPNErrorDomain else {
return nil return nil
} }
return TunnelKitErrorCode(rawValue: te.code) return OpenVPNErrorCode(rawValue: te.code)
} }
} }

View File

@ -259,7 +259,7 @@ public class OpenVPNSession: Session {
// WARNING: runs in notification source queue (we know it's "queue", but better be safe than sorry) // WARNING: runs in notification source queue (we know it's "queue", but better be safe than sorry)
tlsObserver = NotificationCenter.default.addObserver(forName: .TLSBoxPeerVerificationError, object: nil, queue: nil) { (notification) in tlsObserver = NotificationCenter.default.addObserver(forName: .TLSBoxPeerVerificationError, object: nil, queue: nil) { (notification) in
let error = notification.userInfo?[TunnelKitErrorKey] as? Error let error = notification.userInfo?[OpenVPNErrorKey] as? Error
self.queue.async { self.queue.async {
self.deferStop(.shutdown, error) self.deferStop(.shutdown, error)
} }
@ -685,7 +685,7 @@ public class OpenVPNSession: Session {
do { do {
cipherTextOut = try negotiationKey.tls.pullCipherText() cipherTextOut = try negotiationKey.tls.pullCipherText()
} catch let e { } catch let e {
if let _ = e.tunnelKitErrorCode() { if let _ = e.openVPNErrorCode() {
log.error("TLS.auth: Failed pulling ciphertext (error: \(e))") log.error("TLS.auth: Failed pulling ciphertext (error: \(e))")
shutdown(error: e) shutdown(error: e)
return return
@ -714,7 +714,7 @@ public class OpenVPNSession: Session {
do { do {
cipherTextOut = try negotiationKey.tls.pullCipherText() cipherTextOut = try negotiationKey.tls.pullCipherText()
} catch let e { } catch let e {
if let _ = e.tunnelKitErrorCode() { if let _ = e.openVPNErrorCode() {
log.error("TLS.auth: Failed pulling ciphertext (error: \(e))") log.error("TLS.auth: Failed pulling ciphertext (error: \(e))")
shutdown(error: e) shutdown(error: e)
return return
@ -808,7 +808,7 @@ public class OpenVPNSession: Session {
do { do {
cipherTextOut = try negotiationKey.tls.pullCipherText() cipherTextOut = try negotiationKey.tls.pullCipherText()
} catch let e { } catch let e {
if let _ = e.tunnelKitErrorCode() { if let _ = e.openVPNErrorCode() {
log.error("TLS.connect: Failed pulling ciphertext (error: \(e))") log.error("TLS.connect: Failed pulling ciphertext (error: \(e))")
shutdown(error: e) shutdown(error: e)
return return
@ -847,7 +847,7 @@ public class OpenVPNSession: Session {
log.debug("TLS.connect: Send pulled ciphertext (\(cipherTextOut.count) bytes)") log.debug("TLS.connect: Send pulled ciphertext (\(cipherTextOut.count) bytes)")
enqueueControlPackets(code: .controlV1, key: negotiationKey.id, payload: cipherTextOut) enqueueControlPackets(code: .controlV1, key: negotiationKey.id, payload: cipherTextOut)
} catch let e { } catch let e {
if let _ = e.tunnelKitErrorCode() { if let _ = e.openVPNErrorCode() {
log.error("TLS.connect: Failed pulling ciphertext (error: \(e))") log.error("TLS.connect: Failed pulling ciphertext (error: \(e))")
shutdown(error: e) shutdown(error: e)
return return
@ -1147,7 +1147,7 @@ public class OpenVPNSession: Session {
tunnel?.writePackets(decryptedPackets, completionHandler: nil) tunnel?.writePackets(decryptedPackets, completionHandler: nil)
} catch let e { } catch let e {
guard !e.isTunnelKitError() else { guard !e.isOpenVPNError() else {
deferStop(.shutdown, e) deferStop(.shutdown, e)
return return
} }
@ -1187,7 +1187,7 @@ public class OpenVPNSession: Session {
} }
} }
} catch let e { } catch let e {
guard !e.isTunnelKitError() else { guard !e.isOpenVPNError() else {
deferStop(.shutdown, e) deferStop(.shutdown, e)
return return
} }