internal static ClassifyState TransitionExpectEpoxyHeaders( ClassifyState state, Frame frame, ref EpoxyHeaders headers, ref ProtocolErrorCode?errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectEpoxyHeaders); Debug.Assert(frame != null); if (frame.Count == 0 || frame.Framelets[0].Type != FrameletType.EpoxyHeaders) { return(ClassifyState.InternalStateError); } var framelet = frame.Framelets[0]; var inputBuffer = new InputBuffer(framelet.Contents); var fastBinaryReader = new FastBinaryReader <InputBuffer>(inputBuffer, version: 1); switch (headersDeserializer.TryDeserialize(fastBinaryReader, out headers)) { case Deserialize.Result.Success: break; default: logger.Site().Error("Didn't get a valid {0}.", nameof(EpoxyHeaders)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } logger.Site().Debug("Deserialized {0} with conversation ID {1} and message type {2}.", nameof(EpoxyHeaders), headers.conversation_id, headers.message_type); return(ClassifyState.ExpectOptionalLayerData); }
internal static ClassifyState TransitionExpectOptionalLayerData( ClassifyState state, Frame frame, EpoxyHeaders headers, ref ArraySegment <byte> layerData, ref ProtocolErrorCode?errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectOptionalLayerData); Debug.Assert(frame != null); if (headers == null) { return(ClassifyState.InternalStateError); } if (frame.Count < 2) { logger.Site().Error("Frame had headers but no message data."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } var framelet = frame.Framelets[1]; if (framelet.Type == FrameletType.LayerData) { layerData = framelet.Contents; logger.Site().Debug("Extracted {0}-byte layer data in conversation ID {1}.", layerData.Count, headers.conversation_id); } return(ClassifyState.ExpectMessageData); }
internal static ClassifyState TransitionValidFrame( ClassifyState state, EpoxyHeaders headers, ref FrameDisposition disposition) { if (state != ClassifyState.ValidFrame || headers == null) { return(ClassifyState.InternalStateError); } switch (headers.payload_type) { case PayloadType.Request: disposition = FrameDisposition.DeliverRequestToService; return(ClassifyState.ClassifiedValidFrame); case PayloadType.Response: disposition = FrameDisposition.DeliverResponseToProxy; return(ClassifyState.ClassifiedValidFrame); case PayloadType.Event: disposition = FrameDisposition.DeliverEventToService; return(ClassifyState.ClassifiedValidFrame); default: return(ClassifyState.InternalStateError); } }
internal static ClassifyState TransitionExpectFirstFramelet( ClassifyState state, Frame frame, ref ProtocolErrorCode?errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectFirstFramelet); Debug.Assert(frame != null); if (frame.Framelets.Count == 0) { logger.Site().Error("Frame was empty."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } switch (frame.Framelets[0].Type) { case FrameletType.EpoxyHeaders: return(ClassifyState.ExpectEpoxyHeaders); case FrameletType.EpoxyConfig: return(ClassifyState.ExpectConfig); case FrameletType.ProtocolError: return(ClassifyState.ExpectProtocolError); default: logger.Site().Error("Frame began with invalid FrameletType {0}.", frame.Framelets[0].Type); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } }
internal static ClassifyState TransitionExpectPayload( ClassifyState state, Frame frame, EpoxyHeaders headers, ArraySegment <byte> layerData, ref ArraySegment <byte> payload, ref ProtocolErrorCode?errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectPayload); Debug.Assert(frame != null); if (headers == null) { return(ClassifyState.InternalStateError); } int payloadDataIndex = (layerData.Array == null ? 1 : 2); if (payloadDataIndex >= frame.Count) { logger.Site().Error("Frame had headers but no payload."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } var framelet = frame.Framelets[payloadDataIndex]; if (framelet.Type != FrameletType.PayloadData) { logger.Site().Error("Frame had headers but no payload."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } payload = framelet.Contents; logger.Site().Debug("Extracted {0}-byte payload in conversation ID {1}.", payload.Count, headers.conversation_id); return(ClassifyState.ExpectEndOfFrame); }
internal static ClassifyState TransitionExpectProtocolError( ClassifyState state, Frame frame, ref ProtocolError error, ref FrameDisposition disposition, Logger logger) { if (state != ClassifyState.ExpectProtocolError || frame == null || frame.Count == 0 || frame.Framelets[0].Type != FrameletType.ProtocolError) { return(ClassifyState.InternalStateError); } if (frame.Count > 1) { logger.Site().Error("Protocol error frame had trailing framelets."); return(ClassifyState.ErrorInErrorFrame); } var framelet = frame.Framelets[0]; var inputBuffer = new InputBuffer(framelet.Contents); var fastBinaryReader = new FastBinaryReader <InputBuffer>(inputBuffer, version: 1); switch (errorDeserializer.TryDeserialize(fastBinaryReader, out error)) { case Deserialize.Result.Success: break; default: logger.Site().Error("Didn't get a valid {0}.", nameof(ProtocolError)); return(ClassifyState.ErrorInErrorFrame); } logger.Site().Debug("Deserialized {0} with code {1}.", nameof(ProtocolError), error.error_code); disposition = FrameDisposition.HandleProtocolError; return(ClassifyState.ClassifiedValidFrame); }
internal static ClassifyState TransitionValidFrame( ClassifyState state, EpoxyHeaders headers, ref FrameDisposition disposition) { if (state != ClassifyState.ValidFrame || headers == null) { return(ClassifyState.InternalStateError); } switch (headers.message_type) { case EpoxyMessageType.REQUEST: disposition = FrameDisposition.DeliverRequestToService; return(ClassifyState.ClassifiedValidFrame); case EpoxyMessageType.RESPONSE: disposition = FrameDisposition.DeliverResponseToProxy; return(ClassifyState.ClassifiedValidFrame); case EpoxyMessageType.EVENT: disposition = FrameDisposition.DeliverEventToService; return(ClassifyState.ClassifiedValidFrame); default: return(ClassifyState.InternalStateError); } }
internal static ClassifyState TransitionExpectConfig( ClassifyState state, Frame frame, ref ProtocolErrorCode?errorCode, ref FrameDisposition disposition, Logger logger) { Debug.Assert(state == ClassifyState.ExpectConfig); Debug.Assert(frame != null); if (frame.Count == 0 || frame.Framelets[0].Type != FrameletType.EpoxyConfig) { return(ClassifyState.InternalStateError); } if (frame.Count != 1) { logger.Site().Error("Config frame had trailing framelets."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } var framelet = frame.Framelets[0]; var inputBuffer = new InputBuffer(framelet.Contents); var fastBinaryReader = new FastBinaryReader <InputBuffer>(inputBuffer, 1); // We don't currently do anything with the config aside from try to deserialize it. EpoxyConfig config; switch (configDeserializer.TryDeserialize(fastBinaryReader, out config)) { case Deserialize.Result.Success: break; default: logger.Site().Error("Didn't get a valid {0}.", nameof(EpoxyConfig)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } disposition = FrameDisposition.ProcessConfig; return(ClassifyState.ClassifiedValidFrame); }
internal static ClassifyState TransitionExpectMessageData( ClassifyState state, Frame frame, EpoxyHeaders headers, ArraySegment <byte> layerData, ref MessageData messageData, ref ProtocolErrorCode?errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectMessageData); Debug.Assert(frame != null); if (headers == null) { return(ClassifyState.InternalStateError); } int messageDataIndex = (layerData.Array == null ? 1 : 2); if (messageDataIndex >= frame.Count) { logger.Site().Error("Frame had headers but no message data."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } var framelet = frame.Framelets[messageDataIndex]; if (framelet.Type != FrameletType.PayloadData && framelet.Type != FrameletType.ErrorData) { logger.Site().Error("Frame had headers but no message data. Unexpected framelet type {0}", (int)framelet.Type); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } messageData = new MessageData(framelet.Type == FrameletType.ErrorData, framelet.Contents); logger.Site().Debug( "Extracted {0}-byte message in conversation ID {1}.", messageData.Data.Count, headers.conversation_id); return(ClassifyState.ExpectEndOfFrame); }
internal static ClassifyState TransitionFrameComplete( ClassifyState state, EpoxyHeaders headers, ref ProtocolErrorCode?errorCode, Logger logger) { if (state != ClassifyState.FrameComplete || headers == null) { return(ClassifyState.InternalStateError); } switch (headers.payload_type) { case PayloadType.Request: case PayloadType.Response: case PayloadType.Event: return(ClassifyState.ValidFrame); default: logger.Site().Warning("Received unrecognized payload type {0}.", headers.payload_type); errorCode = ProtocolErrorCode.NOT_SUPPORTED; return(ClassifyState.MalformedFrame); } }
internal static ClassifyState TransitionFrameComplete( ClassifyState state, EpoxyHeaders headers, ref ProtocolErrorCode?errorCode, Logger logger) { if (state != ClassifyState.FrameComplete || headers == null) { return(ClassifyState.InternalStateError); } switch (headers.message_type) { case EpoxyMessageType.REQUEST: case EpoxyMessageType.RESPONSE: case EpoxyMessageType.EVENT: return(ClassifyState.ValidFrame); default: logger.Site().Warning("Received unrecognized message type {0}.", headers.message_type); errorCode = ProtocolErrorCode.NOT_SUPPORTED; return(ClassifyState.MalformedFrame); } }
internal static ClassifyState TransitionExpectOptionalLayerData( ClassifyState state, Frame frame, EpoxyHeaders headers, ref ArraySegment <byte> layerData, ref ProtocolErrorCode?errorCode) { Debug.Assert(state == ClassifyState.ExpectOptionalLayerData); Debug.Assert(frame != null); if (headers == null) { return(ClassifyState.InternalStateError); } if (frame.Count < 2) { Log.Error("{0}.{1}: Frame did not continue with LayerData or PayloadData.", nameof(EpoxyProtocol), nameof(TransitionExpectEpoxyHeaders)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } if (frame.Framelets[1].Type == FrameletType.PayloadData) { return(ClassifyState.ExpectPayload); } var framelet = frame.Framelets[1]; if (framelet.Type != FrameletType.LayerData) { Log.Error("{0}.{1}: Frame did not continue with LayerData or PayloadData.", nameof(EpoxyProtocol), nameof(TransitionExpectOptionalLayerData)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } layerData = framelet.Contents; Log.Debug("{0}.{1}: Extracted {2}-byte layer data in conversation ID {3}.", nameof(EpoxyProtocol), nameof(TransitionExpectOptionalLayerData), layerData.Count, headers.conversation_id); return(ClassifyState.ExpectPayload); }
internal static ClassifyState TransitionExpectEndOfFrame( ClassifyState state, Frame frame, ArraySegment <byte> layerData, ref ProtocolErrorCode?errorCode, Logger logger) { if (state != ClassifyState.ExpectEndOfFrame || frame == null) { return(ClassifyState.InternalStateError); } int validFrameSize = (layerData.Array == null ? 2 : 3); if (frame.Count == validFrameSize) { return(ClassifyState.FrameComplete); } else { logger.Site().Error("Frame had trailing framelets."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } }
internal static ClassifyState TransitionExpectPayload( ClassifyState state, Frame frame, EpoxyHeaders headers, ArraySegment <byte> layerData, ref ArraySegment <byte> payload, ref ProtocolErrorCode?errorCode) { Debug.Assert(state == ClassifyState.ExpectPayload); Debug.Assert(frame != null); if (headers == null) { return(ClassifyState.InternalStateError); } int payloadDataIndex = (layerData.Array == null ? 1 : 2); if (payloadDataIndex >= frame.Count) { Log.Error("{0}.{1}: Frame did not continue with PayloadData.", nameof(EpoxyProtocol), nameof(TransitionExpectEpoxyHeaders)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } var framelet = frame.Framelets[payloadDataIndex]; if (framelet.Type != FrameletType.PayloadData) { Log.Error("{0}.{1}: Frame did not continue with PayloadData.", nameof(EpoxyProtocol), nameof(TransitionExpectEpoxyHeaders)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return(ClassifyState.MalformedFrame); } payload = framelet.Contents; Log.Debug("{0}.{1}: Extracted {2}-byte payload in conversation ID {3}.", nameof(EpoxyProtocol), nameof(TransitionExpectPayload), payload.Count, headers.conversation_id); return(ClassifyState.ExpectEndOfFrame); }
internal static ClassifyState TransitionExpectProtocolError( ClassifyState state, Frame frame, ref ProtocolError error, ref FrameDisposition disposition, Logger logger) { if (state != ClassifyState.ExpectProtocolError || frame == null || frame.Count == 0 || frame.Framelets[0].Type != FrameletType.ProtocolError) { return ClassifyState.InternalStateError; } if (frame.Count > 1) { logger.Site().Error("Protocol error frame had trailing framelets."); return ClassifyState.ErrorInErrorFrame; } var framelet = frame.Framelets[0]; var inputBuffer = new InputBuffer(framelet.Contents); var fastBinaryReader = new FastBinaryReader<InputBuffer>(inputBuffer, version: 1); switch (errorDeserializer.TryDeserialize(fastBinaryReader, out error)) { case Deserialize.Result.Success: break; default: logger.Site().Error("Didn't get a valid {0}.", nameof(ProtocolError)); return ClassifyState.ErrorInErrorFrame; } logger.Site().Debug("Deserialized {0} with code {1}.", nameof(ProtocolError), error.error_code); disposition = FrameDisposition.HandleProtocolError; return ClassifyState.ClassifiedValidFrame; }
internal static ClassifyState TransitionExpectConfig( ClassifyState state, Frame frame, ref ProtocolErrorCode? errorCode, ref FrameDisposition disposition, Logger logger) { Debug.Assert(state == ClassifyState.ExpectConfig); Debug.Assert(frame != null); if (frame.Count == 0 || frame.Framelets[0].Type != FrameletType.EpoxyConfig) { return ClassifyState.InternalStateError; } if (frame.Count != 1) { logger.Site().Error("Config frame had trailing framelets."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } var framelet = frame.Framelets[0]; var inputBuffer = new InputBuffer(framelet.Contents); var fastBinaryReader = new FastBinaryReader<InputBuffer>(inputBuffer, version: 1); // We don't currently do anything with the config aside from try to deserialize it. EpoxyConfig config; switch (configDeserializer.TryDeserialize(fastBinaryReader, out config)) { case Deserialize.Result.Success: break; default: logger.Site().Error("Didn't get a valid {0}.", nameof(EpoxyConfig)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } disposition = FrameDisposition.ProcessConfig; return ClassifyState.ClassifiedValidFrame; }
internal static ClassifyState TransitionValidFrame( ClassifyState state, EpoxyHeaders headers, ref FrameDisposition disposition) { if (state != ClassifyState.ValidFrame || headers == null) { return ClassifyState.InternalStateError; } switch (headers.message_type) { case EpoxyMessageType.REQUEST: disposition = FrameDisposition.DeliverRequestToService; return ClassifyState.ClassifiedValidFrame; case EpoxyMessageType.RESPONSE: disposition = FrameDisposition.DeliverResponseToProxy; return ClassifyState.ClassifiedValidFrame; case EpoxyMessageType.EVENT: disposition = FrameDisposition.DeliverEventToService; return ClassifyState.ClassifiedValidFrame; default: return ClassifyState.InternalStateError; } }
internal static ClassifyState TransitionFrameComplete( ClassifyState state, EpoxyHeaders headers, ref ProtocolErrorCode? errorCode, Logger logger) { if (state != ClassifyState.FrameComplete || headers == null) { return ClassifyState.InternalStateError; } switch (headers.message_type) { case EpoxyMessageType.REQUEST: case EpoxyMessageType.RESPONSE: case EpoxyMessageType.EVENT: return ClassifyState.ValidFrame; default: logger.Site().Warning("Received unrecognized message type {0}.", headers.message_type); errorCode = ProtocolErrorCode.NOT_SUPPORTED; return ClassifyState.MalformedFrame; } }
internal static ClassifyState TransitionExpectEndOfFrame( ClassifyState state, Frame frame, ArraySegment<byte> layerData, ref ProtocolErrorCode? errorCode, Logger logger) { // FIXME: Change all of these to asserts. if (state != ClassifyState.ExpectEndOfFrame || frame == null) { return ClassifyState.InternalStateError; } var validFrameSize = (layerData.Array == null ? 2 : 3); if (frame.Count == validFrameSize) { return ClassifyState.FrameComplete; } else { logger.Site().Error("Frame had trailing framelets."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } }
internal static ClassifyState TransitionExpectMessageData( ClassifyState state, Frame frame, EpoxyHeaders headers, ArraySegment<byte> layerData, ref MessageData messageData, ref ProtocolErrorCode? errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectMessageData); Debug.Assert(frame != null); if (headers == null) { return ClassifyState.InternalStateError; } int messageDataIndex = (layerData.Array == null ? 1 : 2); if (messageDataIndex >= frame.Count) { logger.Site().Error("Frame had headers but no message data."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } var framelet = frame.Framelets[messageDataIndex]; if (framelet.Type != FrameletType.PayloadData && framelet.Type != FrameletType.ErrorData) { logger.Site().Error("Frame had headers but no message data. Unexpected framelet type {0}", (int)framelet.Type); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } messageData = new MessageData( isError: framelet.Type == FrameletType.ErrorData, data: framelet.Contents); logger.Site().Debug("Extracted {0}-byte message in conversation ID {1}.", messageData.Data.Count, headers.conversation_id); return ClassifyState.ExpectEndOfFrame; }
internal static ClassifyState TransitionExpectOptionalLayerData( ClassifyState state, Frame frame, EpoxyHeaders headers, ref ArraySegment<byte> layerData, ref ProtocolErrorCode? errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectOptionalLayerData); Debug.Assert(frame != null); if (headers == null) { return ClassifyState.InternalStateError; } if (frame.Count < 2) { logger.Site().Error("Frame had headers but no message data."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } var framelet = frame.Framelets[1]; if (framelet.Type == FrameletType.LayerData) { layerData = framelet.Contents; logger.Site().Debug("Extracted {0}-byte layer data in conversation ID {1}.", layerData.Count, headers.conversation_id); } return ClassifyState.ExpectMessageData; }
internal static ClassifyState TransitionExpectEpoxyHeaders( ClassifyState state, Frame frame, ref EpoxyHeaders headers, ref ProtocolErrorCode? errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectEpoxyHeaders); Debug.Assert(frame != null); if (frame.Count == 0 || frame.Framelets[0].Type != FrameletType.EpoxyHeaders) { return ClassifyState.InternalStateError; } var framelet = frame.Framelets[0]; var inputBuffer = new InputBuffer(framelet.Contents); var fastBinaryReader = new FastBinaryReader<InputBuffer>(inputBuffer, version: 1); switch (headersDeserializer.TryDeserialize(fastBinaryReader, out headers)) { case Deserialize.Result.Success: break; default: logger.Site().Error("Didn't get a valid {0}.", nameof(EpoxyHeaders)); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } logger.Site().Debug("Deserialized {0} with conversation ID {1} and message type {2}.", nameof(EpoxyHeaders), headers.conversation_id, headers.message_type); return ClassifyState.ExpectOptionalLayerData; }
internal static ClassifyState TransitionExpectFirstFramelet( ClassifyState state, Frame frame, ref ProtocolErrorCode? errorCode, Logger logger) { Debug.Assert(state == ClassifyState.ExpectFirstFramelet); Debug.Assert(frame != null); if (frame.Framelets.Count == 0) { logger.Site().Error("Frame was empty."); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } switch (frame.Framelets[0].Type) { case FrameletType.EpoxyHeaders: return ClassifyState.ExpectEpoxyHeaders; case FrameletType.EpoxyConfig: return ClassifyState.ExpectConfig; case FrameletType.ProtocolError: return ClassifyState.ExpectProtocolError; default: logger.Site().Error("Frame began with invalid FrameletType {0}.", frame.Framelets[0].Type); errorCode = ProtocolErrorCode.MALFORMED_DATA; return ClassifyState.MalformedFrame; } }