Beispiel #1
0
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 3)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            // get the randon number
            NetMQFrame randomNumberFrame = message.Pop();

            RandomNumber = randomNumberFrame.ToByteArray();

            // get the length of the ciphers array
            NetMQFrame ciphersLengthFrame = message.Pop();
            int        ciphersLength      = BitConverter.ToInt32(ciphersLengthFrame.Buffer, 0);

            // get the ciphers
            NetMQFrame ciphersFrame = message.Pop();

            CipherSuites = new CipherSuite[ciphersLength];
            for (int i = 0; i < ciphersLength; i++)
            {
                CipherSuites[i] = (CipherSuite)ciphersFrame.Buffer[i * 2 + 1];
            }
        }
Beispiel #2
0
        /// <summary>
        ///   verifies if the message replied obeys the MDP 0.2 protocol
        /// </summary>
        /// <remarks>
        ///     socket strips [client adr][e] from message
        ///     message ->
        ///                [empty frame][protocol header][service name][reply]
        ///                [empty frame][protocol header][service name][result code of service lookup]
        /// </remarks>
        private void ExtractFrames(NetMQMessage reply)
        {
            if (reply.FrameCount < 4)
            {
                throw new ApplicationException("[CLIENT ERROR] received a malformed reply");
            }

            var emptyFrame = reply.Pop();

            if (emptyFrame != NetMQFrame.Empty)
            {
                throw new ApplicationException($"[CLIENT ERROR] received a malformed reply expected empty frame instead of: { emptyFrame } ");
            }
            var header = reply.Pop(); // [MDPHeader] <- [service name][reply] OR ['mmi.service'][return code]

            if (header.ConvertToString() != m_mdpClient)
            {
                throw new ApplicationException($"[CLIENT INFO] MDP Version mismatch: {header}");
            }

//            var service = reply.Pop(); // [service name or 'mmi.service'] <- [reply] OR [return code]

            //          if (service.ConvertToString() != m_serviceName)
            //            throw new ApplicationException($"[CLIENT INFO] answered by wrong service: {service.ConvertToString()}");
        }
Beispiel #3
0
        private CommitForStorage getCommit(NetMQMessage message)
        {
            var context = message.Pop().ConvertToString();
            var stream = message.Pop().ConvertToString();
            var expectedVersion = message.PopInt64();
            var eventCount = message.PopInt32();

            var events = new EventForStorage[eventCount];

            for (int i = 0; i < eventCount; i++)
            {
                var eventId = new Guid(message.Pop().ToByteArray());
                var timestamp = message.PopDateTime();
                var typeKey = message.PopString();
                var headers = message.PopStringOrNull();
                var body = message.PopString();

                //-1 to override concurrency check. Being lazy and not using a constant.
                var version = expectedVersion == -1 ? -1 : expectedVersion + i;

                events[i] = new EventForStorage(eventId, version, timestamp, typeKey, headers, body);
            }

            return new CommitForStorage(context, stream, events);
        }
Beispiel #4
0
        public NetMQMessage DecryptApplicationMessage([NotNull] NetMQMessage cipherMessage)
        {
            if (!SecureChannelReady)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.SecureChannelNotReady, "Cannot decrypt messages until the secure channel is ready");
            }

            if (cipherMessage == null)
            {
                throw new ArgumentNullException("cipherMessage");
            }

            if (cipherMessage.FrameCount < 2)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "cipher message should have at least 2 frames");
            }

            NetMQFrame protocolVersionFrame = cipherMessage.Pop();
            NetMQFrame contentTypeFrame     = cipherMessage.Pop();

            if (!protocolVersionFrame.ToByteArray().SequenceEqual(m_protocolVersion))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version");
            }

            ContentType contentType = (ContentType)contentTypeFrame.Buffer[0];

            if (contentType != ContentType.ApplicationData)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Not an applicagtion data message");
            }

            return(m_recordLayer.DecryptMessage(ContentType.ApplicationData, cipherMessage));
        }
Beispiel #5
0
        private void ReceiveFromRemote(object sender, NetMQSocketEventArgs e)
        {
            NetMQMessage msg      = e.Socket.ReceiveMultipartMessage();
            string       msgtype  = msg.Pop().ConvertToString();
            Guid         remoteId = new Guid(msg.Pop().Buffer);
            string       name     = msg.Pop().ConvertToString();

            switch (msgtype)
            {
            case "ENTER":
                HandleEnterMessage(remoteId, name);
                break;

            case "WHISPER":
                HandleWhisperMessage(remoteId, name, msg);
                break;

            case "SHOUT":
                HandleShoutMessage(remoteId, name, msg);
                break;

            default:
                break;
            }
        }
Beispiel #6
0
        /// <summary>
        /// Remove the two frames from the given NetMQMessage, interpreting them thusly:
        /// 1. a byte with the HandshakeType, assumed to be ClientKeyExchange
        /// 2. a byte-array containing the EncryptedPreMasterSecret.
        /// </summary>
        /// <param name="message">a NetMQMessage - which must have 2 frames</param>
        /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.InvalidFramesCount"/>: FrameCount must be 1.</exception>
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            NetMQFrame lengthFrame = message.Pop();
            NetMQFrame encryptedPreMasterSecretLengthFrame = message.Pop();

            base.SetFromNetMQMessage(message);
        }
Beispiel #7
0
        public void Login(string accountNo, string password)
        {
            NetMQMessage msg =
                Channels.SendRequest(
                    BuildMessage(
                        Header(ID_S_ACCOUNT_LOGIN_REQT),
                        new LoginAccountRequest()
            {
                AccountNo = accountNo,
                Password  = password
            }));

            ResponseHeader header = ResponseHeader.Parser.ParseFrom(msg.Pop().ToByteArray());

            WriteLog(header.ToString());

            LoginAccountResponse response = LoginAccountResponse.Parser.ParseFrom(msg.Pop().ToByteArray());

            WriteLog(response.ToString());
            if (header.Code != ResponseStatusCode.ResponseCodeOk)
            {
                throw new Exception(header.Message);
            }
            Channels.OnSubscribeRecieved += On_SubscribeReceived;
            Channels.ConnectSubscribe();
            Token     = response.Token;
            AccountNo = accountNo;
        }
Beispiel #8
0
        private void On_SubscribeReceived(NetMQMessage message)
        {
            int count = message.FrameCount;

            if (count < 3)
            {
                return;
            }

            string accountNo = message.Pop().ConvertToString();
            var    msgHeader = message.Pop().ToByteArray();
            var    payload   = message.Pop();

            ReportHeader header = ReportHeader.Parser.ParseFrom(msgHeader);

            if (header.ApiId == ID_STOCK_PLACE_REPORT)
            {
                PlacedReport report = PlacedReport.Parser.ParseFrom(payload.ToByteArray());
                PlaceReportReceived?.Invoke(accountNo, header, report);
            }
            else if (header.ApiId == ID_STOCK_FILL_REPORT)
            {
                FillReport report = FillReport.Parser.ParseFrom(payload.ToByteArray());
                FillReportReceived?.Invoke(accountNo, header, report);
            }
            else if (header.ApiId == ID_STOCK_CANCEL_REPORT)
            {
                CancellationReport report = CancellationReport.Parser.ParseFrom(payload.ToByteArray());
                CancelReportReceived?.Invoke(accountNo, header, report);
            }
        }
Beispiel #9
0
        public static void Main(string[] args)
        {
            NetMQContext context = NetMQContext.Create();
            NetMQSocket  server  = context.CreateRequestSocket();

            server.Bind("tcp://*:5555");
            NetMQMessage message = new NetMQMessage();
            NetMQMessage getmass = new NetMQMessage();

            message.Append("Hallo ");
            message.Append(40);

            Client client = new Client();
            Thread t      = new Thread(new ThreadStart(client.runClient));

            t.Start();


            while (true)
            {
                server.SendMessage(message, false);
                getmass = server.ReceiveMessage(false);
                System.Console.WriteLine(getmass.Pop().ConvertToString());
                System.Console.WriteLine(getmass.Pop().ConvertToInt32());
            }
        }
Beispiel #10
0
        public NetMQMessage InQueue(NetMQMessage msg)
        {
            var outMsg = new NetMQMessage();

            if (msg.FrameCount != 2)
            {
                outMsg.Append(0);
                outMsg.Append("占座失败", Encoding.UTF8);
                return(outMsg);
            }
            var seat = msg.Pop().ConvertToInt32();
            var name = msg.Pop().ConvertToString(Encoding.UTF8);

            if (!_queue.ContainsKey(seat) || !_queue[seat].IsNullOrEmpty())
            {
                outMsg.Append(0);
                outMsg.Append("占座失败", Encoding.UTF8);
                return(outMsg);
            }
            _queue[seat] = name;

            outMsg.Append(1);
            outMsg.Append("占座成功", Encoding.UTF8);
            ShowQueue();
            return(outMsg);
        }
Beispiel #11
0
        private void HandleUpdate(NetMQMessage m)
        {
            var topic = m.Pop().ConvertToString();

            long msgid        = m.Pop().ConvertToInt64();
            var  currentMsgid = _messageIds[topic];

            if (msgid - currentMsgid > 1 && msgid != 0 && currentMsgid != 0)
            {
                try
                {
                    _messageSequenceGapAction?.Invoke(topic, currentMsgid, msgid);
                }
                catch
                {
                    // ignored
                }
            }
            _messageIds[topic] = msgid;
            DateTime publishTime = DateTime.FromBinary(m.Pop().ConvertToInt64());
            //TODO: do something with publishTime - perf counter, latency alert

            int frame = m.FrameCount;

            while (frame-- > 0)
            {
                var message = m.Pop().Buffer;
                var type    = _knownTypes[_topics[topic]];
                var obj     = type.Serializer.Deserialize(message);
                var key     = type.KeyExtractor.Extract(obj);
                _lastValueCache.AddOrUpdate(topic, key, obj);
            }
        }
        /// <summary>
        /// Return a new NetMQMessage that holds three frames:
        /// 1. a frame with a single byte representing the HandshakeType, which is ClientHello,
        /// 2. a frame containing the RandomNumber,
        /// 3. a frame containing the list of CipherSuites.
        /// </summary>
        /// <returns>the resulting new NetMQMessage</returns>
        public override NetMQMessage ToNetMQMessage()
        {
            NetMQMessage message       = base.ToNetMQMessage();
            var          handShakeType = message.Pop();
            var          random        = message.Pop();

            message.Push(random);
            message.Push(Version);
            //压缩方法长度
            message.Append(new byte[1] {
                1
            });
            //压缩方法
            message.Append(new byte[1] {
                0
            });
            message.Append(new byte[] { 0, 0 });
            ////todo:测试
            //message.RemoveFrame(message.Last);
            ////扩展长度
            //byte[] extension = "00 0a 00 16 00 14 00 17 00 18 00 19 00 09 00 0a 00 0b 00 0c 00 0d 00 0e 00 16 00 0b 00 02 01 00 00 0d 00 16 00 14 06 03 06 01 05 03 05 01 04 03 04 01 04 02 02 03 02 01 02 02 00 17 00 00 ff 01 00 01 00".ConvertHexToByteArray();
            //message.Append(extension.LengthToBytes(2));
            //message.Append(extension);
            InsertLength(message);
            message.Push(handShakeType);
            return(message);
        }
Beispiel #13
0
        /// <summary>
        /// Remove the three frames from the given NetMQMessage, interpreting them thusly:
        /// 1. a byte with the HandshakeType, presumed here to be ClientHello,
        /// 2. a byte-array containing the RandomNumber,
        /// 3. a byte-array with the list of CipherSuites.
        /// </summary>
        /// <param name="message">a NetMQMessage - which must have 2 frames</param>
        /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.InvalidFramesCount"/>: FrameCount must be 3.</exception>
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 3)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            // get the random number
            NetMQFrame randomNumberFrame = message.Pop();
            RandomNumber = randomNumberFrame.ToByteArray();

            // get the length of the cipher-suites array
            NetMQFrame ciphersLengthFrame = message.Pop();
            int ciphersLength = BitConverter.ToInt32(ciphersLengthFrame.Buffer, 0);

            // get the cipher-suites
            NetMQFrame ciphersFrame = message.Pop();
            CipherSuites = new CipherSuite[ciphersLength];
            for (int i = 0; i < ciphersLength; i++)
            {
                CipherSuites[i] = (CipherSuite)ciphersFrame.Buffer[i * 2 + 1];
            }
        }
Beispiel #14
0
        /// <summary>
        /// Check the message envelope for errors
        /// and get the MDP Command embedded.
        /// The message will be altered!
        /// </summary>
        /// <param name="request">NetMQMessage received</param>
        /// <returns>the received MDP Command</returns>
        private MDPCommand GetMDPCommand(NetMQMessage request)
        {
            // don't try to handle errors
            if (request.FrameCount < 3)
            {
                throw new ApplicationException("Malformed request received!");
            }

            var empty = request.Pop();

            if (!empty.IsEmpty)
            {
                throw new ApplicationException("First frame must be an empty frame!");
            }

            var header = request.Pop();

            if (header.ConvertToString() != m_mdpWorker)
            {
                throw new ApplicationException("Invalid protocol header received!");
            }

            var cmd = request.Pop();

            if (cmd.BufferSize > 1)
            {
                throw new ApplicationException("MDP Command must be one byte not multiple!");
            }

            var command = (MDPCommand)cmd.Buffer[0];

//            Log ($"[WORKER] received a {command}");

            return(command);
        }
Beispiel #15
0
        public NetMQMessage DecryptApplicationMessage(NetMQMessage cipherMessage)
        {
            if (!SecureChannelReady)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.SecureChannelNotReady, "Cannot decrypt messages until the secure channel is ready");
            }

            if (cipherMessage == null)
            {
                throw new ArgumentNullException("cipherMessage is null");
            }

            if (cipherMessage.FrameCount < 2)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "cipher message should have at least 2 frames");
            }

            NetMQFrame protocolVersionFrame = cipherMessage.Pop();
            NetMQFrame contentTypeFrame = cipherMessage.Pop();

            if (!protocolVersionFrame.ToByteArray().SequenceEqual(m_protocolVersion))
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version");
            }

            ContentType contentType = (ContentType)contentTypeFrame.Buffer[0];

            if (contentType != ContentType.ApplicationData)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Not an applicagtion data message");
            }

            return m_recordLayer.DecryptMessage(ContentType.ApplicationData, cipherMessage);
        }
Beispiel #16
0
        public bool ProcessMessage(NetMQMessage incomingMessage, IList <NetMQMessage> outgoingMesssages)
        {
            ContentType contentType = ContentType.Handshake;

            if (incomingMessage != null)
            {
                NetMQFrame protocolVersionFrame = incomingMessage.Pop();
                byte[]     protocolVersionBytes = protocolVersionFrame.ToByteArray();

                if (protocolVersionBytes.Length != 2)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "Wrong length for protocol version frame");
                }

                if (!protocolVersionBytes.SequenceEqual(m_protocolVersion))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version");
                }

                NetMQFrame contentTypeFrame = incomingMessage.Pop();

                if (contentTypeFrame.MessageSize != 1)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "wrong length for message size");
                }

                contentType = (ContentType)contentTypeFrame.Buffer[0];

                if (contentType != ContentType.ChangeCipherSpec && contentType != ContentType.Handshake)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Unkown content type");
                }

                if (ChangeSuiteChangeArrived)
                {
                    incomingMessage = m_recordLayer.DecryptMessage(contentType, incomingMessage);
                }
            }

            bool result = false;

            if (contentType == ContentType.Handshake)
            {
                result = m_handshakeLayer.ProcessMessages(incomingMessage, m_outgoingMessageBag);

                foreach (NetMQMessage outgoingMesssage in m_outgoingMessageBag.Messages)
                {
                    outgoingMesssages.Add(outgoingMesssage);
                }

                m_outgoingMessageBag.Clear();
            }
            else
            {
                ChangeSuiteChangeArrived = true;
            }

            return(SecureChannelReady = result && ChangeSuiteChangeArrived);
        }
Beispiel #17
0
        public ZeroMqNotificationReader Init()
        {
            if (Initialized)
            {
                throw new InvalidOperationException($"{nameof(ZeroMqNotificationReader)} already initialized.");
            }

            var completionSource = new TaskCompletionSource <object>();
            var token            = _source.Token;

            _receiveTask = Task.Factory.StartNew(() =>
            {
                var timeout = TimeSpan.FromSeconds(1);

                using (var subSocket = new SubscriberSocket(EndPoint))
                {
                    try
                    {
                        subSocket.Options.ReceiveHighWatermark = 1000;
                        subSocket.SubscribeToAnyTopic();

                        while (!token.IsCancellationRequested)
                        {
                            var zMessage        = new NetMQMessage(2);
                            var messageReceived = subSocket.TryReceiveMultipartMessage(timeout, ref zMessage, 2);
                            completionSource.TrySetResult(null);

                            if (!messageReceived)
                            {
                                continue;
                            }

                            var topic = zMessage.Pop().ConvertToString(Encoding.UTF8);
                            var json  = zMessage.Pop().ConvertToString(Encoding.UTF8);

                            OnNotificationReceived?.Invoke(topic, json);
                        }
                    }
                    catch (Exception e)
                    {
                        OnError?.Invoke(e);
                    }
                }
            }, TaskCreationOptions.LongRunning);

            _receiveTask.ContinueWith(t =>
            {
                // Propagate exception from initialization if occured
                if (t.Exception != null)
                {
                    completionSource.TrySetException(t.Exception);
                }
            });

            completionSource.Task.GetAwaiter().GetResult();

            Initialized = true;
            return(this);
        }
Beispiel #18
0
        /// <summary>
        /// Remove the two frames from the given NetMQMessage, interpreting them thusly:
        /// 1. a byte with the HandshakeType,
        /// 2. a byte-array containing the X.509 digital certificate.
        /// </summary>
        /// <param name="message">a NetMQMessage - which must have 2 frames</param>
        /// <exception cref="NetMQSecurityException"><see cref="NetMQSecurityErrorCode.InvalidFramesCount"/>: FrameCount must be 1.</exception>
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            NetMQFrame lengthFrame      = message.Pop();
            NetMQFrame certslengthFrame = message.Pop();
            NetMQFrame certlengthFrame  = message.Pop();

            base.SetFromNetMQMessage(message);
        }
Beispiel #19
0
        /// <summary>
        /// Strip the message from the first frame and if empty the following frame as well
        /// </summary>
        /// <returns>the first frame of the message</returns>
        private static NetMQFrame Unwrap (NetMQMessage msg)
        {
            var result = msg.Pop ();

            if (msg.First.IsEmpty)
                msg.Pop ();

            return result;
        }
Beispiel #20
0
        /// <summary>
        ///     returns the first frame and deletes the next frame if it is empty
        ///
        ///     CHANGES message!
        /// </summary>
        private static NetMQFrame UnWrap (NetMQMessage message)
        {
            var frame = message.Pop ();

            if (message.First == NetMQFrame.Empty)
                message.Pop ();

            return frame;
        }
Beispiel #21
0
        /// <summary>
        ///     get the identity of the sending socket
        ///     we hereby assume that the message has the following
        ///     sequence of frames and strips that off the message
        ///
        ///     [identity][empty][data]
        ///
        ///     whereby [data] cold be a wrapped message itself!
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        static byte[] Unwrap(NetMQMessage msg)
        {
            var idFrame = msg.Pop();

            // throw away the empty frame
            msg.Pop();

            return(idFrame.Buffer);
        }
Beispiel #22
0
        /// <summary>
        ///     returns the first frame and deletes the next frame if it is empty
        ///
        ///     CHANGES message!
        /// </summary>
        private NetMQFrame UnWrap(NetMQMessage message)
        {
            var frame = message.Pop();

            if (message.First == NetMQFrame.Empty)
            {
                message.Pop();
            }

            return(frame);
        }
Beispiel #23
0
        /// <summary>
        /// Strip the message from the first frame and if empty the following frame as well
        /// </summary>
        /// <returns>the first frame of the message</returns>
        private NetMQFrame Unwrap(NetMQMessage msg)
        {
            var result = msg.Pop();

            if (msg.First.IsEmpty)
            {
                msg.Pop();
            }

            return(result);
        }
Beispiel #24
0
        ///<summary>
        /// Construct a Message from ReceivedFrames - according to
        /// <para>Frame 1 - RequestTypeName</para>
        /// <para>Frame 2 - Successful parsing and use of Incoming Instance of RequestType / on Response it is the successful deserialization</para>
        /// <para>Frame 3 - Actual Payload and instance of the RequestType</para>
        ///</summary>
        internal static XtResult <TMessage> ParseRqRepMessage <TMessage>(this NetMQMessage msg, SocketConfiguration configuration)
            where TMessage : class
        {
            configuration.Logger.Log(new DebugLogMsg($"parsing [{typeof(TMessage)}]"));
            const string operation = "parse-rq-rep-msg";

            #region precondition checks
            if (msg.FrameCount != 3)
            {
                var exc = ZeroMqXtSocketException.MissedExpectedFrameCount(msg.FrameCount);
                configuration.Logger.Log(new DebugLogMsg(exc.Message));
                return(XtResult <TMessage> .Failed(exc, operation));
            }

            byte[] typeFrame    = msg.Pop().ToByteArray();
            byte[] successFrame = msg.Pop().ToByteArray();
            byte[] payloadFrame = msg.Pop().ToByteArray();

            string msgType       = typeof(TMessage).TypeFrameName();
            string typeFromFrame = configuration.Serializer.Deserialize <string>(typeFrame);
            if (typeFromFrame != msgType)
            {
                var exception = ZeroMqXtSocketException.Frame1TypeDoesNotMatch <TMessage>(typeFromFrame);
                configuration.Logger.Log(new DebugLogMsg(exception.Message));
                return(XtResult <TMessage> .Failed(exception, operation));
            }

            bool isSuccess = Convert.ToBoolean(configuration.Serializer.Deserialize <string>(successFrame));
            if (!isSuccess)
            {
                var exceptnText = configuration.Serializer.Deserialize <string>(payloadFrame);
                var excption    = new ZeroMqXtSocketException("Server failed with" + exceptnText);
                configuration.Logger.Log(new DebugLogMsg(excption.Message));
                return(XtResult <TMessage> .Failed(excption, operation));
            }
            #endregion

            try
            {
                // actual message body deserialization
                TMessage result = configuration.Serializer.Deserialize <TMessage>(payloadFrame);
                if (result == default(TMessage))
                {
                    return(XtResult <TMessage> .Failed(new ArgumentNullException($"{typeof(TMessage)} yielded the default value on deserializing! Proceeding is not safe."), operation));
                }

                configuration.Logger.Log(new DebugLogMsg($"parsing was successful for [{typeof(TMessage)}]"));
                return(XtResult <TMessage> .Success(result, operation));
            }
            catch (System.Exception ex)
            {
                return(XtResult <TMessage> .Failed(ZeroMqXtSocketException.SerializationFailed(ex.Message), operation));
            }
        }
Beispiel #25
0
        /// <summary>
        /// Strip the first frame of a message and the following if it is empty
        /// </summary>
        /// <returns>the first frame and changes the message</returns>
        private static NetMQFrame Unwrap(NetMQMessage msg)
        {
            var id = msg.Pop();

            // forget the empty frame
            if (msg.First.IsEmpty)
            {
                msg.Pop();
            }

            return(id);
        }
Beispiel #26
0
        public void Handle(NetMQFrame[] sender, NetMQMessage message)
        {
            Logger.Debug("[Queue_SubscribeHandler] Received subscribe request.");

            var requestId = message.Pop();
            var context = message.Pop().ConvertToString();
            var queueId = message.Pop().ConvertToString();
            var subscriberId = message.Pop().ConvertToString();
            var filter = message.Pop().ConvertToString();
            var utcStartTime = message.PopDateTime();
            var allocationSize = message.PopInt32();
            var allocationTimeInMilliseconds = message.PopInt32();

            var subscribe = new SubscribeToQueue(context,
                queueId,
                subscriberId,
                filter,
                utcStartTime, allocationSize, allocationTimeInMilliseconds);

            var queuedEvents = _storage.Subscribe(subscribe);
            var events = queuedEvents.Events;

            var msg = new NetMQMessage();
            msg.Append(sender);
            msg.AppendEmptyFrame();
            msg.Append(ResProtocol.ResClient01);
            msg.Append(requestId);
            msg.Append(ResCommands.QueuedEvents);
            msg.Append(context);
            msg.Append(queueId);
            msg.Append(subscriberId);
            msg.Append(DateTime.UtcNow.ToNetMqFrame());
            msg.Append(queuedEvents.AllocationId.ToNetMqFrame());

            var count = events.Length;
            msg.Append(count.ToNetMqFrame());

            foreach (var e in events)
            {
                msg.Append(e.EventId.ToByteArray());
                msg.Append(e.Stream);
                msg.Append(e.Context);
                msg.Append(e.Sequence.ToNetMqFrame());
                msg.Append(e.Timestamp.ToNetMqFrame());
                msg.Append(e.TypeKey);
                msg.Append(e.Headers.ToNetMqFrame());
                msg.Append(e.Body);
            }

            var result = new QueuedMessagesFetched(msg);
            while (!_outBuffer.Offer(result))
                _spin.SpinOnce();
        }
Beispiel #27
0
        private void DealerSocket_ReceiveReady(object sender, NetMQSocketEventArgs e)
        {
            NetMQMessage message  = e.Socket.ReceiveMultipartMessage();
            string       address  = message.Pop().ConvertToString(Encoding.UTF8);
            string       content  = message.Pop().ConvertToString(Encoding.UTF8);
            OwinResponse response = _serializer.Deserialize <OwinResponse>(content);

            if (_requests.TryRemove(response.RequestId, out var taskCompletion))
            {
                taskCompletion.SetResult(response);
            }
        }
Beispiel #28
0
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            var serverTread = new Thread(() =>
            {
                Log("Start server.");
                var _server = new ReliableServer("tcp://*:6669");

                var index = 0;

                while (true)
                {
                    var message = new NetMQMessage();
                    message.Append("A");
                    message.Append("hello: " + index);
                    message.Append("world");
                    _server.Publish(message);
                    Console.WriteLine("publishing: " + message);
                    Thread.Sleep(100);
                    index++;
                }
            });

            serverTread.Start();
            //		client_thread_.Start();

            //new SimpleClient().Run("tcp://localhost:6669");
            var clientTread = new Thread(() =>
            {
                Log("Start client.");
                var _client = new ReliableClient("tcp://localhost:6669");
                _client.Subscribe("A");

                while (true)
                {
                    NetMQMessage msg = null;
                    msg = _client.ReceiveMessage();
                    if (msg != null)
                    {
                        var topic   = msg.Pop().ConvertToString();
                        var message = msg.Pop().ConvertToString();
                        var output  = String.Format("reviced topic: {0}, message: {1}", topic, message);
                        Log(output);
                    }
                    Thread.Sleep(10);
                }
            });

            clientTread.Start();

            Console.ReadLine();
        }
Beispiel #29
0
        public static List <Int64> UnpackMessageListInt64(this NetMQMessage msg)
        {
            var          cnt  = (int)msg.Pop().ConvertToInt32();
            var          buff = msg.Pop().ToByteArray();
            var          rdr  = new BinaryReader(new MemoryStream(LZ4Codec.Unwrap(buff)));
            List <Int64> ret  = new List <Int64>();

            while (cnt-- > 0)
            {
                ret.Add(rdr.ReadInt64());
            }
            return(ret);
        }
Beispiel #30
0
            protected override void OnOutgoingMessage(NetMQMessage message)
            {
                byte[] identity = message.Pop().ToByteArray();

                //  Each frame is a full ZMQ message with identity frame
                while (message.FrameCount > 0)
                {
                    var data = message.Pop().ToByteArray(false);
                    bool more = message.FrameCount > 0;

                    WriteOutgoing(identity, data, more);
                }
            }
Beispiel #31
0
        public static List <T> UnpackMessageList <T>(NetMQMessage msg, Func <Stream, T> parseObject) where T : IMessage
        {
            var      cnt  = (int)msg.Pop().ConvertToInt32();
            var      buff = msg.Pop().ToByteArray();
            var      rdr  = new MemoryStream(buff);
            List <T> ret  = new List <T>();

            while (cnt-- > 0)
            {
                ret.Add(parseObject(rdr));
            }
            return(ret);
        }
Beispiel #32
0
        protected static Tuple <NetMQMessage, Tuple <ServermoduleID, CallID> > SplitMessageInContentAndMetaData(NetMQMessage message)
        {
            var servermoduleID = Convert.ToInt32(message.Pop().ConvertToString());
            var callID         = Convert.ToInt32(message.Pop().ConvertToString());

            return(new Tuple <NetMQMessage, Tuple <ServermoduleID, CallID> >(message, new Tuple <ServermoduleID, CallID>(new ServermoduleID()
            {
                ID = servermoduleID
            }, new CallID()
            {
                ID = callID
            })));
        }
Beispiel #33
0
            protected override void OnOutgoingMessage(NetMQMessage message)
            {
                byte[] identity = message.Pop().ToByteArray();

                //  Each frame is a full ZMQ message with identity frame
                while (message.FrameCount > 0)
                {
                    var  data = message.Pop().ToByteArray(false);
                    bool more = message.FrameCount > 0;

                    WriteOutgoing(identity, data, more);
                }
            }
        public void ProcessMessage(NetMQMessage message, NetMQSocket socket)
        {
            if (message.FrameCount < 3)
                throw new MalformedMessageReceivedException(message.FrameCount);

            var sender = message.PopUntilEmptyFrame();
            var protocolFrame = message.Pop();
            var protocol = protocolFrame.ConvertToString();
            ensureProtocol(protocol);
            var command = message.Pop().ConvertToString();

            _dispatcher.Dispatch(command, sender, message);
        }
        private static void Main(string[] args)
        {
            var deciSecond = new TimeSpan(10000);

            using (var subscriber = new SubscriberSocket()) // For receiving updates from presentation host
                using (var publisher = new WSPublisher())   // For publishing updates from presentation host to audience
                    using (var responder = new WSRouter())  // Handling on-demand requests for late-joining or crashing clients
                    {
                        subscriber.Bind("tcp://*:3000");
                        subscriber.SubscribeToAnyTopic();
                        publisher.Bind("ws://*:3001");
                        responder.Bind("ws://*:3002");

                        byte step = 0;
                        subscriber.ReceiveReady += (_, __) => {
                            if (!subscriber.TryReceiveFrameBytes(deciSecond, out var received))
                            {
                                return;
                            }
                            step = received[0];
                            Console.Out.WriteLine("Sending " + step + " to audience.");
                            publisher.TrySendFrame(deciSecond, new[] { step });
                        };
                        responder.ReceiveReady += (_, __) => {
                            NetMQMessage msg = null;
                            if (!responder.TryReceiveMultipartMessage(deciSecond, ref msg))
                            {
                                return;
                            }
                            var identity = msg.Pop().Buffer;
                            var request  = msg.Pop().ConvertToString();
                            msg.Clear();
                            if (request == "Which slide are we on?")
                            {
                                responder.TrySendMultipartBytes(deciSecond, identity, new[] { step });
                            }
                            else
                            {
                                if (!responder.TrySendFrame(deciSecond, identity, true))
                                {
                                    return;
                                }
                                responder.TrySendFrameEmpty(deciSecond);
                            }
                        };
                        new NetMQPoller {
                            subscriber, responder
                        }.Run();                               // Polling both subscriber and router sockets.
                    }
        }
Beispiel #36
0
        public QueryFillsResponse QueryFill(RequestHeader header, QueryFillsRequest payload)
        {
            NetMQMessage response = Channels.SendRequest(BuildMessage(header, payload));

            ResponseHeader responseHeader = ResponseHeader.Parser.ParseFrom(response.Pop().ToByteArray());

            WriteLog(responseHeader.ToString());

            QueryFillsResponse responsePayload = QueryFillsResponse.Parser.ParseFrom(response.Pop().ToByteArray());

            WriteLog(responsePayload.ToString());
            FillsReceived?.Invoke(responsePayload);
            return(responsePayload);
        }
		public Task Send(ArraySegment<byte> data, params object[] connectionIDs)
		{
			var task = new Task(() =>
			{
				var msg = new NetMQMessage();
				if (_socket is RouterSocket)
				{
					msg.Append(new byte[0]);
					msg.AppendEmptyFrame();
				}
				msg.Append(data.Count == data.Array.Length ? data.Array : data.ToArray());

				if (connectionIDs.Length <= 0)
					_socket.SendMultipartMessage(msg);
				else
				{
					foreach (var connection in connectionIDs)
					{
						if (_socket is RouterSocket && connection is byte[])
						{
							msg.Pop();
							msg.Push(((byte[])connection));
						}
						_socket.SendMultipartMessage(msg);
					}
				}
			});
			task.Start(_scheduler);
			return task;
		}
        /// <summary>
        /// Remove the three frames from the given NetMQMessage, interpreting them thusly:
        /// 1. a byte with the HandshakeType,
        /// 2. RandomNumber (a byte-array),
        /// 3. a 2-byte array with the CipherSuite in the 2nd byte.
        /// </summary>
        /// <param name="message">a NetMQMessage - which must have 3 frames</param>
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 2)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            // Get the random number
            NetMQFrame randomNumberFrame = message.Pop();
            RandomNumber = randomNumberFrame.ToByteArray();

            // Get the cipher suite
            NetMQFrame cipherSuiteFrame = message.Pop();
            CipherSuite = (CipherSuite)cipherSuiteFrame.Buffer[1];
        }
Beispiel #39
0
        public virtual void SetFromNetMQMessage(NetMQMessage message)
        {
            if (message.FrameCount == 0)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            // remove the handshake type column
            message.Pop();
        }
Beispiel #40
0
 public void Handle(NetMQFrame[] sender, NetMQMessage message)
 {
     Log.Debug("[CommitHandler] Got a commit to write...");
     var requestId = message.Pop();
     var commit = getCommit(message);
     var task = _writer.Store(commit);
     var commitContinuationContext = new CommitContinuationContext(sender, commit.CommitId, requestId);
     task.ContinueWith(onComplete, commitContinuationContext, TaskContinuationOptions.ExecuteSynchronously);
     Log.Debug("[CommitHandler] Commit queued up...");
 }
        public void Handle(NetMQFrame[] sender, NetMQMessage message)
        {
            Logger.Debug("[Query_LoadEventsByStream] Received a request.");

            var requestId = message.Pop();
            var context = message.Pop().ConvertToString();
            var stream = message.Pop().ConvertToString();

            var fromVersion = message.PopInt64();

            var maxVersion = message.PopNullableInt64();

            var events = _storage.LoadEventsForStream(context, stream, fromVersion, maxVersion);

            var msg = new NetMQMessage();
            msg.Append(sender);
            msg.AppendEmptyFrame();
            msg.Append(ResProtocol.ResClient01);
            msg.Append(requestId);
            msg.Append(ResCommands.QueryEventsByStreamResponse);

            var count = events.Length;

            msg.Append(count.ToNetMqFrame());

            foreach (var e in events)
            {
                msg.Append(e.EventId.ToByteArray());
                msg.Append(e.Stream);
                msg.Append(e.Context);
                msg.Append(e.Sequence.ToNetMqFrame());
                msg.Append(e.Timestamp.ToNetMqFrame());
                msg.Append(e.TypeKey);
                msg.Append(e.Headers.ToNetMqFrame());
                msg.Append(e.Body);
            }

            var result = new QueryEventsForStreamLoaded(msg);
            while (!_buffer.Offer(result))
                _spin.SpinOnce();
        }
        /// <summary>
        /// Remove the two frames from the given NetMQMessage, interpreting them thusly:
        /// 1. a byte with the HandshakeType, assumed to be ClientKeyExchange
        /// 2. a byte-array containing the EncryptedPreMasterSecret.
        /// </summary>
        /// <param name="message">a NetMQMessage - which must have 2 frames</param>
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 1)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            NetMQFrame preMasterSecretFrame = message.Pop();

            EncryptedPreMasterSecret = preMasterSecretFrame.ToByteArray();
        }
Beispiel #43
0
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 1)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            NetMQFrame verifyDataFrame = message.Pop();

            VerifyData = verifyDataFrame.ToByteArray();
        }
Beispiel #44
0
        public override void SetFromNetMQMessage(NetMQMessage message)
        {
            base.SetFromNetMQMessage(message);

            if (message.FrameCount != 1)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "Malformed message");
            }

            NetMQFrame certificateFrame = message.Pop();

            byte[] certificteBytes = certificateFrame.ToByteArray();

            Certificate = new X509Certificate2();
            Certificate.Import(certificteBytes);
        }
Beispiel #45
0
            protected override void OnIncomingMessage(byte[] identity, NetMQMessage message)
            {
                byte[] data = message.Pop().ToByteArray();

                if (data.Length > 0 && (data[0] == 1 || data[0] == 0))
                {
                    if (data[0] == 0)
                    {
                        m_subscriptions.Remove(data, 1, identity);
                    }
                    else
                    {
                        m_subscriptions.Add(data, 1, identity);
                    }
                }
            }
Beispiel #46
0
            protected override void OnOutgoingMessage(NetMQMessage message)
            {                
                m_subscriptions.Match(message[0].ToByteArray(false), message[0].MessageSize, s_markAsMatching, this);

                while(message.FrameCount >0)
                {
                    var frame = message.Pop().ToByteArray();
                    bool more = message.FrameCount > 0;

                    for (int i = 0; i < m_matching; i++)
                    {
                        WriteOutgoing(m_identities[i], frame, more);                        
                    }    
                }
                             
                m_matching = 0;                                              
            }
Beispiel #47
0
        public static ZreMessage Decode(NetMQMessage message)
        {
            var msg = new ZreMessage(0);
            var frame = message.Pop();
            if (frame == null)
            {
                return null;
            }

            msg._needle = frame.ToByteArray();
            msg._needleReader = new BinaryReader(new MemoryStream(msg._needle));
            msg._needleWriter = new BinaryWriter(new MemoryStream(msg._needle));
            msg._ceiling = msg._needle.Length + frame.MessageSize;
            var signature = msg._needleReader.GetNumber2();
            if (signature != (0xAAA0 | ZreConstants.ProtocolSignature))
            {
                return null;
            }

            msg._id = (ZreMessageType)msg._needleReader.GetNumber1();

            switch (msg._id)
            {
                case ZreMessageType.Hello:
                {
                    msg._version = msg._needleReader.GetNumber1();
                    if (msg._version != ZreConstants.ProtocolVersion)
                    {
                        return null;
                    }
                    msg._sequence = msg._needleReader.GetNumber2();
                    msg._endpoint = msg._needleReader.GetString();

                    var listSize = msg._needleReader.GetNumber4();
                    msg._groups = new HashSet<string>();
                    while (listSize-- > 0)
                    {
                        var groupName = msg._needleReader.GetLongString();
                        msg._groups.Add(groupName);
                    }
                    msg._status = msg._needleReader.GetNumber1();
                    msg._name = msg._needleReader.GetString();

                    var hashSize = msg._needleReader.GetNumber4();
                    msg._headers = new ConcurrentDictionary<string, string>();
                    while (hashSize-- > 0)
                    {
                        var key = msg._needleReader.GetString();
                        var value = msg._needleReader.GetLongString();
                        msg._headers.Add(key, value);
                    }
                }
                break;
                case ZreMessageType.Whisper:
                {
                    msg._version = msg._needleReader.GetNumber1();
                    if (msg._version != ZreConstants.ProtocolVersion)
                    {
                        return null;
                    }
                    msg._sequence = msg._needleReader.GetNumber2();
                    //  Get zero or more remaining frames, leaving current
                    //  frame untouched
                    msg._content = new NetMQMessage();
                    while (!message.IsEmpty)
                    {
                        msg._content.Append(message.Pop());
                    }

                    if (msg._content.IsEmpty)
                    {
                        msg._content.AppendEmptyFrame();
                    }
                }
                break;
                case ZreMessageType.Shout:
                {
                    msg._version = msg._needleReader.GetNumber1();
                    if (msg._version != ZreConstants.ProtocolVersion)
                    {
                        return null;
                    }
                    msg._sequence = msg._needleReader.GetNumber2();
                    msg._group = msg._needleReader.GetString();
                    //  Get zero or more remaining frames, leaving current
                    //  frame untouched
                    msg._content = new NetMQMessage();
                    while (!message.IsEmpty)
                    {
                        msg._content.Append(message.Pop());
                    }

                    if (msg._content.IsEmpty)
                    {
                        msg._content.AppendEmptyFrame();
                    }
                }
                break;
                case ZreMessageType.Join:
                {
                    msg._version = msg._needleReader.GetNumber1();
                    if (msg._version != ZreConstants.ProtocolVersion)
                    {
                        return null;
                    }
                    msg._sequence = msg._needleReader.GetNumber2();
                    msg._group = msg._needleReader.GetString();
                    msg._status = msg._needleReader.GetNumber1();
                }
                break;
                case ZreMessageType.Leave:
                {
                    msg._version = msg._needleReader.GetNumber1();
                    if (msg._version != ZreConstants.ProtocolVersion)
                    {
                        return null;
                    }
                    msg._sequence = msg._needleReader.GetNumber2();
                    msg._group = msg._needleReader.GetString();
                    msg._status = msg._needleReader.GetNumber1();
                }
                break;
                case ZreMessageType.Ping:
                {
                    msg._version = msg._needleReader.GetNumber1();
                    if (msg._version != ZreConstants.ProtocolVersion)
                    {
                        return null;
                    }
                    msg._sequence = msg._needleReader.GetNumber2();
                }
                break;
                case ZreMessageType.PingOk:
                {
                    msg._version = msg._needleReader.GetNumber1();
                    if (msg._version != ZreConstants.ProtocolVersion)
                    {
                        return null;
                    }
                    msg._sequence = msg._needleReader.GetNumber2();
                }
                break;
            }

            return msg;
        }
Beispiel #48
0
        /// <summary>
        ///     process REQUEST from a client. MMI requests are implemented here directly
        /// </summary>
        /// <param name="sender">client identity</param>
        /// <param name="message">the message received</param>
        public void ProcessClientMessage (NetMQFrame sender, NetMQMessage message)
        {
            // should be
            // REQUEST      [service name][request] OR 
            // DISCOVER     ['mmi.service'][service to discover]
            if (message.FrameCount < 2)
                throw new ArgumentException ("The message is malformed!");

            var serviceFrame = message.Pop ();                 // [request] OR [service to discover]
            var serviceName = serviceFrame.ConvertToString ();
            var request = Wrap (sender, message);              // [CLIENT ADR][e][request] OR [service name]

            // if it is a "mmi.service" request, handle it locally
            // this request searches for a service and returns a code indicating the result of that search
            // 200 =>   service exists and worker are available
            // 400 =>   service exists but no workers are available
            // 501 =>   service does not exist
            if (serviceName == "mmi.service")
            {
                var returnCode = "501";
                var name = request.Last.ConvertToString ();

                if (m_services.Exists (s => s.Name == name))
                {
                    var svc = m_services.Find (s => s.Name == name);

                    returnCode = svc.DoWorkersExist () ? "200" : "400";
                }
                // set the return code to be the last frame in the message
                var rc = new NetMQFrame (returnCode);           // [return code]

                request.RemoveFrame (message.Last);             // [CLIENT ADR][e] -> [service name]
                request.Append (serviceName);                   // [CLIENT ADR][e] <- ['mmi.service']
                request.Append (rc);                            // [CLIENT ADR][e]['mmi.service'] <- [return code]

                // remove client return envelope and insert 
                // protocol header and service name, 
                // then rewrap envelope
                var client = UnWrap (request);                  // [return code]
                request.Push (MDPClientHeader);                 // [protocol header][return code]
                var reply = Wrap (client, request);             // [CLIENT ADR][e][protocol header][return code]

                // send to back to CLIENT(!)
                Socket.SendMessage (reply);

                Log (string.Format ("[BROKER] MMI request processed. Answered {0}", reply));
            }
            else
            {
                // get the requested service object
                var service = ServiceRequired (serviceName);

                // a standard REQUEST received
                Log (string.Format ("[BROKER] Dispatching request -> {0}", request));

                // send to a worker offering the requested service
                // will add command, header and worker adr envelope
                ServiceDispatch (service, request);             // [CLIENT ADR][e][request]
            }
        }
Beispiel #49
0
        /// <summary>
        /// Strip the message from the first frame and if empty the following frame as well
        /// </summary>
        /// <returns>the first frame of the message</returns>
        private NetMQFrame Unwrap(NetMQMessage msg)
        {
            var result = msg.Pop();

            if (msg.First.IsEmpty)
                msg.Pop();

            return result;
        }
Beispiel #50
0
        public static ZreEvent Create(NetMQMessage message)
        {
            if (message == null || message.IsEmpty || message.FrameCount < 3)
            {
                return null;
            }

            var self = new ZreEvent();
            var type = message.Pop().ConvertToString();
            self.Sender = message.Pop().ConvertToString();
            self.Name = message.Pop().ConvertToString();

            if (type == Enter)
            {
                self.Type = ZreEventType.Enter;
                var headersFrame = message.Pop();
                if (headersFrame != null)
                {
                    var headers = headersFrame.ToByteArray().UnpackHeaders();
                    self.Headers = headers;
                }

                self.Address = message.Pop().ConvertToString();
            }
            else if (type == Exit)
            {
                self.Type = ZreEventType.Exit;
            }
            else if (type == Join)
            {
                self.Type = ZreEventType.Join;
                self.Group = message.Pop().ConvertToString();
            }
            else if (type == Leave)
            {
                self.Type = ZreEventType.Leave;
                self.Group = message.Pop().ConvertToString();
            }
            else if (type == Whisper)
            {
                self.Type = ZreEventType.Whisper;
                self.Message = message;
            }
            else if (type == Shout)
            {
                self.Type = ZreEventType.Shout;
                self.Group = message.Pop().ConvertToString();
                self.Message = message;
            }
            else if (type == Stop)
            {
                self.Type = ZreEventType.Stop;
            }
            else if (type == Evasive)
            {
                self.Type = ZreEventType.Evasive;
            }

            return self;
        }
Beispiel #51
0
        public NetMQMessage DecryptMessage(ContentType contentType, NetMQMessage cipherMessage)
        {
            if (SecurityParameters.BulkCipherAlgorithm == BulkCipherAlgorithm.Null &&
              SecurityParameters.MACAlgorithm == MACAlgorithm.Null)
            {
                return cipherMessage;
            }

            if (cipherMessage.FrameCount < 2)
            {
                throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFramesCount, "cipher message should have at least 2 frames, iv and sequence number");
            }

            NetMQFrame ivFrame = cipherMessage.Pop();

            m_decryptionBulkAlgorithm.IV = ivFrame.ToByteArray();

            using (var decryptor = m_decryptionBulkAlgorithm.CreateDecryptor())
            {
                NetMQMessage plainMessage = new NetMQMessage();

                NetMQFrame seqNumFrame = cipherMessage.Pop();

                byte[] frameBytes;
                byte[] seqNumMAC;
                byte[] padding;

                DecryptBytes(decryptor, seqNumFrame.ToByteArray(), out frameBytes, out seqNumMAC, out padding);

                ulong seqNum = BitConverter.ToUInt64(frameBytes, 0);
                int frameCount = BitConverter.ToInt32(frameBytes, 8);

                int frameIndex = 0;

                ValidateBytes(contentType, seqNum, frameIndex, frameBytes, seqNumMAC, padding);

                if (CheckReplayAttack(seqNum))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.ReplayAttack,
                                  "Message already handled or very old message, might be under replay attack");
                }

                if (frameCount != cipherMessage.FrameCount)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.EncryptedFramesMissing, "Frames was removed from the encrypted message");
                }

                frameIndex++;

                foreach (NetMQFrame cipherFrame in cipherMessage)
                {
                    byte[] data;
                    byte[] mac;

                    DecryptBytes(decryptor, cipherFrame.ToByteArray(), out data, out mac, out padding);
                    ValidateBytes(contentType, seqNum, frameIndex, data, mac, padding);

                    frameIndex++;

                    plainMessage.Append(data);
                }

                return plainMessage;
            }
        }
Beispiel #52
0
        /// <summary>
        ///   verifies if the message replied obeys the MDP 0.2 protocol
        /// </summary>
        /// <remarks>
        ///     socket strips [client adr][e] from message
        ///     message -> 
        ///                [empty frame][protocol header][service name][reply]
        ///                [empty frame][protocol header][service name][result code of service lookup]
        /// </remarks>
        private void ExtractFrames(NetMQMessage reply)
        {
            if (reply.FrameCount < 4)
                throw new ApplicationException("[CLIENT ERROR] received a malformed reply");

            var emptyFrame = reply.Pop();
            if (emptyFrame != NetMQFrame.Empty)
            {
                throw new ApplicationException($"[CLIENT ERROR] received a malformed reply expected empty frame instead of: { emptyFrame } ");
            }
            var header = reply.Pop(); // [MDPHeader] <- [service name][reply] OR ['mmi.service'][return code]

            if (header.ConvertToString() != m_mdpClient)
                throw new ApplicationException($"[CLIENT INFO] MDP Version mismatch: {header}");

            var service = reply.Pop(); // [service name or 'mmi.service'] <- [reply] OR [return code]

            if (service.ConvertToString() != m_serviceName)
                throw new ApplicationException($"[CLIENT INFO] answered by wrong service: {service.ConvertToString()}");
        }
Beispiel #53
0
        /// <summary>
        /// Strip the first frame of a message and the following if it is empty
        /// </summary>
        /// <returns>the first frame and changes the message</returns>
        private static NetMQFrame Unwrap(NetMQMessage msg)
        {
            var id = msg.Pop();
            // forget the empty frame
            if (msg.First.IsEmpty)
                msg.Pop();

            return id;
        }
Beispiel #54
0
        /// <summary>
        /// Check the message envelope for errors
        /// and get the MDP Command embedded.
        /// The message will be altered!
        /// </summary>
        /// <param name="request">NetMQMessage received</param>
        /// <returns>the received MDP Command</returns>
        private MDPCommand GetMDPCommand(NetMQMessage request)
        {
            // don't try to handle errors
            if (request.FrameCount < 3)
                throw new ApplicationException("Malformed request received!");

            var empty = request.Pop();

            if (!empty.IsEmpty)
                throw new ApplicationException("First frame must be an empty frame!");

            var header = request.Pop();

            if (header.ConvertToString() != m_mdpWorker)
                throw new ApplicationException("Invalid protocol header received!");

            var cmd = request.Pop();

            if (cmd.BufferSize > 1)
                throw new ApplicationException("MDP Command must be one byte not multiple!");

            var command = (MDPCommand)cmd.Buffer[0];

            Log(string.Format("[WORKER] received {0}/{1}", request, command));

            return command;
        }
Beispiel #55
0
        /// <summary>
        ///     get the identity of the sending socket
        ///     we hereby assume that the message has the following
        ///     sequence of frames and strips that off the message
        /// 
        ///     [identity][empty][data]
        /// 
        ///     whereby [data] cold be a wrapped message itself!
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private static byte[] Unwrap(NetMQMessage msg)
        {
            var idFrame = msg.Pop();
            // throw away the empty frame
            msg.Pop();

            return idFrame.Buffer;
        }
Beispiel #56
0
        /// <summary>
        ///     returns the first frame and deletes the next frame if it is empty
        /// 
        ///     CHANGES message!
        /// </summary>
        private static NetMQFrame UnWrap (NetMQMessage message)
        {
            var frame = message.Pop ();

            if (message.First == NetMQFrame.Empty)
                message.Pop ();

            return frame;
        }
Beispiel #57
0
        /// <summary>
        /// Process handshake and change cipher suite messages. This method should be called for every incoming message until the method returns true.
        /// You cannot encrypt or decrypt messages until the method return true.
        /// Each call to the method may include outgoing messages that need to be sent to the other peer.
        /// </summary>
        /// <param name="incomingMessage">the incoming message from the other peer</param>
        /// <param name="outgoingMesssages">the list of outgoing messages that need to be sent to the other peer</param>
        /// <returns>true when the method completes the handshake stage and the SecureChannel is ready to encrypt and decrypt messages</returns>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidContentType: Unknown content type.</exception>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidFrameLength: Wrong length for protocol version frame.</exception>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidFrameLength: Wrong length for message size.</exception>
        /// <exception cref="NetMQSecurityException">NetMQSecurityErrorCode.InvalidProtocolVersion: Wrong protocol version.</exception>
        /// <remarks>
        /// Note: Within this library, this method is ONLY called from within the unit-tests.
        /// </remarks>
        public bool ProcessMessage(NetMQMessage incomingMessage, IList<NetMQMessage> outgoingMesssages)
        {
            ContentType contentType = ContentType.Handshake;

            if (incomingMessage != null)
            {
                // Verify that the first two frames are the protocol-version and the content-type,
                NetMQFrame protocolVersionFrame = incomingMessage.Pop();
                byte[] protocolVersionBytes = protocolVersionFrame.ToByteArray();

                if (protocolVersionBytes.Length != 2)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "Wrong length for protocol version frame");
                }

                if (!protocolVersionBytes.SequenceEqual(m_protocolVersion))
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidProtocolVersion, "Wrong protocol version");
                }

                NetMQFrame contentTypeFrame = incomingMessage.Pop();

                if (contentTypeFrame.MessageSize != 1)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidFrameLength, "wrong length for message size");
                }

                // Verify that the content-type is either handshake, or change-cipher-suit..
                contentType = (ContentType)contentTypeFrame.Buffer[0];

                if (contentType != ContentType.ChangeCipherSpec && contentType != ContentType.Handshake)
                {
                    throw new NetMQSecurityException(NetMQSecurityErrorCode.InvalidContentType, "Unknown content type");
                }

                if (ChangeSuiteChangeArrived)
                {
                    incomingMessage = m_recordLayer.DecryptMessage(contentType, incomingMessage);
                }
            }

            bool result = false;

            if (contentType == ContentType.Handshake)
            {
                result = m_handshakeLayer.ProcessMessages(incomingMessage, m_outgoingMessageBag);

                // Move the messages from the saved list over to the outgoing Messages collection..
                foreach (NetMQMessage outgoingMesssage in m_outgoingMessageBag.Messages)
                {
                    outgoingMesssages.Add(outgoingMesssage);
                }

                m_outgoingMessageBag.Clear();
            }
            else
            {
                ChangeSuiteChangeArrived = true;
            }

            return (SecureChannelReady = result && ChangeSuiteChangeArrived);
        }
Beispiel #58
0
 /// <summary>
 /// Utility to read a Guid from a message.
 /// We transmit 16 bytes that define the Uuid.
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 private static Guid PopGuid(NetMQMessage message)
 {
     var bytes = message.Pop().ToByteArray();
     Debug.Assert(bytes.Length == 16);
     var uuid = new Guid(bytes);
     return uuid;
 }
Beispiel #59
0
        /// <summary>
        ///     process a READY, REPLY, HEARTBEAT, DISCONNECT message sent to the broker by a worker
        /// </summary>
        /// <param name="sender">the sender identity frame</param>
        /// <param name="message">the message sent</param>
        public void ProcessWorkerMessage (NetMQFrame sender, NetMQMessage message)
        {
            // should be 
            // READY        [mdp command][service name]
            // REPLY        [mdp command][client adr][e][reply]
            // HEARTBEAT    [mdp command]
            if (message.FrameCount < 1)
                throw new ApplicationException ("Message with too few frames received.");

            var mdpCommand = message.Pop ();                // get the mdp command frame it should have only one byte payload

            if (mdpCommand.BufferSize > 1)
                throw new ApplicationException ("The MDPCommand frame had more than one byte!");

            var cmd = (MDPCommand) mdpCommand.Buffer[0];    // [service name] or [client adr][e][reply]
            var workerId = sender.ConvertToString ();       // get the id of the worker sending the message
            var workerIsKnown = m_knownWorkers.Any (w => w.Id == workerId);

            switch (cmd)
            {
                case MDPCommand.Ready:
                    if (workerIsKnown)
                    {
                        // then it is not the first command in session -> WRONG
                        // if the worker is know to a service, remove it from that 
                        // service and a potential waiting list therein
                        RemoveWorker (m_knownWorkers.Find (w => w.Id == workerId));

                        Log (string.Format ("[BROKER] READY out of sync. Removed worker {0}.", workerId));
                    }
                    else
                    {
                        // now a new - not know - worker sent his READY initiation message
                        // attach worker to service and mark as idle - worker has send READY as first message
                        var serviceName = message.Pop ().ConvertToString ();
                        var service = ServiceRequired (serviceName);
                        // create a new worker and set the service it belongs to
                        var worker = new Worker (workerId, sender, service);
                        // now add the worker
                        AddWorker (worker, service);

                        Log (string.Format ("[BROKER] READY processed. Worker {0} added to service {1}",
                                            workerId,
                                            serviceName));
                    }
                    break;
                case MDPCommand.Reply:
                    if (workerIsKnown)
                    {
                        var worker = m_knownWorkers.Find (w => w.Id == workerId);
                        // remove the client return envelope and insert the protocol header 
                        // and service name then rewrap the envelope
                        var client = UnWrap (message);                  // [reply]
                        message.Push (worker.Service.Name);             // [service name][reply]
                        message.Push (MDPClientHeader);                 // [protocol header][service name][reply]
                        var reply = Wrap (client, message);             // [client adr][e][protocol header][service name][reply]

                        Socket.SendMessage (reply);

                        Log (string.Format ("[BROKER] REPLY from {0} received and send to {1} -> {2}",
                                            workerId,
                                            client.ConvertToString (),
                                            message));
                        // relist worker for further requests
                        AddWorker (worker, worker.Service);
                    }
                    break;
                case MDPCommand.Heartbeat:
                    if (workerIsKnown)
                    {
                        var worker = m_knownWorkers.Find (w => w.Id == workerId);
                        worker.Expiry = DateTime.UtcNow + m_heartbeatExpiry;

                        Log (string.Format ("[BROKER] HEARTBEAT from {0} received.", workerId));
                    }
                    break;
                default:
                    Log ("[BROKER] ERROR: Invalid MDPCommand received or message received!");
                    break;
            }
        }
Beispiel #60
0
 /// <summary>
 /// Utility to read a Guid from a message.
 /// We transmit 16 bytes that define the Uuid.
 /// </summary>
 /// <param name="message"></param>
 /// <returns></returns>
 private static Guid PopGuid(NetMQMessage message)
 {
     var bytes = message.Pop().ToByteArray();
     if (bytes.Length != 16)
     {
         throw new Exception("Unexpected guid length");
     }
     var uuid = new Guid(bytes);
     return uuid;
 }