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);
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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;
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        /// <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());
                    }
                }
            }
        }
Exemple #6
0
            /**
             * 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);
            }
Exemple #7
0
    /**
     * 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;
        }
Exemple #9
0
    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;
    }
Exemple #10
0
        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...
                }
            }
        }