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(); } } }
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(); } } }