Table of Contents

Class UdpPacketChannel

Namespace
VpnHood.Core.Tunneling.Channels
Assembly
VpnHood.Core.Tunneling.dll

Provides a session's UDP, for the session's whole life: its keys, its send count and a send queue of its own.

public abstract class UdpPacketChannel : PacketTransport, IPacketChannel, IPacketTransport, IChannel, IDisposable, IAsyncDisposable
Inheritance
UdpPacketChannel
Implements
Inherited Members

Remarks

Its one send loop packs the queued packets into datagrams and seals each with the next sequence number, so the count and the send key need no lock. Its tunnel sends on it while UDP is on; what it receives goes up to the tunnel, on or off. It has no connection: it carries packets from its creation until it is disposed, so it has nothing to start and no close of its own, and its tunnel holds it beside the channel manager, never in it.

Constructors

UdpPacketChannel(ulong, ReadOnlySpan<byte>, bool, ulong, TrafficMeter?, bool)

Initializes a new instance of the UdpPacketChannel class.

protected UdpPacketChannel(ulong sessionId, ReadOnlySpan<byte> key, bool isServer, ulong firstSendSequenceNumber, TrafficMeter? trafficMeter, bool isLegacy)

Parameters

sessionId ulong

The session's ID.

key ReadOnlySpan<byte>

The session's key, which seals and opens its datagrams.

isServer bool

true for the server's side of the session.

firstSendSequenceNumber ulong

The sequence number of the channel's first datagram.

trafficMeter TrafficMeter

The meter that counts the channel's traffic and holds what it receives to its receive limit, or null; a server gives one.

isLegacy bool

true to seal and open the legacy way, for a server's session below MinProtocolVersion.

Exceptions

CryptographicException

key is not an AES key's size.

PlatformNotSupportedException

The platform has no AES-GCM.

Properties

ChannelId

Gets the channel's ID.

public string ChannelId { get; }

Property Value

string

Remarks

It is udp.

LastActivityTime

Gets when the channel last sent or received, in UTC.

public DateTime LastActivityTime { get; }

Property Value

DateTime

NextSendSequenceNumber

Gets the sequence number of the channel's next datagram: the ones sent so far are below it.

public ulong NextSendSequenceNumber { get; }

Property Value

ulong

State

Gets the channel's state.

public PacketChannelState State { get; }

Property Value

PacketChannelState

Remarks

It is Connected until it is disposed.

Traffic

Gets what the channel has sent and received.

public Traffic Traffic { get; }

Property Value

Traffic

Methods

DisposeAsync()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources asynchronously.

public ValueTask DisposeAsync()

Returns

ValueTask

A task that represents the asynchronous dispose operation.

Remarks

It disposes the channel at once: it has no connection to hand back.

DisposeManaged()

Releases managed resources; the base detaches the PacketReceived handlers. A derived class must catch its own errors.

protected override void DisposeManaged()

Remarks

It disposes the keys: a send or an open still running meets a disposed key and throws, rather than using a freed one.

GetRoute()

Gets where the channel's datagrams go now.

protected abstract UdpRoute? GetRoute()

Returns

UdpRoute

The route, or null for none.

Remarks

With none, or with a closed socket, the datagrams are lost, as on any UDP path, yet count as sent in the channel's stats.

HandUp(Memory<byte>)

Hands an opened payload's packets up to the tunnel, which keep the received array.

protected void HandUp(Memory<byte> payload)

Parameters

payload Memory<byte>

The opened payload: packets back to back.

Remarks

UDP has no backpressure, so a packet past the meter's receive limit is dropped, never waited on: on a server, one read loop serves every session. A packet message is dropped, as one is a channel's own and UDP has none.

Exceptions

ArgumentException

A packet is broken; the rest of the payload is lost.

NotSupportedException

A packet is neither IPv4 nor IPv6; the rest of the payload is lost.

ObjectDisposedException

The traffic meter is disposed.

Open(Span<byte>)

Opens a datagram of the session's in place.

protected ulong? Open(Span<byte> datagram)

Parameters

datagram Span<byte>

The datagram, at least a header long.

Returns

ulong?

Its sequence number, or null for a copy of one opened before, or one older than the replay window, whose packets must not go up again.

Remarks

Not thread-safe, as the key's context and the window are not: its callers serialize it.

Exceptions

ArgumentOutOfRangeException

datagram is shorter than a header.

AuthenticationTagMismatchException

The session's peer did not seal the datagram; nothing has read it, and the window is as it was.

SendPacketsAsync(IReadOnlyList<IpPacket>)

Sends a batch of packets: one packet in single mode. It runs on the sending loop, one batch at a time; in passthrough mode, on the sender's thread.

protected override ValueTask SendPacketsAsync(IReadOnlyList<IpPacket> ipPackets)

Parameters

ipPackets IReadOnlyList<IpPacket>

The batch. The list is reused after the call.

Returns

ValueTask

A task that represents the asynchronous operation.

Remarks

It must end once the transport is disposed. A throw counts the whole batch dropped and disposes it, except in passthrough mode without AutoDisposePackets, where the derived class disposes what it does not hand on; so it must not throw after handing a packet on. A packet it gives up without failing the batch, it reports with DropPacket(IpPacket), or the packet counts as sent. In passthrough mode it must complete at once and never send on its own transport.

Exceptions

ObjectDisposedException

The traffic meter is disposed.

Exception

The socket sent less than a whole datagram.

Start()

Starts the channel, which then reads from its peer.

public void Start()

Remarks

It does nothing: the channel carries packets from its creation.