# Class VpnTunnel

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

public abstract class VpnTunnel extends Object

The packet loop, written once for both platforms.

    public class MyTunnel extends VpnTunnel {
        protected void onStart(TunnelConfiguration cfg) { }
        protected void onPacket(PacketBuffer p) { forward(p); }
        protected void onStop(TunnelStopReason r) { }
    }

##### Where this runs

On Android, in the app's own process, inside the port's `VpnService`. On iOS, in a Network Extension: a separate process, with a virtual machine of its own, which the build generates for a project that sets `ios.vpn.tunnel`.

Write the tunnel as though it ran somewhere else, because on one of the two platforms it does. Everything it needs travels in `TunnelConfiguration.getData()`; a static the app set happens to be there on Android and is not a thing to rely on -- on iOS it is not there at all, and reaching for the app's own classes drags them into the extension's translation, where the ones backed by UIKit fail its link.

##### What is not there, on iOS

The extension carries the translated program and the virtual machine and no networking stack. `Socket`, `ConnectionRequest` and anything else that reaches the implementation find nothing there, and ParparVM's `java.net` is URI and URL -- there are no sockets in it either. So an iOS tunnel inspects, rewrites, drops and `forward(PacketBuffer)`s packets; it cannot open a connection to a remote server. On Android it can, because it runs in the app's own process. A tunnel that needs to relay is not the same class on both platforms, and the difference is worth an interface rather than a surprise.

##### Constructing it

On Android the app constructs the tunnel and hands it to `Tunnels.start(VpnTunnel, TunnelSetup)`. On iOS the EXTENSION constructs it, because `Tunnels.start(VpnTunnel, TunnelSetup)` ran in another process that has since gone away -- so an iOS tunnel needs an accessible no-argument constructor, and the class named by `ios.vpn.tunnel.class` is the one it calls. A tunnel with only a parameterised constructor fails the build rather than the device.

##### What is expensive

A host process for a tunnel runs under a memory budget far below an app's, and is killed rather than warned when it exceeds it. The buffers handed to `onPacket(PacketBuffer)` are reused for exactly that reason, so copying every packet -- or holding one past the call -- gives back the headroom the pooling was for. See `PacketBuffer`.

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `VpnTunnel()`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `protected final void`
  `forward(byte[] packet, int offset, int length)`
  Sends bytes the tunnel produced itself.
  `protected final void`
  `forward(PacketBuffer packet)`
  Sends a packet back to the device.
  `protected abstract void`
  `onPacket(PacketBuffer packet)`
  One packet arrived from the device, bound for the far end.
  `protected abstract void`
  `onStart(TunnelConfiguration configuration)`
  The tunnel is up and the platform has configured the link.
  `protected abstract void`
  `onStop(TunnelStopReason reason)`
  The tunnel is going down, for the given reason.

  ### Methods inherited from class Object

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

- ## Constructor Details

  - ### VpnTunnel

    public VpnTunnel()

- ## Method Details

  - ### onStart

    protected abstract void onStart(TunnelConfiguration configuration)
    The tunnel is up and the platform has configured the link.

  - ### onPacket

    protected abstract void onPacket(PacketBuffer packet)

    One packet arrived from the device, bound for the far end.

    The buffer is REUSED once this returns; see `PacketBuffer`.

  - ### onStop

    protected abstract void onStop(TunnelStopReason reason)
    The tunnel is going down, for the given reason.

  - ### forward

    protected final void forward(PacketBuffer packet)

    Sends a packet back to the device.

    Safe to call with the buffer `onPacket` was given, which is the ordinary pass-through case and copies nothing.

  - ### forward

    protected final void forward(byte[] packet, int offset, int length)
    Sends bytes the tunnel produced itself.