Beispiel #1
0
        public static IEnumerable <TunnelDataMessage> MakeFragments(IEnumerable <TunnelMessage> messages, I2PTunnelId desttunnel)
        {
            var padcalc = CalculatePadding(messages, desttunnel);

            foreach (var one in padcalc.TDMessages)
            {
                //Logging.Log( "New message" );

                var writer = new BufRefLen(one.TunnelDataInstance.Payload);

                writer.Seek(24);   // TunnelID, IV, Checksum of "Tunnel Message (Decrypted)"
                if (one.PaddingNeeded > 0)
                {
                    //Logging.Log( "Padding " + one.PaddingNeeded.ToString() + " bytes" );
                    writer.Write(new BufRefLen(BufUtils.RandomNZ(one.PaddingNeeded)));
                }

                writer.Write8(0);   // The Zero
                one.TunnelDataInstance.SetFirstDeliveryInstructionPoint(writer.View);

                foreach (var frag in one.Fragments)
                {
                    var fragstart = new BufRefLen(writer);
                    frag.Append(writer);
                    //Logging.Log( "Fragment " + ( one.TunnelDataInstance.Writer - fragstart ).ToString() + " bytes" );
                }

                one.TunnelDataInstance.Checksum.Poke(I2PHashSHA256.GetHash(
                                                         one.TunnelDataInstance.FirstDeliveryInstruction,
                                                         one.TunnelDataInstance.IV), 0, 4);

                if (writer.Length != 0)
                {
                    Logging.LogCritical("TunnelData: MakeFragments. Tunnel block is not filled!");
                    throw new Exception("TunnelData message not filled. Something is wrong.");
                }
            }

            return(padcalc.TDMessages.Select(msg => msg.TunnelDataInstance));
        }