hi everybody,
When I use the following code to connect to WiFi network, an error message of "error=null" or "error='Error Domain=NEHotspotConfigurationErrorDomain Code=11 "" UserInfo={NSLocalizedDescription=}' " will occur. It has been uploaded to Feedback.
Feedback ID:
FB16819345 (WiFi-无法加入网络)
NEHotspotConfiguration *hotspotConfig = [[NEHotspotConfiguration alloc] initWithSSID:ssid passphrase:psk isWEP:NO];
[[NEHotspotConfigurationManager sharedManager] applyConfiguration:hotspotConfig completionHandler:^(NSError * _Nullable error) {
}];
Networking
RSS for tagExplore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hello Everyone,
I’m working on a project that involves multicast communication between processes running on different devices within the same network. For all my Apple devices (macOS, iOS, etc.), I am using NWConnectionGroup, which listens on a multicast address "XX.XX.XX.XX" and a specific multicast port.
The issue occurs when a requestor (such as a non-Apple process) sends a multicast request, and the server, which is a process running on an Apple device using NWConnectionGroup (the responder), attempts to reply. The problem is that the response is sent from a different ephemeral port rather than the port on which the multicast request was received.
If the client is behind a firewall that blocks unsolicited traffic, the firewall only allows incoming packets on the same multicast port used for the initial request. Since the multicast response is sent from a different ephemeral port, the firewall blocks this response, preventing the requestor from receiving it.
Questions:
Is there a recommended approach within the NWConnectionGroup or Network.framework to ensure that responses to multicast requests are sent from the same port used for the request?
Are there any best practices for handling multicast responses in scenarios where the requestor is behind a restrictive firewall?
Any insights or suggestions on how to account for this behavior and ensure reliable multicast communication in such environments would be greatly appreciated.
Thanks,
Harshal
Hi,
I have a problem with my OpenVPN connection on my app with iOS 14.4.
I perform my VPN configuration from an oven file, with a NETunnelProviderManager protocol, but when I perform the startVPNTunnel, it starts connecting and immediately disconnects. The error I see in the logs is the following:
NESMVPNSession[Primary Tunnel:OpenVPN Client: -----(null)]: status changed to disconnected, last stop reason Plugin was disabled
This happens to me when running my app on a physical iPad.
Regards
import NetworkExtension
import OpenVPNAdapter
class VPNConnection {
var connectionStatus = "Disconnected"
var myProviderManager: NETunnelProviderManager?
func manageConnectionChanges( manager:NETunnelProviderManager ) - String {
NSLog("Waiting for changes");
var status = "Disconnected"
NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: manager.connection, queue: OperationQueue.main, using: { notification in
let baseText = "VPN Status is "
switch manager.connection.status {
case .connected:
status = "Connected"
case .connecting:
status = "Connecting"
case .disconnected:
status = "Disconnected"
case .disconnecting:
status = "Disconnecting"
case .invalid:
status = "Invalid"
case .reasserting:
status = "Reasserting"
default:
status = "Connected"
}
self.connectionStatus = status
NSLog(baseText+status)
});
return status
}
func createProtocolConfiguration() - NETunnelProviderProtocol {
guard
let configurationFileURL = Bundle.main.url(forResource: "app-vpn", withExtension: "ovpn"),
let configurationFileContent = try? Data(contentsOf: configurationFileURL)
else {
fatalError()
}
let tunnelProtocol = NETunnelProviderProtocol()
tunnelProtocol.serverAddress = ""
tunnelProtocol.providerBundleIdentifier = "com.app.ios"
tunnelProtocol.providerConfiguration = ["ovpn": String(data: configurationFileContent, encoding: .utf8)! as Any]
tunnelProtocol.disconnectOnSleep = false
return tunnelProtocol
}
func startConnection(completion:@escaping () - Void){
self.myProviderManager?.loadFromPreferences(completionHandler: { (error) in
guard error == nil else {
// Handle an occurred error
return
}
do {
try self.myProviderManager?.connection.startVPNTunnel()
print("Tunnel started")
} catch {
fatalError()
}
})
}
func loadProviderManager(completion:@escaping () - Void) {
NETunnelProviderManager.loadAllFromPreferences { (managers, error) in
guard error == nil else {
fatalError()
return
}
self.myProviderManager = managers?.first ?? NETunnelProviderManager()
self.manageConnectionChanges(manager: self.myProviderManager!)
self.myProviderManager?.loadFromPreferences(completionHandler: { (error) in
guard error == nil else {
fatalError()
return
}
let tunnelProtocol = self.createProtocolConfiguration()
self.myProviderManager?.protocolConfiguration = tunnelProtocol
self.myProviderManager?.localizedDescription = "OpenVPN Client Ubic"
self.myProviderManager?.isEnabled = true
self.myProviderManager?.isOnDemandEnabled = false
self.myProviderManager?.saveToPreferences(completionHandler: { (error) in
if error != nil {
// Handle an occurred error
fatalError()
}
self.startConnection {
print("VPN loaded")
}
})
})
}
}
}
There is a problem with the Apple local network setting api, iOS18 system, you turn off the local network permissions of the APP, uninstall the APP, and then re-install, the local network permissions even if opened, there is no effect, only restart the phone is useful
I'm trying to invoke a 3rd party command line tool from a launch agent to connect to a server on my LAN. It seems impossible.
I have a little shell script that does what I need, and it works fine invoked in Terminal.app. The first time I run it that way I get permission prompts and I agree to them all. Subsequent invocations work.
Now I put a launch agent in ~/Library/Launch Agents. It does nothing more than invoke my shell script at some specific time daily. launchd launches it, but it fails to access the LAN, with a 'no route to host' error message.
The command line tool I'm trying to use is not a macOS-provided one, but one from MacPorts/HomeBrew (I tried both). It doesn't even matter which tool I'm using, I tried a very simple case of just using nc/netcat. If I use the macOS-provided nc, then I can access my LAN. If I install nc from MacPorts /HomeBrew, that nc cannot access my LAN.
This I've reproed on a literally brand new Mac, then updated to newest Sequoia (15.3.2), then done all I've described above.
I've ruled out DNS by working with raw IP addresses.
I've disabled gatekeeper with sudo spctl --master-disable.
I've tried using cron instead of launch agents, same results.
I've tried codesigning with codesign -dvvv /opt/homebrew/bin/nc, no help.
I've read TN3179 Understanding local network privacy.
In summary:
Terminal.app -> script -> macOS/brew nc -> internet/LAN = works
launchagent -> script -> macOS nc -> internet = works
launchagent -> script -> macOS nc -> LAN = works
launchagent -> script -> brew nc -> internet = works
launchagent -> script -> brew nc -> LAN = fails
How can I make that last case work?
Topic:
App & System Services
SubTopic:
Networking
When i try to set the value ‘false’ for ‘usesClassicLoadingMode’ it is getting crashed.
The crash logs has been shared below
Ex:
let config = URLSessionConfiguration.default
if #available(iOS 18.4, *) {
config.usesClassicLoadingMode = false
}
Error log :
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFBoolean objectForKeyedSubscript:]: unrecognized selector sent to instance 0x1f655c390'
*** First throw call stack:
(0x188ae52ec 0x185f69a7c 0x188b4f67c 0x1889fcb84 0x1889fc4f0 0x191393bc8 0x1889ec8a0 0x1889ec6e4 0x191393ad0 0x191344dac 0x191344b58 0x107cfa064 0x107ce36d0 0x191343fcc 0x1891b3b18 0x1892dae58 0x189235c60 0x18921e270 0x18921d77c 0x18921a8ac 0x107ce0584 0x107cfa064 0x107ce891c 0x107ce95d8 0x107ceabcc 0x107cf5894 0x107cf4eb0 0x212f51660 0x212f4e9f8)
terminating due to uncaught exception of type NSException
Can you please provider the resolution steps
Hi,
We are developing an app using PacketTunnelProvider from Network Extension framework. It is packaged as a system extension.
We are trying to implement an "always-on" functionality, but cannot manage to start the extension before user login, with or without on-demand enabled.
However we see in other posts (1, 2) that a network extension packaged as sysex should automatically start before user login.
Are we missing something? Is it a limitation of PacketTunnelProvider?
Thanks
Background
Android phones supporting Wi-Fi Aware 4.0 should be able to connect with iPhones (iOS 26). For testing, we selected two Samsung S25 devices, which support Wi-Fi Aware 4.0.
Issues we are facing
Android as Publisher, iOS as Subscriber.iOS cannot discover the service. Log shows: Discovery: Dropping event, 02:14:60:76:a6:0f missing DCEA attribute.
iOS as Publisher, Android as Subscriber,Android can discover the service.However, the PIN code is not displayed on iOS.
From the packet capture, the publish packet does not contain the DCEA field. However, Android-to-Android devices can still pair normally, and the subsequent PASN packets include the DCEA field. It seems that the Wi-Fi Alliance only requires the DCEA to be present in the PASN packets.
iOS cannot discover Android devices or complete pairing — is this caused by the DCEA field, or by other reasons?
We have a Java application built for macOS. On the first launch, the application prompts the user to allow local network access. We've correctly added the NSLocalNetworkUsageDescription key to the Info.plist, and the provided description appears in the system prompt.
After the user grants permission, the application can successfully connect to a local server using its hostname. However, the issue arises after the system is rebooted. When the application is launched again, macOS does not prompt for local network access a second time—which is expected, as the permission was already granted.
Despite this, the application is unable to connect to the local server. It appears the previously granted permission is being ignored after a reboot. A temporary workaround is to manually toggle the Local Network permission off and back on via System Settings > Privacy & Security, which restores connectivity—until the next reboot.
This behavior is highly disruptive, both for us and for a significant number of our users. We can reproduce this on multiple systems...
The issues started from macOS Sequoia 15.0
By opening the application bundle using "Show Package Contents," we can launch the application via "JavaAppLauncher" without any issues. Once started, the application is able to connect to our server over the local network. This seems to bypass the granted permissions? "JavaAppLauncher" is also been used in our Info.plist file
I am looking for inputs to better understand MacOS entitlements. I ask this in context of OpenJDK project, which builds and ships the JDK. The build process makes uses of make tool and thus doesn't involving building through the XCode product. The JDK itself is a Java language platform providing applications a set of standard APIs. The implementation of these standard APIs internally involves calling platform specific native library functions. In this discussion, I would like to focus on the networking functions that the implementation uses. Almost all of these networking functions and syscalls that the internal implementation uses are BSD socket related. Imagine calls to socket(), connect(), getsockopt(), setsockopt(), getaddrinfo(), sendto(), listen(), accept() and several such.
The JDK that's built through make is then packaged and made available for installation. The packaging itself varies, but for this discussion, I'll focus on the .tar.gz archived packaging. Within this archive there are several executables (for example: java, javac and others) and several libraries. My understanding, based on what I have read of MacOS entitlements is that, the entitlements are set on the executable and any libraries that would be loaded and used by that executable will be evaluated against the entitlements of the executable (please correct me if I misunderstand).
Reading through the list of entitlements noted here https://developer.apple.com/documentation/bundleresources/entitlements, the relevant entitlements that an executable (like "java") which internally invokes BSD socket related syscalls and library functions, appear to be:
com.apple.security.network.client - https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.security.network.client
com.apple.security.network.server - https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.security.network.server
com.apple.developer.networking.multicast - https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.networking.multicast
Is my understanding correct that these are the relevant ones for MacOS? Are there any more entitlements that are of interest? Would it then mean that the executables (java for example) would have to enroll for these entitlements to be allowed to invoke those functions at runtime?
Reading through https://developer.apple.com/documentation/bundleresources/entitlements, I believe that even when an executable is configured with these entitlements, when the application is running if that executable makes use of any operations for which it has an entitlement, the user is still prompted (through a UI notification) whether or not to allow the operation. Did I understand it right?
The part that isn't clear from that documentation is, if the executable hasn't been configured with a relevant entitlement, what happens when the executable invokes on such operation. Will the user see a UI notification asking permission to allow the operation (just like if an entitlement was configured)? Or does that operation just fail in some behind the scenes way?
Coming back to the networking specific entitlements, I found a couple of places in the MacOS documentation where it is claimed that the com.apple.developer.networking.multicast entitlement is only applicable on iOS. In fact, the entitlement definition page for it https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.networking.multicast says:
"Your app must have this entitlement to send or receive IP multicast or broadcast on iOS. It also allows your app to browse and advertise arbitrary Bonjour service types."
Yet, that same page, a few lines above, shows "macOS 10.0+". So, is com.apple.developer.networking.multicast entitlement necessary for an executable running on MacOS which deals with multicasting using BSD sockets?
As a more general comment about the documentation, I see that the main entitlements page here https://developer.apple.com/documentation/bundleresources/entitlements categorizes some of these entitlements under specific categories, for example, notice how some entitlements are categorized under "App Clips". I think it would be useful if there was a category for "BSD sockets" and under that it would list all relevant entitlements that are applicable, even if it means repeating the entitlement names across different categories. I think that will make it easier to identify the relevant entitlements.
Finally, more as a long term question, how does one watch or keep track of these required entitlements for these operations. What I mean is, is it expected that application developers keep visiting the macos documentation, like these pages, to know that a new entitlement is now required in a new macos (update) release? Or are there other ways to keep track of it? For example, if a newer macos requires a new entitlement, then when (an already built) executable is run on that version of macos, perhaps generate a notification or some kind of explicit error which makes it clear what entitlement is missing? I have read through https://developer.apple.com/documentation/bundleresources/diagnosing-issues-with-entitlements but that page focuses on identifying such issues when a executable is being built and doesn't explain the case where an executable has already been shipped with X entitlements and a new Y entitlement is now required to run on a newer version of macos.
I've been wondering what is the memory limit for network extensions. Specifically, I'm using the NEPacketTunnelProvider extension point.The various posts on this forum mention 5 MB and 6 MB for 32-bit and 64-bit respectively. However I find that (at least on iOS 10) the upper limit seems to be 15 MB. Is this the new memory limit for extensions?
I can develop a PacketTunnelProvider on Mac with xcode.
I work with my self codesign.
But when I sign it with Developer ID after read https://developer.apple.com/forums/thread/737894 , it still fail when I turn on the vpn .
I am writing an app using Microsoft's MAUI platform. I am posting this here because that team wants me to make an xcode project to help determine an issue I am having.
My MAUI app sends a broadcast packet on a UDP socket using address 255.255.255.255. This worked fine in iOS version 17.x. After upgrading my phone to iOS 18.x it stopped working.
The error I get is "no route to host".
The exact same code works fine on MacOS. It does not work on iPadOs 18.
My question here is 3 fold:
Did something specific change between iOS 17 and 18 that would cause a 'no route to host' error when sending a UDP broadcast packet?
Can someone provide sample code to show me how to do this type of broadcast using Swift in Xcode for iOS?
I read an article that said my app would need the com.apple.developer.networking.multicast entitlement in order to use boradcast functionality. This was introduced in iOS 14. Why did my app work fine in iOS 17 then? Is this what changed? Did this requirement use to be optional and is now required? I did get this entitlement from Apple and applied it to my provisioning profile and my app gave the same "no route to host" error. Why?
When a VPN is active, RCS messaging does not work on iOS 18.
I work on an iOS VPN app, and we were very appreciative of the excludeCellularServices network flag that was released during the iOS 16 cycle. It's a great solution to ensure the VPN doesn't interfere with cellular network features from the cellular provider.
Separately - As a user, I'm excited that iOS 18 includes RCS messaging.
Unfortunately, RCS messaging is not working when our VPN is active (when checking on the iOS 18 release candidate). My guess is that RCS is not excluded from the VPN tunnel, even when excludeCellularServices is true. It seems like RCS should be added in this situation, as it is a cell provider service.
Can RCS be added as a service that is excluded from the VPN tunnel when excludeCellularServices is true? (I've also sent this via feedback assistant, as 15094270.)
For a long time our app had this creation of a URLRequest:
var urlRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeout)
But since iOS 26 was released we started to get crashes in this call. It is created on a background thread.
Thread 10 Crashed:
0 libsystem_malloc.dylib 0x00000001920e309c _xzm_xzone_malloc_freelist_outlined + 864 (xzone_malloc.c:1869)
1 libswiftCore.dylib 0x0000000184030360 swift::swift_slowAllocTyped(unsigned long, unsigned long, unsigned long long) + 56 (Heap.cpp:110)
2 libswiftCore.dylib 0x0000000184030754 swift_allocObject + 136 (HeapObject.cpp:245)
3 Foundation 0x00000001845dab9c specialized _ArrayBuffer._consumeAndCreateNew(bufferIsUnique:minimumCapacity:growForAppend:) + 120
4 Foundation 0x00000001845daa58 specialized static _SwiftURL._makeCFURL(from:baseURL:) + 2288 (URL_Swift.swift:1192)
5 Foundation 0x00000001845da118 closure #1 in _SwiftURL._nsurl.getter + 112 (URL_Swift.swift:64)
6 Foundation 0x00000001845da160 partial apply for closure #1 in _SwiftURL._nsurl.getter + 20 (<compiler-generated>:0)
7 Foundation 0x00000001845da0a0 closure #1 in _SwiftURL._nsurl.getterpartial apply + 16
8 Foundation 0x00000001845d9a6c protocol witness for _URLProtocol.bridgeToNSURL() in conformance _SwiftURL + 196 (<compiler-generated>:974)
9 Foundation 0x000000018470f31c URLRequest.init(url:cachePolicy:timeoutInterval:) + 92 (URLRequest.swift:44)# Live For Studio
Any idea if this crash is caused by our code or if it is a known problem in iOS 26?
I have attached one of the crash reports from Xcode:
2025-10-08_10-13-45.1128_+0200-8acf1536892bf0576f963e1534419cd29e6e10b8.crash
I'm trying to detect the state of Local Network privacy on macOS Sequoia via NWBrowser, as recommended in https://developer.apple.com/documentation/technotes/tn3179-understanding-local-network-privacy
Regardless of the state of Local Network privacy - undetermined, allowed or denied, NWBrowser receives an update indicating that its in the ready state.
Scanning does not seem to trigger the Local Network privacy alert for me - I have to use the other recommended method to trigger the prompt. Enabling or disabling Local Network privacy does not seem to send any updates for NWBrowser.
https://developer.apple.com/forums/thread/666431 seems related, and implies that they did receive further updates to NWBrowser.
Filed as FB16077972
Hello,
Title states it basically. I have a java program (launched via shell script) running as a service using launchd which is running as a user (not root) and it does not request Local Network permissions ever.
I feel like i'm missing something here. I combed through all of the Local Network FAQs and don't really see this use case addressed.
I do see that there is an open ticket for an API to trigger the request, but no update on that and the ticket is not visible publicly.
Is there is a way to accomplish this for java or other programs running via launchd with a user other than root? something like an entitlement or an API to seed the permission of Local Network when installing the service via launchctl etc?
iPhone 12 pro with iOS 26.0 (23A5276f)
App: https://developer.apple.com/documentation/wifiaware/building-peer-to-peer-apps
We aim to use Wi-Fi Aware to establish file transfer between Android and Apple devices.
Apple will act as the Publisher, and Android will act as the Subscriber.
According to the pairing process outlined in the Wi-Fi Aware protocol (Figure 49 in the Wi-Fi Aware 4.0 specification), the three PASN Authentication frames have been successfully exchanged. Subsequently, Android sends the encrypted Follow-up PMF to Apple, but the Apple log shows: Failed to parse event. Please refer to the attached complete log.
We request Apple to provide a solution.
apple Log-20250808a.txt
Hi folks, I'm building an iOS companion app to a local hosted server app (hosted on 0.0.0.0). The MacOS app locally connects to this server hosted, and I took the approach of advertising the server using a Daemon and BonjourwithTXT(for port) and then net service to resolve a local name. Unfortunately if there's not enough time given after the iPhone/iPad is plugged in (usb or ethernet), the app will cycle through attempts and disconnects many times before connecting and I'm trying to find a way to only connect when a viable en interface is available.
I've run into a weird thing in which the en interface only becomes seen on the NWMonitor after multiple connection attempts have been made and failed. If I screen for en before connecting it simply never appears. Is there any way to handle this such that my app can intelligently wait for an en connection before trying to connect? Attaching my code although I have tried a few other setups but none has been perfect.
func startMonitoringAndBrowse() {
DebugLogger.shared.append("Starting Bonjour + Ethernet monitoring")
if !browserStarted {
let params = NWParameters.tcp
params.includePeerToPeer = false
params.requiredInterfaceType = .wiredEthernet
browser = NWBrowser(for: .bonjourWithTXTRecord(type: "_mytcpapp._tcp", domain: nil), using: params)
browser?.stateUpdateHandler = { state in
if case .ready = state {
DebugLogger.shared.append("Bonjour browser ready.")
}
}
browser?.browseResultsChangedHandler = { results, _ in
self.handleBrowseResults(results)
}
browser?.start(queue: .main)
browserStarted = true
}
// Start monitoring for wired ethernet
monitor = NWPathMonitor()
monitor?.pathUpdateHandler = { path in
let hasEthernet = path.availableInterfaces.contains { $0.type == .wiredEthernet }
let ethernetInUse = path.usesInterfaceType(.wiredEthernet)
DebugLogger.shared.append("""
NWPathMonitor:
- Status: \(path.status)
- Interfaces: \(path.availableInterfaces.map { "\($0.name)[\($0.type)]" }.joined(separator: ", "))
- Wired Ethernet: \(hasEthernet), In Use: \(ethernetInUse)
""")
self.tryToConnectIfReady()
self.stopMonitoring()
}
monitor?.start(queue: monitorQueue)
}
// MARK: - Internal Logic
private func handleBrowseResults(_ results: Set<NWBrowser.Result>) {
guard !self.isResolving, !self.hasResolvedService else { return }
for result in results {
guard case let .bonjour(txtRecord) = result.metadata,
let portString = txtRecord["actual_port"],
let actualPort = Int(portString),
case let .service(name, type, domain, _) = result.endpoint else {
continue
}
DebugLogger.shared.append("Bonjour result — port: \(actualPort)")
self.resolvedPort = actualPort
self.isResolving = true
self.resolveWithNetService(name: name, type: type, domain: domain)
break
}
}
private func resolveWithNetService(name: String, type: String, domain: String) {
let netService = NetService(domain: domain, type: type, name: name)
netService.delegate = self
netService.includesPeerToPeer = false
netService.resolve(withTimeout: 5.0)
resolvingNetService = netService
DebugLogger.shared.append("Resolving NetService: \(name).\(type)\(domain)")
}
private func tryToConnectIfReady() {
guard hasResolvedService,
let host = resolvedHost, let port = resolvedPort else { return }
DebugLogger.shared.append("Attempting to connect: \(host):\(port)")
discoveredIP = host
discoveredPort = port
connectionPublisher.send(.connecting(ip: host, port: port))
stopBrowsing()
socketManager.connectToServer(ip: host, port: port)
hasResolvedService = false
}
}
// MARK: - NetServiceDelegate
extension BonjourManager: NetServiceDelegate {
func netServiceDidResolveAddress(_ sender: NetService) {
guard let hostname = sender.hostName else {
DebugLogger.shared.append("Resolved service with no hostname")
return
}
DebugLogger.shared.append("Resolved NetService hostname: \(hostname)")
resolvedHost = hostname
isResolving = false
hasResolvedService = true
tryToConnectIfReady()
}
func netService(_ sender: NetService, didNotResolve errorDict: [String : NSNumber]) {
DebugLogger.shared.append("NetService failed to resolve: \(errorDict)")
}
}
I implemented a Network Extension in the macOS, use NETransparentProxyProvider. After installing and enabling it, I implemented a UDP client to test its. I found that the UDP client failed to send the data successfully (via sendto, and it returned a success), and when using Wireshark to capture the network data packet, I still couldn't see this UDP data packet.
The code for Network Extension is like this:
@interface MyTransparentProxyProvider : NETransparentProxyProvider
@end
@implementation MyTransparentProxyProvider
- (void)startProxyWithOptions:(NSDictionary *)options completionHandler:(void (^)(NSError *))completionHandler
{
NETransparentProxyNetworkSettings *objSettings = [[NETransparentProxyNetworkSettings alloc] initWithTunnelRemoteAddress:@"127.0.0.1"];
// included rules
NENetworkRule *objIncludedNetworkRule = [[NENetworkRule alloc] initWithRemoteNetwork:nil
remotePrefix:0
localNetwork:nil
localPrefix:0
protocol:NENetworkRuleProtocolAny
direction:NETrafficDirectionOutbound];
NSMutableArray<NENetworkRule *> *arrIncludedNetworkRules = [NSMutableArray array];
[arrIncludedNetworkRules addObject:objIncludedNetworkRule];
objSettings.includedNetworkRules = arrIncludedNetworkRules;
// apply
[self setTunnelNetworkSettings:objSettings completionHandler:
^(NSError * _Nullable error)
{
// TODO
}
];
if (completionHandler != nil)
completionHandler(nil);
}
- (BOOL)handleNewFlow:(NEAppProxyFlow *)flow
{
if (flow == nil)
return NO;
char szProcPath[PROC_PIDPATHINFO_MAXSIZE] = {0};
audit_token_t *lpAuditToken = (audit_token_t*)flow.metaData.sourceAppAuditToken.bytes;
if (lpAuditToken != NULL)
{
proc_pidpath_audittoken(lpAuditToken, szProcPath, sizeof(szProcPath));
}
if ([flow isKindOfClass:[NEAppProxyTCPFlow class]])
{
NWHostEndpoint *objRemoteEndpoint = (NWHostEndpoint *)((NEAppProxyTCPFlow *)flow).remoteEndpoint;
LOG("-MyTransparentProxyProvider handleNewFlow:] TCP flow! Process: (%d)%s, %s Remote: %s:%s, %s",
lpAuditToken != NULL ? audit_token_to_pid(*lpAuditToken) : -1,
flow.metaData.sourceAppSigningIdentifier != nil ? [flow.metaData.sourceAppSigningIdentifier UTF8String] : "",
szProcPath,
objRemoteEndpoint != nil ? (objRemoteEndpoint.hostname != nil ? [objRemoteEndpoint.hostname UTF8String] : "") : "",
objRemoteEndpoint != nil ? (objRemoteEndpoint.port != nil ? [objRemoteEndpoint.port UTF8String] : "") : "",
((NEAppProxyTCPFlow *)flow).remoteHostname != nil ? [((NEAppProxyTCPFlow *)flow).remoteHostname UTF8String] : ""
);
}
else if ([flow isKindOfClass:[NEAppProxyUDPFlow class]])
{
NSString *strLocalEndpoint = [NSString stringWithFormat:@"%@", ((NEAppProxyUDPFlow *)flow).localEndpoint];
LOG("-[MyTransparentProxyProvider handleNewFlow:] UDP flow! Process: (%d)%s, %s LocalEndpoint: %s",
lpAuditToken != NULL ? audit_token_to_pid(*lpAuditToken) : -1,
flow.metaData.sourceAppSigningIdentifier != nil ? [flow.metaData.sourceAppSigningIdentifier UTF8String] : "",
szProcPath,
strLocalEndpoint != nil ? [strLocalEndpoint UTF8String] : ""
);
}
else
{
LOG("-[MyTransparentProxyProvider handleNewFlow:] Unknown flow! Process: (%d)%s, %s",
lpAuditToken != NULL ? audit_token_to_pid(*lpAuditToken) : -1,
flow.metaData.sourceAppSigningIdentifier != nil ? [flow.metaData.sourceAppSigningIdentifier UTF8String] : "",
szProcPath
);
}
return NO;
}
@end
The following methods can all enable UDP data packets to be successfully sent to the UDP server:
1.In -[MyTransparentProxyProvider startProxyWithOptions:completionHandler:], add the exclusion rule "The IP and port of the UDP server, the protocol is UDP";
2.In -[MyTransparentProxyProvider startProxyWithOptions:completionHandler:], add the exclusion rule "All IPs and ports, protocol is UDP";
3.In -[MyTransparentProxyProvider handleNewFlow:] or -[MyTransparentProxyProvider handleNewUDPFlow:initialRemoteEndpoint:], process the UDP Flow and return YES.
Did I do anything wrong?