read2BE() public method

public read2BE ( ) : int
return int
Beispiel #1
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 #2
0
            public override void run()
            {
                byte[]         lbuf = new byte[2];
                OtpInputStream ibuf;
                int            len;

                try
                {
                    while (!done)
                    {
                        readSock(sock, lbuf);
                        ibuf = new OtpInputStream(lbuf, 0);
                        len  = ibuf.read2BE();
                        byte[] tmpbuf = new byte[len];
                        readSock(sock, tmpbuf);
                        ibuf = new OtpInputStream(tmpbuf, 0);

                        int request = ibuf.read1();
                        switch (request)
                        {
                        case publish4req:
                            r4_publish(sock, ibuf);
                            break;

                        case port4req:
                            r4_port(sock, ibuf);
                            done = true;
                            break;

                        case names4req:
                            r4_names(sock, ibuf);
                            done = true;
                            break;

                        case stopReq:
                            break;

                        default:
                            log.InfoFormat("[OtpEpmd] Unknown request (request={0}, length={1}) from {2}",
                                           request, len, sock.Client.RemoteEndPoint);
                            break;
                        }
                    }
                }
                catch (IOException)
                {
                }
                finally
                {
                    quit();
                }
            }
Beispiel #3
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);
        }
Beispiel #4
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
        }
Beispiel #5
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 #6
0
        private static int r3_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(port3req);
                    obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive));

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

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

                    // receive and decode reply
                    byte[] tmpbuf = new byte[100];

                    s.GetStream().Read(tmpbuf, 0, tmpbuf.Length);
                    OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);

                    port = ibuf.read2BE();
                }
            }
            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);
        }
            public override void run()
            {
                byte[] lbuf = new byte[2];
                OtpInputStream ibuf;
                int len;

                try
                {
                    while (!done)
                    {
                        readSock(sock, lbuf);
                        ibuf = new OtpInputStream(lbuf, 0);
                        len = ibuf.read2BE();
                        byte[] tmpbuf = new byte[len];
                        readSock(sock, tmpbuf);
                        ibuf = new OtpInputStream(tmpbuf, 0);

                        int request = ibuf.read1();
                        switch (request)
                        {
                            case publish4req:
                                r4_publish(sock, ibuf);
                                break;

                            case port4req:
                                r4_port(sock, ibuf);
                                done = true;
                                break;

                            case names4req:
                                r4_names(sock, ibuf);
                                done = true;
                                break;

                            case stopReq:
                                break;

                            default:
                                log.InfoFormat("[OtpEpmd] Unknown request (request={0}, length={1}) from {2}",
                                           request, len, sock.Client.RemoteEndPoint);
                                break;
                        }
                    }
                }
                catch (IOException)
                {
                }
                finally
                {
                    quit();
                }
            }
            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;
            }
        protected byte[] read2BytePackage()
        {
            byte[] lbuf = new byte[2];
            byte[] tmpbuf;

            readSock(socket, lbuf);
            OtpInputStream ibuf = new OtpInputStream(lbuf, 0);
            int len = ibuf.read2BE();
            tmpbuf = new byte[len];
            readSock(socket, tmpbuf);
            return tmpbuf;
        }
        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;
        }
        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);
            }
        }
        /*
         * 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;
        }
        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
        }
        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;
        }
        private static int r3_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(port3req);
                    obuf.writeN(Encoding.GetEncoding("iso-8859-1").GetBytes(node.Alive));

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

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

                    // receive and decode reply
                    byte[] tmpbuf = new byte[100];

                    s.GetStream().Read(tmpbuf, 0, tmpbuf.Length);
                    OtpInputStream ibuf = new OtpInputStream(tmpbuf, 0);

                    port = ibuf.read2BE();
                }
            }
            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;
        }