Example #1
0
        /// <summary>Common code to Create an outgoing edge.</summary>
        protected void CreateEdge(TunnelEdgeCallbackAction teca, List <Connection> overlap)
        {
            if (_connections.Contains(teca.TunnelTA.Target))
            {
                FailedEdgeCreate(teca);
                return;
            }

            TunnelEdge te = null;

            while (true)
            {
                te = new TunnelEdge(this, (TunnelTransportAddress)_local_tas[0],
                                    teca.TunnelTA, _iasf.GetForwarderSelector(), overlap);
                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();
            }

            te.CloseEvent += CloseHandler;

            teca.Success.Value   = true;
            teca.Exception.Value = null;
            teca.Edge.Value      = te;

            _node.EnqueueAction(teca);
        }
Example #2
0
        /// <summary>Where data packets prepended with a tunnel come.  Here we
        /// receive data as well as create new TunnelEdges.</summary>
        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);
        }