Post

Replies

Boosts

Views

Activity

NEPacketTunnelFlow.readPackets not always returning UDP packets
I am using the NEPacketTunnelFlow.readPackets completion handler to intercept packets as they are outgoing. A problem I am currently facing is that packets of type UDP are not always received and sometimes, not at all, and I am not really sure why. Is this an operating system caching mechanism maybe? I am not by any means a networking expert nor do I have more than basic knowledge in the field, so maybe I can get a logical explanation here. My current setup: iPhone 11 with iOS 16.2, Xcode 14.2, Minimum OS: iOS 13.0 This is my code: func readOutgoingPackets() { tunnelProvider?.packetFlow.readPackets { [weak self] packets, protocols in guard let self else { return } for (i, packet) in packets.enumerated() { self?.parsePacket(packet) } self?.readOutgoingPackets() } } func parsePacket(_ packet: Data) { do { let data = BinaryData(data: packet) let header = IPHeader(version: try data.get(0), headerLength: try data.get(1), typeOfService: try data.get(2), length: try data.get(3), id: try data.get(5), offset: try data.get(7), timeToLive: try data.get(8), proto: try data.get(9), checksum: try data.get(10), source: in_addr(s_addr: try data.get(12)), destination: in_addr(s_addr: try data.get(16))) switch header.proto { case 17: os_log("๐ŸŒ ๐Ÿ“ฆ UDP packet read") case 6: os_log("๐ŸŒ ๐Ÿ“ฆ TCP packet read") default: break } } catch { os_log("๐ŸŒ โ—๏ธ Error parsing packet") } } I am using an external library called BinarySwift to read the binary IP packet headers. Any help would be appreciated. Thanks!
1
0
666
Dec โ€™22
NEPacketTunnelProvider doesn't keep the DNS packets flowing on iOS
I have a network extension setup on my app using the NEPacketTunnelProvider Network Extension. I have set its DNS settings like so, to override all system DNS settings: let dnsSettings = NEDNSSettings(servers: ["8.8.8.8", "8.8.4.4"]) dnsSettings.matchDomains = [""] tunnelNetworkSettings.dnsSettings = dnsSettings After that, I am catching all DNS network packets (aka UDP, port 53) using tunnelProvider.packetFlow.readPackets { ... } When the packets are incoming, I am stripping them of their headers and sending their payload (DNS Query) to the DNS servers using currentUDPSession.session.writeMultipleDatagrams(packetPayloadsToSend) { ... } And receiving back the answers using the callback on NWUDPSession currentUDPSession.session.setReadHandler { ... } Then, on the received datagram payloads (DNS Answer) I am rebuilding the UDP headers (whether it's IPv4 or IPv6, I'm supporting both), and writing them back to the TUN interface like so: // Examples of the data I'm passing. I'm populating it with VALID rebuilt packets beforehand let rebuiltPackets = [Data]() let rebuiltPacketsProtocols = [NSNumber]() tunnelProvider.packetFlow.writePackets(rebuiltPackets, withProtocols: rebuiltPacketsProtocols) On paper, everything looks great and sniffing those packets using Wireshark shows that everything should work. But here's the thing, It doesn't! When trying to access any website on the iPhone I am getting: Safari could not open the page because the server stopped responding. Here's a screenshot of the Wireshark PCAP for trying to access twitter.com: IP address 10.0.0.43 is my tunnel, while 172.20.100.155 is my iPhone's local network IP address. Not sure why it shows both tunnel and OS DNS packets, but someone told me it's regular iOS behavior. Any ideas? Thanks!
5
0
862
Mar โ€™23
Scheduling UserNotifications in MessageFilter app extension is throwing an error
I have a MessageFilter app extension embedded in my iOS app and it works great filtering out junk SMS messages. I want to show a local notification whenever a message has moved to the junk folder and I'm trying to do it like so: final class MessageFilterExtension: ILMessageFilterExtension { func handle(_ queryRequest: ILMessageFilterQueryRequest, context: ILMessageFilterExtensionContext, completion: @escaping (ILMessageFilterQueryResponse) -> Void) { let offlineAction = self.offlineAction(for: queryRequest) switch offlineAction { case .allow, .junk, .promotion, .transaction: let response = ILMessageFilterQueryResponse() response.action = offlineAction scheduleLocalNotification(for: keyword) /* -> Here */ completion(response) @unknown default: break } } func scheduleLocalNotification(for keyword: Keyword) { let content = UNMutableNotificationContent() content.title = "Test" content.body = "Test2" content.categoryIdentifier = "FILTER_SMS_BLOCKED" let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false) let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { [weak self] error in guard let self else { return } if let error { logger.log(level: .os, icon: "๐Ÿ’ฅ", "Error scheduling local notification: \(error)") } } } } But I am getting the following error: ๐ŸŒ ๐Ÿ’ฅ Error scheduling local notification: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.apple.usernotifications.usernotificationservice was invalidated from this process." UserInfo={NSDebugDescription=The connection to service named com.apple.usernotifications.usernotificationservice was invalidated from this process.} I have setup the Push Notifications entitlement in the main app and in this app extension, and also requested push notifications authorization from the user on the main app. What am I missing here? Thanks!
1
0
666
Apr โ€™23