Slice() 공개 메소드

public Slice ( int offset ) : MemBlock
offset int
리턴 MemBlock
예제 #1
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);
   }
 }
예제 #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
 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) );
   }
 }
예제 #4
0
파일: AHSender.cs 프로젝트: twchoi/brunet
 /** 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;
 }
예제 #5
0
 public override string ToString()
 {
     if (_string_rep != null)
     {
         return(_string_rep);
     }
     else if (_type_num == -2)
     {
         //Unitialized string type:
         _string_rep = System.String.Intern(
             _raw_data.Slice(0, _raw_data.Length - 1).GetString(System.Text.Encoding.UTF8)
             );
     }
     else
     {
         //Unitialized int type:
         _string_rep = "_" + _type_num.ToString();
     }
     return(_string_rep);
 }
예제 #6
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());
      }
    }
예제 #7
0
파일: MemBlock.cs 프로젝트: johnynek/brunet
  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");
    }
  }
예제 #8
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);
        }
예제 #9
0
파일: MemBlock.cs 프로젝트: kingctan/brunet
        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");
            }
        }
예제 #10
0
 /**
  * This is either a request or response.  Look up the handler
  * for it, and pass the packet to the handler
  */
 public void HandleData(MemBlock p, ISender from, object state) {
   //Is it a request or reply?
   ReqrepType rt = (ReqrepType)((byte)p[0]);
   int idnum = NumberSerializer.ReadInt(p,1);
   MemBlock rest = p.Slice(5); //Skip the type and the id
   if( rt == ReqrepType.Request || rt == ReqrepType.LossyRequest ) {
     HandleRequest(rt, idnum, rest, from);
   }
   else if( rt == ReqrepType.Reply ) {
     HandleReply(rt, idnum, rest, from);
   }
   else if (rt == ReqrepType.ReplyAck ) {
     HandleReplyAck(rt, idnum, rest, from);
   }
   else if (rt == ReqrepType.RequestAck ) {
     HandleRequestAck(rt, idnum, rest, from);
   }
   else if( rt == ReqrepType.Error ) {
     HandleError(rt, idnum, rest, from);
   }
 }
예제 #11
0
 public void HandleData(MemBlock mb, ISender from, object state) {
   int len = Header.Length;
   if( mb.Length >= len ) {
     var temph = mb.Slice(0, len);
     if( temph.Equals( Header) ) {
       Handle(mb.Slice(len), from);
       return;
     }
   }
   WithoutHeader.Handle(mb, from);
 }
예제 #12
0
  private static object Deserialize(MemBlock b, int offset, byte term,
                                    out bool finished, out int size) {
    byte typecode = b[offset];
    finished = false;  //By default, we're not finished
    switch( typecode ) {
      case STRING_S:
        int count;
        string s = NumberSerializer.ReadString(b, offset + 1, out count);
        size = count + 1; //add one for the STRING_S byte
        return s;
      case LIST_S:
        IList lst = new ArrayList();
        bool lfin;
        int lsize;
        size = 1;
        offset++; //Skip the LIST_S
        do {
          object o = Deserialize(b, offset, LIST_E, out lfin, out lsize);
	  if( !lfin ) {
	    //If we are finished, tmp holds a meaningless null
	    lst.Add(o);
	  }
          offset += lsize;
          size += lsize;
        } while( ! lfin );
        return lst;
      case LIST_E:
        if( term == LIST_E ) { finished = true; size = 1; }
        else {
          throw new Exception(
               String.Format("terminator mismatch: found: {0} expected: {1}", term, LIST_E));
        }
        return null;
      case MAP_S:
        //Start of a map:
        IDictionary dresult = new Hashtable();
        bool mfinished = false;
        int msize;
        size = 1;
        offset++;
        do {
          //Magical recursion strikes again
          object key = Deserialize(b, offset, MAP_E, out mfinished, out msize);
          offset += msize;
          size += msize;
          if( !mfinished ) {
            object valu = Deserialize(b, offset, out msize);
            offset += msize;
            size += msize;
            dresult.Add(key, valu);
          }
        } while (false == mfinished);
        return dresult;
      case MAP_E:
        //End of a map:
        if (term == MAP_E) {
          //We were reading a list and now we are done:
          finished = true;
          size = 1;
        }
        else {
          throw new Exception(
               String.Format("terminator mismatch: found: {0} expected: {1}", term, MAP_E));
        }
        return null;
      case TRUE:
        size = 1;
        return true;
      case FALSE:
        size = 1;
        return false;
      case NULL:
        size = 1;
        return null;
      case SBYTE:
        size = 2;
        return (sbyte)b[offset + 1];
      case BYTE:
        size = 2;
        return b[offset + 1];
      case SHORT:
        size = 3;
        return NumberSerializer.ReadShort(b, offset + 1);
      case USHORT:
        size = 3;
        return (ushort)NumberSerializer.ReadShort(b, offset + 1);
      case INT:
        size = 5;
        return NumberSerializer.ReadInt(b, offset + 1);
      case UINT:
        size = 5;
        return (uint)NumberSerializer.ReadInt(b, offset + 1);
      case LONG:
        size = 9;
        return NumberSerializer.ReadLong(b, offset + 1);
      case ULONG:
        size = 9;
        return (ulong)NumberSerializer.ReadLong(b, offset + 1);
      case FLOAT:
        size = 5;
        return NumberSerializer.ReadFloat(b, offset + 1);
      case DOUBLE:
	size = 9;
	return NumberSerializer.ReadDouble(b, offset + 1);
      case EXCEPTION_S:
        //Start of a map:
        Hashtable eresult = new Hashtable();
        bool efinished = false;
        int esize;
        size = 1;
        offset++;
        do {
          //Magical recursion strikes again
          object key = Deserialize(b, offset, EXCEPTION_E, out efinished, out esize);
          offset += esize;
          size += esize;
          if( !efinished ) {
            object valu = Deserialize(b, offset, out esize);
            offset += esize;
            size += esize;
            eresult.Add(key, valu);
          }
        } while (false == efinished);
        return new AdrException(eresult);
      case EXCEPTION_E:
        //End of a map:
        if (term == EXCEPTION_E) {
          //We were reading a list and now we are done:
          finished = true;
          size = 1;
        }
        else {
          throw new Exception(
               String.Format("terminator mismatch: found: {0} expected: {1}",
                             term, EXCEPTION_E));
        }
        return null;
      case ARRAY:
        //Read length:
        int asize;
        object olength = Deserialize(b, offset + 1, out asize);
        //Due to boxing here, we have to be careful about unboxing,
        //this will get easier with generics:
        int length = (int)UnboxToLong(olength); 
        offset += 1 + asize;
	byte atype = b[offset];
        offset++;
	switch (atype) {
          case BYTE:
            byte[] aBresult = new byte[length];
            MemBlock b_a = b.Slice(offset, length);
            b_a.CopyTo(aBresult, 0);
            size = 1 + asize + 1 + length;
            return aBresult;
          case INT:
            int[] airesult = new int[length];
            for(int i = 0; i < airesult.Length; i++) {
              airesult[i] = NumberSerializer.ReadInt(b, offset);
              offset += 4;
            }
            size = 1 + asize + 1 + 4 * length;
            return airesult;
            ///@todo add more array types
          default:
            throw new Exception("Unsupported array type code: " + atype);
	}
      default:
        throw new Exception(String.Format("Unrecognized type code: {0}", typecode));
    }
  }
예제 #13
0
파일: PType.cs 프로젝트: pstjuste/brunet
 /**
  * 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;
 }
예제 #14
0
파일: Stun.cs 프로젝트: reith2004/ipop
 /// <summary>Parse an AttributeAddress.</summary>
 public AttributeAddress(AttributeType type, MemBlock data)
     : base(type, data)
 {
     Family = (FamilyType) data[1];
     Port = (ushort) NumberSerializer.ReadShort(data, 2);
     byte[] addr = new byte[data.Length - 4];
     data.Slice(4).CopyTo(addr, 0);
     IP = new IPAddress(addr);
 }
예제 #15
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);
 }
예제 #16
0
파일: AHSender.cs 프로젝트: pstjuste/brunet
 /**
  * Here we handle routing AHPackets
  */
 public void HandleData(MemBlock data, ISender ret_path, object st) {
   var header = new AHHeader(data);
   var payload = data.Slice(header.Length);
   HandleData(header, payload, ret_path, st);
 }
예제 #17
0
파일: AHSender.cs 프로젝트: johnynek/brunet
  /**
   * 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...
      }
    }
  }
예제 #18
0
 public void HandleData(MemBlock b, ISender return_path, object state) {
   //Read the header:
   uint crc32 = (uint)NumberSerializer.ReadInt(b, 0);
   int id = NumberSerializer.ReadInt(b, 4);
   ushort block = (ushort)NumberSerializer.ReadShort(b, 8);
   MemBlock data = b.Slice(10);
   var cachekey = new Triple<uint, int, ushort>(crc32, id, block);
   MemBlock packet = null;
   lock(_sync) {
     if( false == _fragments.Contains(cachekey) ) {
       //This is a new block:
       _fragments.Add(cachekey, data);
       var fc_key = new Pair<uint, int>(crc32, id);
       Fragments this_fc;
       if( false == _frag_count.TryGetValue(fc_key, out this_fc) ) {
         this_fc = new Fragments();
         _frag_count.Add(fc_key, this_fc);
       }
       if( this_fc.AddBlock(block) ) {
         //We have all of them, decode and clean up:
         packet = DecodeAndClear(crc32, id, (ushort)this_fc.Total);
       }
     }
   }
   if( null != packet ) {
     Handle(packet, return_path);
   }
 }