I'm having a Local
VPN
app that using "NETunnelProvider
/ NetworkExtentsion
", In my solution, I created a split tunnel on the device itself to track the DNS request, using NEKit
I was able to peek inside the packets and filter the ongoing request based on the destination address (let's call ita UDP listener for DNS requests).
This solution was working fine on iOS 13.7 and less, recently apple release iOS 14
, and my solution stop working, VPN
connection still established but the user can't access any webSite, I debugged the code and found out the networkExtision
does not receive any packets
from user activity only.
I'm using the CocoaAsyncSocket
library.
func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
let host = GCDAsyncUdpSocket.host(fromAddress: address)
guard let message = DNSMessage(payload: data) else {
return
}
guard let session = pendingSession.removeValue(forKey: message.transactionID) else {
return
}
session.realResponseMessage = message
session.realIP = message.resolvedIPv4Address
let domain = session.requestMessage.queries[0].name
let udpParser = UDPProtocolParser()
udpParser.sourcePort = Port(port: dnsServerPort)
udpParser.destinationPort = (session.requestIPPacket!.protocolParser as! UDPProtocolParser).sourcePort
udpParser.payload = session.realResponseMessage!.payload
let ipPacket = IPPacket()
ipPacket.sourceAddress = IPAddress(fromString: dnsServerAddress)
ipPacket.destinationAddress = session.requestIPPacket!.sourceAddress
ipPacket.protocolParser = udpParser
ipPacket.transportProtocol = .udp
ipPacket.buildPacket()
packetFlow.writePackets([ipPacket.packetData], withProtocols: [NSNumber(value: AF_INET as Int32)])
}
let dummyTunnelAddress = "127.0.0.1"
let dnsServerAddress = "8.8.4.4"
let dnsServerPort: UInt16 = 53
// Tunnel confg.
let tunnelAddress = "192.168.0.1"
let tunnelSubnetMask = "255.255.255.0"
Regarding triggering"Local Network permissions" which is not the issue here (I don't think my solution need to have this permission), Based on the apple document some apps need to request local network permissions, I added the permission to the info.plist
but local network permissions are not triggered.
========================== Update #1 ============================
I found out that I was able to capture the packets and do my own things then write packets back to the packetFlow packetFlow.writePackets
, But on iOS 14 browsers not loading the websites and keep loading until show time out.