示例#1
0
        /*
         * this method simulates net_kernel only for the purpose of replying to
         * pings.
         */
        private bool netKernel(OtpMsg m)
        {
            OtpMbox mbox = null;

            try
            {
                OtpErlangTuple t   = (OtpErlangTuple)m.getMsg();
                OtpErlangTuple req = (OtpErlangTuple)t.elementAt(1); // actual
                // request

                OtpErlangPid pid = (OtpErlangPid)req.elementAt(0); // originating
                // pid

                OtpErlangObject[] pong = new OtpErlangObject[2];
                pong[0] = req.elementAt(1); // his #Ref
                pong[1] = new OtpErlangAtom("yes");

                mbox = createMbox(true);
                mbox.send(pid, new OtpErlangTuple(pong));
                return(true);
            }
            catch (Exception)
            {
            }
            finally
            {
                closeMbox(mbox);
            }
            return(false);
        }
示例#2
0
        /**
         * <p>
         * Determine if another node is alive. This method has the side effect of
         * setting up a connection to the remote node (if possible). Only a single
         * outgoing message is sent; the timeout is how long to wait for a response.
         * </p>
         *
         * <p>
         * Only a single attempt is made to connect to the remote node, so for
         * example it is not possible to specify an extremely long timeout and
         * expect to be notified when the node eventually comes up. If you wish to
         * wait for a remote node to be started, the following construction may be
         * useful:
         * </p>
         *
         * <pre>
         * // ping every 2 seconds until positive response
         * while (!me.ping(him, 2000))
         *     ;
         * </pre>
         *
         * @param node
         *            the name of the node to ping.
         *
         * @param timeout
         *            the time, in milliseconds, to wait for response before
         *            returning false.
         *
         * @return true if the node was alive and the correct ping response was
         *         returned. false if the correct response was not returned on time.
         */
        /*
         * internal info about the message formats...
         *
         * the request: -> REG_SEND {6,#Pid<[email protected]>,'',net_kernel}
         * {'$gen_call',{#Pid<[email protected]>,#Ref<[email protected]>},{is_auth,bingo@aule}}
         *
         * the reply: <- SEND {2,'',#Pid<[email protected]>} {#Ref<[email protected]>,yes}
         */
        public bool ping(String node, long timeout)
        {
            if (node.Equals(this.Node))
            {
                return(true);
            }
            else if (node.IndexOf('@', 0) < 0 && node.Equals(this.Node.Substring(0, this.Node.IndexOf('@', 0))))
            {
                return(true);
            }

            // other node
            OtpMbox mbox = null;

            try
            {
                mbox = createMbox(true);
                mbox.send("net_kernel", node, getPingTuple(mbox));
                OtpErlangObject reply = mbox.receive(timeout);
                OtpErlangTuple  t     = (OtpErlangTuple)reply;
                OtpErlangAtom   a     = (OtpErlangAtom)t.elementAt(1);
                return("yes".Equals(a.atomValue()));
            }
            catch (Exception)
            {
            }
            finally
            {
                closeMbox(mbox);
            }
            return(false);
        }
示例#3
0
        /**
         * Determine if two atoms are equal.
         *
         * @param o
         *                the other object to compare to.
         *
         * @return true if the atoms are equal, false otherwise.
         */
        public override bool Equals(Object o)
        {
            if (!(o is OtpErlangAtom))
            {
                return(false);
            }
            OtpErlangAtom atom = (OtpErlangAtom)o;

            return(this.atom.Equals(atom.atom));
        }
示例#4
0
        /**
         * Send an auth error to peer because he sent a bad cookie. The auth error
         * uses his cookie (not revealing ours). This is just like send_reg
         * otherwise
         */
        protected void CookieError(OtpLocalNode local, OtpErlangAtom cookie)
        {
            try
            {
                OtpOutputStream header = new OtpOutputStream(headerLen);

                // preamble: 4 byte length + "passthrough" tag + version
                header.Write4BE(0); // reserve space for length
                header.Write1(passThrough);
                header.Write1(version);

                header.WriteTupleHead(4);
                header.WriteLong(regSendTag);
                header.WriteAny(local.CreatePid()); // disposable pid
                header.WriteAtom(cookie.Value);     // important: his cookie,
                // not mine...
                header.WriteAtom("auth");

                // version for payload
                header.Write1(version);

                // the payload

                // the no_auth message (copied from Erlang) Don't change this
                // (Erlang will crash)
                // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n",
                // [foo@aule]}}
                IOtpErlangObject[] msg     = new IOtpErlangObject[2];
                IOtpErlangObject[] msgbody = new IOtpErlangObject[3];

                msgbody[0] = new OtpErlangAtom("print");
                msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local + " **~n");

                // Erlang will crash and burn if there is no third argument here...
                msgbody[2] = new OtpErlangList(); // empty list

                msg[0] = new OtpErlangAtom("$gen_cast");
                msg[1] = new OtpErlangTuple(msgbody);

                OtpOutputStream payload = new OtpOutputStream(new OtpErlangTuple(msg));

                // fix up length in preamble
                header.Poke4BE(0, header.Length + payload.Length - 4);

                try { DoSend(header, payload); }
                catch (IOException) { } // ignore
            }
            finally
            {
                Close();
            }

            throw new OtpAuthException("Remote cookie not authorized: " + cookie.Value);
        }
示例#5
0
 /* ping remote node */
 public bool Ping(string node, long timeout)
 {
     try
     {
         Send(node, "net_kernel", PingTuple());
         var reply = (OtpErlangTuple)Receive(timeout);
         if (reply != null && reply.Arity >= 2)
         {
             OtpErlangAtom a = (OtpErlangAtom)reply.ElementAt(1);
             return("yes".Equals(a?.Value));
         }
     }
     catch (Exception) { }
     return(false);
 }
示例#6
0
        /**
         * Send an RPC request to the remote Erlang node. This convenience function
         * creates the following message and sends it to 'rex' on the remote node:
         *
         * <pre>
         * { self, { call, Mod, Fun, Args, user } }
         * </pre>
         *
         * <p>
         * Note that this method has unpredicatble results if the remote node is not
         * an Erlang node.
         * </p>
         *
         * @param mod
         *                the name of the Erlang module containing the function to
         *                be called.
         * @param fun
         *                the name of the function to call.
         * @param args
         *                a list of Erlang terms, to be used as arguments to the
         *                function.
         *
         * @exception java.io.IOException
         *                    if the connection is not active or a communication
         *                    error occurs.
         */
        public void sendRPC(String mod, String fun, OtpErlangList args)
        {
            OtpErlangObject[] rpc  = new OtpErlangObject[2];
            OtpErlangObject[] call = new OtpErlangObject[5];

            /* {self, { call, Mod, Fun, Args, user}} */

            call[0] = new OtpErlangAtom("call");
            call[1] = new OtpErlangAtom(mod);
            call[2] = new OtpErlangAtom(fun);
            call[3] = args;
            call[4] = new OtpErlangAtom("user");

            rpc[0] = self.Pid;
            rpc[1] = new OtpErlangTuple(call);

            send("rex", new OtpErlangTuple(rpc));
        }
示例#7
0
        /* create the outgoing ping message */
        private OtpErlangTuple getPingTuple(OtpMbox mbox)
        {
            OtpErlangObject[] ping = new OtpErlangObject[3];
            OtpErlangObject[] pid  = new OtpErlangObject[2];
            OtpErlangObject[] node = new OtpErlangObject[2];

            pid[0] = mbox.Self;
            pid[1] = createRef();

            node[0] = new OtpErlangAtom("is_auth");
            node[1] = new OtpErlangAtom(Node);

            ping[0] = new OtpErlangAtom("$gen_call");
            ping[1] = new OtpErlangTuple(pid);
            ping[2] = new OtpErlangTuple(node);

            return(new OtpErlangTuple(ping));
        }
示例#8
0
        /*
         * this method simulates net_kernel only for the purpose of replying to
         * pings.
         */
        private bool netKernel(OtpMsg m)
        {
            OtpMbox mbox = null;
            try
            {
                OtpErlangTuple t = (OtpErlangTuple)m.getMsg();
                OtpErlangTuple req = (OtpErlangTuple)t.elementAt(1); // actual
                // request

                OtpErlangPid pid = (OtpErlangPid)req.elementAt(0); // originating
                // pid

                OtpErlangObject[] pong = new OtpErlangObject[2];
                pong[0] = req.elementAt(1); // his #Ref
                pong[1] = new OtpErlangAtom("yes");

                mbox = createMbox(true);
                mbox.send(pid, new OtpErlangTuple(pong));
                return true;
            }
            catch (Exception)
            {
            }
            finally
            {
                closeMbox(mbox);
            }
            return false;
        }
示例#9
0
        /* create the outgoing ping message */
        private OtpErlangTuple getPingTuple(OtpMbox mbox)
        {
            OtpErlangObject[] ping = new OtpErlangObject[3];
            OtpErlangObject[] pid = new OtpErlangObject[2];
            OtpErlangObject[] node = new OtpErlangObject[2];

            pid[0] = mbox.Self;
            pid[1] = createRef();

            node[0] = new OtpErlangAtom("is_auth");
            node[1] = new OtpErlangAtom(Node);

            ping[0] = new OtpErlangAtom("$gen_call");
            ping[1] = new OtpErlangTuple(pid);
            ping[2] = new OtpErlangTuple(node);

            return new OtpErlangTuple(ping);
        }
示例#10
0
        public override void Run()
        {
            if (!Connected)
            {
                Deliver(new IOException("Not connected"));
                return;
            }

            byte[] lbuf = new byte[4];
            int    len;

            try
            {
                while (!Stopping)
                {
                    // don't return until we get a real message
                    // or a failure of some kind (e.g. EXIT)
                    // read length and read buffer must be atomic!

                    // read 4 bytes - get length of incoming packet
                    ReadSock(lbuf);
                    OtpInputStream ibuf = new OtpInputStream(lbuf)
                    {
                        Flags = Local.Flags
                    };
                    len = ibuf.Read4BE();

                    // received tick? send tock!
                    if (len == 0)
                    {
                        lock (objWrite)
                        {
                            socket.OutputStream.Write(TOCK, 0, TOCK.Length);
                            socket.OutputStream.Flush();
                        }

                        continue;
                    }

                    // got a real message (maybe) - read len bytes
                    byte[] tmpbuf = new byte[len];
                    ReadSock(tmpbuf);
                    ibuf = new OtpInputStream(tmpbuf)
                    {
                        Flags = Local.Flags
                    };

                    if (ibuf.Read1() != passThrough)
                    {
                        continue;
                    }

                    // got a real message (really)
                    IOtpErlangObject reason = null;
                    OtpErlangAtom    cookie = null;
                    IOtpErlangObject tmp    = null;
                    OtpErlangTuple   head   = null;
                    OtpErlangAtom    toName;
                    OtpErlangPid     to;
                    OtpErlangPid     from;
                    int tag;

                    // decode the header
                    tmp = ibuf.ReadAny();
                    if (!(tmp is OtpErlangTuple))
                    {
                        continue;
                    }

                    head = (OtpErlangTuple)tmp;
                    if (!(head.ElementAt(0) is OtpErlangLong))
                    {
                        continue;
                    }

                    // lets see what kind of message this is
                    tag = (int)((OtpErlangLong)head.ElementAt(0)).LongValue();

                    switch (tag)
                    {
                    case sendTag:       // { SEND, Cookie, ToPid }
                    case sendTTTag:     // { SEND, Cookie, ToPid, TraceToken }
                        if (!cookieOk)
                        {
                            // we only check this once, he can send us bad cookies later if he likes
                            if (!(head.ElementAt(1) is OtpErlangAtom))
                            {
                                continue;
                            }

                            cookie = (OtpErlangAtom)head.ElementAt(1);
                            if (sendCookie)
                            {
                                if (cookie.Value != Local.Cookie)
                                {
                                    CookieError(Local, cookie);
                                }
                            }
                            else
                            {
                                if (cookie.Value != "")
                                {
                                    CookieError(Local, cookie);
                                }
                            }
                            cookieOk = true;
                        }

                        if (TraceLevel >= TraceSend)
                        {
                            Logger.Debug($"<- {HeaderType(head)} {head}");

                            /* show received payload too */
                            ibuf.Mark();
                            Logger.Debug($"   {ibuf.ReadAny()}");
                            ibuf.Reset();
                        }

                        to = (OtpErlangPid)head.ElementAt(2);

                        Deliver(new OtpMsg(to, ibuf));
                        break;

                    case regSendTag:       // { REG_SEND, FromPid, Cookie, ToName }
                    case regSendTTTag:     // { REG_SEND, FromPid, Cookie, ToName, TraceToken }
                        if (!cookieOk)
                        {
                            // we only check this once, he can send us bad cookies later if he likes
                            if (!(head.ElementAt(2) is OtpErlangAtom))
                            {
                                continue;
                            }

                            cookie = (OtpErlangAtom)head.ElementAt(2);
                            if (sendCookie)
                            {
                                if (cookie.Value != Local.Cookie)
                                {
                                    CookieError(Local, cookie);
                                }
                            }
                            else
                            {
                                if (cookie.Value != "")
                                {
                                    CookieError(Local, cookie);
                                }
                            }

                            cookieOk = true;
                        }

                        if (TraceLevel >= TraceSend)
                        {
                            Logger.Debug($"<- {HeaderType(head)} {head}");

                            /* show received payload too */
                            ibuf.Mark();
                            Logger.Debug($"   {ibuf.ReadAny()}");
                            ibuf.Reset();
                        }

                        from   = (OtpErlangPid)head.ElementAt(1);
                        toName = (OtpErlangAtom)head.ElementAt(3);

                        Deliver(new OtpMsg(from, toName.Value, ibuf));
                        break;

                    case exitTag:      // { EXIT, FromPid, ToPid, Reason }
                    case exit2Tag:     // { EXIT2, FromPid, ToPid, Reason }
                        if (head.ElementAt(3) == null)
                        {
                            continue;
                        }

                        if (TraceLevel >= TraceCTRL)
                        {
                            Logger.Debug($"<- {HeaderType(head)} {head}");
                        }

                        from   = (OtpErlangPid)head.ElementAt(1);
                        to     = (OtpErlangPid)head.ElementAt(2);
                        reason = head.ElementAt(3);

                        Deliver(new OtpMsg(tag, from, to, reason));
                        break;

                    case exitTTTag:      // { EXIT, FromPid, ToPid, TraceToken, Reason }
                    case exit2TTTag:     // { EXIT2, FromPid, ToPid, TraceToken, Reason }
                        // as above, but bifferent element number
                        if (head.ElementAt(4) == null)
                        {
                            continue;
                        }

                        if (TraceLevel >= TraceCTRL)
                        {
                            Logger.Debug($"<- {HeaderType(head)} {head}");
                        }

                        from   = (OtpErlangPid)head.ElementAt(1);
                        to     = (OtpErlangPid)head.ElementAt(2);
                        reason = head.ElementAt(4);

                        Deliver(new OtpMsg(tag, from, to, reason));
                        break;

                    case linkTag:       // { LINK, FromPid, ToPid}
                    case unlinkTag:     // { UNLINK, FromPid, ToPid}
                        if (TraceLevel >= TraceCTRL)
                        {
                            Logger.Debug($"<- {HeaderType(head)} {head}");
                        }

                        from = (OtpErlangPid)head.ElementAt(1);
                        to   = (OtpErlangPid)head.ElementAt(2);

                        Deliver(new OtpMsg(tag, from, to));
                        break;

                    // absolutely no idea what to do with these, so we ignore them...
                    case groupLeaderTag:     // { GROUPLEADER, FromPid, ToPid}
                        // (just show trace)
                        if (TraceLevel >= TraceCTRL)
                        {
                            Logger.Debug("<- " + HeaderType(head) + " " + head);
                        }
                        break;

                    default:
                        // garbage?
                        break;
                    }
                }

                // this section reachable only with break
                // we have received garbage from peer
                Deliver(new OtpExit("Remote is sending garbage"));
            }
            catch (OtpAuthException e)
            {
                Deliver(e);
            }
            catch (OtpDecodeException)
            {
                Deliver(new OtpExit("Remote is sending garbage"));
            }
            catch (IOException)
            {
                Deliver(new OtpExit("Remote has closed connection"));
            }
            finally
            {
                Close();
            }
        }
        private OtpErlangObject ErlangObjectFromPCVMObject(PCObj input)
        {
            if (input is PCFloat)
                return new OtpErlangFloat(((PCFloat)input).val);
            if (input is PCInt)
                return new OtpErlangInt(((PCInt)input).val);
            if (input is PCBool)
                return new OtpErlangBoolean(((PCBool)input).val);
            if (input is PCSym)
                return new OtpErlangAtom(((PCSym)input).val);
            if (input is PCStr)
                return new OtpErlangString(((PCStr)input).val);
            if (input is PCMark)
                return new OtpErlangString(((PCMark)input).ToString());
            if (input is PCUUID)
                return new OtpErlangString(((PCUUID)input).ToString());
            if (input is PCVector2)
            {
                OtpErlangObject[] items = new OtpErlangObject[2];
                items[0] = new OtpErlangFloat(((PCVector2)input).val.X);
                items[1] = new OtpErlangFloat(((PCVector2)input).val.Y);
                return new OtpErlangTuple(items);
            }
            if (input is PCVector3)
            {
                OtpErlangObject[] items = new OtpErlangObject[3];
                items[0] = new OtpErlangFloat(((PCVector3)input).val.X);
                items[1] = new OtpErlangFloat(((PCVector3)input).val.Y);
                items[2] = new OtpErlangFloat(((PCVector3)input).val.Z);
                return new OtpErlangTuple(items);
            }
            if (input is PCVector4)
            {
                OtpErlangObject[] items = new OtpErlangObject[4];
                items[0] = new OtpErlangFloat(((PCVector4)input).val.X);
                items[1] = new OtpErlangFloat(((PCVector4)input).val.Y);
                items[2] = new OtpErlangFloat(((PCVector4)input).val.Z);
                items[3] = new OtpErlangFloat(((PCVector4)input).val.W);
                return new OtpErlangTuple(items);
            }
            if (input is PCNull)
                return new OtpErlangAtom(((PCNull)input).ToString());
            if (input is PCOp)
                return new OtpErlangAtom(((PCOp)input).ToString());
            if (input is PCFun)
                return new OtpErlangAtom(((PCFun)input).ToString());
            if (input is PCDict)
            {
                PCDict dict = (PCDict)input;
                OtpErlangObject[] items = new OtpErlangObject[dict.Dict.Count*2];

                int i = 0;
                foreach (KeyValuePair<string, PCObj> pair in dict.Dict)
                {
                    items[i * 2] = new OtpErlangAtom(pair.Key);
                    items[i * 2 + 1] = ErlangObjectFromPCVMObject(pair.Value);
                    i++;
                }
                return new OtpErlangList(items);
            }
            if (input is PCArray)
            {
                PCArray array = (PCArray)input;
                OtpErlangObject[] items = new OtpErlangObject[array.Length];
                for (int i = 0; i < array.Length; i++)
                {
                    items[i] = ErlangObjectFromPCVMObject(array[i]);
                }
                return new OtpErlangList(items);
            }
            if (input is PCSceneObjectPart)
                return ErlangObjectFromPCVMObject(new PCUUID(((PCSceneObjectPart)input).val.UUID));
            if (input is PCSceneSnapshot)
            {
                PCSceneSnapshot.SnapshotItem[] array = ((PCSceneSnapshot)input).val;
                OtpErlangObject[] items = new OtpErlangObject[array.Length];
                for (int i = 0; i < array.Length; i++)
                {
                    items[i] = ErlangObjectFromPCVMObject(array[i].PCSceneObjectPart);
                }
                return new OtpErlangList(items);
            }

            return new OtpErlangAtom("nonobject");
        }
        public override IEnumerator<OtpActor.Continuation> GetEnumerator()
        {
            m_log.Info("[Distributed PC] New PCVM is ready: " + m_mbox.Self);

            while (true)
            {
                OtpMsg msg = null;

                yield return (delegate(OtpMsg received) { msg = received; });

                OtpErlangObject obj = msg.getMsg();

                if (obj is OtpErlangAtom)
                {
                    string atom = ((OtpErlangAtom)obj).atomValue();
                    if (!String.IsNullOrEmpty(atom) && atom == "noconnection")
                    {
                        break;
                    }
                }

                OtpErlangPid sender = null;
                OtpErlangObject[] reply = new OtpErlangObject[3];

                try
                {
                    OtpErlangTuple t = (OtpErlangTuple)obj;
                    sender = (OtpErlangPid)t.elementAt(0);

                    reply[0] = sender;
                    reply[1] = new OtpErlangAtom("ok");

                    string instr = ((OtpErlangAtom)t.elementAt(1)).ToString();

                    if (instr == "load")
                    {
                        Parser parser = PCVM.MakeParser();
                        string script = String.Empty;
                        if (t.elementAt(2) is OtpErlangString)
                        {
                            script = ((OtpErlangString)t.elementAt(2)).stringValue();
                        }
                        else
                        {
                            script = OtpErlangString.newString(((OtpErlangBinary)t.elementAt(2)).binaryValue());
                        }
                        bool debug = ((OtpErlangAtom)t.elementAt(3)).boolValue();

                        SYMBOL ast = parser.Parse(script);

                        m_vm.Call((Compiler.ExpPair)ast);

                        if (debug)
                        {
                            reply[2] = new OtpErlangAtom("continue");
                        }
                        else
                        {
                            Queue<PCObj> popped = new Queue<PCObj>();
                            try
                            {
                                m_vm.Finish(popped);
                            }
                            finally
                            {
                                reply = new OtpErlangObject[] {
                                    reply[0],
                                    reply[1],
                                    new OtpErlangAtom("finished"),
                                    ErlangObjectFromPCVMObject(popped.ToArray())
                                };
                            }
                        }
                    }
                    else if (instr == "step")
                    {
                        bool cont = true;
                        Queue<PCObj> popped = new Queue<PCObj>();
                        try
                        {
                            cont = m_vm.Step(popped);
                        }
                        finally
                        {
                            reply = new OtpErlangObject[] {
                                reply[0],
                                reply[1],
                                new OtpErlangAtom(cont ? "continue" : "finished"),
                                ErlangObjectFromPCVMObject(popped.ToArray())
                            };
                        }
                    }
                    else if (instr == "finish")
                    {
                        Queue<PCObj> popped = new Queue<PCObj>();
                        try
                        {
                            m_vm.Finish(popped);
                        }
                        finally
                        {
                            reply = new OtpErlangObject[] {
                                reply[0],
                                reply[1],
                                new OtpErlangAtom("finished"),
                                ErlangObjectFromPCVMObject(popped.ToArray())
                            };
                        }
                    }
                    else if (instr == "echo")
                    {
                        reply[2] = t.elementAt(2);
                    }
                    else if (instr == "exit")
                    {
                        reply[2] = new OtpErlangAtom("bye");
                        break;
                    }
                }
                catch (Exception e)
                {
                    m_log.Debug("[Distributed PC] Invalid message format: " + msg.getMsg());

                    reply[1] = new OtpErlangAtom("error");
                    reply[2] = new OtpErlangString(e.Message);
                }
                finally
                {
                    if (sender != null)
                    {
                        m_mbox.send(sender, new OtpErlangTuple(reply));
                    }
                }
            }

            m_log.Info("[Distributed PC] Delete PCVM instance: " + m_mbox.Self);
            m_vm.Dispose();
        }
        public override IEnumerator<OtpActor.Continuation> GetEnumerator()
        {
            while (true)
            {
                OtpMsg msg = null;
                OtpErlangPid sender = null;
                OtpErlangTuple reply = null;

                yield return (delegate(OtpMsg received) { msg = received; });

                try
                {
                    OtpErlangTuple t = (OtpErlangTuple)msg.getMsg();
                    sender = (OtpErlangPid)t.elementAt(0);
                    string instr = ((OtpErlangAtom)t.elementAt(1)).ToString();
                    if (instr == "echo")
                    {
                        OtpErlangObject[] v = new OtpErlangObject[3];
                        v[0] = sender;
                        v[1] = new OtpErlangAtom("ok");
                        v[2] = t.elementAt(2);
                        reply = new OtpErlangTuple(v);
                    }
                    else if (instr == "new")
                    {
                        OtpActorMbox newmbox = (OtpActorMbox)m_node.createMbox(false);
                        PCVMActor newactor = new PCVMActor(m_scene, m_source, m_node, newmbox);

                        m_node.react(newactor);

                        OtpErlangObject[] v = new OtpErlangObject[3];
                        v[0] = sender;
                        v[1] = new OtpErlangAtom("ok");
                        v[2] = newmbox.Self;
                        reply = new OtpErlangTuple(v);
                    }
                }
                catch (Exception e)
                {
                    m_log.Debug("[Distributed PC] Invalid message format: " + msg.getMsg());

                    OtpErlangObject[] v = new OtpErlangObject[3];
                    v[0] = sender;
                    v[1] = new OtpErlangAtom("error");
                    v[2] = new OtpErlangString(e.Message);
                    reply = new OtpErlangTuple(v);
                }
                finally
                {
                    if (sender != null)
                    {
                        m_mbox.send(sender, reply);
                    }
                }
            }
        }
        /*
         * Send an auth error to peer because he sent a bad cookie. The auth error
         * uses his cookie (not revealing ours). This is just like send_reg
         * otherwise
         */
        private void cookieError(OtpLocalNode local, OtpErlangAtom cookie)
        {
            try
            {
                OtpOutputStream header = new OtpOutputStream(headerLen);

                // preamble: 4 byte length + "passthrough" tag + version
                header.write4BE(0); // reserve space for length
                header.write1(passThrough);
                header.write1(version);

                header.write_tuple_head(4);
                header.write_long(regSendTag);
                header.write_any(local.createPid()); // disposable pid
                header.write_atom(cookie.atomValue()); // important: his cookie,
                // not mine...
                header.write_atom("auth");

                // version for payload
                header.write1(version);

                // the payload

                // the no_auth message (copied from Erlang) Don't change this
                // (Erlang will crash)
                // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n",
                // [foo@aule]}}
                OtpErlangObject[] msg = new OtpErlangObject[2];
                OtpErlangObject[] msgbody = new OtpErlangObject[3];

                msgbody[0] = new OtpErlangAtom("print");
                msgbody[1] = new OtpErlangString("~n** Bad cookie sent to " + local + " **~n");

                // Erlang will crash and burn if there is no third argument here...
                msgbody[2] = new OtpErlangList(); // empty list

                msg[0] = new OtpErlangAtom("$gen_cast");
                msg[1] = new OtpErlangTuple(msgbody);

                OtpOutputStream payload = new OtpOutputStream(new OtpErlangTuple(msg));

                // fix up length in preamble
                header.poke4BE(0, header.size() + payload.size() - 4);

                try
                {
                    do_send(header, payload);
                }
                catch (IOException)
                {
                } // ignore
            }
            finally
            {
                close();
            }
            throw new OtpAuthException("Remote cookie not authorized: " + cookie.atomValue());
        }
示例#15
0
        /**
         * Send an RPC request to the remote Erlang node. This convenience function
         * creates the following message and sends it to 'rex' on the remote node:
         * 
         * <pre>
         * { self, { call, Mod, Fun, Args, user } }
         * </pre>
         * 
         * <p>
         * Note that this method has unpredicatble results if the remote node is not
         * an Erlang node.
         * </p>
         * 
         * @param mod
         *                the name of the Erlang module containing the function to
         *                be called.
         * @param fun
         *                the name of the function to call.
         * @param args
         *                a list of Erlang terms, to be used as arguments to the
         *                function.
         * 
         * @exception java.io.IOException
         *                    if the connection is not active or a communication
         *                    error occurs.
         */
        public void sendRPC(String mod, String fun, OtpErlangList args)
        {
            OtpErlangObject[] rpc = new OtpErlangObject[2];
            OtpErlangObject[] call = new OtpErlangObject[5];

            /* {self, { call, Mod, Fun, Args, user}} */

            call[0] = new OtpErlangAtom("call");
            call[1] = new OtpErlangAtom(mod);
            call[2] = new OtpErlangAtom(fun);
            call[3] = args;
            call[4] = new OtpErlangAtom("user");

            rpc[0] = self.Pid;
            rpc[1] = new OtpErlangTuple(call);

            send("rex", new OtpErlangTuple(rpc));
        }