Program.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Net.Sockets;
  6. using System.Text;
  7. using System.Threading;
  8. using System.Threading.Tasks;
  9. namespace TcpTunnel
  10. {
  11. internal class Program
  12. {
  13. private static void Main(string[] args)
  14. {
  15. //#if DEBUG
  16. // Debugger.Launch();
  17. // Debugger.Break();
  18. //#endif
  19. if (args.Length != 6)
  20. {
  21. Console.WriteLine($"Usage: <cl|sv> <token> <listenAddress> <listenPort> <targetHost> <targetPort>");
  22. return;
  23. }
  24. var isCl = args[0] == "cl";
  25. var token = args[1];
  26. if (!IPAddress.TryParse(args[2], out var listenAddress))
  27. {
  28. Console.WriteLine("invalid listen address");
  29. return;
  30. }
  31. if (!int.TryParse(args[3], out var listenPort))
  32. {
  33. Console.WriteLine("invalid listen port");
  34. return;
  35. }
  36. var targetHost = args[4];
  37. if (!int.TryParse(args[5], out var targetPort))
  38. {
  39. Console.WriteLine("invalid target port");
  40. return;
  41. }
  42. var listener = new TcpListener(listenAddress, listenPort);
  43. listener.Start(1);
  44. Console.WriteLine($"Listening on {listener.LocalEndpoint}");
  45. var connectionCount = 0;
  46. var tokenBuf = Encoding.UTF8.GetBytes(token);
  47. listener.BeginAcceptTcpClient(AsyncCallback, null);
  48. void AsyncCallback(IAsyncResult ar)
  49. {
  50. var cn = Interlocked.Increment(ref connectionCount);
  51. listener.BeginAcceptTcpClient(AsyncCallback, null);
  52. var ibClient = listener.EndAcceptTcpClient(ar);
  53. Console.WriteLine($"[#{cn:0000}]Income from {ibClient.Client.RemoteEndPoint}");
  54. var ibStream = ibClient.GetStream();
  55. NetworkStream obStream = null;
  56. TcpClient obClient = null;
  57. if (isCl)
  58. {
  59. Console.WriteLine($"[#{cn:0000}]Connecting to target...");
  60. obClient = new TcpClient(targetHost, targetPort);
  61. obStream = obClient.GetStream();
  62. Console.WriteLine($"[#{cn:0000}]Connected sending token...");
  63. obStream.WriteByte((byte)tokenBuf.Length);
  64. obStream.Write(tokenBuf, 0, tokenBuf.Length);
  65. }
  66. else
  67. {
  68. Console.WriteLine($"[#{cn:0000}]Checking token...");
  69. var tol = ibStream.ReadByte();
  70. if (tol != tokenBuf.Length)
  71. {
  72. Console.WriteLine($"[#{cn:0000}]Invalid token length closing");
  73. Thread.Sleep(1000);
  74. ibStream.Close();
  75. ibClient.Close();
  76. Console.WriteLine($"[#{cn:0000}]Invalid token length closed");
  77. return;
  78. }
  79. var buf = new byte[tol];
  80. ibStream.Read(buf, 0, tol);
  81. if (!buf.SequenceEqual(tokenBuf))
  82. {
  83. Console.WriteLine($"[#{cn:0000}]Invalid token closing");
  84. Thread.Sleep(1000);
  85. ibStream.Close();
  86. ibClient.Close();
  87. Console.WriteLine($"[#{cn:0000}]Invalid token closed");
  88. return;
  89. }
  90. Console.WriteLine($"[#{cn:0000}]Auth OK, Connecting to target...");
  91. obClient = new TcpClient(targetHost, targetPort);
  92. obStream = obClient.GetStream();
  93. }
  94. if (ibClient.Connected && obClient.Connected)
  95. {
  96. Console.WriteLine($"[#{cn:0000}]Start tunneling");
  97. ibClient.ReceiveTimeout = 120000;
  98. ibClient.SendTimeout = 120000;
  99. obClient.ReceiveTimeout = 120000;
  100. obClient.SendTimeout = 120000;
  101. var i2o = Task.Factory.StartNew(delegate { ibStream.CopyTo(obStream); });
  102. var o2i = Task.Factory.StartNew(delegate { obStream.CopyTo(ibStream); });
  103. Task.WaitAny(i2o, o2i);
  104. Console.WriteLine($"[#{cn:0000}]End tunnel");
  105. }
  106. else
  107. {
  108. Console.WriteLine($"[#{cn:0000}]No connected.");
  109. }
  110. ibClient?.Dispose();
  111. obClient?.Dispose();
  112. }
  113. Console.WriteLine("Press ENTER to Stop");
  114. Console.ReadLine();
  115. Console.WriteLine("Stopping...");
  116. listener.Stop();
  117. Console.WriteLine("Stopped,press ENTER to exit");
  118. Console.ReadLine();
  119. }
  120. }
  121. }