/** * 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. } }
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); } }
/** * 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); }
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; }
/** * 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(); }
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 }
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); }
/** * 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()); }
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)); }
/** * 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); }
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; }
public void HTRoundTrip(ConnectToMessage ctm) { ConnectToMessage ctm2 = new ConnectToMessage(ctm.ToDictionary()); Assert.AreEqual(ctm, ctm2, "CTM HT Roundtrip"); }
/** * 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. } }
/** * @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) { }
public void HTRoundTrip(ConnectToMessage ctm) { ConnectToMessage ctm2 = new ConnectToMessage( ctm.ToDictionary() ); Assert.AreEqual(ctm, ctm2, "CTM HT Roundtrip"); }
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 }
/** * @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) { }