Class ManagedProxyConnector
- Namespace
- VpnHood.Core.Proxies.Management
- Assembly
- VpnHood.Core.Proxies.Management.dll
Provides the VPN's connections through a managed list of proxies, kept in an IProxyEndPointStore: it rates the endpoints by their successes and failures, rotates them, checks them, and may update the list from a URL.
public class ManagedProxyConnector : IProxyConnector, IAsyncDisposable
- Inheritance
-
ManagedProxyConnector
- Implements
- Inherited Members
Remarks
A connection tries the enabled endpoints in turn, the one whose turn comes soonest first: an endpoint's next turn moves back by 3 for each point of its penalty. While any endpoint succeeded last, only the first of those that did not keeps its place, and the rest go to the end. When the first endpoint in that order did not succeed last, the endpoints are checked first: the unrated ones all, the others until one succeeds.
A check connects through each enabled endpoint, up to 50 at a time, to 1.1.1.1:443, with
VerifyTls also through a TLS handshake with one.one.one.one, and records each
outcome; once 10 have succeeded, it checks only those never rated. An endpoint whose check fails with a
ProxyClientException of ProtocolNotSupported
or AccessDenied, as an AuthenticationException
in the check's TLS handshake becomes, is disabled. The statuses are saved to the store every 10 seconds, after a check, and at the disposal.
Properties
IsEnabled
Gets a value indicating whether the connector has a proxy to connect through.
public bool IsEnabled { get; }
Property Value
Progress
Gets the progress of a check of the endpoints under way, or null.
public ProgressStatus? Progress { get; }
Property Value
Status
Gets the connector's state, made at each read.
public ProxyConnectorStatus Status { get; }
Property Value
UseRecentSucceeded
Gets or sets a value indicating whether connections use only the endpoints that have succeeded since the connector was made, where there is a list to choose from.
public bool UseRecentSucceeded { get; set; }
Property Value
Methods
CheckServers(ISocketFactory, CancellationToken)
Checks the endpoints, where the connector has a list to check, and records what it finds.
public Task CheckServers(ISocketFactory socketFactory, CancellationToken cancellationToken)
Parameters
socketFactoryISocketFactoryThe factory of the sockets to the proxies, which keeps them out of the tunnel.
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
- Task
A task that represents the asynchronous operation.
Remarks
It checks the enabled endpoints, the best first, and skips the rest of those already rated once 10 have succeeded; see the class's remarks. What it recorded is saved even when it is canceled. The update from a URL checks with the last factory a caller gave.
Exceptions
- OperationCanceledException
cancellationTokenwas canceled.
ConnectAsync(ISocketFactory, IPEndPoint, Action?, CancellationToken)
Connects to an endpoint through a proxy.
public Task<TcpClient> ConnectAsync(ISocketFactory socketFactory, IPEndPoint ipEndPoint, Action? onAttempt, CancellationToken cancellationToken)
Parameters
socketFactoryISocketFactoryThe factory of the sockets to the proxies: the caller's, which keeps them out of the tunnel.
ipEndPointIPEndPointThe endpoint to reach through the proxy.
onAttemptActionCalled after each proxy the connector tried, or null.
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
- Task<TcpClient>
A task whose result is the connection, through the proxy, which the caller owns. Its stream is the raw TCP one, not an HTTPS proxy's TLS tunnel.
Remarks
One connection at a time chooses its order, and waits for the check that runs when the first endpoint did not
succeed last. Each success and failure is recorded, and reported to onAttempt; a failure taken
for the caller's cancellation, any OperationCanceledException within the check timeout, is
neither, and a cancellation during the last attempt ends in the SocketException. With
RemoveDuplicateIps, a success disables the other endpoints of its host and
protocol among those the connection could choose. The connector keeps the last socket factory for its checks.
Exceptions
- SocketException
No endpoint could connect, with NetworkUnreachable.
- ObjectDisposedException
The connector was disposed.
- OperationCanceledException
cancellationTokenwas canceled.
Create(ProxyOptions, IProxyEndPointStore, TimeSpan?, CancellationToken)
Creates a connector with its endpoints already loaded from the store, so IsEnabled and Status hold from the start, and starts its update from a URL where the options ask for one.
public static Task<ManagedProxyConnector> Create(ProxyOptions proxyOptions, IProxyEndPointStore store, TimeSpan? serverCheckTimeout, CancellationToken cancellationToken)
Parameters
proxyOptionsProxyOptionsThe options; with ResetStates, the stored statuses are cleared first, which logs a failure rather than throwing it.
storeIProxyEndPointStoreThe store of the endpoints, which the connector disposes with itself.
serverCheckTimeoutTimeSpan?How long a check of an endpoint may take, or null for 7 seconds.
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
- Task<ManagedProxyConnector>
A task whose result is the connector.
Exceptions
- OperationCanceledException
cancellationTokenwas canceled.
DisposeAsync()
Stops the update and the saving, saves the statuses not saved yet, logging a failure, and disposes the store.
public ValueTask DisposeAsync()
Returns
- ValueTask
A task that represents the asynchronous operation.
Flush(CancellationToken)
Saves the endpoints' statuses not saved yet, where the connector keeps any.
public Task Flush(CancellationToken cancellationToken)
Parameters
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
- Task
A task that represents the asynchronous operation.
Remarks
It saves the changed statuses and enabled states, and the queue position.
Exceptions
- OperationCanceledException
cancellationTokenwas canceled.
GetEndPointInfos()
Gets the endpoints the connector holds, with their statuses.
public IReadOnlyList<ProxyEndPointInfo> GetEndPointInfos()
Returns
- IReadOnlyList<ProxyEndPointInfo>
The connector's own endpoint and status objects, which later connections update.
RecordFailed(TcpClient, Exception)
Records a failure of a connection ConnectAsync(ISocketFactory, IPEndPoint, Action?, CancellationToken) made, after it was made, as in a TLS handshake over it, against the proxy that made it.
public void RecordFailed(TcpClient tcpClient, Exception ex)
Parameters
Remarks
It counts once per connection: the endpoint's success is taken back and a failure recorded. A connection it did not hand out changes nothing; for an OperationCanceledException within the check timeout after the connection was made, the connection is forgotten with no failure recorded.
UpdateOptions(ProxyOptions, CancellationToken)
Takes new options.
public Task UpdateOptions(ProxyOptions proxyOptions, CancellationToken cancellationToken)
Parameters
proxyOptionsProxyOptionsThe options.
cancellationTokenCancellationTokenThe token to monitor for cancellation requests.
Returns
- Task
A task that represents the asynchronous operation.
Remarks
It saves the statuses not saved yet, or, with ResetStates, clears the stored ones instead, then loads the endpoints from the store again. The update from a URL starts again, with a download at once, only when its URL or interval changed.
Exceptions
- OperationCanceledException
cancellationTokenwas canceled.