/// Simulator != thread-safe! protected static Address SimulatorCache(Address a) { int idx = NumberSerializer.ReadInt(a.ToMemBlock(), 0); Address tmp = _cache.GetValue(idx); if(a.Equals(tmp)) { return tmp; } _cache.Replace(idx, a); return a; }
/// <summary>Is the right person sending me this packet?</summary> /// <param name="ip">The IP source.</param> /// <param name="addr">The Brunet.Address source.</summary> public bool Check(MemBlock ip, Address addr) { // Check current results Address stored_addr = null; bool update; bool exists = _cache.TryGetValue(ip, out stored_addr, out update); if(addr.Equals(stored_addr)) { if(update) { Miss(ip); } return true; } else if(!exists) { Miss(ip); return false; } else { // Bad mapping throw new AddressResolutionException(String.Format( "IP:Address mismatch, expected: {0}, got: {1}", addr, stored_addr), AddressResolutionException.Issues.Mismatch); } }
/// <summary>Is the right person sending me this packet?</summary> /// <param name="ip">The IP source.</param> /// <param name="addr">The Brunet.Address source.</summary> public bool Check(MemBlock ip, Address addr) { // Check current results Address stored_addr = null; lock(_sync) { _results.TryGetValue(ip, out stored_addr); } if(addr.Equals(stored_addr)) { // Match! return true; } else if(stored_addr == null) { // No entry, check previous contents lock(_sync) { _last_results.TryGetValue(ip, out stored_addr); } if(Miss(ip)) { IncrementMisses(ip); } return addr.Equals(stored_addr); } else { // Bad mapping Miss(ip); throw new AddressResolutionException(String.Format( "IP:Address mismatch, expected: {0}, got: {1}", addr, stored_addr), AddressResolutionException.Issues.Mismatch); } }
/// <summary>Is the right person sending me this packet?</summary> /// <param name="ip">The IP source.</param> /// <param name="addr">The Brunet.Address source.</summary> public bool Check(MemBlock ip, Address addr) { Address stored_addr = Resolve(ip); if(stored_addr != null) { if(addr.Equals(stored_addr)) { return true; } else{ throw new AddressResolutionException(String.Format( "IP:Address mismatch, expected: {0}, got: {1}", addr, stored_addr), AddressResolutionException.Issues.Mismatch); } } // No mapping, so use the given mapping _incoming_cache.Update(ip, addr); return true; }
/** * Note that a LinkProtocolState only gets a lock *AFTER* it has * received a LinkMessageReply. Prior to that, the Linker that * created it holds the lock (if the _linker.Target is not null). * * So, given that we are being asked to transfer a lock, we must * have already gotten our LinkMessageReply set, or we wouldn't * hold the lock in the first place. * * So, we only transfer locks to other Linkers when we are finished * since us holding a lock means we have already head some * communication from the other side. * * Since the CT.Lock and CT.Unlock methods can't be called when this * is being called, we know that _target_lock won't change during * this method. */ public bool AllowLockTransfer(Address a, string contype, ILinkLocker l) { bool hold_lock = (a.Equals( _target_lock ) && contype == _contype); if( false == hold_lock ) { //This is a bug. throw new Exception(String.Format("We don't hold the lock: {0}", a)); } if( (l is Linker) && IsFinished ) { return true; } return false; }
/** * Allow if we are transfering to a LinkProtocolState or ConnectionPacketHandler * Note this method does not change anything, if the transfer is done, it * is done by the ConnectionTable while it holds its lock. */ public bool AllowLockTransfer(Address a, string contype, ILinkLocker l) { bool allow = false; bool hold_lock = (a.Equals( _target_lock ) && contype == _contype); if( false == hold_lock ) { //We don't even hold this lock! throw new Exception( String.Format("{2} asked to transfer a lock({0}) we don't hold: ({1})", a, _target_lock, this)); } if( l is Linker ) { //Never transfer to another linker: } else if ( l is ConnectionPacketHandler.CphState ) { /** * The ConnectionPacketHandler only locks when it * has actually received a packet. This is a "bird in the * hand" situation, however, if both sides in the double * link case transfer the lock, then we have accomplished * nothing. * * There is a specific case to worry about: the case of * a firewall, where only one node can contact the other. * In this case, it may be very difficult to connect if * we don't eventually transfer the lock to the * ConnectionPacketHandler. In the case of bi-directional * connectivity, we only transfer the lock if the * address we are locking is greater than our own (which * clearly cannot be true for both sides). * * To handle the firewall case, we keep count of how * many times we have been asked to transfer the lock. On * the third time we are asked, we assume we are in the firewall * case and we allow the transfer, this is just a hueristic. */ int reqs = Interlocked.Increment(ref _cph_transfer_requests); if ( (reqs >= 3 ) || ( a.CompareTo( LocalNode.Address ) > 0) ) { allow = true; } } else if( l is LinkProtocolState ) { LinkProtocolState lps = (LinkProtocolState)l; /** * Or Transfer the lock to a LinkProtocolState if: * 1) We created this LinkProtocolState * 2) The LinkProtocolState has received a packet */ if( (lps.Linker == this ) && ( lps.LinkMessageReply != null ) ) { allow = true; } } #if LINK_DEBUG if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Linker({1}) {2}: transfering lock on {3} to {4}", _local_n.Address, _lid, (_target_lock == null), a, l)); } #endif return allow; }
/// <summary>Is the right person sending me this packet?</summary> /// <param name="ip">The IP source.</param> /// <param name="addr">The Brunet.Address source.</summary> public bool Check(MemBlock ip, Address addr) { Address stored_addr = _results[ip] as Address; if(addr.Equals(stored_addr)) { return true; } else if(stored_addr == null) { if(Miss(ip)) { IncrementMisses(ip); } return false; } else { Miss(ip); throw new AddressResolutionException(String.Format("IP:Address mismatch, expected: {0}, got: {1}", addr, stored_addr), AddressResolutionException.Issues.Mismatch); } }
/** * Callback function that is invoked when TargetSelector fetches candidate scores in a range. * Initiates connection setup. * Node: All connection messages can be tagged with a token string. This token string is currenly being * used to keep the following information about a shortcut: * 1. The node who initiated the shortcut setup. * 2. The random target near which shortcut was chosen. * @param start address pointing to the start of range to query. * @param score_table list of candidate addresses sorted by score. * @param current currently selected optimal (nullable) */ protected void CreateShortcutCallback(Address start, SortedList score_table, Address current) { if (score_table.Count > 0) { /** * we remember our address and the start of range inside the token. * token is the concatenation of * (a) local node address * (b) random target for the range queried by target selector */ string token = _node.Address + start.ToString(); //connect to the min_target Address min_target = (Address) score_table.GetByIndex(0); ISender send = null; if (start.Equals(min_target)) { //looks like the target selector simply returned our random address if (LogEnabled) { ProtocolLog.Write(ProtocolLog.SCO, String.Format("SCO local: {0}, Connecting (shortcut) to min_target: {1} (greedy), random_target: {2}.", _node.Address, min_target, start)); } //use a greedy sender send = new AHGreedySender(_node, min_target); } else { if (LogEnabled) { ProtocolLog.Write(ProtocolLog.SCO, String.Format("SCO local: {0}, Connecting (shortcut) to min_target: {1} (exact), random_target: {2}.", _node.Address, min_target, start)); } //use exact sender send = new AHExactSender(_node, min_target); } ConnectTo(send, min_target, STRUC_SHORT, token); } }
/** * 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; }
/// <summary>Is the right person sending me this packet?</summary> /// <param name="ip">The IP source.</param> /// <param name="addr">The Brunet.Address source.</summary> public bool Check(MemBlock ip, Address addr) { if(addr.Equals(_results[ip])) { return true; } Miss(ip); return false; }