예제 #1
0
        /**
         * Try to get an RpcResult out and handle it
         */
        protected void EnqueueHandler(object queue, EventArgs arg)
        {
            Channel   q       = (Channel)queue;
            RpcResult rpc_res = null;

            try {
                rpc_res = (RpcResult)q.Dequeue();
                ConnectToMessage new_ctm = new ConnectToMessage((IDictionary)rpc_res.Result);
                if (_local_node.Address.Equals(new_ctm.Target.Address))
                {
                    throw new Exception("Trying to connect to myself!");
                }
                lock ( _sync ) {
                    /**
                     * It is the responsibilty of the ConnectionOverlord
                     * to deal with this ctm
                     */
                    _got_ctms.Add(new_ctm);
                }
                bool close_queue = _co.HandleCtmResponse(this, rpc_res.ResultSender, new_ctm);
                if (close_queue)
                {
                    q.Close();
                }
            }
            catch (Exception) {
                //This can happen if the queue is empty and closed.  Don't do
                //anything.
            }
        }
예제 #2
0
        public override bool Equals(object o)
        {
            ConnectToMessage co = o as ConnectToMessage;

            if (co != null)
            {
                bool same = true;
                same &= co.ConnectionType == _ct;
                same &= co.Target.Equals(_target_ni);
                same &= co.Token.Equals(_token);
                if (_neighbors == null)
                {
                    same &= co.Neighbors == null;
                }
                else
                {
                    int n_count = co.Neighbors.Length;
                    for (int i = 0; i < n_count; i++)
                    {
                        same &= co.Neighbors[i].Equals(Neighbors[i]);
                    }
                }
                return(same);
            }
            else
            {
                return(false);
            }
        }
예제 #3
0
        /**
         * Connectors just send and receive ConnectToMessages.  They return all responses
         * to the ConnectionOverlord that initiated the ConnectToMessage
         * @return true if we have enough responses for this connector, and should
         * stop listening for more
         */
        virtual public bool HandleCtmResponse(Connector c, ISender return_path, ConnectToMessage resp)
        {
            /**
             * Time to start linking:
             */

            ICollection transports = resp.Target.Transports;

            if (TAAuth != null)
            {
                ArrayList trans = new ArrayList();
                foreach (TransportAddress ta in resp.Target.Transports)
                {
                    if (TAAuth.Authorize(ta) != TAAuthorizer.Decision.Deny)
                    {
                        trans.Add(ta);
                    }
                }
                transports = trans;
            }

            Linker l = new Linker(_node, resp.Target.Address, transports,
                                  resp.ConnectionType, resp.Token, return_path.ToString());

            l.FinishEvent += LinkerEndHandler;
            _node.TaskQueue.Enqueue(l);
            return(true);
        }
예제 #4
0
 public Connector(Node local, ISender ps, ConnectToMessage ctm, ConnectionOverlord co, object state)
 {
     _sync        = new Object();
     _local_node  = local;
     _is_finished = 0;
     _got_ctms    = new ArrayList();
     _sender      = ps;
     _ctm         = ctm;
     _co          = co;
     _task        = new ConnectorTask(ps);
     _abort       = new WriteOnce <AbortCheck>();
     State        = state;
 }
예제 #5
0
 /**
  * This is a method for use with the RpcManager.  Remote
  * nodes can call the "sys:ctm.ConnectTo" method to 
  * reach this method
  */
 public IDictionary ConnectTo(IDictionary ht) {
   ConnectToMessage ctm_req = new ConnectToMessage(ht);
   //Console.Error.WriteLine("[{0}.ConnectTo({1})]", _n.Address, ctm_req);
   NodeInfo target = ctm_req.Target;
   if(_n.Address.Equals(target.Address)) {
     throw new Exception("Trying to connect to myself!");
   }
   string contype = ctm_req.ConnectionType;
   Linker l = new Linker(_n, target.Address, target.Transports, contype, ctm_req.Token);
   //Here we start the job:
   _n.TaskQueue.Enqueue( l );
   ConnectToMessage resp = GetCtmResponseTo(ctm_req);
   //Console.Error.WriteLine("[{0}.ConnectTo()->{1}]", _n.Address, resp);
   return resp.ToDictionary();
 }
예제 #6
0
        public void CTMSerializationTest()
        {
            Address          a  = new DirectionalAddress(DirectionalAddress.Direction.Left);
            TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://127.0.0.1:5000");
            NodeInfo         ni = NodeInfo.CreateInstance(a, ta);

            RandomNumberGenerator rng     = new RNGCryptoServiceProvider();
            AHAddress             tmp_add = new AHAddress(rng);
            ConnectToMessage      ctm1    = new ConnectToMessage(ConnectionType.Unstructured, ni, tmp_add.ToString());

            HTRoundTrip(ctm1);

            //Test multiple tas:
            ArrayList tas = new ArrayList();

            tas.Add(ta);
            for (int i = 5001; i < 5010; i++)
            {
                tas.Add(TransportAddressFactory.CreateInstance("brunet.tcp://127.0.0.1:" + i.ToString()));
            }
            NodeInfo ni2 = NodeInfo.CreateInstance(a, tas);

            ConnectToMessage ctm2 = new ConnectToMessage(ConnectionType.Structured, ni2, tmp_add.ToString());

            HTRoundTrip(ctm2);
            //Here is a ConnectTo message with a neighbor list:
            NodeInfo[] neighs = new NodeInfo[5];
            for (int i = 0; i < 5; i++)
            {
                string   ta_tmp = "brunet.tcp://127.0.0.1:" + (i + 80).ToString();
                NodeInfo tmp    =
                    NodeInfo.CreateInstance(new DirectionalAddress(DirectionalAddress.Direction.Left),
                                            TransportAddressFactory.CreateInstance(ta_tmp)
                                            );
                neighs[i] = tmp;
            }
            ConnectToMessage ctm3 = new ConnectToMessage("structured", ni, neighs, tmp_add.ToString());

            HTRoundTrip(ctm3);
#if false
            Console.Error.WriteLine(ctm3.ToString());
            foreach (NodeInfo tni in ctm3a.Neighbors)
            {
                Console.Error.WriteLine(tni.ToString());
            }
#endif
        }
예제 #7
0
 protected ConnectToMessage GetCtmResponseTo(ConnectToMessage ctm_req) {
   NodeInfo target = ctm_req.Target;
   
   //Send the 4 neighbors closest to this node:
   ArrayList nearest = _n.ConnectionTable.GetNearestTo( (AHAddress)target.Address, 4);
   //Now get these the NodeInfo objects for these:
   ArrayList neighbors = new ArrayList();
   foreach(Connection cons in nearest) {
     //No need to send the TA, since only the address is used
     NodeInfo neigh = NodeInfo.CreateInstance(cons.Address);
     neighbors.Add( neigh );
   }
   //Put these into an NodeInfo[]
   NodeInfo[] neigh_array = new NodeInfo[ neighbors.Count ];
   for(int i = 0; i < neighbors.Count; i++) {
     neigh_array[i] = (NodeInfo)neighbors[i];
   }
   return new ConnectToMessage(ctm_req.ConnectionType, _n.GetNodeInfo(12), neigh_array, ctm_req.Token);
 }
예제 #8
0
        /**
         * This is a method for use with the RpcManager.  Remote
         * nodes can call the "sys:ctm.ConnectTo" method to
         * reach this method
         */
        public IDictionary ConnectTo(IDictionary ht)
        {
            ConnectToMessage ctm_req = new ConnectToMessage(ht);
            //Console.Error.WriteLine("[{0}.ConnectTo({1})]", _n.Address, ctm_req);
            NodeInfo target = ctm_req.Target;

            if (_n.Address.Equals(target.Address))
            {
                throw new Exception("Trying to connect to myself!");
            }
            string contype = ctm_req.ConnectionType;
            Linker l       = new Linker(_n, target.Address, target.Transports, contype, ctm_req.Token);

            //Here we start the job:
            _n.TaskQueue.Enqueue(l);
            ConnectToMessage resp = GetCtmResponseTo(ctm_req);

            //Console.Error.WriteLine("[{0}.ConnectTo()->{1}]", _n.Address, resp);
            return(resp.ToDictionary());
        }
예제 #9
0
        protected ConnectToMessage GetCtmResponseTo(ConnectToMessage ctm_req)
        {
            NodeInfo target = ctm_req.Target;

            //Send the 4 neighbors closest to this node:
            ArrayList nearest = _n.ConnectionTable.GetNearestTo((AHAddress)target.Address, 4);
            //Now get these the NodeInfo objects for these:
            ArrayList neighbors = new ArrayList();

            foreach (Connection cons in nearest)
            {
                //No need to send the TA, since only the address is used
                NodeInfo neigh = NodeInfo.CreateInstance(cons.Address);
                neighbors.Add(neigh);
            }
            //Put these into an NodeInfo[]
            NodeInfo[] neigh_array = new NodeInfo[neighbors.Count];
            for (int i = 0; i < neighbors.Count; i++)
            {
                neigh_array[i] = (NodeInfo)neighbors[i];
            }
            return(new ConnectToMessage(ctm_req.ConnectionType, _n.GetNodeInfo(12), neigh_array, ctm_req.Token));
        }
예제 #10
0
        /**
         * This method allows a user to add some state in the ConnectTo call (see SNCO).
         */
        virtual protected Connector GetConnector(ISender sender, Address target,
                                                 string ConnectionType, string token)
        {
            ConnectionType mt = Connection.StringToMainType(ConnectionType);

            /*
             * This is an anonymous delegate which is called before
             * the Connector starts.  If it returns true, the Connector
             * will finish immediately without sending an ConnectToMessage
             */
            Linker l = new Linker(_node, target, null, ConnectionType,
                                  _node.Address.ToString());
            object link_task = l.Task;

            Connector.AbortCheck abort = delegate(Connector c) {
                bool stop = false;
                stop = _node.ConnectionTable.Contains(mt, target);
                if (!stop)
                {
                    /*
                     * Make a linker to get the task.  We won't use
                     * this linker.
                     * No need in sending a ConnectToMessage if we
                     * already have a linker going.
                     */
                    stop = _node.TaskQueue.HasTask(link_task);
                }
                return(stop);
            };

            ConnectToMessage ctm = GetConnectToMessage(ConnectionType, token);
            Connector        con = new Connector(_node, sender, ctm, this, target);

            con.FinishEvent += ConnectorEndHandler;
            con.AbortIf      = abort;
            return(con);
        }
예제 #11
0
 public Connector(Node local, ISender ps, ConnectToMessage ctm, ConnectionOverlord co, object state)
 {
   _sync = new Object();
   _local_node = local;
   _is_finished = 0;
   _got_ctms = new ArrayList();
   _sender = ps;
   _ctm = ctm;
   _co = co;
   _task = new ConnectorTask(ps);
   _abort = new WriteOnce<AbortCheck>();
   State = state;
 }
 /**
  * When we get ConnectToMessage responses the connector tells us.
  */
 override public bool HandleCtmResponse(Connector c, ISender ret_path,
                                        ConnectToMessage ctm_resp)
 {
   base.HandleCtmResponse(c, ret_path, ctm_resp);
   /**
    * Check this guys neighbors:
    */
   //See if we want more:
   bool got_enough = true;
   object des_o = _connectors[c];
   if( des_o != null ) {
     got_enough = (c.ReceivedCTMs.Count >= (int)des_o);
   }
   return got_enough;
 }
예제 #13
0
        public void HTRoundTrip(ConnectToMessage ctm)
        {
            ConnectToMessage ctm2 = new ConnectToMessage(ctm.ToDictionary());

            Assert.AreEqual(ctm, ctm2, "CTM HT Roundtrip");
        }
예제 #14
0
    /**
     * Try to get an RpcResult out and handle it
     */
    protected void EnqueueHandler(object queue, EventArgs arg) {
      Channel q = (Channel)queue;
      RpcResult rpc_res = null;
      try {
        rpc_res = (RpcResult)q.Dequeue();
        ConnectToMessage new_ctm = new ConnectToMessage( (IDictionary)rpc_res.Result );
        if(_local_node.Address.Equals(new_ctm.Target.Address)) {
          throw new Exception("Trying to connect to myself!");
        }
        lock( _sync ) {
        /**
         * It is the responsibilty of the ConnectionOverlord
         * to deal with this ctm
         */
          _got_ctms.Add(new_ctm);
	      }
        bool close_queue = _co.HandleCtmResponse(this, rpc_res.ResultSender, new_ctm);
        if( close_queue ) {
          q.Close();
        }
      }
      catch(Exception) {
        //This can happen if the queue is empty and closed.  Don't do
        //anything.
      }
    }
예제 #15
0
 /**
  * @param local the local Node to connect to the remote node
  * @param eh EventHandler to call when we are finished.
  * @param ISender Use this specific edge.  This is used when we want to
  * connecto to a neighbor of a neighbor
  * @param ctm the ConnectToMessage which is serialized in the packet
  */
 public Connector(Node local, ISender ps, ConnectToMessage ctm, ConnectionOverlord co):
   this(local, ps, ctm, co, null)
 {
 }
예제 #16
0
 public void HTRoundTrip(ConnectToMessage ctm) {
   ConnectToMessage ctm2 = new ConnectToMessage( ctm.ToDictionary() );
   Assert.AreEqual(ctm, ctm2, "CTM HT Roundtrip");
 }
예제 #17
0
    public void CTMSerializationTest()
    {
      Address a = new DirectionalAddress(DirectionalAddress.Direction.Left);
      TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://127.0.0.1:5000"); 
      NodeInfo ni = NodeInfo.CreateInstance(a, ta);

      RandomNumberGenerator rng = new RNGCryptoServiceProvider();      
      AHAddress tmp_add = new AHAddress(rng);
      ConnectToMessage ctm1 = new ConnectToMessage(ConnectionType.Unstructured, ni, tmp_add.ToString());
      
      HTRoundTrip(ctm1);

      //Test multiple tas:
      ArrayList tas = new ArrayList();
      tas.Add(ta);
      for(int i = 5001; i < 5010; i++)
        tas.Add(TransportAddressFactory.CreateInstance("brunet.tcp://127.0.0.1:" + i.ToString()));
      NodeInfo ni2 = NodeInfo.CreateInstance(a, tas);

      ConnectToMessage ctm2 = new ConnectToMessage(ConnectionType.Structured, ni2, tmp_add.ToString());
      HTRoundTrip(ctm2);
      //Here is a ConnectTo message with a neighbor list:
      NodeInfo[] neighs = new NodeInfo[5];
      for(int i = 0; i < 5; i++) {
	string ta_tmp = "brunet.tcp://127.0.0.1:" + (i+80).ToString();
        NodeInfo tmp =
		NodeInfo.CreateInstance(new DirectionalAddress(DirectionalAddress.Direction.Left),
	                     TransportAddressFactory.CreateInstance(ta_tmp)
			    );
	neighs[i] = tmp;
      }
      ConnectToMessage ctm3 = new ConnectToMessage("structured", ni, neighs, tmp_add.ToString());
      HTRoundTrip(ctm3);
#if false
      Console.Error.WriteLine( ctm3.ToString() );
      foreach(NodeInfo tni in ctm3a.Neighbors) {
        Console.Error.WriteLine(tni.ToString());
      }
#endif
    }
예제 #18
0
 /**
  * @param local the local Node to connect to the remote node
  * @param eh EventHandler to call when we are finished.
  * @param ISender Use this specific edge.  This is used when we want to
  * connecto to a neighbor of a neighbor
  * @param ctm the ConnectToMessage which is serialized in the packet
  */
 public Connector(Node local, ISender ps, ConnectToMessage ctm, ConnectionOverlord co) :
     this(local, ps, ctm, co, null)
 {
 }