Ejemplo n.º 1
0
        private void doConnect(int port)
        {
            try
            {
                m_Transport = ErlTransportFactory.Create(RemoteNode.TransportClassName, RemoteNode.NodeName.Value);

                m_Transport.Trace += (o, t, d, msg) => m_Home.OnTrace(t, d, msg);

                setSockOpts();

                m_Home.OnTrace(ErlTraceLevel.Handshake, Direction.Outbound, () =>
                               "MD5 CONNECT TO {0}:{1}".Args(m_Peer.Host, port));

                //m_TcpClient.ReceiveTimeout = 5000;
                m_Transport.Connect(m_Peer.Host, port, ConnectTimeout);

                m_Home.OnTrace(ErlTraceLevel.Handshake, Direction.Outbound, () =>
                               "MD5 CONNECTED TO {0}:{1}".Args(m_Peer.Host, port));

                sendName(m_Peer.DistChoose, ErlAbstractNode.NodeCompatibility.Flags);
                recvStatus();
                int    herChallenge = recvChallenge();
                byte[] our_digest   = genDigest(herChallenge, m_Cookie);
                int    ourChallenge = genChallenge();
                sendChallengeReply(ourChallenge, our_digest);
                recvChallengeAck(ourChallenge);
                m_CookieOk         = true;
                m_ShouldSendCookie = false;
            }
            catch (ErlAuthException ae)
            {
                Close();
                throw ae;
            }
            catch (Exception e)
            {
                Close();
                throw new ErlConnectionException(Name,
                                                 StringConsts.ERL_CONN_CANT_CONNECT_TO_NODE_ERROR.Args(
                                                     "{0}:{1}{2}: {3}".Args(m_Peer.Host, port,
                                                                            m_Peer.NodeName == ErlAtom.Null ? "" : " [{0}]".Args(m_Peer.NodeName.Value),
                                                                            e.Message)));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determine what port a node listens for incoming connections on
        /// </summary>
        /// <param name="home">Local node</param>
        /// <param name="node">Remote lode for which to look up the port number from remote EPMD</param>
        /// <param name="closeSocket">If true, close the connection to remote EPMD at return</param>
        /// <returns>the listen port for the specified node, or 0 if the node
        /// was not registered with Epmd</returns>
        public static int LookupPort(ErlLocalNode home, ErlRemoteNode node,
                                     bool closeSocket = false)
        {
            IErlTransport s = null;

            try
            {
                var obuf = new ErlOutputStream(writeVersion: false, capacity: 4 + 3 + node.AliveName.Length + 1);
                s = node.Epmd;

                if (s == null)
                {
                    //create transport
                    s = ErlTransportFactory.Create(node.TransportClassName, node.NodeName.Value);

                    s.Trace += (o, t, d, msg) => home.OnTrace(t, d, msg);

                    //append SSH params to transport
                    node.AppendSSHParamsToTransport(s);

                    //connect (I am not sure)
                    s.Connect(node.Host, EPMD_PORT);
                }

                // build and send epmd request
                // length[2], tag[1], alivename[n] (length = n+1)
                obuf.Write2BE(node.AliveName.Length + 1);
                obuf.Write1((byte)Indicator.Port4req);
                //UPGRADE_NOTE: This code will be optimized in the future;
                byte[] buf = Encoding.ASCII.GetBytes(node.AliveName);
                obuf.Write(buf);

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

                home.OnTrace(ErlTraceLevel.Epmd, Direction.Outbound,
                             StringConsts.ERL_EPMD_LOOKUP_R4.Args(node.NodeName.Value));

                // 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]
                buf = new byte[100];

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

                if (n < 0)
                {
                    throw new ErlException(StringConsts.ERL_EPMD_NOT_RESPONDING.Args(node.Host, node.AliveName));
                }

                var ibuf = new ErlInputStream(buf, 0, n, checkVersion: false);

                if (Indicator.Port4resp == (Indicator)ibuf.Read1())
                {
                    if (0 == ibuf.Read1())
                    {
                        node.Port = ibuf.Read2BE();

                        node.Ntype    = (ErlAbstractNode.NodeType)ibuf.Read1();
                        node.Proto    = ibuf.Read1();
                        node.DistHigh = ibuf.Read2BE();
                        node.DistLow  = ibuf.Read2BE();
                        // ignore rest of fields
                    }
                }

                if (!closeSocket)
                {
                    node.Epmd = s;
                    s         = null;
                }
            }
            catch (Exception)
            {
                home.OnTrace(ErlTraceLevel.Epmd, Direction.Inbound, StringConsts.ERL_EPMD_INVALID_RESPONSE_ERROR);
                throw new ErlException(StringConsts.ERL_EPMD_NOT_RESPONDING.Args(node.Host, node.AliveName));
            }
            finally
            {
                if (s != null)
                {
                    try { s.Close(); } catch { }
                }
                s = null;
            }

            home.OnTrace(ErlTraceLevel.Epmd, Direction.Inbound, () =>
                         node.Port == 0 ? StringConsts.ERL_EPMD_NOT_FOUND : StringConsts.ERL_EPMD_PORT.Args(node.Port));

            return(node.Port);
        }
Ejemplo n.º 3
0
        private void doConnect(int port)
        {
            try
            {
                m_Transport = ErlTransportFactory.Create(RemoteNode.TransportClassName, RemoteNode.NodeName.Value);

                m_Transport.Trace += (o, t, d, msg) => m_Home.OnTrace(t, d, msg);

                setSockOpts();
                //m_TcpClient.ReceiveTimeout = 5000;
                var    connected = false;
                Thread thr       = new Thread(
                    () =>
                {
                    try
                    {
                        m_Transport.Connect(m_Peer.Host, port);
                        connected = true;
                    }
                    catch (Exception) { }
                }
                    )
                {
                    IsBackground = true, Name = "ErlSockConnectThread"
                };

                thr.Start();

                m_Home.OnTrace(ErlTraceLevel.Handshake, Direction.Outbound, () =>
                               "MD5 CONNECT TO {0}:{1}".Args(m_Peer.Host, port));

                var untilTime = DateTime.Now.AddMilliseconds(ConnectTimeout);

                while (!connected && DateTime.Now < untilTime)
                {
                    Thread.Sleep(10);
                }

                if (!connected) // Timeout
                {
                    throw new ErlException(StringConsts.ERL_CONN_TIMEOUT_ERROR.Args(m_Peer.Host, port));
                }

                m_Home.OnTrace(ErlTraceLevel.Handshake, Direction.Outbound, () =>
                               "MD5 CONNECTED TO {0}:{1}".Args(m_Peer.Host, port));

                sendName(m_Peer.DistChoose, ErlAbstractNode.NodeCompatibility.Flags);
                recvStatus();
                int    herChallenge = recvChallenge();
                byte[] our_digest   = genDigest(herChallenge, m_Cookie);
                int    ourChallenge = genChallenge();
                sendChallengeReply(ourChallenge, our_digest);
                recvChallengeAck(ourChallenge);
                m_CookieOk         = true;
                m_ShouldSendCookie = false;
            }
            catch (ErlAuthException ae)
            {
                Close();
                throw ae;
            }
            catch (Exception e)
            {
                Close();
                throw new ErlConnectionException(Name,
                                                 StringConsts.ERL_CONN_CANT_CONNECT_TO_NODE_ERROR.Args(
                                                     "{0}:{1}{2}: {3}".Args(m_Peer.Host, port,
                                                                            m_Peer.NodeName == ErlAtom.Null ? "" : " [{0}]".Args(m_Peer.NodeName.Value),
                                                                            e.Message)));
            }
        }