# 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));
    }

##### Android only

`isSupported()` answers true on Android and false everywhere else, including iOS: a packet tunnel there runs in a Network Extension, and the translation that would give that process a virtual machine has not been written. Ask `isSupported()` 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.