Beispiel #1
0
 /// <summary>Whenever the node receives a new StatusMessage from a tunnel,
 /// we use this to build a consisting of the intersection of our peers
 /// creating a table of potential tunneling options.  We close the edge if
 /// it is empty.</summary>
 protected void UpdateNeighborIntersection(TunnelEdge from, IDictionary msg)
 {
   List<Connection> overlap = _ito.EvaluateOverlap(_connections, msg);
   from.UpdateNeighborIntersection(overlap);
 }
Beispiel #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);
    }
Beispiel #3
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);
    }