Table of Contents

Class DomainFilteringService

Namespace
VpnHood.Core.Filtering.DomainFiltering
Assembly
VpnHood.Core.Filtering.DomainFiltering.dll

Provides the client's filtering of flows by their domain names, which it reads from their TLS server names (SNI): a QUIC flow's from its first packets, and a TCP connection's from the first bytes of its stream.

public class DomainFilteringService : IDisposable
Inheritance
DomainFilteringService
Implements
Inherited Members

Remarks

A TCP connection's name comes after its handshake, too late to exclude it from its packets, so TCP is filtered by its stream alone, which the client's TCP forwarding hands over. The service filters nothing while IsEnabled is false.

Constructors

DomainFilteringService(IDomainFilter, EventId, int, bool)

Initializes a new instance of the DomainFilteringService class.

public DomainFilteringService(IDomainFilter domainFilter, EventId sniEventId, int tlsBufferSize, bool trackObservations = false)

Parameters

domainFilter IDomainFilter

The domain filter pipe that decides each name's verdict.

sniEventId EventId

The event ID of the log entries of the names found: each QUIC flow's, and each name the observer records.

tlsBufferSize int

The size of the one read that takes a TCP stream's first bytes, which must hold its TLS ClientHello.

trackObservations bool

true to record each name in DomainObserver.

Properties

DomainObserver

Gets the record of the domain names seen, which is kept only when the service was made to track them.

public DomainObserver DomainObserver { get; }

Property Value

DomainObserver

IsEnabled

Gets or sets a value indicating whether the service filters. The default is false.

public bool IsEnabled { get; set; }

Property Value

bool

QuicStat

Gets the counts of the QUIC flows whose name was found, by verdict.

public DomainObserverStat QuicStat { get; }

Property Value

DomainObserverStat

TcpStat

Gets the counts of the TCP connections whose name was found, by verdict.

public DomainObserverStat TcpStat { get; }

Property Value

DomainObserverStat

Methods

Dispose()

Releases the record of the QUIC flows.

public void Dispose()

ProcessPacket(IpPacket)

Decides what happens to a UDP packet by the server name of its QUIC flow, holding the flow's first packets back until the name is found or given up on.

public PacketSniFilterResult ProcessPacket(IpPacket ipPacket)

Parameters

ipPacket IpPacket

The packet the device sent.

Returns

PacketSniFilterResult

The verdict for the packet and for the flow's packets held before it, which the result releases; a result with NeedMore when the service holds the packet. A packet of another protocol, or any packet while the service is off, gets Default.

Remarks

A flow is known by the packet's source address and port alone, whatever its destination: once decided, its verdict answers every later packet from them, until a periodic sweep finds the flow unused for two minutes. A flow whose first packets are not QUIC gets Default. A held packet is the service's until a later result releases it: route nothing for a result that needs more, and route the released packets before the packet given. A flow forgotten with packets held leaves them undisposed.

A flow whose name is found counts in QuicStat, and is recorded in DomainObserver when the service tracks names.

Exceptions

ObjectDisposedException

The packet is disposed and the service is on, or the service is disposed and the packet is UDP while it is on.

InvalidDataException

The UDP packet is a fragment.

ArgumentException

The UDP packet is malformed.

ProcessStream(Stream, IPEndPoint, CancellationToken)

Decides what happens to a TCP connection by the server name in the TLS ClientHello its stream begins with.

public Task<StreamSniFilterResult> ProcessStream(Stream tlsStream, IPEndPoint remoteEndPoint, CancellationToken cancellationToken)

Parameters

tlsStream Stream

The connection's stream, from the device, not read yet.

remoteEndPoint IPEndPoint

The connection's destination, which is logged with the name when the service tracks names.

cancellationToken CancellationToken

The token to monitor for cancellation requests.

Returns

Task<StreamSniFilterResult>

A task whose result holds the verdict, the name, and the bytes read from the stream, which the caller must send on before the rest of it. While the service is off, nothing is read and the verdict is Default.

Remarks

It reads from the stream once, up to the buffer size the service was made with, and looks for the name in what that read returned: a stream with no name there, as when the ClientHello comes in pieces, gets the verdict of a null name. A name found counts in TcpStat, and is recorded in DomainObserver when the service tracks names.

Exceptions

OperationCanceledException

cancellationToken was canceled.

Events

IsEnabledChanged

Occurs when IsEnabled changes.

public event EventHandler? IsEnabledChanged

Event Type

EventHandler