public interface TunnelTransport
How packets reach the tunnel, which is where the two platforms differ.
This interface EXPOSES that difference rather than hiding it, because hiding it would mean pretending one of the platforms works like the other:
- On Android a
VpnServiceruns in the app’s own process and hands over a file descriptor. Reading it blocks, and the read loop owns a thread. - A host that delivers packets through a completion handler instead –
an
NEPacketTunnelProvideris the example, though iOS does not run these tunnels – has nothing to block on, and a loop that tried to would deadlock it. The simulation takes this shape so the case is exercised.
isBlocking is the discriminator, and the host reads it rather than
guessing from the platform. A tunnel written against VpnTunnel never
sees any of this; it is here for the ports and for the simulation.
Methods
public abstract boolean isBlocking() | Whether read blocks until packets arrive. |
public abstract int read(PacketBuffer[] into) | Takes the next packets, filling into and answering how many. |
public abstract void write(PacketBuffer packet) | Sends one packet back out. |
public abstract PacketBuffer[] buffers() | The buffers this transport reads into, sized for the link. |
public abstract void close() | Releases whatever the platform gave the tunnel. |
Method details
isBlocking
public abstract boolean isBlocking()Whether read blocks until packets arrive.
True on Android, where the host gives the loop a thread. False for a host that arms a callback and returns, which is the simulation.
read
public abstract int read(PacketBuffer[] into)Takes the next packets, filling into and answering how many.
Answers 0 when the tunnel is going down, which is how a blocking
loop learns to stop.
write
public abstract void write(PacketBuffer packet)buffers
public abstract PacketBuffer[] buffers()The buffers this transport reads into, sized for the link.
Owned by the transport and reused; see PacketBuffer.
close
public abstract void close()