public AHRoutingAlgorithm GetRoutingAlgo(AHHeader head) { int addclass = head.Destination.Class; if (addclass == AHAddress.ClassValue) { ushort opts = head.Opts; if (opts == AHHeader.Options.Last || opts == AHHeader.Options.Greedy) { return(_greedy); } else { return(_annealing); } } else if (addclass == DirectionalAddress.ClassValue) { return(_directional); } else { throw new Exception( String.Format("No router for class: {0}", addclass)); } }
/** * Here we handle routing AHPackets */ public void HandleData(MemBlock data, ISender ret_path, object st) { var header = new AHHeader(data); var payload = data.Slice(header.Length); HandleData(header, payload, ret_path, st); }
public void Send(ICopyable data) { /* * Assemble an AHPacket: */ if (_header == null) { AHHeader ahh = new AHHeader(_hops, _ttl, _source, _dest, _options); _header = MemBlock.Copy(new CopyList(PType.Protocol.AH, ahh)); _header_length = _header.Length; } byte[] ah_packet; int packet_length; int packet_offset; //Try to get the shared BufferAllocator, useful when //we don't know how big the data is, which in general //is just as expensive as doing a CopyTo... BufferAllocator ba = Interlocked.Exchange <BufferAllocator>(ref _buf_alloc, null); if (ba != null) { try { ah_packet = ba.Buffer; packet_offset = ba.Offset; int tmp_off = packet_offset; tmp_off += _header.CopyTo(ah_packet, packet_offset); tmp_off += data.CopyTo(ah_packet, tmp_off); packet_length = tmp_off - packet_offset; ba.AdvanceBuffer(packet_length); } catch (System.Exception x) { throw new SendException(false, "could not write the packet, is it too big?", x); } finally { //Put the BA back Interlocked.Exchange <BufferAllocator>(ref _buf_alloc, ba); } } else { //Oh well, someone else is using the buffer, just go ahead //and allocate new memory: packet_offset = 0; packet_length = _header_length + data.Length; ah_packet = new byte[packet_length]; int off_to_data = _header.CopyTo(ah_packet, 0); data.CopyTo(ah_packet, off_to_data); } MemBlock mb_packet = MemBlock.Reference(ah_packet, packet_offset, packet_length); /* * Now we announce this packet, the AHHandler will * handle routing it for us */ _n.HandleData(mb_packet, _from, this); }
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; }
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)); }
public Pair<Connection, bool> NextConnection(Edge edge, AHHeader header) { Pair<Connection, bool> result = null; //Check to see if we can use a Leaf connection: int dest_idx = _ahstate.Leafs.IndexOf(header.Destination); if( dest_idx >= 0 ) { result = new Pair<Connection, bool>(_ahstate.Leafs[dest_idx], false); } else { var alg = _ahstate.GetRoutingAlgo(header); result = alg.NextConnection(edge, header); } return result; }
public AHSender(Node n, ISender from, Address destination, short ttl, ushort options, short hops_taken) { Node = n as StructuredNode; if (Node == null) { throw new Exception("Node must be a structured node"); } ReceivedFrom = from; //Here are the fields in the order they appear: Ttl = ttl; Source = n.Address; Destination = destination; Options = options; HopsTaken = hops_taken; Header = new AHHeader(Hops, Ttl, Source, Destination, Options); }
public override bool Equals(object o) { AHHeader o_head = o as AHHeader; if (o_head != null) { return((this.Hops == o_head.Hops) && (this.Ttl == o_head.Ttl) && (this.Opts == o_head.Opts) && (this.Destination.Equals(o_head.Destination)) && (this.Source.Equals(o_head.Source))); } else { return(false); } }
/** * Here we handle routing AHPackets */ public void HandleData(MemBlock data, ISender ret_path, object st) { AHState state = _state; //Read the state, it can't change after the read var header = new AHHeader(data); var payload = data.Slice(header.Length); Connection next_con; //Check to see if we can use a Leaf connection: int dest_idx = state.Leafs.IndexOf(header.Destination); if (dest_idx >= 0) { next_con = state.Leafs[dest_idx]; } else { var alg = state.GetRoutingAlgo(header); Pair <Connection, bool> result = alg.NextConnection(ret_path as Edge, header); if (result.Second) { //Send a response exactly back to the node that sent to us var resp_send = new AHSender(_n, ret_path, header.Source, AHSender.DefaultTTLFor(_n.NetworkSize), AHHeader.Options.Exact); _n.HandleData(payload, resp_send, this); } next_con = result.First; } //Send it on: if (next_con != null) { //Now we do the sending: var new_packet = new CopyList(PType.Protocol.AH, header.IncrementHops(), payload); try { next_con.Edge.Send(new_packet); } catch (EdgeException) { //Just drop the packet... } } }
public override Pair <Connection, bool> NextConnection(Edge from, AHHeader h) { DirectionalAddress dest = (DirectionalAddress)h.Destination; if (h.Ttl <= h.Hops) { //Deliver it to us but stop it here: return(_NULL_TRUE); } if (dest.Bearing == DirectionalAddress.Direction.Left) { if (h.Opts == AHHeader.Options.Path) { return(_LEFT_TRUE); } else { return(_LEFT_FALSE); } } else if (dest.Bearing == DirectionalAddress.Direction.Right) { if (h.Opts == AHHeader.Options.Path) { return(_RIGHT_TRUE); } else { return(_RIGHT_FALSE); } } else { throw new System.Exception( System.String.Format("Unrecognized direction: {0}", dest.Bearing)); } }
public AHRoutingAlgorithm GetRoutingAlgo(AHHeader head) { int addclass = head.Destination.Class; if( addclass == AHAddress.ClassValue ) { ushort opts = head.Opts; if( opts == AHHeader.Options.Last || opts == AHHeader.Options.Greedy ) { return _greedy; } else { return _annealing; } } else if( addclass == DirectionalAddress.ClassValue ) { return _directional; } else { throw new Exception( String.Format("No router for class: {0}", addclass)); } }
public override Pair<Connection, bool> NextConnection(Edge from, AHHeader h) { DirectionalAddress dest = (DirectionalAddress)h.Destination; if( h.Ttl <= h.Hops ) { //Deliver it to us but stop it here: return _NULL_TRUE; } if ( dest.Bearing == DirectionalAddress.Direction.Left ) { if( h.Opts == AHHeader.Options.Path ) { return _LEFT_TRUE; } else { return _LEFT_FALSE; } } else if (dest.Bearing == DirectionalAddress.Direction.Right) { if( h.Opts == AHHeader.Options.Path ) { return _RIGHT_TRUE; } else { return _RIGHT_FALSE; } } else { throw new System.Exception( System.String.Format("Unrecognized direction: {0}", dest.Bearing)); } }
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); } }
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); }
/** compute the next step in the route * @param from the Edge the packet came in on * @param head the header to route * @return next connection and bool indicating if local node should get * packet. If there is no next connection, the connection will be null */ public abstract Pair<Connection, bool> NextConnection(Edge from, AHHeader head);
public void Send(ICopyable data) { /* * Assemble an AHPacket: */ if( _header == null ) { AHHeader ahh = new AHHeader(_hops, _ttl, _source, _dest, _options); _header = MemBlock.Copy(new CopyList( PType.Protocol.AH, ahh)); _header_length = _header.Length; } byte[] ah_packet; int packet_length; int packet_offset; //Try to get the shared BufferAllocator, useful when //we don't know how big the data is, which in general //is just as expensive as doing a CopyTo... BufferAllocator ba = Interlocked.Exchange<BufferAllocator>(ref _buf_alloc, null); if( ba != null ) { try { ah_packet = ba.Buffer; packet_offset = ba.Offset; int tmp_off = packet_offset; tmp_off += _header.CopyTo(ah_packet, packet_offset); tmp_off += data.CopyTo(ah_packet, tmp_off); packet_length = tmp_off - packet_offset; ba.AdvanceBuffer(packet_length); } catch(System.Exception x) { throw new SendException(false, "could not write the packet, is it too big?", x); } finally { //Put the BA back Interlocked.Exchange<BufferAllocator>(ref _buf_alloc, ba); } } else { //Oh well, someone else is using the buffer, just go ahead //and allocate new memory: packet_offset = 0; packet_length = _header_length + data.Length; ah_packet = new byte[ packet_length ]; int off_to_data = _header.CopyTo(ah_packet, 0); data.CopyTo(ah_packet, off_to_data); } MemBlock mb_packet = MemBlock.Reference(ah_packet, packet_offset, packet_length); /* * Now we announce this packet, the AHHandler will * handle routing it for us */ _n.HandleData(mb_packet, _from, this); }
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)); } }
public void HandleData(AHHeader header, ICopyable payload, ISender ret_path, object st) { AHState state = _state; //Read the state, it can't change after the read Connection next_con; //Check to see if we can use a Leaf connection: int dest_idx = state.Leafs.IndexOf(header.Destination); if( dest_idx >= 0 ) { next_con = state.Leafs[dest_idx]; } else { var alg = state.GetRoutingAlgo(header); Pair<Connection, bool> result = alg.NextConnection(ret_path as Edge, header); if( result.Second ) { //Send a response exactly back to the node that sent to us var resp_send = new AHSender(_n, ret_path, header.Source, AHSender.DefaultTTLFor(_n.NetworkSize), AHHeader.Options.Exact, header.Hops); MemBlock data = payload as MemBlock; if(data == null) { // Try to get the shared BufferAllocator, useful when we don't know // how big the data is, which in general is just as expensive as // doing a CopyTo... BufferAllocator ba = Interlocked.Exchange<BufferAllocator>(ref _ba, null); if( ba != null ) { try { int length = payload.CopyTo(ba.Buffer, ba.Offset); data = MemBlock.Reference(ba.Buffer, ba.Offset, length); ba.AdvanceBuffer(length); } catch(System.Exception x) { throw new SendException(false, "could not write the packet, is it too big?", x); } finally { Interlocked.Exchange<BufferAllocator>(ref _ba, ba); } } else { data = MemBlock.Copy(payload); } } _n.HandleData( data, resp_send, this); } next_con = result.First; } //Send it on: if( next_con != null ) { //Now we do the sending: var new_packet = new CopyList(PType.Protocol.AH, header.IncrementHops(), payload); try { next_con.State.Edge.Send(new_packet); } catch(SendException) { //Just drop the packet... } } }
public AHSender(Node n, ISender from, Address destination, short ttl, ushort options, short hops_taken) { Node = n as StructuredNode; if(Node == null) { throw new Exception("Node must be a structured node"); } ReceivedFrom = from; //Here are the fields in the order they appear: Ttl = ttl; Source = n.Address; Destination = destination; Options = options; HopsTaken = hops_taken; Header = new AHHeader(Hops, Ttl, Source, Destination, Options); }
public void HandleData(AHHeader header, ICopyable payload, ISender ret_path, object st) { AHState state = _state; //Read the state, it can't change after the read Connection next_con; //Check to see if we can use a Leaf connection: int dest_idx = state.Leafs.IndexOf(header.Destination); if (dest_idx >= 0) { next_con = state.Leafs[dest_idx]; } else { var alg = state.GetRoutingAlgo(header); Pair <Connection, bool> result = alg.NextConnection(ret_path as Edge, header); if (result.Second) { //Send a response exactly back to the node that sent to us var resp_send = new AHSender(_n, ret_path, header.Source, AHSender.DefaultTTLFor(_n.NetworkSize), AHHeader.Options.Exact, header.Hops); MemBlock data = payload as MemBlock; if (data == null) { // Try to get the shared BufferAllocator, useful when we don't know // how big the data is, which in general is just as expensive as // doing a CopyTo... BufferAllocator ba = Interlocked.Exchange <BufferAllocator>(ref _ba, null); if (ba != null) { try { int length = payload.CopyTo(ba.Buffer, ba.Offset); data = MemBlock.Reference(ba.Buffer, ba.Offset, length); ba.AdvanceBuffer(length); } catch (System.Exception x) { throw new SendException(false, "could not write the packet, is it too big?", x); } finally { Interlocked.Exchange <BufferAllocator>(ref _ba, ba); } } else { data = MemBlock.Copy(payload); } } _n.HandleData(data, resp_send, this); } next_con = result.First; } //Send it on: if (next_con != null) { //Now we do the sending: var new_packet = new CopyList(PType.Protocol.AH, header.IncrementHops(), payload); try { next_con.State.Edge.Send(new_packet); } catch (SendException) { //Just drop the packet... } } }
/// <summary>Sends a packet from A to B returning the delay and hop count.</summary> public List<SendPacketResult> SendPacket(AHAddress from, AHAddress to, ushort option) { AHHeader ah = new AHHeader(0, 100, from, to, option); GraphNode cnode = _addr_to_node[from]; Edge cedge = null; AHAddress last_addr = from; Pair<Connection, bool> next = new Pair<Connection, bool>(null, false); int delay = 0; int hops = 0; var results = new List<SendPacketResult>(); while(true) { next = cnode.NextConnection(cedge, ah); if(next.Second) { results.Add(new SendPacketResult(last_addr, delay, hops)); } if(next.First == null) { break; } AHAddress caddress = next.First.Address as AHAddress; cnode = _addr_to_node[caddress]; cedge = cnode.ConnectionTable.GetConnection(next.First.MainType, last_addr).Edge; last_addr = caddress; delay += (cedge as GraphEdge).Delay; hops++; } return results; }
/** compute the next step in the route * @param from the Edge the packet came in on * @param head the header to route * @return next connection and bool indicating if local node should get * packet. If there is no next connection, the connection will be null */ public abstract Pair <Connection, bool> NextConnection(Edge from, AHHeader head);
/** * Here we handle routing AHPackets */ public void HandleData(MemBlock data, ISender ret_path, object st) { AHState state = _state; //Read the state, it can't change after the read var header = new AHHeader(data); var payload = data.Slice(header.Length); Connection next_con; //Check to see if we can use a Leaf connection: int dest_idx = state.Leafs.IndexOf(header.Destination); if( dest_idx >= 0 ) { next_con = state.Leafs[dest_idx]; } else { var alg = state.GetRoutingAlgo(header); Pair<Connection, bool> result = alg.NextConnection(ret_path as Edge, header); if( result.Second ) { //Send a response exactly back to the node that sent to us var resp_send = new AHSender(_n, ret_path, header.Source, AHSender.DefaultTTLFor(_n.NetworkSize), AHHeader.Options.Exact); _n.HandleData( payload, resp_send, this); } next_con = result.First; } //Send it on: if( next_con != null ) { //Now we do the sending: var new_packet = new CopyList(PType.Protocol.AH, header.IncrementHops(), payload); try { next_con.Edge.Send(new_packet); } catch(EdgeException) { //Just drop the packet... } } }
/// <summary>Constructor for a RelayEdge, RemoteID == -1 for out bound.</summary> public RelayEdge(IEdgeSendHandler send_handler, RelayTransportAddress local_ta, RelayTransportAddress remote_ta, IForwarderSelector ias, List<Connection> overlap, int remote_id) : base(send_handler, remote_id != -1) { _remote_id = remote_id; lock(_rand) { LocalID = _rand.Next(); } byte[] bid = new byte[8]; NumberSerializer.WriteInt(LocalID, bid, 0); NumberSerializer.WriteInt(_remote_id, bid, 4); _mid = MemBlock.Reference(bid); _local_ta = local_ta; _remote_ta = remote_ta; _tunnels = new List<Connection>(overlap); _ias = ias; _ias.Update(_tunnels); AHHeader ahh = new AHHeader(1, 20, local_ta.Target, remote_ta.Target, AHHeader.Options.Exact); ICopyable header = new CopyList(PType.Protocol.AH, ahh, PType.Protocol.Relaying); Header = MemBlock.Copy(header); }