Beispiel #1
0
 /// <summary>
 /// Break links of all pids linked to pids on the fromNode node
 /// </summary>
 internal void BreakLinks(ErlAtom fromNode, IErlObject reason)
 {
     foreach (var m in m_Mailboxes)
     {
         m.Value.BreakLinks(fromNode, reason);
     }
 }
Beispiel #2
0
        internal ErlTuple ToCtrlTuple(ErlAtom cookie)
        {
            switch (Type)
            {
            case Tag.Link: return(new ErlTuple((int)Type, m_From, m_To));

            case Tag.Send: return(new ErlTuple((int)Type, cookie, m_To));

            case Tag.Exit: return(new ErlTuple((int)Type, m_From, m_To, Reason));

            case Tag.Unlink: return(new ErlTuple((int)Type, m_From, m_To));

            case Tag.NodeLink: return(new ErlTuple((int)Type));

            case Tag.RegSend: return(new ErlTuple((int)Type, m_From, cookie, m_To));

            case Tag.GroupLeader: return(new ErlTuple((int)Type, m_From, m_To));

            case Tag.Exit2: return(new ErlTuple((int)Type, m_From, m_To, Reason));

            case Tag.SendTT: return(new ErlTuple((int)Type, cookie, m_To, TraceToken));

            case Tag.Exit2TT:
            case Tag.ExitTT: return(new ErlTuple((int)Type, m_From, m_To, TraceToken, Reason));

            case Tag.RegSendTT: return(new ErlTuple((int)Type, m_From, cookie, m_To, TraceToken));

            case Tag.MonitorP:
            case Tag.DemonitorP: return(new ErlTuple((int)Type, m_From, Recipient, Ref));

            case Tag.MonitorPexit: return(new ErlTuple((int)Type, Sender, m_To, Ref, Reason));

            default: throw new ErlException(StringConsts.ERL_INVALID_VALUE_ERROR.Args(Type));
            }
        }
Beispiel #3
0
 protected internal virtual void OnNodeStatusChange(ErlAtom node, bool up, object info)
 {
     if (NodeStatusChange != null)
     {
         NodeStatusChange(this, node, up, info);
     }
 }
Beispiel #4
0
 /// <summary>
 /// Create a node with the given name, cookie, and short name indicator
 /// </summary>
 public ErlLocalNode(string node, ErlAtom cookie, bool shortName = true,
                     bool acceptConns = true)
     : base(node, cookie, shortName)
 {
     m_AcceptConnections = acceptConns;
     TraceLevel          = ErlApp.DefaultTraceLevel;
 }
Beispiel #5
0
 protected internal virtual void OnIoOutput(ErlAtom encoding, IErlObject output)
 {
     if (IoOutput != null)
     {
         IoOutput(this, encoding, output);
     }
 }
Beispiel #6
0
 internal void IoOutput(ErlAtom encoding, IErlObject output)
 {
     if (m_OnIoOutput != null)
     {
         m_OnIoOutput(encoding, output);
     }
 }
Beispiel #7
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);

            //try to append config to remote node
            TryAppendConfigToRemoteNode(peer);

            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);
            }
        }
Beispiel #8
0
 internal void NodeStatus(ErlAtom node, bool up, object info)
 {
     if (m_OnNodeStatus != null)
     {
         m_OnNodeStatus(node, up, info);
     }
 }
Beispiel #9
0
 internal void ConnectAttempt(ErlAtom node, Direction dir, object info)
 {
     if (m_OnConnectAttempt != null)
     {
         m_OnConnectAttempt(node, dir, info);
     }
 }
Beispiel #10
0
 /// <summary>
 /// Used to break all known links to this mbox
 /// </summary>
 internal void BreakLinks(ErlAtom reason)
 {
     foreach (var l in m_Links.Clear())
     {
         m_Node.Deliver(ErlMsg.Exit(m_Self, l.Pid, reason));
     }
 }
Beispiel #11
0
        static ErlAbstractNode()
        {
            try   { LocalHost = System.Net.Dns.GetHostName(); }
            catch { LocalHost = "localhost"; }

            s_DefaultCookie = tryReadDefaultCookieFromFile();
        }
Beispiel #12
0
 protected internal virtual void OnConnectAttempt(ErlAtom node, Direction dir, object info)
 {
     if (ConnectAttempt != null)
     {
         ConnectAttempt(this, node, dir, info);
     }
 }
Beispiel #13
0
 protected internal void OnEpmdFailedConnectAttempt(ErlAtom node, object info)
 {
     if (EpmdFailedConnectAttempt != null)
     {
         EpmdFailedConnectAttempt(this, node, info);
     }
 }
Beispiel #14
0
        /// <summary>
        /// Create a node with the given name and cookie
        /// </summary>
        /// <param name="name">Node name in the form "name" or "name@hostname"</param>
        /// <param name="cookie">Security cookie used to connect to this/other node(s)</param>
        /// <param name="shortName">Use short/long host names</param>
        protected ErlAbstractNode(string name, ErlAtom cookie, bool shortName)
            : base(null)
        {
            m_Cookie       = new ErlAtom(cookie.Empty ? s_DefaultCookie : cookie);
            m_UseShortName = shortName;

            SetNodeName(name);
        }
Beispiel #15
0
 /// <summary>
 /// Create an Erlang pid from the given values
 /// </summary>
 public ErlPid(ErlAtom node, int id, int serial, int creation)
 {
     // TODO: check compatibility with latest version of Erlang supporting 28bit pids
     Node = node;
     // m_Num is 15+13+2 bits
     m_Num = (((id & 0x7fff) << 15)
              | ((serial & 0x1fff) << 2)
              | (creation & 0x3)) & 0x3fffFFFF;
 }
Beispiel #16
0
 internal ErlMbox(ErlLocalNode home, ErlPid self, ErlAtom name)
 {
     m_Self     = self;
     m_Node     = home;
     m_RegName  = name;
     m_Queue    = new ErlBlockingQueue <IQueable>();
     m_Links    = new ErlLinks();
     m_Monitors = new ErlMonitors(this);
 }
Beispiel #17
0
        private byte[] genDigest(int challenge, ErlAtom cookie)
        {
            long ch2 = challenge < 0
          ? 1L << 31 | (long)(challenge & 0x7FFFFFFFL)
                : (long)challenge;

            return(new MD5CryptoServiceProvider().ComputeHash(
                       Encoding.UTF8.GetBytes(cookie.Value + Convert.ToString(ch2))));
        }
Beispiel #18
0
        public IErlObject RPC(ErlAtom node, ErlAtom mod, ErlAtom fun, ErlList args, int timeout, ErlAtom?remoteCookie = null)
        {
            AsyncRPC(node, mod, fun, args, remoteCookie);
            var r = m_Monitors.Add(node);

            using (Scope.OnExit(() => m_Monitors.Remove(r)))
            {
                return(ReceiveRPC(timeout));
            }
        }
Beispiel #19
0
        public bool Register(ErlAtom name)
        {
            var res = m_Node.Mailboxes.Register(name, this);

            if (res)
            {
                m_RegName = name;
            }
            return(res);
        }
Beispiel #20
0
 /// <summary>
 /// Close this mailbox
 /// </summary>
 /// <remarks>
 /// After this operation, the mailbox will no longer be able to
 /// receive messages. Any delivered but as yet unretrieved messages
 /// can still be retrieved however.
 ///
 /// If there are links from this mailbox to other <see cref="ErlPid"/>
 /// pids they will be broken when this method is
 /// called and exit signals will be sent.
 /// </remarks>
 internal void Close()
 {
     // Notify all registered monitors that this pid is closing
     foreach (var monitor in m_Monitors)
     {
         var msg = ErlMsg.MonitorPexit(m_Self, monitor.Value, monitor.Key, ErlAtom.Normal);
         m_Node.Deliver(monitor.Value.Node, msg);
     }
     m_Node.CloseMbox(this);
     m_RegName = ErlAtom.Null;
 }
Beispiel #21
0
        public List <ErlLink> Remove(ErlAtom toNode)
        {
            var links = new List <ErlLink>(Math.Min(m_Links.Count, 32));

            lock (m_Links)
                m_Links.RemoveWhere(l => { var r = l.Node == toNode; if (r)
                                           {
                                               links.Add(l);
                                           }
                                           return(r); });

            return(links);
        }
Beispiel #22
0
        public IErlObject RPC(ErlAtom node, ErlAtom mod, ErlAtom fun, ErlList args, int timeout)
        {
            var mbox = m_Mailboxes.Create(true);

            try
            {
                var res = mbox.RPC(node, mod, fun, args, timeout);
                return(res);
            }
            finally
            {
                m_Mailboxes.Unregister(mbox);
            }
        }
Beispiel #23
0
 public void RPCcast(ErlAtom node, ErlAtom mod, ErlAtom fun, ErlList args, IErlObject ioServer)
 {
     if (node.Equals(m_Node.NodeName))
     {
         throw new ErlException(StringConsts.ERL_CONN_CANT_RPC_TO_LOCAL_NODE_ERROR);
     }
     else
     {
         var msg  = Internal.ErlRpcServer.EncodeRPCcast(m_Self, mod, fun, args, ioServer);
         var conn = m_Node.Connection(node);
         if (conn == null)
         {
             throw new ErlConnectionException(
                       node, StringConsts.ERL_CONN_CANT_CONNECT_TO_NODE_ERROR.Args(node));
         }
         conn.Send(m_Self, ConstAtoms.Rex, msg);
     }
 }
Beispiel #24
0
        internal bool Deliver(ErlAtom node, ErlMsg msg)
        {
            if (node == NodeName)
            {
                return(Deliver(msg));
            }

            var conn = Connection(node);

            if (conn == null)
            {
                return(false);
            }

            try     { conn.Send(msg); }
            catch   { return(false); }
            return(true);
        }
Beispiel #25
0
        private void sendChallenge(int dist, ErlAbstractNode.NodeCompatibility flags, int challenge)
        {
            ErlAtom str  = m_Home.NodeName;
            var     obuf = new ErlOutputStream(writeVersion: false, writePktSize: false, capacity: 11 + str.Length);

            obuf.Write2BE((short)str.Length + 11); // 11 bytes + nodename
            obuf.Write1((byte)ErlAbstractNode.NodeType.Ntype_R6);
            obuf.Write2BE((short)dist);
            obuf.Write4BE((int)flags);
            obuf.Write4BE(challenge);
            obuf.Write(Encoding.ASCII.GetBytes(str.Value));

            obuf.WriteTo(m_TcpClient.GetStream());

            m_Home.OnTrace(ErlTraceLevel.Handshake, Direction.Outbound, () =>
                           "sendChallenge(flags({0:X2})={1}, dist={2}, challenge={3}, local={4}".Args(
                               (int)flags, flags, dist, challenge, m_Home.AliveName));
        }
Beispiel #26
0
        /// <summary>
        /// Send an auth error to peer because he sent a bad cookie
        /// The auth error uses his cookie (not revealing ours).
        /// This is just like send_reg otherwise
        /// </summary>
        private void cookieError(ErlLocalNode local, ErlAtom cookie)
        {
            var header = new ErlOutputStream(writeVersion: false, capacity: HEADER_LEN);

            // preamble: 4 byte length + "PASS_THROUGH" tag + version
            header.Write4BE(0); // reserve space for length
            header.Write1(PASS_THROUGH);
            header.Write1((byte)ErlExternalTag.Version);

            header.WriteTupleHead(4);
            header.WriteLong((long)ErlMsg.Tag.RegSend);
            header.WritePid(local.CreatePid()); // disposable pid
            header.WriteAtom(cookie);           // important: his cookie, not mine...
            header.WriteAtom("auth");

            // version for payload written later by the payload stream
            //header.Write1((byte)ErlExternalTag.Version);

            // the payload

            // the no_auth message (copied from Erlang) Don't change this (Erlang will crash)
            // {$gen_cast, {print, "~n** Unauthorized cookie ~w **~n", [foo@aule]}}

            var msg = ErlObject.Parse(
                "{'$gen_cast', {print, \"\n** Unauthorized cookie ~w **\n\", [" + local.NodeName.Value + "]}}");

            var payload = new ErlOutputStream(msg, writeVersion: true);

            // fix up length in preamble
            header.Poke4BE(0, (int)(header.Length + payload.Length - 4));

            try
            {
                DoSend(header, payload);
            }
            catch (Exception e)
            {
                Close();
                throw new ErlException(StringConsts.ERL_CONN_UNAUTH_COOKIE_ERROR.Args(cookie.Value), e);
            }
        }
Beispiel #27
0
 /// <summary>
 /// Create an Erlang reference from the given values
 /// </summary>
 public ErlRef(ErlAtom node, uint[] ids, int creation)
 {
     Node     = node;
     Creation = creation & 0x3;
     if (ids.Length == 3)
     {
         Ids = ids;
     }
     else
     {
         Ids = new uint[3];
         int i = 0;
         for (int n = Math.Min(ids.Length, 3); i < n; i++)
         {
             Ids[i] = ids[i];
         }
         for (; i < 3; i++)
         {
             Ids[i] = 0;
         }
     }
 }
Beispiel #28
0
        /// <summary>
        /// Used to break all known links to this mbox
        /// </summary>
        internal void BreakLinks(ErlAtom fromNode, IErlObject reason)
        {
            var links = m_Links.Remove(fromNode);

            foreach (var link in links)
            {
                if (link.HasPid)
                {
                    m_Node.Deliver(ErlMsg.Exit(m_Self, link.Pid, reason));
                }
                else
                {
                    m_Node.Deliver(new ErlConnectionException(fromNode, reason));
                }
            }

            foreach (var m in m_Monitors.Where(o => o.Value.Node == fromNode)
                     .Where(m => m_Monitors.Remove(m.Key)))
            {
                Deliver(new ErlConnectionException(fromNode, reason));
            }
        }
Beispiel #29
0
        internal static void splitNodeName(string name, bool shortName,
                                           out string alive, out string host, out ErlAtom nodeName, out ErlAtom longName)
        {
            int i = name.IndexOf('@');

            if (i < 0)
            {
                alive = name;
                host  = LocalHost;
            }
            else
            {
                alive = name.Substring(0, i);
                host  = name.Substring(i + 1);
            }

            if (alive.Length > AtomTable.MAX_ATOM_LEN)
            {
                alive = alive.Substring(0, AtomTable.MAX_ATOM_LEN);
            }

            longName = new ErlAtom(alive + "@" + host);
            nodeName = node(longName, shortName);
        }
Beispiel #30
0
 public void Down(ErlRef eref, ErlPid pid, ErlAtom reason)
 {
     // TODO
     throw new NotImplementedException();
 }