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); }
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()); }