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);
}