Пример #1
0
        /// <summary>Common code to Create an outgoing edge.</summary>
        protected void CreateEdge(RelayEdgeCallbackAction teca, List <Connection> overlap)
        {
            if (_connections.Contains(teca.RelayTA.Target))
            {
                FailedEdgeCreate(teca);
                return;
            }

            RelayEdge te = null;

            while (true)
            {
                te = new RelayEdge(this, (RelayTransportAddress)_local_tas[0],
                                   teca.RelayTA, _iasf.GetForwarderSelector(), overlap);
                lock (_sync) {
                    if (!_id_to_tunnel.ContainsKey(te.LocalID))
                    {
                        _id_to_tunnel[te.LocalID] = te;
                        break;
                    }
                }
                // Arriving here, implies another RelayEdge 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);
        }
Пример #2
0
        public void HandleRpc(ISender caller, string method, IList args, object rs)
        {
            if (method.Equals("Sync"))
            {
                RelayEdge te = (caller as ReqrepManager.ReplyState).ReturnPath as RelayEdge;
                if (te == null)
                {
                    throw new Exception(String.Format(
                                            "{0} must be called from a RelayEdge.", method));
                }

                IDictionary dict = args[0] as IDictionary;
                if (dict == null)
                {
                    throw new Exception(method + "\'s parameter is an IDictionary!");
                }

                UpdateNeighborIntersection(te, dict);
                _node.Rpc.SendResult(rs, true);
            }
            else if (method.Equals("RequestSync"))
            {
                _node.Rpc.SendResult(rs, _ito.GetSyncMessage(null, _node.Address, _connections));
            }
            else
            {
                throw new Exception(String.Format("No such method: {0}.", method));
            }
        }
Пример #3
0
        /// <summary>When a RelayEdge closes, we must remove it from our
        /// hashtable.</summary>
        protected void CloseHandler(object o, EventArgs ea)
        {
            RelayEdge te = o as RelayEdge;

            lock (_sync) {
                _id_to_tunnel.Remove(te.LocalID);
            }
        }
Пример #4
0
        public void WrapperEdgeRegressionTest()
        {
            AHAddress        addr  = new AHAddress(new System.Security.Cryptography.RNGCryptoServiceProvider());
            TransportAddress ta    = TransportAddressFactory.CreateInstance("brunet.tcp://169.0.5.1:5000");
            FakeEdge         fe    = new FakeEdge(ta, ta);
            WrapperEdge      we_fe = new WrapperEdge(fe);
            Connection       fcon  = new Connection(we_fe, addr, "structured", null, null);

            List <Connection> overlap = new List <Connection>();

            overlap.Add(fcon);
            RelayTransportAddress tta    = new RelayTransportAddress(addr, overlap);
            RelayEdge             te1    = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
            WrapperEdge           we_te1 = new WrapperEdge(te1);
            Connection            t1con  = new Connection(we_te1, addr, "structured", null, null);

            overlap = new List <Connection>();
            overlap.Add(t1con);
            RelayEdge   te2    = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
            WrapperEdge we_te2 = new WrapperEdge(te2);
            Connection  t2con  = new Connection(we_te2, addr, "structured", null, null);

            overlap = new List <Connection>();
            overlap.Add(t2con);
            RelayEdge   te3    = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
            WrapperEdge we_te3 = new WrapperEdge(te3);
            Connection  t3con  = new Connection(we_te3, addr, "structured", null, null);

            overlap = new List <Connection>();
            overlap.Add(t3con);
            RelayEdge   te4    = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
            WrapperEdge we_te4 = new WrapperEdge(te4);
            Connection  t4con  = new Connection(we_te4, addr, "structured", null, null);

            overlap = new List <Connection>();
            overlap.Add(t4con);
            RelayEdge   te5    = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
            WrapperEdge we_te5 = new WrapperEdge(te5);
            Connection  t5con  = new Connection(we_te5, addr, "structured", null, null);

            Assert.AreEqual(te5.ShouldClose(), false, "Shouldn't close yet...");
            te1.DisconnectionHandler(fcon);
            Assert.AreEqual(te5.ShouldClose(), true, "Should close...");

            overlap.Add(t5con);
            overlap.Add(t3con);
            overlap.Add(t1con);
            te2.UpdateNeighborIntersection(overlap);
            Assert.AreEqual(te5.ShouldClose(), true, "Should close... 2");
        }
Пример #5
0
        /// <summary>Used to send data over the tunnel via forwarding senders
        /// using a randomly selected peer from our overlap list.</summary>
        public void HandleEdgeSend(Edge from, ICopyable data)
        {
            RelayEdge  te        = from as RelayEdge;
            Connection forwarder = te.NextForwarder;

            if (te.RemoteID == -1)
            {
                Address target = (te.RemoteTA as RelayTransportAddress).Target;
                ISender sender = new ForwardingSender(_node, forwarder.Address, target);
                sender.Send(new CopyList(PType.Protocol.Relaying, te.MId, data));
            }
            else
            {
                try {
                    forwarder.Edge.Send(new CopyList(te.Header, te.MId, data));
                } catch {
                    // We could be sending aon a closed edge... we could deal with this
                    // better, but let's just let the system take its natural course.
                }
            }
        }
Пример #6
0
        protected bool ShouldClose()
        {
#endif
            Dictionary <Edge, bool> have_passed = new Dictionary <Edge, bool>();
            Stack stack = new Stack();
            stack.Push(_tunnels.GetEnumerator());
            while (stack.Count > 0)
            {
                IEnumerator <Connection> cons = stack.Pop() as IEnumerator <Connection>;
                while (cons.MoveNext())
                {
                    RelayEdge re = cons.Current.Edge as RelayEdge;
                    if (re == null)
                    {
                        var we = cons.Current.Edge as WrapperEdge;
                        if (we != null)
                        {
                            re = we.WrappedEdge as RelayEdge;
                        }
                        if (re == null)
                        {
                            return(false);
                        }
                    }

                    if (have_passed.ContainsKey(re))
                    {
                        continue;
                    }
                    have_passed[re] = true;
                    stack.Push(cons);
                    cons = re.Overlap.GetEnumerator();
                }
            }
            return(true);
        }
Пример #7
0
    public void WrapperEdgeRegressionTest()
    {
      AHAddress addr = new AHAddress(new System.Security.Cryptography.RNGCryptoServiceProvider());
      TransportAddress ta = TransportAddressFactory.CreateInstance("brunet.tcp://169.0.5.1:5000");
      FakeEdge fe = new FakeEdge(ta, ta);
      WrapperEdge we_fe = new WrapperEdge(fe);
      Connection fcon = new Connection(we_fe, addr, "structured", null, null);

      List<Connection> overlap = new List<Connection>();
      overlap.Add(fcon);
      RelayTransportAddress tta = new RelayTransportAddress(addr, overlap);
      RelayEdge te1 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
      WrapperEdge we_te1 = new WrapperEdge(te1);
      Connection t1con = new Connection(we_te1, addr, "structured", null, null);

      overlap = new List<Connection>();
      overlap.Add(t1con);
      RelayEdge te2 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
      WrapperEdge we_te2 = new WrapperEdge(te2);
      Connection t2con = new Connection(we_te2, addr, "structured", null, null);

      overlap = new List<Connection>();
      overlap.Add(t2con);
      RelayEdge te3 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
      WrapperEdge we_te3 = new WrapperEdge(te3);
      Connection t3con = new Connection(we_te3, addr, "structured", null, null);

      overlap = new List<Connection>();
      overlap.Add(t3con);
      RelayEdge te4 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
      WrapperEdge we_te4 = new WrapperEdge(te4);
      Connection t4con = new Connection(we_te4, addr, "structured", null, null);

      overlap = new List<Connection>();
      overlap.Add(t4con);
      RelayEdge te5 = new RelayEdge(null, tta, tta, new SimpleForwarderSelector(), overlap);
      WrapperEdge we_te5 = new WrapperEdge(te5);
      Connection t5con = new Connection(we_te5, addr, "structured", null, null);

      Assert.AreEqual(te5.ShouldClose(), false, "Shouldn't close yet...");
      te1.DisconnectionHandler(fcon);
      Assert.AreEqual(te5.ShouldClose(), true, "Should close...");

      overlap.Add(t5con);
      overlap.Add(t3con);
      overlap.Add(t1con);
      te2.UpdateNeighborIntersection(overlap);
      Assert.AreEqual(te5.ShouldClose(), true, "Should close... 2");
    }
Пример #8
0
    /// <summary>Where data packets prepended with a tunnel come.  Here we
    /// receive data as well as create new RelayEdges.</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);

      RelayEdge te = null;
      // No locally assigned ID, so we'll create a new RelayEdge 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 RelayEdge(this, (RelayTransportAddress) _local_tas[0],
              new RelayTransportAddress(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 RelayEdge 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);
    }
Пример #9
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(RelayEdge from, IDictionary msg)
 {
   List<Connection> overlap = _ito.EvaluateOverlap(_connections, msg);
   from.UpdateNeighborIntersection(overlap);
 }
Пример #10
0
    /// <summary>Common code to Create an outgoing edge.</summary>
    protected void CreateEdge(RelayEdgeCallbackAction teca, List<Connection> overlap)
    {
      if(_connections.Contains(teca.RelayTA.Target)) {
        FailedEdgeCreate(teca);
        return;
      }

      RelayEdge te = null;
      while(true) {
        te = new RelayEdge(this, (RelayTransportAddress) _local_tas[0],
            teca.RelayTA, _iasf.GetForwarderSelector(), overlap);
        lock(_sync) {
          if(!_id_to_tunnel.ContainsKey(te.LocalID)) {
            _id_to_tunnel[te.LocalID] = te;
            break;
          }
        }
        // Arriving here, implies another RelayEdge 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);
    }
Пример #11
0
        /// <summary>Where data packets prepended with a tunnel come.  Here we
        /// receive data as well as create new RelayEdges.</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);

            RelayEdge te = null;

            // No locally assigned ID, so we'll create a new RelayEdge 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 RelayEdge(this, (RelayTransportAddress)_local_tas[0],
                                       new RelayTransportAddress(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 RelayEdge 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);
        }
Пример #12
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(RelayEdge from, IDictionary msg)
        {
            List <Connection> overlap = _ito.EvaluateOverlap(_connections, msg);

            from.UpdateNeighborIntersection(overlap);
        }