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
domainFilterIDomainFilterThe domain filter pipe that decides each name's verdict.
sniEventIdEventIdThe event ID of the log entries of the names found: each QUIC flow's, and each name the observer records.
tlsBufferSizeintThe size of the one read that takes a TCP stream's first bytes, which must hold its TLS ClientHello.
trackObservationsbooltrue 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
IsEnabled
Gets or sets a value indicating whether the service filters. The default is false.
public bool IsEnabled { get; set; }
Property Value
QuicStat
Gets the counts of the QUIC flows whose name was found, by verdict.
public DomainObserverStat QuicStat { get; }
Property Value
TcpStat
Gets the counts of the TCP connections whose name was found, by verdict.
public DomainObserverStat TcpStat { get; }
Property Value
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
ipPacketIpPacketThe 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
tlsStreamStreamThe connection's stream, from the device, not read yet.
remoteEndPointIPEndPointThe connection's destination, which is logged with the name when the service tracks names.
cancellationTokenCancellationTokenThe 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
cancellationTokenwas canceled.
Events
IsEnabledChanged
Occurs when IsEnabled changes.
public event EventHandler? IsEnabledChanged