Пример #1
0
 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;
 }
Пример #2
0
 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;
 }
Пример #3
0
 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);
 }
Пример #4
0
        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));
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        private void TryAppendConfigToRemoteNode(ErlRemoteNode peer)
        {
            if (AllNodeConfigs == null)
            {
                return;
            }

            var cfg = RemoteNodeConfig(peer.NodeName);

            if (cfg.Exists)
            {
                peer.Configure(cfg);
            }
        }
Пример #7
0
 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);
     }
 }
Пример #8
0
        /// <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();
            }
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
            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;
                }
            }
Пример #11
0
 /// <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));
 }
Пример #12
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, 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;
        }
Пример #13
0
            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;
                }
            }
Пример #14
0
        private void TryAppendConfigToRemoteNode(ErlRemoteNode peer)
        {
            if (AllNodeConfigs == null) return;

              var cfg = RemoteNodeConfig(peer.NodeName);

              if (cfg.Exists)
            peer.Configure(cfg);
        }
Пример #15
0
        /// <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();
        }
Пример #16
0
 /// <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));
 }
Пример #17
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)
        {
            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);
        }
Пример #18
0
        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));
        }
Пример #19
0
        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);
        }