Наследование: Brunet.Util.ICopyable
Пример #1
0
    /// <summary>Create a DtlsFilter.</summary>
    /// <param name="key">A CryptoKey initialized by the OpenSSL.NET library.</param>
    /// <param name="cert">The path to the certificate to use.</param>
    /// <param name="ca_cert">The path to the ca certificate to use.</param>
    /// <param name="client">Use client initialization parameters.</param>
    public DtlsAssociation(ISender sender, CertificateHandler ch, PType ptype,
        Ssl ssl, bool client) : base(sender, ch)
    {
      _ip = new IdentifierPair();
      PType = ptype;
      _ssl = ssl;
      _client = client;
      _ssl.SetReadAhead(1);
      // Buggy SSL versions have issue with compression and dtls
      _ssl.SetOptions((int) SslOptions.SSL_OP_NO_COMPRESSION);
      if(client) {
        _ssl.SetConnectState();
      } else {
        _ssl.SetAcceptState();
      }

      // The ssl object will take control
      _read = BIO.MemoryBuffer(false);
      _read.NonBlocking = true;
      _write = BIO.MemoryBuffer(false);
      _write.NonBlocking = true;

      _ssl.SetBIO(_read, _write);
      _ssl.DoHandshake();

      _buffer = new byte[Int16.MaxValue];
      _buffer_sync = new object();
      _fe_lock = 0;
    }
Пример #2
0
 /// <summary>Constructor for an outgoing edge, since we don't know the remote
 /// id yet, it must be outgoing!</summary>
 public SubringEdge(TransportAddress local_ta, TransportAddress remote_ta,
     bool inbound, ISender sender, PType ptype) :
     base(null, inbound)
 {
   _ip = new IdentifierPair();
   _local_ta = local_ta;
   _remote_ta = remote_ta;
   _ptype = ptype;
   _overlay_sender = sender;
 }
Пример #3
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;
    }
Пример #4
0
        public override bool Equals(object o)
        {
            if (o == this)
            {
                return(true);
            }
            PType other = o as PType;

            if (other != null)
            {
                return(other.ToMemBlock().Equals(ToMemBlock()));
            }
            return(false);
        }
Пример #5
0
    /// <summary>Create a SubringEdgeListener.</summary>
    /// <param name="shared_node">The overlay used for the transport.</param>
    /// <param name="private_node">The overlay needing edges.</param>
    public SubringEdgeListener(Node shared_node, Node private_node)
    {
      _shared_node = shared_node;
      _private_node = private_node;
      _it = new IdentifierTable();

      _local_ta = new SubringTransportAddress(shared_node.Address as AHAddress,
          shared_node.Realm);

      _ptype = new PType("ns:" + shared_node.Realm);
      shared_node.DemuxHandler.GetTypeSource(_ptype).Subscribe(this, null);

      _running = 0;
      _started = 0;
    }
Пример #6
0
  public ReqrepManager(object info, PType prefix) {
    ReqrepManager existing;
    lock( _inst_tab_sync ) {
      if(_instance_table.TryGetValue(info, out existing) ) {
        throw new Exception("Already an existing ReqrepManager for: " + info.ToString());
      }
      else {
        _instance_table[info] = this;
      }
    }
    _info = info.ToString();

    _prefix = prefix;
    _req_handler_table = new Hashtable();
    Random r = new Random();
    //Don't use negative numbers:
    _req_state_table = new UidGenerator<RequestState>(r, true);
    //Don't use negative numbers:
    _reply_id_table = new UidGenerator<ReplyState>(r, true);
    _rep_handler_table = new Hashtable();

    /**
     * We keep a list of the most recent 1000 replies until they
     * get too old.  If the reply gets older than reptimeout, we
     * remove it
     */
    _reply_cache = new Cache(1000);
    _reply_cache.EvictionEvent += HandleReplyCacheEviction;
    /*
     * Here we set the timeout mechanisms.  There is a default
     * value, but this is now dynamic based on the observed
     * RTT of the network
     */
    //resend the request after 5 seconds.
    _edge_reqtimeout = new TimeSpan(0,0,0,0,5000);
    _nonedge_reqtimeout = new TimeSpan(0,0,0,0,5000);
    //Start with 50 sec timeout
    _acked_reqtimeout = new TimeSpan(0,0,0,0,50000);
    //Here we track the statistics to improve the timeouts:
    _nonedge_rtt_stats = new TimeStats(_nonedge_reqtimeout.TotalMilliseconds, 0.98);
    _edge_rtt_stats = new TimeStats(_edge_reqtimeout.TotalMilliseconds, 0.98);
    _acked_rtt_stats = new TimeStats(_acked_reqtimeout.TotalMilliseconds, 0.98);
    _last_check = DateTime.UtcNow;
  }
Пример #7
0
 static Protocol()
 {
     //Here are all the defined protocols
     PType[] prots = new PType[] {
         Linking,
         AH,
         Connection,
         Forwarding,
         Relaying,
         Echo,
         IP,
         ReqRep,
         Rpc
     };
     foreach (PType p in prots)
     {
         PType.AddToTable(p);
     }
 }
Пример #8
0
 static PType()
 {
     //Initialize the _table:
     _table = new PType[ASCII_UPPER_BOUND];
 }
Пример #9
0
  public ReqrepManager(string info, PType prefix) {
    lock( _inst_tab_sync ) {
      _instance_table.Replace(info, this);
    }
    _info = info;

    _prefix = prefix;
    _req_handler_table = new Hashtable();
#if BRUNET_SIMULATOR
    Random r = Node.SimulatorRandom;
#else
    Random r = new Random();
#endif
    //Don't use negative numbers:
    _req_state_table = new UidGenerator<RequestState>(r, true);
    //Don't use negative numbers:
    _reply_id_table = new UidGenerator<ReplyState>(r, true);
    _rep_handler_table = new Hashtable();

    /**
     * We keep a list of the most recent 1000 replies until they
     * get too old.  If the reply gets older than reptimeout, we
     * remove it
     */
    _reply_cache = new Cache(1000);
    _reply_cache.EvictionEvent += HandleReplyCacheEviction;
    /*
     * Here we set the timeout mechanisms.  There is a default
     * value, but this is now dynamic based on the observed
     * RTT of the network
     */
    //resend the request after 5 seconds.
    _edge_reqtimeout = new TimeSpan(0,0,0,0,5000);
    _nonedge_reqtimeout = new TimeSpan(0,0,0,0,5000);
    //Start with 50 sec timeout
    _acked_reqtimeout = new TimeSpan(0,0,0,0,50000);
    //Here we track the statistics to improve the timeouts:
    _nonedge_rtt_stats = new TimeStats(_nonedge_reqtimeout.TotalMilliseconds, 0.98);
    _edge_rtt_stats = new TimeStats(_edge_reqtimeout.TotalMilliseconds, 0.98);
    _acked_rtt_stats = new TimeStats(_acked_reqtimeout.TotalMilliseconds, 0.98);
    _last_check = DateTime.UtcNow;
  }
Пример #10
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);
        }
Пример #11
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");
        }
Пример #12
0
  public ReqrepManager(string info, PType prefix) {
    lock( _inst_tab_sync ) {
      _instance_table.Replace(info, this);
    }
    _info = info;
    _prefix = prefix;
#if BRUNET_SIMULATOR
    Random r = Node.SimulatorRandom;
#else
    Random r = new Random();
#endif
    //Don't use negative numbers:
    _req_state_table = new UidGenerator<RequestState>(r, true);
    //Don't use negative numbers:
    _reply_id_table = new UidGenerator<ReplyState>(r, true);

    /**
     * We keep a list of the most recent 1000 replies until they
     * get too old.  If the reply gets older than reptimeout, we
     * remove it
     */
    _reply_cache = new Cache(1000);
    _reply_cache.EvictionEvent += HandleReplyCacheEviction;
    _to_mgr = new TimeOutManager();
  }
Пример #13
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");
  }
Пример #14
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;
 }
Пример #15
0
   // Methods /////

   /** Create a ReplyState for a new Request
    * Note, this is not synchronized, you must hold the lock when calling!
    */
   protected ReplyState GenerateReplyState(PType prefix, RequestKey rk) {
     var rs = new ReplyState(_prefix, rk);
     _reply_cache[rk] = rs;
     rs.LocalID = _reply_id_table.GenerateID(rs);
     return rs;
   }
Пример #16
0
 static PType() {
   //Initialize the _table:
   _table = new PType[ ASCII_UPPER_BOUND ];
 }
Пример #17
0
  /**
   * Implements the IReplyHandler (also provides some light-weight statistics)
   */
  public bool HandleReply(ReqrepManager man, ReqrepManager.ReqrepType rt,
			  int mid, PType prot, MemBlock payload, ISender ret_path,
			  ReqrepManager.Statistics statistics, object state)
  {
    RpcRequestState rs = (RpcRequestState) state;
    //ISender target = rs.RpcTarget;
    Channel bq = rs.Results;
    if( bq != null ) {
      object data = AdrConverter.Deserialize(payload);
      RpcResult res = new RpcResult(ret_path, data, statistics);
      //handle possible exception:
      try {
        bq.Enqueue(res);
        //Keep listening unless the queue is closed
        return (!bq.Closed);
      }
      catch(System.InvalidOperationException) {
        //The queue is closed, stop listening for more results:
        return false;
      }
    }
    else {
      //If they didn't even pass us a queue, I guess they didn't want to
      //listen too long
      return false;
    }
  }
Пример #18
0
 public SecureConnectionHandler(PType ptype, StructuredNode node,
     SymphonySecurityOverlord so) : base(ptype, node)
 {
   _so = so;
   _registered = new Dictionary<SecurityAssociation, bool>();
 }
Пример #19
0
 static Protocol() {
   //Here are all the defined protocols
   PType[] prots = new PType[]{ 
                             Linking,
                             AH,
                             Connection,
                             Forwarding,
                             Relaying,
                             Echo,
                             IP,
                             ReqRep,
                             Rpc
                             };
   foreach(PType p in prots) {
     PType.AddToTable(p);
   }
 }
Пример #20
0
 protected static void AddToTable(PType p) {
   if (0 <= p.TypeNumber && p.TypeNumber < _table.Length) {
     _table[ p.TypeNumber ] = p;
   }
 }
Пример #21
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;
 }
Пример #22
0
 public ReplyState(PType prefix, RequestKey rk) {
   _prefix = prefix;
   RequestKey = rk;
   RequestDate = DateTime.UtcNow;
   _reply_timeouts = 0;
   _uri = new WriteOnce<string>();
   _lid = 0;
 }