Networking

RSS for tag

Explore the networking protocols and technologies used by the device to connect to Wi-Fi networks, Bluetooth devices, and cellular data services.

Networking Documentation

Post

Replies

Boosts

Views

Activity

T-mobile SIM Card 5G UC Cellular data limits udp data sending
The device releases the AP hotspot, and the iPhone connects to the hotspot to send upd data communication. Use the T-mobile SIM card 5G to enable the cellular network to send upd data, but the device cannot receive UPD data. It takes about 1 minute to receive after repeated sending; It is normal for the same program to use China Mobile 5G/4G cellular data or turn off the cellular network; How to solve the problem that T-mobile SIM card 5G UC cellular data limit udp data sending?
0
0
542
Aug ’23
ifconfig ether / assign MAC address to Ethernet NIC
There seems to be a lot of inconsistency when it comes to macOS versions supporting "ifconfig ether" and any tools (including commercial software) using that functionality. MAC-spoofing in general is a incredibly useful diagnostic method for a very broad spectrum of situations. Here are some observations, I'm trying to collect future issues in this thread. Previous issues were a mix of WiFi or Ethernet NICS and not very focused. Have a look at this blog post, it's really helpful: https://khronokernel.github.io/macos/2021/11/22/PCIE-ETHERNET.html Currently in macOS Ventura, there are 3 PCIe Ethernet Vendors natively supported. All drivers in macOS natively support both Intel and Apple Silicon machines: Vendor Driver Supported Architectures Hardware Intel AppleIntelI210Ethernet.kext x86_64, arm64e i210, i225 Broadcom AppleBCM5701Ethernet.kext x86_64, arm64e 5764M, 57761, 57762, 57765, 57766 Aquantia AppleEthernetAquantiaAqtion.kext x86_64, arm64e AQC107, AQC113 With the above 5 drivers, currently Apple only uses 2 of them in their products: Aquantia is used on all Macs with 10Gbe ie. 2017 iMac Pro, 2019 Mac Pro, 2018 Mac mini Broadcom is used on all 2011+ Macs with 1Gbe ie. 2011-2020 iMacs, 2010-2020 Mac minis, 2013 Mac Pro Interestingly this issue seems to heavily depend on the driver that is used. Ideally you'll want to use a NIC that is connected via PCI and is also used in some Apple product - that will make it more likely that Apple will maintain the drivers throughout macOS versions. I'm only focusing on PCI/TB adapters in this issue. However, I have not actually managed to get MAC spoofing working with anything other than the Apple TB2 - GbE adapter: Tested with a MacBook Pro 14" 2023 (M2Pro) on macOS Ventura 13.4, 13.5 and macOS Sonoma Developer Beta 1 with the command sudo ifconfig ether enXX xx:xx:xx[...]: Apple Thunderbolt to GbE Adapter (uses AppleBCM5701Ethernet iirc): works and accepts new MAC address OWC TB3 to 10GbE Adapter, with AQC-107 Chipset (uses AppleEthernetAquantiaAqtion): fails silently (accepts command) and does not change the MAC address (most USB adapters will fail with some error code, which is as expected as they use a more generic driver class) In another Forum I read that someone also didn't get a Mac Mini (M2) with 10GbE to support ifconfig ether. That model also uses an AQC-107, so the AppleEthernetAquantiaAqtion driver - supporting the argument that only the Broadcom driver supports MAC spoofing in the latest OS releases. If anyone gets a different network adapter to work, please comment :) This does not seem like an issue any 3rd-party developer can solve (apart from re-writing the Aquantia driver from scratch), and it seems like it is not a HW limitation - using Windows/Linux I can easily spoof the MAC of my tested devices. Apple should ideally acknowledge that this is a known limitation, whether by accident or by conscious decision ("security concerns" as hinted in an Apple Developer Forum). I'm leaning towards this being a bug from porting drivers & not putting in the time to support all NIC features, and hope that a future release will solve it. In the meantime - if you need to use MAC spoofing the TB2 adapter is a relatively safe bet (albeit ugly due to dongle chaining etc.)
0
0
670
Aug ’23
Getting error -108 while setting eap username and password through CoreWLAN
Hello Experts, I am trying to connect Mac Pro through command line utility using Mac OS API. I am successfully able to connect client though when network goes down and comes up again, on GUI dialog is again asking for username and password even though it was connected earlier. So I tried to use helper method CWKeychainSetWiFiEAPUsernameAndPassword but unfortunately it is giving error code -108 Error: 0xFFFFFF94 -108 Failed to allocate memory. My little code snippet looks as below, BOOL result = [a associateToEnterpriseNetwork:network.anyObject identity:nil username:onexuser password:onexpass error:&connecterr]; NSLog(@"Association Result: %d", result); NSLog(@"Error: %@", connecterr); NSData *nssid = [network.anyObject ssidData]; CWKeychainDomain d = kCWKeychainDomainUser; OSStatus er = CWKeychainSetWiFiEAPUsernameAndPassword(kCWKeychainDomainUser, nssid, onexuser, onexpass); NSLog(@"Status: %d", er); Now I am not sure what could be the cause of error? Any pointers would be appreciated.
4
0
1k
Aug ’23
DNSProxyProvider - High CPU usage
Hello everyone, I am currently experiencing an issue with a network extension that we've developed, which seems to be causing problems on a select number of machines. Problem Overview: Our extension is designed to analyze all DNS traffic and block access to suspicious domains. Most of the time, this works seamlessly. However, I've observed repeated log messages on a few machines that hint at some network-related problems. Accompanying these logs, I've also noticed occasional spikes in CPU usage. Logs: Below are the logs captured from the Console that are repeated over and over again: [C659 IPv6#3738d855.53 udp, attribution: developer] restart [C659 IPv6#3738d855.53 waiting parent-flow (unsatisfied (No network route), dns)] event: path:restart @14383.841s, uuid: C7F27BD5-E86F-4076-A03E-1BD6A9C4C405 [C659 IPv6#3738d855.53 waiting parent-flow (unsatisfied (No network route), dns)] event: path:unsatisfied @14383.841s, uuid: C7F27BD5-E86F-4076-A03E-1BD6A9C4C405 [C659 IPv6#3738d855.53 in_progress parent-flow (unsatisfied (No network route), dns)] event: flow:start_child @14383.841s nw_connection_report_state_with_handler_on_nw_queue [C659] reporting state preparing [C659.157 IPv6#3738d855.53 initial path ((null))] event: path:start @14383.841s [C659.157 IPv6#3738d855.53 waiting path (unsatisfied (No network route), dns)] event: path:unsatisfied @14383.842s, uuid: C7F27BD5-E86F-4076-A03E-1BD6A9C4C405 [C659.157 IPv6#3738d855.53 failed path (unsatisfied (No network route), dns)] event: null:null @14383.842s [C659 IPv6#3738d855.53 waiting parent-flow (unsatisfied (No network route), dns)] event: flow:child_failed @14383.842s nw_connection_report_state_with_handler_on_nw_queue [C659] reporting state waiting [C659 IPv6#3738d855.53 waiting parent-flow (unsatisfied (No network route), dns)] event: path:restart @14383.842s, uuid: C7F27BD5-E86F-4076-A03E-1BD6A9C4C405 [C659 IPv6#3738d855.53 udp, attribution: developer] restart Details & Observations: The high CPU usage appears randomly, and I haven't discerned any specific pattern. When CPU usage increase, the only way to go back to 0-0.3, is to restart the computer or restart the extension. A considerable amount of the above logs are generated over and over again, in the console, in a very short amount of time (in 15 seconds there are about ok 500k logs) Of the 600 machines using this extension, only 4 are exhibiting this issue. I've thoroughly checked the network configuration of the problematic machines, and I haven't found any disparities when compared to the ones working seamlessly. In cases where our extension can't determine if access to a specific domain should be blocked, we forward a request to our backend for verification. The code snippet used for this is: URLRequest(url: requestUrl) ... urlSession.dataTask(with: request)...resume(). Given that this method works perfectly on other machines, I'm inclined to believe this isn't the root issue. I'm reaching out to understand if anyone has encountered a similar problem or if there are any insights into what might be causing this. Any guidance or suggestions would be greatly appreciated. Also would be helpful if anyone can help me to break down the anatomy of the logs. Here is the main classes that handle the entire UDP flow, maybe you can spot any issue in the code. If I have to guess, a single flow fails, and then automatically tries to resolve over and over again, but I don't know how to add a counter for the number of retries. Thank you in advance for your assistance! PS: A ScreenShot from the console to see the times between logs: https://ibb.co/pvjVD89
4
0
400
Aug ’23
NEHotspotConfigurationManager.apply() is not triggering.
Whenever I turn off Wi-Fi in the Setting.app, NEHotspotConfigurationManager.apply() doesn't get triggered. If I restart my app, the apply function responds with Error Domain=NEHotspotConfigurationErrorDomain Code=8 "internal error." UserInfo={NSLocalizedDescription=internal error.} After restarting the device, this issue occurs again. I observed this issue on iOS 16.6, and I'm not sure if it's the same on other versions.
4
0
665
Aug ’23
[NETransparentProxyProvider] NEAppProxyUDPFlow.writeDatagrams sentByEndpoints ipv4 address will become "", ipv6 address can work.
Sorry, my English is not good. I use NETransparentProxyProvider to implement a global proxy program, and the tcp and udp connections will be passed to the remote proxy server by the TransparentProxy system extension. But now I have a problem, the package sent through NEAppProxyUDPFlow.writeDatagrams, when the address is ipv6, the normal program taken over by the proxy can correctly get the address of the udp package. But when the address is IPv4, the normal program taken over by the proxy can only get the source port number of the packet, and the obtained ip address will be blank. TransparentProxy system extension NEAppProxyUDPFlow.writeDatagrams code to send packets: // NWHostEndpoint *hostAddr = [NWHostEndpoint endpointWithHostname:@"::11:22:33:44" port:@"5566"]; NWHostEndpoint *hostAddr = [NWHostEndpoint endpointWithHostname:@"1.2.3.4" port:@"5566"]; NWEndpoint* addr = hostAddr; // _internalEndpoint NWOSAddressEndpoint * 0x151804ce0 0x0000000151804ce0 os_log(OS_LOG_DEFAULT, "[DEBUG] appproxy-test-LocalUdpConn(%{public}@)-writeLoop uFlow writeDatagrams addr:%{public}@ ",uuid,addr.debugDescription); [uFlow writeDatagrams:@[udpPack.data] sentByEndpoints:@[addr] completionHandler:^(NSError *error) { ... } TransparentProxy system extension log: [DEBUG] appproxy-test-LocalUdpConn(6B0C27A0-588E-4D2B-8544-AE927522DD25)-writeLoop uFlow writeDatagrams addr:1.2.3.4:5566 The log shows that the address should be 1.2.3.4:5566. But the ip address actually obtained by the local program taken over by the extension is empty, see below. Local udp test program: package main import ( "log" "net" ) func main() { l, err := net.ListenUDP("udp", &net.UDPAddr{ IP: net.IPv4(0, 0, 0, 0), Port: 0, Zone: "", }) if err != nil { panic(err) } defer l.Close() wData := []byte("0123456789") addr, err := net.ResolveUDPAddr("udp", "1.2.3.4:8088") if err != nil { panic(err) } for { log.Printf("Send a ping to %v...", addr) n, err := l.WriteTo(wData, addr) if err != nil { log.Printf("l.writeTo(%v), %v", addr, err) return } if n != len(wData) { log.Printf("%v!=%v", n, len(wData)) } buf := make([]byte, 1024) log.Printf("Receive pong...") n, rAddr, err := l.ReadFromUDP(buf) if err != nil { log.Printf("%v", err) return } log.Printf("rAddr:%v", rAddr) } } Local test program log: 2023/08/14 19:34:34 Send a ping to 1.2.3.4:8088... 2023/08/14 19:34:34 Receive pong... 2023/08/14 19:34:34 rAddr:[::]:5566 2023/08/14 19:34:34 Send a ping to 1.2.3.4:8088... 2023/08/14 19:34:34 Receive pong... 2023/08/14 19:34:34 rAddr:[::]:5566 2023/08/14 19:34:34 Send a ping to 1.2.3.4:8088... 2023/08/14 19:34:34 Receive pong... 2023/08/14 19:34:34 rAddr:[::]:5566 2023/08/14 19:34:34 Send a ping to 1.2.3.4:8088... 2023/08/14 19:34:34 Receive pong... After changing to IPv6 address, the ip address can be obtained normally. System extensions: NWHostEndpoint *hostAddr = [NWHostEndpoint endpointWithHostname:@"::11:22:33:44" port:@"5566"]; // NWHostEndpoint *hostAddr = [NWHostEndpoint endpointWithHostname:@"1.2.3.4" port:@"5566"]; Local test program log: 2023/08/14 19:43:27 Send a ping to 1.2.3.4:8088... 2023/08/14 19:43:27 Receive pong... 2023/08/14 19:43:27 rAddr:[::11:22:33:44]:5566 2023/08/14 19:43:27 Send a ping to 1.2.3.4:8088... 2023/08/14 19:43:27 Receive pong... 2023/08/14 19:43:27 rAddr:[::11:22:33:44]:5566 2023/08/14 19:43:27 Send a ping to 1.2.3.4:8088... 2023/08/14 19:43:27 Receive pong... 2023/08/14 19:43:27 rAddr:[::11:22:33:44]:5566 2023/08/14 19:43:27 Send a ping to 1.2.3.4:8088... 2023/08/14 19:43:27 Receive pong... It can be seen that when the address is an IPv6 address, the ip address can be obtained correctly. Where should this be the problem? How should it be corrected? Thank you so much.
2
0
319
Aug ’23
Matter - programmable switch and battery
Hi, we develop devices on Matter. I have two questions: I have a device with four buttons. These are programmable buttons that can be programmed for a short press and a long press. I have an issue that after pairing the buttons with Apple Home, all the buttons are displayed as button 1. They also appear in different environments each time. How do I need to configure the clusters for Apple Home to correctly recognize the buttons? How do I display the battery status? I'm using the Power Cluster, but Apple Home doesn't detect it. The battery doesn't show up in the app at all. On Samsung SmartThings, the battery works correctly. Best regards, HaWca.
0
0
563
Aug ’23
Per App Web Content Filter - No NEFilterBrowserFlow?
Since iOS 16 it is possible to use content filter on managed apps instead of supervised devices using the new ContentFilterUUID attribute. I built a simple test project for this and found that even when targeting browser apps, no flow in the data filter is NEFilterBrowserFlow and thus can be remediated with a blocking page. All received flows are socket flows. When changing the configuration via NEFilterManager to filterSockets=false and filterBrowsers=true nothing passes through the content filter. Is this by design? is there no way to show blocking pages using per app content filter?
4
0
533
Aug ’23
NEPacketTunnelNetworkSettings excludedRoutes not working for few ip's such as: 239.255.255.250
Hi, We are observing few NEPacketTunnelNetworkSettings excludedRoutes ip's in PacketTunnel even-though it is added in exclude routes. As you can see in network setting where we have added destinationAddress = 239.255.255.0 destinationSubnetMask = 255.255.255.0 in exclude route, still traffic of IP 239.255.255.250 coming to packet tunnel. We also observing other IP's traffic that is not added in include route such as: 20.192.170.9 //Network Settings for Packet Tunnel IPv4Settings = { configMethod = PPP addresses = ( 10.10.10.10, ) subnetMasks = ( 255.255.255.255, ) includedRoutes = ( { destinationAddress = 10.10.10.10 destinationSubnetMask = 255.255.255.255 gatewayAddress = 10.10.10.10 }, ) excludedRoutes = ( { destinationAddress = 192.168.0.0 destinationSubnetMask = 255.255.0.0 }, { destinationAddress = 10.0.0.0 destinationSubnetMask = 255.0.0.0 }, { destinationAddress = 127.0.0.1 destinationSubnetMask = 255.255.255.255 }, { destinationAddress = 172.16.0.0 destinationSubnetMask = 255.240.0.0 }, { destinationAddress = 239.255.255.0 destinationSubnetMask = 255.255.255.0 }, ) am i doing something wrong in setting NEPacketTunnelNetworkSettings?
4
1
785
Aug ’23
OSSystemExtensionRequest not superseding previous requests
I'm working on a VPN App that uses a NEPacketTunnelProvider system extension. On my computer, when sending out the first OSSystemExtensionRequest requesting that the extension is installed / activated, a system alert is shown to the user informing them that the extension installation was blocked. This is fine. Each time the user starts the process again (for whatever reason) we're sending out a new OSSystemExtensionRequest. And this is where it gets strange: On my computers (I've tried on my development and personal one) the previous request is immediately cancelled with a OSSystemExtensionErrorRequestSuperseded error and a new alert is shown. For everyone else trying this out, the previous request is not being cancelled at all and it seems like requests are silently piling up. Newly-sent requests do trigger the delegate's requestNeedsUserApproval(_:). But because they're piling up users are not shown a new system alert, breaking the UX. I guess I could evaluate if there's an existing request to avoid sending out a new one, but this is only supported in macOS 12+ through (propertiesRequest(forExtensionWithIdentifier:queue:)). My questions: Which of the above is the correct behaviour? Why could it be that only I am seeing a different behaviour?
2
0
454
Aug ’23
Getting Started with Bonjour
Every now and then I talk to someone who’s trying to use Bonjour and just can’t get over the first hurdle. That happened today, and so I decided to share my write-up for the benefit of others. Questions or comments? Put them in a new thread here on DevForums, tagging it with Bonjour so that I see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" Getting Started with Bonjour Bonjour is an Apple term for a variety of Internet standards [1]. Bonjour allows your app to browse for and connect to services on the network without infrastructure support. For example, Bonjour lets you find and connect to a printer even if the network has no DHCP server to hand out IP addresses. If you’re new to Bonjour, a good place to start is the Bonjour Overview. It’s in the documentation archive, so it hasn’t been updated in a while, but the fundamentals haven’t changed. There are, however, two things that have changed: Network framework has new Bonjour APIs, and the old ones are now deprecated. iOS 14 introduced local network privacy. This post shows how to get started with Bonjour, taking into account these new developments. [1] Specifically: RFC 3927 Dynamic Configuration of IPv4 Link-Local Addresses RFC 6762 Multicast DNS RFC 6763 DNS-Based Service Discovery Start Browsing Let’s start by implementing a service browser. To simplify things, this browses for SSH services. That way you can get started with the browser without first having to implement a server to register your service. If you don’t already have an SSH service registered on your network, start one by enabling System Settings > General > Sharing > Remote Login on your Mac. The SSH service type is, unsurprisingly, _ssh._tcp. First, on your Mac, run the dns-sd tool to confirm that you have an SSH service visible on your network: % dns-sd -B "_ssh._tcp" "local." % dns-sd -B "_ssh._tcp" "local." … Timestamp A-R Flags if Domain Service Type Instance Name … 11:54:43.315 Add 2 6 local. _ssh._tcp. Fluffy … 11:54:43.725 Add 2 6 local. _ssh._tcp. SAM the Robot 12 ^C This shows that I have two services, one called Fluffy and the other called SAM the Robot 12. Let’s write some iOS code to browse for those. To start, create an app from the iOS > App template and connect a button to the startStop() method of a class like this: import Foundation import Network class AppModel { var browserQ: NWBrowser? = nil func start() -> NWBrowser { print("browser will start") let descriptor = NWBrowser.Descriptor.bonjour(type: "_ssh._tcp", domain: "local.") let browser = NWBrowser(for: descriptor, using: .tcp) browser.stateUpdateHandler = { newState in print("browser did change state, new: \(newState)") } browser.browseResultsChangedHandler = { updated, changes in print("browser results did change:") for change in changes { switch change { case .added(let result): print("+ \(result.endpoint)") case .removed(let result): print("- \(result.endpoint)") case .changed(old: let old, new: let new, flags: _): print("± \(old.endpoint) \(new.endpoint)") case .identical: fallthrough @unknown default: print("?") } } } browser.start(queue: .main) return browser } func stop(browser: NWBrowser) { print("browser will stop") browser.stateUpdateHandler = nil browser.cancel() } func startStop() { if let browser = self.browserQ { self.browserQ = nil self.stop(browser: browser) } else { self.browserQ = self.start() } } } Note I’m using SwiftUI, but if you chose to use UIKit you could add this code directly to your view controller. Of course, whether you want to add networking code to your view controller is another question. The answer is, natch, “No”, except when creating a tiny test project like this one (-: Now build and run in the simulator and click your buton. It’ll print something like this: browser will start browser did change state, new: ready browser results did change: + SAM the Robot 12._ssh._tcp.local. + Fluffy._ssh._tcp.local. As you can see, it’s found our two SSH services. Yay! Run on the Device Now stop the app and run it on a real device. This time the Test button results in: browser will start … browser did change state, new: failed(-65555: NoAuth) This is local network privacy kicking in. There are two things you need to do: Add a NSBonjourServices property to your Info.plist to declare what service types you’re using. Add a NSLocalNetworkUsageDescription property to your Info.plist to explain what you’re doing with the local network. Do that and run your app again. On tapping the Test button you’ll see an alert asking you to grant your app access to the local network. Tap Allow and the browser will start generating results as before. Respond to Updates When working with Bonjour it’s important to keep your browser running to update your app’s state. To test this, start a Remote Login on a different machine and look for a new result being printed: browser results did change: + Slimey._ssh._tcplocal. And then turn it off: browser results did change: - Slimey._ssh._tcplocal. If you don’t have another Mac to test this with, start a dummy service using dns-sd: % dns-sd -R "Guy Smiley" "_ssh._tcp" "local." 12345 Registering Service Test._ssh._tcp.local. port 12345 … Press control-C to stop the dns-sd tool, which unregisters the service. Connect When the user choose a service, it’s time to connect. There are two ways to do this, depending on the networking API you use to run your connection. NWConnection can connect directly to a Bonjour service endpoint. For example, you might have code that connects to a DNS name and port: func makeConnection(host: String, port: UInt16) -> NWConnection { let host = NWEndpoint.Host(host) let port = NWEndpoint.Port(rawValue: port)! let endpoint = NWEndpoint.hostPort(host: host, port: port) return NWConnection(to: endpoint, using: .tcp) } Replace that with code that takes the endpoint you get back from the browser: func makeConnection(endpoint: NWEndpoint) -> NWConnection { return NWConnection(to: endpoint, using: .tcp) } If you’re using a legacy API, like BSD Sockets, you’ll need to resolve the Bonjour service endpoint to a DNS name and then pass that DNS name into your connection code. Network framework does not support resolving Bonjour service endpoints out of the box, so you’ll have to do that yourself. For an example of how you might do this, see this post. IMPORTANT For this to work reliably, your BSD Sockets code must support Happy Eyeballs. See TN3151 Choosing the right networking API for specific advice on that front. Register a Service Now let’s look at the server side. To listen for connections with Network framework, you might write code like this: import Foundation import Network class AppModel { var listenerQ: NWListener? = nil func start() -> NWListener? { print("listener will start") guard let listener = try? NWListener(using: .tcp) else { return nil } listener.stateUpdateHandler = { newState in print("listener did change state, new: \(newState)") } listener.newConnectionHandler = { connection in connection.cancel() } listener.start(queue: .main) return listener } func stop(listener: NWListener) { print("listener will stop") listener.stateUpdateHandler = nil listener.cancel() } func startStop() { if let listener = self.listenerQ { self.listenerQ = nil self.stop(listener: listener) } else { self.listenerQ = self.start() } } } To register your service with Bonjour, add these lines before the call to start(queue:): listener.service = .init(type: "_ssh._tcp") listener.serviceRegistrationUpdateHandler = { change in print(change) } The listener calls your service registration update handler to tell you the name of the service. Typically you display this value somewhere in your UI. For more about this, see Showing Connection Information in an iOS Server. To confirm that your service is running, open Terminal and choose Shell > New Remote Command. Your service should show up in the Secure Shell (ssh) list. Alternatively, browse for SSH services using the dns-sd tool, as illustrated in the Start Browsing section above.
0
0
2.3k
Aug ’23
Memory management between Objective-C Core WLAN Functions called from Go lang
Hi Experts, I am working on a application where I am calling Objective-C Core WLAN API from golang with below code, darwin_lib.m void ConnectWiFi(char * cInterfacename, char * cSSID, char * cSecurity, char *cSubsecurity, char * cPassphrase, char * cOnexuser, char * cOnexpass) { @autoreleasepool { NSString * interfacename = [[NSString alloc] initWithUTF8String:cInterfacename]; NSString * ssid = [[NSString alloc] initWithUTF8String:cSSID]; NSString * security = [[NSString alloc] initWithUTF8String:cSecurity]; NSString * subsecurity = [[NSString alloc] initWithUTF8String:cSubsecurity]; NSString * passphrase = [[NSString alloc] initWithUTF8String:cPassphrase]; NSString * onexuser = [[NSString alloc] initWithUTF8String:cOnexuser]; NSString * onexpass = [[NSString alloc] initWithUTF8String:cOnexpass]; NSError * connecterr = nil; CWWiFiClient * cwwificlient = [CWWiFiClient sharedWiFiClient]; CWInterface *a = [cwwificlient interfaceWithName:interfacename]; NSSet<CWNetwork *> * network = [a scanForNetworksWithName:ssid error:&connecterr]; **** some more code ***** BOOL result = [a associateToEnterpriseNetwork:network.anyObject identity:nil username:onexuser password:onexpass error:&connecterr]; main.go package main // #cgo CFLAGS: -x objective-c // #cgo LDFLAGS: -framework CoreWLAN // #cgo LDFLAGS: -framework Foundation // #include "clib.h" import "C" import "fmt" func main() { var status C.int = C.ConnectWiFi() time.Sleep(20) *** some more code and long running process *** } Now what I am trying to understand here from memory release point of view is, Is object created in C code will be freed once I reach time.Sleep(20) e.g cwwificlient a spcifically to Core WLAN side or do I have to call release specifically on object? I tried calling release on cwwificlient and program is crashing on second execution, not sure why it would crash on only second execution, why not first time itself? I tried calling release on a and program is not crashing. Do I have to free all the Core WLAN related object myself or autoreleasepool will take care of it? As whole code is inside autoreleasepool, will all the objects be released on it's own even though function is being called from go code? As go's garbage collector has no idea how many objects C code created so go's garbage collector won't be of any help here Is autoreleasepool, can also take care of releasing any alloc object e.g ssid created inside C code ?
3
0
846
Aug ’23
NEHotspotConfigurationHelper failed to communicate to helper server. ("Connection invalid")
When I am trying to connect from a iOS 15 device to a new local network that the device has never connected to before using this code: let hotspotConfig = NEHotspotConfiguration(ssid: "ssid", passphrase: "pass", isWEP: false) hotspotConfig.joinOnce = false let hotspotManager = NEHotspotConfigurationManager.shared hotspotManager.apply(hotspotConfig) { error in if let error = error { print(error) } } The following error is given when executing above code: NEHotspotConfigurationHelper failed to communicate to helper server. Error Domain=NEHotspotConfigurationErrorDomain Code=8 "internal error." UserInfo={NSLocalizedDescription=internal error.} Failed to send a 9 message to nehelper: &lt;dictionary: 0x1f4150c70&gt; { count = 1, transaction: 0, voucher = 0x0, contents = "XPCErrorDescription" =&gt; &lt;string: 0x1f4150e08&gt; { length = 18, contents = "Connection invalid" } } I have added the following capabilities: Access WiFi Information Hotspot Configuration Wireless Accessory Configuration (don't think this is needed?) The in my info.plist I got the following strings: NSLocalNetworkUsageDescription NSLocationWhenInUseUsageDescription I have tested following actions based on other threads on this topic: Set joinOnce = false since this might cause bugs om iOS 15 Add location permission Restart the phone Check if the "Edit your App ID Configuration" is correct (which has the 3 capabilities checked) I also never receive a dialogue that the app wants to connect to ... so I have no idea what is causing this error since the network SSID is available and the password is correct.
1
1
543
Aug ’23
Always On VPN (Running app on startup)
Hi, I want to ask about "Auto running application when finish booting/restart/on startup device" I already read some article for this but there no solution of it. But I've notice VPN can be running on that condition then I do my research on it. I found https://developer.apple.com/documentation/networkextension and there are something called by "Always-on VPN". I would to ask about this features, because I really need my application can be running on startup. can I use some feature to make my application like VPN?
6
0
599
Aug ’23
How cam I bind a socket to an interface to send data through it
Hello, In a simple macOS tool, I'm trying to bind a socket to the default interface like "en0" or a VPN interface like "utun5" to make the socket send the data only through that interface. int idx = (int)if_nametoindex("utun5"); if (setsockopt(sock, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx)) == -1) { perror("setsockopt"); exit(1); } The method setsockopt succeeds however the data doesn't go through the bound interface, but it goes through the default interface like if there has been no binding at all. I tried also with libcurl, which is based on sockets, but the data goes through the default interface like before, even if the method succeed. if (curl_easy_setopt(curlH, CURLOPT_INTERFACE, "utun5") != CURLE_OK) { perror("CURLOPT_INTERFACE"); exit(1); } May someone suggest how to bind an interface to a socket in a way that makes all the data transmitted by that socket go only through the bound interface? Any constructive suggestion is very welcome. Thank you! Best regards, Luca Severini
1
0
512
Aug ’23
Testing/Debugging Background Session Code
I’m trying to debug background session workflows. I read the excellent article Quinn wrote here: https://developer.apple.com/forums/thread/14855 I’m not seeing the call to exit(0) work for relaunching an app when a background URL Session completes. I’m also not getting the UIApplication.willTerminateNotification in that case. I am testing on an actual device and not hooked up to the debugger. Has anything changed since that article was published? Are there new tips for debugging background URLSession relaunch workflows?
2
0
648
Aug ’23
UDP listener only receives one packet
I have an issue where my iPhone app needs to listen for a UDP packet, and respond to the sender. This works when I first load the app, but after receiving the first packet and responding, it stops receiving any more, and I instead see errors in the logs. Code for UDP Listener: import Foundation import Network import Combine class UDPListener: ObservableObject { var listener: NWListener? var connection: NWConnection? /// New data will be place in this variable to be received by observers @Published private(set) public var messageReceived: Data? /// When there is an active listening NWConnection this will be `true` @Published private(set) public var isReady: Bool = false /// Default value `true`, this will become false if the UDPListener ceases listening for any reason @Published public var listening: Bool = true /// A convenience init using Int instead of NWEndpoint.Port convenience init(on port: Int) { self.init( on: NWEndpoint.Port(integerLiteral: NWEndpoint.Port.IntegerLiteralType(port)) ) } /// Use this init or the one that takes an Int to start the listener init(on port: NWEndpoint.Port) { let params = NWParameters.udp params.allowLocalEndpointReuse = true params.allowFastOpen = true self.listener = try? NWListener(using: params, on: port) self.listener?.stateUpdateHandler = { update in switch update { case .ready: self.isReady = true print("Listener connected to port \(port)") case .failed, .cancelled: // Announce we are no longer able to listen self.listening = false self.isReady = false print("Listener disconnected from port \(port)") default: print("Listener connecting to port \(port)...") } } self.listener?.newConnectionHandler = { connection in print("Listener receiving new message") self.createConnection(connection: connection) } self.listener?.start(queue: .main) } func createConnection(connection: NWConnection) { self.connection = connection self.connection?.stateUpdateHandler = { (newState) in switch (newState) { case .ready: print("Listener ready to receive message - \(connection)") self.receive() case .cancelled, .failed: print("Listener failed to receive message - \(connection)") // Cancel the listener, something went wrong self.listener?.cancel() // Announce we are no longer able to listen self.listening = false default: print("Listener waiting to receive message - \(connection)") } } self.connection?.start(queue: .main) } func receive() { self.connection?.receiveMessage { data, context, isComplete, error in if let unwrappedError = error { print("Error: NWError received in \(#function) - \(unwrappedError)") return } guard isComplete, let data = data else { print("Error: Received nil Data with context - \(String(describing: context))") return } self.messageReceived = data print(String(decoding: data, as: UTF8.self)) if String(decoding: data, as: UTF8.self) == "teststring" { switch self.connection?.endpoint { case .hostPort(let host, let port): print("Sending response to \(host):\(port)") default: break } self.connection?.send( content: String("received").data(using: .utf8), completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in if (NWError == nil) { print("Data was sent to UDP") } else { print("ERROR SEND! Error when data (Type: Data) sending. NWError: \n \(NWError!)") } })) ) } if self.listening { self.receive() } print(String(self.listening)) } } func cancel() { print("cancelling udp listener") self.listening = false self.connection?.cancel() } }
6
0
656
Aug ’23
NwPathMonitor's pathUpdateHandler block is called without change.
It seems that sometimes the pathUpdateHandler block is called even though the NWPath data is unchanged. Is this known? Or is there some unexposed change to the NWPath struct? 2023-08-23 14:16:02.149962+0900 NWPath -> status: satisfied, unsatisfiedReason: notAvailable, availableInterfaces: ["(type: wifi, name: en0, kernel index: 11)", "(type: cellular, name: pdp_ip0, kernel index: 3)"], isExpensive: false, isConstrained: false, supportsIPv4: true, supportsIPv6: false, supportsDNS: true, gateways: ["(description: 192.168.0.1:0, interface: nil, txtRecord: nil)"], localEndpoint: nil, remoteEndpoint: nil 2023-08-23 14:19:12.077079+0900 NWPath -> status: satisfied, unsatisfiedReason: notAvailable, availableInterfaces: ["(type: wifi, name: en0, kernel index: 11)", "(type: cellular, name: pdp_ip0, kernel index: 3)"], isExpensive: false, isConstrained: false, supportsIPv4: true, supportsIPv6: false, supportsDNS: true, gateways: ["(description: 192.168.0.1:0, interface: nil, txtRecord: nil)"], localEndpoint: nil, remoteEndpoint: nil 2023-08-23 14:19:16.065005+0900 NWPath -> status: satisfied, unsatisfiedReason: notAvailable, availableInterfaces: ["(type: wifi, name: en0, kernel index: 11)", "(type: cellular, name: pdp_ip0, kernel index: 3)"], isExpensive: false, isConstrained: false, supportsIPv4: true, supportsIPv6: false, supportsDNS: true, gateways: ["(description: 192.168.0.1:0, interface: nil, txtRecord: nil)"], localEndpoint: nil, remoteEndpoint: nil
1
0
438
Aug ’23