public void MakeAndReadFragment()
        {
            var arec = new DatabaseLookupMessage(
                new I2PIdentHash(true),
                new I2PIdentHash(true),
                DatabaseLookupMessage.LookupTypes.Normal);

            var msg = new TunnelMessageRouter(
                arec,
                new I2PIdentHash(true));

            var refmsgdata = msg.Message.CreateHeader16.HeaderAndPayload;

            var fragments = TunnelDataMessage.MakeFragments(
                new TunnelMessage[] { msg },
                BufUtils.RandomUint());

            var mkmsg     = new TunnelDataFragmentReassembly();
            var recvtmsgs = mkmsg.Process(fragments.Shuffle().ToArray(), out var _);

            foreach (var rmsg in recvtmsgs)
            {
                var rmsgdata = rmsg.Message.CreateHeader16.HeaderAndPayload;
                Assert.IsTrue(msg.Delivery == rmsg.Delivery);
                Assert.IsTrue(refmsgdata == rmsgdata);
            }
        }
示例#2
0
        /*
         * Exploration
         *
         * Exploration is a special form of netdb lookup, where a router attempts to learn about new routers.
         * It does this by sending a floodfill router a I2NP DatabaseLookupMessage, looking for a random key.
         * As this lookup will fail, the floodfill would normally respond with a I2NP DatabaseSearchReplyMessage
         * containing hashes of floodfill routers close to the key. This would not be helpful, as the requesting
         * router probably already knows those floodfills, and it would be impractical to add ALL floodfill
         * routers to the "don't include" field of the lookup. For an exploration query, the requesting router
         * adds a router hash of all zeros to the "don't include" field of the DatabaseLookupMessage.
         *
         * The floodfill will then respond only with non-floodfill routers close to the requested key.
         *
         * https://geti2p.net/en/docs/how/network-database
         *
         *  11  => exploration lookup, return DatabaseSearchReplyMessage
         *          containing non-floodfill routers only (replaces an
         *          excludedPeer of all zeroes)
         * https://geti2p.net/spec/i2np#databaselookup
         */
        void ExplorationRouterLookup()
        {
            I2PIdentHash ident = new I2PIdentHash(true);

            var ff = NetDb.Inst.GetClosestFloodfill(ident, 10, null, false)
                     .Shuffle()
                     .Take(DatabaseLookupSelectFloodfillCount)
                     .ToArray();

            foreach (var oneff in ff)
            {
                var msg = new DatabaseLookupMessage(
                    ident,
                    RouterContext.Inst.MyRouterIdentity.IdentHash,
                    DatabaseLookupMessage.LookupTypes.Exploration,
                    new I2PIdentHash[] { new I2PIdentHash(false) });

#if LOG_ALL_IDENT_LOOKUPS
                Logging.Log("IdentResolver: Random router lookup " + ident.Id32Short + " sent to " + oneff.Id32Short);
#endif
                try
                {
                    TransportProvider.Send(oneff, msg);
                }
                catch (Exception ex)
                {
                    Logging.Log(ex);
                }
            }
        }
        public void MakeAndReadFragmentsWithSerialize()
        {
            var origmsgs = new List <TunnelMessage>();

            for (int i = 0; i < 200; ++i)
            {
                switch (BufUtils.RandomInt(3))
                {
                case 0:
                    var adatarec = new DataMessage(
                        new BufLen(
                            BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageLocal(adatarec));
                    break;

                case 1:
                    var arec = new DatabaseLookupMessage(
                        new I2PIdentHash(true),
                        new I2PIdentHash(true),
                        DatabaseLookupMessage.LookupTypes.RouterInfo);

                    origmsgs.Add(new TunnelMessageRouter(
                                     arec,
                                     new I2PIdentHash(true)));
                    break;

                case 2:
                    var adatarec2 = new DataMessage(
                        new BufLen(
                            BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageTunnel(adatarec2,
                                                         new I2PIdentHash(true),
                                                         BufUtils.RandomUint()));
                    break;
                }
            }

            var msgs     = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint());
            var recvlist = new List <TunnelDataMessage>();

            foreach (var msg in msgs)
            {
                recvlist.Add((TunnelDataMessage)I2NPMessage.ReadHeader16(
                                 new BufRefLen(msg.CreateHeader16.HeaderAndPayload)).Message);
            }

            var mkmsg     = new TunnelDataFragmentReassembly();
            var recvtmsgs = mkmsg.Process(recvlist, out var _);

            foreach (var rmsg in recvtmsgs)
            {
                Assert.IsTrue(origmsgs.SingleOrDefault(m =>
                                                       m.Delivery == rmsg.Delivery &&
                                                       m.Message.CreateHeader16.HeaderAndPayload == rmsg.Message.CreateHeader16.HeaderAndPayload
                                                       ) != null);
            }
        }
示例#4
0
        public void MakeAndReadFragments()
        {
            var origmsgs = new List <TunnelMessage>();

            for (int i = 0; i < 200; ++i)
            {
                switch (BufUtils.RandomInt(3))
                {
                case 0:
                    var adatarec = new DataMessage(new BufLen(BufUtils.Random(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageTunnel(
                                     adatarec.Header16,
                                     new I2PIdentHash(true),
                                     BufUtils.RandomUint()));
                    break;

                case 1:
                    var arec = new DatabaseLookupMessage(
                        new I2PIdentHash(true),
                        new I2PIdentHash(true),
                        DatabaseLookupMessage.LookupTypes.Normal);

                    origmsgs.Add(new TunnelMessageRouter(arec.Header16, new I2PIdentHash(true)));
                    break;

                case 2:
                    var adatarec2 = new DataMessage(new BufLen(BufUtils.Random(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageLocal(adatarec2.Header16));
                    break;
                }
            }

            var msgs = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint());

            var mkmsg     = new TunnelDataFragmentReassembly();
            var recvtmsgs = mkmsg.Process(msgs);

            foreach (var rmsg in recvtmsgs)
            {
                Assert.IsTrue(origmsgs.SingleOrDefault(m =>
                                                       m.Delivery == rmsg.Delivery &&
                                                       m.Header.HeaderAndPayload == rmsg.Header.HeaderAndPayload
                                                       ) != null);
            }
        }
示例#5
0
        private void SendRIDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info)
        {
            var ff = NetDb.Inst.GetClosestFloodfill(
                ident,
                10 + 3 * info.Retries,
                info.AlreadyQueried,
                false);

            if (!ff.Any())
            {
                Logging.Log($"IdentResolver: failed to find a floodfill router to lookup ({ident}): ");
                return;
            }

            ff.Shuffle();
            ff = ff.Take(DatabaseLookupSelectFloodfillCount).ToArray();

            foreach (var oneff in ff)
            {
                try
                {
                    var msg = new DatabaseLookupMessage(
                        ident,
                        RouterContext.Inst.MyRouterIdentity.IdentHash,
                        DatabaseLookupMessage.LookupTypes.RouterInfo);

                    TransportProvider.Send(oneff, msg);
#if LOG_ALL_IDENT_LOOKUPS
                    Logging.Log($"IdentResolver: RouterInfo query {msg.Key.Id32Short} sent to {oneff.Id32Short}");
#endif
                }
                catch (Exception ex)
                {
                    Logging.Log("SendRIDatabaseLookup", ex);
                }
            }

            foreach (var f in ff)
            {
                info.AlreadyQueried.Add(f);
            }
        }
示例#6
0
        private void SendRIDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info)
        {
            var ff = NetDb.Inst.GetClosestFloodfill(ident, 10, info.AlreadyQueried, false).ToArray();

            if (ff == null || ff.Length == 0)
            {
                DebugUtils.Log("IdentResolver: failed to find a floodfill router to lookup (" + ident.ToString() + "): ");
                return;
            }

            ff.Shuffle();
            ff = ff.Take(DatabaseLookupSelectFloodfillCount).ToArray();

            foreach (var oneff in ff)
            {
                try
                {
                    var msg = new DatabaseLookupMessage(
                        ident,
                        RouterContext.Inst.MyRouterIdentity.IdentHash,
                        DatabaseLookupMessage.LookupTypes.RouterInfo);

                    TransportProvider.Send(oneff, msg);
#if LOG_ALL_IDENT_LOOKUPS
                    DebugUtils.Log("IdentResolver: RouterInfo query " + msg.Key.Id32Short + " sent to " + oneff.Id32Short);
#endif
                }
                catch (Exception ex)
                {
                    DebugUtils.Log("SendRIDatabaseLookup", ex);
                }
            }

            lock (info.AlreadyQueried)
            {
                info.AlreadyQueried.AddRange(ff);
            }
        }
        public void MakeAndReadFragments100()
        {
            var origmsgs = new List <TunnelMessage>();

            for (int i = 0; i < 100; ++i)
            {
                switch (BufUtils.RandomInt(3))
                {
                case 0:
                    var adatarec = new DataMessage(new BufLen(BufUtils.RandomBytes(2048)));

                    origmsgs.Add(new TunnelMessageTunnel(
                                     adatarec,
                                     new I2PIdentHash(true),
                                     BufUtils.RandomUint()));
                    break;

                case 1:
                    var arec = new DatabaseLookupMessage(
                        new I2PIdentHash(true),
                        new I2PIdentHash(true),
                        DatabaseLookupMessage.LookupTypes.Normal);

                    origmsgs.Add(new TunnelMessageRouter(
                                     arec,
                                     new I2PIdentHash(true)));
                    break;

                case 2:
                    var adatarec2 = new DataMessage(
                        new BufLen(
                            BufUtils.RandomBytes(2048 + BufUtils.RandomInt(1024))));

                    origmsgs.Add(new TunnelMessageLocal(adatarec2));
                    break;
                }
            }

            var msgs   = TunnelDataMessage.MakeFragments(origmsgs, BufUtils.RandomUint());
            var mkmsg  = new TunnelDataFragmentReassembly();
            var chunks = msgs
                         .Shuffle()
                         .ToArray()
                         .Chunk(a => 1 + BufUtils.RandomInt(10))
                         .Shuffle();

            var recvtmsgs = chunks.SelectMany(c => mkmsg.Process(c, out var _)).ToArray();

            Assert.IsTrue(origmsgs.All(o => recvtmsgs.Any(m =>
                                                          m.Delivery == o.Delivery &&
                                                          m.Message.CreateHeader16.HeaderAndPayload == o.Message.CreateHeader16.HeaderAndPayload
                                                          )));

            var mkmsg2  = new TunnelDataFragmentReassembly();
            var chunks2 = msgs
                          .Shuffle()
                          .ToArray()
                          .Skip(1)
                          .Chunk(a => 1 + BufUtils.RandomInt(10))
                          .Shuffle();

            var recvtmsgs2 = chunks2.SelectMany(c => mkmsg2.Process(c, out var _)).ToArray();

            Assert.IsFalse(origmsgs.All(o => recvtmsgs2.Any(m =>
                                                            m.Delivery == o.Delivery &&
                                                            m.Message.CreateHeader16.HeaderAndPayload == o.Message.CreateHeader16.HeaderAndPayload
                                                            )));
        }
示例#8
0
        private void SendLSDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info)
        {
            var outtunnel   = TunnelProvider.Inst.GetEstablishedOutboundTunnel(true);
            var replytunnel = TunnelProvider.Inst.GetInboundTunnel(true);

            if (outtunnel is null || replytunnel is null)
            {
                Logging.LogDebug($"SendLSDatabaseLookup: " +
                                 $"outtunnel: {outtunnel}, replytunnel: {replytunnel}");
                return;
            }

            var getnext = DateTime.UtcNow.Hour >= 23;
            var ff      = NetDb.Inst.GetClosestFloodfill(
                ident,
                DatabaseLookupSelectFloodfillCount + 2 * info.Retries,
                info.AlreadyQueried,
                getnext)
                          .Select(r => new { Id = r, NetDb.Inst.Statistics[r].Score });

#if LOG_ALL_IDENT_LOOKUPS
            StringBuilder foundrouters     = new StringBuilder();
            StringBuilder foundrouterskeys = new StringBuilder();

            foreach (var router in ff)
            {
                foundrouters.AppendFormat("{0}{1}{2}", (foundrouters.Length != 0 ? ", " : ""),
                                          router.Id32Short,
                                          FreenetBase64.Encode(router.Hash));
                foundrouterskeys.AppendFormat("{0}{1}{2}", (foundrouterskeys.Length != 0 ? ", " : ""),
                                              router.Id32Short,
                                              FreenetBase64.Encode(router.RoutingKey.Hash));
            }
            var st  = foundrouters.ToString();
            var st2 = foundrouterskeys.ToString();
#endif

            if (!ff.Any())
            {
                Logging.Log($"IdentResolver failed to find a floodfill router to lookup ({ident}): ");
                return;
            }

            var minscore = ff.Min(r => r.Score);

            for (int i = 0; i < DatabaseLookupSelectFloodfillCount; ++i)
            {
                var oneff = ff
                            .RandomWeighted(r => r.Score - minscore + 0.1)
                            .Id;
                try
                {
                    var msg = new DatabaseLookupMessage(
                        ident,
                        replytunnel.Destination, replytunnel.GatewayTunnelId,
                        DatabaseLookupMessage.LookupTypes.LeaseSet, null);

                    outtunnel.Send(new TunnelMessageRouter(msg, oneff));

                    info.AlreadyQueried.Add(oneff);

#if !LOG_ALL_IDENT_LOOKUPS
                    Logging.Log($"IdentResolver: LeaseSet query {msg.Key.Id32Short} " +
                                $"sent to {oneff.Id32Short}. Dist: {oneff ^ msg.Key.RoutingKey}");
#endif
                }
                catch (Exception ex)
                {
                    Logging.Log("SendLSDatabaseLookup", ex);
                }
            }
        }
示例#9
0
        private void SendLSDatabaseLookup(I2PIdentHash ident, IdentUpdateRequestInfo info)
        {
            /*
             * var replytunnel = TunnelProvider.Inst.GetInboundTunnel();
             * if ( replytunnel == null ) return;
             */

            var ff = NetDb.Inst.GetClosestFloodfill(ident, DatabaseLookupSelectFloodfillCount * 2, info.AlreadyQueried, false).ToArray();

#if LOG_ALL_IDENT_LOOKUPS
            StringBuilder foundrouters     = new StringBuilder();
            StringBuilder foundrouterskeys = new StringBuilder();

            foreach (var router in ff)
            {
                foundrouters.AppendFormat("{0}{1}{2}", (foundrouters.Length != 0 ? ", " : ""),
                                          router.Id32Short,
                                          FreenetBase64.Encode(router.Hash));
                foundrouterskeys.AppendFormat("{0}{1}{2}", (foundrouterskeys.Length != 0 ? ", " : ""),
                                              router.Id32Short,
                                              FreenetBase64.Encode(router.RoutingKey.Hash));
            }
            var st  = foundrouters.ToString();
            var st2 = foundrouterskeys.ToString();
#endif

            if (ff == null || ff.Length == 0)
            {
                DebugUtils.Log("IdentResolver failed to find a floodfill router to lookup (" + ident.ToString() + "): ");
                return;
            }

            ff.Shuffle();
            ff = ff.Take(DatabaseLookupSelectFloodfillCount).ToArray();

            foreach (var oneff in ff)
            {
                try
                {
                    var msg = new DatabaseLookupMessage(
                        ident,
                        RouterContext.Inst.MyRouterIdentity.IdentHash,
                        DatabaseLookupMessage.LookupTypes.LeaseSet);

                    /*
                     * var msg = new DatabaseLookupMessage(
                     *          ident,
                     *          replytunnel.Destination, replytunnel.GatewayTunnelId,
                     *          DatabaseLookupMessage.LookupTypes.LeaseSet, null );
                     */

                    //TunnelProvider.Inst.SendEncrypted( oneff.Identity, false, msg );
                    TransportProvider.Send(oneff, msg);
#if LOG_ALL_IDENT_LOOKUPS
                    DebugUtils.Log(string.Format("IdentResolver: LeaseSet query {0} sent to {1}. Dist: {2}",
                                                 msg.Key.Id32Short,
                                                 oneff.Id32Short,
                                                 oneff ^ msg.Key.RoutingKey));
#endif
                }
                catch (Exception ex)
                {
                    DebugUtils.Log("SendLSDatabaseLookup", ex);
                }
            }

            lock (info.AlreadyQueried)
            {
                info.AlreadyQueried.AddRange(ff);
            }
        }
示例#10
0
        public static I2NPMessage GetMessage(
            I2NPMessage.MessageTypes messagetype,
            BufRef reader,
            uint?msgid = null)
        {
            I2NPMessage result = null;

            try
            {
                switch (messagetype)
                {
                case I2NPMessage.MessageTypes.Garlic:
                    result = new GarlicMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.Data:
                    result = new DataMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.DatabaseSearchReply:
                    result = new DatabaseSearchReplyMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.DatabaseStore:
                    result = new DatabaseStoreMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.DeliveryStatus:
                    result = new DeliveryStatusMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.TunnelData:
                    result = new TunnelDataMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.TunnelGateway:
                    result = new TunnelGatewayMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.DatabaseLookup:
                    result = new DatabaseLookupMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.VariableTunnelBuild:
                    result = new VariableTunnelBuildMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.TunnelBuild:
                    result = new TunnelBuildMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.TunnelBuildReply:
                    result = new TunnelBuildReplyMessage(reader);
                    break;

                case I2NPMessage.MessageTypes.VariableTunnelBuildReply:
                    result = new VariableTunnelBuildReplyMessage(reader);
                    break;

                default:
                    Logging.LogDebug($"GetMessage: '{messagetype}' is not a known message type!");
                    throw new NotImplementedException();
                }
            }
            catch (Exception ex)
            {
                Logging.Log("GetMessage", ex);
                throw;
            }

            if (result != null && msgid.HasValue)
            {
                result.MessageId = msgid.Value;
            }

            return(result);
        }