Network connections send and receive data using transport and security protocols.

Posts under Network tag

200 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Authenticate with ProxyConfiguration in WebKit
Hello, I am trying to apply ProxyConfiguration on the WebKit webview. I've tried HTTP and SOCKSv5 without authentication, and it proxies normally. However, after I set up username authenticate on the server side, then set username and password with applyCredential on the client side, it couldn't authenticate the connection. Logs on the server side show the client side says it doesn't support any authentication. So I have some questions about the authentication: Does the ProxyConfiguration support authentication now? Does applyCredential apply credentials on HTTP/HTTPS and SOCKSv5 proxy?
4
1
794
Nov ’23
swift: create URLCredential() with newly generated certificate/private key
Hello! I am a newby into Apple ecosystem/swift development so forgive me if it is a trivial question. But I cannot find a good tutorial/article on this topic. I am trying to implement a mutual TLS for my iOS application. To generate key/certificate I use https://github.com/apple/swift-* libraries. Next moving to mTLS logic. I use URLSessionDelegate for this purpose as it seems it is the only way to implement mTLS. The NSURLAuthenticationMethodServerTrust part seems fine. Now I am trying to implement the client side of the authentication. let identity = ??? let urlCredential = URLCredential( identity: identity, certificates: nil, persistence: .none) completionHandler(.useCredential, urlCredential) And here is my question. What is the correct/idiomatic way to create SecIdentityRef object out of a private key/certificate? Certificate can be serialized into DER form if needed. I googled for a whole day and did not find a clear information on how to create the identity I need. If anyone has some information on this topic, could you please help me?
1
0
595
Jul ’23
Apple private relay and Websocket messaging
Hi. i've app in swift for iOS and macOS, which using websocket webSocketTask = URLSession.shared.webSocketTask(with: request) //Session let session = URLSession(configuration: configuration ?? .default, delegate: self, delegateQueue: OperationQueue()) and as the result, when user have turn on Private relay, user doesn't receive any informatiom from web socket, if user switch off this function, all is fine. Could you give some advise, how to setup client, or server to allow working websockets in that case?
7
0
843
Aug ’23
NWConnection WebSocket Protocol hangs on preparing for iOS 13 only
I have a critical issue where my websocket will not connect to a server that is sitting behind an NGINX reverse proxy only on iOS 13. I have tested on both a real device and simulator with no success. It simply hangs on preparing. it never receives updates to the viabilityUpdateHandler and only ever enters the preparing state of the stateUpdateHandler. On any iOS greater or equal to iOS 14 it works seamlessly. I can connect to a local server that is not dealing with any certificates on iOS 13 no problem, but when my production server is in play it does not communicate something properly. I am using NWConnection's NWProtocolWebSocket. The setup is basic and straight forward let options = NWProtocolWebSocket.Options() options.autoReplyPing = configuration.autoReplyPing options.maximumMessageSize = configuration.maximumMessageSize if configuration.urlRequest != nil { options.setAdditionalHeaders(configuration.urlRequest?.allHTTPHeaderFields?.map { ($0.key, $0.value) } ?? []) _ = configuration.cookies.map { cookie in options.setAdditionalHeaders([(name: cookie.name, value: cookie.value)]) } } if !configuration.headers.isEmpty { options.setAdditionalHeaders(configuration.headers.map { ($0.key, $0.value) } ) } let parameters: NWParameters = configuration.trustAll ? try TLSConfiguration.trustSelfSigned( configuration.trustAll, queue: configuration.queue, certificates: configuration.certificates) : (configuration.url.scheme == "ws" ? .tcp : .tls) parameters.defaultProtocolStack.applicationProtocols.insert(options, at: 0) connection = NWConnection(to: .url(configuration.url), using: parameters) The trust store is also straight forward public static func trustSelfSigned(_ trustAll: Bool, queue: DispatchQueue, certificates: [String]? ) throws -> NWParameters { let options = NWProtocolTLS.Options() var secTrustRoots: [SecCertificate]? secTrustRoots = try certificates?.compactMap({ certificate in let filePath = Bundle.main.path(forResource: certificate, ofType: "der")! let data = try Data(contentsOf: URL(fileURLWithPath: filePath)) return SecCertificateCreateWithData(nil, data as CFData)! }) sec_protocol_options_set_verify_block( options.securityProtocolOptions, { _, sec_trust, sec_protocol_verify_complete in guard !trustAll else { sec_protocol_verify_complete(true) return } let trust = sec_trust_copy_ref(sec_trust).takeRetainedValue() if let trustRootCertificates = secTrustRoots { SecTrustSetAnchorCertificates(trust, trustRootCertificates as CFArray) } dispatchPrecondition(condition: .onQueue(queue)) SecTrustEvaluateAsyncWithError(trust, queue) { _, result, error in if let error = error { print("Trust failed: \(error.localizedDescription)") } print("Validation Result: \(result)") sec_protocol_verify_complete(result) } }, queue ) sec_protocol_options_set_min_tls_protocol_version(options.securityProtocolOptions, .TLSv12) let parameters = NWParameters(tls: options) parameters.allowLocalEndpointReuse = true parameters.includePeerToPeer = true return parameters }
3
0
586
Aug ’23
Background API call in iOS
Hello, I am building an enterprise application, where I will be syncing user location to the backend server every 5 min for a period of 12 hr every day. I have enabled location updates and background processing for the app in Xcode, and also will be getting location permission as always from user. We are able to get the location update from the user for the whole time, but the part where we make the service call to sync with backend is delayed. It works fine for the first couple of minutes, but later we see the delay. I have also used NWConnection to directly make the service call without using URLSession, this approach is slight better comparatively, but not perfect. I have made sure "Low power mode" and "Low data mode" is disabled, also "Background App Refresh" is enabled for the application. I believe it should be possible since may app eg. WhatsApp, Telegram have a feature of sharing live location for up to 8 hrs. Is there any way where we can achieve this without delay? Thanks in advance.
1
0
693
Aug ’23
MTU cache doesn't gets updated when PMTU is set.
HI, I've created a virtual interface that used to get all outgoing packets, encapsulate with some VPN header, before resend them to their final destination through the physical adapter. In order to choose the optimal MTU size that won't trigger fragmentation, I'd like to calculate the PMTU between the physical interface and the destination, subtracted by the encapsulation header size. Then I'll set the virtual adapter's MTU with this result. In order to do so, I poll the overall MTU cache using sysctl on macOS. First, I verified that path mtu discovery is set sysctl net.inet.tcp.path_mtu_discovery net.inet.tcp.path_mtu_discovery: 1 Then, I tried to extract the cached pmtu for the gateway from the other size of the tunnel using the routing table . static constexpr auto kSysctlMibLength = 6; void get_pmtu_cache() { std::map<std::string, std::uint32_t> res; size_t size_needed = 0; std::vector<char> route_table; std::array<int, kSysctlMibLength> mib; char *next = nullptr; char *lim = nullptr; struct rt_msghdr *rtm = nullptr; struct sockaddr *saddr = nullptr; struct sockaddr_in *sockin = nullptr; char dest_ip_address[INET6_ADDRSTRLEN]; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; // stage 1 : get the routing table // get routing table size if (sysctl(mib.data(), kSysctlMibLength, nullptr, &size_needed, nullptr, 0) < 0) { return; } // allocate local var according to size route_table.reserve(size_needed); // get routing table contents if (sysctl(mib.data(), kSysctlMibLength, route_table.data(), &size_needed, nullptr, 0) < 0) { return; } In the next step, I simple iterate the routing table elements and extract the following field for each destination : rt_msghdr.rt_metrics.rmx_mtu which is the path MTU from current endpoint to dest address. lim = route_table.data() + size_needed; for (next = route_table.data(); next < lim; next += rtm->rtm_msglen) { rtm = reinterpret_cast<struct rt_msghdr *>(next); saddr = reinterpret_cast<struct sockaddr *>(rtm + 1); if ((rtm->rtm_addrs & RTA_DST) != 0) { sockin = reinterpret_cast<struct sockaddr_in *>(saddr); if (nullptr == inet_ntop(saddr->sa_family, &sockin->sin_addr.s_addr, dest_ip_address,INET6_ADDRSTRLEN)) { continue; } const std::string dest_ip_address_str(dest_ip_address, strlen(dest_ip_address)); auto iter = res.find(dest_ip_address_str); if (iter == res.end() || iter->second > rtm->rtm_rmx.rmx_mtu) { res.insert_or_assign(dest_ip_address_str, rtm->rtm_rmx.rmx_mtu); } } } when I finally print all the values in res I see that my pmtu to my VPN server is 1500, even-though I've set the server's mtu size to 1000, and I check that ping -D -s 1500 <server> doesn't work since packets from size 1500 that cannot be fragmanted won't work. auto item = res.find(vpn_server_address); if (item == res.cend()) { printf("no pmtu found to %s\n", vpn_server_address ); return; } ret = item->second; I've tried to trigger the pmtu discovery to the VPN server using nscurl by sending https requests there, but the pmtu still remained on 1500. Perhaps I'm missing something ? do I extract the pmtu correctly ? do I trigger the pmtu discovery by sending https messages using nscurl which is based on NSURLSession ? Thanks !
2
0
626
Aug ’23
Using SimplePing example to send ICMP with DF flag set
Hi, I've tried to modify the simplePing example from here https://developer.apple.com/library/archive/samplecode/SimplePing/ and set the DF flag on. In my attempt, I've used setsockopt right after socket was created : fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); int val = 1; setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val)); However, from wireshark I could clearly see that the icmp packet had the DF bit unset ... Please help me figure out what's wrong in my code. Thanks !
4
0
928
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 &amp; 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
663
Aug ’23
App Privacy Report "context" & "contextVerificationType"
Hey all, recently I've been inspecting my app's privacy report to look for any unexpected hosts. One thing I've noticed is that for hosts that seem unexpected, like the facebook example below, the context field is populated. For all expected requests, it is an empty string. Here in the docs, context and contextVerificationType are not described in much detail. Could someone provide me with some more detail on how those fields are populated? My assumption is that these domains are coming from embedded WKWebView's, but I'm not sure how those fields are populated so I cannot confirm my suspicion. Is it possible to have context poopulated without being in a webview? { "timeStamp":"2023-08-08T09:37:33.456-04:00", "initiatedType":"AppInitiated", "context":"facebook.com", "domain":"www.facebook.com", "contextVerificationType":2, "type":"networkActivity", "domainType":1, "firstTimeStamp":"2023-08-08T09:37:33.456-04:00", "bundleID":"my-bundle-id", "domainOwner":"Facebook, Inc.", "hits":1, "domainClassification":1 } Thanks! LMK if I can add any additional details or if this has been discussed before.
0
0
456
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
396
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
516
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.2k
Aug ’23
GoCert for SSL and TLS certificate, App throws error
Hi, I just set up a new domain and got the SSL certificate using GoCert. I used Nginx to set up a reverse proxy so that my domain points to my VM instance (which I am hosting on GCP). However, I am getting this problem where when my front end sends an HTTP request to my domain, the app crashes and complains and crashes because of an SSL error. For now I am able to mask this error by putting this in my info.plist: &lt;key&gt;NSAppTransportSecurity&lt;/key&gt; &lt;dict&gt; &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt; &lt;true/&gt; &lt;/dict&gt; &lt;key&gt;NSAppTransportSecurity&lt;/key&gt; &lt;dict&gt; &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt; &lt;true/&gt; &lt;key&gt;NSExceptionDomains&lt;/key&gt; &lt;dict&gt; ... Having this in the info.plist file works. But, I was wondering if there was anything that I can do so that I don't need to include this? I am new to app development and network programming and was wondering if anyone had suggestions for what to do or what this means. Would it be because of GoCert?
1
0
373
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
504
Aug ’23
Xcode 15 b6 - "The network connection was lost" in Simulator
Hello, I'm working on SwiftUI app where I'm trying to access ReST API. When I run may app in Simulator, I'm getting "The network connection was lost", but it's working without issues on physical device. struct ContentView: View { @State var jednotky: Jednotky = Bundle.main.decode("jednotky.json") @State private var isOffline = false var body: some View { NavigationView{ VStack{ List(jednotky.rootLevel, id: \.id) { item in NavigationLink{ SoutezeView(rocnik: 2023, jednotka: item.childId, nazev: item.nazev) } label: { JednotkaRowView(nazev: item.nazev, childId: item.childId, parentId: item.parentId) } } if (isOffline) { Text("Using offline data") } } .navigationTitle("Fotbal") }.onAppear{ Task{ await loadData() } } } func loadData() async { let url = URL(string: JEDNOTKY_URL)! var request = URLRequest(url: url) guard let authData = (USERNAME + ":" + PASSWORD).data(using: .utf8)?.base64EncodedString() else { print("Can't create authorization header") return } request.addValue("Basic \(authData)", forHTTPHeaderField: "Authorization") do { let (data, _) = try await URLSession.shared.data(for: request) if let temp = try? JSONDecoder().decode(Jednotky.self, from: data) { jednotky = temp } } catch { print("Cannot download data, using stored sample instead") isOffline = true } } } The error in console: nw_socket_handle_socket_event [C1.1.1:3] Socket SO_ERROR 9 Connection 1: received failure notification Connection 1: failed to connect 1:9, reason 18 446 744 073 709 551 615 Connection 1: encountered error(1:9) Task <103A0196-6715-429B-A5F2-79698C6E9D45>.<1> HTTP load failed, 0/0 bytes (error code: 18 446 744 073 709 550 611 [1:9]) Cannot download data, using stored sample instead Task <103A0196-6715-429B-A5F2-79698C6E9D45>.<1> finished with error [18 446 744 073 709 550 611] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=9, NSUnderlyingError=0x600000c03d50 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en0[802.11], _kCFStreamErrorCodeKey=9, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <103A0196-6715-429B-A5F2-79698C6E9D45>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=( "LocalDataTask <103A0196-6715-429B-A5F2-79698C6E9D45>.<1>" ), NSLocalizedDescription=The network connection was lost., NSErrorFailingURLStringKey=https://is.fotbal.cz/api/jmobile2/orgJednotky.aspx, NSErrorFailingURLKey=https://is.fotbal.cz/api/jmobile2/orgJednotky.aspx, _kCFStreamErrorDomainKey=1}
3
0
904
Aug ’23
Better Control of Background URLSession + UploadTasks
I am trying to implement (in Swift/iOS) Resumable Uploads in a similar fashion to this wwdc23 video Fortunately there is an open source solution to do most of the work! The issue is that background URLSessions seem to have a mind of their own? Basically the gist of the resumable uploads is that an upload will progress to the best of its ability, and then when it fails it's supposed to run a HEAD request to see how much of the file has been written, and then resume uploading from the last good offset. I can not for the life of me get this to work in a "real life" scenario. Something as trivial as leaving wifi for cell causes everything to break. And this isn't that crazy of a scenario! It's totally reasonable to expect a user to do some stuff before they leave the house, and then take their phone and drive away. The WiFI connection will drop and the user will switch to cell. As it is right now the way URLSession handles things is that the initial task fails, but instead of loud, hard failing it quietly, softly fails and then as soon as there is network again the request is completely restarted. This breaks everything. Either the original request timed out and attempting to re-write the entire file fails because the offsets dont match any more (prev had some non-0 offset, new has 0 offset, non-zero != 0), or it fails because there are now two requests who think they have the appropriate offsets and everything gets out of sync. My understanding is that iOS 17 has implemented resumable uploads in a nice way, but how to manage for all the users who don't immediately upgrade? Is there a way to say "Hey URLSession, I know you want to immediately restart this request that failed due to the network disappearing and normally this is what people want, but maybe just cancel that last request that failed and then run this little handler to see where you should really start from and then start from there" My guess is that this is impossible because it needs to run in the background and iOS doesn't like letting apps run when they're not supposed to be? That's why this all had to be baked into iOS17. Just looking for anyone who has any idea how to handle this.
1
1
592
Aug ’23