/** * This creates Edges of a given type */ public void CreateEdgeTo(TransportAddress destination, EdgeListener.EdgeCreationCallback ecb) { TransportAddress.TAType t = destination.TransportAddressType; if( _el_map.Contains( t ) ) { EdgeListener el = (EdgeListener)_el_map[ t ]; el.CreateEdgeTo( destination, ecb ); } else { ecb(false, null, new EdgeException("No EdgeListener for TA type: " + t.ToString() ) ); } }
/** * It is imperative that the ECB be called and not ignored. Not * calling back will leave the system in a stale state as it waits * for the CreateEdgeTo to complete. * @param ta TransportAddress to create an edge to * @param ecb the EdgeCreationCallback to call when done * @throw EdgeException if we try to call this before calling */ public abstract void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb);
/** * At the end of the day, we will often allow as long as * an address is not denied (@see SeriesTAAuthorizer), * so this makes it a little easier for us to check */ public bool IsNotDenied(TransportAddress a) { return (Authorize(a) != Decision.Deny); }
public override TAAuthorizer.Decision Authorize(TransportAddress a) { IPAddress ipa = null; try { ipa = (IPAddress)( ((IPTransportAddress) a).GetIPAddress() ); } catch (Exception x) { ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format( "{0}", x)); } if (ipa == null) { return _result_on_mismatch; } byte[] add_bytes = ipa.GetAddressBytes(); int bits = _bit_c; int block = 0; bool match = true; while( bits > 0 && match ) { match = FirstBitsMatch( add_bytes[block], _nw_bytes[block], bits); bits -= 8; block++; } if( match ) { return _result_on_match; } else { return _result_on_mismatch; } }
public override TAAuthorizer.Decision Authorize(TransportAddress a) { if (_denied_port == ((IPTransportAddress) a).Port) { return TAAuthorizer.Decision.Deny; } else { //else this decision should not matter return TAAuthorizer.Decision.None; } }
public LinkProtocolState(Linker l, TransportAddress ta, Edge e) { _linker = l; _node = l.LocalNode; _contype = l.ConType; _target_lock = null; _lm_reply = new WriteOnce<LinkMessage>(); _x = new WriteOnce<Exception>(); _con = new WriteOnce<Connection>(); _ta = ta; _is_finished = 0; //Setup the edge: _e = e; _result = Result.None; }
/** * Given a TransportAddress, return the associated RestartState. * If there are no more restarts, this returns null. */ protected RestartState GetRestartState(TransportAddress ta) { RestartState rss = null; lock( _ta_to_restart_state ) { rss = (RestartState)_ta_to_restart_state[ta]; if( rss == null ) { //This is the first time we are restarting rss = new RestartState(this, ta); } else if (rss.RemainingAttempts > 0) { //We have to decrement the remainingAttempts: int ra = rss.RemainingAttempts - 1; rss = new RestartState(this, ta, ra); } else { /* * The old TA has had it */ rss = null; } } if( rss != null ) { _ta_to_restart_state[rss.TA] = rss; rss.FinishEvent += this.RestartHandler; #if LINK_DEBUG if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Linker({1}) restarting; remaining attempts: {2}", _local_n.Address, _lid, rss.RemainingAttempts)); } #endif } return rss; }
public RestartState(Linker l, TransportAddress ta, int remaining_attempts) { _linker = l; _ta = ta; _restart_attempts = remaining_attempts; _first_start = 1; }
/** * When a new Connection is added, we may need to update the list * of TAs to make sure it is not too long, and that the it is sorted * from most likely to least likely to be successful * @param e the new Edge * @param ta the TransportAddress our TA according to our peer */ public override void UpdateLocalTAs(Edge e, TransportAddress ta) { if( e.TAType == this.TAType ) { UdpEdge ue = (UdpEdge)e; ue.PeerViewOfLocalTA = ta; NatDataPoint dp = new LocalMappingChangePoint(DateTime.UtcNow, e, ta); Interlocked.Exchange<NatHistory>(ref _nat_hist, _nat_hist + dp); Interlocked.Exchange<IEnumerable>(ref _nat_tas, new NatTAs( _tas, _nat_hist )); } }
/* * Implements the EdgeListener function to * create edges of this type. */ public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) { if( !IsStarted ) { // it should return null and not throw an exception // for graceful disconnect and preventing others to // connect to us after we've disconnected. ecb(false, null, new EdgeException("Not started")); return; } if( ta.TransportAddressType != this.TAType ) { //Can't make an edge of this type ecb(false, null, new EdgeException("Can't make edge of this type")); return; } if( _ta_auth.Authorize(ta) == TAAuthorizer.Decision.Deny ) { //Not authorized. Can't make this edge: ecb(false, null, new EdgeException( ta.ToString() + " is not authorized") ); return; } int remote_id = ((SimulationTransportAddress) ta).ID; //Get the edgelistener: //Outbound edge: int delay = 0; if(_use_delay) { if(LatencyMap != null) { // id != 0, so we reduce all by 1 delay = LatencyMap[_listener_id][remote_id] / 1000; } else { lock(_sync) { delay = _rand.Next(10, 250); } } } SimulationEdge se_l = new SimulationEdge(this, _listener_id, remote_id, false, delay); AddEdge(se_l); SimulationEdgeListener remote = (SimulationEdgeListener) _listener_map[remote_id]; if( remote != null ) { // // Make sure that the remote listener does not deny // our TAs. // foreach (TransportAddress ta_local in LocalTAs) { if (remote.TAAuth.Authorize(ta_local) == TAAuthorizer.Decision.Deny ) { //Not authorized. Can't make this edge: ecb(false, null, new EdgeException( ta_local.ToString() + " is not authorized by remote node.") ); return; } } SimulationEdge se_r = new SimulationEdge(remote, remote_id, _listener_id, true, delay); remote.AddEdge(se_r); se_l.Partner = se_r; se_r.Partner = se_l; remote.SendEdgeEvent(se_r); } else { //There is no other edge, for now, we use "udp-like" //behavior of just making an edge that goes nowhere. } ecb(true, se_l, null); }
/** * We will often create NodeInfo objects with only one * TransportAddress. This constructor makes that easy. */ protected NodeInfo(Address a, TransportAddress ta) { _address = a; _tas = new TransportAddress[]{ ta }; }
public static NodeInfo CreateInstance(IDictionary d) { Address address = null; IList tas; object addr_str = d["address"]; if( addr_str != null ) { address = AddressParser.Parse((string)addr_str); } IList trans = d["transports"] as IList; if( trans != null ) { int count = trans.Count; tas = new TransportAddress[count]; for(int i = 0; i < count; i++) { tas[i] = TransportAddressFactory.CreateInstance((string)trans[i]); } NodeInfo ni = CreateInstance(address, tas); return ni; } else { NodeInfo ni = CreateInstance(address); return ni; } }
public static NodeInfo CreateInstance(Address a, TransportAddress ta) { 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; }
public FakeEdge(TransportAddress local, TransportAddress remote, TransportAddress.TAType tatype) { _tatype = tatype; local_add = local; remote_add = remote; }
public FakeEdge(TransportAddress local, TransportAddress remote) : this(local, remote, TransportAddress.TAType.Tcp) { }
public override TAAuthorizer.Decision Authorize(TransportAddress a) { int port = ((IPTransportAddress) a).Port; lock(_sync) { if(!_allowed.Contains(port)) { if(_rand.NextDouble() > _prob) { _allowed[port] = TAAuthorizer.Decision.Allow; } else { _allowed[port] = TAAuthorizer.Decision.Deny; } } } return (TAAuthorizer.Decision) _allowed[port]; }
public EdgeWorker(Node n, TransportAddress ta) { _n = n; _ta = ta; _result = new WriteOnce<EWResult>(); }
/** * Implements the EdgeListener function to * create edges of this type. */ public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) { Edge e = null; try { if( !IsStarted ) { throw new EdgeException("UdpEdgeListener is not started"); } else if( ta.TransportAddressType != this.TAType ) { throw new EdgeException(ta.TransportAddressType.ToString() + " is not my type: " + this.TAType.ToString() ); } else if( _ta_auth.Authorize(ta) == TAAuthorizer.Decision.Deny ) { //Too bad. Can't make this edge: throw new EdgeException( ta.ToString() + " is not authorized"); } else { IPAddress first_ip = ((IPTransportAddress) ta).GetIPAddress(); IPEndPoint end = new IPEndPoint(first_ip, ((IPTransportAddress) ta).Port); /* We have to keep our mapping of end point to edges up to date */ lock( _id_ht ) { //Get a random ID for this edge: int id; do { id = _rand.Next(); //Make sure we don't have negative ids if( id < 0 ) { id = ~id; } } while( _id_ht.Contains(id) || id == 0 ); e = new UdpEdge(this, false, end, _local_ep, id, 0); _id_ht[id] = e; } NatDataPoint dp = new NewEdgePoint(DateTime.UtcNow, e); Interlocked.Exchange<NatHistory>(ref _nat_hist, _nat_hist + dp); Interlocked.Exchange<IEnumerable>(ref _nat_tas, new NatTAs( _tas, _nat_hist )); /* Tell me when you close so I can clean up the table */ e.CloseEvent += this.CloseHandler; ecb(true, e, null); } } catch(Exception ex) { if( e != null ) { //Clean up the edge CloseHandler(e, null); } ecb(false, null, ex); } }
public RestartState(Linker l, TransportAddress ta) : this(l, ta, _MAX_RESTARTS) { }
/* ////////////////////////////// * * Here are all the normal methods of TcpEdgeListener * * ////////////////////////////// */ public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) { try { if( !IsStarted ) { throw new EdgeException("TcpEdgeListener is not started"); } else if( ta.TransportAddressType != TransportAddress.TAType.Tcp ) { throw new EdgeException(ta.TransportAddressType.ToString() + " is not my type: Tcp"); } else if( _ta_auth.Authorize(ta) == TAAuthorizer.Decision.Deny ) { //Too bad. Can't make this edge: throw new EdgeException( ta.ToString() + " is not authorized"); } else { //Everything looks good: ArrayList tmp_ips = new ArrayList(); tmp_ips.Add(((IPTransportAddress)ta).GetIPAddress()); CreationState cs = new CreationState(ecb, new Queue( tmp_ips ), ((IPTransportAddress) ta).Port, this); ActionQueue.Enqueue(cs); } } catch(Exception e) { ecb(false, null, e); } }
/** * This creates a TaskWorker that represents the next step that should * be taken for the ta. It can only be two tasks: create the edge * (EdgeWorker) or wait and try again (RestartState). * * We return null if: * - the TA is null * - Linker is finished * - a Connection was already created * - this TA has been restarted too many times * * If we cannot get a ConnectionTable.Lock with SetTarget, we return a * RestartState to wait a little while to try to get the lock again. * * @returns the next TaskWorker that should be enqueued, does not start or * Enqueue it. */ protected TaskWorker StartAttempt(TransportAddress next_ta) { TaskWorker next_task = null; if ( (next_ta == null) || (_added_cons != 0) || IsFinished || ConnectionInTable ) { //Looks like we are already connected... return null; } try { #if LINK_DEBUG if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Linker ({1}) attempting to lock {2}", _local_n.Address, _lid, _target)); } #endif /* * If we cannot set this address as our target, we * stop before we even try to make an edge. * * Locks flow around in complex ways, but we * (or one of our LinkProtocolState) * will hold the lock */ SetTarget(); #if LINK_DEBUG if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Linker ({1}) acquired lock on {2}", _local_n.Address, _lid, _target)); ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Linker: ({1}) Trying TA: {2}", _local_n.Address, _lid, next_ta)); } #endif next_task = new EdgeWorker(_local_n, next_ta); next_task.FinishEvent += this.EdgeWorkerHandler; } catch(CTLockException) { /* * If we cannot get a lock on the address in SetTarget() * we wait and and try again */ #if LINK_DEBUG if (ProtocolLog.LinkDebug.Enabled) { ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Linker ({1}) failed to lock {2}", _local_n.Address, _lid, _target)); } #endif next_task = GetRestartState(next_ta); } catch(ConnectionExistsException) { //We already have a connection to the target } catch(Exception) { } return next_task; }
public override TAAuthorizer.Decision Authorize(TransportAddress a) { if (_denied_id == ((SimulationTransportAddress)a).ID) { return TAAuthorizer.Decision.Deny; } else { //else this decision should not matter return TAAuthorizer.Decision.None; } }
/** * Go through the list of Authorizers returning the first decision */ public override TAAuthorizer.Decision Authorize(TransportAddress a) { TAAuthorizer.Decision result = TAAuthorizer.Decision.None; foreach(TAAuthorizer ipa in _authorizers) { result = ipa.Authorize(a); if( result != TAAuthorizer.Decision.None ) { break; } } return result; }
public TATypeAuthorizer(TransportAddress.TAType[] list, TAAuthorizer.Decision on_match, TAAuthorizer.Decision on_mismatch) { _on_match = on_match; _on_mismatch = on_mismatch; _match_table = new Dictionary<TransportAddress.TAType, bool>(); foreach(TransportAddress.TAType tatype in list) { _match_table[tatype] = true; } }
public override TAAuthorizer.Decision Authorize(TransportAddress a) { if (_deny_list.Contains(a)) { return TAAuthorizer.Decision.Deny; } // randomly deny the TA if (_rand.NextDouble() > _deny_prob) { _deny_list.Add(a); return TAAuthorizer.Decision.Deny; } return TAAuthorizer.Decision.Allow; }
public override TAAuthorizer.Decision Authorize(TransportAddress a) { if(_match_table.ContainsKey(a.TransportAddressType)) { return _on_match; } return _on_mismatch; }
/** * @return the Decision for this TransportAddress */ public virtual Decision Authorize(TransportAddress a) { return Decision.None; }
/* * Implements the EdgeListener function to * create edges of this type. */ public override void CreateEdgeTo(TransportAddress ta, EdgeCreationCallback ecb) { if( !IsStarted ) { // it should return null and not throw an exception // for graceful disconnect and preventing others to // connect to us after we've disconnected. ecb(false, null, new EdgeException("Not started")); return; } #if FUNCTION_DEBUG foreach (TransportAddress local_ta in LocalTAs) { Console.Error.WriteLine("Create edge local: {0} <-> remote {1}.", local_ta, ta); } #endif if( ta.TransportAddressType != this.TAType ) { //Can't make an edge of this type #if FUNCTION_DEBUG Console.Error.WriteLine("Can't make edge of this type."); #endif ecb(false, null, new EdgeException("Can't make edge of this type")); return; } if( _ta_auth.Authorize(ta) == TAAuthorizer.Decision.Deny ) { //Not authorized. Can't make this edge: #if FUNCTION_DEBUG Console.Error.WriteLine("Can't make edge. Remote TA {0} is not authorized locally.", ta); #endif ecb(false, null, new EdgeException( ta.ToString() + " is not authorized") ); return; } int remote_id = ((IPTransportAddress) ta).Port; //Get the edgelistener: //Outbound edge: FunctionEdge fe_l = new FunctionEdge(this, _listener_id, remote_id, false); lock( _listener_map ) { FunctionEdgeListener remote = (FunctionEdgeListener) _listener_map[remote_id]; if( remote != null ) { // // Make sure that the remote listener does not deny // our TAs. // foreach (TransportAddress ta_local in LocalTAs) { if (remote.TAAuth.Authorize(ta_local) == TAAuthorizer.Decision.Deny ) { //Not authorized. Can't make this edge: #if FUNCTION_DEBUG Console.Error.WriteLine("Can't make edge. local TA {0} is not authorized remotely by {1}.", ta_local, ta); #endif ecb(false, null, new EdgeException( ta_local.ToString() + " is not authorized by remote node.") ); return; } } FunctionEdge fe_r = new FunctionEdge(remote, remote_id, _listener_id, true); fe_l.Partner = fe_r; fe_r.Partner = fe_l; remote.SendEdgeEvent(fe_r); } else { //There is no other edge, for now, we use "udp-like" //behavior of just making an edge that goes nowhere. } ecb(true, fe_l, null); } }
public override TAAuthorizer.Decision Authorize(TransportAddress a) { return _dec; }
public RestartState(Linker l, TransportAddress ta, int remaining_attempts) { _linker = l; _ta = ta; _restart_attempts = remaining_attempts; //Compute the interval: Random rand = new Random(); int restart_sec = rand.Next(_MS_RESTART_TIME); _interval = new TimeSpan(0,0,0,0,restart_sec); }