Пример #1
0
        /*
         * Start sending packets
         */
        public void Run()
        {
            byte[] buf     = new byte[UInt16.MaxValue];
            Random ran_obj = new Random();

            for (int counter = 0; counter < count; counter++)
            {
                try {
                    int size = ran_obj.Next(4, Int16.MaxValue);
                    ran_obj.NextBytes(buf);
                    NumberSerializer.WriteInt(counter, buf, 0);
                    MemBlock cp = MemBlock.Copy(buf, 0, Math.Max(4, counter));
                    lock (_sync) { _sent_blocks[cp] = counter; }
                    _e.Send(cp);
                    Thread.Sleep(10);
                    Console.WriteLine("Sending Packet #: " + counter);
                }
                catch (Exception x) {
                    Console.WriteLine("send: {0} caused exception: {1}", counter, x);
                    break;
                }
            }
            //Let all the responses get back
            Thread.Sleep(5000);
            Check();
            _e.Close();
        }
Пример #2
0
        /// <summary>Writes an IPPacket as is to the TAP device.</summary>
        /// <param name="packet">The IPPacket!</param>
        protected virtual void WriteIP(ICopyable packet)
        {
            MemBlock mp = packet as MemBlock;

            if (mp == null)
            {
                mp = MemBlock.Copy(packet);
            }

            IPPacket ipp  = new IPPacket(mp);
            MemBlock dest = null;

            if (!_ip_to_ether.TryGetValue(ipp.DestinationIP, out dest))
            {
                if (ipp.DestinationIP[0] >= 224 && ipp.DestinationIP[0] <= 239)
                {
                    dest = EthernetPacket.GetMulticastEthernetAddress(ipp.DestinationIP);
                }
                else if (ipp.DestinationIP[3] == 255)
                {
                    dest = EthernetPacket.BroadcastAddress;
                }
                else
                {
                    return;
                }
            }

            EthernetPacket res_ep = new EthernetPacket(dest,
                                                       EthernetPacket.UnicastAddress, EthernetPacket.Types.IP, mp);

            Ethernet.Send(res_ep.ICPacket);
        }
Пример #3
0
        /// <summary>Constructor for a TunnelEdge, RemoteID == -1 for out bound.</summary>
        public TunnelEdge(IEdgeSendHandler send_handler, TunnelTransportAddress local_ta,
                          TunnelTransportAddress 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.Tunneling);

            Header = MemBlock.Copy(header);
        }
Пример #4
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);
        }
Пример #5
0
        override protected bool HandleIncoming(MemBlock data, out MemBlock app_data)
        {
            app_data = null;
            int count = 0;

            lock (_buffer_sync) {
                if (data != null)
                {
                    data.CopyTo(_buffer, 0);
                    _read.Write(_buffer, data.Length);
                }

                count = _ssl.Read(_buffer, _buffer.Length);
                if (count > 0)
                {
                    app_data = MemBlock.Copy(_buffer, 0, count);
                }
            }

            if (app_data != null)
            {
                // If the read was successful, Dtls has received an incoming data
                // message and decrypted it
                return(true);
            }
            else
            {
                SslError error = _ssl.GetError(count);
                if (error == SslError.SSL_ERROR_WANT_READ)
                {
                    if (SslState == SslState.OK)
                    {
                        UpdateState(States.Active);
                        // In the SslCtx verify, there's no way to get the underlying Sender
                        _ch.Verify(RemoteCertificate, Sender);
                    }
                    HandleWouldBlock();
                }
                else if (error == SslError.SSL_ERROR_SSL)
                {
                    var ose = new OpenSslException();
                    Close("Received unrecoverable error: " + ose.ToString());
                    throw ose;
                }
                else if (error == SslError.SSL_ERROR_ZERO_RETURN)
                {
                    Close("Received clean close notification");
                }
                else
                {
                    ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions,
                                        "Receive other: " + error);
                }
            }
            return(false);
        }
Пример #6
0
        /**
         * Read the address out of the buffer  This makes a copy
         * and calls Parse on the copy.  This is a "convienience" method.
         * @throw ParseException if the buffer is not a valid address
         */
        static public Address Parse(MemBlock mb)
        {
            //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
            ushort  idx = (ushort)NumberSerializer.ReadShort(mb, Address.MemSize - 3);
            Address a   = _mb_cache[idx];

            if (a != null)
            {
                if (a.ToMemBlock().Equals(mb))
                {
                    return(a);
                }
            }
            //Else we need to read the address and put it in the cache
            try {
                if (2 * mb.Length < mb.ReferencedBufferLength)
                {
                    /*
                     * This MemBlock is much smaller than the array
                     * we are referencing, don't keep the big one
                     * in scope, instead make a copy
                     */
                    mb = MemBlock.Copy((ICopyable)mb);
                }
                int add_class = Address.ClassOf(mb);
                switch (add_class)
                {
                case AHAddress.ClassValue:
                    a = new AHAddress(mb);
                    break;

                case DirectionalAddress.ClassValue:
                    a = new DirectionalAddress(mb);
                    break;

                default:
                    a = null;
                    throw new ParseException("Unknown Address Class: " +
                                             add_class + ", buffer:" +
                                             mb.ToString());
                }
                //Cache this result:
                _mb_cache[idx] = a;
                return(a);
            }
            catch (ArgumentOutOfRangeException ex) {
                throw new ParseException("Address too short: " +
                                         mb.ToString(), ex);
            }
            catch (ArgumentException ex) {
                throw new ParseException("Could not parse: " +
                                         mb.ToString(), ex);
            }
        }
Пример #7
0
        /**
         * This just announces the data with the current node
         * as the return path
         */
        public void Send(ICopyable data)
        {
            MemBlock mb = data as MemBlock;

            if (mb == null)
            {
                mb = MemBlock.Copy(data);
            }
            this.HandleData(mb, this, null);
        }
Пример #8
0
            public void Send(ICopyable data)
            {
                MemBlock mb = data as MemBlock;

                if (null == mb)
                {
                    mb = MemBlock.Copy(data);
                }
                Handle(mb, this);
            }
Пример #9
0
    /**
    <summary>The _listen_threads method, reads from sockets and let's the node
    handle the incoming data.</summary>
    */
    protected void Listen() {
      if (Thread.CurrentThread.Name == null) {
        Thread.CurrentThread.Name = "iphandler_thread";
      }
      ArrayList sockets = new ArrayList();
      sockets.Add(_uc);
      if(_mc != null) {
        sockets.Add(_mc);
      }

      byte[] buffer =  new byte[Int16.MaxValue];
      DateTime last_debug = DateTime.UtcNow;
      TimeSpan debug_period = TimeSpan.FromSeconds(5);
      while(1 == _running) {
        if (ProtocolLog.Monitor.Enabled) {
          DateTime now = DateTime.UtcNow;
          if (now - last_debug > debug_period) {
            last_debug = now;
            ProtocolLog.Write(ProtocolLog.Monitor, String.Format("I am alive: {0}", now));
          }
        }
        try {
          ArrayList readers = (ArrayList) sockets.Clone();
          Socket.Select(readers, null, null, 10000000); //10 seconds
          foreach(Socket socket in readers) {
            EndPoint ep = new IPEndPoint(IPAddress.Any, 0);
            int rec_bytes = socket.ReceiveFrom(buffer, ref ep);
            Subscriber s = _sub;
            //s can't change once we've read it.
            if( s != null && rec_bytes > 0) {
              MemBlock packet = MemBlock.Copy(buffer, 0, rec_bytes);
              MemBlock cookie = packet.Slice(0, 4);
              if(cookie.Equals(MagicCookie)) {
                packet = packet.Slice(4);
                ISender sender = CreateUnicastSender(ep);
                s.Handle(packet, sender);
              }
            }
          }
        }
        catch(ObjectDisposedException odx) {
          //If we are no longer running, this is to be expected.
          if(1 == _running) {
          //If we are running print it out
            ProtocolLog.WriteIf(ProtocolLog.Exceptions, odx.ToString());
          }
          break;
        }
        catch(Exception x) {
          if(0 == _running) {
            ProtocolLog.WriteIf(ProtocolLog.Exceptions, x.ToString());
          }
        }
      }
    }
Пример #10
0
        public void Send(ICopyable data)
        {
            //We always use the fragmenting header to signal
            //to the receiving end that we support (and want)
            //fragmentation.
            MemBlock rest = data as MemBlock;

            if (null == rest)
            {
                rest = MemBlock.Copy(data);
            }
            int len = rest.Length;

            if (len > MAX_SEND_SIZE)
            {
                throw new SendException(true,
                                        System.String.Format("Packet too large: {0}, MaxSize = {1}", len,
                                                             MAX_SEND_SIZE));
            }
            uint crc32 = rest.Read <uint>(Crc32.ComputeChecksum);
            //Avoid a RNG operation for now, might need to reconsider
            //If we use RNG, we have to touch state, that has thread-safety issues
            int id = _wrapped_sender.GetHashCode() ^ rest.GetHashCode();

            byte[] header = new byte[HEADER_SIZE - 2];
            int    off    = FragPType.CopyTo(header, 0);

            NumberSerializer.WriteInt((int)crc32, header, off);
            NumberSerializer.WriteInt(id, header, off + 4);
            MemBlock header_mb = MemBlock.Reference(header);

            ushort block     = 0;
            int    blocksize = ComputeBlockSize(len);

            while (rest.Length > 0)
            {
                int      this_size  = System.Math.Min(blocksize, rest.Length);
                MemBlock this_block = rest.Slice(0, this_size);
                rest = rest.Slice(this_size);
                //Check to see if this is the last block:
                if (rest.Length == 0)
                {
                    block = (ushort)(block ^ (0x8000)); //Set the highest bit, this is last
                }
                byte[] block_b = new byte[2];
                NumberSerializer.WriteShort((short)block, block_b, 0);
                MemBlock block_mb = MemBlock.Reference(block_b);

                _wrapped_sender.Send(new CopyList(header_mb, block_mb, this_block));
                block += 1;
            }
        }
        public void TestParse()
        {
            RSACryptoServiceProvider key = new RSACryptoServiceProvider();
            CertificateMaker         cm  = new CertificateMaker("United States", "UFL",
                                                                "ACIS", "David Wolinsky", "*****@*****.**", key,
                                                                "brunet:node:abcdefghijklmnopqrs");
            Certificate           cert = cm.Sign(cm, key);
            UserRevocationMessage urm  = new UserRevocationMessage(key, "David Wolinsky");
            UserRevocationMessage urm0 = new UserRevocationMessage(cert, MemBlock.Copy(urm));

            Assert.AreEqual(urm.Signature, urm0.Signature, "Signature");
            Assert.AreEqual(urm.Username, urm0.Username, "Username");
            Assert.AreEqual(urm.Hash, urm0.Hash, "Hash");
        }
Пример #12
0
        public virtual void Send(ICopyable data)
        {
            if (_rand.NextDouble() < _drop_rate)
            {
                return;
            }

            MemBlock mdata = data as MemBlock;

            if (mdata == null)
            {
                mdata = MemBlock.Copy(data);
            }

            for (int i = 0; i < _remove_n_ptypes; i++)
            {
                MemBlock payload = mdata;
                PType.Parse(mdata, out payload);
                mdata = payload;
            }
            Receiver.HandleData(mdata, ReturnPath, State);
        }
Пример #13
0
 /**
  * @deprecated
  * This makes a copy of b and initializes the AHAddress with
  * that value
  */
 public AHAddress(byte[] b, int off) : this(MemBlock.Copy(b, off, MemSize))
 {
     _prefix = (uint)NumberSerializer.ReadInt(_buffer, 0);
 }
Пример #14
0
        override protected bool HandleOutgoing(ICopyable app_data, out ICopyable data)
        {
            MemBlock buffer = null;

            data = null;
            int written = 1;

            lock (_buffer_sync) {
                if (app_data != null)
                {
                    int count = app_data.CopyTo(_buffer, 0);
                    written = _ssl.Write(_buffer, count);
                }

                if (written > 0)
                {
                    int count = _write.Read(_buffer, _buffer.Length);
                    if (count <= 0)
                    {
                        // This really shouldn't ever happen
                        ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, this + " error");
                        data = null;
                        return(false);
                    }

                    buffer = MemBlock.Copy(_buffer, 0, count);
                }
            }

            if (written > 0)
            {
                // Timer becomes -1 when there are no more control messages
                long to = _ssl.GetTimeout();
                if (to >= 0)
                {
                    HandleWouldBlock();
                }

                if (buffer != null)
                {
                    data = new CopyList(PType, Header, buffer);
                    return(true);
                }
            }

            // If the write failed, then Dtls is either waiting for a control message
            // or has a control message to send
            var error = _ssl.GetError(written);

            if (error == SslError.SSL_ERROR_WANT_READ)
            {
                HandleWouldBlock();
            }
            else if (error == SslError.SSL_ERROR_SSL)
            {
                var ose = new OpenSslException();
                Close("Received unrecoverable error: " + ose.ToString());
                throw ose;
            }
            else
            {
                ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, "Send other");
            }
            data = null;
            return(false);
        }
Пример #15
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...
                }
            }
        }