public void GetHostEntryCallback(IAsyncResult ar) { try { DNSCbContext ct = (DNSCbContext)ar.AsyncState; IPHostEntry ipHostInfo = Dns.EndGetHostEntry(ar); IPAddress ipAddress = ipHostInfo.AddressList[0]; DNSCache.GetInstence().Put(ct.host, ipAddress); IPEndPoint remoteEP = new IPEndPoint(ipAddress, ct.port); remote = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); remote.BeginConnect(remoteEP, new AsyncCallback(remoteConnectCallback), null); } catch (Exception) { try { DNSCbContext ct = (DNSCbContext)ar.AsyncState; Console.WriteLine("Unknow Host " + ct.host); this.Close(); } catch (Exception) { //already recycle } } }
//Single thread private void handshakeReceiveCallback(IAsyncResult ar) { //this check is moved to except //try //{ // //already recycle // lock (this) // { // if (closed) // return; // } //} //catch (Exception) //{ // return; //} try { int bytesRead = connection.EndReceive(ar); if (bytesRead == 0) { throw new Exception("Error When handshakeReceiveCallback"); } //Console.WriteLine("bytesRead" + bytesRead.ToString() + " stage" + stage.ToString()); if (stage == 0) { //recv numbers of ivlen data byte[] iv = encryptor.Decrypt(this.connetionBuffer, bytesRead); //Decrypt sucessful //iv stage = 1; connection.BeginReceive(this.connetionBuffer, 0, 1, 0, new AsyncCallback(handshakeReceiveCallback), null); } else if (stage == 1) { byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); //Decrypt sucessful //addrtype char addrtype = (char)buff[0]; if (addrtype == 1) { //type of ipv4 stage = 4; connection.BeginReceive(this.connetionBuffer, 0, 4, 0, new AsyncCallback(handshakeReceiveCallback), addrtype); } else if (addrtype == 3) { //type of url stage = 3; connection.BeginReceive(this.connetionBuffer, 0, 1, 0, new AsyncCallback(handshakeReceiveCallback), addrtype); } else if (addrtype == 4) { //type of ipv6 stage = 4; connection.BeginReceive(this.connetionBuffer, 0, 16, 0, new AsyncCallback(handshakeReceiveCallback), addrtype); } else { throw new Exception("Error Socket5 AddrType"); } } else if (stage == 3) { //addr len byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); stage = 4; //recv addr connection.BeginReceive(this.connetionBuffer, 0, buff[0], 0, new AsyncCallback(handshakeReceiveCallback), ar.AsyncState); } else if (stage == 4) { //addr byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); if (1 == (char)ar.AsyncState) { //ipv4 destAddr = string.Format("{0:D}.{1:D}.{2:D}.{3:D}", buff[0], buff[1], buff[2], buff[3]); } else if (3 == (char)ar.AsyncState) { //ipv6 url destAddr = ASCIIEncoding.Default.GetString(buff); } else { //url destAddr = string.Format("[{0:x2}{1:x2}:{2:x2}{3:x2}:{4:x2}{5:x2}:{6:x2}{7:x2}:{8:x2}{9:x2}:{10:x2}{11:x2}:{12:x2}{13:x2}:{14:x2}{15:x2}]" , buff[0], buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7], buff[8], buff[9], buff[10], buff[11], buff[12], buff[13], buff[14], buff[15]); } stage = 5; //recv port connection.BeginReceive(this.connetionBuffer, 0, 2, 0, new AsyncCallback(handshakeReceiveCallback), null); } else if (stage == 5) { //port byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); int port = (int)(buff[0] << 8) + (int)buff[1]; stage = 6; //handshake completed lock (timeOutTimer) { this.timeOutTimer.Dispose(); timeOutTimer = null; } //Begin to connect remote IPAddress ipAddress; bool parsed = IPAddress.TryParse(destAddr, out ipAddress); if (!parsed) { IPAddress cache_ipAddress = DNSCache.GetInstence().Get(destAddr); if (cache_ipAddress == null) { DNSCbContext ct = new DNSCbContext(destAddr, port); Dns.BeginGetHostEntry(destAddr, new AsyncCallback(GetHostEntryCallback), ct); return; } ipAddress = cache_ipAddress; } IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); remote = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); remote.BeginConnect(remoteEP, new AsyncCallback(remoteConnectCallback), null); } } catch (Exception e) { try { //handshake time out lock (timeOutTimer) { if (timeOutTimer != null) this.timeOutTimer.Dispose(); timeOutTimer = null; } Console.WriteLine(e.ToString()); this.Close(); } catch(Exception) { //already recycle } } }
//Single thread private void handshakeReceiveCallback(IAsyncResult ar) { //this check is moved to except //try //{ // //already recycle // lock (this) // { // if (closed) // return; // } //} //catch (Exception) //{ // return; //} try { int bytesRead = connection.EndReceive(ar); if (bytesRead == 0) { throw new Exception("Error When handshakeReceiveCallback"); } //Console.WriteLine("bytesRead" + bytesRead.ToString() + " stage" + stage.ToString()); if (stage == 0) { //recv numbers of ivlen data byte[] iv = encryptor.Decrypt(this.connetionBuffer, bytesRead); //Decrypt sucessful //iv stage = 1; connection.BeginReceive(this.connetionBuffer, 0, 1, 0, new AsyncCallback(handshakeReceiveCallback), null); } else if (stage == 1) { byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); //Decrypt sucessful //addrtype char addrtype = (char)buff[0]; if (addrtype == 1) { //type of ipv4 stage = 4; connection.BeginReceive(this.connetionBuffer, 0, 4, 0, new AsyncCallback(handshakeReceiveCallback), addrtype); } else if (addrtype == 3) { //type of url stage = 3; connection.BeginReceive(this.connetionBuffer, 0, 1, 0, new AsyncCallback(handshakeReceiveCallback), addrtype); } else if (addrtype == 4) { //type of ipv6 stage = 4; connection.BeginReceive(this.connetionBuffer, 0, 16, 0, new AsyncCallback(handshakeReceiveCallback), addrtype); } else { throw new Exception("Error Socket5 AddrType"); } } else if (stage == 3) { //addr len byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); stage = 4; //recv addr connection.BeginReceive(this.connetionBuffer, 0, buff[0], 0, new AsyncCallback(handshakeReceiveCallback), ar.AsyncState); } else if (stage == 4) { //addr byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); if (1 == (char)ar.AsyncState) { //ipv4 destAddr = string.Format("{0:D}.{1:D}.{2:D}.{3:D}", buff[0], buff[1], buff[2], buff[3]); } else if (3 == (char)ar.AsyncState) { //ipv6 url destAddr = ASCIIEncoding.Default.GetString(buff); } else { //url destAddr = string.Format("[{0:x2}{1:x2}:{2:x2}{3:x2}:{4:x2}{5:x2}:{6:x2}{7:x2}:{8:x2}{9:x2}:{10:x2}{11:x2}:{12:x2}{13:x2}:{14:x2}{15:x2}]" , buff[0], buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7], buff[8], buff[9], buff[10], buff[11], buff[12], buff[13], buff[14], buff[15]); } stage = 5; //recv port connection.BeginReceive(this.connetionBuffer, 0, 2, 0, new AsyncCallback(handshakeReceiveCallback), null); } else if (stage == 5) { //port byte[] buff = encryptor.Decrypt(this.connetionBuffer, bytesRead); int port = (int)(buff[0] << 8) + (int)buff[1]; stage = 6; //handshake completed lock (timeOutTimer) { this.timeOutTimer.Dispose(); timeOutTimer = null; } //Begin to connect remote IPAddress ipAddress; bool parsed = IPAddress.TryParse(destAddr, out ipAddress); if (!parsed) { IPAddress cache_ipAddress = DNSCache.GetInstence().Get(destAddr); if (cache_ipAddress == null) { DNSCbContext ct = new DNSCbContext(destAddr, port); Dns.BeginGetHostEntry(destAddr, new AsyncCallback(GetHostEntryCallback), ct); return; } ipAddress = cache_ipAddress; } IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); remote = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); remote.BeginConnect(remoteEP, new AsyncCallback(remoteConnectCallback), null); } } catch (Exception e) { try { //handshake time out lock (timeOutTimer) { if (timeOutTimer != null) { this.timeOutTimer.Dispose(); } timeOutTimer = null; } Console.WriteLine(e.ToString()); this.Close(); } catch (Exception) { //already recycle } } }