public void HandleEdgeSend(Edge from, ICopyable p) { if (_ploss_prob > 0) { lock (_rand) { if (_rand.NextDouble() < _ploss_prob) { return; } } } MemBlock mb = p as MemBlock; if (mb == null) { lock (_sync) { int offset = p.CopyTo(_ba.Buffer, _ba.Offset); mb = MemBlock.Reference(_ba.Buffer, _ba.Offset, offset); _ba.AdvanceBuffer(offset); } } SimulationEdge se_from = (SimulationEdge)from; SimulationEdge se_to = se_from.Partner; if (se_to != null) { se_to.Push(mb); } }
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 void ListenThread() { Thread.CurrentThread.Name = "udp_listen_thread"; BufferAllocator ba = new BufferAllocator(8 + Int16.MaxValue); EndPoint end = new IPEndPoint(IPAddress.Any, 0); int rec_bytes = 0; MonitorLogSwitch(); ProtocolLog.Monitor.SwitchedSetting += MonitorLogSwitch; while (1 == _running) { int max = ba.Capacity; try { rec_bytes = _s.ReceiveFrom(ba.Buffer, ba.Offset, max, SocketFlags.None, ref end); } catch (SocketException x) { if ((1 == _running) && ProtocolLog.UdpEdge.Enabled) { ProtocolLog.Write(ProtocolLog.UdpEdge, x.ToString()); } } if (rec_bytes < 8) { continue; } int remoteid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset); int localid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset + 4); MemBlock packet_buffer = MemBlock.Reference(ba.Buffer, ba.Offset + 8, rec_bytes - 8); ba.AdvanceBuffer(rec_bytes); if (localid < 0) { // Negative ids are control messages HandleControlPacket(remoteid, localid, packet_buffer, end); } else { HandleDataPacket(remoteid, localid, packet_buffer, end, null); } } ProtocolLog.Monitor.SwitchedSetting -= MonitorLogSwitch; //Let everyone know we are out of the loop _listen_finished_event.Set(); _s.Close(); //Allow garbage collection _s = null; }
public void HandleEdgeSend(Edge from, ICopyable p) { SimulationEdge se_from = (SimulationEdge)from; if (!Nat.Outgoing(se_from.RemoteTA)) { return; } if (_ploss_prob > 0) { if (_rand.NextDouble() < _ploss_prob) { return; } } MemBlock mb = p as MemBlock; if (mb == null) { int offset = p.CopyTo(_ba.Buffer, _ba.Offset); mb = MemBlock.Reference(_ba.Buffer, _ba.Offset, offset); _ba.AdvanceBuffer(offset); _bytes += offset; } SimulationEdge se_to = se_from.Partner; if (se_to == null) { return; } if (!se_to.SimEL.Nat.Incoming(se_from.LocalTA)) { return; } se_to.Push(mb); }
/// <summary>The thread acting as the ISource for Ethernet, this is where /// reading of the TAP is performed. Use Subscribe to receive the packets /// coming from here.</summary> /// <remarks>The same max MTU byte array is always read into. This is then /// copied to a minimum sized MemBlock and send to the subscriber. </remarks> protected void ReadLoop() { byte[] read_buffer = new byte[MTU]; BufferAllocator ba = new BufferAllocator(MTU, 1.1); while (_running) { int length = -1; try { length = _tap.Read(read_buffer); } catch (ThreadInterruptedException x) { if (_running && ProtocolLog.Exceptions.Enabled) { ProtocolLog.Write(ProtocolLog.Exceptions, x.ToString()); } } catch (Exception e) { ProtocolLog.WriteIf(ProtocolLog.Exceptions, e.ToString()); } if (length == 0 || length == -1) { ProtocolLog.WriteIf(IpopLog.TapLog, "Couldn't read TAP"); continue; } Array.Copy(read_buffer, 0, ba.Buffer, ba.Offset, length); MemBlock packet = MemBlock.Reference(ba.Buffer, ba.Offset, length); ba.AdvanceBuffer(length); Subscriber s = _sub; if (s != null) { try { s.Handle(packet, this); } catch (Exception e) { ProtocolLog.WriteIf(ProtocolLog.Exceptions, e.ToString()); } } } }
/** * Do as much of a read as we can * @return true if the socket is still ready, false if we should close * the edge. */ public bool Receive() { int got = 0; int avail = 0; do { if (Buffer == null) { //Time to read the size: Reset(_ba.Buffer, _ba.Offset, 2, true); _ba.AdvanceBuffer(2); } try { got = _s.Receive(Buffer, CurrentOffset, RemainingLength, SocketFlags.None); avail = _s.Available; } catch (SocketException) { //Some OS error, just close the edge: Buffer = null; return(false); } if (got == 0) { //this means the edge is closed: return(false); } CurrentOffset += got; RemainingLength -= got; if (RemainingLength == 0) { //Time to do some action: if (ReadingSize) { short size = NumberSerializer.ReadShort(Buffer, Offset); if (size <= 0) { //This doesn't make sense, later we might use this to code //something else return(false); } //Start to read the packet and the duplicate size value at the //end Reset(_ba.Buffer, _ba.Offset, size + 2, false); _ba.AdvanceBuffer(size + 2); } else { try { short size = NumberSerializer.ReadShort(Buffer, Offset + Length - 2); if (size == Length - 2) { Edge.ReceivedPacketEvent(MemBlock.Reference(Buffer, Offset, size)); } else { //The packet seems to have an error: string err_msg = String.Format("ERROR Packet length mismatch: Edge: {0}; size: {1} != {2}; Packet: {3}", Edge, Length - 2, size, System.Convert.ToBase64String(Buffer, Offset, Length)); ProtocolLog.Write(ProtocolLog.Monitor, err_msg); //Close the edge return(false); } } catch (EdgeClosedException) { return(false); } finally { //Drop the reference and signal we are ready to read the next //size Buffer = null; } } } } while(avail > 0); return(true); }
/** * This is a System.Threading.ThreadStart delegate * We loop waiting for edges that need to send, * or data on the socket. * * This is the only thread that can touch the socket, * therefore, we do not need to lock the socket. */ protected void ListenThread() { Thread.CurrentThread.Name = "udp_listen_thread"; BufferAllocator ba = new BufferAllocator(8 + Int16.MaxValue); EndPoint end = new IPEndPoint(IPAddress.Any, 0); DateTime last_debug = DateTime.UtcNow; int debug_period = 5000; bool logging = ProtocolLog.Monitor.Enabled; int rec_bytes = 0; while(1 == _running) { if(logging) { DateTime now = DateTime.UtcNow; if(last_debug.AddMilliseconds(debug_period) < now) { last_debug = now; ProtocolLog.Write(ProtocolLog.Monitor, String.Format("I am alive: {0}", now)); } } int max = ba.Capacity; try { rec_bytes = _s.ReceiveFrom(ba.Buffer, ba.Offset, max, SocketFlags.None, ref end); } catch(SocketException x) { if((1 == _running) && ProtocolLog.UdpEdge.Enabled) { ProtocolLog.Write(ProtocolLog.UdpEdge, x.ToString()); } } if(rec_bytes < 8) { continue; } int remoteid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset); int localid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset + 4); MemBlock packet_buffer = MemBlock.Reference(ba.Buffer, ba.Offset + 8, rec_bytes - 8); ba.AdvanceBuffer(rec_bytes); if( localid < 0 ) { // Negative ids are control messages HandleControlPacket(remoteid, localid, packet_buffer, null); } else { HandleDataPacket(remoteid, localid, packet_buffer, end, null); } } //Let everyone know we are out of the loop _listen_finished_event.Set(); _s.Close(); //Allow garbage collection _s = null; }
/** * This is a System.Threading.ThreadStart delegate * We loop waiting for edges that need to send, * or data on the socket. * * This is the only thread that can touch the socket, * therefore, we do not need to lock the socket. */ protected void ListenThread() { Thread.CurrentThread.Name = "udp_listen_thread"; BufferAllocator ba = new BufferAllocator(8 + Int16.MaxValue); EndPoint end = new IPEndPoint(IPAddress.Any, 0); DateTime last_debug = DateTime.UtcNow; int debug_period = 5000; bool logging = ProtocolLog.Monitor.Enabled; int rec_bytes = 0; while (1 == _running) { if (logging) { DateTime now = DateTime.UtcNow; if (last_debug.AddMilliseconds(debug_period) < now) { last_debug = now; ProtocolLog.Write(ProtocolLog.Monitor, String.Format("I am alive: {0}", now)); } } int max = ba.Capacity; try { rec_bytes = _s.ReceiveFrom(ba.Buffer, ba.Offset, max, SocketFlags.None, ref end); } catch (SocketException x) { if ((1 == _running) && ProtocolLog.UdpEdge.Enabled) { ProtocolLog.Write(ProtocolLog.UdpEdge, x.ToString()); } } if (rec_bytes < 8) { continue; } int remoteid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset); int localid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset + 4); MemBlock packet_buffer = MemBlock.Reference(ba.Buffer, ba.Offset + 8, rec_bytes - 8); ba.AdvanceBuffer(rec_bytes); if (localid < 0) { // Negative ids are control messages HandleControlPacket(remoteid, localid, packet_buffer, null); } else { HandleDataPacket(remoteid, localid, packet_buffer, end, null); } } //Let everyone know we are out of the loop _listen_finished_event.Set(); _s.Close(); //Allow garbage collection _s = null; }
protected void ListenThread() { Thread.CurrentThread.Name = "udp_listen_thread"; BufferAllocator ba = new BufferAllocator(8 + Int16.MaxValue); EndPoint end = new IPEndPoint(IPAddress.Any, 0); int rec_bytes = 0; MonitorLogSwitch(); ProtocolLog.Monitor.SwitchedSetting += MonitorLogSwitch; while(1 == _running) { int max = ba.Capacity; try { rec_bytes = _s.ReceiveFrom(ba.Buffer, ba.Offset, max, SocketFlags.None, ref end); } catch(SocketException x) { if((1 == _running) && ProtocolLog.UdpEdge.Enabled) { ProtocolLog.Write(ProtocolLog.UdpEdge, x.ToString()); } } if(rec_bytes < 8) { continue; } int remoteid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset); int localid = NumberSerializer.ReadInt(ba.Buffer, ba.Offset + 4); MemBlock packet_buffer = MemBlock.Reference(ba.Buffer, ba.Offset + 8, rec_bytes - 8); ba.AdvanceBuffer(rec_bytes); if( localid < 0 ) { // Negative ids are control messages HandleControlPacket(remoteid, localid, packet_buffer, end); } else { HandleDataPacket(remoteid, localid, packet_buffer, end, null); } } ProtocolLog.Monitor.SwitchedSetting -= MonitorLogSwitch; //Let everyone know we are out of the loop _listen_finished_event.Set(); _s.Close(); //Allow garbage collection _s = null; }
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... } } }