From 7f5ad3e503f231893dc5d298f703c4b72b83bdb9 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 16 Jun 2021 15:56:21 +0200 Subject: [PATCH] Kit: Adapter: iterate through all FDs to find UTUN This is a bit of a kludge, until I find something better. We simply iterate through all FDs, and call getsockopt on each one until we find the utun FD. This works, and completes rather quickly (fd is usually 6 or 7). Rather than maintain the old path for older kernels, just use this for all versions, to get more coverage. Other techniques involve undocumented APIs; this one has the advantage of using nothing undocumented. Signed-off-by: Jason A. Donenfeld --- Sources/WireGuardKit/WireGuardAdapter.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Sources/WireGuardKit/WireGuardAdapter.swift b/Sources/WireGuardKit/WireGuardAdapter.swift index 0ed9b3b..b18769e 100644 --- a/Sources/WireGuardKit/WireGuardAdapter.swift +++ b/Sources/WireGuardKit/WireGuardAdapter.swift @@ -57,7 +57,14 @@ public class WireGuardAdapter { /// Tunnel device file descriptor. private var tunnelFileDescriptor: Int32? { - return self.packetTunnelProvider?.packetFlow.value(forKeyPath: "socket.fileDescriptor") as? Int32 + var buf = [CChar](repeating: 0, count: Int(IFNAMSIZ)) + for fd: Int32 in 0...1024 { + var len = socklen_t(buf.count) + if getsockopt(fd, SYSPROTO_CONTROL, 2, &buf, &len) == 0 && String(cString: buf).hasPrefix("utun") { + return fd + } + } + return nil } /// Returns a WireGuard version.