12 Replies
      Latest reply on Jan 10, 2018 12:51 AM by eskimo
      roee84 Level 1 Level 1 (0 points)

        In related to my other question "Packet Tunnel Provider + libcurl" https://forums.developer.apple.com/message/285308

        I have a VPN app with Packet Tunnel Provider, and the VPN is connected and works as expeceted.

        Now I'm trying to add some code at the Extension app, which should access the internet.

        I see that the requests doesn't go via the tunnel, so I'm guessing that traffic made at the extension doesn't reach to the packetFlow object.

         

        Am I correct / wrong? Is it a bug or this is the expected behavior? How can I force the traffic at the extension to go through the tunnel?

        • Re: Packet Tunnel Provider - route traffic via tunnel at the Extension app
          eskimo Apple Staff Apple Staff (12,695 points)

          I see that the requests doesn't go via the tunnel, so I'm guessing that traffic made at the extension doesn't reach to the packetFlow object.

          I’ve seen behaviour like this, but only in the context of per-app VPN.  Is your packet tunnel provider running in source app (NETunnelProviderRoutingMethodSourceApplication) or destination IP address (NETunnelProviderRoutingMethodDestinationIP) mode?

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: Packet Tunnel Provider - route traffic via tunnel at the Extension app
              roee84 Level 1 Level 1 (0 points)

              NETunnelProviderRoutingMethodDestinationIP  (which is the default, I didn't set routingMethod).

                • Re: Packet Tunnel Provider - route traffic via tunnel at the Extension app
                  eskimo Apple Staff Apple Staff (12,695 points)

                  In destination IP mode traffic is routed via IP address.  Despite the name, the source IP address is also considered.  The general rule is something like this:

                  1. If the app binds the socket to a specific interface (either by calling bind with the interface’s source IP address or by IP_BOUND_IF), it goes via that interface.

                  2. If the destination address is on a network defined by the interface, it goes via that interface.

                  3. If there’s an explicitly entry in the routing table, it honours that.

                  4. Finally, it goes via the default route.

                  Your packet tunnel provider can control the last three steps:

                  • For step 2 you set the interface’s networks via the addresses and subnetMasks properties of the NEIPv4Settings object you use to configure the interface (and similarly for IPv6).

                  • For step 3 you can explicitly opt in to and out of networks via the includedRoutes and excludedRoutes.  Also, you can automatically opted out of the address in the tunnelRemoteAddress property of the NEPacketTunnelNetworkSettings object.

                  • For step 4 you claim the default route (and thus become the primary interface) by including +[NEIPv4Route defaultRoute] in the includedRoutes property.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"

                    • Re: Packet Tunnel Provider - route traffic via tunnel at the Extension app
                      roee84 Level 1 Level 1 (0 points)

                      That exactly what I thought, but still - I'm not sure it's working that way:

                      Just for example, I wrote this test:

                        let url = URL(string: "https:/ /   somewebsite.com"")
                                          let task = URLSession.shared.dataTask(with: url!) {(data, response, error) in
                                              if data != nil {
                                                  let res = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                                                  DDLogInfo("res:\(res!)")
                                              } else {
                                                  DDLogInfo("data is null")
                                              }
                                          }
                                          task.resume()
                      

                       

                      When I'm running it at the Extension (after the tunnel is open, and the VPN is connected) - this reqeust doesn't goes via the tunnel.

                      But if I'm writing this code at the containing app (after the VPN is connected), the request will go via the tunnel.

                       

                      In addition to what you said:

                      I did include defaultRoute (step 4), so the tunnel supposed to become the primary interface as you said

                      I did not excluded anything (step 3)

                      I'm not using bind

                      There's no explicit entry at the routing table

                       

                      In general - everything else is working good and goes via the tunnel.

                      Only traffic from the Extension itself behaves differently.