I have a MacOS Swift App that uses a Network Extension to connect to a VPN using WireGuard via TunnelKit.
I've added several logs here, but can only see that the "Start Tunnel" one is happening; even though the VPN is connected.
import Foundation
import NetworkExtension
import TunnelKitWireGuardAppExtension
class PacketTunnelProvider: WireGuardTunnelProvider {
private var totalRXBytes: Int = 0
private var totalTXBytes: Int = 0
private let sharedDefaults = UserDefaults(suiteName: "com.co.AppGroup")
override init() {
super.init()
setupUserDefaults()
capturePacketFlowData()
}
override func startTunnel(options: [String : NSObject]?, completionHandler: @escaping (Error?) -> Void) {
logMessage("START TUNNEL")
super.startTunnel(options: options, completionHandler: completionHandler)
}
private func setupUserDefaults() {
sharedDefaults?.set(0, forKey: "TotalRXBytes")
sharedDefaults?.set(0, forKey: "TotalTXBytes")
sharedDefaults?.synchronize()
logMessage("User defaults setup completed")
}
private func capturePacketFlowData() {
logMessage("Attempting to capture packet flow data")
packetFlow.readPackets { [weak self] packets, protocols in
guard let strongSelf = self else {
self?.logMessage("Failed to capture packet flow data: self is nil")
return
}
strongSelf.logMessage("Packets captured: \(packets.count)")
strongSelf.processPackets(packets, isOutgoing: false)
strongSelf.sendOutgoingPackets(packets, protocols: protocols)
strongSelf.capturePacketFlowData() // Continue capturing packets
}
}
private func processPackets(_ packets: [Data], isOutgoing: Bool) {
for packet in packets {
if isOutgoing {
totalTXBytes += packet.count
logMessage("Processed outgoing packet. Size: \(packet.count) bytes. Total TX: \(totalTXBytes) bytes")
updateUserDefaults(for: "TotalTXBytes", with: totalTXBytes)
} else {
totalRXBytes += packet.count
logMessage("Processed incoming packet. Size: \(packet.count) bytes. Total RX: \(totalRXBytes) bytes")
updateUserDefaults(for: "TotalRXBytes", with: totalRXBytes)
}
}
}
func sendOutgoingPackets(_ packets: [Data], protocols: [NSNumber]) {
logMessage("Sending \(packets.count) outgoing packets")
processPackets(packets, isOutgoing: true)
packetFlow.writePackets(packets, withProtocols: protocols)
}
private func updateUserDefaults(for key: String, with value: Int) {
sharedDefaults?.set(value, forKey: key)
sharedDefaults?.synchronize()
logMessage("Updated UserDefaults for key: \(key) with value: \(value)")
}
private func logMessage(_ message: String) {
NSLog(" \(message)")
}
func sizeInMB(data: Data) -> String {
let bytes = Double(data.count)
let megabytes = bytes / (1024 * 1024)
return String(format: "%.2f MB", megabytes)
}
}