State information that is used during ReceiveCommandResponse()'s async operations
Example #1
0
        //
        // I/O callback methods
        //

        /// <summary>
        ///    <para>Provides a wrapper for the async operations, so that the code can be shared with sync</para>
        /// </summary>
        private static void ReadCallback(IAsyncResult asyncResult)
        {
            ReceiveState state = (ReceiveState)asyncResult.AsyncState;

            try {
                Stream stream    = (Stream)state.Connection;
                int    bytesRead = 0;
                try {
                    bytesRead = stream.EndRead(asyncResult);
                    if (bytesRead == 0)
                    {
                        state.Connection.CloseSocket();
                    }
                }
                catch (IOException) {
                    state.Connection.MarkAsRecoverableFailure();
                    throw;
                }
                catch {
                    throw;
                }

                state.Connection.ReceiveCommandResponseCallback(state, bytesRead);
            } catch (Exception e) {
                state.Connection.Abort(e);
            }
        }
Example #2
0
        void OnAccept(IAsyncResult asyncResult)
        {
            Socket clientSocket = null;
            try
            {
                clientSocket = listenSocket.EndAccept(asyncResult);

                // Wait for next client
                this.listenSocket.BeginAccept(OnAccept, null);

                IPEndPoint clientIp = (IPEndPoint)clientSocket.RemoteEndPoint;
                Console.WriteLine("Connection from {0}.{1}", clientIp.Address, clientIp.Port);
                ReceiveState receiveState = new ReceiveState
                {
                    ClientSocket = clientSocket,
                    Buffer = new byte[4],
                    Offset = 0,
                    Count = 4,
                    ReceivingLength = true,
                };
                clientSocket.BeginReceive(receiveState.Buffer, 0, 4, SocketFlags.None, OnReceive, receiveState);
            }
            catch (ObjectDisposedException)
            {
                // socket closed
            }
            catch (SocketException e)
            {
                Console.WriteLine("Socket exception: {0}", e);
            }
        }
Example #3
0
        /// <summary>
        /// Kicks off an asynchronous or sync request to receive a response from the server.
        /// Uses the Encoding <code>encoding</code> to transform the bytes received into a string to be
        /// returned in the GeneralResponseDescription's StatusDescription field.
        /// </summary>
        private ResponseDescription ReceiveCommandResponse()
        {
            // These are the things that will be needed to maintain state.
            ReceiveState state = new ReceiveState(this);

            try
            {
                // If a string of nonzero length was decoded from the buffered bytes after the last complete response, then we
                // will use this string as our first string to append to the response StatusBuffer, and we will
                // forego a Connection.Receive here.
                if (_buffer.Length > 0)
                {
                    ReceiveCommandResponseCallback(state, -1);
                }
                else
                {
                    int bytesRead;

                    try
                    {
                        if (_isAsync)
                        {
                            BeginRead(state.Buffer, 0, state.Buffer.Length, s_readCallbackDelegate, state);
                            return(null);
                        }
                        else
                        {
                            bytesRead = Read(state.Buffer, 0, state.Buffer.Length);
                            if (bytesRead == 0)
                            {
                                CloseSocket();
                            }
                            ReceiveCommandResponseCallback(state, bytesRead);
                        }
                    }
                    catch (IOException)
                    {
                        MarkAsRecoverableFailure();
                        throw;
                    }
                    catch
                    {
                        throw;
                    }
                }
            }
            catch (Exception e)
            {
                if (e is WebException)
                {
                    throw;
                }
                throw GenerateException(SR.net_ftp_receivefailure, WebExceptionStatus.ReceiveFailure, e);
            }
            return(state.Resp);
        }
Example #4
0
        private ResponseDescription ReceiveCommandResponse()
        {
            ReceiveState state = new ReceiveState(this);

            try
            {
                if (this.m_Buffer.Length > 0)
                {
                    this.ReceiveCommandResponseCallback(state, -1);
                }
                else
                {
                    try
                    {
                        if (this.m_Async)
                        {
                            this.BeginRead(state.Buffer, 0, state.Buffer.Length, m_ReadCallbackDelegate, state);
                            return(null);
                        }
                        int bytesRead = this.Read(state.Buffer, 0, state.Buffer.Length);
                        if (bytesRead == 0)
                        {
                            base.CloseSocket();
                        }
                        this.ReceiveCommandResponseCallback(state, bytesRead);
                    }
                    catch (IOException)
                    {
                        this.MarkAsRecoverableFailure();
                        throw;
                    }
                    catch
                    {
                        throw;
                    }
                }
            }
            catch (Exception exception)
            {
                if (exception is WebException)
                {
                    throw;
                }
                throw this.GenerateException(WebExceptionStatus.ReceiveFailure, exception);
            }
            return(state.Resp);
        }
        public void BeginHandling()
        {
            send = new SocketAsyncEventArgs();
            send.Completed += IOCompleted;
            send.UserToken = new SendToken();
            //send.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE);

            var receive = new SocketAsyncEventArgs();
            receive.Completed += IOCompleted;
            receive.UserToken = new ReceiveToken();
            receive.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE);

            receiveState = ReceiveState.ReceivingHdr;
            receive.SetBuffer(0, 5);
            if (!skt.ReceiveAsync(receive))
                IOCompleted(this, receive);
        }
        public void BeginHandling()
        {
            skt.NoDelay = true;
            skt.UseOnlyOverlappedIO = true;

            send = new SocketAsyncEventArgs();
            send.Completed += SendCompleted;
            send.UserToken = new SendToken();
            send.SetBuffer(sendBuff = new byte[BUFFER_SIZE], 0, BUFFER_SIZE);

            receive = new SocketAsyncEventArgs();
            receive.Completed += ReceiveCompleted;
            receive.UserToken = new ReceiveToken();
            receive.SetBuffer(receiveBuff = new byte[BUFFER_SIZE], 0, BUFFER_SIZE);

            receiveState = ReceiveState.ReceivingHdr;
            receive.SetBuffer(0, 5);
            if (!skt.ReceiveAsync(receive))
                ReceiveCompleted(this, receive);
        }
Example #7
0
        public void BeginHandling()
        {
            logger.InfoFormat("{0} connected.", skt.RemoteEndPoint);

            skt.NoDelay = true;
            skt.UseOnlyOverlappedIO = true;

            send = new SocketAsyncEventArgs();
            send.Completed += IOCompleted;
            send.UserToken = new SendToken();
            send.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE);

            var receive = new SocketAsyncEventArgs();
            receive.Completed += IOCompleted;
            receive.UserToken = new ReceiveToken();
            receive.SetBuffer(new byte[BUFFER_SIZE], 0, BUFFER_SIZE);

            receiveState = ReceiveState.ReceivingHdr;
            receive.SetBuffer(0, 5);
            if (!skt.ReceiveAsync(receive))
                IOCompleted(this, receive);
        }
Example #8
0
        /// <summary>
        /// Kicks off an asynchronous or sync request to receive a response from the server.
        /// Uses the Encoding <code>encoding</code> to transform the bytes received into a string to be
        /// returned in the GeneralResponseDescription's StatusDescription field.
        /// </summary>
        private ResponseDescription ReceiveCommandResponse()
        {
            // These are the things that will be needed to maintain state.
            ReceiveState state = new ReceiveState(this);

            try
            {
                // If a string of nonzero length was decoded from the buffered bytes after the last complete response, then we
                // will use this string as our first string to append to the response StatusBuffer, and we will
                // forego a Connection.Receive here.
                if (_buffer.Length > 0)
                {
                    ReceiveCommandResponseCallback(state, -1);
                }
                else
                {
                    int bytesRead;

                    try
                    {
                        if (_isAsync)
                        {
                            BeginRead(state.Buffer, 0, state.Buffer.Length, s_readCallbackDelegate, state);
                            return null;
                        }
                        else
                        {
                            bytesRead = Read(state.Buffer, 0, state.Buffer.Length);
                            if (bytesRead == 0)
                                CloseSocket();
                            ReceiveCommandResponseCallback(state, bytesRead);
                        }
                    }
                    catch (IOException)
                    {
                        MarkAsRecoverableFailure();
                        throw;
                    }
                    catch
                    {
                        throw;
                    }
                }
            }
            catch (Exception e)
            {
                if (e is WebException)
                    throw;
                throw GenerateException(SR.net_ftp_receivefailure, WebExceptionStatus.ReceiveFailure, e);
            }
            return state.Resp;
        }
Example #9
0
        void receiveLength(ReceiveState state)
        {
            int offset = state == null ? 0 : 1;

            state = state == null ? new ReceiveState() : state;

            _socket.BeginReceive(state.len,
                                 offset,
                                 2 - offset,
                                 SocketFlags.None,
                                 _receiveCallback,
                                 state);            
        }
Example #10
0
        void ReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                bool repeat;
                do
                {
                    repeat = false;

                    if (e.SocketError != SocketError.Success)
                        throw new SocketException((int)e.SocketError);

                    switch (receiveState)
                    {
                        case ReceiveState.ReceivingHdr:
                            if (e.BytesTransferred < 5)
                            {
                                parent.Disconnect();
                                return;
                            }

                            if (e.Buffer[0] == 0x3c && e.Buffer[1] == 0x70 &&
                                e.Buffer[2] == 0x6f && e.Buffer[3] == 0x6c && e.Buffer[4] == 0x69)
                            {
                                ProcessPolicyFile();
                                return;
                            }

                            var len = (e.UserToken as ReceiveToken).Length =
                                IPAddress.NetworkToHostOrder(BitConverter.ToInt32(e.Buffer, 0)) - 5;
                            if (len < 0 || len > BUFFER_SIZE)
                                throw new InternalBufferOverflowException();
                            (e.UserToken as ReceiveToken).Packet = Packet.Packets[(PacketID)e.Buffer[4]].CreateInstance();

                            receiveState = ReceiveState.ReceivingBody;
                            e.SetBuffer(0, len);
                            if (!skt.ReceiveAsync(e))
                            {
                                repeat = true;
                                continue;
                            }
                            break;
                        case ReceiveState.ReceivingBody:
                            if (e.BytesTransferred < (e.UserToken as ReceiveToken).Length)
                            {
                                parent.Disconnect();
                                return;
                            }

                            var pkt = (e.UserToken as ReceiveToken).Packet;
                            pkt.Read(parent, e.Buffer, 0, (e.UserToken as ReceiveToken).Length);

                            receiveState = ReceiveState.Processing;
                            bool cont = OnPacketReceived(pkt);

                            if (cont && skt.Connected)
                            {
                                receiveState = ReceiveState.ReceivingHdr;
                                e.SetBuffer(0, 5);
                                if (!skt.ReceiveAsync(e))
                                {
                                    repeat = true;
                                    continue;
                                }
                            }
                            break;
                        default:
                            throw new InvalidOperationException(e.LastOperation.ToString());
                    }
                } while (repeat);
            }
            catch (Exception ex)
            {
                OnError(ex);
            }
        }
Example #11
0
        /// <summary>
        /// Initiate method for asynchronous receive operation of payload data in "payload-aware" mode.
        /// </summary>
        private void ReceivePayloadAwareAsync(ReceiveState receiveState)
        {
            int length;

            if (!receiveState.Token.Cancelled)
            {
                if (receiveState.PayloadLength < 0)
                    length = m_payloadMarker.Length + Payload.LengthSegment;
                else
                    length = receiveState.PayloadLength;

                if (receiveState.Buffer != receiveState.ReceiveArgs.Buffer)
                    receiveState.ReceiveArgs.SetBuffer(receiveState.Buffer, 0, length);
                else
                    receiveState.ReceiveArgs.SetBuffer(receiveState.Offset, length - receiveState.Offset);

                if (!receiveState.Socket.ReceiveAsync(receiveState.ReceiveArgs))
                    ThreadPool.QueueUserWorkItem(state => ProcessReceivePayloadAware(receiveState));
            }
        }
Example #12
0
        void receiveLength(ReceiveState state)
        {
            if (_closing || _disposed)
                return;

            int offset = state == null ? 0 : 1;

            state = state == null ? new ReceiveState() : state;

            _stream.BeginRead(state.len,
                              offset,
                              2 - offset,
                              _receiveCallback,
                              state);            
        }
 private ResponseDescription ReceiveCommandResponse()
 {
     ReceiveState state = new ReceiveState(this);
     try
     {
         if (this.m_Buffer.Length > 0)
         {
             this.ReceiveCommandResponseCallback(state, -1);
         }
         else
         {
             try
             {
                 if (this.m_Async)
                 {
                     this.BeginRead(state.Buffer, 0, state.Buffer.Length, m_ReadCallbackDelegate, state);
                     return null;
                 }
                 int bytesRead = this.Read(state.Buffer, 0, state.Buffer.Length);
                 if (bytesRead == 0)
                 {
                     base.CloseSocket();
                 }
                 this.ReceiveCommandResponseCallback(state, bytesRead);
             }
             catch (IOException)
             {
                 this.MarkAsRecoverableFailure();
                 throw;
             }
             catch
             {
                 throw;
             }
         }
     }
     catch (Exception exception)
     {
         if (exception is WebException)
         {
             throw;
         }
         throw this.GenerateException(WebExceptionStatus.ReceiveFailure, exception);
     }
     return state.Resp;
 }
Example #14
0
        /// <summary>
        /// Kicks off an asynchronous or sync request to receive a response from the server.
        /// Uses the Encoding <code>encoding</code> to transform the bytes received into a string to be
        /// returned in the GeneralResponseDescription's StatusDescription field.
        /// </summary>
        private ResponseDescription ReceiveCommandResponse()
        {
            // These are the things that will be needed to maintain state
            ReceiveState state = new ReceiveState(this);

            // If there are any bytes left over in the buffer, then attempt to form a string out of the bytes remaining, decoding it
            // into a string using the implementor's encoding.
            if (m_BufferCount > 0)
            {
                state.StringFromBuffer = Encoding.GetString(m_Buffer, m_BufferOffset, m_BufferCount);
            }
            try
            {
                // If a string of nonzero length was decoded from the buffered bytes, then we
                // will use this string as our first string to append to the response StatusBuffer, and we will
                // forego a Connection.Receive here.

                // Note that we get the number of bytes in the byte encoding of the decoded string, in order to determine
                // how many bytes were used in the string.  The number of bytes left in the buffer is decremented by this
                // amount (this will usually mean buffer count goes to zero) and increment the buffer offset to indicate
                // that there are a few buffer bytes left over.
                if (state.StringFromBuffer.Length > 0)
                {
                    int bytesUsed = Encoding.GetByteCount(state.StringFromBuffer);
                    m_BufferCount  -= bytesUsed;
                    m_BufferOffset += bytesUsed;
                    ReceiveCommandResponseCallback(state, -1);
                }
                else
                {
                    int bytesRead;
                    int readOffset = 0;
                    int readLength = state.Buffer.Length;

                    // we didn't get anything out of the buffer -
                    // this means that either the only contents of the buffer were less than a complete character in the encoding,
                    // or that there was nothing in the buffer at all.
                    if (m_BufferCount > 0)
                    {
                        // if there was anything in the buffer, then the buffer contents represent a partial character in the encoding used.
                        // This means that in order to get anything productive done, we need to perform a Receive on the connection in order
                        // to finish at least one character to send to CheckValid.
                        // So copy the remaining contents of the buffer into the beginning of the receive buffer (state.Buffer).
                        // Then try to fill the rest of the buffer with a receive.

                        Buffer.BlockCopy(m_Buffer, m_BufferOffset, state.Buffer, 0, m_BufferCount);
                        state.BytesInBuffer = m_BufferCount;

                        readOffset = m_BufferCount;
                        readLength = state.Buffer.Length - readOffset;

                        m_BufferCount = 0; // buffer is flushed.
                    }


                    try {
                        if (m_Async)
                        {
                            BeginRead(state.Buffer, readOffset, readLength, m_ReadCallbackDelegate, state);
                            return(null);
                        }
                        else
                        {
                            bytesRead = Read(state.Buffer, readOffset, readLength);
                            if (bytesRead == 0)
                            {
                                CloseSocket();
                            }
                            ReceiveCommandResponseCallback(state, bytesRead);
                        }
                    }
                    catch (IOException) {
                        MarkAsRecoverableFailure();
                        throw;
                    }
                    catch {
                        throw;
                    }
                }
            }
            catch (Exception e) {
                if (e is WebException)
                {
                    throw;
                }
                throw GenerateException(WebExceptionStatus.ReceiveFailure, e);
            }
            return(state.Resp);
        }
Example #15
0
        private void ReceiveMessageLength(IAsyncResult ar)
        {
            var receiveState = ar.AsyncState.CastObj<ReceiveState>();
            var connectedSocket = receiveState.ConnectedSocket;
            if (!StillConnected(connectedSocket)) return;

            var bytesReceived = connectedSocket.EndReceive(ar);
            if (bytesReceived == 0) throw new Exception("Nothing received");
            if (bytesReceived != 4) throw new Exception("Cannot receive message size");

            var messageSize = BitConverter.ToInt32(receiveState.Buffer, 0);

            var buffer = new byte[messageSize];
            var nextReceiveState = new ReceiveState
                                       {
                                           Buffer = buffer,
                                           ConnectedSocket = connectedSocket
                                       };
            connectedSocket.BeginReceive(buffer, 0, buffer.Length, 0, ReceiveMessage, nextReceiveState);
        }
 private void Receive(ReceiveState st)
 {
     try
     {
         //_log.Debug("MockTcpServer.Receive: Wait for data from Socket connection");
         st.socket.BeginReceive(st.buffer, 0, ReceiveState.BufferSize, SocketFlags.None, (ar) => {
             ReceiveState state = (ReceiveState)ar.AsyncState;
             int received = state.socket.EndReceive(ar);
             //_log.Debug(string.Format("MockTcpServer.Receive: Read {0} from Socket connection", received));
             if (received > 0)
             {
                 state.message.AddRange(state.buffer.Take(received).ToList());
                 Receive(state); // read the remaining
             }
             else
             {
                 //_log.Debug("MockTcpServer.Receive: Read message from Socket connection");
                 Received.Add(state.message.ToArray());
                 Receive(new ReceiveState(state.socket));
             }
         }, st);
     }
     catch { }
 }
Example #17
0
        //It is said that ReceiveAsync/SendAsync never returns false unless error
        //So...let's just treat it as always true

        void ReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                if (!skt.Connected) return;

                if (e.SocketError != SocketError.Success)
                    throw new SocketException((int)e.SocketError);

                switch (receiveState)
                {
                    case ReceiveState.ReceivingHdr:
                        if (e.BytesTransferred < 5)
                        {
                            parent.Disconnect();
                            return;
                        }

                        if (e.Buffer[0] == 0x3c && e.Buffer[1] == 0x70 &&
                            e.Buffer[2] == 0x6f && e.Buffer[3] == 0x6c && e.Buffer[4] == 0x69)
                        {
                            ProcessPolicyFile();
                            return;
                        }

                        var len = (e.UserToken as ReceiveToken).Length =
                            IPAddress.NetworkToHostOrder(BitConverter.ToInt32(e.Buffer, 0)) - 5;
                        if (len < 0 || len > BUFFER_SIZE)
                            log.ErrorFormat("Buffer not large enough! (requested size={0})", len);
                        (e.UserToken as ReceiveToken).PacketBody = new byte[len];
                        (e.UserToken as ReceiveToken).ID = (PacketID)e.Buffer[4];

                        receiveState = ReceiveState.ReceivingBody;
                        e.SetBuffer(0, len);
                        skt.ReceiveAsync(e);

                        break;
                    case ReceiveState.ReceivingBody:
                        if (e.BytesTransferred < (e.UserToken as ReceiveToken).Length)
                        {
                            parent.Disconnect();
                            return;
                        }

                        var body = (e.UserToken as ReceiveToken).PacketBody;
                        var id = (e.UserToken as ReceiveToken).ID;
                        Buffer.BlockCopy(e.Buffer, 0, body, 0, body.Length);
                        //pkt.Read(parent, e.Buffer, 0, (e.UserToken as ReceiveToken).Length);

                        receiveState = ReceiveState.Processing;
                        bool cont = OnPacketReceived(id, body);

                        if (cont && skt.Connected)
                        {
                            receiveState = ReceiveState.ReceivingHdr;
                            e.SetBuffer(0, 5);
                            skt.ReceiveAsync(e);
                        }
                        break;
                    default:
                        throw new InvalidOperationException(e.LastOperation.ToString());
                }
            }
            catch (Exception ex)
            {
                OnError(ex);
            }
        }
Example #18
0
 private void Receive(Socket socket)
 {
     var buffer = new byte[4];
     var receiveState = new ReceiveState
                            {
                                Buffer = buffer,
                                ConnectedSocket = socket
                            };
     socket.BeginReceive(buffer, 0, buffer.Length, 0, ReceiveMessageLength, receiveState);
 }
Example #19
0
 public void AddEdge(TcpEdge e) {
   Socket s = e.Socket;
   AllSockets.Add(s); 
   ReceiveState rs = new ReceiveState(e, BA);
   _sock_to_rs[s] = rs;
   Interlocked.Increment(ref TEL._count);
 }
        Task<byte[]> DoReceive(ReceiveState state = null)
        {
            try
            {
                if (_socket == null)
                    return Task<byte[]>.FromResult(new byte[]{});

                if (state == null)
                    state = new ReceiveState(_socket);
                _socket.BeginReceive(state.buffer, 0, ReceiveState.BufferSize, 0, (ar) => {
                    try
                    {
                        ReceiveState st = (ReceiveState)ar.AsyncState;
                        var t = st.Task;
                        var s = (Socket)t.Task.AsyncState;
                        try
                        {
                            int received = st.socket.EndReceive(ar);
                            if (received > 0)
                            {
                                RaiseDebug("AsyncSocketClient: Received {0}", received);
                                state.message.AddRange(st.buffer.Take(received).ToList());
                            }
                            if (received < ReceiveState.BufferSize)
                            {
                                var data = st.message.ToArray();
                                t.TrySetResult(data);
                                if (data.Length > 0)
                                {
                                    RaiseDebug("AsyncSocketClient: Received message {0}", data.Length);
                                    RaiseReceivedData(data, data.Length);
                                }
                            }
                            else
                            {
                                DoReceive(state).Wait(); // read the remaining
                            }
                        }
                        catch (Exception exc)
                        {
                            RaiseError(exc);
                            t.TrySetException(exc);
                        }
                    }
                    catch (Exception ex)
                    {
                        RaiseError(ex);
                    }
                }, state);
                return state.Task.Task;
            }
            catch (Exception ex)
            {
                RaiseError(ex);
                return Task<byte[]>.FromResult(new byte[] { });
            }
        }
Example #21
0
        void receive(ReceiveState state)
        {
            if (_closing || _disposed)
                return;

            _stream.BeginRead(state.data,
                              state.offset,
                              state.length - state.offset,
                              _receiveCallback,
                              state);            
        }
Example #22
0
        /// <summary>
        /// ReceiveCommandResponseCallback is the main "while loop" of the ReceiveCommandResponse function family.
        /// In general, what is does is perform an EndReceive() to complete the previous retrieval of bytes from the
        /// server (unless it is using a buffered response)  It then processes what is received by using the
        /// implementing class's CheckValid() function, as described above. If the response is complete, it returns the single complete
        /// response in the GeneralResponseDescription created in BeginReceiveComamndResponse, and buffers the rest as described above.
        ///
        /// If the response is not complete, it issues another Connection.BeginReceive, with callback ReceiveCommandResponse2,
        /// so the action will continue at the next invocation of ReceiveCommandResponse2.
        /// </summary>
        private void ReceiveCommandResponseCallback(ReceiveState state, int bytesRead)
        {
            // completeLength will be set to a nonnegative number by CheckValid if the response is complete:
            // it will set completeLength to the length of a complete response.
            int completeLength = -1;

            while (true)
            {
                int validThrough = state.ValidThrough; // passed to checkvalid

                // If we have a Buffered response (ie data was received with the last response that was past the end of that response)
                // deal with it as if we had just received it now instead of actually doing another receive
                if (_buffer.Length > 0)
                {
                    // Append the string we got from the buffer, and flush it out.
                    state.Resp.StatusBuffer.Append(_buffer);
                    _buffer = string.Empty;

                    // invoke checkvalid.
                    if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
                    {
                        throw GenerateException(SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
                    }
                }
                else // we did a Connection.BeginReceive.  Note that in this case, all bytes received are in the receive buffer (because bytes from
                     // the buffer were transferred there if necessary
                {
                    // this indicates the connection was closed.
                    if (bytesRead <= 0)
                    {
                        throw GenerateException(SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
                    }

                    // decode the bytes in the receive buffer into a string, append it to the statusbuffer, and invoke checkvalid.
                    // Decoder automatically takes care of caching partial codepoints at the end of a buffer.

                    char[] chars = new char[_decoder.GetCharCount(state.Buffer, 0, bytesRead)];
                    int numChars = _decoder.GetChars(state.Buffer, 0, bytesRead, chars, 0, false);

                    string szResponse = new string(chars, 0, numChars);

                    state.Resp.StatusBuffer.Append(szResponse);
                    if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
                    {
                        throw GenerateException(SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
                    }

                    // If the response is complete, then determine how many characters are left over...these bytes need to be set into Buffer.
                    if (completeLength >= 0)
                    {
                        int unusedChars = state.Resp.StatusBuffer.Length - completeLength;
                        if (unusedChars > 0)
                        {
                            _buffer = szResponse.Substring(szResponse.Length - unusedChars, unusedChars);
                        }
                    }
                }

                // Now, in general, if the response is not complete, update the "valid through" length for the efficiency of checkValid,
                // and perform the next receive.
                // Note that there may NOT be bytes in the beginning of the receive buffer (even if there were partial characters left over after the
                // last encoding), because they get tracked in the Decoder.
                if (completeLength < 0)
                {
                    state.ValidThrough = validThrough;
                    try
                    {
                        if (_isAsync)
                        {
                            BeginRead(state.Buffer, 0, state.Buffer.Length, s_readCallbackDelegate, state);
                            return;
                        }
                        else
                        {
                            bytesRead = Read(state.Buffer, 0, state.Buffer.Length);
                            if (bytesRead == 0)
                                CloseSocket();
                            continue;
                        }
                    }
                    catch (IOException)
                    {
                        MarkAsRecoverableFailure();
                        throw;
                    }
                    catch
                    {
                        throw;
                    }
                }

                // The response is completed
                break;
            }

            // Otherwise, we have a complete response.
            string responseString = state.Resp.StatusBuffer.ToString();
            state.Resp.StatusDescription = responseString.Substring(0, completeLength);
            // Set the StatusDescription to the complete part of the response.  Note that the Buffer has already been taken care of above.

            if (NetEventSource.Log.IsEnabled())
                NetEventSource.PrintInfo(NetEventSource.ComponentType.Web, this, string.Format("Received response: {0}", responseString.Substring(0, completeLength - 2)));

            if (_isAsync)
            {
                // Tell who is listening what was received.
                if (state.Resp != null)
                {
                    _currentResponseDescription = state.Resp;
                }
                Stream stream = null;
                if (PostReadCommandProcessing(ref stream))
                    return;
                ContinueCommandPipeline();
            }
        }
        void IOCompleted(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                bool repeat;
                do
                {
                    repeat = false;

                    if (e.SocketError != SocketError.Success)
                        throw new SocketException((int)e.SocketError);

                    if (e.LastOperation == SocketAsyncOperation.Receive)
                    {
                        switch (receiveState)
                        {
                            case ReceiveState.ReceivingHdr:
                                if (e.BytesTransferred < 5)
                                {
                                    parent.Disconnect();
                                    return;
                                }

                                var len = (e.UserToken as ReceiveToken).Length =
                                    IPAddress.NetworkToHostOrder(BitConverter.ToInt32(e.Buffer, 0)) - 5;
                                if (len < 0 || len > BUFFER_SIZE)
                                    throw new InternalBufferOverflowException();
                                (e.UserToken as ReceiveToken).Packet = Packet.Packets[(PacketID)e.Buffer[4]].CreateInstance();

                                receiveState = ReceiveState.ReceivingBody;
                                e.SetBuffer(0, len);
                                if (!skt.ReceiveAsync(e))
                                {
                                    repeat = true;
                                    continue;
                                }
                                break;
                            case ReceiveState.ReceivingBody:
                                if (e.BytesTransferred < (e.UserToken as ReceiveToken).Length)
                                {
                                    parent.Disconnect();
                                    return;
                                }

                                var pkt = (e.UserToken as ReceiveToken).Packet;
                                pkt.Read(parent, e.Buffer, (e.UserToken as ReceiveToken).Length);

                                receiveState = ReceiveState.Processing;
                                bool cont = OnPacketReceived(pkt);

                                if (cont)
                                {
                                    receiveState = ReceiveState.ReceivingHdr;
                                    e.SetBuffer(0, 5);
                                    if (!skt.ReceiveAsync(e))
                                    {
                                        repeat = true;
                                        continue;
                                    }
                                }
                                break;
                            default:
                                throw new InvalidOperationException(e.LastOperation.ToString());
                        }
                    }
                    else if (e.LastOperation == SocketAsyncOperation.Send)
                    {
                        switch (sendState)
                        {
                            case SendState.Ready:
                                var dat = (e.UserToken as SendToken).Packet.Write(parent);

                                sendState = SendState.Sending;
                                e.SetBuffer(dat, 0, dat.Length);
                                if (!skt.SendAsync(e))
                                {
                                    repeat = true;
                                    continue;
                                }
                                break;
                            case SendState.Sending:
                                (e.UserToken as SendToken).Packet = null;

                                if (CanSendPacket(e,true))
                                {
                                    repeat = true;
                                    continue;
                                }
                                break;
                            default:
                                throw new InvalidOperationException(e.LastOperation.ToString());
                        }
                    }
                    else
                        throw new InvalidOperationException(e.LastOperation.ToString());
                } while (repeat);
            }
            catch (Exception ex)
            {
                OnError(ex);
            }
        }
        //It is said that ReceiveAsync/SendAsync never returns false unless error
        //So...let's just treat it as always true
        private void ReceiveCompleted(object sender, SocketAsyncEventArgs e)
        {
            try
            {
                if (!skt.Connected)
                {
                    parent.Disconnect();
                    return;
                }

                if (e.SocketError != SocketError.Success)
                    throw new SocketException((int) e.SocketError);

                switch (receiveState)
                {
                    case ReceiveState.ReceivingHdr:
                        if (e.BytesTransferred < 5)
                        {
                            parent.Disconnect();
                            return;
                        }

                        if (e.Buffer[0] == 0x4d && e.Buffer[1] == 0x61 &&
                            e.Buffer[2] == 0x64 && e.Buffer[3] == 0x65 && e.Buffer[4] == 0xff)
                        {
                            log.InfoFormat("Usage request from: @ {0}.", skt.RemoteEndPoint);
                            byte[] c = Encoding.ASCII.GetBytes(parent.Manager.MaxClients +
                                ":" + parent.Manager.Clients.Count.ToString());
                            skt.Send(c);
                            return;
                        }

                        if (e.Buffer[0] == 0x3c && e.Buffer[1] == 0x70 &&
                            e.Buffer[2] == 0x6f && e.Buffer[3] == 0x6c && e.Buffer[4] == 0x69)
                        {
                            ProcessPolicyFile();
                            return;
                        }

                        int len = (e.UserToken as ReceiveToken).Length =
                            IPAddress.NetworkToHostOrder(BitConverter.ToInt32(e.Buffer, 0)) - 5;
                        if (len < 0 || len > BUFFER_SIZE)
                            throw new InternalBufferOverflowException();
                        Packet packet = null;
                        try
                        {
                            packet = Packet.Packets[(PacketID)e.Buffer[4]].CreateInstance();
                        }
                        catch
                        {
                            log.ErrorFormat("Packet ID not found: {0}", e.Buffer[4]);
                        }
                        (e.UserToken as ReceiveToken).Packet = packet;

                        receiveState = ReceiveState.ReceivingBody;
                        e.SetBuffer(0, len);
                        skt.ReceiveAsync(e);
                        break;
                    case ReceiveState.ReceivingBody:
                        if (e.BytesTransferred < (e.UserToken as ReceiveToken).Length)
                        {
                            parent.Disconnect();
                            return;
                        }

                        Packet pkt = (e.UserToken as ReceiveToken).Packet;
                        pkt.Read(parent, e.Buffer, 0, (e.UserToken as ReceiveToken).Length);

                        receiveState = ReceiveState.Processing;
                        bool cont = OnPacketReceived(pkt);

                        if (cont && skt.Connected)
                        {
                            receiveState = ReceiveState.ReceivingHdr;
                            e.SetBuffer(0, 5);
                            skt.ReceiveAsync(e);
                        }
                        break;
                    default:
                        throw new InvalidOperationException(e.LastOperation.ToString());
                }
            }
            catch (Exception ex)
            {
                OnError(ex);
            }
        }
Example #25
0
        /// <summary>
        /// Initiate method for asynchronous receive operation of payload data in "payload-unaware" mode.
        /// </summary>
        private void ReceivePayloadUnawareAsync(ReceiveState receiveState)
        {
            if (!receiveState.Token.Cancelled)
            {
                receiveState.ReceiveArgs.SetBuffer(0, ReceiveBufferSize);

                if (!receiveState.Socket.ReceiveAsync(receiveState.ReceiveArgs))
                    ThreadPool.QueueUserWorkItem(state => ProcessReceivePayloadUnaware(receiveState));
            }
        }
Example #26
0
 void receive(ReceiveState state)
 {
     _socket.BeginReceive(state.data,
                          state.offset,
                          state.length - state.offset,
                          SocketFlags.None,
                          _receiveCallback,
                          state);            
 }
Example #27
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="TcpClient"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if ((object)m_connectState != null)
                        {
                            TerminateConnection(m_connectState.Token);
                            m_connectState.Dispose();
                            m_connectState = null;
                        }

                        if ((object)m_receiveState != null)
                        {
                            m_receiveState.Dispose();
                            m_receiveState = null;
                        }

                        if ((object)m_sendState != null)
                        {
                            m_sendState.Dispose();
                            m_sendState = null;
                        }

                        if ((object)m_connectWaitHandle != null)
                        {
                            m_connectWaitHandle.Set();
                            m_connectWaitHandle.Dispose();
                            m_connectWaitHandle = null;
                        }
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }
Example #28
0
        /// <summary>
        /// ReceiveCommandResponseCallback is the main "while loop" of the ReceiveCommandResponse function family.
        /// In general, what is does is perform an EndReceive() to complete the previous retrieval of bytes from the
        /// server (unless it is using a buffered response)  It then processes what is received by using the
        /// implementing class's CheckValid() function, as described above. If the response is complete, it returns the single complete
        /// response in the GeneralResponseDescription created in BeginReceiveComamndResponse, and buffers the rest as described above.
        ///
        /// If the resposne is not complete, it issues another Connection.BeginReceive, with callback ReceiveCommandResponse2,
        /// so the action will continue at the next invocation of ReceiveCommandResponse2.
        /// </summary>
        /// <param name="asyncResult"></param>
        ///
        private void ReceiveCommandResponseCallback(ReceiveState state, int bytesRead)
        {
            // completeLength will be set to a nonnegative number by CheckValid if the response is complete:
            // it will set completeLength to the length of a complete response.
            int completeLength = -1;

            while (true)
            {
                int validThrough = state.ValidThrough; // passed to checkvalid


                // If we got a string from decoding the contents of the Buffered response, then we didn't call BeginReceive, so don't
                // call end receive...
                if (state.StringFromBuffer.Length > 0)
                {
                    // Append the string we got from the buffer, and flush it out.
                    state.Resp.StatusBuffer.Append(state.StringFromBuffer);
                    state.StringFromBuffer = "";

                    // invoke checkvalid.
                    if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
                    {
                        throw GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
                    }

                    // if the response is NOT complete, then we'll have to do a Receive.  However, there may be
                    // bytes left over in the buffer that were not decoded into the string.
                    // Copy these bytes into the receive buffer so that they will not be lost in the next Receive().
                    if (completeLength < 0)
                    {
                        Buffer.BlockCopy(m_Buffer, m_BufferOffset, state.Buffer, 0, m_BufferCount);
                        state.BytesInBuffer = m_BufferCount;
                        m_BufferCount       = 0;
                    }
                    // else if the response is complete, then we can leave the buffer, possibly with leftover bytes, as is, and all is accurate.

                    // Update the "last length of the statusBuffer" info.
                    state.LastResponseLength += state.StringFromBuffer.Length;
                }
                else // we did a Connection.BeginReceive.  Note that in this case, all bytes received are in the receive buffer (because bytes from
                     // the buffer were transferred there if necessary
                {
                    // this indicates the connection was closed.
                    if (bytesRead <= 0)
                    {
                        throw GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
                    }

                    // There may have been bytes in the receive buffer before, so increase the count of bytes by the number read from (receive).
                    state.BytesInBuffer += bytesRead;

                    // decode the bytes in the receive buffer into a string, append it to the statusbuffer, and invoke checkvalid.
                    string szResponse = Encoding.GetString(state.Buffer, 0, state.BytesInBuffer);
                    state.Resp.StatusBuffer.Append(szResponse);
                    if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
                    {
                        throw GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
                    }

                    // If the response is complete, then determine how many bytes are left over...these bytes need to be set into Buffer.
                    // To do this we see how many characters from the last appended string are used up in the complete response.
                    // This number is completeLength - state.LastResponseLength.  Note at every execution of ReceiveCommandresponse2,
                    // the invariant is that the bytes in the receive buffer are exactly those bytes beyond the end of the last status buffer
                    // string, so the encoding in bytes of the status buffer from (state.LastResponseLength) to (completeLength) are those
                    // bytes used from the last string appended, and the rest are to be buffered.
                    if (completeLength >= 0)
                    {
                        if (completeLength < state.LastResponseLength)
                        {
                            throw GenerateException(WebExceptionStatus.ServerProtocolViolation, null); // CompleteLength Too Low
                        }

                        int bytesFromThisReceive = Encoding.GetByteCount(szResponse.Substring(0, completeLength - state.LastResponseLength));
                        // bytes to buffer
                        if (state.BytesInBuffer > bytesFromThisReceive)
                        {
                            SetBuffer(state.Buffer, bytesFromThisReceive, state.BytesInBuffer - bytesFromThisReceive);
                        }
                    }
                    else // not complete.  Any bytes that were not in the string that was appended (szResponse)
                         //  are moved to the beginning of the receive buffer so they can be considered in the next Receive().
                         // this prevents loss of any bytes.
                    {
                        state.LastResponseLength = state.Resp.StatusBuffer.Length;  // update the last length of the statusbuffer.
                        int bytesUsed = Encoding.GetByteCount(szResponse);
                        state.BytesInBuffer -= bytesUsed;

                        Buffer.BlockCopy(state.Buffer, bytesUsed, state.Buffer, 0, state.BytesInBuffer);
                    }
                }

                // Now, in general, if the response is not complete, update the "valid through" length for the efficiency of checkValid.
                // and perform the next receive.
                // Note that there may be bytes in the beginning of the receive buffer (if there were partial characters left over after the
                // last encoding), so start the receive at state.BytesInBuffer.
                if (completeLength < 0)
                {
                    state.ValidThrough = validThrough;
                    try {
                        if (m_Async)
                        {
                            BeginRead(state.Buffer, state.BytesInBuffer, state.Buffer.Length - state.BytesInBuffer, m_ReadCallbackDelegate, state);
                            return;
                        }
                        else
                        {
                            bytesRead = Read(state.Buffer, state.BytesInBuffer, state.Buffer.Length - state.BytesInBuffer);
                            if (bytesRead == 0)
                            {
                                CloseSocket();
                            }
                            continue;
                        }
                    }
                    catch (IOException) {
                        MarkAsRecoverableFailure();
                        throw;
                    }
                    catch {
                        throw;
                    }
                }
                // the response is completed
                break;
            }


            // Otherwise, we have a complete response.
            string responseString = state.Resp.StatusBuffer.ToString();

            state.Resp.StatusDescription = responseString.Substring(0, completeLength);
            // set the StatusDescription to the complete part of the response.  Note that the Buffer has already been taken care of above.

            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_received_response, responseString.Substring(0, completeLength - 2)));
            }

            if (m_Async)
            {
                // Tell who is listening what was received.
                if (state.Resp != null)
                {
                    m_CurrentResponseDescription = state.Resp;
                }
                Stream stream = null;
                if (PostReadCommandProcessing(ref stream))
                {
                    return;
                }
                ContinueCommandPipeline();
            }
        }
Example #29
0
        private void ProcessIntegratedSecurityAuthentication(IAsyncResult asyncResult)
        {
            ConnectState connectState = null;
            ReceiveState receiveState = null;
            SendState sendState = null;

            try
            {
                // Get the connect state from the async result
                connectState = (ConnectState)asyncResult.AsyncState;

                // Quit if this connection loop has been cancelled
                if (connectState.Token.Cancelled)
                    return;

                try
                {
                    // Complete the operation to authenticate with the server
                    connectState.NegotiateStream.EndAuthenticateAsClient(asyncResult);
                }
                catch (InvalidCredentialException)
                {
                    if (!m_ignoreInvalidCredentials)
                        throw;
                }

                // Initialize the SocketAsyncEventArgs for receive operations
                connectState.ReceiveArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction();
                connectState.ReceiveArgs.SetBuffer(new byte[ReceiveBufferSize], 0, ReceiveBufferSize);

                if (m_payloadAware)
                    connectState.ReceiveArgs.Completed += (sender, args) => ProcessReceivePayloadAware((ReceiveState)args.UserToken);
                else
                    connectState.ReceiveArgs.Completed += (sender, args) => ProcessReceivePayloadUnaware((ReceiveState)args.UserToken);

                // Initialize the SocketAsyncEventArgs for send operations
                connectState.SendArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction();
                connectState.SendArgs.SetBuffer(new byte[SendBufferSize], 0, SendBufferSize);
                connectState.SendArgs.Completed += (sender, args) => ProcessSend((SendState)args.UserToken);

                // Initialize state object for the asynchronous send loop
                sendState = new SendState();
                sendState.Token = connectState.Token;
                sendState.Socket = connectState.Socket;
                sendState.ReceiveArgs = connectState.ReceiveArgs;
                sendState.SendArgs = connectState.SendArgs;
                sendState.SendArgs.UserToken = sendState;

                // Store sendState in m_sendState so that calls to Disconnect
                // and Dispose can dispose resources and cancel asynchronous loops
                m_sendState = sendState;

                // Check the state of cancellation one more time before
                // proceeding to the next step of the connection loop
                if (connectState.Token.Cancelled)
                    return;

                // Notify of established connection
                // and begin receiving data.
                m_connectWaitHandle.Set();
                OnConnectionEstablished();

                // Initialize state object for the asynchronous receive loop
                receiveState = new ReceiveState();
                receiveState.Token = connectState.Token;
                receiveState.Socket = connectState.Socket;
                receiveState.Buffer = connectState.ReceiveArgs.Buffer;
                receiveState.ReceiveArgs = connectState.ReceiveArgs;
                receiveState.ReceiveArgs.UserToken = receiveState;
                receiveState.SendArgs = connectState.SendArgs;

                // Store receiveState in m_receiveState so that calls to Disconnect
                // and Dispose can dispose resources and cancel asynchronous loops
                m_receiveState = receiveState;

                // Start receiving data
                if (m_payloadAware)
                    ReceivePayloadAwareAsync(receiveState);
                else
                    ReceivePayloadUnawareAsync(receiveState);

                // Further socket interactions are handled through the SslStream
                // object, so the SocketAsyncEventArgs is no longer needed
                connectState.ConnectArgs.Dispose();
            }
            catch (SocketException ex)
            {
                // Log exception during connection attempt
                OnConnectionException(ex);

                // If connectState is null, we cannot proceed
                if ((object)connectState == null)
                    return;

                // If the connection is refused by the server,
                // keep trying until we reach our maximum connection attempts
                if (ex.SocketErrorCode == SocketError.ConnectionRefused &&
                    (MaxConnectionAttempts == -1 || connectState.ConnectionAttempts < MaxConnectionAttempts))
                {
                    try
                    {
                        ConnectAsync(connectState);
                    }
                    catch
                    {
                        TerminateConnection(connectState.Token);
                    }
                }
                else
                {
                    // For any other socket exception,
                    // terminate the connection
                    TerminateConnection(connectState.Token);
                }
            }
            catch (Exception ex)
            {
                // Log exception during connection attempt
                string errorMessage = $"Unable to authenticate connection to server: {ex.Message}";
                OnConnectionException(new Exception(errorMessage, ex));

                // Terminate the connection
                if ((object)connectState != null)
                    TerminateConnection(connectState.Token);
            }
            finally
            {
                if ((object)connectState != null)
                {
                    // If the operation was cancelled during execution,
                    // make sure to dispose of erroneously allocated resources;
                    // otherwise, dispose of the NegotiateStream which is only used for authentication
                    if (connectState.Token.Cancelled)
                    {
                        connectState.Dispose();
                    }
                    else
                    {
                        connectState.NetworkStream.Dispose();
                        connectState.NegotiateStream.Dispose();
                    }
                }

                if ((object)receiveState != null && receiveState.Token.Cancelled)
                    receiveState.Dispose();

                if ((object)sendState != null && sendState.Token.Cancelled)
                    sendState.Dispose();
            }
        }
Example #30
0
        /// <summary>
        /// Callback method for asynchronous receive operation of payload data in "payload-aware" mode.
        /// </summary>
        private void ProcessReceivePayloadAware(ReceiveState receiveState)
        {
            try
            {
                // Quit if this receive loop has been cancelled
                if (receiveState.Token.Cancelled)
                    return;

                // Determine if the server disconnected gracefully
                if (receiveState.ReceiveArgs.SocketError != SocketError.Success)
                    throw new SocketException((int)receiveState.ReceiveArgs.SocketError);

                if (receiveState.ReceiveArgs.BytesTransferred == 0)
                    throw new SocketException((int)SocketError.Disconnecting);

                // Update statistics and bytes received.
                UpdateBytesReceived(receiveState.ReceiveArgs.BytesTransferred);
                receiveState.Offset += receiveState.ReceiveArgs.BytesTransferred;

                if (receiveState.PayloadLength < 0)
                {
                    // If we haven't parsed the length of the payload yet, attempt to parse it
                    receiveState.PayloadLength = Payload.ExtractLength(receiveState.Buffer, receiveState.Offset, m_payloadMarker);

                    if (receiveState.PayloadLength > 0)
                    {
                        receiveState.Offset = 0;

                        if (receiveState.Buffer.Length < receiveState.PayloadLength)
                            receiveState.Buffer = new byte[receiveState.PayloadLength];
                    }
                }
                else if (receiveState.Offset == receiveState.PayloadLength)
                {
                    // We've received the entire payload so notify the user
                    OnReceiveDataComplete(receiveState.Buffer, receiveState.PayloadLength);

                    // Reset payload length
                    receiveState.Offset = 0;
                    receiveState.PayloadLength = -1;
                }

                // Continue asynchronous loop
                ReceivePayloadAwareAsync(receiveState);
            }
            catch (ObjectDisposedException)
            {
                // Make sure connection is terminated when client is disposed.
                TerminateConnection(receiveState.Token);
            }
            catch (SocketException ex)
            {
                // Log exception during receive operation
                OnReceiveDataException(ex);

                // Terminate connection when socket exception is encountered
                TerminateConnection(receiveState.Token);
            }
            catch (Exception ex)
            {
                try
                {
                    // For any other exception, notify and resume
                    OnReceiveDataException(ex);
                    ReceivePayloadAwareAsync(receiveState);
                }
                catch
                {
                    // Terminate connection if resume fails
                    TerminateConnection(receiveState.Token);
                }
            }
            finally
            {
                // If the operation was cancelled during execution,
                // make sure to dispose of allocated resources
                if ((object)receiveState != null && receiveState.Token.Cancelled)
                    receiveState.Dispose();
            }
        }
 private void ReceiveCommandResponseCallback(ReceiveState state, int bytesRead)
 {
     int num2;
     int completeLength = -1;
 Label_0002:
     num2 = state.ValidThrough;
     if (this.m_Buffer.Length > 0)
     {
         state.Resp.StatusBuffer.Append(this.m_Buffer);
         this.m_Buffer = string.Empty;
         if (!this.CheckValid(state.Resp, ref num2, ref completeLength))
         {
             throw this.GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
         }
     }
     else
     {
         if (bytesRead <= 0)
         {
             throw this.GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
         }
         char[] chars = new char[this.m_Decoder.GetCharCount(state.Buffer, 0, bytesRead)];
         int length = this.m_Decoder.GetChars(state.Buffer, 0, bytesRead, chars, 0, false);
         string str = new string(chars, 0, length);
         state.Resp.StatusBuffer.Append(str);
         if (!this.CheckValid(state.Resp, ref num2, ref completeLength))
         {
             throw this.GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
         }
         if (completeLength >= 0)
         {
             int num4 = state.Resp.StatusBuffer.Length - completeLength;
             if (num4 > 0)
             {
                 this.m_Buffer = str.Substring(str.Length - num4, num4);
             }
         }
     }
     if (completeLength < 0)
     {
         state.ValidThrough = num2;
         try
         {
             if (this.m_Async)
             {
                 this.BeginRead(state.Buffer, 0, state.Buffer.Length, m_ReadCallbackDelegate, state);
                 return;
             }
             bytesRead = this.Read(state.Buffer, 0, state.Buffer.Length);
             if (bytesRead == 0)
             {
                 base.CloseSocket();
             }
             goto Label_0002;
         }
         catch (IOException)
         {
             this.MarkAsRecoverableFailure();
             throw;
         }
         catch
         {
             throw;
         }
     }
     string str2 = state.Resp.StatusBuffer.ToString();
     state.Resp.StatusDescription = str2.Substring(0, completeLength);
     if (Logging.On)
     {
         Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_received_response", new object[] { str2.Substring(0, completeLength - 2) }));
     }
     if (this.m_Async)
     {
         if (state.Resp != null)
         {
             this.m_CurrentResponseDescription = state.Resp;
         }
         Stream stream = null;
         if (!this.PostReadCommandProcessing(ref stream))
         {
             this.ContinueCommandPipeline();
         }
     }
 }
Example #32
0
        /// <summary>
        /// Callback method for asynchronous receive operation of payload data in "payload-unaware" mode.
        /// </summary>
        private void ProcessReceivePayloadUnaware(ReceiveState receiveState)
        {
            try
            {
                // Quit if this receive loop has been cancelled
                if (receiveState.Token.Cancelled)
                    return;

                if (receiveState.ReceiveArgs.SocketError != SocketError.Success)
                    throw new SocketException((int)receiveState.ReceiveArgs.SocketError);

                if (receiveState.ReceiveArgs.BytesTransferred == 0)
                    throw new SocketException((int)SocketError.Disconnecting);

                // Update statistics and bytes received
                UpdateBytesReceived(receiveState.ReceiveArgs.BytesTransferred);
                receiveState.PayloadLength = receiveState.ReceiveArgs.BytesTransferred;

                // Notify of received data and resume receive operation.
                OnReceiveDataComplete(receiveState.Buffer, receiveState.PayloadLength);
                ReceivePayloadUnawareAsync(receiveState);
            }
            catch (ObjectDisposedException)
            {
                // Make sure connection is terminated when client is disposed
                TerminateConnection(receiveState.Token);
            }
            catch (SocketException ex)
            {
                // Log exception during receive operation
                OnReceiveDataException(ex);

                // Terminate connection when socket exception is encountered
                TerminateConnection(receiveState.Token);
            }
            catch (Exception ex)
            {
                try
                {
                    // For any other exception, notify and resume
                    OnReceiveDataException(ex);
                    ReceivePayloadUnawareAsync(receiveState);
                }
                catch
                {
                    // Terminate connection if resume fails
                    TerminateConnection(receiveState.Token);
                }
            }
        }
Example #33
0
        /// <summary>
        /// Callback method for asynchronous authenticate operation.
        /// </summary>
        private void ProcessTlsAuthentication(IAsyncResult asyncResult)
        {
            ConnectState connectState = null;
            ReceiveState receiveState = null;
            SendState sendState = null;

            try
            {
                // Get the connect state from the async result
                connectState = (ConnectState)asyncResult.AsyncState;

                // Quit if this connection loop has been cancelled
                if (connectState.Token.Cancelled)
                    return;

                // Complete the operation to authenticate with the server
                connectState.SslStream.EndAuthenticateAsClient(asyncResult);

                // Ensure that this client is authenticated and encrypted
                if (EnabledSslProtocols != SslProtocols.None)
                {
                    if (!connectState.SslStream.IsAuthenticated)
                        throw new InvalidOperationException("Connection could not be established because we could not authenticate with the server.");

                    if (!connectState.SslStream.IsEncrypted)
                        throw new InvalidOperationException("Connection could not be established because the data stream is not encrypted.");
                }

                if (m_integratedSecurity)
                {
#if !MONO
                    // Check the state of cancellation one more time before
                    // proceeding to the next step of the connection loop
                    if (connectState.Token.Cancelled)
                        return;

                    // Create the NegotiateStream to begin authentication of the user's Windows credentials
                    connectState.NegotiateStream = new NegotiateStream(connectState.SslStream, true);
                    connectState.NegotiateStream.BeginAuthenticateAsClient(m_networkCredential ?? (NetworkCredential)CredentialCache.DefaultCredentials, string.Empty, ProcessIntegratedSecurityAuthentication, connectState);
#endif
                }
                else
                {
                    // Initialize state object for the asynchronous send loop
                    sendState = new SendState();

                    sendState.Socket = connectState.Socket;
                    sendState.NetworkStream = connectState.NetworkStream;
                    sendState.SslStream = connectState.SslStream;
                    sendState.Token = connectState.Token;

                    // Store sendState in m_sendState so that calls to Disconnect
                    // and Dispose can dispose resources and cancel asynchronous loops
                    m_sendState = sendState;

                    // Check the state of cancellation one more time before
                    // proceeding to the next step of the connection loop
                    if (connectState.Token.Cancelled)
                        return;

                    // Notify of established connection
                    m_connectWaitHandle.Set();
                    OnConnectionEstablished();

                    // Initialize state object for the asynchronous receive loop
                    receiveState = new ReceiveState();

                    receiveState.Socket = connectState.Socket;
                    receiveState.NetworkStream = connectState.NetworkStream;
                    receiveState.SslStream = connectState.SslStream;
                    receiveState.Buffer = new byte[m_payloadMarker.Length + Payload.LengthSegment];
                    receiveState.Token = connectState.Token;

                    // Store receiveState in m_receiveState so that calls to Disconnect
                    // and Dispose can dispose resources and cancel asynchronous loops
                    m_receiveState = receiveState;

                    // Start receiving data
                    if (m_payloadAware)
                        ReceivePayloadAwareAsync(receiveState);
                    else
                        ReceivePayloadUnawareAsync(receiveState);

                    // Further socket interactions are handled through the SslStream
                    // object, so the SocketAsyncEventArgs is no longer needed
                    connectState.ConnectArgs.Dispose();
                }
            }
            catch (SocketException ex)
            {
                // Log exception during connection attempt
                OnConnectionException(ex);

                // If connectState is null, we cannot proceed
                if ((object)connectState == null)
                    return;

                // If the connection is refused by the server,
                // keep trying until we reach our maximum connection attempts
                if (ex.SocketErrorCode == SocketError.ConnectionRefused &&
                    (MaxConnectionAttempts == -1 || connectState.ConnectionAttempts < MaxConnectionAttempts))
                {
                    try
                    {
                        ConnectAsync(connectState);
                    }
                    catch
                    {
                        TerminateConnection(connectState.Token);
                    }
                }
                else
                {
                    // For any other socket exception,
                    // terminate the connection
                    TerminateConnection(connectState.Token);
                }
            }
            catch (Exception ex)
            {
                // Log exception during connection attempt
                string errorMessage = string.Format("Unable to authenticate connection to server: {0}", CertificateChecker.ReasonForFailure ?? ex.Message);
                OnConnectionException(new Exception(errorMessage, ex));

                // Terminate the connection
                if ((object)connectState != null)
                    TerminateConnection(connectState.Token);
            }
            finally
            {
                // If the operation was cancelled during execution,
                // make sure to dispose of erroneously allocated resources
                if ((object)connectState != null && connectState.Token.Cancelled)
                    connectState.Dispose();

                if ((object)receiveState != null && receiveState.Token.Cancelled)
                    receiveState.Dispose();

                if ((object)sendState != null && sendState.Token.Cancelled)
                    sendState.Dispose();
            }
        }
Example #34
0
        /// <summary>
        /// Callback method for asynchronous connect operation.
        /// </summary>
        private void ProcessConnect(ConnectState connectState)
        {
            ReceiveState receiveState = null;
            SendState sendState = null;

            try
            {
                // Quit if this connection loop has been cancelled
                if (connectState.Token.Cancelled)
                    return;

                // Increment the number of connection attempts that
                // have occurred in this asynchronous connection loop
                connectState.ConnectionAttempts++;

                // Check the SocketAsyncEventArgs for errors during the asynchronous connection attempt
                if (connectState.ConnectArgs.SocketError != SocketError.Success)
                    throw new SocketException((int)connectState.ConnectArgs.SocketError);

                // Set the size of the buffer used by the socket to store incoming data from the server
                connectState.Socket.ReceiveBufferSize = ReceiveBufferSize;

                if (m_integratedSecurity)
                {
#if !MONO
                    // Check the state of cancellation one more time before
                    // proceeding to the next step of the connection loop
                    if (connectState.Token.Cancelled)
                        return;

                    // Create the SslStream object used to perform
                    // send and receive operations on the socket
                    connectState.NetworkStream = new NetworkStream(connectState.Socket, false);
                    connectState.NegotiateStream = new NegotiateStream(connectState.NetworkStream, true);
                    connectState.NegotiateStream.BeginAuthenticateAsClient(m_networkCredential ?? (NetworkCredential)CredentialCache.DefaultCredentials, string.Empty, ProcessIntegratedSecurityAuthentication, connectState);
#endif
                }
                else
                {
                    // Initialize the SocketAsyncEventArgs for receive operations
                    connectState.ReceiveArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction();
                    connectState.ReceiveArgs.SetBuffer(new byte[ReceiveBufferSize], 0, ReceiveBufferSize);

                    if (m_payloadAware)
                        connectState.ReceiveArgs.Completed += (sender, args) => ProcessReceivePayloadAware((ReceiveState)args.UserToken);
                    else
                        connectState.ReceiveArgs.Completed += (sender, args) => ProcessReceivePayloadUnaware((ReceiveState)args.UserToken);

                    // Initialize the SocketAsyncEventArgs for send operations
                    connectState.SendArgs = FastObjectFactory<SocketAsyncEventArgs>.CreateObjectFunction();
                    connectState.SendArgs.SetBuffer(new byte[SendBufferSize], 0, SendBufferSize);
                    connectState.SendArgs.Completed += (sender, args) => ProcessSend((SendState)args.UserToken);

                    // Initialize state object for the asynchronous send loop
                    sendState = new SendState();
                    sendState.Token = connectState.Token;
                    sendState.Socket = connectState.Socket;
                    sendState.ReceiveArgs = connectState.ReceiveArgs;
                    sendState.SendArgs = connectState.SendArgs;
                    sendState.SendArgs.UserToken = sendState;

                    // Store sendState in m_sendState so that calls to Disconnect
                    // and Dispose can dispose resources and cancel asynchronous loops
                    m_sendState = sendState;

                    // Check the state of cancellation one more time before
                    // proceeding to the next step of the connection loop
                    if (connectState.Token.Cancelled)
                        return;

                    // Notify of established connection
                    m_connectWaitHandle.Set();
                    OnConnectionEstablished();

                    // Initialize state object for the asynchronous receive loop
                    receiveState = new ReceiveState();
                    receiveState.Token = connectState.Token;
                    receiveState.Socket = connectState.Socket;
                    receiveState.Buffer = connectState.ReceiveArgs.Buffer;
                    receiveState.ReceiveArgs = connectState.ReceiveArgs;
                    receiveState.ReceiveArgs.UserToken = receiveState;
                    receiveState.SendArgs = connectState.SendArgs;

                    // Store receiveState in m_receiveState so that calls to Disconnect
                    // and Dispose can dispose resources and cancel asynchronous loops
                    m_receiveState = receiveState;

                    // Start receiving data
                    if (m_payloadAware)
                        ReceivePayloadAwareAsync(receiveState);
                    else
                        ReceivePayloadUnawareAsync(receiveState);

                    // Further socket interactions are handled through the ReceiveArgs
                    // and SendArgs objects, so the ConnectArgs is no longer needed
                    connectState.ConnectArgs.Dispose();
                }
            }
            catch (SocketException ex)
            {
                // Log exception during connection attempt
                OnConnectionException(ex);

                // If the connection is refused by the server,
                // keep trying until we reach our maximum connection attempts
                if (ex.SocketErrorCode == SocketError.ConnectionRefused &&
                    (MaxConnectionAttempts == -1 || connectState.ConnectionAttempts < MaxConnectionAttempts))
                {
                    // Server is unavailable, so keep retrying connection to the server.
                    try
                    {
                        ConnectAsync(connectState);
                    }
                    catch
                    {
                        TerminateConnection(connectState.Token);
                    }
                }
                else
                {
                    // For any other reason, clean-up as if the client was disconnected.
                    TerminateConnection(connectState.Token);
                }
            }
            catch (Exception ex)
            {
                // Log exception during connection attempt
                OnConnectionException(ex);

                // Terminate the connection
                TerminateConnection(connectState.Token);
            }
            finally
            {
                // If the operation was cancelled during execution,
                // make sure to dispose of erroneously allocated resources
                if ((object)connectState != null && connectState.Token.Cancelled)
                    connectState.Dispose();

                if ((object)receiveState != null && receiveState.Token.Cancelled)
                    receiveState.Dispose();

                if ((object)sendState != null && sendState.Token.Cancelled)
                    sendState.Dispose();
            }
        }
Example #35
0
        /// <summary>
        /// ReceiveCommandResponseCallback is the main "while loop" of the ReceiveCommandResponse function family.
        /// In general, what is does is perform an EndReceive() to complete the previous retrieval of bytes from the
        /// server (unless it is using a buffered response)  It then processes what is received by using the
        /// implementing class's CheckValid() function, as described above. If the response is complete, it returns the single complete
        /// response in the GeneralResponseDescription created in BeginReceiveComamndResponse, and buffers the rest as described above.
        ///
        /// If the response is not complete, it issues another Connection.BeginReceive, with callback ReceiveCommandResponse2,
        /// so the action will continue at the next invocation of ReceiveCommandResponse2.
        /// </summary>
        private void ReceiveCommandResponseCallback(ReceiveState state, int bytesRead)
        {
            // completeLength will be set to a nonnegative number by CheckValid if the response is complete:
            // it will set completeLength to the length of a complete response.
            int completeLength = -1;

            while (true)
            {
                int validThrough = state.ValidThrough; // passed to checkvalid

                // If we have a Buffered response (ie data was received with the last response that was past the end of that response)
                // deal with it as if we had just received it now instead of actually doing another receive
                if (_buffer.Length > 0)
                {
                    // Append the string we got from the buffer, and flush it out.
                    state.Resp.StatusBuffer.Append(_buffer);
                    _buffer = string.Empty;

                    // invoke checkvalid.
                    if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
                    {
                        throw GenerateException(SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
                    }
                }
                else // we did a Connection.BeginReceive.  Note that in this case, all bytes received are in the receive buffer (because bytes from
                     // the buffer were transferred there if necessary
                {
                    // this indicates the connection was closed.
                    if (bytesRead <= 0)
                    {
                        throw GenerateException(SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
                    }

                    // decode the bytes in the receive buffer into a string, append it to the statusbuffer, and invoke checkvalid.
                    // Decoder automatically takes care of caching partial codepoints at the end of a buffer.

                    char[] chars    = new char[_decoder.GetCharCount(state.Buffer, 0, bytesRead)];
                    int    numChars = _decoder.GetChars(state.Buffer, 0, bytesRead, chars, 0, false);

                    string szResponse = new string(chars, 0, numChars);

                    state.Resp.StatusBuffer.Append(szResponse);
                    if (!CheckValid(state.Resp, ref validThrough, ref completeLength))
                    {
                        throw GenerateException(SR.net_ftp_protocolerror, WebExceptionStatus.ServerProtocolViolation, null);
                    }

                    // If the response is complete, then determine how many characters are left over...these bytes need to be set into Buffer.
                    if (completeLength >= 0)
                    {
                        int unusedChars = state.Resp.StatusBuffer.Length - completeLength;
                        if (unusedChars > 0)
                        {
                            _buffer = szResponse.Substring(szResponse.Length - unusedChars, unusedChars);
                        }
                    }
                }

                // Now, in general, if the response is not complete, update the "valid through" length for the efficiency of checkValid,
                // and perform the next receive.
                // Note that there may NOT be bytes in the beginning of the receive buffer (even if there were partial characters left over after the
                // last encoding), because they get tracked in the Decoder.
                if (completeLength < 0)
                {
                    state.ValidThrough = validThrough;
                    try
                    {
                        if (_isAsync)
                        {
                            BeginRead(state.Buffer, 0, state.Buffer.Length, s_readCallbackDelegate, state);
                            return;
                        }
                        else
                        {
                            bytesRead = Read(state.Buffer, 0, state.Buffer.Length);
                            if (bytesRead == 0)
                            {
                                CloseSocket();
                            }
                            continue;
                        }
                    }
                    catch (IOException)
                    {
                        MarkAsRecoverableFailure();
                        throw;
                    }
                    catch
                    {
                        throw;
                    }
                }

                // The response is completed
                break;
            }

            // Otherwise, we have a complete response.
            string responseString = state.Resp.StatusBuffer.ToString();

            state.Resp.StatusDescription = responseString.Substring(0, completeLength);
            // Set the StatusDescription to the complete part of the response.  Note that the Buffer has already been taken care of above.

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"Received response: {responseString.Substring(0, completeLength - 2)}");
            }

            if (_isAsync)
            {
                // Tell who is listening what was received.
                if (state.Resp != null)
                {
                    _currentResponseDescription = state.Resp;
                }
                Stream stream = null;
                if (PostReadCommandProcessing(ref stream))
                {
                    return;
                }
                ContinueCommandPipeline();
            }
        }
        private void IOCompleted(object sender, SocketAsyncEventArgs e)
        {

            try
            {
                bool repeat;
                do
                {
                    repeat = false;

                    if (e.SocketError != SocketError.Success)
                        throw new SocketException((int) e.SocketError);
                    /*
                    SocketError errorCode;
                    int nBytesRec = Socket.EndReceive(ar, out errorCode);
                    if (errorCode != SocketError.Success)
                    {
                        nBytesRec = 0;
                    }
                    */
                    if (e.LastOperation == SocketAsyncOperation.Receive)
                    {
                        switch (receiveState)
                        {
                            case ReceiveState.ReceivingHdr:
                                if (debug)
                                    Console.WriteLine(@"test");

                                if (e.BytesTransferred < 5)
                                {
                                    parent.Disconnect();
                                    return;
                                }

                                if (debug)
                                    Console.WriteLine(@"test2");

                                if (e.Buffer[0] == 0x3c && e.Buffer[1] == 0x70 &&
                                    e.Buffer[2] == 0x6f && e.Buffer[3] == 0x6c && e.Buffer[4] == 0x69)
                                {
                                    ProcessPolicyFile();
                                    return;
                                }

                                var len = (e.UserToken as ReceiveToken).Length =
                                    IPAddress.NetworkToHostOrder(BitConverter.ToInt32(e.Buffer, 0)) - 5;
                                if (len < 0 || len > BUFFER_SIZE)
                                    throw new InternalBufferOverflowException();
                                (e.UserToken as ReceiveToken).Packet =
                                    Packet.Packets[(PacketID) e.Buffer[4]].CreateInstance();
                                if (debug)
                                    Console.WriteLine("test3 - " + (e.UserToken as ReceiveToken).Packet.GetType().Name);

                                receiveState = ReceiveState.ReceivingBody;
                                e.SetBuffer(0, len);
                                if (!skt.ReceiveAsync(e))
                                {
                                    repeat = true;
                                }
                                break;
                            case ReceiveState.ReceivingBody:
                                if (e.BytesTransferred < (e.UserToken as ReceiveToken).Length)
                                {
                                    parent.Disconnect();
                                    return;
                                }

                                var pkt = (e.UserToken as ReceiveToken).Packet;
                                pkt.Read(parent, e.Buffer, (e.UserToken as ReceiveToken).Length);

                                receiveState = ReceiveState.Processing;
                                var cont = OnPacketReceived(pkt);

                                if (cont && skt.Connected)
                                {
                                    receiveState = ReceiveState.ReceivingHdr;
                                    e.SetBuffer(0, 5);
                                    if (!skt.ReceiveAsync(e))
                                    {
                                        repeat = true;
                                    }
                                }
                                break;
                            default:
                                throw new InvalidOperationException(e.LastOperation.ToString());
                        }
                    }
                    else if (e.LastOperation == SocketAsyncOperation.Send)
                    {
                        switch (sendState)
                        {
                            case SendState.Ready:
                                var dat = (e.UserToken as SendToken).Packet.Write(parent);

                                sendState = SendState.Sending;
                                e.SetBuffer(dat, 0, dat.Length);
                                if (!skt.SendAsync(e))
                                {
                                    repeat = true;
                                }
                                break;
                            case SendState.Sending:
                                (e.UserToken as SendToken).Packet = null;

                                if (CanSendPacket(e, true))
                                {
                                    repeat = true;
                                }
                                break;
                            default:
                                throw new InvalidOperationException(e.LastOperation.ToString());
                        }
                    }
                    else
                        throw new InvalidOperationException(e.LastOperation.ToString());
                } while (repeat);
            }
            catch (Exception ex)
            {
                OnError(ex);
            }
        }
Example #37
0
        private void ReceiveCommandResponseCallback(ReceiveState state, int bytesRead)
        {
            int num2;
            int completeLength = -1;

Label_0002:
            num2 = state.ValidThrough;
            if (this.m_Buffer.Length > 0)
            {
                state.Resp.StatusBuffer.Append(this.m_Buffer);
                this.m_Buffer = string.Empty;
                if (!this.CheckValid(state.Resp, ref num2, ref completeLength))
                {
                    throw this.GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
                }
            }
            else
            {
                if (bytesRead <= 0)
                {
                    throw this.GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
                }
                char[] chars  = new char[this.m_Decoder.GetCharCount(state.Buffer, 0, bytesRead)];
                int    length = this.m_Decoder.GetChars(state.Buffer, 0, bytesRead, chars, 0, false);
                string str    = new string(chars, 0, length);
                state.Resp.StatusBuffer.Append(str);
                if (!this.CheckValid(state.Resp, ref num2, ref completeLength))
                {
                    throw this.GenerateException(WebExceptionStatus.ServerProtocolViolation, null);
                }
                if (completeLength >= 0)
                {
                    int num4 = state.Resp.StatusBuffer.Length - completeLength;
                    if (num4 > 0)
                    {
                        this.m_Buffer = str.Substring(str.Length - num4, num4);
                    }
                }
            }
            if (completeLength < 0)
            {
                state.ValidThrough = num2;
                try
                {
                    if (this.m_Async)
                    {
                        this.BeginRead(state.Buffer, 0, state.Buffer.Length, m_ReadCallbackDelegate, state);
                        return;
                    }
                    bytesRead = this.Read(state.Buffer, 0, state.Buffer.Length);
                    if (bytesRead == 0)
                    {
                        base.CloseSocket();
                    }
                    goto Label_0002;
                }
                catch (IOException)
                {
                    this.MarkAsRecoverableFailure();
                    throw;
                }
                catch
                {
                    throw;
                }
            }
            string str2 = state.Resp.StatusBuffer.ToString();

            state.Resp.StatusDescription = str2.Substring(0, completeLength);
            if (Logging.On)
            {
                Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_received_response", new object[] { str2.Substring(0, completeLength - 2) }));
            }
            if (this.m_Async)
            {
                if (state.Resp != null)
                {
                    this.m_CurrentResponseDescription = state.Resp;
                }
                Stream stream = null;
                if (!this.PostReadCommandProcessing(ref stream))
                {
                    this.ContinueCommandPipeline();
                }
            }
        }