private ErlAbstractConnection(ErlLocalNode home, ErlRemoteNode peer, TcpClient s, ErlAtom?cookie = null) { m_Peer = peer; m_Home = home; m_TcpClient = s; m_Cookie = !cookie.HasValue || cookie.Value == ErlAtom.Null ? (peer.Cookie == ErlAtom.Null ? home.Cookie : peer.Cookie) : cookie.Value; m_SentBytes = 0; m_ReceivedBytes = 0; m_MaxPayloadLength = DEFAULT_MAX_PAYLOAD_LENGTH; }
private ErlAbstractConnection(ErlLocalNode home, ErlRemoteNode peer, TcpClient s, ErlAtom? cookie = null) { m_Peer = peer; m_Home = home; m_TcpClient = s; m_Cookie = !cookie.HasValue || cookie.Value == ErlAtom.Null ? (peer.Cookie == ErlAtom.Null ? home.Cookie : peer.Cookie) : cookie.Value; m_SentBytes = 0; m_ReceivedBytes = 0; m_MaxPayloadLength = DEFAULT_MAX_PAYLOAD_LENGTH; }
private ErlAbstractConnection(ErlLocalNode home, ErlRemoteNode peer, IErlTransport s, ErlAtom? cookie = null) { m_Peer = peer; m_Home = home; m_Transport = s; m_Cookie = !cookie.HasValue || cookie.Value == ErlAtom.Null ? (peer.Cookie == ErlAtom.Null ? home.Cookie : peer.Cookie) : cookie.Value; m_SentBytes = 0; m_ReceivedBytes = 0; m_MaxPayloadLength = DEFAULT_MAX_PAYLOAD_LENGTH; if (m_Transport != null) m_Transport.Trace += (o, t, d, msg) => home.OnTrace(t, d, msg); }
private void recvName(ErlRemoteNode peer) { string hisname = string.Empty; ErlInputStream ibuf; try { ibuf = getInputStream(); } catch { throw new ErlConnectionException(Name, StringConsts.ERL_CONN_HANDSHAKE_DATA_ERROR); } int len = (int)ibuf.Length; m_Peer.Ntype = (ErlAbstractNode.NodeType)ibuf.Read1(); if (m_Peer.Ntype != ErlAbstractNode.NodeType.Ntype_R6) { throw new ErlConnectionException(Name, StringConsts.ERL_CONN_UNKNOWN_REMOTE_NODE_ERROR); } m_Peer.DistLow = m_Peer.DistHigh = ibuf.Read2BE(); if (m_Peer.DistLow < ErlAbstractNode.DIST_LOW) { throw new ErlConnectionException(Name, StringConsts.ERL_CONN_UNKNOWN_REMOTE_NODE_ERROR); } m_Peer.Flags = (ErlAbstractNode.NodeCompatibility)ibuf.Read4BE(); hisname = ibuf.ReadBytesAsString(len - 7); // Set the old nodetype parameter to indicate hidden/normal status // When the old handshake is removed, the ntype should also be. m_Peer.Ntype = (m_Peer.Flags & ErlAbstractNode.NodeCompatibility.Published) != 0 ? ErlAbstractNode.NodeType.Ntype_R4_Erlang : ErlAbstractNode.NodeType.Ntype_R4_Hidden; if ((m_Peer.Flags & ErlAbstractNode.NodeCompatibility.ExtendedReferences) == 0) { throw new ErlConnectionException(Name, StringConsts.ERL_CONN_HANDSHAKE_REF_ERROR); } if (ErlApp.UseExtendedPidsPorts && (m_Peer.Flags & ErlAbstractNode.NodeCompatibility.ExtendedPidsPorts) == 0) { throw new ErlConnectionException(Name, StringConsts.ERL_CONN_HANDSHAKE_EXT_PIDS_ERROR); } m_Peer.SetNodeName(hisname); m_Home.OnTrace(ErlTraceLevel.Handshake, Direction.Inbound, () => "ntype({0})={1}, dist={2}, remote={3}".Args( (int)m_Peer.Ntype, m_Peer.Ntype, (int)m_Peer.DistHigh, m_Peer)); }
private void TryAppendConfigToRemoteNode(ErlRemoteNode peer) { if (RemoteNodeConfigs == null) { return; } var conf = RemoteNodeConfigs.FirstOrDefault(c => c.Value.IsNotNullOrEmpty() && c.Value.EqualsSenseCase(peer.NodeName)); if (conf != null) { peer.Configure(conf); } }
private void TryAppendConfigToRemoteNode(ErlRemoteNode peer) { if (AllNodeConfigs == null) { return; } var cfg = RemoteNodeConfig(peer.NodeName); if (cfg.Exists) { peer.Configure(cfg); } }
private ErlAbstractConnection(ErlLocalNode home, ErlRemoteNode peer, IErlTransport s, ErlAtom?cookie = null) { m_Peer = peer; m_Home = home; m_Transport = s; m_Cookie = !cookie.HasValue || cookie.Value == ErlAtom.Null ? (peer.Cookie == ErlAtom.Null ? home.Cookie : peer.Cookie) : cookie.Value; m_SentBytes = 0; m_ReceivedBytes = 0; m_MaxPayloadLength = DEFAULT_MAX_PAYLOAD_LENGTH; if (m_Transport != null) { m_Transport.Trace += (o, t, d, msg) => home.OnTrace(t, d, msg); } }
/// <summary> /// Intiate and open a connection to a remote node /// </summary> protected ErlAbstractConnection(ErlLocalNode self, ErlRemoteNode other, ErlAtom?cookie = null, bool connect = true) : this(self, other, null, cookie) { // now find highest common dist value if ((m_Peer.Proto != self.Proto) || (self.DistHigh < m_Peer.DistLow) || (self.DistLow > m_Peer.DistHigh)) { throw new ErlException(StringConsts.ERL_CONN_NO_COMMON_PROTO_ERROR); } // highest common version: min(m_Peer.distHigh, self.distHigh) m_Peer.DistChoose = Math.Min(m_Peer.DistHigh, self.DistHigh); m_Connected = false; if (connect) { Connect(); } }
internal ErlConnection Connection(string toNode, IConfigSectionNode config) { var peer = new ErlRemoteNode(this, toNode); // This will convert toNode to a valid ErlAtom lock (m_Connections) { ErlConnection c; if (m_Connections.TryGetValue(peer.NodeName, out c)) { return(c); } peer.Configure(config); // Fetch all proper TCP and other settings try { c = new ErlConnection(this, peer, true); } catch { return(null); } m_Connections.TryAdd(peer.NodeName, c); return(c); } }
internal ErlConnection Connection(string toNode, IConfigSectionNode config) { var peer = new ErlRemoteNode(this, toNode); // This will convert toNode to a valid ErlAtom lock (m_Connections) { ErlConnection c; if (m_Connections.TryGetValue(peer.NodeName, out c)) return c; peer.Configure(config); // Fetch all proper TCP and other settings try { c = new ErlConnection(this, peer, true); } catch { return null; } m_Connections.TryAdd(peer.NodeName, c); return c; } }
/// <summary> /// Intiate and open a connection to a remote node /// </summary> internal ErlConnection(ErlLocalNode node, ErlRemoteNode peer, bool connect = true) : base(node, peer, connect: connect) { _ctor(StringConsts.ERL_CONNECTION.Args(m_Home.NodeName.Value, "->", peer.NodeName.Value)); }
/// <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, node.ConnectTimeout); } // 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 e) { home.OnTrace(ErlTraceLevel.Epmd, Direction.Inbound, StringConsts.ERL_EPMD_INVALID_RESPONSE_ERROR.Args(node.Host, node.AliveName, e.ToString())); throw new ErlException(StringConsts.ERL_EPMD_NOT_RESPONDING.Args(node.Host, node.AliveName, e.ToString())); } 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; }
public ErlConnection Connection(ErlAtom toNode, ErlAtom? cookie = null) { ErlConnection c; if (m_Connections.TryGetValue(toNode, out c)) return c; var peer = new ErlRemoteNode(this, toNode, cookie); lock (m_Connections) { if (m_Connections.TryGetValue(toNode, out c)) return c; try { c = new ErlConnection(this, peer, true); } catch { return null; } m_Connections.TryAdd(toNode, c); return c; } }
private void TryAppendConfigToRemoteNode(ErlRemoteNode peer) { if (AllNodeConfigs == null) return; var cfg = RemoteNodeConfig(peer.NodeName); if (cfg.Exists) peer.Configure(cfg); }
/// <summary> /// Intiate and open a connection to a remote node /// </summary> protected ErlAbstractConnection(ErlLocalNode self, ErlRemoteNode other, ErlAtom? cookie = null, bool connect = true) : this(self, other, null, cookie) { // now find highest common dist value if ((m_Peer.Proto != self.Proto) || (self.DistHigh < m_Peer.DistLow) || (self.DistLow > m_Peer.DistHigh)) throw new ErlException(StringConsts.ERL_CONN_NO_COMMON_PROTO_ERROR); // highest common version: min(m_Peer.distHigh, self.distHigh) m_Peer.DistChoose = Math.Min(m_Peer.DistHigh, self.DistHigh); m_Connected = false; if (connect) Connect(); }
/// <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) { TcpClient s = null; try { var obuf = new ErlOutputStream( writeVersion: false, capacity: 4 + 3 + node.AliveName.Length + 1); s = node.Epmd ?? new TcpClient(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.Trace(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.Trace(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.Trace(ErlTraceLevel.Epmd, Direction.Inbound, () => node.Port == 0 ? StringConsts.ERL_EPMD_NOT_FOUND : StringConsts.ERL_EPMD_PORT.Args(node.Port)); return(node.Port); }
private void recvName(ErlRemoteNode peer) { string hisname = string.Empty; ErlInputStream ibuf; try { ibuf = getInputStream(); } catch { throw new ErlConnectionException(Name, StringConsts.ERL_CONN_HANDSHAKE_DATA_ERROR); } int len = (int)ibuf.Length; m_Peer.Ntype = (ErlAbstractNode.NodeType)ibuf.Read1(); if (m_Peer.Ntype != ErlAbstractNode.NodeType.Ntype_R6) throw new ErlConnectionException(Name, StringConsts.ERL_CONN_UNKNOWN_REMOTE_NODE_ERROR); m_Peer.DistLow = m_Peer.DistHigh = ibuf.Read2BE(); if (m_Peer.DistLow < ErlAbstractNode.DIST_LOW) throw new ErlConnectionException(Name, StringConsts.ERL_CONN_UNKNOWN_REMOTE_NODE_ERROR); m_Peer.Flags = (ErlAbstractNode.NodeCompatibility)ibuf.Read4BE(); hisname = ibuf.ReadBytesAsString(len - 7); // Set the old nodetype parameter to indicate hidden/normal status // When the old handshake is removed, the ntype should also be. m_Peer.Ntype = (m_Peer.Flags & ErlAbstractNode.NodeCompatibility.Published) != 0 ? ErlAbstractNode.NodeType.Ntype_R4_Erlang : ErlAbstractNode.NodeType.Ntype_R4_Hidden; if ((m_Peer.Flags & ErlAbstractNode.NodeCompatibility.ExtendedReferences) == 0) throw new ErlConnectionException(Name, StringConsts.ERL_CONN_HANDSHAKE_REF_ERROR); if (ErlApp.UseExtendedPidsPorts && (m_Peer.Flags & ErlAbstractNode.NodeCompatibility.ExtendedPidsPorts) == 0) throw new ErlConnectionException(Name, StringConsts.ERL_CONN_HANDSHAKE_EXT_PIDS_ERROR); m_Peer.SetNodeName(hisname); m_Home.OnTrace(ErlTraceLevel.Handshake, Direction.Inbound, () => "ntype({0})={1}, dist={2}, remote={3}".Args( (int)m_Peer.Ntype, m_Peer.Ntype, (int)m_Peer.DistHigh, m_Peer)); }
private void TryAppendConfigToRemoteNode(ErlRemoteNode peer) { if (RemoteNodeConfigs == null) return; var conf = RemoteNodeConfigs.FirstOrDefault( c => c.Value.IsNotNullOrEmpty() && c.Value.EqualsSenseCase(peer.NodeName)); if (conf != null) peer.Configure(conf); }