TcpReverseProxyHandler.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using FastGithub.DomainResolve;
  2. using Microsoft.AspNetCore.Connections;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.IO.Pipelines;
  7. using System.Net;
  8. using System.Net.Sockets;
  9. using System.Threading.Tasks;
  10. namespace FastGithub.HttpServer
  11. {
  12. /// <summary>
  13. /// tcp反射代理处理者
  14. /// </summary>
  15. abstract class TcpReverseProxyHandler : ConnectionHandler
  16. {
  17. private readonly IDomainResolver domainResolver;
  18. private readonly DnsEndPoint endPoint;
  19. /// <summary>
  20. /// tcp反射代理处理者
  21. /// </summary>
  22. /// <param name="domainResolver"></param>
  23. /// <param name="endPoint"></param>
  24. public TcpReverseProxyHandler(IDomainResolver domainResolver, DnsEndPoint endPoint)
  25. {
  26. this.domainResolver = domainResolver;
  27. this.endPoint = endPoint;
  28. }
  29. /// <summary>
  30. /// ssh连接后
  31. /// </summary>
  32. /// <param name="context"></param>
  33. /// <returns></returns>
  34. public override async Task OnConnectedAsync(ConnectionContext context)
  35. {
  36. var targetStream = await this.CreateConnectionAsync();
  37. var task1 = targetStream.CopyToAsync(context.Transport.Output);
  38. var task2 = context.Transport.Input.CopyToAsync(targetStream);
  39. await Task.WhenAny(task1, task2);
  40. }
  41. /// <summary>
  42. /// 创建连接
  43. /// </summary>
  44. /// <returns></returns>
  45. /// <exception cref="AggregateException"></exception>
  46. private async Task<Stream> CreateConnectionAsync()
  47. {
  48. var innerExceptions = new List<Exception>();
  49. await foreach (var address in this.domainResolver.ResolveAllAsync(this.endPoint))
  50. {
  51. var socket = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
  52. try
  53. {
  54. await socket.ConnectAsync(address, this.endPoint.Port);
  55. return new NetworkStream(socket, ownsSocket: false);
  56. }
  57. catch (Exception ex)
  58. {
  59. socket.Dispose();
  60. innerExceptions.Add(ex);
  61. }
  62. }
  63. throw new AggregateException($"无法连接到{this.endPoint.Host}:{this.endPoint.Port}", innerExceptions);
  64. }
  65. }
  66. }