aboutsummaryrefslogtreecommitdiffstats
path: root/WireGuardNetworkExtension/PacketTunnelProvider.swift
blob: f5ba60aad846611d57de5068ed62bbb4e8d284f8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
//
//  PacketTunnelProvider.swift
//  WireGuardNetworkExtension
//
//  Created by Jeroen Leenarts on 19-06-18.
//  Copyright © 2018 Jason A. Donenfeld <Jason@zx2c4.com>. All rights reserved.
//

import NetworkExtension
import os.log

class PacketTunnelProvider: NEPacketTunnelProvider {
    let wireGuardWrapper = WireGuardGoWrapper()

    private let tunnelQueue = DispatchQueue(label: PacketTunnelProvider.description())

    //TODO create a way to transfer config into extension

    override func startTunnel(options: [String: NSObject]?, completionHandler: @escaping (Error?) -> Void) {
        os_log("Starting tunnel", log: Log.general, type: .info)
        // Add code here to start the process of connecting the tunnel.

        //TODO get a settings string in here.
        tunnelQueue.sync {
            wireGuardWrapper.turnOn(withInterfaceName: "TODO", settingsString: "TODO")
        }
    }

    override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
        os_log("Stopping tunnel", log: Log.general, type: .info)
        // Add code here to start the process of stopping the tunnel.
        tunnelQueue.sync {
            wireGuardWrapper.turnOff()
        }
        completionHandler()
    }

    override func handleAppMessage(_ messageData: Data, completionHandler: ((Data?) -> Void)?) {
        // Add code here to handle the message.
        if let handler = completionHandler {
            handler(messageData)
        }
    }

    private func loopReadPackets(_ handler: @escaping ([Data]?, Error?) -> Void) {
        packetFlow.readPackets { [weak self] (_, _) in
            // TODO write packets into the tunnel
            self?.loopReadPackets(handler)
        }
    }

    func writePacket(_ packet: Data, completionHandler: ((Error?) -> Void)?) {
        packetFlow.writePackets([packet], withProtocols: [AF_INET] as [NSNumber])
        completionHandler?(nil)
    }

    func writePackets(_ packets: [Data], completionHandler: ((Error?) -> Void)?) {
        let protocols = [Int32](repeating: AF_INET, count: packets.count) as [NSNumber]
        packetFlow.writePackets(packets, withProtocols: protocols)
        completionHandler?(nil)
    }
}