Пример #1
0
        protected void SendChallenge(long her_flags, long our_flags, int challenge)
        {
            OtpOutputStream obuf = new OtpOutputStream();
            string          str  = Local.Node;

            if ((her_flags & AbstractNode.dFlagHandshake23) == 0)
            {
                obuf.Write2BE(1 + 2 + 4 + 4 + str.Length);
                obuf.Write1('n');
                obuf.Write2BE(5);
                obuf.Write4BE(our_flags & 0xffffffff);
                obuf.Write4BE(challenge);
                obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str));
            }
            else
            {
                obuf.Write2BE(1 + 8 + 4 + 4 + 2 + str.Length);
                obuf.Write1('N');
                obuf.Write8BE(our_flags);
                obuf.Write4BE(challenge);
                obuf.Write4BE(Local.Creation);
                obuf.Write2BE(str.Length);
                obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str));
            }

            obuf.WriteTo(socket.OutputStream);

            if (TraceLevel >= TraceHandshake)
            {
                Logger.Debug($"-> HANDSHAKE sendChallenge flags={our_flags} challenge={challenge} local={Local}");
            }
        }
Пример #2
0
        /**
         * Send an exit signal to a remote process.
         * Used internally when "processes" terminate
         */
        private void SendExit(int tag, OtpErlangPid from, OtpErlangPid dest, IOtpErlangObject reason)
        {
            if (!Connected)
            {
                throw new IOException("Not connected");
            }

            OtpOutputStream header = new OtpOutputStream(headerLen);

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

            // header
            header.WriteTupleHead(4);
            header.WriteLong(tag);
            header.WriteAny(from);
            header.WriteAny(dest);
            header.WriteAny(reason);

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

            DoSend(header);
        }
Пример #3
0
        /**
         * Send a pre-encoded message to a process on a remote node.
         */
        protected void SendBuf(OtpErlangPid from, OtpErlangPid dest, OtpOutputStream payload)
        {
            if (!Connected)
            {
                throw new IOException("Not connected");
            }

            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 info
            header.WriteTupleHead(3);
            header.WriteLong(sendTag);
            if (sendCookie)
            {
                header.WriteAtom(Local.Cookie);
            }
            else
            {
                header.WriteAtom("");
            }
            header.WriteAny(dest);

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

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

            DoSend(header, payload);
        }
Пример #4
0
        protected int SendName(int dist, long aflags, int creation)
        {
            OtpOutputStream obuf    = new OtpOutputStream();
            string          str     = Local.Node;
            int             nameTag = (dist == 5 ? 'n' : 'N');

            if (dist == 5)
            {
                obuf.Write2BE(1 + 2 + 4 + str.Length);
                obuf.Write1(nameTag);
                obuf.Write2BE(dist);
                obuf.Write4BE(aflags);
                obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str));
            }
            else
            {
                obuf.Write2BE(1 + 8 + 4 + 2 + str.Length);
                obuf.Write1(nameTag);
                obuf.Write8BE(aflags);
                obuf.Write4BE(creation);
                obuf.Write2BE(str.Length);
                obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(str));
            }

            obuf.WriteTo(socket.OutputStream);

            if (TraceLevel >= TraceHandshake)
            {
                Logger.Debug($"-> HANDSHAKE sendName flags={aflags} dist={dist} local={Local}");
            }

            return(nameTag);
        }
Пример #5
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);
        }
Пример #6
0
        private async Task <string> Publish_R4(IOtpTransport socket, OtpInputStream ibuf)
        {
            try
            {
                int    port     = ibuf.Read2BE();
                int    type     = ibuf.Read1();
                int    proto    = ibuf.Read1();
                int    distHigh = ibuf.Read2BE();
                int    distLow  = ibuf.Read2BE();
                string name     = ibuf.ReadStringData();
                ibuf.ReadStringData(); // extra
                AbstractNode node = new AbstractNode()
                {
                    Node     = name,
                    Port     = port,
                    Type     = type,
                    DistHigh = distHigh,
                    DistLow  = distLow,
                    Proto    = proto
                };

                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug($"<- PUBLISH (r4) {name} port={node.Port}");
                }

                OtpOutputStream obuf = new OtpOutputStream();
                obuf.Write1(ALIVE2_RESP);
                obuf.Write1(0);
                obuf.Write2BE(NextCreation());
                await obuf.WriteToAsync(socket.OutputStream);

                portmap.TryAdd(name, node);
                return(name);
            }
            catch (IOException e)
            {
                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug("<- (no response)");
                }
                throw new IOException("Request not responding", e);
            }
        }
Пример #7
0
        private async Task Port_R4(IOtpTransport socket, OtpInputStream ibuf)
        {
            try
            {
                int    len   = (int)(ibuf.Length - 1);
                byte[] alive = ibuf.ReadN(len);

                string name = OtpErlangString.FromEncoding(alive);
                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug($"<- PORT (r4) {name}");
                }

                if (!portmap.TryGetValue(name, out AbstractNode node))
                {
                    node = null;
                }

                OtpOutputStream obuf = new OtpOutputStream();
                if (node != null)
                {
                    obuf.Write1(port4resp);
                    obuf.Write1(0);
                    obuf.Write2BE(node.Port);
                    obuf.Write1(node.Type);
                    obuf.Write1(node.Proto);
                    obuf.Write2BE(node.DistHigh);
                    obuf.Write2BE(node.DistLow);
                    obuf.Write2BE(len);
                    obuf.WriteN(alive);
                    obuf.Write2BE(0);
                    if (traceLevel >= traceThreshold)
                    {
                        Logger.Debug("-> 0 (success)");
                    }
                }
                else
                {
                    obuf.Write1(port4resp);
                    obuf.Write1(1);
                    if (traceLevel >= traceThreshold)
                    {
                        Logger.Debug("-> 1 (failure)");
                    }
                }

                await obuf.WriteToAsync(socket.OutputStream);
            }
            catch (IOException e)
            {
                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug("<- (no response)");
                }
                throw new IOException("Request not responding", e);
            }
        }
Пример #8
0
        protected void SendStatus(string status)
        {
            OtpOutputStream obuf = new OtpOutputStream();

            obuf.Write2BE(status.Length + 1);
            obuf.Write1(ChallengeStatus);
            obuf.Write(Encoding.GetEncoding("ISO-8859-1").GetBytes(status));

            obuf.WriteTo(socket.OutputStream);

            if (TraceLevel >= TraceHandshake)
            {
                Logger.Debug($"-> HANDSHAKE sendStatus status={status} local={Local}");
            }
        }
Пример #9
0
        protected void SendChallengeAck(byte[] digest)
        {
            OtpOutputStream obuf = new OtpOutputStream();

            obuf.Write2BE(17);
            obuf.Write1(ChallengeAck);
            obuf.Write(digest);

            obuf.WriteTo(socket.OutputStream);

            if (TraceLevel >= TraceHandshake)
            {
                Logger.Debug($"-> HANDSHAKE sendChallengeAck digest={Hex(digest)} local={Local}");
            }
        }
Пример #10
0
        protected void SendChallengeReply(int challenge, byte[] digest)
        {
            OtpOutputStream obuf = new OtpOutputStream();

            obuf.Write2BE(21);
            obuf.Write1(ChallengeReply);
            obuf.Write4BE(challenge);
            obuf.Write(digest);

            obuf.WriteTo(socket.OutputStream);

            if (TraceLevel >= TraceHandshake)
            {
                Logger.Debug($"-> HANDSHAKE sendChallengeReply challenge={challenge} digest={Hex(digest)} local={Local}");
            }
        }
Пример #11
0
        protected void SendComplement(int nameTag)
        {
            if (nameTag == 'n' && (Peer.CapFlags & AbstractNode.dFlagHandshake23) != 0)
            {
                OtpOutputStream obuf = new OtpOutputStream();
                obuf.Write2BE(1 + 4 + 4);
                obuf.Write1('c');
                int flagsHigh = (int)(Local.CapFlags >> 32);
                obuf.Write4BE(flagsHigh);
                obuf.Write4BE(Local.Creation);

                obuf.WriteTo(socket.OutputStream);

                if (TraceLevel >= TraceHandshake)
                {
                    Logger.Debug($"-> HANDSHAKE sendComplement flagsHigh={flagsHigh} creation={Local.Creation}");
                }
            }
        }