# Class Tunnels

java.lang.Object
com.codename1.vpn.tunnel.Tunnels

public final class Tunnels extends Object

Starts and stops a packet tunnel this application implements.

    if (Tunnels.isSupported()) {
        Tunnels.start(new MyTunnel(), new TunnelSetup()
                .address("10.0.0.2/32")
                .route("0.0.0.0/0")
                .dnsServer("10.0.0.1")
                .data(sessionToken));
    }

##### Ask whether it is supported

`isSupported()` answers true on Android, and on an iOS build that generated the packet tunnel extension -- which is one that set `ios.vpn.tunnel=true`, named its tunnel in `ios.vpn.tunnel.class`, and holds the Network Extension entitlement Apple grants case by case. It answers false on every other iOS build, which is most of them, and everywhere else. Ask it and keep a path for the answer being no -- `start(VpnTunnel, TunnelSetup)` refuses with `NOT_SUPPORTED` rather than pretending.

##### Do not assume the instance you pass is the one that runs

On Android it is: the tunnel runs in this process, inside the port's `VpnService`, so everything it closed over is still there. That is a property of one platform rather than of this API -- a tunnel hosted in another process would be CONSTRUCTED there, with none of the app's statics, which is what `TunnelSetup.data` is for.

The rule that follows costs nothing on Android and is the only thing that stays portable: a tunnel takes everything it needs from `VpnTunnel.onStart(TunnelConfiguration)`'s configuration.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static boolean`
  `isSupported()`
  Whether this platform can run a tunnel the application implements.
  `static AsyncResource<Boolean>`
  `start(VpnTunnel tunnel, TunnelSetup setup)`
  Brings the tunnel up, resolving true once the platform has it.
  `static AsyncResource<Boolean>`
  `stop()`
  Takes the tunnel down.

  ### Methods inherited from class Object

  `clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Method Details

  - ### isSupported

    public static boolean isSupported()

    Whether this platform can run a tunnel the application implements.

    False is the ordinary answer on most ports, and it is the query to branch on -- not a platform test, which would go stale the moment a port gained the capability.

  - ### start

    public static AsyncResource<Boolean> start(VpnTunnel tunnel, TunnelSetup setup)

    Brings the tunnel up, resolving true once the platform has it.

    Shows the system's VPN consent prompt where one is needed, so the result can be a `VpnError.USER_DECLINED` failure.

    Parameters:
      `tunnel` - the application's packet loop
      `setup` - what the platform should establish
    Returns:
      true once the tunnel is up

  - ### stop

    public static AsyncResource<Boolean> stop()

    Takes the tunnel down.

    Answers even where no tunnel is running, because an app that has lost track of its own state must be able to ask for the stopped one.