Inheritance: OtpErlangObject
Exemple #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;
        }
Exemple #2
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);
        }
        /**
         * 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));
        }
        /*
         * 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());
        }
Exemple #5
0
        /// <summary>
        /// Executes a MFA over TCP stream and synchronously retrieves the data
        /// </summary>
        /// <param name="stream">TCP stream</param>
        /// <param name="module">Erlang Module atom</param>
        /// <param name="function">Erlang function atom</param>
        /// <param name="args">Function arguments (maybe empty/null)</param>
        /// <returns></returns>
        public static OtpErlangObject CallMFASync(ErlStream stream,
            string module, string function, OtpErlangObject[] args)
        {
            OtpErlangObject[] mfaArray = null;
            OtpOutputStream eouts = new OtpOutputStream();

            mfaArray = new OtpErlangObject[4];

            // mod and fun and args as list
            // ['mod', 'fun', arg1, arg2, ...]
            mfaArray[0] = new OtpErlangAtom("c#ref");
            mfaArray[1] = new OtpErlangAtom(module);
            mfaArray[2] = new OtpErlangAtom(function);
            if (null != args)
                mfaArray[3] = new OtpErlangList(args);
            else
                mfaArray[3] = new OtpErlangList();

            OtpErlangTuple mfaTouple = new OtpErlangTuple(mfaArray);
            eouts = new OtpOutputStream();
            mfaTouple.encode(eouts);

            uint payloadLen = (uint)(eouts.Length + 1);
            byte[] buf = new byte[eouts.Length + 5];

            // added payload size (including protocol id byte)
            // and the missing protocol id byte after it
            buf[0] = (byte)((payloadLen & 0xFF000000) >> 24);
            buf[1] = (byte)((payloadLen & 0x00FF0000) >> 16);
            buf[2] = (byte)((payloadLen & 0x0000FF00) >> 8);
            buf[3] = (byte)((payloadLen & 0x000000FF));
            buf[4] = 131;

            Array.Copy(eouts.GetBuffer(), 0, buf, 5, eouts.Length); // rest of the buffer copied

            stream.Write(buf, 0, buf.Length);

            // wait for data
            DateTime startToWaitForData = DateTime.Now;
            while (!stream.DataAvailable)
            {
                if ((DateTime.Now - startToWaitForData).Seconds > Properties.Settings.Default.StreamResponseTimeout)
                    throw new ErlnetException("Response timeout in call to " + module + ":" + function);
                else
                    Thread.Sleep(0);
            }

            // read till empty
            int readCount = 0;
            payloadLen = 0;

            // read payload length (4 byte header)
            byte[] payloadbuf = new byte[4];
            do {
                readCount += stream.Read(payloadbuf, readCount, payloadbuf.Length - readCount);
                if (readCount != 4)
                    continue;
                else
                    payloadLen = ((uint)payloadbuf[3] & 0x000000FF)
                               + (((uint)payloadbuf[2] << 8) & 0x0000FF00)
                               + (((uint)payloadbuf[1] << 16) & 0x00FF0000)
                               + (((uint)payloadbuf[0] << 24) & 0xFF000000);
                break;
            } while(true);
            //Console.WriteLine("RX " + payloadLen + " bytes");

            // read the payload of length 'payloadLen'
            readCount = 0;
            buf = new byte[payloadLen];
            MemoryStream resp = new MemoryStream();
            do
            {
                readCount += stream.Read(buf, readCount, buf.Length - readCount);
                if (readCount != payloadLen)
                    continue;
                else
                    break;
            } while (true);

            // rebuild term
            resp.Write(buf, 0, buf.Length);
            OtpErlangTuple res = (OtpErlangTuple)OtpErlangObject.decode(new OtpInputStream(resp.GetBuffer()));

            //Console.WriteLine("RX " + res.elementAt(0).ToString());
            return res.elementAt(1);
        }