public void HandleData(MemBlock data, ISender return_path, object state)
{
AHSender ah_from = return_path as AHSender;
ForwardingSender fs_from = return_path as ForwardingSender;
AHAddress target = null;
if(ah_from == null) {
if(fs_from == null) {
return;
}
target = (AHAddress) fs_from.Destination;
} else {
target = (AHAddress) ah_from.Destination;
}
int remote_id = NumberSerializer.ReadInt(data, 0);
int local_id = NumberSerializer.ReadInt(data, 4);
TunnelEdge te = null;
// No locally assigned ID, so we'll create a new TunnelEdge and assign it one.
// This could be hit many times by the same RemoteID, but it is safe since
// we'll attempt Linkers on all of them and he'll only respond to the first
// one he receives back.
if(local_id == -1) {
if(fs_from == null) {
throw new Exception("No LocalID assigned but not from a useful sender!");
}
ConnectionList cons = _connections;
int index = cons.IndexOf(fs_from.Forwarder);
if(index < 0) {
return;
}
List<Connection> overlap_addrs = new List<Connection>();
overlap_addrs.Add(cons[index]);
while(true) {
te = new TunnelEdge(this, (TunnelTransportAddress) _local_tas[0],
new TunnelTransportAddress(target, overlap_addrs),
_iasf.GetForwarderSelector(), overlap_addrs, remote_id);
lock(_sync) {
if(!_id_to_tunnel.ContainsKey(te.LocalID)) {
_id_to_tunnel[te.LocalID] = te;
break;
}
}
// Arriving here, implies another TunnelEdge will be created and this
// one needs to be closed
te.Close();
}
local_id = te.LocalID;
te.CloseEvent += CloseHandler;
SendEdgeEvent(te);
}
if(!_id_to_tunnel.TryGetValue(local_id, out te)) {
// Maybe we closed this edge
// throw new Exception("No such edge");
// Old behavior would ignore these packets...
return;
} else if(te.RemoteID == -1) {
// We created this, but we haven't received a packet yet
te.RemoteID = remote_id;
} else if(te.RemoteID != remote_id) {
// Either we closed this edge and it was reallocated or something is up!
// throw new Exception("Receiving imposter packet...");
// Old behavior would ignore these packets...
return;
}
if(te.IsClosed) {
throw new Exception("Edge is closed...");
}
// Chop off the Ids
data = data.Slice(8);
te.ReceivedPacketEvent(data);
}