Example #1
0
        private static void InitHeader(byte[] arrPayload, ref GatewayPayload payload)
        {
            // Create a BinaryReader around the incoming array to parse the data out of it
            MemoryStream msPayload = new MemoryStream(arrPayload);
            BinaryReader reader    = new BinaryReader(msPayload);

            payload.Mode = (BlockMode)reader.ReadUInt32();

            // Skip over the ActualPayloadSize field
            reader.ReadUInt32();

            payload.OffsetToRW        = reader.ReadUInt64();
            payload.SizePayloadBuffer = reader.ReadUInt32();
            payload.LengthDeviceID    = reader.ReadUInt32();

            // Read the SRB address
            payload.SRBAddress = new UIntPtr(reader.ReadUInt64());

            // Read the deviceID string
            byte[] arrDeviceID = reader.ReadBytes((int)payload.LengthDeviceID);
            unsafe
            {
                fixed(byte *pDeviceID = arrDeviceID)
                {
                    IntPtr ptrDeviceID = new IntPtr(pDeviceID);

                    payload.DeviceID = Marshal.PtrToStringUni(ptrDeviceID);
                }
            }

            // Fetch the EndOfPayloadMarker
            payload.EndOfPayloadMarker = reader.ReadUInt32();

            reader.Close();
        }
        private static GatewayPayload HandleProcessPayloadException(ref GatewayPayload payload, Exception ex)
        {
            Console.WriteLine("SFBlockstoreService::HandleProcessPayloadException: Got an exception [{0} - {1}] while processing payload.", ex.GetType(), ex.Message);

            // Build the payload information to be dumped.
            StringBuilder sbPayloadInfo = new StringBuilder();

            sbPayloadInfo.AppendLine(String.Format("Mode: {0:X}", payload.Mode));
            sbPayloadInfo.AppendLine(String.Format("Offset: {0:X}", payload.OffsetToRW));
            sbPayloadInfo.AppendLine(String.Format("Length to R/W: {0:X}", payload.SizePayloadBuffer));
            sbPayloadInfo.AppendLine(String.Format("DeviceID Length: {0:X}", payload.LengthDeviceID));
            sbPayloadInfo.AppendLine(String.Format("DeviceID: {0}", payload.DeviceID));
            sbPayloadInfo.AppendLine(String.Format("EndOfPayloadMarker: {0:X}", payload.EndOfPayloadMarker));

            Console.WriteLine(sbPayloadInfo.ToString());

            // TODO: Can we do this better?
            // Payload processing failed - Reflect in the payload status
            uint expectedResponsePayloadSize = (uint)GatewayPayloadConst.blockSizeManagementRequest;

            if (payload.Mode == BlockMode.Read)
            {
                if (payload.UseDMA)
                {
                    // We do not have any payload to send for the DMA scenario.
                    expectedResponsePayloadSize = 0;
                }
                else
                {
                    // Read request's receiver is expecting the intended size
                    expectedResponsePayloadSize = payload.SizePayloadBuffer;
                }
            }
            else if (payload.Mode == BlockMode.Write)
            {
                // Write request's receiver is expected only the payload header.
                expectedResponsePayloadSize = 0;
            }
            else
            {
                // All other requests (e.g. LU registration) expected the default (BlockSizeManagementRequest sized) payload size.
            }

            payload.SizePayloadBuffer = expectedResponsePayloadSize;
            payload.PayloadData       = null;

            if (payload.EndOfPayloadMarker != GatewayPayloadConst.EndOfPayloadMarker)
            {
                // We got a payload that was invalid, so reflect that
                // in the mode we will send back
                payload.Mode = BlockMode.ServerInvalidPayload;
                Console.WriteLine("SFBlockstoreService::HandleProcessPayloadException: Client sent an invalid payload.");
            }
            else
            {
                payload.Mode = BlockMode.OperationFailed;
            }

            return(payload);
        }
        private void ProcessNPClient(NamedPipeServerStream pipeServer, CancellationToken cancellationToken)
        {
            if (!cancellationToken.IsCancellationRequested)
            {
                byte[] arrHeader = null;

                try
                {
                    while (pipeServer.IsConnected && (!cancellationToken.IsCancellationRequested))
                    {
                        // Fetch the header from the stream
                        arrHeader = new byte[GatewayPayloadConst.payloadHeaderSize];
                        int iTotalRead = FetchDataFromTransport(null, pipeServer, arrHeader, GatewayPayloadConst.payloadHeaderSize);
                        if (iTotalRead > 0)
                        {
                            // Did we get a buffer of expected size?
                            if (iTotalRead != GatewayPayloadConst.payloadHeaderSize)
                            {
                                throw new InvalidOperationException(String.Format("SFBlockstoreService::ProcessNPClient: Malformed request of size {0} encountered; expected size is {1}", iTotalRead, GatewayPayloadConst.payloadHeaderSize));
                            }

                            GatewayPayload payload = GatewayPayload.ParseHeader(arrHeader, pipeServer, this);

                            // Process the payload
                            try
                            {
                                payload.ProcessPayload(serviceBlockStore, cancellationToken);
                            }
                            catch (Exception ex)
                            {
                                HandleProcessPayloadException(ref payload, ex);
                            }

                            // Send the Data back to the sender
                            payload.SendResponse();
                        }
                    }
                }
                catch (IOException)
                {
                    // Network connection was closed
                }
                catch (ObjectDisposedException)
                {
                    // Network connection was closed
                }
                catch (Exception ex)
                {
                    Console.WriteLine("SFBlockstoreService::ProcessNPClient: Got an exception [{0} - {1}] while handling incoming request.", ex.GetType().ToString(), ex.Message);
                }

                // If we are here, we are not in a position to process the network requests and thus, should close
                // the connection.
                if (pipeServer != null)
                {
                    pipeServer.Close();
                }
            }
        }
Example #4
0
        public static GatewayPayload ParseHeader(byte[] arrPayload, NamedPipeServerStream pipeServer, SFBlockStoreCommunicationListener commListener)
        {
            GatewayPayload payload = new GatewayPayload();

            payload.PipeServer            = pipeServer;
            payload.ClientStream          = null;
            payload.CommunicationListener = commListener;

            InitHeader(arrPayload, ref payload);

            return(payload);
        }
        private void ProcessTcpClient(CancellationToken cancellationToken, TcpClient tcpClient)
        {
            if (!cancellationToken.IsCancellationRequested)
            {
                NetworkStream ns        = null;
                byte[]        arrHeader = null;

                try
                {
                    try
                    {
                        ns = tcpClient.GetStream();
                    }
                    catch (InvalidOperationException)
                    {
                        Console.WriteLine("SFBlockstoreService::ProcessTCPClient: Unable to get NetworkStream to read data!");
                        tcpClient.Close();
                        ns = null;
                    }

                    while ((ns != null) && (tcpClient.Connected) && (!cancellationToken.IsCancellationRequested))
                    {
                        // Fetch the header from the stream
                        arrHeader = new byte[GatewayPayloadConst.payloadHeaderSize];
                        int iTotalRead = FetchDataFromTransport(ns, null, arrHeader, GatewayPayloadConst.payloadHeaderSize);
                        if (iTotalRead > 0)
                        {
                            // Did we get a buffer of expected size?
                            if (iTotalRead != GatewayPayloadConst.payloadHeaderSize)
                            {
                                throw new InvalidOperationException(String.Format("SFBlockstoreService::ProcessTCPClient: Malformed request of size {0} encountered; expected size is {1}", iTotalRead, GatewayPayloadConst.payloadHeaderSize));
                            }

                            GatewayPayload payload = GatewayPayload.ParseHeader(arrHeader, ns, this);

                            // Process the payload
                            try
                            {
                                payload.ProcessPayload(serviceBlockStore, cancellationToken);
                            }
                            catch (Exception ex)
                            {
                                HandleProcessPayloadException(ref payload, ex);
                            }

                            // Send the Data back to the sender
                            payload.SendResponse();
                        }
                        else
                        {
                            //Remote socket is terminated.
                            break;
                        }
                    }
                }
                catch (IOException)
                {
                    // Network connection was closed
                }
                catch (ObjectDisposedException)
                {
                    // Network connection was closed
                }
                catch (Exception ex)
                {
                    Console.WriteLine("SFBlockstoreService::ProcessTCPClient: Got an exception [{0} - {1}] while handling incoming request.", ex.GetType().ToString(), ex.Message);
                }

                // If we are here, we are not in a position to process the network requests and thus, should close
                // the connection.
                if (tcpClient != null)
                {
                    tcpClient.Close();
                }
            }
        }