Esempio n. 1
0
        public void Move(ref Msg src)
        {
            //  Check the validity of the source.
            if (!src.Check())
            {
                throw NetMQException.Create(ErrorCode.EFAULT);
            }

            Close();

            this = src;

            src.InitEmpty();
        }
Esempio n. 2
0
        public XSub(Ctx parent, int threadId, int sid)
            : base(parent, threadId, sid)
        {
            m_options.SocketType = ZmqSocketType.Xsub;
            m_hasMessage         = false;
            m_more = false;

            m_options.Linger = 0;
            m_fq             = new FQ();
            m_dist           = new Dist();
            m_subscriptions  = new Trie();

            m_message = new Msg();
            m_message.InitEmpty();
        }
Esempio n. 3
0
        public virtual bool PushMsg(ref Msg msg)
        {
            //  First message to receive is identity (if required).
            if (!m_identityReceived)
            {
                msg.SetFlags(MsgFlags.Identity);
                m_identityReceived = true;

                if (!m_options.RecvIdentity)
                {
                    msg.Close();
                    msg.InitEmpty();
                    return(true);
                }
            }

            if (m_pipe != null && m_pipe.Write(ref msg))
            {
                msg.InitEmpty();
                return(true);
            }

            return(false);
        }
Esempio n. 4
0
        public virtual void PushMsg(ref Msg msg)
        {
            //  First message to receive is identity (if required).
            if (!m_identityReceived)
            {
                msg.SetFlags(MsgFlags.Identity);
                m_identityReceived = true;

                if (!m_options.RecvIdentity)
                {
                    msg.Close();
                    msg.InitEmpty();
                    return;
                }
            }

            if (m_pipe != null && m_pipe.Write(ref msg))
            {
                msg.InitEmpty();
                return;
            }

            throw AgainException.Create();
        }
Esempio n. 5
0
        public bool RecvPipe(Pipe[] pipe, ref Msg msg)
        {
            //  Deallocate old content of the message.
            msg.Close();

            //  Round-robin over the pipes to get the next message.
            while (m_active > 0)
            {
                //  Try to fetch new message. If we've already read part of the message
                //  subsequent part should be immediately available.
                bool fetched = m_pipes[m_current].Read(ref msg);

                //  Note that when message is not fetched, current pipe is deactivated
                //  and replaced by another active pipe. Thus we don't have to increase
                //  the 'current' pointer.
                if (fetched)
                {
                    if (pipe != null)
                    {
                        pipe[0] = m_pipes[m_current];
                    }
                    m_more = msg.HasMore;
                    if (!m_more)
                    {
                        m_current = (m_current + 1) % m_active;
                    }
                    return(true);
                }

                //  Check the atomicity of the message.
                //  If we've already received the first part of the message
                //  we should get the remaining parts without blocking.
                Debug.Assert(!m_more);

                m_active--;
                Utils.Swap(m_pipes, m_current, m_active);
                if (m_current == m_active)
                {
                    m_current = 0;
                }
            }

            //  No message is available. Initialise the output parameter
            //  to be a 0-byte message.
            msg.InitEmpty();
            return(false);
        }
Esempio n. 6
0
        protected bool XSend(ref Msg msg, SendReceiveOptions flags)
        {
            if (m_pipe == null || !m_pipe.Write(ref msg))
            {
                return(false);
            }

            if ((flags & SendReceiveOptions.SendMore) == 0)
            {
                m_pipe.Flush();
            }

            //  Detach the original message from the data buffer.
            msg.InitEmpty();

            return(true);
        }
Esempio n. 7
0
        public static MonitorEvent Read([NotNull] SocketBase s)
        {
            var msg = new Msg();

            msg.InitEmpty();

            s.Recv(ref msg, SendReceiveOptions.None);

            int pos = 0;
            ByteArraySegment data = msg.Data;

            var @event = (SocketEvent)data.GetInteger(Endianness.Little, pos);

            pos += 4;
            var    len  = (int)data[pos++];
            string addr = data.GetString(len, pos);

            pos += len;
            var    flag = (int)data[pos++];
            Object arg  = null;

            if (flag == ValueInteger)
            {
                arg = data.GetInteger(Endianness.Little, pos);
            }
            else if (flag == ValueChannel)
            {
                IntPtr value = s_sizeOfIntPtr == 4
                    ? new IntPtr(data.GetInteger(Endianness.Little, pos))
                    : new IntPtr(data.GetLong(Endianness.Little, pos));

                GCHandle    handle = GCHandle.FromIntPtr(value);
                AsyncSocket socket = null;

                if (handle.IsAllocated)
                {
                    socket = handle.Target as AsyncSocket;
                }

                handle.Free();

                arg = socket;
            }

            return(new MonitorEvent(@event, addr, arg));
        }
Esempio n. 8
0
        protected override bool XSend(ref Msg msg, SendReceiveOptions flags)
        {
            //  If we've sent a request and we still haven't got the reply,
            //  we can't send another request.
            if (m_receivingReply)
            {
                throw NetMQException.Create("Cannot send another request", ErrorCode.EFSM);
            }

            bool isMessageSent;

            //  First part of the request is the request identity.
            if (m_messageBegins)
            {
                Msg bottom = new Msg();
                bottom.InitEmpty();
                bottom.SetFlags(MsgFlags.More);
                isMessageSent = base.XSend(ref bottom, 0);

                if (!isMessageSent)
                {
                    return(false);
                }

                m_messageBegins = false;
            }

            bool more = msg.HasMore;

            isMessageSent = base.XSend(ref msg, flags);

            if (!isMessageSent)
            {
                return(false);
            }
            //  If the request was fully sent, flip the FSM into reply-receiving state.
            else if (!more)
            {
                m_receivingReply = true;
                m_messageBegins  = true;
            }

            return(true);
        }
Esempio n. 9
0
        //  Holds the prefetched message.
        public Dealer(Ctx parent, int threadId, int sid)
            : base(parent, threadId, sid)
        {
            m_prefetched         = false;
            m_options.SocketType = ZmqSocketType.Dealer;

            m_fq = new FQ();
            m_lb = new LB();
            //  TODO: Uncomment the following line when DEALER will become true DEALER
            //  rather than generic dealer socket.
            //  If the socket is closing we can drop all the outbound requests. There'll
            //  be noone to receive the replies anyway.
            //  options.delay_on_close = false;

            m_options.RecvIdentity = true;

            m_prefetchedMsg = new Msg();
            m_prefetchedMsg.InitEmpty();
        }
Esempio n. 10
0
        public void Plug(IOThread ioThread, SessionBase session)
        {
            m_encoder.SetMsgSource(session);

            AddFd(m_socket);
            SetPollout(m_socket);

            // get the first message from the session because we don't want to send identities

            Msg msg = new Msg();

            msg.InitEmpty();

            bool ok = session.PullMsg(ref msg);

            if (ok)
            {
                msg.Close();
            }
        }
Esempio n. 11
0
        public void Plug(IOThread ioThread, SessionBase session)
        {
            m_session = session;

            m_socket = session.Socket;

            m_ioObject = new IOObject(null);
            m_ioObject.SetHandler(this);
            m_ioObject.Plug(ioThread);
            m_ioObject.AddFd(m_handle);
            m_ioObject.SetPollin(m_handle);

            DropSubscriptions();

            var msg = new Msg();

            msg.InitEmpty();

            // push message to the session because there is no identity message with pgm
            session.PushMsg(ref msg);
        }
Esempio n. 12
0
        public Stream(Ctx parent, int threadId, int sid)
            : base(parent, threadId, sid)
        {
            m_prefetched   = false;
            m_identitySent = false;
            m_currentOut   = null;
            m_moreOut      = false;
            m_nextPeerId   = Utils.GenerateRandom();

            m_options.SocketType = ZmqSocketType.Stream;


            m_fq           = new FQ();
            m_prefetchedId = new Msg();
            m_prefetchedId.InitEmpty();
            m_prefetchedMsg = new Msg();
            m_prefetchedMsg.InitEmpty();

            m_outpipes = new Dictionary <Blob, Outpipe>();

            m_options.RawSocket = true;
        }
Esempio n. 13
0
        //  Remove any half processed messages. Flush unflushed messages.
        //  Call this function when engine disconnect to get rid of leftovers.
        private void CleanPipes()
        {
            if (m_pipe != null)
            {
                //  Get rid of half-processed messages in the out pipe. Flush any
                //  unflushed messages upstream.
                m_pipe.Rollback();
                m_pipe.Flush();

                //  Remove any half-read message from the in pipe.
                while (m_incompleteIn)
                {
                    Msg msg = new Msg();
                    msg.InitEmpty();

                    if (!PullMsg(ref msg))
                    {
                        Debug.Assert(!m_incompleteIn);
                        break;
                    }
                    msg.Close();
                }
            }
        }
Esempio n. 14
0
        public static bool CreateProxy(SocketBase frontend,
                                       SocketBase backend, SocketBase capture)
        {
            //  The algorithm below assumes ratio of requests and replies processed
            //  under full load to be 1:1.

            int more;
            int rc;
            Msg msg = new Msg();

            msg.InitEmpty();
            PollItem[] items = new PollItem[2];

            items[0] = new PollItem(frontend, PollEvents.PollIn);
            items[1] = new PollItem(backend, PollEvents.PollIn);

            while (true)
            {
                //  Wait while there are either requests or replies to process.
                rc = ZMQ.Poll(items, -1);
                if (rc < 0)
                {
                    return(false);
                }

                //  Process a request.
                if ((items[0].ResultEvent & PollEvents.PollIn) == PollEvents.PollIn)
                {
                    while (true)
                    {
                        try
                        {
                            frontend.Recv(ref msg, SendReceiveOptions.None);
                        }
                        catch (TerminatingException)
                        {
                            return(false);
                        }

                        more = frontend.GetSocketOption(ZmqSocketOptions.ReceiveMore);

                        if (more < 0)
                        {
                            return(false);
                        }

                        //  Copy message to capture socket if any
                        if (capture != null)
                        {
                            Msg ctrl = new Msg();
                            ctrl.InitEmpty();

                            ctrl.Copy(ref msg);

                            capture.Send(ref ctrl, more > 0 ? SendReceiveOptions.SendMore : 0);
                        }

                        backend.Send(ref msg, more > 0 ? SendReceiveOptions.SendMore : 0);
                        if (more == 0)
                        {
                            break;
                        }
                    }
                }
                //  Process a reply.
                if ((items[1].ResultEvent & PollEvents.PollIn) == PollEvents.PollIn)
                {
                    while (true)
                    {
                        try
                        {
                            backend.Recv(ref msg, SendReceiveOptions.None);
                        }
                        catch (TerminatingException)
                        {
                            return(false);
                        }

                        more = backend.GetSocketOption(ZmqSocketOptions.ReceiveMore);

                        if (more < 0)
                        {
                            return(false);
                        }

                        //  Copy message to capture socket if any
                        if (capture != null)
                        {
                            Msg ctrl = new Msg();
                            ctrl.InitEmpty();

                            ctrl.Copy(ref msg);

                            capture.Send(ref ctrl, more > 0 ? SendReceiveOptions.SendMore : 0);
                        }

                        frontend.Send(ref msg, more > 0 ? SendReceiveOptions.SendMore : 0);
                        if (more == 0)
                        {
                            break;
                        }
                    }
                }
            }
        }
Esempio n. 15
0
        public virtual bool PushMsg(ref Msg msg)
        {
            //  First message to receive is identity (if required).
            if (!m_identityReceived)
            {
                msg.SetFlags(MsgFlags.Identity);
                m_identityReceived = true;

                if (!m_options.RecvIdentity)
                {
                    msg.Close();
                    msg.InitEmpty();
                    return true;
                }
            }

            if (m_pipe != null && m_pipe.Write(ref msg))
            {
                msg.InitEmpty();
                return true;
            }

            return false;
        }
Esempio n. 16
0
        public static MonitorEvent Read([NotNull] SocketBase s)
        {
            var msg = new Msg();
            msg.InitEmpty();

            s.Recv(ref msg, SendReceiveOptions.None);

            int pos = 0;
            ByteArraySegment data = msg.Data;

            var @event = (SocketEvent)data.GetInteger(Endianness.Little, pos);
            pos += 4;
            var len = (int)data[pos++];
            string addr = data.GetString(len, pos);
            pos += len;
            var flag = (int)data[pos++];
            Object arg = null;

            if (flag == ValueInteger)
            {
                arg = data.GetInteger(Endianness.Little, pos);
            }
            else if (flag == ValueChannel)
            {
                IntPtr value = s_sizeOfIntPtr == 4
                    ? new IntPtr(data.GetInteger(Endianness.Little, pos))
                    : new IntPtr(data.GetLong(Endianness.Little, pos));

                GCHandle handle = GCHandle.FromIntPtr(value);
                AsyncSocket socket = null;

                if (handle.IsAllocated)
                {
                    socket = handle.Target as AsyncSocket;
                }

                handle.Free();

                arg = socket;
            }

            return new MonitorEvent(@event, addr, arg);
        }
Esempio n. 17
0
        protected override bool XSend(ref Msg msg, SendReceiveOptions flags)
        {
            //  If this is the first part of the message it's the ID of the
            //  peer to send the message to.
            if (!m_moreOut)
            {
                Debug.Assert(m_currentOut == null);

                //  If we have malformed message (prefix with no subsequent message)
                //  then just silently ignore it.
                //  TODO: The connections should be killed instead.
                if (msg.HasMore)
                {
                    m_moreOut = true;

                    //  Find the pipe associated with the identity stored in the prefix.
                    //  If there's no such pipe just silently ignore the message, unless
                    //  mandatory is set.
                    Blob    identity = new Blob(msg.Data, msg.Size);
                    Outpipe op;

                    if (m_outpipes.TryGetValue(identity, out op))
                    {
                        m_currentOut = op.Pipe;
                        if (!m_currentOut.CheckWrite())
                        {
                            op.Active    = false;
                            m_currentOut = null;
                            if (m_mandatory)
                            {
                                m_moreOut = false;
                                return(false);
                            }
                        }
                    }
                    else if (m_mandatory)
                    {
                        m_moreOut = false;
                        throw NetMQException.Create(ErrorCode.EHOSTUNREACH);
                    }
                }

                //  Detach the message from the data buffer.
                msg.Close();
                msg.InitEmpty();

                return(true);
            }

            if (m_options.RawSocket)
            {
                msg.ResetFlags(MsgFlags.More);
            }

            //  Check whether this is the last part of the message.
            m_moreOut = msg.HasMore;

            //  Push the message into the pipe. If there's no out pipe, just drop it.
            if (m_currentOut != null)
            {
                // Close the remote connection if user has asked to do so
                // by sending zero length message.
                // Pending messages in the pipe will be dropped (on receiving term- ack)
                if (m_rawSocket && msg.Size == 0)
                {
                    m_currentOut.Terminate(false);
                    msg.Close();
                    msg.InitEmpty();
                    m_currentOut = null;
                    return(true);
                }

                bool ok = m_currentOut.Write(ref msg);
                if (!ok)
                {
                    m_currentOut = null;
                }
                else if (!m_moreOut)
                {
                    m_currentOut.Flush();
                    m_currentOut = null;
                }
            }
            else
            {
                msg.Close();
            }

            //  Detach the message from the data buffer.
            msg.InitEmpty();

            return(true);
        }
Esempio n. 18
0
        private bool IdentifyPeer(Pipe pipe)
        {
            Blob identity;

            if (m_options.RawSocket)
            {
                // Always assign identity for raw-socket
                byte[] buf = new byte[5];
                buf[0] = 0;
                byte[] result = BitConverter.GetBytes(m_nextPeerId++);
                Buffer.BlockCopy(result, 0, buf, 1, 4);
                identity = new Blob(buf, buf.Length);
            }
            else
            {
                //  Pick up handshake cases and also case where next identity is set

                Msg msg = new Msg();
                msg.InitEmpty();

                bool ok = pipe.Read(ref msg);

                if (!ok)
                {
                    return(false);
                }

                if (msg.Size == 0)
                {
                    //  Fall back on the auto-generation
                    byte[] buf = new byte[5];

                    buf[0] = 0;

                    byte[] result = BitConverter.GetBytes(m_nextPeerId++);

                    Buffer.BlockCopy(result, 0, buf, 1, 4);
                    identity = new Blob(buf, buf.Length);

                    msg.Close();
                }
                else
                {
                    identity = new Blob(msg.Data, msg.Size);

                    //  Ignore peers with duplicate ID.
                    if (m_outpipes.ContainsKey(identity))
                    {
                        msg.Close();
                        return(false);
                    }

                    msg.Close();
                }
            }

            pipe.Identity = identity;
            //  Add the record into output pipes lookup table
            Outpipe outpipe = new Outpipe(pipe, true);

            m_outpipes.Add(identity, outpipe);

            return(true);
        }
Esempio n. 19
0
        protected override void Consume(PullSocket socket, int messageSize)
        {
            var msg = new Msg();
            msg.InitEmpty();

            for (int i = 0; i < MsgCount; i++)
            {
                socket.Receive(ref msg, SendReceiveOptions.None);
                Debug.Assert(msg.Data.Length == messageSize, "Message length was different from expected size.");
                Debug.Assert(msg.Data[msg.Size/2] == 0x42, "Message did not contain verification data.");
            }
        }
Esempio n. 20
0
        //  Remove any half processed messages. Flush unflushed messages.
        //  Call this function when engine disconnect to get rid of leftovers.
        private void CleanPipes()
        {
            if (m_pipe != null)
            {
                //  Get rid of half-processed messages in the out pipe. Flush any
                //  unflushed messages upstream.
                m_pipe.Rollback();
                m_pipe.Flush();

                //  Remove any half-read message from the in pipe.
                while (m_incompleteIn)
                {
                    var msg = new Msg();
                    msg.InitEmpty();

                    if (!PullMsg(ref msg))
                    {
                        Debug.Assert(!m_incompleteIn);
                        break;
                    }
                    msg.Close();
                }
            }
        }