예제 #1
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:
       */

      Linker l = new Linker(_node, resp.Target.Address,
                            resp.Target.Transports,
                            resp.ConnectionType,
                            _node.Address.ToString());
      _node.TaskQueue.Enqueue( l );
      return true;
    }
예제 #2
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;
   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();
 }
예제 #3
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(8), neigh_array, ctm_req.Token);
 }
    /**
     * 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);
      l.FinishEvent += LinkerEndHandler;
      _node.TaskQueue.Enqueue( l );
      return true;
    }
예제 #5
0
    virtual protected void ConnectTo(Address target, string ConnectionType) {
      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;
      };
      if (abort(null)) {
        return;
      }

      ConnectToMessage  ctm = new ConnectToMessage(ConnectionType, _node.GetNodeInfo(8),
          _node.Address.ToString());
      ISender send = new AHSender(_node, target, AHPacket.AHOptions.Exact);
      Connector con = new Connector(_node, send, ctm, this);
      con.FinishEvent += ConnectorEndHandler;
      con.AbortIf = abort;
      _node.TaskQueue.Enqueue(con);
    }
 /**
  * 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;
 }
예제 #7
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.
      }
    }
예제 #8
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;
 }
예제 #9
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)
 {
 }
예제 #10
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
    }
예제 #11
0
 public void HTRoundTrip(ConnectToMessage ctm) {
   ConnectToMessage ctm2 = new ConnectToMessage( ctm.ToDictionary() );
   Assert.AreEqual(ctm, ctm2, "CTM HT Roundtrip");
 }
예제 #12
0
    /**
     * Initiates connection setup. 
     * @param sender the ISender for the Connector to use
     * @param contype the type of connection we want to make
     * @param token the token used for connection messages
     * @param responses the maximum number of ctm response messages to listen
     */
    protected void ConnectTo(ISender sender, string contype, string token, int responses)
    {
      ConnectionType mt = Connection.StringToMainType(contype);
      /*
       * 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
       */
      Connector.AbortCheck abort = null;
      ForwardingSender fs = sender as ForwardingSender;
      if( fs != null ) {
        //In general, we only know the exact node we are trying
        //to reach when we are using a ForwardingSender
        Address target = fs.Destination;
        Linker l = new Linker(_node, target, null, contype, token);
        object linker_task = l.Task;  //This is what we check for
        abort = delegate(Connector c) {
          bool 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( linker_task );
          }
          return stop;
        };
        if ( abort(null) ) {
          return;
        }
      }
      //Send the 4 neighbors closest to this node:
      ArrayList nearest = _node.ConnectionTable.GetNearestTo( (AHAddress)_node.Address, 4);
      NodeInfo[] near_ni = new NodeInfo[nearest.Count];
      int i = 0;
      foreach(Connection cons in nearest) {
        //We don't use the TAs, just the addresses
        near_ni[i] = NodeInfo.CreateInstance(cons.Address);
        i++;
      }
      ConnectToMessage ctm = new ConnectToMessage(contype, _node.GetNodeInfo(8), near_ni, token);

      Connector con = new Connector(_node, sender, ctm, this);
      con.AbortIf = abort;
      //Keep a reference to it does not go out of scope
      lock( _sync ) {
        _connectors[con] = responses;
      }
      con.FinishEvent += new EventHandler(this.ConnectorEndHandler);
      //Start up this Task:
      _node.TaskQueue.Enqueue(con);
    }
예제 #13
0
 /**
  * When we get ConnectToMessage responses the connector tells us.
  */
 override public bool HandleCtmResponse(Connector c, ISender ret_path,
                                        ConnectToMessage ctm_resp)
 {
   /**
    * Time to start linking:
    */
   
   Linker l = new Linker(_node, ctm_resp.Target.Address,
                         ctm_resp.Target.Transports,
                         ctm_resp.ConnectionType,
                         ctm_resp.Token);
   _node.TaskQueue.Enqueue( l );
   /**
    * Check this guys neighbors:
    */
   /* POB: I don't think this is needed because we also do the 
    * same thing in the ConnectorEndHandler, so why do this twice?
    * In fact, it seems better to wait for all the responses before
    * looking for the closest one
    *
    * commenting this out:
    *
   ConnectionList structs =
       _node.ConnectionTable.GetConnections(ConnectionType.Structured);
   ConnectToNearer(structs, ctm_resp.Target.Address, ctm_resp.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;
 }