Inheritance: System.IComparable, System.ICloneable, ICopyable
示例#1
0
 public override bool Equals(object a)
 {
     if (a == null)
     {
         //If the other is null, clearly it's not equal to a non-null
         return(false);
     }
     if (this == a)
     {
         //Clearly we are the Equal to ourselves
         return(true);
     }
     if (a is byte[])
     {
         /**
          * @todo
          * This is very questionable to just treat byte[] as MemBlock,
          * because the hashcodes won't be equal, but we have code
          * that does this.  We should remove the assumption that MemBlock
          * can equal a byte[]
          */
         a = MemBlock.Reference((byte[])a);
     }
     if (this.GetHashCode() != a.GetHashCode())
     {
         //Hashcodes must be equal for the objects to be equal
         return(false);
     }
     else
     {
         return(this.CompareTo(a) == 0);
     }
 }
示例#2
0
    /// <summary>Parse a revocation message.</summary>
    public UserRevocationMessage(Certificate cacert, MemBlock data)
    {
      _data = data;

      int pos = 0;
      int length = 0;

      Username = AdrConverter.Deserialize(data, pos, out length) as string;
      pos += length;
      // Random number to reduce likelihood of malicious duplication of messages
      NumberSerializer.ReadInt(data, pos);
      pos += 4;
      // Verify that there is a date contained therein, perhaps we should verify the time
      new DateTime(NumberSerializer.ReadLong(data, pos));
      pos += 8;
      Signature = new byte[data.Length - pos];
      data.Slice(pos).CopyTo(Signature, 0);

      // hash the data
      SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
      Hash = sha1.ComputeHash(data, 0, data.Length - Signature.Length);

      if(!cacert.PublicKey.VerifyHash(Hash,
            CryptoConfig.MapNameToOID("SHA1"), Signature))
      {
        throw new Exception("Invalid UserRevocationMessage signature");
      }
    }
示例#3
0
        /**
         * Shorter MemBlocks are less than longer ones.  MemBlocks of identical
         * length are compared from first byte to last byte.  The first byte
         * that differs is compared to get the result of the function
         */
        public int CompareTo(object o)
        {
            if (this == o)
            {
                return(0);
            }
            MemBlock other = o as MemBlock;

            if (other == null)
            {
                byte[] data = o as byte[];
                if (data != null)
                {
                    other = MemBlock.Reference(data);
                }
                else
                {
                    //Put us ahead of all other types, this might not be smart
                    return(-1);
                }
            }
            int t_l = this.Length;
            int o_l = other.Length;

            if (t_l == o_l)
            {
                for (int i = 0; i < t_l; i++)
                {
                    byte t_b = this._buffer[this._offset + i];
                    byte o_b = other._buffer[other._offset + i];
                    if (t_b != o_b)
                    {
                        //OKAY! They are different:
                        if (t_b < o_b)
                        {
                            return(-1);
                        }
                        else
                        {
                            return(1);
                        }
                    }
                    else
                    {
                        //This position is equal, go to the next
                    }
                }
                //We must be equal
                return(0);
            }
            else if (t_l < o_l)
            {
                return(-1);
            }
            else
            {
                return(1);
            }
        }
示例#4
0
文件: DhtGet.cs 项目: pstjuste/brunet
 public DhtGet(Node node, MemBlock key, EventHandler enqueue,
     EventHandler close) : base(close)
 {
   Node = node;
   Key = key;
   _enqueue = enqueue;
   Results = new Queue<MemBlock>();
 }
示例#5
0
 //Too bad we can't use a template here, .Net generics *may* do the job
 public static int ReadInt(MemBlock mb, int offset)
 {
   int val = 0;
   for(int i = 0; i < 4; i++) {
     val = (val << 8) | mb[i + offset];
   }
   return val;
 }
示例#6
0
 /// <summary>Adds a local signed public certificate to this CH.</summary>
 public bool AddSignedCertificate(X509Certificate cert)
 {
     Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(cert.SerialNumber);
     lock (_sync) {
         _lc[sn] = cert;
         _lc_issuers.Add(sn);
     }
     return(true);
 }
示例#7
0
 public void HandleData(MemBlock b, ISender return_path, object state) {
   byte b0 = b[0];
   if( b0 == 0 ) {
     //This is a request:
     MemBlock data = b.Slice(1);
     //Make sure node to reply with a zero
     return_path.Send( new CopyList( PType.Protocol.Echo, REPLY_HEADER, data) );
   }
 }
示例#8
0
 public static float ReadFloat(MemBlock mb, int offset)
 {
     byte[] bin = new byte[4];
     for (int i = 0; i < 4; i++)
     {
         bin[i] = mb[offset + i];
     }
     return(ReadFloat(bin, 0));
 }
 /// <summary>Adds CA certificate to this CH.</summary>
 virtual public bool AddCACertificate(X509Certificate cert)
 {
     Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(cert.SerialNumber);
     lock (_sync) {
         _cas[sn] = cert;
         _supported_cas.Add(sn);
     }
     return(true);
 }
示例#10
0
文件: DhtPut.cs 项目: pstjuste/brunet
 public DhtPut(Node node, MemBlock key, MemBlock value, int ttl,
     EventHandler finished) : base(finished)
 {
   Node = node;
   Key = key;
   Value = value;
   Ttl = ttl;
   _result = null;
 }
示例#11
0
 public static double ReadDouble(MemBlock mb, int offset)
 {
     byte[] bin = new byte[8];
     for (int i = 0; i < 8; i++)
     {
         bin[i] = mb[offset + i];
     }
     return(ReadDouble(bin, 0));
 }
示例#12
0
 override public void HandleData(MemBlock data, ISender return_path, object state)
 {
   SecurityAssociation sa = return_path as SecurityAssociation;
   if(sa == null) {
     ProtocolLog.WriteIf(ProtocolLog.Exceptions, String.Format(
           "Insecure sender {0} sent ptype {1}", return_path, _ptype));
     return;
   }
   base.HandleData(data, return_path, state);
 }
示例#13
0
文件: Stun.cs 项目: pstjuste/brunet
 /// <summary>Create a new Attribute.</summary>
 public Attribute(AttributeType type, MemBlock value)
 {
   Type = type;
   Value = value;
   byte[] data = new byte[4 + value.Length];
   NumberSerializer.WriteUShort((ushort) type, data, 0);
   NumberSerializer.WriteUShort((ushort) value.Length, data, 2);
   value.CopyTo(data, 4);
   Data = MemBlock.Reference(data);
 }
示例#14
0
        // coded by hand for speed (profiled on mono)
        public static long ReadLong(MemBlock bin, int offset)
        {
            long val = 0;

            for (int i = 0; i < 8; i++)
            {
                val = (val << 8) | bin[i + offset];
            }
            return(val);
        }
示例#15
0
        //Too bad we can't use a template here, .Net generics *may* do the job
        public static int ReadInt(MemBlock mb, int offset)
        {
            int val = 0;

            for (int i = 0; i < 4; i++)
            {
                val = (val << 8) | mb[i + offset];
            }
            return(val);
        }
示例#16
0
 /** Parse the first LENGTH bytes to get the AHHeader
  */
 public AHHeader(MemBlock mb) {
   Hops = NumberSerializer.ReadShort(mb, 0);
   Ttl = NumberSerializer.ReadShort(mb, 2);
   //We parse the Address objects lazily
   Opts = (ushort)NumberSerializer.ReadShort(mb, 2 * Address.MemSize + 4);
   if( mb.Length != LENGTH ) {
     mb = mb.Slice(0,LENGTH);
   }
   _data = mb;
 }
示例#17
0
 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;
 }
示例#18
0
 /**
  * This handles the packet forwarding protocol
  */
 public void HandleData(MemBlock b, ISender ret_path, object state)
 {
   /*
    * Check it
    */
   AHSender ahs = ret_path as AHSender;
   if( ahs != null ) {
     //This was an AHSender:
     /*
      * This goes A -> B -> C
      */
     if( b[0] == 0 ) {
       int offset = 1;
       //This is the first leg, going from A->B
       Address add_c = AddressParser.Parse(b.Slice(offset, Address.MemSize));
       offset += Address.MemSize;
       //Since ahs a sender to return, we would be the source:
       Address add_a = ahs.Destination;
       short ttl = NumberSerializer.ReadShort(b, offset);//2 bytes
       offset += 2;
       ushort options = (ushort) NumberSerializer.ReadShort(b, offset);//2 bytes
       offset += 2;
       MemBlock payload = b.Slice(offset);
       MemBlock f_header = MemBlock.Reference( new byte[]{1} );
       /*
        * switch the packet from [A B f0 C] to [B C f 1 A]
        */
       ICopyable new_payload = new CopyList(PType.Protocol.Forwarding,
                                        f_header, add_a, payload);
       /*
        * ttl and options are present in the forwarding header.
        */
       AHSender next = new AHSender(_n, ahs.ReceivedFrom, add_c,
                                    ttl,
                                    options); 
       next.Send(new_payload);
     }
     else if ( b[0] == 1 ) {
       /*
        * This is the second leg: B->C
        * Make a Forwarding Sender, and unwrap the inside packet
        */
       Address add_a = AddressParser.Parse(b.Slice(1, Address.MemSize));
       Address add_b = ahs.Destination;
       MemBlock rest_of_payload = b.Slice(1 + Address.MemSize);
       //Here's the return path:
       ISender new_ret_path = new ForwardingSender(_n, add_b, add_a);
       _n.HandleData(rest_of_payload, new_ret_path, this);
     }
   }
   else {
     //This is not (currently) supported.
     Console.Error.WriteLine("Got a forwarding request from: {0}", ret_path);
   }
 }
示例#19
0
 public DirectionalAddress(MemBlock mb)
 {
   if (ClassOf(mb) != this.Class) {
     throw new System.
     ArgumentException
     ("This is not an AHAddress (Class 124) :  ",
      this.ToString());
   }
   _buffer = mb;
   _dir = (Direction) NumberSerializer.ReadInt(mb, 0);
 }
示例#20
0
 public void HandleData(MemBlock data, ISender return_path, object state)
 {
   MemBlock user_data;
   // Parse BroadcastSender
   BroadcastSender bs = BroadcastSender.Parse(Node, data, out user_data);
   // Present the packet to the local handler
   BroadcastReceiver br = new BroadcastReceiver(bs);
   Node.HandleData(user_data, br, null);
   // Broadcast to the next hop
   bs.Send(user_data);
 }
示例#21
0
        public void StringTests()
        {
            string   test_ascii = "Hello simple test";
            MemBlock b          = MemBlock.Reference(System.Text.Encoding.UTF8.GetBytes(test_ascii));

            Assert.IsTrue(b.IsAscii(0, b.Length), "IsAscii");
            string test_unicode = "la\u00dfen";

            b = MemBlock.Reference(System.Text.Encoding.UTF8.GetBytes(test_unicode));
            Assert.IsFalse(b.IsAscii(0, b.Length), "Unicode not ascii");
        }
        /// <summary>Adds a local signed public certificate to this CH.</summary>
        virtual public bool AddSignedCertificate(X509Certificate cert)
        {
            if (_local_id != String.Empty && !Verify(cert, _local_id))
            {
                throw new Exception("Invalid certificate: " + cert);
            }

            Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(cert.SerialNumber);
            lock (_sync) {
                _lc[sn] = cert;
                _lc_issuers.Add(sn);
            }
            return(true);
        }
示例#23
0
    public ConnectionHandler(PType ptype, StructuredNode node)
    {
      _node = node;
      _ondemand = new OnDemandConnectionOverlord(node);
      _node.AddConnectionOverlord(_ondemand);
      _ptype = ptype;
      _ptype_mb = ptype.ToMemBlock();
      _address_to_sender = new Dictionary<Address, ISender>();
      _sender_to_address = new Dictionary<ISender, Address>();

      node.GetTypeSource(_ptype).Subscribe(this, null);
      node.ConnectionTable.ConnectionEvent += HandleConnection;
      node.ConnectionTable.DisconnectionEvent += HandleDisconnection;
    }
示例#24
0
        public void SomeInsanityTests()
        {
            byte[]   data;
            bool     got_x;
            MemBlock b;

            System.Random r = new System.Random();
            for (int i = 0; i < 100; i++)
            {
                int size = r.Next(1024);
                data = new byte[size];
                r.NextBytes(data);
                int overshoot = r.Next(1, 1024);
                got_x = false;
                b     = null;
                try {
                    //Should throw an exception:
                    b = MemBlock.Reference(data, 0, size + overshoot);
                }
                catch {
                    got_x = true;
                }
                Assert.IsNull(b, "Reference failure test");
                Assert.IsTrue(got_x, "Exception catch test");

                overshoot = r.Next(1, 1024);
                got_x     = false;
                b         = MemBlock.Reference(data);
                try {
                    //Should throw an exception:
                    byte tmp = b[size + overshoot];
                }
                catch {
                    got_x = true;
                }
                Assert.IsTrue(got_x, "index out of range exception");
                got_x = false;
                try {
                    //Should throw an exception:
                    byte tmp = b[b.Length];
                }
                catch {
                    got_x = true;
                }
                Assert.IsTrue(got_x, "index out of range exception");
            }
        }
示例#25
0
 public void HandleData(MemBlock b, ISender from, object state) {
   MemBlock payload = null;
   PType t = null;
   try {
     t = PType.Parse(b, out payload);
     if(t.Equals(PType.Protocol.ReqRep)) {
       _rrm.HandleData(payload, from, state);
     }
     else if(t.Equals(PType.Protocol.Rpc)) {
       Rpc.HandleData(payload, from, state);
     }
   }
   catch(Exception x) {
     Console.Error.WriteLine("Packet Handling Exception: {3}\n\tType: {0}\n\t\n\tFrom: {1}\n\tData: {2}",
       t, from, payload.GetString(System.Text.Encoding.ASCII), x);
   }
 }
示例#26
0
    /// <summary>Uses the Dht for the bootstrap problem.</summary>
    /// <param name="node">The node needing remote tas.</param>
    /// <param name="dht">The dht for the shared overlay.</param>
    /// <param name="dht_proxy">A dht proxy for the shared overlay.</param>
    public DhtDiscovery(StructuredNode node, IDht dht, string shared_namespace,
        RpcDhtProxy dht_proxy) :
      base(node)
    {
      _dht = dht;
      _dht_proxy = dht_proxy;
      _node = node;
      _shared_namespace = shared_namespace;
      string skey = "PrivateOverlay:" + node.Realm;
      byte[] bkey = Encoding.UTF8.GetBytes(skey);
      _p2p_address = node.Address.ToMemBlock();
      _private_dht_key = MemBlock.Reference(bkey);

      _ongoing = 0;
      _steady_state = 0;
      _dht_proxy.Register(_private_dht_key, _p2p_address, PUT_DELAY_S);
    }
示例#27
0
文件: Group.cs 项目: pstjuste/brunet
    public GroupGraph(int count, int near, int shortcuts, int random_seed,
        List<List<int>> dataset, int group_count) :
      base(count, near, shortcuts, random_seed, dataset)
    {
      if(group_count > count || group_count < 0) {
        throw new Exception("Invalid group count: " + group_count);
      }

      _group_members = new List<GraphNode>();

      for(int i = 0; i < group_count; i++) {
        int index = _rand.Next(0, count);
        AHAddress addr = _addrs[index];
        _group_members.Add(_addr_to_node[addr]);
      }

      _group_identifier = GenerateAddress().ToMemBlock();
    }
    /// <summary>Parses an incoming revocation and updates the revoked users
    /// hashtable if successful.</summary>
    public void HandleData(MemBlock data, ISender ret, object state)
    {
      UserRevocationMessage urm = null;
      try {
        urm = new UserRevocationMessage(_ca_cert, data);
      } catch(Exception e) {
        ProtocolLog.WriteIf(ProtocolLog.SecurityExceptions, e.ToString());
        return;
      }


      lock(_revoked_users) {
        if(_revoked_users.Contains(urm.Username)) {
          return;
        }
        _revoked_users[urm.Username] = true;
      }

      _so.VerifySAs();
    }
示例#29
0
        /**
         * This method is used by subclasses.
         * @param b the packet to send a ReceivedPacket event for
         */
        public void ReceivedPacketEvent(BU.MemBlock b)
        {
            if (1 == _is_closed)
            {
                //We should not be receiving packets on closed edges:
                throw new EdgeClosedException(
                          String.Format("Trying to Receive on a Closed Edge: {0}",
                                        this));
            }
            try {
                _sub.Handle(b, this);
                Interlocked.Exchange(ref _last_in_packet_datetime, DateTime.UtcNow.Ticks);
            }
            catch (System.NullReferenceException) {
                //this can happen if _sub is null
                //We don't record the time of this packet.  We don't
                //want unhandled packets to keep edges open.
                //
                //This packet is going into the trash:
//        Console.Error.WriteLine("{0} lost packet {1}",this,b.ToBase16String());
            }
        }
示例#30
0
    /// <summary>Create a new revocation message.</summary>
    public UserRevocationMessage(RSACryptoServiceProvider private_key, string username)
    {
      Username = username;
      int signature_length = private_key.KeySize / 8;
      byte[] data = null;

      using(MemoryStream ms = new MemoryStream()) {
        AdrConverter.Serialize(Username, ms);
        Random rand = new Random();
        NumberSerializer.WriteInt(rand.Next(), ms);
        NumberSerializer.WriteLong(DateTime.UtcNow.Ticks, ms);
        data = new byte[ms.Length + signature_length];
        ms.Position = 0;
        ms.Read(data, 0, (int) ms.Length);
      }

      SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
      Hash = sha1.ComputeHash(data, 0, data.Length - signature_length);
      Signature = private_key.SignHash(Hash, CryptoConfig.MapNameToOID("SHA1"));
      Signature.CopyTo(data, data.Length - signature_length);
      _data = MemBlock.Reference(data);
    }
示例#31
0
        public static string ReadString(MemBlock b, int offset, out int bytelength)
        {
            int null_idx   = b.IndexOf(0, offset);
            int raw_length = null_idx - offset;

            bytelength = raw_length + 1; //One for the null
            Encoding e;

            /*
             * Benchmarks of mono show this to be about twice as fast as just
             * using UTF8.  That really means UTF8 could be optimized in mono
             */
            if (b.IsAscii(offset, raw_length))
            {
                e = Encoding.ASCII;
            }
            else
            {
                e = Encoding.UTF8;
            }
            return(b.GetString(e, offset, raw_length));
        }
        protected void StartQueueProcessing()
        {
            /*
             * Simulate packet loss
             */
            Random r = new Random();

            try {
                bool timedout;
                while (1 == _is_started)
                {
                    FQEntry ent = (FQEntry)_queue.Dequeue(-1, out timedout);
                    if (r.NextDouble() > _ploss_prob)
                    {
                        //Stop in this case
                        if (ent.P == null)
                        {
                            return;
                        }
                        FunctionEdge fe           = ent.Edge;
                        BU.MemBlock  data_to_send = ent.P as BU.MemBlock;
                        if (data_to_send == null)
                        {
                            data_to_send = BU.MemBlock.Copy(ent.P);
                        }
                        try {
                            fe.ReceivedPacketEvent(data_to_send);
                        }
                        catch (EdgeClosedException) {
                            //The edge may have closed, just ignore it
                        }
                    }
                }
            }
            catch (InvalidOperationException) {
                // The queue has been closed
            }
        }
示例#33
0
 public MemBlock ToMemBlock()
 {
     if (_raw_data != null)
     {
         return(_raw_data);
     }
     //Else make it:
     if (IsValidNumeric(_type_num))
     {
         byte[] buf = new byte[1];
         buf[0]    = (byte)_type_num;
         _raw_data = MemBlock.Reference(buf);
     }
     else
     {
         //It's a string type:
         int    l   = NumberSerializer.GetByteCount(_string_rep);
         byte[] buf = new byte[l];
         NumberSerializer.WriteString(_string_rep, buf, 0);
         _raw_data = MemBlock.Reference(buf);
     }
     return(_raw_data);
 }
        /// <summary>True if this certificate is signed by a CA whose cetificate
        /// we have, false otherwise.</summary>
        public bool Verify(X509Certificate x509, ISender sender)
        {
            Brunet.Util.MemBlock sn = Brunet.Util.MemBlock.Reference(x509.SerialNumber);
            lock (_sync) {
                if (!_cas.ContainsKey(sn))
                {
                    throw new Exception("Unsupported CA!");
                }
                if (!x509.VerifySignature(_cas[sn].RSA))
                {
                    throw new Exception("Unable to verify certificate, bad signature!");
                }
            }

            foreach (ICertificateVerification icv in _certificate_verifiers)
            {
                if (!icv.Verify(x509, sender))
                {
                    throw new Exception("Certificate not valid, reason unsure");
                }
            }

            return(true);
        }
示例#35
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);
  }
示例#36
0
 public static float ReadFloat(MemBlock mb)
 {
     return(ReadFloat(mb, 0));
 }
示例#37
0
 /*
  * Handle the data from our underlying edge
  */
 public void HandleData(MemBlock b, ISender ret, object state) {
   MemBlock tmp = b.Slice(0, PType.Protocol.Pathing.Length);
   if(tmp.Equals(PType.Protocol.Pathing.ToMemBlock())) {
     _pem.HandleData(b, ret, null);
     return;
   }
   ReceivedPacketEvent(b);
 }
示例#38
0
    /** Handle incoming data on an Edge 
     */
    public void HandleData(MemBlock data, ISender retpath, object state) {
      MemBlock rest_of_data;
      PType p;

      if( state == null ) {
        try {
          p = PType.Parse(data, out rest_of_data);
        } catch(ParseException) {
          ProtocolLog.WriteIf(ProtocolLog.Pathing, "Invalid PType from: " + data);
          return;
        }
        p = PType.Parse(data, out rest_of_data);
      }
      else {
        //a demux has already happened:
        p = (PType)state;
        rest_of_data = data;
      }

      if( PType.Protocol.Pathing.Equals(p) ) {
        /*
         * We use a special PType to denote this transaction so
         * we don't confuse it with other RepRep communication
         */
        _rrm.HandleData(rest_of_data, retpath, null);
      }
      else if( PType.Protocol.Rpc.Equals(p) ) {
       /*
        * Send this to the RpcHandler
        */
       Rpc.HandleData(rest_of_data, retpath, null);
      }
      else {
        /*
         * This is some other data
         * It is either:
         * 1) Time to announce an already created edge.
         * 2) Assume this is a "default path" edge creation, to be backwards
         * compatible
         */
        Edge e = null;
        PathEdge pe = null;
        try {
          e = (Edge)retpath;
          PathEdgeListener pel = null;
          lock( _sync ) {
            if( _unannounced.TryGetValue(e, out pe) ) {
              //
              _unannounced.Remove(e);
              pel = _pel_map[pe.LocalPath];
            }
          }
          if( pe == null ) {
            if(! _pel_map.ContainsKey(Root) ) {
              ProtocolLog.WriteIf(ProtocolLog.Pathing, "No root, can't create edge");
              if(e != null) {
                e.Close();
              }
              return;
            }
            /*
             * This must be a "default path" incoming connection
             */
            pel = _pel_map[Root];
            pe = new PathEdge(this, e, Root, Root);
          }
          pel.SendPathEdgeEvent(pe);
          pe.Subscribe();
          pe.ReceivedPacketEvent(data);
        }
        catch(Exception x) {
          if( pe != null ) {
            //This closes both edges:
            pe.Close();  
          }
          else if( e != null ) {
            ProtocolLog.WriteIf(ProtocolLog.Pathing,
                String.Format("Closing ({0}) due to: {1}", e, x));
            e.Close();  
          }
        }
      }
    }
示例#39
0
    /**
     * This reads a packet from buf which came from end, with
     * the given ids
     */
    protected void HandleDataPacket(int remoteid, int localid,
                                    MemBlock packet, EndPoint end, object state)
    {
      bool read_packet = true;
      bool is_new_edge = false;
      //It is threadsafe to read from Hashtable
      UdpEdge edge = (UdpEdge)_id_ht[localid];
      if( localid == 0 ) {
        //This is a potentially a new incoming edge
        is_new_edge = true;

        //Check to see if it is a dup:
        UdpEdge e_dup = (UdpEdge)_remote_id_ht[remoteid];
        if( e_dup != null ) {
          //Lets check to see if this is a true dup:
          if( e_dup.End.Equals( end ) ) {
            //Same id from the same endpoint, looks like a dup...
            is_new_edge = false;
            //Reuse the existing edge:
            edge = e_dup;
          }
          else {
            //This is just a coincidence.
          }
        }
        if( is_new_edge ) {
          TransportAddress rta = TransportAddressFactory.CreateInstance(this.TAType,(IPEndPoint)end);
          if( _ta_auth.Authorize(rta) == TAAuthorizer.Decision.Deny ) {
            //This is bad news... Ignore it...
            ///@todo perhaps we should send a control message... I don't know
            is_new_edge= false;
            read_packet = false;
            if(ProtocolLog.UdpEdge.Enabled)
              ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
                "Denying: {0}", rta));
          }
          else {
            //We need to assign it a local ID:
            lock( _id_ht ) {
              /*
               * Now we need to lock the table so that it cannot
               * be written to by anyone else while we work
               */
              do {
                localid = _rand.Next();
                //Make sure not to use negative ids
                if( localid < 0 ) { localid = ~localid; }
              } while( _id_ht.Contains(localid) || localid == 0 );
              /*
               * We copy the endpoint because (I think) .Net
               * overwrites it each time.  Since making new
               * edges is rare, this is better than allocating
               * a new endpoint each time
               */
              IPEndPoint this_end = (IPEndPoint)end;
              IPEndPoint my_end = new IPEndPoint(this_end.Address,
                                                 this_end.Port);
              edge = new UdpEdge(_send_handler, true, my_end,
                             _local_ep, localid, remoteid);
              _id_ht[localid] = edge;
              _remote_id_ht[remoteid] = edge;
            }
          }
        }
      }
      else if ( edge == null ) {
        /*
         * This is the case where the Edge is not a new edge,
         * but we don't know about it.  It is probably an old edge
         * that we have closed.  We can ignore this packet
         */
        read_packet = false;
         //Send a control packet
        SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state);
      }
      else if ( edge.RemoteID == 0 ) {
        /* This is the response to our edge creation */
        edge.RemoteID = remoteid;
      }
      else if( edge.RemoteID != remoteid ) {
        /*
         * This could happen as a result of packet loss or duplication
         * on the first packet.  We should ignore any packet that
         * does not have both ids matching.
         */
        read_packet = false;
         //Tell the other guy to close this ignored edge
        SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state);
        edge = null;
      }
      if( (edge != null) && !edge.End.Equals(end) ) {
        //This happens when a NAT mapping changes
        if(ProtocolLog.UdpEdge.Enabled)
          ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
            "Remote NAT Mapping changed on Edge: {0}\n{1} -> {2}",
            edge, edge.End, end)); 
        //Actually update:
        TransportAddress rta = TransportAddressFactory.CreateInstance(this.TAType,(IPEndPoint)end);
        if( _ta_auth.Authorize(rta) != TAAuthorizer.Decision.Deny ) {
          IPEndPoint this_end = (IPEndPoint) end;
          edge.End = new IPEndPoint(this_end.Address, this_end.Port);
          NatDataPoint dp = new RemoteMappingChangePoint(DateTime.UtcNow, edge);
          Interlocked.Exchange<NatHistory>(ref _nat_hist, _nat_hist + dp);
          Interlocked.Exchange<IEnumerable>(ref _nat_tas, new NatTAs( _tas, _nat_hist ));
          //Tell the other guy:
          SendControlPacket(end, remoteid, localid, ControlCode.EdgeDataAnnounce, state);
        }
        else {
          /*
           * Looks like the new TA is no longer authorized.
           */
          SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state);
          RequestClose(edge);
          CloseHandler(edge, null);
        }
      }
      if( is_new_edge ) {
        try {
          NatDataPoint dp = new NewEdgePoint(DateTime.UtcNow, edge);
          Interlocked.Exchange<NatHistory>(ref _nat_hist, _nat_hist + dp);
          Interlocked.Exchange<IEnumerable>(ref _nat_tas, new NatTAs( _tas, _nat_hist ));
          edge.CloseEvent += this.CloseHandler;
          //If we make it here, the edge wasn't closed, go ahead and process it.
          SendEdgeEvent(edge);
          // Stun support
          SendControlPacket(end, remoteid, localid, ControlCode.EdgeDataAnnounce, state);
        }
        catch {
          //Make sure this edge is closed and we are done with it.
          RequestClose(edge);
          CloseHandler(edge, null);
          read_packet = false;
          //This was a new edge, so the other node has our id as zero, send
          //with that localid:
          SendControlPacket(end, remoteid, 0, ControlCode.EdgeClosed, state);
        }
      }
      if( read_packet ) {
        //We have the edge, now tell the edge to announce the packet:
        try {
          edge.ReceivedPacketEvent(packet);
        }
        catch(EdgeClosedException) {
          SendControlPacket(end, remoteid, localid, ControlCode.EdgeClosed, state);
          //Make sure we record that this edge has been closed
          CloseHandler(edge, null);
        }
      }
    }
示例#40
0
    /**
     * This handles lightweight control messages that may be sent
     * by UDP
     */
    protected void HandleControlPacket(int remoteid, int n_localid,
                                       MemBlock buffer, object state)
    {
      int local_id = ~n_localid;
      UdpEdge e = _id_ht[local_id] as UdpEdge;
      if(e == null) {
        return;
      }

      if(e.RemoteID == 0) {
        try {
          e.RemoteID = remoteid;
        } catch {
          return;
        }
      }

      if(e.RemoteID != remoteid) {
        return;
      }

      try {
        ControlCode code = (ControlCode)NumberSerializer.ReadInt(buffer, 0);
        if(ProtocolLog.UdpEdge.Enabled)
          ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
            "Got control {1} from: {0}", e, code));
        if( code == ControlCode.EdgeClosed ) {
          //The edge has been closed on the other side
          RequestClose(e);
          CloseHandler(e, null);
        }
        else if( code == ControlCode.EdgeDataAnnounce ) {
          //our NAT mapping may have changed:
          IDictionary info =
            (IDictionary)AdrConverter.Deserialize( buffer.Slice(4) );
          string our_local_ta = (string)info["RemoteTA"]; //his remote is our local
          if( our_local_ta != null ) {
            //Update our list:
            TransportAddress new_ta = TransportAddressFactory.CreateInstance(our_local_ta);
            TransportAddress old_ta = e.PeerViewOfLocalTA;
            if( ! new_ta.Equals( old_ta ) ) {
              if(ProtocolLog.UdpEdge.Enabled)
                ProtocolLog.Write(ProtocolLog.UdpEdge, String.Format(
                  "Local NAT Mapping changed on Edge: {0}\n{1} => {2}",
               e, old_ta, new_ta));
              //Looks like matters have changed:
              this.UpdateLocalTAs(e, new_ta);
              /**
               * @todo, maybe we should ping the other edges sharing this
               * EndPoint, but we need to be careful not to do some O(E^2)
               * operation, which could easily happen if each EdgeDataAnnounce
               * triggered E packets to be sent
               */
            }
          }
        }
        else if( code == ControlCode.Null ) {
          //Do nothing in this case
        }
      }
      catch(Exception x) {
      //This could happen if this is some control message we don't understand
        if(ProtocolLog.Exceptions.Enabled)
          ProtocolLog.Write(ProtocolLog.Exceptions, x.ToString());
      }
    }
示例#41
0
        public void Test()
        {
            //8 is long enough to hold all the numbers:
            byte[]        buffer = new byte[8];
            System.Random r      = new System.Random();
            int           tests  = 100;

            //Here are shorts:
            for (int i = 0; i < tests; i++)
            {
                short val = (short)r.Next(Int16.MaxValue);
                WriteShort(val, buffer, 0);
                Assert.AreEqual(val, ReadShort(buffer, 0));
            }
            //Ints:
            for (int i = 0; i < tests; i++)
            {
                int val = r.Next();
                WriteInt(val, buffer, 0);
                Assert.AreEqual(val, ReadInt(buffer, 0));
            }
            //Longs:
            for (int i = 0; i < tests; i++)
            {
                long val = r.Next();
                val <<= 4;
                val  |= r.Next();
                WriteLong(val, buffer, 0);
                Assert.AreEqual(val, ReadLong(buffer, 0));
            }
            //Floats:
            for (int i = 0; i < tests; i++)
            {
                float val = (float)r.NextDouble();
                WriteFloat(val, buffer, 0);
                Assert.AreEqual(val, ReadFloat(buffer, 0));
            }
            //Doubles:
            for (int i = 0; i < tests; i++)
            {
                double val = r.NextDouble();
                WriteDouble(val, buffer, 0);
                Assert.AreEqual(val, ReadDouble(buffer, 0));
            }
            //Strings:
            for (int i = 0; i < tests; i++)
            {
                byte[] bin = new byte[1000];
                r.NextBytes(bin);
                //Here's a random ascii string:
                string s = Base32.Encode(bin);
                if (i % 2 == 0)
                {
                    //Half the time make sure there is some unicode bit:
                    s = s + "la\u00dfen";
                }
                byte[] enc      = Encoding.UTF8.GetBytes(s);
                byte[] enc_null = new byte[enc.Length + 1];
                Array.Copy(enc, 0, enc_null, 0, enc.Length);
                enc_null[enc.Length] = 0;
                int    l;
                string s2 = ReadString(enc_null, 0, out l);
                Assert.AreEqual(s, s2, "byte[] readstring");
                Assert.AreEqual(l, enc_null.Length, "byte[] string length");
                string s3 = ReadString(MemBlock.Reference(enc_null), 0, out l);
                Assert.AreEqual(s, s3, "byte[] readstring");
                Assert.AreEqual(l, enc_null.Length, "byte[] string length");
            }

            /*
             * Round tripping is great, but we still might have some
             * brain damage: we could be cancel out the error when reading
             * the data back in.
             */
            Assert.AreEqual((short)511, ReadShort(new byte[] { 1, 255 }, 0));
            Assert.AreEqual((short)511,
                            ReadShort(new MemoryStream(new byte[] { 1, 255 })));
            Assert.AreEqual((short)1535, ReadShort(new byte[] { 5, 255 }, 0));
            Assert.AreEqual((short)1535,
                            ReadShort(new MemoryStream(new byte[] { 5, 255 })));
            Assert.AreEqual(43046721,
                            ReadInt(new byte[] { 2, 144, 215, 65 }, 0));
            Assert.AreEqual(43046721,
                            ReadInt(new MemoryStream(new byte[] { 2, 144, 215, 65 })));
            Assert.AreEqual(59296646043258912L,
                            ReadLong(new byte[] { 0, 210, 169, 252, 67, 199, 208, 32 }, 0));
            Assert.AreEqual(59296646043258912L,
                            ReadLong(new MemoryStream(new byte[] { 0, 210, 169, 252, 67, 199, 208, 32 })));
        }
示例#42
0
 public bool HandleReply(ReqrepManager man, ReqrepManager.ReqrepType rt,
                int mid,
                PType prot,
                MemBlock payload, ISender returnpath,
                ReqrepManager.Statistics statistics,
                object state) {
   DateTime reply_time = DateTime.UtcNow;
   
   ListDictionary res_dict = new ListDictionary();
   AHSender ah_rp = returnpath as AHSender;
   if( ah_rp != null ) {
     res_dict["target"] = ah_rp.Destination.ToString();
   }
   //Here are the number of microseconds
   res_dict["musec"] = (int)( 1000.0 * ((reply_time - _start_time).TotalMilliseconds) );
   //Send the RPC result now;
   RpcManager my_rpc = System.Threading.Interlocked.Exchange(ref _rpc, null);
   if( my_rpc != null ) {
     //We have not sent any reply yet:
     my_rpc.SendResult(_req_state, res_dict);
   }
   return false;
 }
示例#43
0
 public static short ReadShort(MemBlock bin, int offset)
 {
     return((short)((bin[offset] << 8) | bin[offset + 1]));
 }
示例#44
0
 public static double ReadDouble(MemBlock mb)
 {
     return(ReadDouble(mb, 0));
 }
示例#45
0
        public void Test()
        {
            System.Random r = new System.Random();

            byte[] data;
            for (int i = 0; i < 100; i++)
            {
                data = new byte[r.Next(1024)];
                r.NextBytes(data);
                int      offset = r.Next(data.Length);
                MemBlock mb1    = new MemBlock(data, 0, data.Length);
                MemBlock mb1a   = MemBlock.Copy(data, 0, data.Length);
                Assert.IsTrue(mb1.Equals(mb1a), "MemBlock.Copy");
                Assert.IsTrue(mb1.Equals(data), "MemBlock == byte[]");
                MemBlock mb2  = new MemBlock(data, offset, data.Length - offset);
                MemBlock mb2a = mb1.Slice(offset);
                MemBlock mb3  = new MemBlock(data, 0, offset);
                MemBlock mb3a = mb1.Slice(0, offset);
                Assert.IsTrue(mb3.Equals(mb3a), "mb3.Equals(mb3a)");
                Assert.IsTrue(mb3a.Equals(mb3), "mb3a.Equals(mb3)");
                Assert.IsTrue(mb3.CompareTo(mb2) + mb2.CompareTo(mb3) == 0, "CompareTo");
                Assert.IsTrue(mb2.Equals(mb2a), "mb2.Equals(mb2a)");
                Assert.IsTrue(mb2a.Equals(mb2), "mb2a.Equals(mb2)");

                MemBlock cat  = MemBlock.Concat(mb3, mb2);
                MemBlock cata = MemBlock.Concat(mb3a, mb2a);
                Assert.IsTrue(cat.Equals(cata), "Concat Equals");
                Assert.IsTrue(cata.Equals(cat), "Concat a Equals");
                Assert.IsTrue(mb1.Equals(cat), "Concat Equals Original");
                if (offset != 0)
                {
                    //These should not be equal
                    Assert.IsFalse(mb2.Equals(mb1), "mb2 != mb1");
                }
                int    mb2a_l   = mb2a.Length;
                byte[] tmp_data = new byte[mb2a_l];
                mb2a.CopyTo(tmp_data, 0);
                MemBlock mb2b = new MemBlock(tmp_data, 0, tmp_data.Length);
                Assert.IsTrue(mb2a.Equals(mb2b), "mb2a.Equals(mb2b)");
                Assert.IsTrue(mb2b.Equals(mb2a), "mb2b.Equals(mb2a)");

                //Check the Hash:
                Assert.IsTrue(mb2b.GetHashCode() == mb2a.GetHashCode(), "GetHashCode");

                //Here are some manual equality testing using the indexer
                bool all_equals = true;
                int  j          = 0;
                while (all_equals && (j < mb1.Length))
                {
                    all_equals = (mb1[j] == cat[j]);
                    j++;
                }
                Assert.IsTrue(all_equals, "Manual equality test mb1");
                all_equals = true;
                j          = 0;
                while (all_equals && (j < mb2.Length))
                {
                    all_equals = (mb2[j] == mb2a[j]);
                    j++;
                }
                Assert.IsTrue(all_equals, "Manual equality test mb2");
                all_equals = true;
                j          = 0;
                while (all_equals && (j < mb2.Length))
                {
                    all_equals = (mb2[j] == mb2b[j]);
                    j++;
                }
                Assert.IsTrue(all_equals, "Manual equality test mb2b");
            }
        }
示例#46
0
 public DhtPut(Node node, MemBlock key, MemBlock value, int ttl, EventHandler callback)
 {
   _node = node;
   _key = key;
   _value = value;
   _ttl = ttl;
   _callback = callback;
   _successful = false;
 }
示例#47
0
 public void HandleData(MemBlock data, ISender sender, object state)
 {
   BroadcastReceiver br = sender as BroadcastReceiver; 
   _estimated_time_left = DateTime.UtcNow.AddSeconds(1);
   _results.Add(br);
 }
示例#48
0
  /**
   * 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...
      }
    }
  }
示例#49
0
        public void Test()
        {
            System.Random r = new System.Random();
            //Test numeric type codes:
            for (int i = 1; i < 32; i++)
            {
                PType    p = new PType(i);
                MemBlock b = p.ToMemBlock();

                byte[] buf = new byte[100];
                r.NextBytes(buf); //Get some junk:
                MemBlock junk = MemBlock.Reference(buf);
                MemBlock b1   = MemBlock.Concat(b, junk);
                MemBlock rest = null;
                PType    pp   = PType.Parse(b1, out rest);

                byte[] buf2 = new byte[1];
                buf2[0] = (byte)i;
                MemBlock b2 = MemBlock.Reference(buf2);

                Assert.AreEqual(p, pp, System.String.Format("Round trip int: {0}", i));
                Assert.AreEqual(b, b2, System.String.Format("Convert to MemBlock int: {0}", i));
                Assert.AreEqual(i, pp.TypeNumber, "Typenumber equality");
                Assert.AreEqual(rest, junk, "rest in int PType");
            }

            //Test string types:
            for (int i = 0; i < 1000; i++)
            {
                //Make a random string:
                //
                byte[] buf = new byte[r.Next(1, 100)];
                r.NextBytes(buf);
                string s  = Base32.Encode(buf);
                PType  p1 = new PType(s);
                r.NextBytes(buf); //Get some junk:
                MemBlock b       = MemBlock.Copy(buf);
                MemBlock combine = MemBlock.Concat(p1.ToMemBlock(), b);
                MemBlock b2      = null;
                PType    p2      = PType.Parse(combine, out b2);

                Assert.AreEqual(p1, p2, "Round trip string: " + s);
                Assert.AreEqual(b, b2, "Round trip rest");
                Assert.AreEqual(s, p2.ToString(), "Round trip to string");
                Assert.AreEqual(s, p1.ToString(), "Round trip to string");
                Assert.AreEqual(p1.TypeNumber, p2.TypeNumber, "RT: TypeNumber test");
            }
            //Test all one byte ascii strings:
            for (byte b = 32; b < ASCII_UPPER_BOUND; b++)
            {
                MemBlock raw = MemBlock.Reference(new byte[] { b, 0 });
                MemBlock rest;
                PType    p1 = PType.Parse(raw, out rest);
                Assert.AreEqual(rest, MemBlock.Null, "Rest is null");
                PType p2 = PType.Parse(raw, out rest);
                Assert.AreEqual(rest, MemBlock.Null, "Rest is null");
                Assert.IsTrue(p1 == p2, "reference equality of single byte type");
                Assert.AreEqual(p1, p2, "equality of single byte type");
                Assert.AreEqual(p1, new PType(p1.ToString()), "Round trip string");
            }
            //Test TypeNumber of string types:
            for (int i = 0; i < 100; i++)
            {
                byte[] buf = new byte[20];
                r.NextBytes(buf);
                for (int j = 1; j < 4; j++)
                {
                    string s    = Base32.Encode(buf).Substring(0, j);
                    PType  p1   = new PType(s);
                    byte[] buf2 = System.Text.Encoding.UTF8.GetBytes(s);
                    int    t    = 0;
                    for (int k = 0; k < buf2.Length; k++)
                    {
                        t   = t | buf2[k];
                        t <<= 8;
                    }
                    Assert.AreEqual(t, p1.TypeNumber, System.String.Format("String type number: {0}, s={1}", t, s));
                }
            }
            //Console.Error.WriteLine("Tested PType");
        }
示例#50
0
  public AHHeader(short hops, short ttl, Address source, Address dest, ushort options) {
    //Make the header part:
    byte[] header = new byte[ LENGTH ];
    int offset = 0;
    //Write hops:
    NumberSerializer.WriteShort(hops, header, offset);
    Hops = hops;
    offset += 2;

    NumberSerializer.WriteShort(ttl, header, offset);
    Ttl = ttl;
    offset += 2;
    
    _src = source;
    offset += source.CopyTo(header, offset);

    _dest = dest;
    offset += dest.CopyTo(header, offset);

    Opts = options;
    NumberSerializer.WriteShort((short)options, header, offset);
    offset += 2;

    _data = MemBlock.Reference(header, 0, offset);
  }
示例#51
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;
    }
示例#52
0
        /**
         * Parse the PType starting at mb, and return all of mb <b>after</b>
         * the PType.
         */
        public static PType Parse(MemBlock mb, out MemBlock rest)
        {
            PType result = null;
            byte  fb     = mb[0];
            bool  is_v_n = IsValidNumeric((int)fb);

            /**
             * Since ptypes must be valid UTF8 strings,
             * if the second byte is null, the first byte is an ascii character
             * and hence has a value less than ASCII_UPPER_BOUND
             */
            bool store_in_tbl = (is_v_n || (mb[1] == 0));

            if (store_in_tbl)
            {
                //This is stored in our table:
                result = _table[fb];
                if (result != null)
                {
                    if (is_v_n)
                    {
                        //There is no null
                        rest = mb.Slice(1);
                    }
                    else
                    {
                        //Skip the null
                        rest = mb.Slice(2);
                    }
                    return(result);
                }
            }
            //Otherwise we have to make it:
            MemBlock raw_data = null;

            result = new PType();
            if (is_v_n)
            {
                /*
                 * Don't set the raw_data since it is only one byte and we may not need
                 * it
                 */
                rest             = mb.Slice(1);
                result._type_num = (int)fb;
            }
            else
            {
                int null_pos = mb.IndexOf(0);
                if (null_pos > 0)
                {
                    //Include the "null", but make a copy so we don't keep some data in
                    //scope for ever
                    raw_data = MemBlock.Copy((ICopyable)mb.Slice(0, null_pos + 1));
                    rest     = mb.Slice(null_pos + 1);
                }
                else
                {
                    //There is no terminating Null, panic!!
                    throw new ParseException(
                              System.String.Format("PType not null terminated: {0}", mb.ToBase16String()));
                }
                result._type_num = -2;
                result._raw_data = raw_data;
            }
            if (store_in_tbl)
            {
                //Make sure we don't have to create an object like this again
                _table[fb] = result;
            }
            return(result);
        }
示例#53
0
  public void Test() {
    System.Random r = new System.Random();

    byte[] data;
    for(int i = 0; i < 100; i++) {
      data = new byte[ r.Next(1024) ];
      r.NextBytes(data);
      int offset = r.Next(data.Length);
      MemBlock mb1 = new MemBlock(data, 0, data.Length);
      MemBlock mb1a = MemBlock.Copy(data, 0, data.Length);
      Assert.IsTrue(mb1.Equals(mb1a), "MemBlock.Copy");
      Assert.IsTrue(mb1.Equals(data), "MemBlock == byte[]");
      MemBlock mb2 = new MemBlock(data, offset, data.Length - offset);
      MemBlock mb2a = mb1.Slice(offset);
      MemBlock mb3 = new MemBlock(data, 0, offset);
      MemBlock mb3a = mb1.Slice(0, offset);
      Assert.IsTrue(mb3.Equals( mb3a ), "mb3.Equals(mb3a)");
      Assert.IsTrue(mb3a.Equals( mb3 ), "mb3a.Equals(mb3)");
      Assert.IsTrue(mb3.CompareTo(mb2) + mb2.CompareTo(mb3) == 0, "CompareTo");
      Assert.IsTrue(mb2.Equals( mb2a ), "mb2.Equals(mb2a)");
      Assert.IsTrue(mb2a.Equals( mb2 ), "mb2a.Equals(mb2)");

      MemBlock cat = MemBlock.Concat(mb3, mb2);
      MemBlock cata = MemBlock.Concat(mb3a, mb2a);
      Assert.IsTrue(cat.Equals(cata), "Concat Equals");
      Assert.IsTrue(cata.Equals(cat), "Concat a Equals");
      Assert.IsTrue(mb1.Equals(cat), "Concat Equals Original");
      if( offset != 0 ) {
        //These should not be equal
        Assert.IsFalse(mb2.Equals(mb1), "mb2 != mb1");
      }
      int mb2a_l = mb2a.Length;
      byte[] tmp_data = new byte[mb2a_l];
      mb2a.CopyTo(tmp_data, 0);
      MemBlock mb2b = new MemBlock(tmp_data, 0, tmp_data.Length);
      Assert.IsTrue(mb2a.Equals(mb2b), "mb2a.Equals(mb2b)");
      Assert.IsTrue(mb2b.Equals(mb2a), "mb2b.Equals(mb2a)");

      //Check the Hash:
      Assert.IsTrue(mb2b.GetHashCode() == mb2a.GetHashCode(), "GetHashCode");

      //Here are some manual equality testing using the indexer
      bool all_equals = true;
      int j = 0;
      while( all_equals && (j < mb1.Length) ) {
        all_equals = (mb1[ j ] == cat[ j ]);
        j++;
      }
      Assert.IsTrue(all_equals, "Manual equality test mb1");
      all_equals = true;
      j = 0;
      while( all_equals && (j < mb2.Length) ) {
        all_equals = (mb2[ j ] == mb2a[ j ]);
        j++;
      }
      Assert.IsTrue(all_equals, "Manual equality test mb2");
      all_equals = true;
      j = 0;
      while( all_equals && (j < mb2.Length) ) {
        all_equals = (mb2[ j ] == mb2b[ j ]);
        j++;
      }
      Assert.IsTrue(all_equals, "Manual equality test mb2b");
    }
  }