Table of Contents

Class PacketTransportBase

Namespace
VpnHood.Net.PacketTransports
Assembly
VpnHood.Net.PacketTransports.dll

Provides the send queue, the sending loop, the packet ownership rules and the counters every packet transport shares; a derived class sends the packets and raises the ones it receives.

public abstract class PacketTransportBase : IPacketTransport, IDisposable
Inheritance
PacketTransportBase
Implements
Derived
Inherited Members

Remarks

The transport takes every packet it is given. One it drops or refuses is disposed in any mode. One a send fails on or gives up (DropPacket(IpPacket)), or left in the queue at the end, is disposed too, except in a passthrough transport without AutoDisposePackets, whose derived class disposes what it does not hand on. One delivered is disposed with AutoDisposePackets. A full queue waits with Blocking, or drops its oldest packet. A sending loop that fails disposes the transport.

Constructors

PacketTransportBase(PacketTransportOptions, bool, bool)

Initializes the transport and, unless it is a passthrough one, starts its sending loop.

protected PacketTransportBase(PacketTransportOptions options, bool singleMode, bool passthrough)

Parameters

options PacketTransportOptions

The queue's capacity, blocking and packet disposal.

singleMode bool

true to send one packet per batch.

passthrough bool

true to queue nothing and send on the sender's thread; it needs single mode.

Exceptions

ArgumentException

passthrough is set without singleMode.

ArgumentOutOfRangeException

The blocking timeout is negative or too long, or the queue's capacity is not above zero.

Properties

IsDisposed

Gets a value indicating whether the transport is disposed.

protected bool IsDisposed { get; }

Property Value

bool

IsDisposing

Gets a value indicating whether the transport's disposal has begun; it stays set.

protected bool IsDisposing { get; }

Property Value

bool

IsSending

Gets a value indicating whether the transport has packets queued or a batch in flight.

public bool IsSending { get; }

Property Value

bool

IsSendingBatch

Gets a value indicating whether a batch is being sent now, for a stop that waits for it.

protected bool IsSendingBatch { get; }

Property Value

bool

Name

Gets the name the transport's log lines carry. The default is its type's name.

protected virtual string Name { get; }

Property Value

string

PacketStat

Gets the transport's counters: packets and bytes sent and received, drops, and the times of the last activity.

public ReadOnlyPacketTransportStat PacketStat { get; }

Property Value

ReadOnlyPacketTransportStat

QueueLength

Gets the number of packets waiting in the send queue.

public virtual int QueueLength { get; }

Property Value

int

Methods

Dispose()

Closes the send queue, which refuses later sends and releases waiting ones, then disposes the transport. Packets left in the queue are dropped and disposed by the sending loop, which may finish after this method returns. Calling it again does nothing.

public virtual void Dispose()

Dispose(bool)

Disposes the transport once: DisposeManaged() when disposing is set, then DisposeUnmanaged().

protected void Dispose(bool disposing)

Parameters

disposing bool

true when called from Dispose().

DisposeManaged()

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

protected virtual void DisposeManaged()

DisposeUnmanaged()

Releases unmanaged resources, such as native handles. A derived class must catch its own errors.

protected virtual void DisposeUnmanaged()

DropPacket(IpPacket)

Drops a packet of the batch being sent: counts it as dropped, not sent. It is for a send that gives a packet up without failing its batch, as when its device stays full.

protected void DropPacket(IpPacket ipPacket)

Parameters

ipPacket IpPacket

The packet.

Remarks

Call it only from SendPacketsAsync(IReadOnlyList<IpPacket>), once for a packet of its batch. The transport disposes the packet when the send returns, as it does a packet a send fails on; in a passthrough transport without AutoDisposePackets it does not, and the derived class disposes what it does not hand on.

LogPacket(IpPacket, LogLevel, Exception?, string, params object?[])

Logs a packet, but only when the logger writes trace lines: the packet path is too busy to log otherwise.

protected virtual void LogPacket(IpPacket ipPacket, LogLevel logLevel, Exception? exception, string message, params object?[] args)

Parameters

ipPacket IpPacket

The packet.

logLevel LogLevel

The level of the line.

exception Exception

The error, or null.

message string

The message.

args object[]

The message's arguments.

LogPacket(IpPacket, Exception, string)

Logs a packet at the error level, when the logger writes trace lines.

protected void LogPacket(IpPacket ipPacket, Exception exception, string message)

Parameters

ipPacket IpPacket

The packet.

exception Exception

The error.

message string

The message.

LogPacket(IpPacket, string)

Logs a packet at the trace level.

protected void LogPacket(IpPacket ipPacket, string message)

Parameters

ipPacket IpPacket

The packet.

message string

The message.

OnPacketReceived(IpPacket)

Counts a received packet and raises PacketReceived with it. A packet that cannot be delivered (the transport is disposed, no handler is attached, or the handler throws) is disposed.

protected virtual void OnPacketReceived(IpPacket ipPacket)

Parameters

ipPacket IpPacket

The packet, which the handler takes.

PreDispose()

Runs first in a disposal, after the queue is closed. A derived class stops its work here; it must catch its own errors, as a throw would skip the rest of the close.

protected virtual void PreDispose()

SendPacketQueued(IpPacket)

Queues a packet to send. The transport takes the packet whatever the outcome: it is never the caller's again.

public bool SendPacketQueued(IpPacket ipPacket)

Parameters

ipPacket IpPacket

The packet.

Returns

bool

true if the packet was queued, or sent; false if it was refused or dropped, and disposed.

Exceptions

ObjectDisposedException

The transport is disposed; the packet is disposed too.

InvalidOperationException

A passthrough transport's send did not complete at once.

SendPacketQueuedAsync(IpPacket)

Queues a packet to send, waiting without a thread for room when the queue is full and the transport blocks. The transport takes the packet whatever the outcome.

public ValueTask SendPacketQueuedAsync(IpPacket ipPacket)

Parameters

ipPacket IpPacket

The packet.

Returns

ValueTask

A task that represents the asynchronous operation. It completes when the packet is queued or dropped.

Exceptions

ObjectDisposedException

The transport is disposed; the packet is disposed too.

InvalidOperationException

A passthrough transport's send did not complete at once.

ChannelClosedException

The queue closed during the send, as the transport is being disposed; the packet is disposed too.

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 abstract 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.

Events

PacketReceived

Occurs when the transport receives a packet. The handler takes the packet: it delivers or disposes it, or throws to give it back to the transport, which disposes it. Attach one handler only: a second could see a packet the first one disposed or handed on.

public event EventHandler<IpPacket>? PacketReceived

Event Type

EventHandler<IpPacket>