Example #1
0
        public void Send(ICopyable data)
        {
            ConnectionList cl = Node.ConnectionTable.GetConnections(ConnectionType.Structured);
            // We start with the node immediately after the starting index
            int start = cl.IndexOf(From);

            if (start < 0)
            {
                start = ~start;
            }

            // We end with the node immediately before the end index
            int end = cl.IndexOf(To);

            if (end < 0)
            {
                end = ~end;
            }

            // If start >= end, because From < To or because this is a terminal
            // node and there are no other entities to forward it to.  So the
            // second test ensures that the first entity is actually inside the
            // range to forward it to.
            AHAddress start_addr = cl[start].Address as AHAddress;

            if (start >= end && start_addr.IsBetweenFromLeft(From, To))
            {
                end += cl.Count;
            }

            List <Connection> cons = SortByDistance(cl, start, end, Forwarders);

            for (int i = 0; i < cons.Count; i++)
            {
                Connection con   = cons[i];
                int        next  = i + 1;
                AHAddress  nfrom = con.Address as AHAddress;
                Address    nto   = To;
                if (next < cons.Count)
                {
                    nto = GetLeftNearTarget(cons[next].Address as AHAddress);
                }
                con.Edge.Send(new CopyList(PType, Source.ToMemBlock(),
                                           nfrom.ToMemBlock(), nto.ToMemBlock(), _forwarders, _hops, data));
            }

            _sent_to = cons.Count;
        }
Example #2
0
        /// <summary>Performs the bounded broadcast using recursion.</summary>
        public int BoundedBroadcast(AHAddress caller, AHAddress from, AHAddress to)
        {
            GraphNode      node = _addr_to_node[from];
            ConnectionList cl   = node.ConnectionTable.GetConnections(ConnectionType.Structured);

            // We start with the node immediately after the starting index
            int start = cl.IndexOf(from);

            if (start < 0)
            {
                start = ~start;
            }

            // We end with the node immediately before the end index
            int end = cl.IndexOf(to);

            if (end < 0)
            {
                end = ~end;
            }

            // Ensure we wrap around as necessary
            if (start > end && GetNearTarget(from).IsBetweenFromRight(to, from))
            {
                end += cl.Count;
            }

            int max_delay = 0;

            for (int i = start; i < end; i++)
            {
                AHAddress nfrom = cl[i].Address as AHAddress;
                AHAddress nto   = GetLeftNearTarget(cl[i + 1].Address as AHAddress);
                // If this is the last one, just have him query to 'to'
                if (i == end - 1)
                {
                    nto = to;
                }
                // recursion, yuck
                int delay = BoundedBroadcast(from, nfrom, nto);
                // We send a message and potentially the peer does as well
                max_delay = delay > max_delay ? delay : max_delay;
            }

            // Return our delay and the bytes cost for sending to us
            return(max_delay + SendPacket(caller, from)[0].Delay);
        }
Example #3
0
        protected Connection GetConnection(Address addr)
        {
            ConnectionList cons  = _node.ConnectionTable.GetConnections(ConnectionType.Structured);
            int            index = cons.IndexOf(addr);

            if (index < 0)
            {
                return(null);
            }
            return(cons[index]);
        }
Example #4
0
        public override Pair <Connection, bool> NextConnection(Edge from, AHHeader head)
        {
            Address    dest  = head.Destination;
            int        d_idx = _structs.IndexOf(dest);
            Connection next_con;

            if (d_idx >= 0)
            {
                //We have a direct connection:
                next_con = _structs[d_idx];
            }
            else
            {
                //We have to check the right and the left:
                var        ah_dest   = (AHAddress)dest;
                int        left_idx  = ~d_idx;
                Connection l_c       = _structs[left_idx];
                int        right_idx = left_idx - 1;
                Connection r_c       = _structs[right_idx];

                if (ah_dest.IsCloserToFirst((AHAddress)l_c.Address, (AHAddress)r_c.Address))
                {
                    next_con = l_c;
                }
                else
                {
                    next_con = r_c;
                }

                /*
                 * Note, DO NOT DO COMPARISONS WITH INDEX VALUES!!!!!
                 * do the the wrap around, _structs[x] == _structs[y]
                 * when x = y + k * _structs.Count for all k, so equality
                 * of Connection is not the same as equality of index
                 */
                if (head.Hops >= head.Ttl)
                {
                    //Only deliver if we are the closest or last mode:
                    bool local = next_con == _local_con || head.Opts == AHHeader.Options.Last;
                    if (local)
                    {
                        return(_LOCAL);
                    }
                    else
                    {
                        return(_NO_ONE);
                    }
                }
            }
            return(next_con == _local_con ? _LOCAL : new Pair <Connection, bool>(next_con, false));
        }
Example #5
0
        /// <summary>Performs a broadcast to the entire overlay.</summary>
        public int Broadcast(AHAddress from)
        {
            GraphNode      node  = _addr_to_node[from];
            ConnectionList cl    = node.ConnectionTable.GetConnections(ConnectionType.Structured);
            int            index = cl.IndexOf(from);

            if (index < 0)
            {
                index = ~index;
            }
            AHAddress start = cl[index].Address as AHAddress;

            return(BoundedBroadcast(from, start, GetLeftNearTarget(from)));
        }
Example #6
0
        /// <summary>First we try to find a third party we can connect with for
        /// overlap, if that is successful, we attempt to connect to him, if that
        /// is successful, we create a new tunnel edge.</summary>
        protected void AttemptToCreateOverlap(RelayEdgeCallbackAction teca)
        {
            WaitCallback create_connection = delegate(object o) {
                Address target = o as Address;
                if (o == null)
                {
                    FailedEdgeCreate(teca);
                    return;
                }

                ConnectionList cons  = _connections;
                int            index = cons.IndexOf(target);
                if (index < 0)
                {
                    FailedEdgeCreate(teca);
                    return;
                }

                List <Connection> overlap = new List <Connection>(1);
                overlap.Add(cons[index]);
                CreateEdge(teca, overlap);
            };

            Channel chan = new Channel(1);

            chan.CloseEvent += delegate(object o, EventArgs ea) {
                Address target = null;
                try {
                    IDictionary msg = (chan.Dequeue() as RpcResult).Result as IDictionary;
                    target = _ito.EvaluatePotentialOverlap(msg);
                } catch {
                }

                if (target == null)
                {
                    FailedEdgeCreate(teca);
                }
                else
                {
                    _oco.ConnectTo(target, create_connection);
                }
            };

            ISender s = new AHExactSender(_node, teca.RelayTA.Target);

            try { _node.Rpc.Invoke(s, chan, "tunnel.RequestSync"); }
            catch { chan.Close(); }
        }
Example #7
0
        protected void FindOverlapWorker(Node node1, Node node2)
        {
            ConnectionList cl = node1.ConnectionTable.GetConnections(ConnectionType.Structured);
            IEnumerable    ov = node1.ConnectionTable.GetConnections(Relay.OverlapConnectionOverlord.STRUC_OVERLAP);

            foreach (Connection ov_con in ov)
            {
                int index = cl.IndexOf(ov_con.Address);
                if (index < 0)
                {
                    Console.WriteLine("No matching pair for overlap...");
                    continue;
                }
                Connection con   = cl[index];
                int        delay = (ov_con.State.Edge as SimulationEdge).Delay + (con.State.Edge as SimulationEdge).Delay;
                Console.WriteLine("Delay: " + delay);
            }
        }
Example #8
0
        /// <summary>Returns a Tunnel Sync message containing up to 40 addresses
        /// first starting with previous overlap followed by new potential
        /// connections for overlap.</summary>
        public virtual IDictionary GetSyncMessage(IList <Connection> current_overlap,
                                                  Address local_addr, ConnectionList cons)
        {
            Hashtable ht  = new Hashtable();
            DateTime  now = DateTime.UtcNow;

            if (current_overlap != null)
            {
                foreach (Connection con in current_overlap)
                {
                    Hashtable info = new Hashtable(2);
                    info["ta"] = TransportAddress.TATypeToString(con.Edge.TAType);
                    info["ct"] = (int)(now - con.CreationTime).TotalMilliseconds;
                    ht[con.Address.ToMemBlock()] = info;
                }
            }

            int idx = cons.IndexOf(local_addr);

            if (idx < 0)
            {
                idx = ~idx;
            }
            int max   = cons.Count < 16 ? cons.Count : 16;
            int start = idx - max / 2;
            int end   = idx + max / 2;

            for (int i = start; i < end; i++)
            {
                Connection con = cons[i];
                MemBlock   key = con.Address.ToMemBlock();
                if (ht.Contains(key))
                {
                    continue;
                }
                Hashtable info = new Hashtable();
                info["ta"] = TransportAddress.TATypeToString(con.Edge.TAType);
                info["ct"] = (int)(now - con.CreationTime).TotalMilliseconds;
                ht[key]    = info;
            }

            return(ht);
        }
Example #9
0
        public DirectionalRouting(AHAddress local, ConnectionList structs)
        {
            _NULL_TRUE  = new Pair <Connection, bool>(null, true);
            _NULL_FALSE = new Pair <Connection, bool>(null, false);
            Connection left_c  = null;
            Connection right_c = null;

            if (structs.Count > 0)
            {
                int local_idx = ~structs.IndexOf(local);
                int left_idx  = local_idx;
                int right_idx = left_idx - 1;
                left_c  = structs[left_idx];
                right_c = structs[right_idx];
            }
            _LEFT_FALSE  = new Pair <Connection, bool>(left_c, false);
            _RIGHT_FALSE = new Pair <Connection, bool>(right_c, false);
            _LEFT_TRUE   = new Pair <Connection, bool>(left_c, true);
            _RIGHT_TRUE  = new Pair <Connection, bool>(right_c, true);
        }
Example #10
0
        /// <summary>Returns the oldest 4 addresses in the overlap.</summary>
        public virtual List <Connection> EvaluateOverlap(ConnectionList cons, IDictionary msg)
        {
            List <Connection> overlap = new List <Connection>();

            foreach (DictionaryEntry de in msg)
            {
                MemBlock key = de.Key as MemBlock;
                if (key == null)
                {
                    key = MemBlock.Reference((byte[])de.Key);
                }
                Address addr = new AHAddress(key);

                int index = cons.IndexOf(addr);
                if (index < 0)
                {
                    continue;
                }

                Connection con = cons[index];

                // Since there are no guarantees about routing over two tunnels, we do
                // not consider cases where we are connected to the overlapping tunnels
                // peers via tunnels
                if (con.Edge.TAType.Equals(TransportAddress.TAType.Tunnel))
                {
                    Hashtable values = de.Value as Hashtable;
                    TransportAddress.TAType tatype =
                        TransportAddressFactory.StringToType(values["ta"] as string);
                    if (tatype.Equals(TransportAddress.TAType.Tunnel))
                    {
                        continue;
                    }
                }
                overlap.Add(con);
            }

            return(GetOldest(overlap));
        }
Example #11
0
        /// <summary>
        /// changes the index of currently selected RDPConnection in list
        /// </summary>
        /// <param name="steps">steps to move index</param>
        private void MoveItemInConnectionlist(int steps)
        {
            int currentIndex = ConnectionList.IndexOf(SelectedRDPConnection);
            int newIndex     = currentIndex + steps;

            if (newIndex < 0)
            {
                newIndex = 0;
            }
            else
            {
                int lastIndex = ConnectionList.IndexOf(ConnectionList.Last());
                if (newIndex > lastIndex)
                {
                    newIndex = lastIndex;
                }
            }

            if (currentIndex != newIndex)
            {
                ConnectionList.Move(currentIndex, newIndex);
                NotifyPropertyChanged("ConnectionList");
            }
        }
Example #12
0
    /// <summary>Returns the four fastest in the overlap.</summary>
    public override List<Connection> EvaluateOverlap(ConnectionList cons, IDictionary msg)
    {
      List<Connection> overlap = new List<Connection>();

      foreach(DictionaryEntry de in msg) {
        MemBlock key = de.Key as MemBlock;
        if(key == null) {
          key = MemBlock.Reference((byte[]) de.Key);
        }
        Address addr = new AHAddress(key);

        int index = cons.IndexOf(addr);
        if(index < 0) {
          continue;
        }

        Connection con = cons[index];

        // Since there are no guarantees about routing over two tunnels, we do
        // not consider cases where we are connected to the overlapping tunnels
        // peers via tunnels
        if(con.Edge.TAType.Equals(TransportAddress.TAType.Tunnel)) {
          Hashtable values = de.Value as Hashtable;
          TransportAddress.TAType tatype =
            TransportAddressFactory.StringToType(values["ta"] as string);
          if(tatype.Equals(TransportAddress.TAType.Tunnel)) {
            continue;
          }
        }
        overlap.Add(con);
      }

      return GetClosest(overlap);
    }
Example #13
0
 public DirectionalRouting(AHAddress local, ConnectionList structs) {
   _NULL_TRUE = new Pair<Connection, bool>(null, true);
   _NULL_FALSE = new Pair<Connection, bool>(null, false);
   Connection left_c = null;
   Connection right_c = null;
   if( structs.Count > 0) {
     int local_idx = ~structs.IndexOf(local);
     int left_idx = local_idx;
     int right_idx = left_idx - 1;
     left_c = structs[left_idx];
     right_c = structs[right_idx];
   }
   _LEFT_FALSE = new Pair<Connection, bool>(left_c, false);
   _RIGHT_FALSE = new Pair<Connection, bool>(right_c, false);
   _LEFT_TRUE = new Pair<Connection, bool>(left_c, true);
   _RIGHT_TRUE = new Pair<Connection, bool>(right_c, true);
 }
Example #14
0
    /// <summary>Returns a Relay Sync message containing up to 40 addresses
    /// first starting with previous overlap followed by new potential
    /// connections for overlap.</summary>
    public virtual IDictionary GetSyncMessage(IList<Connection> current_overlap,
        Address local_addr, ConnectionList cons)
    {
      Hashtable ht = new Hashtable();
      DateTime now = DateTime.UtcNow;
      if(current_overlap != null) {
        foreach(Connection con in current_overlap) {
          Hashtable info = new Hashtable(2);
          info["ta"] = TransportAddress.TATypeToString(con.State.Edge.TAType);
          info["ct"] = (int) (now - con.CreationTime).TotalMilliseconds;
          ht[con.Address.ToMemBlock()] = info;
        }
      }

      int idx = cons.IndexOf(local_addr);
      if(idx < 0) {
        idx = ~idx;
      }
      int max = cons.Count < 16 ? cons.Count : 16;
      int start = idx - max / 2;
      int end = idx + max / 2;

      for(int i = start; i < end; i++) {
        Connection con = cons[i];
        MemBlock key = con.Address.ToMemBlock();
        if(ht.Contains(key)) {
          continue;
        }
        Hashtable info = new Hashtable();
        info["ta"] = TransportAddress.TATypeToString(con.State.Edge.TAType);
        info["ct"] = (int) (now - con.CreationTime).TotalMilliseconds;
        ht[key] = info;
      }

      return ht;
    }
Example #15
0
        /**
         * Generates tree for bounded broadcast. Algorithm works as follows:
         * The goal is to broadcast to all nodes in range [local_address, end).
         * Given a range [local_address, b), determine all connections that belong to this range.
         * Let the connections be b_1, b_2, ..... b_n.
         * To connection bi assign the range [b_i, b_{i+1}).
         * To the connection bn assign range [b_n, end).]
         */
        public override void GenerateTree(Channel q, MapReduceArgs mr_args)
        {
            object gen_arg   = mr_args.GenArg;
            string end_range = gen_arg as string;

            Log("generating child tree, range end: {0}.", end_range);
            AHAddress end_addr   = (AHAddress)AddressParser.Parse(end_range);
            AHAddress start_addr = _node.Address as AHAddress;
            //we are at the start node, here we go:
            ConnectionTable tab     = _node.ConnectionTable;
            ConnectionList  structs = tab.GetConnections(ConnectionType.Structured);
            ArrayList       retval  = new ArrayList();

            if (structs.Count > 0)
            {
                Connection curr_con = structs.GetLeftNeighborOf(_node.Address);
                int        curr_idx = structs.IndexOf(curr_con.Address);
                //keep going until we leave the range
                int       count    = 0;
                ArrayList con_list = new ArrayList();
                while (count++ < structs.Count && ((AHAddress)curr_con.Address).IsBetweenFromLeft(start_addr, end_addr))
                {
                    con_list.Add(curr_con);
                    //Log("adding connection: {0} to list.", curr_con.Address);
                    curr_idx = (curr_idx + 1) % structs.Count;
                    curr_con = structs[curr_idx];
                }

                Log("{0}: {1}, number of child connections: {2}",
                    this.TaskName, _node.Address, con_list.Count);
                for (int i = 0; i < con_list.Count; i++)
                {
                    MapReduceInfo mr_info = null;
                    ISender       sender  = null;
                    Connection    con     = (Connection)con_list[i];
                    sender = (ISender)con.Edge;
                    //check if last connection
                    if (i == con_list.Count - 1)
                    {
                        mr_info = new MapReduceInfo((ISender)sender,
                                                    new MapReduceArgs(this.TaskName,
                                                                      mr_args.MapArg,   //map argument
                                                                      end_range,        //generate argument
                                                                      mr_args.ReduceArg //reduce argument
                                                                      ));

                        Log("{0}: {1}, adding address: {2} to sender list, range end: {3}",
                            this.TaskName, _node.Address,
                            con.Address, end_range);
                        retval.Add(mr_info);
                    }
                    else
                    {
                        string child_end = ((Connection)con_list[i + 1]).Address.ToString();
                        mr_info = new MapReduceInfo(sender,
                                                    new MapReduceArgs(this.TaskName,
                                                                      mr_args.MapArg,
                                                                      child_end,
                                                                      mr_args.ReduceArg));
                        Log("{0}: {1}, adding address: {2} to sender list, range end: {3}",
                            this.TaskName, _node.Address,
                            con.Address, child_end);
                        retval.Add(mr_info);
                    }
                }
            }
            q.Enqueue(retval.ToArray(typeof(MapReduceInfo)));
        }
Example #16
0
        /// <summary>Make sure there are no entries in the Dht, who we should be
        /// connected to, but aren't.</summary>
        protected void CheckAndUpdateRemoteTAs(List <TransportAddress> tas)
        {
            AHAddress  right = null, left = null;
            BigInteger right_dist = null, left_dist = null;
            AHAddress  addr = _node.Address as AHAddress;

            // Find the closest left and right nodes
            foreach (TransportAddress ta in tas)
            {
                AHAddress target = (ta as SubringTransportAddress).Target;
                if (target.Equals(addr))
                {
                    continue;
                }
                BigInteger ldist = addr.LeftDistanceTo(target);
                BigInteger rdist = addr.RightDistanceTo(target);

                if (left_dist == null || ldist < left_dist)
                {
                    left_dist = ldist;
                    left      = target;
                }

                if (right_dist == null || rdist < right_dist)
                {
                    right_dist = rdist;
                    right      = target;
                }
            }

            ConnectionList cl        = _node.ConnectionTable.GetConnections(ConnectionType.Structured);
            int            local_idx = ~cl.IndexOf(_node.Address);

            if (left != null)
            {
                int remote_idx = ~cl.IndexOf(left);
                // If we're not connected to the left closest and its closer than any
                // of our current peers, let's connect to it
                if (remote_idx > 0 && Math.Abs(local_idx - remote_idx) < 2)
                {
                    List <TransportAddress> tmp_tas = new List <TransportAddress>(1);
                    tmp_tas.Add(new SubringTransportAddress(left, _shared_namespace));
                    Linker linker = new Linker(_node, null, tmp_tas, "leaf", addr.ToString());
                    linker.Start();
                }
            }

            if (right != null && right != left)
            {
                int remote_idx = ~cl.IndexOf(right);
                // If we're not connected to the right closest and its closer than any
                // of our current peers, let's connect to it
                if (remote_idx > 0 && Math.Abs(local_idx - remote_idx) < 2)
                {
                    List <TransportAddress> tmp_tas = new List <TransportAddress>(1);
                    tas.Add(new SubringTransportAddress(right, _shared_namespace));
                    Linker linker = new Linker(_node, null, tmp_tas, "leaf", addr.ToString());
                    linker.Start();
                }
            }

            UpdateRemoteTAs(tas);
        }
        /// <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);
        }
Example #18
0
        /**
         * On every activation, the ChotaConnectionOverlord trims any connections
         * that are unused, and also creates any new connections of needed
         */
        override public void Activate()
        {
            if (!_active)
            {
                return;
            }

            ConnectionList cons = _node.ConnectionTable.GetConnections(Connection.StringToMainType(struc_chota));

            // Trim and add OUTSIDE of the lock!
            List <Edge>    to_trim = new List <Edge>();
            List <Address> to_add  = new List <Address>();

            lock (_sync) {
                _node_rank_list.Sort(_cmp);
                // Find the guys to trim....
                for (int i = _node_rank_list.Count - 1; i >= MAX_CHOTA && i > 0; i--)
                {
                    NodeRankInformation node_rank = (NodeRankInformation)_node_rank_list[i];
                    // Must remove from _dest_to_node_rank to prevent memory leak
                    _dest_to_node_rank.Remove(node_rank.Addr);
                    // Now check to see if ChotaCO owns this connections and add to_trim if it does
                    int idx = cons.IndexOf(node_rank.Addr);
                    if (idx >= 0 && cons[idx].ConType.Equals(struc_chota))
                    {
                        to_trim.Add(cons[idx].Edge);
                    }
                }

                // Don't keep around stale state
                if (_node_rank_list.Count > MAX_CHOTA)
                {
                    _node_rank_list.RemoveRange(MAX_CHOTA, _node_rank_list.Count - MAX_CHOTA);
                }

                // Find guys to connect to!
                for (int i = 0; i < _node_rank_list.Count && i < MAX_CHOTA; i++)
                {
                    //we are traversing the list in descending order of
                    NodeRankInformation node_rank = (NodeRankInformation)_node_rank_list[i];
                    if (node_rank.Count < MIN_SCORE_THRESHOLD)
                    {
                        //too low score to create a connection
                        continue;
                    }
                    else if (cons.IndexOf(node_rank.Addr) >= 0)
                    {
                        // already have a connection to that node!
                        continue;
                    }
                    to_add.Add(node_rank.Addr);
                }
            }

            foreach (Edge e in to_trim)
            {
                _node.GracefullyClose(e, "From Chota, low score trim.");
            }

            foreach (Address addr in to_add)
            {
                ConnectTo(addr, struc_chota);
            }
        }
Example #19
0
        public override Pair <Connection, bool> NextConnection(Edge from, AHHeader head)
        {
            Address dest  = head.Destination;
            int     d_idx = _structs.IndexOf(dest);

            if (d_idx >= 0)
            {
                //We have a direct connection:
                Connection next = _structs[d_idx];
                if (next != _local_con)
                {
                    return(new Pair <Connection, bool>(next, false));
                }
                else
                {
                    return(new Pair <Connection, bool>(null, true));
                }
            }
            else
            {
                var        ah_dest   = (AHAddress)dest;
                int        left_idx  = ~d_idx;
                Connection l_c       = _structs[left_idx];
                int        right_idx = left_idx - 1;
                Connection r_c       = _structs[right_idx];

                Connection next_con;
                Connection other_con;
                if (ah_dest.IsCloserToFirst((AHAddress)l_c.Address, (AHAddress)r_c.Address))
                {
                    next_con  = l_c;
                    other_con = r_c;
                }
                else
                {
                    next_con  = r_c;
                    other_con = l_c;
                }
                //See if we need to get it:

                /* everyone gets "path" packets,
                 * if it's exact, only the destination gets it, handled above
                 * otherwise, only the two nodes on either side of the destination get
                 * it
                 */
                bool local = head.Opts == AHHeader.Options.Path ||
                             ((next_con == _local_con || other_con == _local_con) &&
                              head.Opts != AHHeader.Options.Exact);

                Connection to_send;
                //Check not to send it back the way it came:
                if (from == null)
                {
                    /*
                     * This packet is from us, so just send it to the closest
                     * node, other than us.
                     */
                    to_send = _local_con != next_con ? next_con : other_con;
                }
                else if (next_con.Edge == from)
                {
                    //Don't send it back the way it came:
                    to_send = other_con;
                }
                else
                {
                    //Great, the closest has not yet been visited:
                    to_send = next_con;
                }
                //Now, make sure not to send it to ourselves:
                to_send = to_send == _local_con ? null : to_send;
                return(new Pair <Connection, bool>(to_send, local));
            }
        }