using System.Net.Sockets; using LumaTunnel.Client.Core.Abstractions; using LumaTunnel.Shared.Models; namespace LumaTunnel.Client.Core.Networking; public sealed class DirectConnector(TimeSpan? connectTimeout = null) : IProxyConnector { private readonly TimeSpan _connectTimeout = connectTimeout ?? TimeSpan.FromSeconds(10); public async ValueTask ConnectAsync(ProxyTarget target, CancellationToken cancellationToken = default) { var client = new TcpClient { NoDelay = true }; try { using var timeout = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); timeout.CancelAfter(_connectTimeout); await client.ConnectAsync(target.Host, target.Port, timeout.Token).ConfigureAwait(false); return new OwnedTcpStream(client); } catch { client.Dispose(); throw; } } }