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))); } }
/// <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); }
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))); } }