Skip to content

Instantly share code, notes, and snippets.

@aravindhkumar23
Created September 27, 2023 12:07
Show Gist options
  • Save aravindhkumar23/ec66fc78e4f9c5dbae4bab676c0b9af9 to your computer and use it in GitHub Desktop.
Save aravindhkumar23/ec66fc78e4f9c5dbae4bab676c0b9af9 to your computer and use it in GitHub Desktop.
C-based implementation for nw_connection_t and swift implementation for NWConnection [adding it here so that some developers will get help from this.]. Adding to this [(NW_PARAMETERS_DEFAULT_CONFIGURATION, NW_PARAMETERS_DEFAULT_CONFIGURATION)] macros for nw_parameters_create_secure_tcp is not available in swift so we need to create an obj-c brid…
//
// ViewController.swift
// vpn-client
//
// Created by Aravindh Kumar on 9/13/23.
//
import UIKit
import Network
import NetworkExtension
import Foundation
class ViewController: UIViewController {
private let queue = DispatchQueue(label: "com.rootquotient.packet-tunnel-provider")
var headers: [(name: String, value: String)] = []
let socketUrl : String = "https://your-custom-domain.com"
override func viewDidLoad() {
super.viewDidLoad()
//add you custom headers here
headers.append(("Host","your-custom-domain.com"))
//......
}
@IBAction func connectAction(_ sender: Any) {
create_C_NW_Connection()
}
@IBAction func connectToSwift(_ sender: Any) {
create_Swift_NW_Connection()
}
func create_C_NW_Connection(){
print("Connection to ws at \(socketUrl)")
let endpoint = nw_endpoint_create_url(socketUrl)
let params : nw_parameters_t = my_nw_parameters_create_tcp()
let stack : nw_protocol_stack_t = nw_parameters_copy_default_protocol_stack(params);
let ws : nw_protocol_options_t = nw_ws_create_options(nw_ws_version_13);
nw_ws_options_set_auto_reply_ping(ws, true)
nw_ws_options_add_subprotocol(ws, "wapp_pkt_tunnel")
nw_ws_options_add_subprotocol(ws, "binary")
for (field, value) in headers {
nw_ws_options_add_additional_header(ws, field, value)
}
nw_protocol_stack_prepend_application_protocol(stack, ws);
let connection : nw_connection_t = nw_connection_create(endpoint, params);
connectionListener(connection: connection)
nw_connection_set_queue(connection, queue);
nw_connection_start(connection);
}
func connectionListener(connection:nw_connection_t){
nw_connection_set_state_changed_handler(connection) { state, error in
switch state {
case nw_connection_state_waiting:
print("C-implementation state WAITING with error \(error.debugDescription)")
case nw_connection_state_preparing:
print("C-implementation state PREPARING")
case nw_connection_state_ready:
print("C-implementation state READY")
case nw_connection_state_failed:
print("C-implementation state FAILED with error \(error.debugDescription)")
case nw_connection_state_cancelled:
print("C-implementation state CANCELLED with error \(error.debugDescription)")
default:
break
}
}
}
func create_Swift_NW_Connection(){
print("Connection to ws at \(socketUrl)")
if let url = URL(string: socketUrl){
// ws - tcp; wss - tls
let parameters = NWParameters.tls
let stack = parameters.defaultProtocolStack
let ws = NWProtocolWebSocket.Options(.version13)
ws.setSubprotocols(["wapp_pkt_tunnel","binary"])
ws.autoReplyPing = true
ws.setAdditionalHeaders(headers)
stack.applicationProtocols.insert(ws, at: 0)
let connection = NWConnection(to: .url(url), using: parameters)
self.connectionStateListener(connection: connection)
connection.start(queue: queue)
}
}
func connectionStateListener(connection: NWConnection) {
connection.stateUpdateHandler = { state in
switch state {
case .setup:
break
case .waiting(let error):
print("swift-implementation state WAITING with error \(error.debugDescription)")
case .preparing:
print("swift-implementation state PREPARING")
case .ready:
print("swift-implementation state READY")
case .failed(let error):
print("swift-implementation state FAILED with error \(error.debugDescription)")
case .cancelled:
break
@unknown default:
print("swift-implementation state WAITING")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment