read4BE() public method

public read4BE ( ) : int
return int
        protected int recvChallenge()
        {
            int challenge;

            try
            {
                byte[] buf = read2BytePackage();
                OtpInputStream ibuf = new OtpInputStream(buf, 0);
                peer.Type = ibuf.read1();
                if (peer.Type != AbstractNode.NTYPE_R6)
                {
                    throw new IOException("Unexpected peer type");
                }
                peer.DistLow = peer.DistHigh = ibuf.read2BE();
                peer.Flags = ibuf.read4BE();
                challenge = ibuf.read4BE();
                byte[] tmpname = new byte[buf.Length - 11];
                ibuf.readN(tmpname);
                String hisname = OtpErlangString.newString(tmpname);
                if (!hisname.Equals(peer.Node))
                {
                    throw new IOException("Handshake failed - peer has wrong name: " + hisname);
                }

                if ((peer.Flags & AbstractNode.dFlagExtendedReferences) == 0)
                {
                    throw new IOException("Handshake failed - peer cannot handle extended references");
                }

                if ((peer.Flags & AbstractNode.dFlagExtendedPidsPorts) == 0)
                {
                    throw new IOException("Handshake failed - peer cannot handle extended pids and ports");
                }

            }
            catch (OtpErlangDecodeException)
            {
                throw new IOException("Handshake failed - not enough data");
            }

            if (traceLevel >= handshakeThreshold)
            {
                log.Debug("<- " + "HANDSHAKE recvChallenge" + " from="
                             + peer.Node + " challenge=" + challenge + " local=" + self);
            }

            return challenge;
        }
        public override void run()
        {
            if (!connected)
            {
                deliver(new IOException("Not connected"));
                return;
            }

            byte[] lbuf = new byte[4];
            OtpInputStream ibuf;
            OtpErlangObject traceobj;
            int len;
            byte[] tock = { 0, 0, 0, 0 };

            try
            {
            receive_loop:
                while (!done)
                {
                    // 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!
                    do
                    {
                        // read 4 bytes - get length of incoming packet
                        // socket.getInputStream().read(lbuf);
                        readSock(socket, lbuf);
                        ibuf = new OtpInputStream(lbuf, flags);
                        len = ibuf.read4BE();

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

                    } while (len == 0); // tick_loop

                    // got a real message (maybe) - read len bytes
                    byte[] tmpbuf = new byte[len];
                    // i = socket.getInputStream().read(tmpbuf);
                    readSock(socket, tmpbuf);
                    ibuf = new OtpInputStream(tmpbuf, flags);

                    if (ibuf.read1() != passThrough)
                    {
                        goto receive_loop;
                    }

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

                    // decode the header
                    tmp = ibuf.read_any();
                    if (!(tmp is OtpErlangTuple))
                    {
                        goto receive_loop;
                    }

                    head = (OtpErlangTuple)tmp;
                    if (!(head.elementAt(0) is OtpErlangLong))
                    {
                        goto receive_loop;
                    }

                    // 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))
                                {
                                    goto receive_loop;
                                }
                                cookie = (OtpErlangAtom)head.elementAt(1);
                                if (sendCookie)
                                {
                                    if (!cookie.atomValue().Equals(self.Cookie))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                else
                                {
                                    if (!cookie.atomValue().Equals(""))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                cookieOk = true;
                            }

                            if (traceLevel >= sendThreshold)
                            {
                                log.Debug("<- " + headerType(head) + " " + head);

                                /* show received payload too */
                                ibuf.Mark(0);
                                traceobj = ibuf.read_any();

                                if (traceobj != null)
                                {
                                    log.Debug("   " + traceobj);
                                }
                                else
                                {
                                    log.Debug("   (null)");
                                }
                                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))
                                {
                                    goto receive_loop;
                                }
                                cookie = (OtpErlangAtom)head.elementAt(2);
                                if (sendCookie)
                                {
                                    if (!cookie.atomValue().Equals(self.Cookie))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                else
                                {
                                    if (!cookie.atomValue().Equals(""))
                                    {
                                        cookieError(self, cookie);
                                    }
                                }
                                cookieOk = true;
                            }

                            if (traceLevel >= sendThreshold)
                            {
                                log.Debug("<- " + headerType(head) + " " + head);

                                /* show received payload too */
                                ibuf.Mark(0);
                                traceobj = ibuf.read_any();

                                if (traceobj != null)
                                {
                                    log.Debug("   " + traceobj);
                                }
                                else
                                {
                                    log.Debug("   (null)");
                                }
                                ibuf.Reset();
                            }

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

                            deliver(new OtpMsg(from, toName.atomValue(), ibuf));
                            break;

                        case exitTag: // { EXIT, FromPid, ToPid, Reason }
                        case exit2Tag: // { EXIT2, FromPid, ToPid, Reason }
                            if (head.elementAt(3) == null)
                            {
                                goto receive_loop;
                            }
                            if (traceLevel >= ctrlThreshold)
                            {
                                log.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)
                            {
                                goto receive_loop;
                            }
                            if (traceLevel >= ctrlThreshold)
                            {
                                log.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 >= ctrlThreshold)
                            {
                                log.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}
                        case nodeLinkTag: // { NODELINK }
                            // (just show trace)
                            if (traceLevel >= ctrlThreshold)
                            {
                                log.Debug("<- " + headerType(head) + " " + head);
                            }
                            break;

                        default:
                            // garbage?
                            goto receive_loop;
                    }
                } // end receive_loop

                // this section reachable only with break
                // we have received garbage from peer
                deliver(new OtpErlangExit("Remote is sending garbage"));

            } // try

            catch (OtpAuthException e)
            {
                deliver(e);
            }
            catch (OtpErlangDecodeException)
            {
                deliver(new OtpErlangExit("Remote is sending garbage"));
            }
            catch (IOException)
            {
                deliver(new OtpErlangExit("Remote has closed connection"));
            }
            finally
            {
                close();
            }
        }
        protected int recvChallengeReply(int our_challenge)
        {
            int challenge;
            byte[] her_digest = new byte[16];

            try
            {
                byte[] buf = read2BytePackage();
                OtpInputStream ibuf = new OtpInputStream(buf, 0);
                int tag = ibuf.read1();
                if (tag != ChallengeReply)
                {
                    throw new IOException("Handshake protocol error");
                }
                challenge = ibuf.read4BE();
                ibuf.readN(her_digest);
                byte[] our_digest = genDigest(our_challenge, self.Cookie);
                if (!digests_equals(her_digest, our_digest))
                {
                    throw new OtpAuthException("Peer authentication error.");
                }
            }
            catch (OtpErlangDecodeException)
            {
                throw new IOException("Handshake failed - not enough data");
            }

            if (traceLevel >= handshakeThreshold)
            {
                log.Debug("<- " + "HANDSHAKE recvChallengeReply"
                             + " from=" + peer.Node + " challenge=" + challenge
                             + " digest=" + hex(her_digest) + " local=" + self);
            }

            return challenge;
        }
        protected void recvName(OtpPeer peer)
        {
            String hisname = "";

            try
            {
                byte[] tmpbuf = read2BytePackage();
                OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);
                byte[] tmpname;
                int len = tmpbuf.Length;
                peer.Type = ibuf.read1();
                if (peer.Type != AbstractNode.NTYPE_R6)
                {
                    throw new IOException("Unknown remote node type");
                }
                peer.DistLow = peer.DistHigh = ibuf.read2BE();
                if (peer.DistLow < 5)
                {
                    throw new IOException("Unknown remote node type");
                }
                peer.Flags = ibuf.read4BE();
                tmpname = new byte[len - 7];
                ibuf.readN(tmpname);
                hisname = OtpErlangString.newString(tmpname);
                // Set the old nodetype parameter to indicate hidden/normal status
                // When the old handshake is removed, the ntype should also be.
                if ((peer.Flags & AbstractNode.dFlagPublished) != 0)
                {
                    peer.Type = AbstractNode.NTYPE_R4_ERLANG;
                }
                else
                {
                    peer.Type = AbstractNode.NTYPE_R4_HIDDEN;
                }

                if ((peer.Flags & AbstractNode.dFlagExtendedReferences) == 0)
                {
                    throw new IOException("Handshake failed - peer cannot handle extended references");
                }

                if ((peer.Flags & AbstractNode.dFlagExtendedPidsPorts) == 0)
                {
                    throw new IOException("Handshake failed - peer cannot handle extended pids and ports");
                }
            }
            catch (OtpErlangDecodeException)
            {
                throw new IOException("Handshake failed - not enough data");
            }

            int i = hisname.IndexOf('@', 0);
            peer.Node = hisname;
            peer.Alive = hisname.Substring(0, i);
            peer.Host = hisname.Substring(i + 1, hisname.Length - (i + 1));

            if (traceLevel >= handshakeThreshold)
            {
                log.Debug("<- " + "HANDSHAKE" + " ntype=" + peer.Type
                             + " dist=" + peer.DistHigh + " remote=" + peer);
            }
        }
        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");
            }
        }