/// <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); }
public static byte GetChannel(byte[] data) { var decoder = new Decoder(data, RESERVED); return((byte)decoder.Decode32U()); }
// 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); }