public static ControlFrame.Type ToControlFrameType(this FrameOpcode opcode) { switch (opcode) { case FrameOpcode.Close: return(ControlFrame.Type.Close); case FrameOpcode.Ping: return(ControlFrame.Type.Ping); case FrameOpcode.Pong: return(ControlFrame.Type.Pong); default: throw new InvalidOperationException("that opcode is not for a control frame!"); } }
private static async Task SendFixedFrame(Synchronized <Stream> sStream, FrameOpcode opcode, int appDataLength, bool masking, Action <byte[], int> dataWriter) { int appDataOffset; byte[] buffer, maskData; BuildFrameHeader(opcode, appDataLength, masking, out maskData, out buffer, out appDataOffset, bareHeader: false); dataWriter(buffer, appDataOffset); if (masking) { for (int i = 0; i < appDataLength; i++) { buffer[i + appDataOffset] ^= maskData[i % 4]; } } using (var streamHolder = await sStream) await streamHolder.LockedObject.WriteAsync(buffer, 0, buffer.Length); }
private static void BuildFrameHeader(FrameOpcode opcode, int appDataLength, bool masking, out byte[] maskData, out byte[] buffer, out int appDataOffset, bool bareHeader) { PayloadLengthMode plm; if (appDataLength < 126) { plm = PayloadLengthMode.Short; } else if (appDataLength <= UInt16.MaxValue) { plm = PayloadLengthMode.Medium; } else { plm = PayloadLengthMode.Long; } // TODO: implement extensions int bufferLength = 2 + (((int)plm) / 8) + (masking ? 4 : 0) + (bareHeader ? 0 : appDataLength); buffer = new byte[bufferLength]; buffer[0] = (byte)((byte)opcode | FLAG1_FIN); switch (plm) { case PayloadLengthMode.Short: buffer[1] = (byte)appDataLength; appDataOffset = 2; break; case PayloadLengthMode.Medium: buffer[1] = 126; var shortLength = Util.ReverseArray(BitConverter.GetBytes(checked ((UInt16)appDataLength))); Array.Copy(shortLength, 0, buffer, 2, shortLength.Length); appDataOffset = 4; break; case PayloadLengthMode.Long: buffer[1] = 127; var longLength = Util.ReverseArray(BitConverter.GetBytes(checked ((UInt64)appDataLength))); Array.Copy(longLength, 0, buffer, 2, longLength.Length); appDataOffset = 10; break; default: throw new InvalidOperationException("Either the string is impossibly large (HI FUTURE! :D) or the selection loop (or the switch) has failed."); } if (masking) { maskData = new byte[4]; if (CSPRNG == null) { CSPRNG = System.Security.Cryptography.RandomNumberGenerator.Create(); } CSPRNG.GetBytes(maskData); buffer[1] |= FLAG2_MASK; Array.Copy(maskData, 0, buffer, appDataOffset, maskData.Length); appDataOffset += 4; } else { maskData = null; } }
/// <summary> /// Gets the frame from opcode. /// </summary> /// <param name="protocolVersion">the version of the cql binary protocol in use</param> /// <param name="opcode">The opcode.</param> /// <returns></returns> /// <exception cref="ProtocolException">Unexpected OpCode received.</exception> private static Frame GetFrameFromOpcode(byte protocolVersion, FrameOpcode opcode) { Frame frame; switch(opcode) { case FrameOpcode.Error: frame = new ErrorFrame(); break; case FrameOpcode.Ready: frame = new ReadyFrame(); break; case FrameOpcode.Authenticate: frame = new AuthenticateFrame(); break; case FrameOpcode.AuthChallenge: frame = new AuthChallengeFrame(); break; case FrameOpcode.AuthSuccess: frame = new AuthSuccessFrame(); break; case FrameOpcode.Supported: frame = new SupportedFrame(); break; case FrameOpcode.Result: frame = new ResultFrame(); break; case FrameOpcode.Event: frame = new EventFrame(); break; default: throw new ProtocolException(protocolVersion, 0, string.Format("Unexpected OpCode {0:X} received.", opcode)); } return frame; }