/** * 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[] {}); }
public object[] forwardingproxy(string relay, int init_option, string dest, int ttl, int ahOptions, int maxResultsToWait, string method, params object[] args) { Address forwarder = AddressParser.Parse(relay); Address target = AddressParser.Parse(dest); ForwardingSender s = new ForwardingSender(_node, forwarder, (ushort)init_option, target, (short)ttl, (ushort)ahOptions); return(this.Proxy(s, maxResultsToWait, method, args)); }
/// <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. } } }
/** * Invoked when a result is enqueued into the channel. */ protected void EnqueueHandler(object o, EventArgs args) { Channel q = (Channel)o; bool close_channel = false; lock (_sync) { try { RpcResult result = q.Dequeue() as RpcResult; Hashtable ht = (Hashtable)result.Result; Hashtable ht_position = (Hashtable)ht["position"]; NCService.VivaldiState vs = new NCService.VivaldiState(); vs.Position = new Point((double[])((ArrayList)ht_position["side"]).ToArray(typeof(double)), (double)ht_position["height"]); vs.WeightedError = (double)ht["error"]; ForwardingSender fs = result.ResultSender as ForwardingSender; //record this information in the request state. RequestState request = (RequestState)_channel_to_state[q]; if (request != null) { //make sure this is not our own reply if (!fs.Destination.Equals(_node.Address)) { #if VTS_DEBUG Console.Error.WriteLine("VTS local: {0}, start: {1}, dest: {2}", _node.Address, request.Start, fs.Destination); #endif request.ResultTable[fs.Destination] = new object[] { vs, (string)ht["hostname"] }; } if (request.ResultTable.Keys.Count >= (int)request.Range * 0.75) { close_channel = true; } } } catch {} } if (close_channel) { q.Close(); } }
/// <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) { TunnelEdge te = from as TunnelEdge; Connection forwarder = te.NextForwarder; if(te.RemoteID == -1) { Address target = (te.RemoteTA as TunnelTransportAddress).Target; ISender sender = new ForwardingSender(_node, forwarder.Address, target); sender.Send(new CopyList(PType.Protocol.Tunneling, 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. } } }
/** * 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[]{}); }
/// <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); }
public object[] forwardingproxy(string relay, int init_option, string dest, int ttl, int ahOptions, int maxResultsToWait, string method, params object[] args) { Address forwarder = AddressParser.Parse(relay); Address target = AddressParser.Parse(dest); ForwardingSender s = new ForwardingSender(_node, forwarder, (ushort) init_option, target, (short) ttl, (ushort)ahOptions); return this.Proxy(s, maxResultsToWait, method, args); }