Пример #1
0
        public BufLen GenerateData(I2NPMessage msg)
        {
            if (NTCPContext == null)
            {
                throw new Exception("NTCP Session not negotiated!");
            }
            if (NTCPContext.Encryptor == null)
            {
                throw new Exception("NTCP encryptor not available");
            }

            var data = msg != null ? msg.Header16.HeaderAndPayload: null;

            var datalength = msg == null ? 4 : data.Length;
            var buflen     = 2 + datalength + 4;
            var padlength  = BufUtils.Get16BytePadding(buflen);

            buflen += padlength;

            var buf    = new BufLen(new byte[buflen]);
            var writer = new BufRefLen(buf);

            // Length
            if (msg == null)
            {
                // Send timestamp
                writer.Write16(0);
                writer.WriteFlip32((uint)(DateTime.UtcNow - I2PDate.RefDate).TotalSeconds);
            }
            else
            {
                if (data.Length > 16378)
                {
                    throw new ArgumentException("NTCP data can be max 16378 bytes long!");
                }
                writer.WriteFlip16((ushort)data.Length);
                writer.Write(data);
            }

            // Pad
            writer.Write(BufUtils.Random(writer.Length - 4));

            // Checksum
            var checkbuf = new BufLen(buf, 0, writer - buf);
            var checksum = LZUtils.Adler32(1, checkbuf);

            writer.WriteFlip32(checksum);

            // Encrypt
            NTCPContext.Encryptor.ProcessBytes(buf);

            return(buf);
        }
Пример #2
0
        private BufLen ReadBlock()
        {
            var inbufend = 2 + BlockLength + 4;

            inbufend += BufUtils.Get16BytePadding(inbufend);

            while (InBufPos < inbufend)
            {
                if (MySocket.Available > 0)
                {
                    var len = MySocket.Receive(InBuf, InBufPos, inbufend - InBufPos, SocketFlags.None);
                    if (len == 0)
                    {
                        throw new EndOfStreamEncounteredException();
                    }
                    InBufPos += len;
                }
                else
                {
                    Thread.Sleep(400);
                    if (!MySocket.Connected)
                    {
                        throw new EndOfStreamEncounteredException();
                    }
                }
            }

            Cipher.ProcessBytes(new BufLen(InBuf, 16, InBufPos - 16));

            var checksum = LZUtils.Adler32(1, new BufLen(InBuf, 0, InBufPos - 4));
            var blocksum = BufUtils.Flip32(InBuf, InBufPos - 4);

            if (checksum != blocksum)
            {
                throw new ChecksumFailureException("NTCPReader: Received Adler checksum mismatch.");
            }

            var result = new BufLen(InBuf, 2, BlockLength);

            BlockLength = -1;

#if LOG_ALL_TRANSPORT
            Logging.LogTransport(string.Format("NTCPReader +{1}+ block received: {0} bytes [0x{0:X}]", result.Length, Context.TransportInstance));
#endif
            return(result.Clone());
        }