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
optionsPacketTransportOptionsThe queue's capacity, blocking and packet disposal.
singleModebooltrue to send one packet per batch.
passthroughbooltrue to queue nothing and send on the sender's thread; it needs single mode.
Exceptions
- ArgumentException
passthroughis set withoutsingleMode.- 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
IsDisposing
Gets a value indicating whether the transport's disposal has begun; it stays set.
protected bool IsDisposing { get; }
Property Value
IsSending
Gets a value indicating whether the transport has packets queued or a batch in flight.
public bool IsSending { get; }
Property Value
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
Name
Gets the name the transport's log lines carry. The default is its type's name.
protected virtual string Name { get; }
Property Value
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
QueueLength
Gets the number of packets waiting in the send queue.
public virtual int QueueLength { get; }
Property Value
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
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
ipPacketIpPacketThe 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
ipPacketIpPacketThe packet.
logLevelLogLevelThe level of the line.
exceptionExceptionThe error, or null.
messagestringThe message.
argsobject[]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
LogPacket(IpPacket, string)
Logs a packet at the trace level.
protected void LogPacket(IpPacket ipPacket, string message)
Parameters
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
ipPacketIpPacketThe 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
ipPacketIpPacketThe packet.
Returns
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
ipPacketIpPacketThe 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
ipPacketsIReadOnlyList<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