diff options
author | Roopesh Chander <roop@roopc.net> | 2018-11-29 15:46:21 +0530 |
---|---|---|
committer | Roopesh Chander <roop@roopc.net> | 2018-11-30 00:36:33 +0530 |
commit | 679d63294dad8abdb68b9bcd270746912ec4e7cf (patch) | |
tree | 1de73899aa8165536863b164f3b8e30f9ccfe200 /WireGuard/WireGuardNetworkExtension | |
parent | Info.plist: Add app group id for accessing from both the app and the network extension (diff) | |
download | wireguard-apple-679d63294dad8abdb68b9bcd270746912ec4e7cf.tar.xz wireguard-apple-679d63294dad8abdb68b9bcd270746912ec4e7cf.zip |
NE: Write log to file
Signed-off-by: Roopesh Chander <roop@roopc.net>
Diffstat (limited to 'WireGuard/WireGuardNetworkExtension')
-rw-r--r-- | WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift | 89 |
1 files changed, 79 insertions, 10 deletions
diff --git a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift index cae4524..4111282 100644 --- a/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift +++ b/WireGuard/WireGuardNetworkExtension/PacketTunnelProvider.swift @@ -2,6 +2,7 @@ // Copyright © 2018 WireGuard LLC. All Rights Reserved. import NetworkExtension +import Foundation import os.log enum PacketTunnelProviderError: Error { @@ -11,6 +12,8 @@ enum PacketTunnelProviderError: Error { case coultNotSetNetworkSettings } +private var logFileHandle: FileHandle? + /// A packet tunnel provider object. class PacketTunnelProvider: NEPacketTunnelProvider { @@ -35,7 +38,11 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } func startTunnel(with tunnelConfiguration: TunnelConfiguration, completionHandler startTunnelCompletionHandler: @escaping (Error?) -> Void) { - os_log("Starting tunnel", log: OSLog.default, type: .info) + + // Configure logging + configureLogger() + + wg_log(.info, "Starting tunnel") // Resolve endpoint domains @@ -44,8 +51,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { do { resolvedEndpoints = try DNSResolver.resolveSync(endpoints: endpoints) } catch DNSResolverError.dnsResolutionFailed(let hostnames) { - os_log("Starting tunnel failed: DNS resolution failure for %{public}d hostnames (%{public}s)", log: OSLog.default, - type: .error, hostnames.count, hostnames.joined(separator: ", ")) + wg_log(.error, "Starting tunnel failed: DNS resolution failure") + wg_log(.error, "Hostnames for which DNS resolution failed: \(hostnames.joined(separator: ", "))") ErrorNotifier.notify(PacketTunnelProviderError.dnsResolutionFailure(hostnames: hostnames), from: self) startTunnelCompletionHandler(PacketTunnelProviderError.dnsResolutionFailure(hostnames: hostnames)) return @@ -62,11 +69,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider { // Bring up wireguard-go backend - configureLogger() - let fd = packetFlow.value(forKeyPath: "socket.fileDescriptor") as! Int32 if fd < 0 { - os_log("Starting tunnel failed: Could not determine file descriptor", log: OSLog.default, type: .error) + wg_log(.error, "Starting tunnel failed: Could not determine file descriptor") ErrorNotifier.notify(PacketTunnelProviderError.couldNotStartWireGuard, from: self) startTunnelCompletionHandler(PacketTunnelProviderError.couldNotStartWireGuard) return @@ -76,7 +81,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { let handle = connect(interfaceName: tunnelConfiguration.interface.name, settings: wireguardSettings, fd: fd) if handle < 0 { - os_log("Starting tunnel failed: Could not start WireGuard", log: OSLog.default, type: .error) + wg_log(.error, "Starting tunnel failed: Could not start WireGuard") ErrorNotifier.notify(PacketTunnelProviderError.couldNotStartWireGuard, from: self) startTunnelCompletionHandler(PacketTunnelProviderError.couldNotStartWireGuard) return @@ -89,7 +94,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { let networkSettings: NEPacketTunnelNetworkSettings = packetTunnelSettingsGenerator.generateNetworkSettings() setTunnelNetworkSettings(networkSettings) { (error) in if let error = error { - os_log("Starting tunnel failed: Error setting network settings: %s", log: OSLog.default, type: .error, error.localizedDescription) + wg_log(.error, "Starting tunnel failed: Error setting network settings.") + wg_log(.error, "Error from setTunnelNetworkSettings: \(error.localizedDescription)") ErrorNotifier.notify(PacketTunnelProviderError.coultNotSetNetworkSettings, from: self) startTunnelCompletionHandler(PacketTunnelProviderError.coultNotSetNetworkSettings) } else { @@ -100,14 +106,34 @@ class PacketTunnelProvider: NEPacketTunnelProvider { /// Begin the process of stopping the tunnel. override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { - os_log("Stopping tunnel", log: OSLog.default, type: .info) + wg_log(.info, "Stopping tunnel") if let handle = wgHandle { wgTurnOff(handle) } + if let fileHandle = logFileHandle { + fileHandle.closeFile() + } completionHandler() } private func configureLogger() { + + // Setup writing the log to a file + if let networkExtensionLogFileURL = FileManager.networkExtensionLogFileURL { + let fileManager = FileManager.default + let filePath = networkExtensionLogFileURL.path + fileManager.createFile(atPath: filePath, contents: nil) // Create the file if it doesn't already exist + if let fileHandle = FileHandle(forWritingAtPath: filePath) { + logFileHandle = fileHandle + } else { + os_log("Can't open log file for writing. Log is not saved to file.", log: OSLog.default, type: .error) + logFileHandle = nil + } + } else { + os_log("Can't obtain log file URL. Log is not saved to file.", log: OSLog.default, type: .error) + } + + // Setup WireGuard logger wgSetLogger { (level, msgCStr) in let logType: OSLogType switch level { @@ -121,7 +147,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { logType = .default } let msg = (msgCStr != nil) ? String(cString: msgCStr!) : "" - os_log("%{public}s", log: OSLog.default, type: logType, msg) + wg_log(logType, msg) } } @@ -130,6 +156,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { return wgTurnOn(nameGoStr, settingsGoStr, fd) } } + } private func withStringsAsGoStrings<R>(_ str1: String, _ str2: String, closure: (gostring_t, gostring_t) -> R) -> R { @@ -141,3 +168,45 @@ private func withStringsAsGoStrings<R>(_ str1: String, _ str2: String, closure: } } } + +private func wg_log(_ type: OSLogType, _ msg: StaticString) { + // Write to os log + os_log(msg, log: OSLog.default, type: type) + // Write to file log + let msgString: String = msg.withUTF8Buffer { (ptr: UnsafeBufferPointer<UInt8>) -> String in + return String(decoding: ptr, as: UTF8.self) + } + file_log(type: type, message: msgString) +} + +private func wg_log(_ type: OSLogType, _ msg: String) { + // Write to os log + os_log("%{public}s", log: OSLog.default, type: type, msg) + // Write to file log + file_log(type: type, message: msg) +} + +private func file_log(type: OSLogType, message: String) { + var msgLine = type.toMessagePrefix() + message + if (msgLine.last! != "\n") { + msgLine.append("\n") + } + let data = msgLine.data(using: .utf8) + if let data = data, let logFileHandle = logFileHandle { + logFileHandle.write(data) + logFileHandle.synchronizeFile() + } +} + +extension OSLogType { + func toMessagePrefix() -> String { + switch (self) { + case .debug: return "Debug: " + case .info: return "Info: " + case .error: return "Error: " + case .fault: return "Fault: " + default: + return "Unknown: " + } + } +} |