示例#1
0
        private void PipeConnectionReceiveCallback(IAsyncResult ar)
        {
            if (_closed)
            {
                return;
            }
            try
            {
                if (connection == null)
                {
                    return;
                }
                int bytesRead = connection.EndReceive(ar);
                _totalWrite += bytesRead;
                if (bytesRead > 0)
                {
                    int    atyp = _connetionRecvBuffer[0];
                    string dst_addr;
                    int    dst_port;
                    switch (atyp)
                    {
                    case 1:      // IPv4 address, 4 bytes
                        dst_addr = new IPAddress(_connetionRecvBuffer.Skip(1).Take(4).ToArray()).ToString();
                        dst_port = (_connetionRecvBuffer[5] << 8) + _connetionRecvBuffer[6];
                        if (_config.isVerboseLogging)
                        {
                            Logging.Info($"connect to {dst_addr}:{dst_port}");
                        }
                        break;

                    case 3:      // domain name, length + str
                        int len = _connetionRecvBuffer[1];
                        dst_addr = System.Text.Encoding.UTF8.GetString(_connetionRecvBuffer, 2, len);
                        dst_port = (_connetionRecvBuffer[len + 2] << 8) + _connetionRecvBuffer[len + 3];
                        if (_config.isVerboseLogging)
                        {
                            Logging.Info($"connect to {dst_addr}:{dst_port}");
                        }
                        break;

                    case 4:      // IPv6 address, 16 bytes
                        dst_addr = new IPAddress(_connetionRecvBuffer.Skip(1).Take(16).ToArray()).ToString();
                        dst_port = (_connetionRecvBuffer[17] << 8) + _connetionRecvBuffer[18];
                        if (_config.isVerboseLogging)
                        {
                            Logging.Info($"connect to [{dst_addr}]:{dst_port}");
                        }
                        break;
                    }
                    int bytesToSend;
                    lock (_encryptionLock)
                    {
                        if (_closed)
                        {
                            return;
                        }
                        encryptor.Encrypt(_connetionRecvBuffer, bytesRead, _connetionSendBuffer, out bytesToSend);
                    }
                    _tcprelay.UpdateOutboundCounter(server, bytesToSend);
                    _startSendingTime = DateTime.Now;
                    _bytesToSend      = bytesToSend;
                    remote.BeginSend(_connetionSendBuffer, 0, bytesToSend, SocketFlags.None, new AsyncCallback(PipeRemoteSendCallback), null);
                    IStrategy strategy = controller.GetCurrentStrategy();
                    strategy?.UpdateLastWrite(server);
                }
                else
                {
                    remote.Shutdown(SocketShutdown.Send);
                    _remoteShutdown = true;
                    CheckClose();
                }
            }
            catch (Exception e)
            {
                Logging.LogUsefulException(e);
                Close();
            }
        }