public static int ProxyTCP(ProxyRequest pr) { Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { sock.Connect(pr.Target); } catch (SocketException ex) { #if DEBUG Console.WriteLine(ex); #endif pr.NetStream.Close(); return 1; } bool Lock = true; Thread inco = new Thread(() => passthrough(pr.NetStream, sock, ref Lock)); Thread outg = new Thread(() => passthrough(sock, pr.NetStream, ref Lock)); inco.Start(); outg.Start(); while (true) { if (!Lock) { inco.Abort(); outg.Abort(); pr.NetStream.Close(); sock.Close(); break; } Thread.Sleep(10); } return 0; }
private void ProcessConnection(Func<ProxyRequest, int> processTCPRequest, Func<string, bool> processAuthentication, Socket sock) { byte[] verinfo = new byte[2]; sock.Receive(verinfo); if (verinfo[0] != 0x04) { sock.Close(); return; } if (verinfo[1] != 0x01) { //Only support streams, not opening ports. sock.Close(); return; } byte[] portip = new byte[6]; byte[] bport = new byte[2]; byte[] bip = new byte[4]; sock.Receive(portip); Array.Copy(portip, bport, 2); Array.Copy(portip, 2, bip, 0, 4); if (BitConverter.IsLittleEndian) { Array.Reverse(bport); //Array.Reverse(bip); } int port = Convert.ToInt32(BitConverter.ToUInt16(bport, 0)); IPAddress ip = new IPAddress((long)BitConverter.ToUInt32(bip, 0)); List<byte> userid = new List<byte>(); while ((userid.Count == 0) || (userid[userid.Count - 1] != 0x00)) { byte[] temp = new byte[1]; sock.Receive(temp); userid.Add(temp[0]); } if (BitConverter.IsLittleEndian) userid.Reverse(); string user = System.Text.ASCIIEncoding.ASCII.GetString(userid.ToArray()); ProxyRequest pr = new ProxyRequest(user, ip, port, sock); //Begin validation and reply bool reject = false; byte[] message = new byte[8]; message[0] = 0x00; if (processAuthentication.Invoke(user)) message[1] = 0x5a; else { message[1] = 0x5b; reject = true; } //Why do we have to add gibberish that is ignored System.Text.ASCIIEncoding.ASCII.GetBytes("P0NIES").CopyTo(message, 2); sock.Send(message); #if DEBUG Console.WriteLine("New tunnel!"); Console.Write("\nPort/IP: "); foreach (byte b in portip) { Console.Write(b); Console.Write(" "); } Console.WriteLine(); Console.WriteLine(port); Console.WriteLine(BitConverter.ToUInt32(portip, 2)); Console.WriteLine(verinfo.Length + portip.Length); Console.WriteLine(reject); Console.Out.Flush(); #endif if (reject) sock.Close(); else processTCPRequest.Invoke(pr); }