Пример #1
0
 public ConnectToMessage(string contype, NodeInfo target, string token)
 {
   _ct = contype;
   _target_ni = target;
   _neighbors = new NodeInfo[0]; //Make sure this isn't null
   _token = token;
 }
Пример #2
0
 public ConnectToMessage(string contype, NodeInfo target, NodeInfo[] neighbors, string token)
 {
   _ct = contype;
   _target_ni = target;
   _neighbors = neighbors;
   _token = token;
 }
Пример #3
0
 public LinkMessage(StringDictionary attributes, NodeInfo local, NodeInfo remote, string token)
 {
   _attributes = attributes;
   _local_ni = local;
   _remote_ni = remote;
   _token = token;
 }
Пример #4
0
 /**
  * @param t connection type
  * @param target the Address of the target node
  * @param token unique token used to associate all connection setup messages
  *              with each other
  */
 public ConnectToMessage(ConnectionType t, NodeInfo target, string token)
 {
   _ct = Connection.ConnectionTypeToString(t);
   _target_ni = target;
   _neighbors = new NodeInfo[0]; //Make sure this isn't null
   _token = token;
 }
Пример #5
0
 public LinkMessage(string connection_type, NodeInfo local, NodeInfo remote, string token)
 {
   _attributes = new StringDictionary();
   _attributes["type"] = String.Intern( connection_type );
   _local_ni = local;
   _remote_ni = remote;
   _token = token;
 }
Пример #6
0
 public LinkMessage(ConnectionType t,
                    NodeInfo local,
                    NodeInfo remote,
                    string token)
 {
   _attributes = new StringDictionary();
   _attributes["type"] = Connection.ConnectionTypeToString(t);
   _local_ni = local;
   _remote_ni = remote;
   _token = token;
 }
Пример #7
0
 public ConnectToMessage(IDictionary ht) {
   _ct = (string)ht["type"];
   _target_ni = NodeInfo.CreateInstance((IDictionary)ht["target"]);
   _token = (string) ht["token"];
   IList neighht = ht["neighbors"] as IList;
   if( neighht != null ) {
     _neighbors = new NodeInfo[ neighht.Count ];
     for(int i = 0; i < neighht.Count; i++) {
       _neighbors[i] = NodeInfo.CreateInstance( (IDictionary)neighht[i] );
     }
   }
 }
Пример #8
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
    }
Пример #9
0
        /**
         * This starts a linking operation on the given edge
         */
        public IDictionary Start(IDictionary link_message, ISender edge)
        {
            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -start- sys:link.Start", _node.Address));
            }

            Edge        from = GetEdge(edge);
            LinkMessage lm   = new LinkMessage(link_message);

            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -args- sys:link.Start({1},{2})", _node.Address, lm, from));
            }

            CphState cph = new CphState(from, lm);

            lock ( _sync ) {
                if (!_edge_to_cphstate.ContainsKey(from))
                {
                    _edge_to_cphstate[from] = cph;
                }
                else
                {
                    throw new AdrException((int)ErrorMessage.ErrorCode.InProgress,
                                           "Already have a link in progress on this edge");
                }
            }
            ErrorMessage err = null;

            if (CanConnect(cph, out err))
            {
                try {
                    //If the CloseEvent was already called, this throws an exception
                    from.CloseEvent += this.CloseHandler;
                }
                catch {
                    CloseHandler(from, null);
                    throw new AdrException((int)ErrorMessage.ErrorCode.EdgeClosed,
                                           "Edge Closed after receiving message");
                }
            }
            else
            {
                lock ( _sync ) {
                    _edge_to_cphstate.Remove(from);
                }
            }
            //Now we prepare our response
            LinkMessage lm_resp = null;

            if (err == null)
            {
                //We send a response:
                NodeInfo n_info      = NodeInfo.CreateInstance(_node.Address, from.LocalTA);
                NodeInfo remote_info = NodeInfo.CreateInstance(null, from.RemoteTA);
                lm_resp = new LinkMessage(lm.ConTypeString, n_info, remote_info, _node.Realm, lm.Token);
            }
            else
            {
                if (err.Ec == ErrorMessage.ErrorCode.AlreadyConnected)
                {
                    /**
                     * When we send the ErrorCode.AlreadyConnected,
                     * we could have a stale connection, lets try pinging
                     * the other node, if they are there, but have lost
                     * the Edge, this may trigger the edge to close, causing
                     * us to remove the Connection.
                     * @todo consider putting this address on a "fast track"
                     * to removal if we don't hear from it soon
                     */
                    ConnectionTable tab = _node.ConnectionTable;
                    Connection      c   = tab.GetConnection(lm.ConnectionType,
                                                            lm.Local.Address);
                    if (c != null)
                    {
                        RpcManager rpc = _node.Rpc;
                        rpc.Invoke(c.Edge, null, "sys:link.Ping", String.Empty);
                    }
                }
            }
            if (err != null)
            {
                throw new AdrException((int)err.Ec, err.Message);
            }
            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -end- sys:link.Start()->{1}", _node.Address, lm_resp));
            }
            return(lm_resp.ToDictionary());
        }
Пример #10
0
 public void RoundTripHT(NodeInfo ni) {
   NodeInfo ni_other = NodeInfo.CreateInstance( ni.ToDictionary() );
   Assert.AreEqual(ni, ni_other, "Hashtable roundtrip");
   Assert.AreEqual(ni.GetHashCode(), ni_other.GetHashCode(), "Hashtable GetHashCode roundtrip");
 }
Пример #11
0
 public static NodeInfo CreateInstance(Address a, IList ta) {
   NodeInfo result = null;
   Cache ni_cache = Interlocked.Exchange<Cache>(ref _cache, null);
   if( ni_cache != null ) {
     try {
       //Set up the key:
       _cache_key._done_hash = false;
       _cache_key._address = a;
       _cache_key._tas = ta;
       
       result = (NodeInfo)ni_cache[_cache_key];
       if( result == null ) {
         //This may look weird, but we are using a NodeInfo as a key
         //to lookup NodeInfos, this will allow us to only keep one
         //identical NodeInfo in scope at a time.
         result = new NodeInfo(a, ta);
         ni_cache[result] = result;
       }
     }
     finally {
       Interlocked.Exchange<Cache>(ref _cache, ni_cache);
     }
   }
   else {
     result = new NodeInfo(a, ta);
   }
   return result;
 }
Пример #12
0
 static NodeInfo()
 {
   _cache = new WeakValueTable<int, NodeInfo>();
   _cache_key = new NodeInfo();
   _ta_list = new TransportAddress[1];
 }
Пример #13
0
 protected static NodeInfo CreateInstance(Address a, IList tas, TransportAddress ta) {
   NodeInfo result = null;
   var ni_cache = Interlocked.Exchange<WeakValueTable<int, NodeInfo>>(ref _cache, null);
   if(ni_cache != null) {
     try {
       //Set up the key:
       _cache_key._done_hash = false;
       _cache_key._address = a;
       if(tas == null) {
        if(ta == null) {
           _cache_key._tas = EmptyTas;
         } else {
           _ta_list[0] = ta;
           _cache_key._tas = _ta_list;
         }
       } else {
         _cache_key._tas = tas;
       }
       
       result = ni_cache.GetValue(_cache_key.GetHashCode());
       if( !_cache_key.Equals(result) ) {
         //This may look weird, but we are using a NodeInfo as a key
         //to lookup NodeInfos, this will allow us to only keep one
         //identical NodeInfo in scope at a time.
         if(ta == null) {
           //Note, if ta == null that implies tas is not null
           result = new NodeInfo(a, tas);
         } else {
           result = new NodeInfo(a, ta);
         }
         ni_cache.Replace(result.GetHashCode(), result);
       }
     } finally {
       Interlocked.Exchange<WeakValueTable<int, NodeInfo>>(ref _cache, ni_cache);
     }
   }
   else if(ta == null) {
     //Note, if ta == null that implies tas is not null
     result = new NodeInfo(a, tas);
   } else {
     result = new NodeInfo(a, ta);
   }
   return result;
 }
Пример #14
0
    public static NodeInfo CreateInstance(Address a, TransportAddress ta) {
#if BRUNET_SIMULATOR
        return new NodeInfo(a, ta);
#else
      NodeInfo result = null;
      Cache ni_cache = Interlocked.Exchange<Cache>(ref _cache, null);
      if( ni_cache != null ) {
        //Only one thread at the time can be in here:
        try {
          //Set up the key:
          _cache_key._done_hash = false;
          _cache_key._address = a;
          _ta_list[0] = ta;
          _cache_key._tas = _ta_list;

          result = (NodeInfo)ni_cache[_cache_key];
          if( result == null ) {
            //This may look weird, but we are using a NodeInfo as a key
            //to lookup NodeInfos, this will allow us to only keep one
            //identical NodeInfo in scope at a time.
            result = new NodeInfo(a, ta);
            ni_cache[result] = result;
          }
        }
        finally {
          Interlocked.Exchange<Cache>(ref _cache, ni_cache);
        }
      }
      else {
        result = new NodeInfo(a, ta);
      }
      return result;
#endif
    }
Пример #15
0
        /**
         * This starts a linking operation on the given edge
         */
        public IDictionary Start(IDictionary link_message, ISender edge)
        {
            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -start- sys:link.Start", _node.Address));
            }

            Edge        from = GetEdge(edge);
            LinkMessage lm   = new LinkMessage(link_message);

            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -args- sys:link.Start({1},{2})", _node.Address, lm, from));
            }

            CphState cph = new CphState(from, lm);

            lock ( _sync ) {
                if (!_edge_to_cphstate.ContainsKey(from))
                {
                    _edge_to_cphstate[from] = cph;
                }
                else
                {
                    throw new AdrException((int)ErrorMessage.ErrorCode.InProgress,
                                           "Already have a link in progress on this edge");
                }
            }
            ErrorMessage err = null;

            if (CanConnect(cph, out err))
            {
                try {
                    //If the CloseEvent was already called, this throws an exception
                    from.CloseEvent += this.CloseHandler;
                }
                catch {
                    CloseHandler(from, null);
                    throw new AdrException((int)ErrorMessage.ErrorCode.EdgeClosed,
                                           "Edge Closed after receiving message");
                }
            }
            else
            {
                lock ( _sync ) {
                    _edge_to_cphstate.Remove(from);
                }
            }
            //Now we prepare our response
            LinkMessage lm_resp = null;

            if (err == null)
            {
                //We send a response:
                NodeInfo n_info      = NodeInfo.CreateInstance(_node.Address, from.LocalTA);
                NodeInfo remote_info = NodeInfo.CreateInstance(null, from.RemoteTA);
                lm_resp = new LinkMessage(lm.ConTypeString, n_info, remote_info, _node.Realm, lm.Token);
            }
            else
            {
                throw new AdrException((int)err.Ec, err.Message);
            }
            if (ProtocolLog.LinkDebug.Enabled)
            {
                ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format(
                                      "{0} -end- sys:link.Start()->{1}", _node.Address, lm_resp));
            }
            return(lm_resp.ToDictionary());
        }
Пример #16
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);
 }
Пример #17
0
 public void RoundTrip(NodeInfo ni) {
   NodeInfo ni_other = NodeInfo.CreateInstance(ni.Address, ni.Transports);
   Assert.AreEqual(ni, ni_other, "Hashtable roundtrip");
   Assert.AreEqual(ni.GetHashCode(), ni_other.GetHashCode(), "Hashtable GetHashCode roundtrip");
 }
Пример #18
0
 /**
  * Factory method to reduce memory allocations by caching
  * commonly used NodeInfo objects
  */
 public static NodeInfo CreateInstance(Address a) {
   //Read some of the least significant bytes out,
   //AHAddress all have last bit 0, so we skip the last byte which
   //will have less entropy
   MemBlock mb = a.ToMemBlock();
   ushort idx = (ushort)NumberSerializer.ReadShort(mb, Address.MemSize - 3);
   NodeInfo ni = _mb_cache[idx];
   if( ni != null ) {
     if (a.Equals(ni._address)) {
       return ni;
     }
   }
   ni = new NodeInfo(a);
   _mb_cache[idx] = ni;
   return ni;
 }
 /// We want to include our 4 nearest neighbors
 override protected ConnectToMessage GetConnectToMessage(string ConnectionType,
     string token)
 {
   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++;
   }
   return new ConnectToMessage(ConnectionType, _node.GetNodeInfo(12, TAAuth), near_ni, token);
 }
Пример #20
0
 static NodeInfo()
 {
     _cache     = new WeakValueTable <int, NodeInfo>();
     _cache_key = new NodeInfo();
     _ta_list   = new TransportAddress[1];
 }