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