using FastGithub.DomainResolve;
using Microsoft.AspNetCore.Connections;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace FastGithub.HttpServer
{
///
/// tcp反射代理处理者
///
abstract class TcpReverseProxyHandler : ConnectionHandler
{
private readonly IDomainResolver domainResolver;
private readonly DnsEndPoint endPoint;
///
/// tcp反射代理处理者
///
///
///
public TcpReverseProxyHandler(IDomainResolver domainResolver, DnsEndPoint endPoint)
{
this.domainResolver = domainResolver;
this.endPoint = endPoint;
}
///
/// ssh连接后
///
///
///
public override async Task OnConnectedAsync(ConnectionContext context)
{
var targetStream = await this.CreateConnectionAsync();
var task1 = targetStream.CopyToAsync(context.Transport.Output);
var task2 = context.Transport.Input.CopyToAsync(targetStream);
await Task.WhenAny(task1, task2);
}
///
/// 创建连接
///
///
///
private async Task CreateConnectionAsync()
{
var innerExceptions = new List();
await foreach (var address in this.domainResolver.ResolveAllAsync(this.endPoint))
{
var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
await socket.ConnectAsync(address, this.endPoint.Port);
return new NetworkStream(socket, ownsSocket: false);
}
catch (Exception ex)
{
socket.Dispose();
innerExceptions.Add(ex);
}
}
throw new AggregateException($"无法连接到{this.endPoint.Host}:{this.endPoint.Port}", innerExceptions);
}
}
}