| @@ -44,6 +44,7 @@ namespace Shadowsocks.Controller | |||||
| public Socket remote; | public Socket remote; | ||||
| public Socket connection; | public Socket connection; | ||||
| private byte command; | |||||
| private byte[] _firstPacket; | private byte[] _firstPacket; | ||||
| private int _firstPacketLength; | private int _firstPacketLength; | ||||
| // Size of receive buffer. | // Size of receive buffer. | ||||
| @@ -70,32 +71,7 @@ namespace Shadowsocks.Controller | |||||
| { | { | ||||
| this._firstPacket = firstPacket; | this._firstPacket = firstPacket; | ||||
| this._firstPacketLength = length; | this._firstPacketLength = length; | ||||
| try | |||||
| { | |||||
| // TODO async resolving | |||||
| IPAddress ipAddress; | |||||
| bool parsed = IPAddress.TryParse(server.server, out ipAddress); | |||||
| if (!parsed) | |||||
| { | |||||
| IPHostEntry ipHostInfo = Dns.GetHostEntry(server.server); | |||||
| ipAddress = ipHostInfo.AddressList[0]; | |||||
| } | |||||
| IPEndPoint remoteEP = new IPEndPoint(ipAddress, server.server_port); | |||||
| remote = new Socket(ipAddress.AddressFamily, | |||||
| SocketType.Stream, ProtocolType.Tcp); | |||||
| remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | |||||
| // Connect to the remote endpoint. | |||||
| remote.BeginConnect(remoteEP, | |||||
| new AsyncCallback(ConnectCallback), null); | |||||
| } | |||||
| catch (Exception e) | |||||
| { | |||||
| Logging.LogUsefulException(e); | |||||
| this.Close(); | |||||
| } | |||||
| this.HandshakeReceive(); | |||||
| } | } | ||||
| private void CheckClose() | private void CheckClose() | ||||
| @@ -149,28 +125,6 @@ namespace Shadowsocks.Controller | |||||
| } | } | ||||
| } | } | ||||
| private void ConnectCallback(IAsyncResult ar) | |||||
| { | |||||
| if (closed) | |||||
| { | |||||
| return; | |||||
| } | |||||
| try | |||||
| { | |||||
| // Complete the connection. | |||||
| remote.EndConnect(ar); | |||||
| //Console.WriteLine("Socket connected to {0}", | |||||
| // remote.RemoteEndPoint.ToString()); | |||||
| HandshakeReceive(); | |||||
| } | |||||
| catch (Exception e) | |||||
| { | |||||
| Logging.LogUsefulException(e); | |||||
| this.Close(); | |||||
| } | |||||
| } | |||||
| private void HandshakeReceive() | private void HandshakeReceive() | ||||
| { | { | ||||
| @@ -241,11 +195,12 @@ namespace Shadowsocks.Controller | |||||
| try | try | ||||
| { | { | ||||
| int bytesRead = connection.EndReceive(ar); | int bytesRead = connection.EndReceive(ar); | ||||
| if (bytesRead > 0) | |||||
| if (bytesRead >= 3) | |||||
| { | { | ||||
| command = connetionRecvBuffer[1]; | |||||
| byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 }; | byte[] response = { 5, 0, 0, 1, 0, 0, 0, 0, 0, 0 }; | ||||
| connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(StartPipe), null); | |||||
| connection.BeginSend(response, 0, response.Length, 0, new AsyncCallback(StartConnect), null); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| @@ -260,8 +215,62 @@ namespace Shadowsocks.Controller | |||||
| } | } | ||||
| } | } | ||||
| private void StartConnect(IAsyncResult ar) | |||||
| { | |||||
| try | |||||
| { | |||||
| connection.EndSend(ar); | |||||
| // TODO async resolving | |||||
| IPAddress ipAddress; | |||||
| bool parsed = IPAddress.TryParse(server.server, out ipAddress); | |||||
| if (!parsed) | |||||
| { | |||||
| IPHostEntry ipHostInfo = Dns.GetHostEntry(server.server); | |||||
| ipAddress = ipHostInfo.AddressList[0]; | |||||
| } | |||||
| IPEndPoint remoteEP = new IPEndPoint(ipAddress, server.server_port); | |||||
| remote = new Socket(ipAddress.AddressFamily, | |||||
| SocketType.Stream, ProtocolType.Tcp); | |||||
| remote.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true); | |||||
| // Connect to the remote endpoint. | |||||
| remote.BeginConnect(remoteEP, | |||||
| new AsyncCallback(ConnectCallback), null); | |||||
| } | |||||
| catch (Exception e) | |||||
| { | |||||
| Logging.LogUsefulException(e); | |||||
| this.Close(); | |||||
| } | |||||
| } | |||||
| private void ConnectCallback(IAsyncResult ar) | |||||
| { | |||||
| if (closed) | |||||
| { | |||||
| return; | |||||
| } | |||||
| try | |||||
| { | |||||
| // Complete the connection. | |||||
| remote.EndConnect(ar); | |||||
| //Console.WriteLine("Socket connected to {0}", | |||||
| // remote.RemoteEndPoint.ToString()); | |||||
| StartPipe(); | |||||
| } | |||||
| catch (Exception e) | |||||
| { | |||||
| Logging.LogUsefulException(e); | |||||
| this.Close(); | |||||
| } | |||||
| } | |||||
| private void StartPipe(IAsyncResult ar) | |||||
| private void StartPipe() | |||||
| { | { | ||||
| if (closed) | if (closed) | ||||
| { | { | ||||
| @@ -269,7 +278,6 @@ namespace Shadowsocks.Controller | |||||
| } | } | ||||
| try | try | ||||
| { | { | ||||
| connection.EndReceive(ar); | |||||
| remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, | remote.BeginReceive(remoteRecvBuffer, 0, RecvSize, 0, | ||||
| new AsyncCallback(PipeRemoteReceiveCallback), null); | new AsyncCallback(PipeRemoteReceiveCallback), null); | ||||
| connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, | connection.BeginReceive(connetionRecvBuffer, 0, RecvSize, 0, | ||||