Skip to content

Commit

Permalink
copies pull request ss-abramchuk#211 Make compatible with SystemExten…
Browse files Browse the repository at this point in the history
…sions API
  • Loading branch information
ntoichkina committed Jul 20, 2021
1 parent 0e2db0b commit d41a87b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Sources/OpenVPNAdapter/library/OpenVPNAdapterImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ - (BOOL)establishTunnel {
}

- (CFSocketNativeHandle)socketHandle {
return CFSocketGetNative(self.packetFlowBridge.openVPNSocket);
return self.packetFlowBridge.openVPNSocket;
}

- (void)clientEventName:(NSString *)eventName message:(NSString *)message {
Expand Down
5 changes: 3 additions & 2 deletions Sources/OpenVPNAdapter/library/OpenVPNPacketFlowBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, weak) id<OpenVPNAdapterPacketFlow> packetFlow;

@property (nonatomic, readonly) CFSocketRef openVPNSocket;
@property (nonatomic, readonly) CFSocketRef packetFlowSocket;
@property (nonatomic, readonly) int openVPNSocket;
@property (nonatomic, readonly) int packetFlowSocket;
@property (nonatomic, readonly) dispatch_source_t source;

- (BOOL)configureSocketsWithError:(NSError **)error;
- (void)invalidateSocketsIfNeeded;
Expand Down
60 changes: 32 additions & 28 deletions Sources/OpenVPNAdapter/library/OpenVPNPacketFlowBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ @implementation OpenVPNPacketFlowBridge

#pragma mark - Sockets Configuration

static void SocketCallback(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *obj) {
if (type != kCFSocketDataCallBack) { return; }
static void SocketCallback(NSData *data, OpenVPNPacketFlowBridge *obj) {
OpenVPNPacket *packet = [[OpenVPNPacket alloc] initWithVPNData:data];

OpenVPNPacket *packet = [[OpenVPNPacket alloc] initWithVPNData:(__bridge NSData *)data];

OpenVPNPacketFlowBridge *bridge = (__bridge OpenVPNPacketFlowBridge *)obj;
OpenVPNPacketFlowBridge *bridge = obj;
[bridge writePackets:@[packet] toPacketFlow:bridge.packetFlow];
}

Expand All @@ -46,13 +44,24 @@ - (BOOL)configureSocketsWithError:(NSError * __autoreleasing *)error {
return NO;
}

CFSocketContext socketCtxt = {0, (__bridge void *)self, NULL, NULL, NULL};

_packetFlowSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sockets[0], kCFSocketDataCallBack,
SocketCallback, &socketCtxt);
_openVPNSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sockets[1], kCFSocketNoCallBack, NULL, NULL);

if (!(_packetFlowSocket && _openVPNSocket)) {
_packetFlowSocket = sockets[0];
_openVPNSocket = sockets[1];

int flags = fcntl(_packetFlowSocket, F_GETFL);
bool success = fcntl(_packetFlowSocket, F_SETFL, flags | O_NONBLOCK) >= 0;
_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, _packetFlowSocket, 0, DISPATCH_QUEUE_SERIAL);
dispatch_source_set_event_handler(_source, ^{
unsigned long bytesAvail = dispatch_source_get_data(_source);
static char buffer[1024*500]; // 500 KB buffer
unsigned long actual = read(_packetFlowSocket, buffer, sizeof(buffer));
NSData* someData = [NSData dataWithBytes:(const void *)buffer length:sizeof(unsigned char)*actual];
SocketCallback(someData, self);
});
dispatch_source_set_cancel_handler(_source, ^{
close(_packetFlowSocket);
});

if (!(flags != 0 && success && _source)) {
if (error) {
NSDictionary *userInfo = @{
NSLocalizedDescriptionKey: @"Failed to create core foundation sockets from native sockets.",
Expand All @@ -70,15 +79,13 @@ - (BOOL)configureSocketsWithError:(NSError * __autoreleasing *)error {
if (!([self configureOptionsForSocket:_packetFlowSocket error:error] &&
[self configureOptionsForSocket:_openVPNSocket error:error])) { return NO; }

CFRunLoopSourceRef packetFlowSocketSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _packetFlowSocket, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), packetFlowSocketSource, kCFRunLoopDefaultMode);
CFRelease(packetFlowSocketSource);
dispatch_activate(_source);

return YES;
}

- (BOOL)configureOptionsForSocket:(CFSocketRef)socket error:(NSError * __autoreleasing *)error {
CFSocketNativeHandle socketHandle = CFSocketGetNative(socket);
- (BOOL)configureOptionsForSocket:(int)socket error:(NSError * __autoreleasing *)error {
CFSocketNativeHandle socketHandle = socket;

int buf_value = 65536;
socklen_t buf_len = sizeof(buf_value);
Expand Down Expand Up @@ -120,17 +127,14 @@ - (BOOL)configureOptionsForSocket:(CFSocketRef)socket error:(NSError * __autorel

- (void)invalidateSocketsIfNeeded {
if (_openVPNSocket) {
CFSocketInvalidate(_openVPNSocket);
CFRelease(_openVPNSocket);

close(_openVPNSocket);
_openVPNSocket = NULL;
}

if (_packetFlowSocket) {
CFSocketInvalidate(_packetFlowSocket);
CFRelease(_packetFlowSocket);

dispatch_source_cancel(_source);
_packetFlowSocket = NULL;
_source = NULL;
}
}

Expand All @@ -149,14 +153,14 @@ - (void)startReading {

#pragma mark - TUN -> VPN

- (void)writePackets:(NSArray<NSData *> *)packets protocols:(NSArray<NSNumber *> *)protocols toSocket:(CFSocketRef)socket {
if (socket == NULL) { return; }

- (void)writePackets:(NSArray<NSData *> *)packets protocols:(NSArray<NSNumber *> *)protocols toSocket:(int)socket {
[packets enumerateObjectsUsingBlock:^(NSData *data, NSUInteger idx, BOOL *stop) {
NSNumber *protocolFamily = protocols[idx];
OpenVPNPacket *packet = [[OpenVPNPacket alloc] initWithPacketFlowData:data protocolFamily:protocolFamily];

CFSocketSendData(socket, NULL, (CFDataRef)packet.vpnData, 0.05);

char buffer[1024*500];
[packet.vpnData getBytes:buffer length:packet.vpnData.length];
write(socket, buffer, packet.vpnData.length);
}];
}

Expand Down

0 comments on commit d41a87b

Please sign in to comment.