Beispiel #1
0
 protected void TargetSelectorCallback(Address start, SortedList score_table, Address current) {
   Assert.IsTrue(score_table.Count > 0);
   if (current == null) {
     Address min_target = (Address) score_table.GetByIndex(0);
     Assert.AreEqual(_addr_list[_idx++], min_target);
   }
 }
 public RequestState(Address start, int range, TargetSelectorDelegate cb, Address current) {
   Start = start;
   Range = range;
   Callback = cb;
   Current = current;
   ResultTable = new Hashtable();
 }
Beispiel #3
0
  public AHHeader(short hops, short ttl, Address source, Address dest, ushort options) {
    //Make the header part:
    byte[] header = new byte[ LENGTH ];
    int offset = 0;
    //Write hops:
    NumberSerializer.WriteShort(hops, header, offset);
    Hops = hops;
    offset += 2;

    NumberSerializer.WriteShort(ttl, header, offset);
    Ttl = ttl;
    offset += 2;
    
    _src = source;
    offset += source.CopyTo(header, offset);

    _dest = dest;
    offset += dest.CopyTo(header, offset);

    Opts = options;
    NumberSerializer.WriteShort((short)options, header, offset);
    offset += 2;

    _data = MemBlock.Reference(header, 0, offset);
  }
 /// <summary>This methods send some ICopyable data to the remote address.
 /// </summary>
 /// <param name="remote_addr">Remote Nodes are referenced by their P2P
 /// Address, typically of type AHAddress.</param>
 /// <param name="data">This is an ICopyable object which contains the data
 /// to send.</param>
 public void SendMessage(Address remote_addr, ICopyable data) {
   // This instantiates a multi-use method to sending to the remote node,
   // though we will only use it once.  It is VERY similar to UDP.
   AHExactSender sender = new AHExactSender(_app_node.Node, remote_addr);
   // This is the process of actually sending the data.
   sender.Send(new CopyList(HW, data));
 }
    ///<summary>Verify the edge by comparing the address in the certificate to
    ///the one provided in the overlay.</summary>
    public static bool AddressInSubjectAltName(Node node, Edge e, Address addr) {
      SecureEdge se = e as SecureEdge;
      if(se == null) {
        throw new Exception("Invalid edge type!");
      }

      return se.SA.VerifyCertificateBySubjectAltName(addr.ToString());
    }
Beispiel #6
0
 /**
  * Selects an optimal target given a start address, the range starting at that address, and the current address (could be null).
  * If the current address is not null, it is returned as optimal, or else start address is returned.
  * @param start start address of the range.
  * @param range number of candidates
  * @param callback callback function into the caller
  * @param current currently selected optimal
  */
   public override void ComputeCandidates(Address start, int range, TargetSelectorDelegate callback, Address current) {
     SortedList sorted = new SortedList();
     if (current != null) {
       sorted[1.0] = (Address) current;
     } else {
       sorted[1.0] = start;
     }
     callback(start, sorted, current);
   }
Beispiel #7
0
 /// Simulator != thread-safe!
 protected static Address SimulatorCache(Address a) {
   int idx = NumberSerializer.ReadInt(a.ToMemBlock(), 0);
   Address tmp = _cache.GetValue(idx);
   if(a.Equals(tmp)) {
     return tmp;
   }
   _cache.Replace(idx, a);
   return a;
 }
Beispiel #8
0
 protected AHHeader(short hops, AHHeader head) {
   //Set a new number of hops:
   Hops = hops;
   //Copy the rest:
   Ttl = head.Ttl;
   Opts = head.Opts;
   _src = head._src; 
   _dest = head._dest; 
   _data = head._data;
 }
Beispiel #9
0
    /**
     * Prefered constructor for a Connection
     */
    public Connection(Edge e, Address a,
		      string connectiontype,
		      StatusMessage sm, LinkMessage peerlm)
    {
      _e = e;
      _a = a;
      _ct = String.Intern(connectiontype);
      _stat = sm;
      _lm = peerlm;
      _creation_time = DateTime.UtcNow;
      MainType = StringToMainType(_ct);
    }
Beispiel #10
0
    /**
     * Prefered constructor for a Connection
     */
    public Connection(Edge e, Address a,
		      string connectiontype,
		      StatusMessage sm, LinkMessage peerlm)
    {
      _e = e;
      _a = a;
      _ct = String.Intern(connectiontype);
      _stat = sm;
      _lm = peerlm;
      _creation_time = DateTime.UtcNow;
      MainType = StringToMainType(_ct);
      _as_dict = new WriteOnce<ListDictionary>();
      _sub_type = new WriteOnce<string>();
    }
Beispiel #11
0
 public AHHeader(short hops, short ttl, Address source, Address dest, ushort options) {
   //Make the header part:
   byte[] header = new byte[ AHPacket.HeaderLength ];
   int offset = 0;
   //Write hops:
   NumberSerializer.WriteShort(hops, header, offset);
   offset += 2;
   NumberSerializer.WriteShort(ttl, header, offset);
   offset += 2;
   offset += source.CopyTo(header, offset);
   offset += dest.CopyTo(header, offset);
   NumberSerializer.WriteShort((short)options, header, offset);
   offset += 2;
   _data = MemBlock.Reference(header, 0, offset);
 }
Beispiel #12
0
 /**
  * Factory method to reduce memory allocations by caching
  * commonly used NodeInfo objects
  */
 public static NodeInfo CreateInstance(Address a) {
   //Read some of the least significant bytes out,
   //AHAddress all have last bit 0, so we skip the last byte which
   //will have less entropy
   MemBlock mb = a.ToMemBlock();
   ushort idx = (ushort)NumberSerializer.ReadShort(mb, Address.MemSize - 3);
   NodeInfo ni = _mb_cache[idx];
   if( ni != null ) {
     if (a.Equals(ni._address)) {
       return ni;
     }
   }
   ni = new NodeInfo(a);
   _mb_cache[idx] = ni;
   return ni;
 }
 private static string GetString(Address target, IEnumerable forwarders) {
   var sb = new System.Text.StringBuilder();
   sb.Append("brunet.tunnel://");
   sb.Append(target.ToString().Substring(12));
   sb.Append("/");
   foreach(object forwarder in forwarders) {
     Address addr = forwarder as Address;
     if(addr == null) {
       addr = (forwarder as Brunet.Connections.Connection).Address;
     }
     sb.Append(addr.ToString().Substring(12,8));
     sb.Append("+");
   }
   if(sb[sb.Length - 1] == '+') {
     sb.Remove(sb.Length - 1, 1);
   }
   return sb.ToString();
 }
 public TunnelTransportAddress(string s) : base(s) {
   /** String representing the tunnel TA is as follows: brunet.tunnel://A/X1+X2+X3
    *  A: target address
    *  X1, X2, X3: forwarders, each X1, X2 and X3 is actually a slice of the initial few bytes of the address.
    */
   int k = s.IndexOf(":") + 3;
   int k1 = s.IndexOf("/", k);
   byte []addr_t  = Base32.Decode(s.Substring(k, k1 - k)); 
   _target = AddressParser.Parse( MemBlock.Reference(addr_t) );
   k = k1 + 1;
   _forwarders = new List<MemBlock>();
   while (k < s.Length) {
     byte [] addr_prefix = Base32.Decode(s.Substring(k, 8));
     _forwarders.Add(MemBlock.Reference(addr_prefix));
     //jump over the 8 characters and the + sign
     k = k + 9;
   }
   _forwarders.Sort();
 }
 public PacketForwarder(Node local)
 {
   _n = local;
   _local = _n.Address;
 }
Beispiel #16
0
    /**
     * Compute candidate scores for a shortcut connection.
     * @param start address computed by the SCO.
     * @param range nunber of candidate nodes.
     * @param cb callback function when candidate scores are available. 
     * @param current current selection of the optimal in the provided range.
     */
    public override void ComputeCandidates(Address start, int range, TargetSelectorDelegate cb, Address current) {
      Channel q = null;
      RequestState rs = null;
      lock(_sync) {
#if VTS_DEBUG
        Console.Error.WriteLine("VTS local: {0}, start: {1}, range: {2}, count: {3}", _node.Address, start, range, _num_requests);
#endif
        if (_num_requests == MAX_REQUESTS) {
          return; //do nothing and return;
        }
        _num_requests++;
        q = new Channel();
        rs = new RequestState(start, range, cb, current);
        _channel_to_state[q] = rs;        
      }
      
      //create a new request state
      ISender s = new ForwardingSender(_node, 
                                       start, 
                                       AHHeader.Options.Greedy, 
                                       new DirectionalAddress(DirectionalAddress.Direction.Left),
                                       (short) range,
                                       AHHeader.Options.Path
                                       );

      q.EnqueueEvent += new EventHandler(EnqueueHandler);
      q.CloseEvent += new EventHandler(CloseHandler);
      RpcManager rpc = _node.Rpc;
      rpc.Invoke(s, q, "ncserver.EchoVivaldiState", new object[]{});
    }
 /**
  * Note that a LinkProtocolState only gets a lock *AFTER* it has
  * received a LinkMessageReply.  Prior to that, the Linker that
  * created it holds the lock (if the _linker.Target is not null).
  *
  * So, given that we are being asked to transfer a lock, we must
  * have already gotten our LinkMessageReply set, or we wouldn't
  * hold the lock in the first place.
  *
  * So, we only transfer locks to other Linkers when we are finished
  * since us holding a lock means we have already head some
  * communication from the other side.
  * 
  * Since the CT.Lock and CT.Unlock methods can't be called when this
  * is being called, we know that _target_lock won't change during
  * this method.
  */
 public bool AllowLockTransfer(Address a, string contype, ILinkLocker l)
 {
   bool hold_lock = (a.Equals( _target_lock ) && contype == _contype);
   if( false == hold_lock ) {
     //This is a bug.
     throw new Exception(String.Format("We don't hold the lock: {0}", a));
   }
   if( (l is Linker) && IsFinished ) {
     return true;
   }
   return false;
 }
 public LinkProtocolState(Linker l, TransportAddress ta, Edge e) {
   _linker = l;
   _node = l.LocalNode;
   _contype = l.ConType;
   _target_lock = null;
   _lm_reply = new WriteOnce<LinkMessage>();
   _x = new WriteOnce<Exception>();
   _con = new WriteOnce<Connection>();
   _ta = ta;
   _is_finished = 0;
   //Setup the edge:
   _e = e;
   _result = Result.None;
 }
Beispiel #19
0
    /**
    <summary>This is called whenever there is a disconnect or a connect, the
    idea is to determine if there is a new left or right node, if there is and
    here is a pre-existing transfer, we must interupt it, and start a new
    transfer.</summary>
    <remarks>The possible scenarios where this would be active:
     - no change on left
     - new left node with no previous node (from disc or new node)
     - left disconnect and new left ready
     - left disconnect and no one ready
     - no change on right
     - new right node with no previous node (from disc or new node)
     - right disconnect and new right ready
     - right disconnect and no one ready
    </remarks>
    <param name="o">Unimportant</param>
    <param name="eargs">Contains the ConnectionEventArgs, which lets us know
    if this was a Structured Connection change and if it is, we should check
    the state of the system to see if we have a new left or right neighbor.
    </param>
    */

    protected void ConnectionHandler(object o, EventArgs eargs) {
      if(!_online) {
        return;
      }

      ConnectionEventArgs cargs = eargs as ConnectionEventArgs;
      Connection old_con = cargs.Connection;
      //first make sure that it is a new StructuredConnection
      if (old_con.MainType != ConnectionType.Structured) {
        return;
      }
      lock(_transfer_sync) {
        if(!_online) {
          return;
        }
        ConnectionTable tab = _node.ConnectionTable;
        Connection lc = null, rc = null;
        try {
          lc = tab.GetLeftStructuredNeighborOf((AHAddress) _node.Address);
        }
        catch(Exception) {}
        try {
          rc = tab.GetRightStructuredNeighborOf((AHAddress) _node.Address);
        }
        catch(Exception) {}

        if(lc != null) {
          if(lc.Address != _left_addr) {
            if(_left_transfer_state != null) {
              _left_transfer_state.Interrupt();
              _left_transfer_state = null;
            }
            _left_addr = lc.Address;
            if(Count > 0) {
              _left_transfer_state = new TransferState(lc, this);
            }
          }
        }
        else if(_left_addr != null) {
          if(_left_transfer_state != null) {
            _left_transfer_state.Interrupt();
            _left_transfer_state = null;
          }
          _left_addr = null;
        }

        if(rc != null) {
          if(rc.Address != _right_addr) {
            if(_right_transfer_state != null) {
              _right_transfer_state.Interrupt();
              _right_transfer_state = null;
            }
            _right_addr = rc.Address;
            if(Count > 0) {
              _right_transfer_state = new TransferState(rc, this);
            }
          }
        }
        else if(_right_addr != null) {
          if(_right_transfer_state != null) {
            _right_transfer_state.Interrupt();
            _right_transfer_state = null;
          }
          _right_addr = null;
        }
      }
    }
Beispiel #20
0
        /// <summary>Is the right person sending me this packet?</summary>
        /// <param name="ip">The IP source.</param>
        /// <param name="addr">The Brunet.Address source.</summary>
        public bool Check(MemBlock ip, Address addr)
        {
            // Check current results
              Address stored_addr = null;
              lock(_sync) {
            _results.TryGetValue(ip, out stored_addr);
              }

              if(addr.Equals(stored_addr)) {
            // Match!
            return true;
              } else if(stored_addr == null) {
            // No entry, check previous contents
            lock(_sync) {
              _last_results.TryGetValue(ip, out stored_addr);
            }
            if(Miss(ip)) {
              IncrementMisses(ip);
            }
            return addr.Equals(stored_addr);
              } else {
            // Bad mapping
            Miss(ip);
            throw new AddressResolutionException(String.Format(
              "IP:Address mismatch, expected: {0}, got: {1}",
              addr, stored_addr), AddressResolutionException.Issues.Mismatch);
              }
        }
Beispiel #21
0
    /*private static readonly log4net.ILog _log =
        log4net.LogManager.GetLogger(System.Reflection.MethodBase.
        GetCurrentMethod().DeclaringType);*/

    public DirectionalRouter(Address a)
    {
      _local = a;
    }
Beispiel #22
0
 /// <summary>Returns our nearest neighbors to the specified address, which
 /// is in turn used to help communicate with tunnel peer.</summary>
 public static List<Address> GetNearest(Address addr, ConnectionList cons)
 {
   ConnectionList cons_near = cons.GetNearestTo(addr, 16);
   List<Address> addrs = new List<Address>();
   foreach(Connection con in cons_near) {
     addrs.Add(con.Address);
   }
   return addrs;
 }
Beispiel #23
0
 /// <summary>Is the right person sending me this packet?</summary>
 /// <param name="ip">The IP source.</param>
 /// <param name="addr">The Brunet.Address source.</summary>
 public bool Check(MemBlock ip, Address addr)
 {
   // Check current results
   Address stored_addr = null;
   bool update;
   bool exists = _cache.TryGetValue(ip, out stored_addr, out update);
   if(addr.Equals(stored_addr)) {
     if(update) {
       Miss(ip);
     }
     return true;
   } else if(!exists) {
     Miss(ip);
     return false;
   } else {
     // Bad mapping
     throw new AddressResolutionException(String.Format(
           "IP:Address mismatch, expected: {0}, got: {1}",
           addr, stored_addr), AddressResolutionException.Issues.Mismatch);
   }
 }
Beispiel #24
0
 public LinkerTask(Address local, Address target, string ct) {
   _local = local;
   _target = target;
   _ct = Connection.StringToMainType(ct);
 }
Beispiel #25
0
    virtual protected void ConnectTo(Address target, string ConnectionType) {
      ConnectionType mt = Connection.StringToMainType(ConnectionType);
      /*
       * This is an anonymous delegate which is called before
       * the Connector starts.  If it returns true, the Connector
       * will finish immediately without sending an ConnectToMessage
       */
      Linker l = new Linker(_node, target, null, ConnectionType,
          _node.Address.ToString());
      object link_task = l.Task;
      Connector.AbortCheck abort = delegate(Connector c) {
        bool stop = false;
        stop = _node.ConnectionTable.Contains( mt, target );
        if (!stop ) {
          /*
           * Make a linker to get the task.  We won't use
           * this linker.
           * No need in sending a ConnectToMessage if we
           * already have a linker going.
           */
          stop = _node.TaskQueue.HasTask( link_task );
        }
        return stop;
      };
      if (abort(null)) {
        return;
      }

      ConnectToMessage  ctm = new ConnectToMessage(ConnectionType, _node.GetNodeInfo(8),
          _node.Address.ToString());
      ISender send = new AHSender(_node, target, AHPacket.AHOptions.Exact);
      Connector con = new Connector(_node, send, ctm, this);
      con.FinishEvent += ConnectorEndHandler;
      con.AbortIf = abort;
      _node.TaskQueue.Enqueue(con);
    }
Beispiel #26
0
///////////////
///
///  Here is the constructor
///
////////////////

    /**
     * @param local the local Node to connect to the remote node
     * @param target the address of the node you are trying to connect
     * to.  Set to null if you don't know
     * @param target_list an enumerable list of TransportAddress of the
     *                    Host we want to connect to
     * @param t ConnectionType string of the new connection
     * @token unique token to associate the different connection setup messages
     */
    public Linker(Node local, Address target, ICollection target_list, string ct, string token)
    {
      _task = new LinkerTask(local.Address, target, ct);
      _local_n = local;
      _active_lps_count = 0;
      //this TaskQueue starts new tasks in the announce thread of the node.
      _task_queue = new NodeTaskQueue(local);
      _task_queue.EmptyEvent += this.FinishCheckHandler;
      _ta_queue = new Brunet.Util.LockFreeQueue<TransportAddress>();
      if( target_list != null ) {
        int count = 0;
        Hashtable tas_in_queue = new Hashtable( _MAX_REMOTETAS );
        foreach(TransportAddress ta in target_list ) {
          if(tas_in_queue.ContainsKey(ta) ) {
//            Console.Error.WriteLine("TA: {0} appeared in list twice", ta);
          }
          else {
            _ta_queue.Enqueue(ta);
            tas_in_queue[ta] = null; //Remember that we've seen this one
            if( target != null ) {
              /*
               * Make sure we don't go insane with TAs
               * we know who we want to try to connect to,
               * if it doesn't work after some number of
               * attempts, give up.  Don't go arbitrarily
               * long
               */
              count++;
              if( count >= _MAX_REMOTETAS ) { break; }
            }
          }
        }
      }
      _added_cons = 0; //We have not added a connection yet
      _contype = ct;
      _maintype = Connection.StringToMainType( _contype );
      _target = target;
      _token = token;
      _ta_to_restart_state = new Hashtable( _MAX_REMOTETAS );
      _started = 0;
      _hold_fire = 1;
      _cph_transfer_requests = 0;
#if LINK_DEBUG
      _lid = Interlocked.Increment(ref _last_lid);
      if(ProtocolLog.LinkDebug.Enabled) {
        ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}: Making {1}",
              _local_n.Address, this));
        if( target_list != null ) {
	        ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("TAs:"));
          foreach(TransportAddress ta in target_list) {
            ProtocolLog.Write(ProtocolLog.LinkDebug, String.Format("{0}", ta));
          }
        }
      }
#endif
    }
 public bool AllowLockTransfer(Address a, string contype, ILinkLocker new_locker) {
   return false;
 }
Beispiel #28
0
    /**
     * Allow if we are transfering to a LinkProtocolState or ConnectionPacketHandler
     * Note this method does not change anything, if the transfer is done, it
     * is done by the ConnectionTable while it holds its lock.
     */
    public bool AllowLockTransfer(Address a, string contype, ILinkLocker l) {
      bool allow = false;
      bool hold_lock = (a.Equals( _target_lock ) && contype == _contype);
      if( false == hold_lock ) {
        //We don't even hold this lock!
        throw new Exception(
                            String.Format("{2} asked to transfer a lock({0}) we don't hold: ({1})",
                                          a, _target_lock, this));
      }
      if( l is Linker ) {
        //Never transfer to another linker:
      }
      else if ( l is ConnectionPacketHandler.CphState ) {
      /**
       * The ConnectionPacketHandler only locks when it
       * has actually received a packet.  This is a "bird in the
       * hand" situation, however, if both sides in the double
       * link case transfer the lock, then we have accomplished
       * nothing.
       *
       * There is a specific case to worry about: the case of
       * a firewall, where only one node can contact the other.
       * In this case, it may be very difficult to connect if
       * we don't eventually transfer the lock to the
       * ConnectionPacketHandler.  In the case of bi-directional
       * connectivity, we only transfer the lock if the
       * address we are locking is greater than our own (which
       * clearly cannot be true for both sides).
       * 
       * To handle the firewall case, we keep count of how
       * many times we have been asked to transfer the lock.  On
       * the third time we are asked, we assume we are in the firewall
       * case and we allow the transfer, this is just a hueristic.
       */
        int reqs = Interlocked.Increment(ref _cph_transfer_requests);
        if ( (reqs >= 3 ) || ( a.CompareTo( LocalNode.Address ) > 0) ) {
          allow = true;
        }
      }
      else if( l is LinkProtocolState ) {
        LinkProtocolState lps = (LinkProtocolState)l;
        /**
         * Or Transfer the lock to a LinkProtocolState if:
         * 1) We created this LinkProtocolState
         * 2) The LinkProtocolState has received a packet
         */
        if( (lps.Linker == this ) && ( lps.LinkMessageReply != null ) ) {
          allow = true;
        }
      }
#if LINK_DEBUG
      if (ProtocolLog.LinkDebug.Enabled) {
	  ProtocolLog.Write(ProtocolLog.LinkDebug,
                            String.Format("{0}: Linker({1}) {2}: transfering lock on {3} to {4}",
                              _local_n.Address, _lid, (_target_lock == null), a, l));
      }
#endif
      return allow;
    }
    protected void SendRpcMessage(Address addr, string method, 
      string query, bool secure) {

      System.DateTime sent = System.DateTime.Now;

#if !SVPN_NUNIT
      string meth_call = RPCID + "." + method;
      Channel q = new Channel();
      q.CloseAfterEnqueue();
      q.CloseEvent += delegate(object obj, EventArgs eargs) {
        try {
          RpcResult res = (RpcResult) q.Dequeue();
          string result = (string) res.Result;

          if(method == "Ping") {
              System.DateTime recv = System.DateTime.Now;
            _times = _times.InsertIntoNew(result, recv);
            TimeSpan rtt = recv - sent;
            _ssm.UpdateLatency(result, rtt.TotalMilliseconds);
          }

          ProtocolLog.WriteIf(SocialLog.SVPNLog,
            String.Format("RPC {0} {1} {2}", addr.ToString(), method, 
            query));

        } catch(Exception e) {
          ProtocolLog.WriteIf(SocialLog.SVPNLog, e.ToString());
        }
      };

      ISender sender;
      if(!secure) {
        sender = new AHExactSender(_node.Node, addr);
      }
      else {
        sender = _node.Bso.GetSecureSender(addr);
      }
      _rpc.Invoke(sender, q, meth_call, _node.Address, query);
#endif
    }
    /// <summary>Is the right person sending me this packet?</summary>
    /// <param name="ip">The IP source.</param>
    /// <param name="addr">The Brunet.Address source.</summary>
    public bool Check(MemBlock ip, Address addr)
    {
      Address stored_addr = Resolve(ip);

      if(stored_addr != null) {
        if(addr.Equals(stored_addr)) {
          return true;
        } else{
          throw new AddressResolutionException(String.Format(
                "IP:Address mismatch, expected: {0}, got: {1}",
                addr, stored_addr), AddressResolutionException.Issues.Mismatch);
        }
      }

      // No mapping, so use the given mapping
      _incoming_cache.Update(ip, addr);
      return true;
    }