From 257a1ada1fed91c0cca59b6af76e7ced5d212524 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 14 Jan 2013 15:52:54 +0800 Subject: [PATCH] add local --- LICENSE | 24 +++ shadowsocks-csharp/Encryptor.cs | 8 +- shadowsocks-csharp/Local.cs | 278 +++++++++++++++++++++++++++ shadowsocks-csharp/Program.cs | 2 +- shadowsocks-csharp/shadowsocks-csharp.csproj | 4 +- 5 files changed, 310 insertions(+), 6 deletions(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..45e39ea6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +shadowsocks-csharp + +Copyright (c) 2013 clowwindy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + + diff --git a/shadowsocks-csharp/Encryptor.cs b/shadowsocks-csharp/Encryptor.cs index 903461f4..ddce03c3 100755 --- a/shadowsocks-csharp/Encryptor.cs +++ b/shadowsocks-csharp/Encryptor.cs @@ -75,16 +75,16 @@ namespace shadowsocks_csharp } } - public void Encrypt(byte[] buf) + public void Encrypt(byte[] buf, int length) { - for (int i = 0; i < buf.Length; i++) + for (int i = 0; i < length; i++) { buf[i] = encryptTable[buf[i]]; } } - public void Decrypt(byte[] buf) + public void Decrypt(byte[] buf, int length) { - for (int i = 0; i < buf.Length; i++) + for (int i = 0; i < length; i++) { buf[i] = decryptTable[buf[i]]; } diff --git a/shadowsocks-csharp/Local.cs b/shadowsocks-csharp/Local.cs index 9046b57d..14dd7eab 100755 --- a/shadowsocks-csharp/Local.cs +++ b/shadowsocks-csharp/Local.cs @@ -2,10 +2,288 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Net.Sockets; +using System.Net; +using System.Threading; namespace shadowsocks_csharp { + + class Local { + private int port; + private Encryptor encryptor; + public Local(int port) + { + this.port = port; + this.encryptor = new Encryptor("barfoo!"); + } + + public void Start() + { + + // Create a TCP/IP socket. + Socket listener = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, ProtocolType.Tcp); + IPEndPoint localEndPoint = new IPEndPoint(0, port); + + // Bind the socket to the local endpoint and listen for incoming connections. + listener.Bind(localEndPoint); + listener.Listen(100); + + + // Start an asynchronous socket to listen for connections. + Console.WriteLine("Waiting for a connection..."); + listener.BeginAccept( + new AsyncCallback(AcceptCallback), + listener); + + } + + + public void AcceptCallback(IAsyncResult ar) + { + + // Get the socket that handles the client request. + Socket listener = (Socket)ar.AsyncState; + listener.BeginAccept( + new AsyncCallback(AcceptCallback), + listener); + + Socket conn = listener.EndAccept(ar); + + // Create the state object. + Handler handler = new Handler(); + handler.connection = conn; + handler.encryptor = encryptor; + + handler.Start(); + //handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, + // new AsyncCallback(ReadCallback), state); + } + + } + + class Handler + { + public Encryptor encryptor; + // Client socket. + public Socket remote; + public Socket connection; + // Size of receive buffer. + public const int BufferSize = 1500; + // remote receive buffer + public byte[] remoteBuffer = new byte[BufferSize]; + // connection receive buffer + public byte[] connetionBuffer = new byte[BufferSize]; + // Received data string. + public StringBuilder sb = new StringBuilder(); + + public void Start() + { + // TODO async resolving + IPHostEntry ipHostInfo = Dns.GetHostEntry("127.0.0.1"); + IPAddress ipAddress = ipHostInfo.AddressList[0]; + IPEndPoint remoteEP = new IPEndPoint(ipAddress, 8388); + + + remote = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, ProtocolType.Tcp); + + // Connect to the remote endpoint. + remote.BeginConnect(remoteEP, + new AsyncCallback(connectCallback), null); + } + + private void connectCallback(IAsyncResult ar) + { + try + { + // Complete the connection. + remote.EndConnect(ar); + + Console.WriteLine("Socket connected to {0}", + remote.RemoteEndPoint.ToString()); + Console.WriteLine(Thread.CurrentThread.ManagedThreadId); + + handshakeReceive(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void handshakeReceive() + { + try + { + connection.BeginReceive(new byte[256], 0, 256, 0, + new AsyncCallback(handshakeReceiveCallback), null); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void handshakeReceiveCallback(IAsyncResult ar) + { + try + { + int bytesRead = connection.EndReceive(ar); + + if (bytesRead > 0) + { + byte[] response = { 5, 0 }; + connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(handshakeSendCallback), null); + } + else + { + // TODO error + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void handshakeSendCallback(IAsyncResult ar) + { + try + { + connection.EndSend(ar); + + // +----+-----+-------+------+----------+----------+ + // |VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT | + // +----+-----+-------+------+----------+----------+ + // | 1 | 1 | X'00' | 1 | Variable | 2 | + // +----+-----+-------+------+----------+----------+ + // Skip first 3 bytes + // TODO validate + connection.BeginReceive(new byte[3], 0, 3, 0, + new AsyncCallback(handshakeReceive2Callback), null); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void handshakeReceive2Callback(IAsyncResult ar) + { + try + { + int bytesRead = connection.EndReceive(ar); + + if (bytesRead > 0) + { + byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 }; + connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(startPipe), null); + } + else + { + // TODO error + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + + private void startPipe(IAsyncResult ar) + { + try + { + connection.EndReceive(ar); + remote.BeginReceive(remoteBuffer, 0, BufferSize, 0, + new AsyncCallback(pipeRemoteReceiveCallback), null); + connection.BeginReceive(connetionBuffer, 0, BufferSize, 0, + new AsyncCallback(pipeConnectionReceiveCallback), null); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void pipeRemoteReceiveCallback(IAsyncResult ar) + { + + try + { + int bytesRead = remote.EndReceive(ar); + + if (bytesRead > 0) + { + encryptor.Decrypt(remoteBuffer, bytesRead); + connection.BeginSend(remoteBuffer, 0, bytesRead, 0, new AsyncCallback(pipeConnectionSendCallback), null); + } + else + { + // TODO error + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void pipeConnectionReceiveCallback(IAsyncResult ar) + { + + try + { + int bytesRead = connection.EndReceive(ar); + + if (bytesRead > 0) + { + encryptor.Encrypt(connetionBuffer, bytesRead); + remote.BeginSend(connetionBuffer, 0, bytesRead, 0, new AsyncCallback(pipeRemoteSendCallback), null); + } + else + { + // TODO error + } + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void pipeRemoteSendCallback(IAsyncResult ar) + { + try + { + remote.EndSend(ar); + connection.BeginReceive(this.connetionBuffer, 0, BufferSize, 0, + new AsyncCallback(pipeConnectionReceiveCallback), null); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } + + private void pipeConnectionSendCallback(IAsyncResult ar) + { + try + { + connection.EndSend(ar); + remote.BeginReceive(this.remoteBuffer, 0, BufferSize, 0, + new AsyncCallback(pipeRemoteReceiveCallback), null); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + } } + } diff --git a/shadowsocks-csharp/Program.cs b/shadowsocks-csharp/Program.cs index 5da1a70e..d21d81aa 100755 --- a/shadowsocks-csharp/Program.cs +++ b/shadowsocks-csharp/Program.cs @@ -13,7 +13,7 @@ namespace shadowsocks_csharp [STAThread] static void Main() { - Test.Test1(); + new Local(1081).Start(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index f6fc3c58..09d36023 100755 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -6,12 +6,14 @@ 9.0.21022 2.0 {8C02D2F7-7CDB-4D55-9F25-CD03EF4AA062} - WinExe + Exe Properties shadowsocks_csharp shadowsocks-csharp v3.5 512 + + true