示例#1
0
        /// <summary>
        /// Encode a hashcash token into a buffer
        /// </summary>
        /// <param name="buffer">the buffer where to store the hashcash</param>
        /// <param name="index">the index in the buffer where to put it</param>
        /// <param name="hashCash">the token to be encoded</param>
        /// <returns>the length of the written data</returns>
        public static HashCash Decode(byte[] buffer, int index)
        {
            var   decoder  = new Decoder(buffer, index);
            long  ticks    = (long)decoder.Decode64U();
            int   resource = (int)decoder.Decode32U();
            ulong salt     = decoder.Decode64U();
            ulong counter  = decoder.Decode64U();

            var token = new HashCash(
                new DateTime(ticks),
                resource,
                salt,
                counter
                );

            return(token);
        }
示例#2
0
        public static int GetChannel(byte[] data)
        {
            var decoder = new Decoder(data, RESERVED);

            return((int)decoder.Decode32U());
        }
示例#3
0
        // ikcp_input
        /// used when you receive a low level packet (eg. UDP packet)
        public int Input(byte[] data, int size)
        {
            uint prev_una = snd_una;
            uint maxack   = 0;
            bool flag     = false;

            // the data is expected to have the reserved space
            size -= Reserved;
            if (size < OVERHEAD)
            {
                return(-1);
            }

            int reservedOffset = Reserved;

            while (size >= OVERHEAD)
            {
                var    decoder = new Decoder(data, reservedOffset);
                uint   conv_   = decoder.Decode32U();
                var    cmd     = (CommandType)decoder.Decode8U();
                byte   frg     = decoder.Decode8U();
                ushort wnd     = decoder.Decode16U();
                uint   ts      = decoder.Decode32U();
                uint   sn      = decoder.Decode32U();
                uint   una     = decoder.Decode32U();
                int    len     = (int)decoder.Decode32U();

                reservedOffset = decoder.Position;
                size          -= OVERHEAD;

                if (!ValidateSegment(size, conv_, cmd, len))
                {
                    return(-1);
                }

                rmt_wnd = wnd;
                ParseUna(una);
                ShrinkBuf();

                switch (cmd)
                {
                case CommandType.Ack:
                    UpdateAck(ts);
                    ParseAck(sn);
                    ShrinkBuf();
                    maxack = Math.Max(maxack, sn);
                    flag   = true;
                    break;

                case CommandType.Push:
                    if (sn >= rcv_nxt + rcv_wnd)
                    {
                        break;
                    }

                    AckPush(sn, ts);
                    if (sn < rcv_nxt)
                    {
                        break;
                    }

                    var seg = Segment.Lease();
                    seg.conversation   = conv_;
                    seg.cmd            = cmd;
                    seg.fragment       = frg;
                    seg.window         = wnd;
                    seg.timeStamp      = ts;
                    seg.serialNumber   = sn;
                    seg.unacknowledged = una;
                    seg.data.Write(data, reservedOffset, len);
                    ParseData(seg);
                    break;

                case CommandType.WindowAsk:

                    // ready to send back CMD_WINS in flush
                    // tell remote my window size
                    probe |= ASK_TELL;
                    break;
                }

                reservedOffset += len;
                size           -= len;
            }

            if (flag)
            {
                ParseFastack(maxack);
            }

            // cwnd update when packet arrived
            UpdateCongestionWindow(prev_una);

            return(0);
        }