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(); }
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()); }
/** * 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); }
/// 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; }
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; }
/** * 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); }
/** * 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>(); }
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); }
/** * 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; }
/** * 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; }
/** <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; } } }
/// <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); } }
/*private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase. GetCurrentMethod().DeclaringType);*/ public DirectionalRouter(Address a) { _local = a; }
/// <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; }
/// <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); } }
public LinkerTask(Address local, Address target, string ct) { _local = local; _target = target; _ct = Connection.StringToMainType(ct); }
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); }
/////////////// /// /// 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; }
/** * 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; }