123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- using System;
- using System.Diagnostics;
- using System.Linq;
- using System.Net;
- using System.Net.Sockets;
- using System.Text;
- using System.Threading;
- using System.Threading.Tasks;
- namespace TcpTunnel
- {
- internal class Program
- {
- private static void Main(string[] args)
- {
- //#if DEBUG
- // Debugger.Launch();
- // Debugger.Break();
- //#endif
- if (args.Length != 6)
- {
- Console.WriteLine($"Usage: <cl|sv> <token> <listenAddress> <listenPort> <targetHost> <targetPort>");
- return;
- }
- var isCl = args[0] == "cl";
- var token = args[1];
- if (!IPAddress.TryParse(args[2], out var listenAddress))
- {
- Console.WriteLine("invalid listen address");
- return;
- }
- if (!int.TryParse(args[3], out var listenPort))
- {
- Console.WriteLine("invalid listen port");
- return;
- }
- var targetHost = args[4];
- if (!int.TryParse(args[5], out var targetPort))
- {
- Console.WriteLine("invalid target port");
- return;
- }
- var listener = new TcpListener(listenAddress, listenPort);
- listener.Start(1);
- Console.WriteLine($"Listening on {listener.LocalEndpoint}");
- var connectionCount = 0;
- var tokenBuf = Encoding.UTF8.GetBytes(token);
- listener.BeginAcceptTcpClient(AsyncCallback, null);
- void AsyncCallback(IAsyncResult ar)
- {
- var cn = Interlocked.Increment(ref connectionCount);
- listener.BeginAcceptTcpClient(AsyncCallback, null);
- var ibClient = listener.EndAcceptTcpClient(ar);
- Console.WriteLine($"[#{cn:0000}]Income from {ibClient.Client.RemoteEndPoint}");
- var ibStream = ibClient.GetStream();
- NetworkStream obStream = null;
- TcpClient obClient = null;
- if (isCl)
- {
- Console.WriteLine($"[#{cn:0000}]Connecting to target...");
- obClient = new TcpClient(targetHost, targetPort);
- obStream = obClient.GetStream();
- Console.WriteLine($"[#{cn:0000}]Connected sending token...");
- obStream.WriteByte((byte)tokenBuf.Length);
- obStream.Write(tokenBuf, 0, tokenBuf.Length);
- }
- else
- {
- Console.WriteLine($"[#{cn:0000}]Checking token...");
- var tol = ibStream.ReadByte();
- if (tol != tokenBuf.Length)
- {
- Console.WriteLine($"[#{cn:0000}]Invalid token length closing");
- Thread.Sleep(1000);
- ibStream.Close();
- ibClient.Close();
- Console.WriteLine($"[#{cn:0000}]Invalid token length closed");
- return;
- }
- var buf = new byte[tol];
- ibStream.Read(buf, 0, tol);
- if (!buf.SequenceEqual(tokenBuf))
- {
- Console.WriteLine($"[#{cn:0000}]Invalid token closing");
- Thread.Sleep(1000);
- ibStream.Close();
- ibClient.Close();
- Console.WriteLine($"[#{cn:0000}]Invalid token closed");
- return;
- }
- Console.WriteLine($"[#{cn:0000}]Auth OK, Connecting to target...");
- obClient = new TcpClient(targetHost, targetPort);
- obStream = obClient.GetStream();
- }
- if (ibClient.Connected && obClient.Connected)
- {
- Console.WriteLine($"[#{cn:0000}]Start tunneling");
-
- ibClient.ReceiveTimeout = 120000;
- ibClient.SendTimeout = 120000;
- obClient.ReceiveTimeout = 120000;
- obClient.SendTimeout = 120000;
- var i2o = Task.Factory.StartNew(delegate { ibStream.CopyTo(obStream); });
- var o2i = Task.Factory.StartNew(delegate { obStream.CopyTo(ibStream); });
- Task.WaitAny(i2o, o2i);
- Console.WriteLine($"[#{cn:0000}]End tunnel");
- }
- else
- {
- Console.WriteLine($"[#{cn:0000}]No connected.");
- }
- ibClient?.Dispose();
- obClient?.Dispose();
- }
- Console.WriteLine("Press ENTER to Stop");
- Console.ReadLine();
- Console.WriteLine("Stopping...");
- listener.Stop();
- Console.WriteLine("Stopped,press ENTER to exit");
- Console.ReadLine();
- }
- }
- }
|