Пример #1
0
        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
                }
            }
        }
Пример #3
0
        //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
                }
            }
        }