Exemple #1
0
        public DatabaseLookupMessage(
            I2PIdentHash key,
            I2PIdentHash tunnelgw,
            I2PTunnelId tunnelid,
            LookupTypes flags,
            IEnumerable <I2PIdentHash> excludelist)
        {
            var excludecount = excludelist == null ? 0 : excludelist.Count();

            AllocateBuffer(2 * 32 + 1 + 4 + 2 + 32 * excludecount);
            var writer = new BufRefLen(Payload);

            writer.Write(key.Hash);
            writer.Write(tunnelgw.Hash);
            writer.Write8((byte)((byte)flags | (byte)LookupTypes.Tunnel));
            writer.Write32(tunnelid);

            if (excludecount > 0)
            {
                writer.WriteFlip16((ushort)excludecount);
                foreach (var addr in excludelist)
                {
                    writer.Write(addr.Hash);
                }
            }
            else
            {
                writer.Write16(0);
            }

            //dest.Add( 0 ); // Tags
        }
        public DatabaseStoreMessage(
            I2PLeaseSet leaseset,
            uint replytoken,
            I2PIdentHash replygw,
            I2PTunnelId replytunnelid)
        {
            var ls = leaseset.ToByteArray();

            AllocateBuffer(32 + 5 + (replytoken != 0 ? 4 + 32: 0) + ls.Length);
            var writer = new BufRefLen(Payload);

            writer.Write(leaseset.Destination.IdentHash.Hash);
            writer.Write8((byte)MessageContent.LeaseSet);
            writer.Write32(replytoken);
            if (replytoken != 0)
            {
                writer.Write32(replytunnelid);
                if (replygw == null || replygw.Hash.Length != 32)
                {
                    throw new FormatException("ReplyGateway has to be 32 bytes long!");
                }
                writer.Write(replygw.Hash);
            }

            writer.Write(ls);
            UpdateCachedFields((BufRefLen)Payload);
        }
Exemple #3
0
        void UpdateCachedFields(BufRef reader)
        {
            CachedKey        = new I2PIdentHash(reader);
            CachedFrom       = new I2PIdentHash(reader);
            CachedLookupType = (LookupTypes)reader.Read8();
            if (((byte)CachedLookupType & 0x01) != 0)
            {
                CachedTunnelId = new I2PTunnelId(reader);
            }

            var excludecount = reader.ReadFlip16();

            for (int i = 0; i < excludecount; ++i)
            {
                CachedExcludeList.Add(new DatabaseSearchReplyMessage(reader));
            }

            if (((byte)CachedLookupType & 0x02) != 0)
            {
                CachedReplyKey = new I2PSessionKey(reader);

                var tagcount = reader.Read8();
                CachedTags.Add(new I2PSessionTag(reader));
            }
        }
Exemple #4
0
        public TunnelDataMessage(I2PTunnelId desttunnel)
        {
            AllocateBuffer(DataLength + 4);

            TunnelId = desttunnel;
            IV.Randomize();
        }
Exemple #5
0
            public I2NPHeader16(BufRef reader, I2PTunnelId fromtunnel)
                : base(reader, fromtunnel)
            {
                MessageRef = I2NPUtil.GetMessage(this, reader);
#if DEBUG
                DebugCheckMessageCreation(MessageRef);
#endif
            }
        public OutboundTunnel(ITunnelOwner owner, TunnelConfig config, int replytunnelhops)
            : base(owner, config)
        {
            var outtunnel = config.Info.Hops[0];

            NextHop         = outtunnel.Peer.IdentHash;
            SendTunnelId    = outtunnel.TunnelId;
            ReplyTunnelHops = replytunnelhops;
        }
Exemple #7
0
        public OutboundTunnel(TunnelConfig config, int replytunnelhops) : base(config)
        {
            TunnelSetup = config.Info;

            var outtunnel = TunnelSetup.Hops[0];

            NextHop         = outtunnel.Peer.IdentHash;
            SendTunnelId    = outtunnel.TunnelId;
            ReplyTunnelHops = replytunnelhops;
        }
Exemple #8
0
        public TunnelDataMessage(byte[] data, I2PTunnelId tunnel)
        {
            var start  = new BufRef(data);
            var reader = new BufRefLen(data);

            reader.Seek(4 + DataLength);
            SetBuffer(start, reader);
            TunnelId = tunnel;

            UpdateFirstDeliveryInstructionPosition();
        }
        public TunnelGatewayMessage(I2NPMessage message, I2PTunnelId outtunnel)
        {
            var msg = message.CreateHeader16.HeaderAndPayload;

            AllocateBuffer(6 + msg.Length);

            TunnelId             = outtunnel;
            GatewayMessageLength = (ushort)msg.Length;
            // TODO: Remove mem copy
            Payload.Poke(msg, 6);
        }
Exemple #10
0
        // Fake 0-hop
        protected InboundTunnel(ITunnelOwner owner, TunnelConfig config)
            : base(owner, config)
        {
            Established = true;

            ReceiveTunnelId = config.Info.Hops.Last().TunnelId;
            RemoteGateway   = RouterContext.Inst.MyRouterIdentity.IdentHash;
            GatewayTunnelId = ReceiveTunnelId;

            Logging.LogDebug($"{this}: 0-hop tunnel {Destination?.Id32Short} created.");
        }
Exemple #11
0
 public GarlicCloveDeliveryTunnel(BufRef reader, byte flag) : base(DeliveryMethod.Tunnel)
 {
     Flag = flag;
     if ((Flag & (byte)DeliveryFlags.Encrypted) != 0)
     {
         SessionKey = new I2PSessionKey(reader);
     }
     Destination = new I2PIdentHash(reader);
     Tunnel      = new I2PTunnelId(reader);
     if ((Flag & (byte)DeliveryFlags.Delay) != 0)
     {
         Delay = reader.ReadFlip32();
     }
 }
Exemple #12
0
        public InboundTunnel(ITunnelOwner owner, TunnelConfig config, int outtunnelhops)
            : base(owner, config)
        {
            OutTunnelHops = outtunnelhops;

            var gw = config.Info.Hops[0];

            RemoteGateway   = gw.Peer.IdentHash;
            GatewayTunnelId = gw.TunnelId;

            ReceiveTunnelId = config.Info.Hops.Last().TunnelId;

#if LOG_ALL_TUNNEL_TRANSFER
            Logging.LogDebug($"InboundTunnel: Tunnel {Destination?.Id32Short} created.");
#endif
        }
Exemple #13
0
        public GatewayTunnel(BuildRequestRecord brrec)
            : base(null)
        {
            Config = new TunnelConfig(
                TunnelConfig.TunnelDirection.Outbound,
                TunnelConfig.TunnelPool.External,
                null);

            Limiter = new BandwidthLimiter(Bandwidth.SendBandwidth, TunnelSettings.GatewayTunnelBitrateLimit);

            ReceiveTunnelId = new I2PTunnelId(brrec.ReceiveTunnel);
            SendTunnelId    = new I2PTunnelId(brrec.NextTunnel);

            NextHop  = new I2PIdentHash(new BufRefLen(brrec.NextIdent.Hash.Clone()));
            IVKey    = brrec.IVKey.Clone();
            LayerKey = brrec.LayerKey.Clone();
        }
        public DatabaseStoreMessage(
            I2PRouterInfo info,
            uint replytoken,
            I2PIdentHash replygw,
            I2PTunnelId replytunnelid)
        {
            BufLen msb;

#if USE_BC_GZIP
            msb = LZUtils.BCGZipCompressNew(new BufLen(info.ToByteArray()));
#else
            using (var ms = new MemoryStream())
            {
                var buf = info.ToByteArray();

                using (var gzs = new GZipStream(ms, CompressionMode.Compress))
                {
                    gzs.Write(buf, 0, buf.Length);
                    gzs.Flush();
                }

                msb = new BufLen(ms.ToArray());
            }
#endif

            var len = 32 + 1 + 4 + 2 + msb.Length + (replytoken != 0 ? 4 + 32 : 0);
            AllocateBuffer(len);
            var writer = new BufRefLen(Payload);

            writer.Write(info.Identity.IdentHash.Hash);
            writer.Write8((byte)MessageContent.RouterInfo);
            writer.Write(BitConverter.GetBytes(replytoken));
            if (replytoken != 0)
            {
                writer.Write(BitConverter.GetBytes(replytunnelid));
                if (replygw == null || replygw.Hash.Length != 32)
                {
                    throw new FormatException("ReplyGateway has to be 32 bytes long!");
                }
                writer.Write(replygw.Hash);
            }

            writer.WriteFlip16((ushort)msb.Length);
            writer.Write(msb);
        }
Exemple #15
0
        public EndpointTunnel(BuildRequestRecord brrec)
            : base(null)
        {
            Config = new TunnelConfig(
                TunnelConfig.TunnelDirection.Inbound,
                TunnelConfig.TunnelRole.Endpoint,
                TunnelConfig.TunnelPool.External,
                null);

            Limiter = new BandwidthLimiter(Bandwidth.SendBandwidth, TunnelSettings.EndpointTunnelBitrateLimit);

            ReceiveTunnelId   = new I2PTunnelId(brrec.ReceiveTunnel);
            ResponseTunnelId  = new I2PTunnelId(brrec.NextTunnel);
            ResponseMessageId = brrec.SendMessageId;

            NextHop  = new I2PIdentHash(new BufRefLen(brrec.NextIdent.Hash.Clone()));
            IVKey    = brrec.IVKey.Clone();
            LayerKey = brrec.LayerKey.Clone();
        }
Exemple #16
0
        public InboundTunnel(TunnelConfig config, int outtunnelhops) : base(config)
        {
            if (config != null)
            {
                Fake0HopTunnel = false;
                TunnelSetup    = config.Info;
                OutTunnelHops  = outtunnelhops;

                var gw = TunnelSetup.Hops[0];
                RemoteGateway   = gw.Peer.IdentHash;
                GatewayTunnelId = gw.TunnelId;

                ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId;

#if LOG_ALL_TUNNEL_TRANSFER
                Logging.LogDebug($"InboundTunnel: Tunnel {Destination.Id32Short} created.");
#endif
            }
            else
            {
                Fake0HopTunnel = true;

                var hops = new List <HopInfo>
                {
                    new HopInfo(RouterContext.Inst.MyRouterIdentity, new I2PTunnelId())
                };
                TunnelSetup = new TunnelInfo(hops);

                Config = new TunnelConfig(
                    TunnelConfig.TunnelDirection.Inbound,
                    TunnelConfig.TunnelPool.Exploratory,
                    TunnelSetup);

                ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId;
                RemoteGateway   = RouterContext.Inst.MyRouterIdentity.IdentHash;
                GatewayTunnelId = ReceiveTunnelId;

#if LOG_ALL_TUNNEL_TRANSFER
                Logging.LogDebug($"InboundTunnel {TunnelDebugTrace}: 0-hop tunnel {Destination.Id32Short} created.");
#endif
            }
        }
Exemple #17
0
        public InboundTunnel(TunnelConfig config, int outtunnelhops) : base(config)
        {
            if (config != null)
            {
                Fake0HopTunnel = false;
                TunnelSetup    = config.Info;
                OutTunnelHops  = outtunnelhops;

                var gw = TunnelSetup.Hops[0];
                RemoteGateway   = gw.Peer.IdentHash;
                GatewayTunnelId = gw.TunnelId;

                ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId;

                DebugUtils.LogDebug("InboundTunnel: Tunnel " + Destination.Id32Short + " created.");
            }
            else
            {
                Fake0HopTunnel = true;

                var hops = new List <HopInfo>();
                hops.Add(new HopInfo(RouterContext.Inst.MyRouterIdentity, new I2PTunnelId()));
                TunnelSetup = new TunnelInfo(hops);

                Config = new TunnelConfig(
                    TunnelConfig.TunnelDirection.Inbound,
                    TunnelConfig.TunnelRole.Endpoint,
                    TunnelConfig.TunnelPool.Exploratory,
                    TunnelSetup);

                ReceiveTunnelId = TunnelSetup.Hops.Last().TunnelId;
                RemoteGateway   = RouterContext.Inst.MyRouterIdentity.IdentHash;
                GatewayTunnelId = ReceiveTunnelId;

                DebugUtils.LogDebug("InboundTunnel " + TunnelDebugTrace + ": 0-hop tunnel " + Destination.Id32Short + " created.");
            }
        }
Exemple #18
0
 protected I2NPHeader(BufRef reader, I2PTunnelId tunnel)
 {
     Buf        = reader.ReadBufLen(Length);
     FromTunnel = tunnel;
 }
Exemple #19
0
 public TunnelMessageTunnel(II2NPHeader16 header, InboundTunnel tunnel)
     : base(header, tunnel.Destination, DeliveryTypes.Tunnel)
 {
     Tunnel = tunnel.GatewayTunnelId;
 }
Exemple #20
0
 public HopInfo(I2PKeysAndCert dest, I2PTunnelId id)
 {
     Peer     = dest;
     TunnelId = id;
 }
Exemple #21
0
 public GarlicCloveDeliveryTunnel(I2NPMessage msg, I2PIdentHash dest, I2PTunnelId tunnel)
     : base(msg, DeliveryMethod.Tunnel)
 {
     Destination = dest;
     Tunnel      = tunnel;
 }
Exemple #22
0
 public GarlicCloveDeliveryTunnel(I2NPMessage msg, InboundTunnel tunnel)
     : base(msg, DeliveryMethod.Tunnel)
 {
     Destination = tunnel.Destination;
     Tunnel      = tunnel.GatewayTunnelId;
 }
Exemple #23
0
        private static PaddingInfo CalculatePadding(IEnumerable <TunnelMessage> messages, I2PTunnelId desttunnel)
        {
            var result = new PaddingInfo();

            int tunneldatabufferavailable = FREE_SPACE_IN_DATA_MESSAGE_BODY;
            var currenttdrecord           = new TunnelDataConstructionInfo(desttunnel);

            result.TDMessages.Add(currenttdrecord);

            var lastix = messages.Count() - 1;
            var ix     = 0;

            foreach (var one in messages)
            {
                var lastmessage = ix++ == lastix;

                var data       = one.Message.CreateHeader16.HeaderAndPayload;
                var datareader = new BufRefLen(data);

nexttunneldatablock:

                int firstfragmentheadersize;
                bool fragmented = false;

                switch (one.Delivery)
                {
                case TunnelMessage.DeliveryTypes.Local:
                    firstfragmentheadersize = 3;
                    if (data.Length + firstfragmentheadersize > tunneldatabufferavailable)
                    {
                        firstfragmentheadersize += 4;     // Need message id
                        fragmented = true;
                    }
                    break;

                case TunnelMessage.DeliveryTypes.Router:
                    firstfragmentheadersize = 35;
                    if (data.Length + firstfragmentheadersize > tunneldatabufferavailable)
                    {
                        firstfragmentheadersize += 4;     // Need message id
                        fragmented = true;
                    }
                    break;

                case TunnelMessage.DeliveryTypes.Tunnel:
                    firstfragmentheadersize = 39;
                    if (data.Length + firstfragmentheadersize > tunneldatabufferavailable)
                    {
                        firstfragmentheadersize += 4;     // Need message id
                        fragmented = true;
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }

                var freespace = tunneldatabufferavailable - firstfragmentheadersize;

                if (freespace < TUNNEL_DATA_MESSAGE_FREE_SPACE_LOW_WATERMARK)
                {
                    currenttdrecord.PaddingNeeded = tunneldatabufferavailable;

                    currenttdrecord = new TunnelDataConstructionInfo(desttunnel);
                    result.TDMessages.Add(currenttdrecord);
                    tunneldatabufferavailable = FREE_SPACE_IN_DATA_MESSAGE_BODY;
                    goto nexttunneldatablock;
                }

                // Might fit, and have at least TUNNEL_DATA_MESSAGE_FREE_SPACE_LOW_WATERMARK bytes for payload.

                var useddata  = fragmented ? freespace : datareader.Length;
                var usedspace = firstfragmentheadersize + useddata;

                currenttdrecord.Fragments.Add(
                    new TunnelDataFragmentCreation(
                        currenttdrecord.TunnelDataInstance,
                        one,
                        new BufLen(datareader, 0, useddata),
                        fragmented));

                datareader.Seek(useddata);

                tunneldatabufferavailable -= usedspace;

                int fragnr = 1;
                while (datareader.Length > 0)
                {
                    if (tunneldatabufferavailable < TUNNEL_DATA_MESSAGE_FREE_SPACE_LOW_WATERMARK + FOLLOW_ON_FRAGMENT_HEADER_SIZE)
                    {
                        currenttdrecord.PaddingNeeded = tunneldatabufferavailable;

                        currenttdrecord = new TunnelDataConstructionInfo(desttunnel);
                        result.TDMessages.Add(currenttdrecord);
                        tunneldatabufferavailable = FREE_SPACE_IN_DATA_MESSAGE_BODY;
                    }

                    freespace = tunneldatabufferavailable - FOLLOW_ON_FRAGMENT_HEADER_SIZE;

                    if (datareader.Length <= freespace)
                    {
                        currenttdrecord.Fragments.Add(
                            new TunnelDataFragmentFollowOn(
                                currenttdrecord.TunnelDataInstance,
                                one,
                                new BufLen(datareader),
                                fragnr++, true
                                ));

                        tunneldatabufferavailable -= FOLLOW_ON_FRAGMENT_HEADER_SIZE + datareader.Length;
                        datareader.Seek(datareader.Length);

                        if (lastmessage)
                        {
                            currenttdrecord.PaddingNeeded = tunneldatabufferavailable;
                            return(result);
                        }
                    }
                    else
                    {
                        useddata = freespace;

                        currenttdrecord.Fragments.Add(
                            new TunnelDataFragmentFollowOn(
                                currenttdrecord.TunnelDataInstance,
                                one,
                                new BufLen(datareader, 0, useddata),
                                fragnr++,
                                false
                                ));
                        datareader.Seek(useddata);

                        tunneldatabufferavailable = 0;
                    }
                }
            }

            currenttdrecord.PaddingNeeded = tunneldatabufferavailable;
            return(result);
        }
Exemple #24
0
 internal TunnelDataConstructionInfo(I2PTunnelId desttunnel)
 {
     TunnelDataInstance = new TunnelDataMessage(desttunnel);
 }
Exemple #25
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));
        }
        public static VariableTunnelBuildMessage BuildOutboundTunnel(
            TunnelInfo setup,
            I2PIdentHash replyaddr, I2PTunnelId replytunnel,
            uint replymessageid)
        {
            byte usehops = (byte)(setup.Hops.Count > 5 ? 8 : 5);
            //byte usehops = 7; // 8 makes the response "TunnelBuildReply"
            var result = new VariableTunnelBuildMessage(usehops);

            // Hop sort order
            var requests = new List <BuildRequestRecord>();

            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                // Hop order: Our out dest -> Endpoint
                var endpoint = i == setup.Hops.Count - 1;
                var gateway  = i == 0;

                var rec = new BuildRequestRecord();

                rec.Data.Randomize();
                rec.Flag = 0;

                var hop = setup.Hops[i];

                rec.OurIdent      = hop.Peer.IdentHash;
                rec.ReceiveTunnel = hop.TunnelId;

                if (!endpoint)
                {
                    var nexthop = setup.Hops[i + 1];

                    rec.NextIdent  = nexthop.Peer.IdentHash;
                    rec.NextTunnel = nexthop.TunnelId;
                }
                else
                {
                    rec.SendMessageId = replymessageid;

                    rec.NextIdent  = replyaddr;
                    rec.NextTunnel = replytunnel;
                }

                rec.RequestTime = DateTime.UtcNow;
                rec.ToAnyone    = endpoint;

                hop.LayerKey = new I2PSessionKey(rec.LayerKey.Clone());
                hop.IVKey    = new I2PSessionKey(rec.IVKey.Clone());

                requests.Add(rec);

#if LOG_ALL_TUNNEL_TRANSFER
                Logging.Log(rec.ToString());
#endif
            }

            // Physical record sort order
            var order = new List <AesEGBuildRequestRecord>(result.Records);
            order.Shuffle();

            // Scramble the rest
            for (int i = setup.Hops.Count; i < usehops; ++i)
            {
                order[i].Data.Randomize();
            }

            // ElGamal encrypt all of the non random records
            // and place them in shuffled order.
            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                var hop   = setup.Hops[i];
                var egrec = new EGBuildRequestRecord(order[i].Data, requests[i], hop.Peer.IdentHash, hop.Peer.PublicKey);
            }

            var cipher = new CbcBlockCipher(new AesEngine());

            // Dont Aes the first destination
            for (int i = setup.Hops.Count - 2; i >= 0; --i)
            {
                var prevhop = requests[i];

                cipher.Init(false, prevhop.ReplyKeyBuf.ToParametersWithIV(prevhop.ReplyIV));

                for (int j = i + 1; j < setup.Hops.Count; ++j)
                {
                    cipher.Reset();
                    cipher.ProcessBytes(order[j].Data);
                }
            }

            for (int i = 0; i < setup.Hops.Count; ++i)
            {
                setup.Hops[i].ReplyProcessing = new ReplyProcessingInfo()
                {
                    BuildRequestIndex = result.Records.IndexOf(order[i]),
                    ReplyIV           = requests[i].ReplyIV.Clone(),
                    ReplyKey          = new I2PSessionKey(requests[i].ReplyKeyBuf.Clone())
                };
            }

            return(result);
        }
Exemple #27
0
 public TunnelMessageTunnel(I2NPMessage message, I2PIdentHash destination, I2PTunnelId tunnel)
     : base(message, destination, DeliveryTypes.Tunnel)
 {
     Tunnel = tunnel;
 }
Exemple #28
0
 public TunnelMessageTunnel(II2NPHeader16 header, I2PIdentHash destination, I2PTunnelId tunnel)
     : base(header, destination, DeliveryTypes.Tunnel)
 {
     Tunnel = tunnel;
 }
Exemple #29
0
 public TunnelMessageTunnel(I2NPMessage message, InboundTunnel tunnel)
     : base(message, tunnel.Destination, DeliveryTypes.Tunnel)
 {
     Tunnel = tunnel.GatewayTunnelId;
 }