Inheritance: System.IO.MemoryStream
Beispiel #1
0
        // used by send and send_reg (message types with payload)
        protected void DoSend(OtpOutputStream header, OtpOutputStream payload)
        {
            lock (objWrite)
            {
                try
                {
                    if (TraceLevel >= TraceSend)
                    {
                        // Need to decode header and output buffer to show trace
                        // message!
                        // First make OtpInputStream, then decode.
                        try
                        {
                            IOtpErlangObject h = header.Slice(5).ReadAny();
                            Logger.Debug("-> " + HeaderType(h) + " " + h);

                            IOtpErlangObject o = payload.Slice(0).ReadAny();
                            Logger.Debug("   " + o);
                        }
                        catch (OtpDecodeException e)
                        {
                            Logger.Debug("   " + "can't decode output buffer:" + e);
                        }
                    }

                    header.WriteTo(socket.OutputStream);
                    payload.WriteTo(socket.OutputStream);
                }
                catch (IOException)
                {
                    Close();
                    throw;
                }
            }
        }
Beispiel #2
0
            private void r4_names(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- NAMES(r4) ");
                    }

                    OtpOutputStream obuf = new OtpOutputStream();
                    obuf.write4BE(EpmdPort.get());
                    lock (portmap)
                    {
                        foreach (KeyValuePair <string, OtpPublishedNode> pair in portmap)
                        {
                            OtpPublishedNode node  = pair.Value;
                            string           info  = String.Format("name {0} at port {1}\n", node.Alive, node.Port);
                            byte[]           bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(info);
                            obuf.writeN(bytes);
                        }
                    }
                    obuf.WriteTo(s.GetStream());
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
Beispiel #3
0
        // used by the other message types
        protected void DoSend(OtpOutputStream header)
        {
            lock (objWrite)
            {
                try
                {
                    if (TraceLevel >= TraceCTRL)
                    {
                        try
                        {
                            IOtpErlangObject h = header.Slice(5).ReadAny();
                            Logger.Debug("-> " + HeaderType(h) + " " + h);
                        }
                        catch (OtpDecodeException e)
                        {
                            Logger.Debug("   " + "can't decode output buffer: " + e);
                        }
                    }

                    header.WriteTo(socket.OutputStream);
                }
                catch (IOException)
                {
                    Close();
                    throw;
                }
            }
        }
Beispiel #4
0
 private void ListenActivity()
 {
     EndPoint remote = new IPEndPoint(IPAddress.Any, 0);
     for (;;)
     {
         byte[] message = new byte[BUF];
         while (this.socket.Available == 0) { }
         int size = this.socket.ReceiveFrom(message, ref remote);
         if (size == 0) continue;
         Debug.Print("Received " + size + " bytes from " + ((IPEndPoint)remote).Address + " (" + ((IPEndPoint)remote).Port + ")");
         string messageString = "";
         for (int i = 0; i < size; ++i)
         {
             messageString += (int)message[i] + " ";
         }
         Debug.Print(messageString);
         OtpInputStream inStream = new OtpInputStream(message);
         OtpErlangObject msg = inStream.read_any();
         Debug.Print(msg.ToString());
         OtpErlangTuple t = new OtpErlangTuple(new OtpErlangObject[] { new OtpErlangAtom("ok"), msg });
         OtpOutputStream outStream = new OtpOutputStream(t, false);
         byte[] answer = outStream.GetBuffer();
         this.socket.SendTo(answer, remote);
         Debug.Print(t.ToString());
     }
 }
        private async Task Names_R4(IOtpTransport socket)
        {
            try
            {
                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug("<- NAMES(r4) ");
                }

                OtpOutputStream obuf = new OtpOutputStream();
                obuf.Write4BE(EpmdPort);
                foreach (var node in portmap.Values)
                {
                    byte[] bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes($"name {node.Alive} at port {node.Port}\n");
                    obuf.WriteN(bytes);
                    Logger.Debug($"-> name {node.Alive} at port {node.Port}");
                }

                await obuf.WriteToAsync(socket.OutputStream);
            }
            catch (IOException e)
            {
                if (traceLevel >= traceThreshold)
                {
                    Logger.Debug("<- (no response)");
                }
                throw new IOException("Request not responding", e);
            }
        }
Beispiel #6
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}");
            }
        }
 public void WriteCompressed(IOtpErlangObject o, CompressionLevel level)
 {
     try
     {
         OtpOutputStream oos = new OtpOutputStream(o);
         if (oos.Length < 5)
         {
             oos.WriteTo(this);
         }
         else
         {
             Write1(OtpExternal.compressedTag);
             Write4BE(oos.Length);
             DeflateStream dos = new DeflateStream(this, level, true);
             oos.WriteTo(dos);
             dos.Close();
         }
     }
     catch (ObjectDisposedException)
     {
         throw new ArgumentException("Intermediate stream failed for Erlang object " + o);
     }
     catch (IOException)
     {
         throw new ArgumentException("Intermediate stream failed for Erlang object " + o);
     }
 }
Beispiel #8
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);
        }
Beispiel #9
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);
        }
Beispiel #10
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);
        }
Beispiel #11
0
 public void Encode(OtpOutputStream buf)
 {
     buf.WriteMapHead(Arity);
     foreach (var pair in this)
     {
         buf.WriteAny(pair.Key);
         buf.WriteAny(pair.Value);
     }
 }
Beispiel #12
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);
            }
        }
Beispiel #13
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);
        }
Beispiel #14
0
 /**
  * Convert this number to the equivalent Erlang external representation.
  *
  * @param buf
  *                an output stream to which the encoded number should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     if (!BigIntegerIsNull(bigVal))
     {
         buf.write_big_integer(bigVal);
     }
     else
     {
         buf.write_long(val);
     }
 }
Beispiel #15
0
            private void r4_port(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    int    len   = (int)(ibuf.Length - 1);
                    byte[] alive = new byte[len];
                    ibuf.readN(alive);
                    String           name = OtpErlangString.newString(alive);
                    OtpPublishedNode node = null;

                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- PORT (r4) " + name);
                    }

                    lock (portmap)
                    {
                        if (portmap.ContainsKey(name))
                        {
                            node = portmap[name];
                        }
                    }

                    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);
                    }
                    else
                    {
                        obuf.write1(port4resp);
                        obuf.write1(1);
                    }
                    obuf.WriteTo(s.GetStream());
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
Beispiel #16
0
        /**
         * Convert this tuple to the equivalent Erlang external representation.
         *
         * @param buf
         *                an output stream to which the encoded tuple should be
         *                written.
         */
        public override void encode(OtpOutputStream buf)
        {
            int arity = elems.Length;

            buf.write_tuple_head(arity);

            for (int i = 0; i < arity; i++)
            {
                buf.write_any(elems[i]);
            }
        }
Beispiel #17
0
            private void r4_publish(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    int    port     = ibuf.read2BE();
                    int    type     = ibuf.read1();
                    int    proto    = ibuf.read1();
                    int    distHigh = ibuf.read2BE();
                    int    distLow  = ibuf.read2BE();
                    int    len      = ibuf.read2BE();
                    byte[] alive    = new byte[len];
                    ibuf.readN(alive);
                    int    elen  = ibuf.read2BE();
                    byte[] extra = new byte[elen];
                    ibuf.readN(extra);
                    String           name = OtpErlangString.newString(alive);
                    OtpPublishedNode node = new OtpPublishedNode(name);
                    node.Type     = type;
                    node.DistHigh = distHigh;
                    node.DistLow  = distLow;
                    node.Proto    = proto;
                    node.Port     = port;

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

                    OtpOutputStream obuf = new OtpOutputStream();
                    obuf.write1(publish4resp);
                    obuf.write1(0);
                    obuf.write2BE(epmd.Creation);
                    obuf.WriteTo(s.GetStream());

                    lock (portmap)
                    {
                        portmap.Add(name, node);
                    }
                    publishedPort.Add(name);
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
Beispiel #18
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}");
            }
        }
Beispiel #19
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}");
            }
        }
Beispiel #20
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}");
            }
        }
Beispiel #21
0
        /**
         * Write an arbitrary Erlang term to the stream in compressed format.
         *
         * @param o
         *            the Erlang tem to write.
         */
        public void write_compressed(OtpErlangObject o)
        {
            OtpOutputStream oos = new OtpOutputStream(o);

            write1(OtpExternal.compressedTag);
            write4BE(oos.Length);
            DeflateStream dos = new DeflateStream(this, CompressionMode.Compress, true);

            try
            {
                oos.WriteTo(dos);
                dos.Close();
            }
            catch (ObjectDisposedException)
            {
                throw new ArgumentException("Intremediate stream failed for Erlang object " + o);
            }
        }
Beispiel #22
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);
            }
        }
Beispiel #23
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}");
                }
            }
        }
Beispiel #24
0
        protected void encode(OtpOutputStream buf, int start)
        {
            int arity = this.arity() - start;

            if (arity > 0)
            {
                buf.write_list_head(arity);

                for (int i = start; i < arity + start; i++)
                {
                    buf.write_any(elems[i]);
                }
            }
            if (lastTail == null)
            {
                buf.write_nil();
            }
            else
            {
                buf.write_any(lastTail);
            }
        }
Beispiel #25
0
        // Ask epmd to close his end of the connection.
        // Caller should close his epmd socket as well.
        // This method is pretty forgiving...

        /**
         * Unregister from Epmd. Other nodes wishing to connect will no longer be
         * able to.
         *
         * <p>
         * This method does not report any failures.
         */
        public static void unPublishPort(OtpLocalNode node)
        {
            try
            {
                using (TcpClient s = new TcpClient(Dns.GetHostName(), EpmdPort.get()))
                {
                    OtpOutputStream obuf = new OtpOutputStream();
                    obuf.write2BE(node.Alive.Length + 1);
                    obuf.write1(stopReq);
                    obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive));
                    obuf.WriteTo(s.GetStream());
                    // don't even wait for a response (is there one?)
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("-> UNPUBLISH " + node + " port=" + node.Port);
                        log.Debug("<- OK (assumed)");
                    }
                }
            }
            catch (Exception) /* ignore all failures */
            {
            }
        }
        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.GetOutputStream());

            if (traceLevel >= handshakeThreshold)
            {
                log.Debug("-> " + "HANDSHAKE sendChallengeReply"
                             + " challenge=" + challenge + " digest=" + hex(digest)
                             + " local=" + self);
            }
        }
        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.GetOutputStream());

            if (traceLevel >= handshakeThreshold)
            {
                log.Debug("-> " + "HANDSHAKE sendStatus" + " status="
                             + status + " local=" + self);
            }
        }
        private void sendExit(int tag, OtpErlangPid from, OtpErlangPid dest, OtpErlangObject 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.write_tuple_head(4);
            header.write_long(tag);
            header.write_any(from);
            header.write_any(dest);
            header.write_any(reason);

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

            do_send(header);
        }
 // used by the other message types
 protected void do_send(OtpOutputStream header)
 {
     lock (this)
     {
         try
         {
             if (traceLevel >= ctrlThreshold)
             {
                 try
                 {
                     OtpErlangObject h = header.getOtpInputStream(5).read_any();
                     log.Debug("-> " + headerType(h) + " " + h);
                 }
                 catch (OtpErlangDecodeException e)
                 {
                     log.Debug("   " + "can't decode output buffer: " + e);
                 }
             }
             header.WriteTo(socket.GetOutputStream());
         }
         catch (IOException e)
         {
             close();
             throw e;
         }
     }
 }
Beispiel #30
0
 /**
  * Convert this atom to the equivalent Erlang external representation.
  *
  * @param buf
  *                an output stream to which the encoded atom should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_atom(atom);
 }
 /**
  * Convert this number to the equivalent Erlang external representation.
  *
  * @param buf
  *                an output stream to which the encoded number should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     if (!BigIntegerIsNull(bigVal))
     {
         buf.write_big_integer(bigVal);
     }
     else
     {
         buf.write_long(val);
     }
 }
Beispiel #32
0
        /**
         * Convert this tuple to the equivalent Erlang external representation.
         *
         * @param buf
         *                an output stream to which the encoded tuple should be
         *                written.
         */
        public override void encode(OtpOutputStream buf)
        {
            int arity = elems.Length;

            buf.write_tuple_head(arity);

            for (int i = 0; i < arity; i++)
            {
                buf.write_any(elems[i]);
            }
        }
Beispiel #33
0
 /**
  * Convert this double to the equivalent Erlang external representation.
  *
  * @param buf
  *                an output stream to which the encoded value should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_double(d);
 }
 public override void encode(OtpOutputStream buf)
 {
     buf.write_fun(pid, module, old_index, arity, md5, index, uniq,
           freeVars);
 }
            private void r4_publish(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    int port = ibuf.read2BE();
                    int type = ibuf.read1();
                    int proto = ibuf.read1();
                    int distHigh = ibuf.read2BE();
                    int distLow = ibuf.read2BE();
                    int len = ibuf.read2BE();
                    byte[] alive = new byte[len];
                    ibuf.readN(alive);
                    int elen = ibuf.read2BE();
                    byte[] extra = new byte[elen];
                    ibuf.readN(extra);
                    String name = OtpErlangString.newString(alive);
                    OtpPublishedNode node = new OtpPublishedNode(name);
                    node.Type = type;
                    node.DistHigh = distHigh;
                    node.DistLow = distLow;
                    node.Proto = proto;
                    node.Port = port;

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

                    OtpOutputStream obuf = new OtpOutputStream();
                    obuf.write1(publish4resp);
                    obuf.write1(0);
                    obuf.write2BE(epmd.Creation);
                    obuf.WriteTo(s.GetStream());

                    lock (portmap)
                    {
                        portmap.Add(name, node);
                    }
                    publishedPort.Add(name);
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
Beispiel #36
0
 /**
  * Convert this number to the equivalent Erlang external representation.
  *
  * @param buf
  *                an output stream to which the encoded number should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_long(val);
 }
Beispiel #37
0
 /**
  * Convert this list to the equivalent Erlang external representation. Note
  * that this method never encodes lists as strings, even when it is possible
  * to do so.
  *
  * @param buf
  *            An output stream to which the encoded list should be written.
  *
  */
 public override void encode(OtpOutputStream buf)
 {
     encode(buf, 0);
 }
Beispiel #38
0
        protected void encode(OtpOutputStream buf, int start)
        {
            int arity = this.arity() - start;

            if (arity > 0)
            {
                buf.write_list_head(arity);

                for (int i = start; i < arity + start; i++)
                {
                    buf.write_any(elems[i]);
                }
            }
            if (lastTail == null)
            {
                buf.write_nil();
            }
            else
            {
                buf.write_any(lastTail);
            }
        }
Beispiel #39
0
 public override void encode(OtpOutputStream stream)
 {
     parent.encode(stream, start);
 }
        /**
         * Send a pre-encoded message to a process on a remote node.
         *
         * @param dest
         *            the Erlang PID of the remote process.
         * @param msg
         *            the encoded message to send.
         *
         * @exception java.io.IOException
         *                if the connection is not active or a communication error
         *                occurs.
         */
        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.write_tuple_head(3);
            header.write_long(sendTag);
            if (sendCookie)
            {
                header.write_atom(self.Cookie);
            }
            else
            {
                header.write_atom("");
            }
            header.write_any(dest);

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

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

            do_send(header, payload);
        }
 /**
  * Convert the object according to the rules of the Erlang external format.
  * This is mainly used for sending Erlang terms in messages, however it can
  * also be used for storing terms to disk.
  *
  * @param buf
  *                an output stream to which the encoded term should be
  *                written.
  */
 public abstract void encode(OtpOutputStream buf);
            private void r4_port(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    int len = (int)(ibuf.Length - 1);
                    byte[] alive = new byte[len];
                    ibuf.readN(alive);
                    String name = OtpErlangString.newString(alive);
                    OtpPublishedNode node = null;

                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- PORT (r4) " + name);
                    }

                    lock (portmap)
                    {
                        if (portmap.ContainsKey(name))
                        {
                            node = portmap[name];
                        }
                    }

                    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);
                    }
                    else
                    {
                        obuf.write1(port4resp);
                        obuf.write1(1);
                    }
                    obuf.WriteTo(s.GetStream());
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
Beispiel #43
0
 /**
  * Convert this port to the equivalent Erlang external representation.
  */
 public void Encode(OtpOutputStream buf) => buf.WritePort(this);
Beispiel #44
0
        private static int r4_lookupPort(AbstractNode node)
        {
            int port = 0;

            try
            {
                OtpOutputStream obuf = new OtpOutputStream();
                using (TcpClient s = new TcpClient(node.Host, EpmdPort.get()))
                {
                    // build and send epmd request
                    // length[2], tag[1], alivename[n] (length = n+1)
                    obuf.write2BE(node.Alive.Length + 1);
                    obuf.write1(port4req);
                    obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive));

                    // send request
                    obuf.WriteTo(s.GetStream());

                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("-> LOOKUP (r4) " + node);
                    }

                    // receive and decode reply
                    // resptag[1], result[1], port[2], ntype[1], proto[1],
                    // disthigh[2], distlow[2], nlen[2], alivename[n],
                    // elen[2], edata[m]
                    byte[] tmpbuf = new byte[100];

                    int n = s.GetStream().Read(tmpbuf, 0, tmpbuf.Length);

                    if (n < 0)
                    {
                        // this was an r3 node => not a failure (yet)
                        throw new IOException("Nameserver not responding on "
                                              + node.Host + " when looking up " + node.Alive);
                    }

                    OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);

                    int response = ibuf.read1();
                    if (response == port4resp)
                    {
                        int result = ibuf.read1();
                        if (result == 0)
                        {
                            port = ibuf.read2BE();

                            node.Type     = ibuf.read1();
                            node.Proto    = ibuf.read1();
                            node.DistHigh = ibuf.read2BE();
                            node.DistLow  = ibuf.read2BE();
                            // ignore rest of fields
                        }
                    }
                }
            }
            catch (SocketException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host);
            }
            catch (IOException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host
                                      + " when looking up " + node.Alive);
            }
            catch (OtpErlangDecodeException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (invalid response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host
                                      + " when looking up " + node.Alive);
            }

            if (traceLevel >= traceThreshold)
            {
                if (port == 0)
                {
                    log.Debug("<- NOT FOUND");
                }
                else
                {
                    log.Debug("<- PORT " + port);
                }
            }
            return(port);
        }
Beispiel #45
0
 /**
  * Convert this bitstr to the equivalent Erlang external representation.
  * 
  * @param buf
  *                an output stream to which the encoded bitstr should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_bitstr(bin, pad_bits);
 }
Beispiel #46
0
        private static TcpClient r3_publish(OtpLocalNode node)
        {
            TcpClient s;

            try
            {
                OtpOutputStream obuf = new OtpOutputStream();
                s = new TcpClient(node.Host, EpmdPort.get());

                obuf.write2BE(node.Alive.Length + 3);

                obuf.write1(publish3req);
                obuf.write2BE(node.Port);
                obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive));

                // send request
                obuf.WriteTo(s.GetStream());
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("-> PUBLISH (r3) " + node + " port=" + node.Port);
                }

                byte[] tmpbuf = new byte[100];

                int n = s.GetStream().Read(tmpbuf, 0, tmpbuf.Length);

                if (n < 0)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    return(null);
                }

                OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);

                if (ibuf.read1() == publish3ok)
                {
                    node.Creation = ibuf.read2BE();
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- OK");
                    }
                    return(s); // success - don't close socket
                }
            }
            catch (SocketException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host);
            }
            catch (IOException)
            {
                // epmd closed the connection = fail
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host
                                      + " when publishing " + node.Alive);
            }
            catch (OtpErlangDecodeException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (invalid response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host
                                      + " when publishing " + node.Alive);
            }
            return(null); // failure
        }
 /**
  * Convert this PID to the equivalent Erlang external representation.
  * 
  * @param buf
  *                an output stream to which the encoded PID should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_pid(node, id, serial, creation);
 }
Beispiel #48
0
        /*
         * this function will get an exception if it tries to talk to an r3 epmd, or
         * if something else happens that it cannot forsee. In both cases we return
         * an exception (and the caller should try again, using the r3 protocol). If
         * we manage to successfully communicate with an r4 epmd, we return either
         * the socket, or null, depending on the result.
         */
        private static TcpClient r4_publish(OtpLocalNode node)
        {
            TcpClient s = null;

            try
            {
                OtpOutputStream obuf = new OtpOutputStream();
                s = new TcpClient(node.Host, EpmdPort.get());

                obuf.write2BE(node.Alive.Length + 13);

                obuf.write1(publish4req);
                obuf.write2BE(node.Port);

                obuf.write1(node.Type);

                obuf.write1(node.Proto);
                obuf.write2BE(node.DistHigh);
                obuf.write2BE(node.DistLow);

                obuf.write2BE(node.Alive.Length);
                obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive));
                obuf.write2BE(0); // No extra

                // send request
                obuf.WriteTo(s.GetStream());

                if (traceLevel >= traceThreshold)
                {
                    log.Debug("-> PUBLISH (r4) " + node + " port=" + node.Port);
                }

                // get reply
                byte[] tmpbuf = new byte[100];
                int    n      = s.GetStream().Read(tmpbuf, 0, tmpbuf.Length);

                if (n < 0)
                {
                    // this was an r3 node => not a failure (yet)
                    if (s != null)
                    {
                        s.Close();
                    }
                    throw new IOException("Nameserver not responding on "
                                          + node.Host + " when publishing " + node.Alive);
                }

                OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);

                int response = ibuf.read1();
                if (response == publish4resp)
                {
                    int result = ibuf.read1();
                    if (result == 0)
                    {
                        node.Creation = ibuf.read2BE();
                        if (traceLevel >= traceThreshold)
                        {
                            log.Debug("<- OK");
                        }
                        return(s); // success
                    }
                }
            }
            catch (SocketException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host);
            }
            catch (IOException)
            {
                // epmd closed the connection = fail
                if (s != null)
                {
                    s.Close();
                }
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host
                                      + " when publishing " + node.Alive);
            }
            catch (OtpErlangDecodeException)
            {
                if (s != null)
                {
                    s.Close();
                }
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (invalid response)");
                }
                throw new IOException("Nameserver not responding on " + node.Host
                                      + " when publishing " + node.Alive);
            }

            if (s != null)
            {
                s.Close();
            }
            return(null);
        }
        // used by send and send_reg (message types with payload)
        protected void do_send(OtpOutputStream header, OtpOutputStream payload)
        {
            lock (this)
            {
                try
                {
                    if (traceLevel >= sendThreshold)
                    {
                        // Need to decode header and output buffer to show trace
                        // message!
                        // First make OtpInputStream, then decode.
                        try
                        {
                            OtpErlangObject h = header.getOtpInputStream(5).read_any();

                            log.Debug("-> " + headerType(h) + " " + h);

                            OtpErlangObject o = payload.getOtpInputStream(0).read_any();
                            log.Debug("   " + o);
                            o = null;
                        }
                        catch (OtpErlangDecodeException e)
                        {
                            log.Debug("   " + "can't decode output buffer:" + e);
                        }
                    }

                    header.WriteTo(socket.GetOutputStream());
                    payload.WriteTo(socket.GetOutputStream());
                }
                catch (IOException e)
                {
                    close();
                    throw e;
                }
            }
        }
Beispiel #50
0
        public static String[] lookupNames(IPAddress address)
        {
            try
            {
                OtpOutputStream obuf = new OtpOutputStream();

                using (TcpClient s = new TcpClient(address.ToString(), EpmdPort.get()))
                {
                    obuf.write2BE(1);
                    obuf.write1(names4req);
                    // send request
                    obuf.WriteTo(s.GetStream());

                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("-> NAMES (r4) ");
                    }

                    // get reply
                    byte[]       buffer = new byte[256];
                    MemoryStream ms     = new MemoryStream(256);
                    while (true)
                    {
                        int bytesRead = s.GetStream().Read(buffer, 0, buffer.Length);
                        if (bytesRead == -1)
                        {
                            break;
                        }
                        ms.Write(buffer, 0, bytesRead);
                    }
                    byte[]         tmpbuf = ms.GetBuffer();
                    OtpInputStream ibuf   = new OtpInputStream(tmpbuf, 0);
                    ibuf.read4BE(); // read port int
                    // int port = ibuf.read4BE();
                    // check if port = epmdPort

                    int    n   = tmpbuf.Length;
                    byte[] buf = new byte[n - 4];
                    Array.Copy(tmpbuf, 4, buf, 0, n - 4);
                    String all = OtpErlangString.newString(buf);
                    return(all.Split(new char[] { '\n' }));
                }
            }
            catch (SocketException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding on " + address);
            }
            catch (IOException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (no response)");
                }
                throw new IOException("Nameserver not responding when requesting names");
            }
            catch (OtpErlangDecodeException)
            {
                if (traceLevel >= traceThreshold)
                {
                    log.Debug("<- (invalid response)");
                }
                throw new IOException("Nameserver not responding when requesting names");
            }
        }
        /*
         * 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());
        }
            private void r4_names(TcpClient s, OtpInputStream ibuf)
            {
                try
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- NAMES(r4) ");
                    }

                    OtpOutputStream obuf = new OtpOutputStream();
                    obuf.write4BE(EpmdPort.get());
                    lock (portmap)
                    {
                        foreach (KeyValuePair<string, OtpPublishedNode> pair in portmap)
                        {
                            OtpPublishedNode node = pair.Value;
                            string info = String.Format("name {0} at port {1}\n", node.Alive, node.Port);
                            byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes(info);
                            obuf.writeN(bytes);
                        }
                    }
                    obuf.WriteTo(s.GetStream());
                }
                catch (IOException)
                {
                    if (traceLevel >= traceThreshold)
                    {
                        log.Debug("<- (no response)");
                    }
                    throw new IOException("Request not responding");
                }
                return;
            }
        protected void sendName(int dist, int flags)
        {
            OtpOutputStream obuf = new OtpOutputStream();
            String str = self.Node;
            obuf.write2BE(str.Length + 7); // 7 bytes + nodename
            obuf.write1(AbstractNode.NTYPE_R6);
            obuf.write2BE(dist);
            obuf.write4BE(flags);
            obuf.write(Encoding.GetEncoding("iso-8859-1").GetBytes(str));

            obuf.WriteTo(socket.GetOutputStream());

            if (traceLevel >= handshakeThreshold)
            {
                log.Debug("-> " + "HANDSHAKE sendName" + " flags=" + flags
                             + " dist=" + dist + " local=" + self);
            }
        }
Beispiel #54
0
 /**
  * Convert this string to the equivalent Erlang external representation.
  *
  * @param buf
  *            an output stream to which the encoded string should be
  *            written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_string(str);
 }
        protected void sendChallengeAck(byte[] digest)
        {
            OtpOutputStream obuf = new OtpOutputStream();
            obuf.write2BE(17);
            obuf.write1(ChallengeAck);
            obuf.write(digest);

            obuf.WriteTo(socket.GetOutputStream());

            if (traceLevel >= handshakeThreshold)
            {
                log.Debug("-> " + "HANDSHAKE sendChallengeAck"
                             + " digest=" + hex(digest) + " local=" + self);
            }
        }
Beispiel #56
0
 /**
  * Convert this binary to the equivalent Erlang external representation.
  *
  * @param buf
  *                an output stream to which the encoded binary should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_binary(bin);
 }
Beispiel #57
0
 /**
  * Convert this binary to the equivalent Erlang external representation.
  *
  * @param buf
  *                an output stream to which the encoded binary should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_binary(bin);
 }
 /**
  * Write an arbitrary Erlang term to the stream in compressed format.
  * 
  * @param o
  *            the Erlang tem to write.
  */
 public void write_compressed(OtpErlangObject o)
 {
     OtpOutputStream oos = new OtpOutputStream(o);
     write1(OtpExternal.compressedTag);
     write4BE(oos.Length);
     DeflateStream dos = new DeflateStream(this, CompressionMode.Compress, true);
     try
     {
         oos.WriteTo(dos);
         dos.Close();
     }
     catch (ObjectDisposedException)
     {
         throw new ArgumentException("Intremediate stream failed for Erlang object " + o);
     }
 }
 /**
  * Convert this port to the equivalent Erlang external representation.
  * 
  * @param buf
  *                an output stream to which the encoded port should be
  *                written.
  */
 public override void encode(OtpOutputStream buf)
 {
     buf.write_port(node, id, creation);
 }
 /**
  * Send a pre-encoded message to a process on a remote node.
  * 
  * @param dest
  *                the Erlang PID of the remote process.
  * @param msg
  *                the encoded message to send.
  * 
  * @exception java.io.IOException
  *                    if the connection is not active or a communication
  *                    error occurs.
  */
 public void sendBuf(OtpErlangPid dest, OtpOutputStream payload)
 {
     base.sendBuf(self.Pid, dest, payload);
 }