public void TestSimpleDatabaseStoreLeaseSetEd25519Creation()
        {
            var linfo  = new I2PLeaseInfo(Public, PublicSigningEd25519, Private, PrivateSigningEd25519);
            var leases = new List <I2PLease>();

            for (int i = 0; i < 5; ++i)
            {
                leases.Add(new I2PLease(new I2PIdentHash(true), (uint)((i * 72 + 6) * i * 1314 + 5) % 40000, I2PDate.Now));
            }
            var ls = new I2PLeaseSet(new I2PDestination(Public, PublicSigningEd25519), leases, linfo);

            var dbsm = new DatabaseStoreMessage(ls);

            var data = dbsm.Header16.HeaderAndPayload;

            var recreated = I2NPMessage.ReadHeader16(new BufRefLen(data));

            Assert.IsTrue(recreated.MessageType == I2NPMessage.MessageTypes.DatabaseStore);
            var rdsm = (DatabaseStoreMessage)recreated.Message;

            Assert.IsTrue(rdsm.LeaseSet.Leases.Count == 5);

            Assert.IsTrue(BufUtils.Equal(ls.Destination.ToByteArray(), rdsm.LeaseSet.Destination.ToByteArray()));
            Assert.IsTrue(BufUtils.Equal(ls.PublicKey.ToByteArray(), rdsm.LeaseSet.PublicKey.ToByteArray()));
            Assert.IsTrue(BufUtils.Equal(ls.PublicSigningKey.ToByteArray(), rdsm.LeaseSet.PublicSigningKey.ToByteArray()));
            for (int i = 0; i < 5; ++i)
            {
                Assert.IsTrue(BufUtils.Equal(ls.Leases[i].ToByteArray(), rdsm.LeaseSet.Leases[i].ToByteArray()));
            }

            Assert.IsTrue(rdsm.LeaseSet.VerifySignature());
        }
Beispiel #2
0
 public FFUpdateRequestInfo(I2PIdentHash ff, uint token, I2PLeaseSet ls, int retries)
 {
     CurrentTargetFF = ff;
     Token           = token;
     LeaseSet        = ls;
     Retries         = retries;
 }
Beispiel #3
0
        private void HandleHostLookupResult(I2PIdentHash hash, I2PLeaseSet ls, object o)
        {
            if (Session.Terminated)
            {
                return;
            }

            var hlinfo = (HostLookupInfo)o;

            Logging.LogDebug($"{this} HandleDestinationLookupResult: {hlinfo.SessionId} {hlinfo.RequestId} {hash.Id32Short} '{ls}'");

            if (ls != null)
            {
                Session.Send(new HostReplyMessage(
                                 hlinfo.SessionId,
                                 hlinfo.RequestId,
                                 ls.Destination));
                return;
            }

            Session.Send(new HostReplyMessage(
                             hlinfo.SessionId,
                             hlinfo.RequestId,
                             HostLookupResults.Failure));
        }
Beispiel #4
0
        internal ClientDestination(ClientTunnelProvider tp, I2PDestinationInfo dest, bool publishdest)
        {
            ClientTunnelMgr    = tp;
            PublishDestination = publishdest;
            ThisDestination    = dest;
            MyDestination      = new I2PDestination(ThisDestination);

            LeaseSet = new I2PLeaseSet(MyDestination, null, new I2PLeaseInfo(ThisDestination));

            IncommingSessions = new ReceivedSessions(ThisDestination.PrivateKey);
            Destinations      = new DestinationSessions((ls, header, inf) =>
            {
                DebugUtils.LogDebug(string.Format("ClientDestination: Execute: Sending data. TrackingId: {0} ({1}) ack {2}, msg {3}.",
                                                  inf.TrackingId, inf.KeyType, inf.AckMessageId, header));

                var outtunnel = OutboundEstablishedPool.Random();
                if (outtunnel == null || ls == null || ls.Leases.Count == 0)
                {
                    throw new FailedToConnectException("No tunnels available");
                }
                var lease = ls.Leases.Random();

                outtunnel.Send(
                    new TunnelMessageTunnel(header, lease.TunnelGw, lease.TunnelId));
            },
                                                        () => InboundEstablishedPool.Random());

            NetDb.Inst.IdentHashLookup.LeaseSetReceived += new IdentResolver.IdentResolverResultLeaseSet(IdentHashLookup_LeaseSetReceived);
            NetDb.Inst.IdentHashLookup.LookupFailure    += new IdentResolver.IdentResolverResultFail(IdentHashLookup_LookupFailure);
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
 public void AddLeaseSet(I2PLeaseSet leaseset)
 {
     LeaseSets[leaseset.Destination.IdentHash] = leaseset;
     if (LeaseSetUpdates != null)
     {
         ThreadPool.QueueUserWorkItem(a => LeaseSetUpdates(leaseset));
     }
 }
Beispiel #7
0
        internal void RemoteLeaseSetUpdated(I2PLeaseSet leaseset)
        {
            LatestRemoteLeaseSet = leaseset;

#if LOG_ALL_TUNNEL_TRANSFER
            Logging.LogDebug(() => string.Format(
                                 "DestinationSession: LeaseSet updated for {0}.", leaseset.Destination.IdentHash.Id32Short));
#endif
        }
        /// <summary>
        /// This is for any received lease update
        /// </summary>
        /// <param name="ls">Ls.</param>
        internal void PassiveLeaseSetUpdate(I2PLeaseSet ls)
        {
            if (Subscribers.TryGetValue(ls.Destination.IdentHash, out var info))
            {
                Logging.LogDebugData(
                    $"{Owner} RemoteDestinations: updating LeaseSet for {ls.Destination} (passive)");

                info.LeaseSet = ls;
            }
        }
 public CreateLeaseSetMessage(
     I2PDestination dest,
     ushort sessionid,
     I2PLeaseInfo info,
     List <I2PLease> leases) : base(ProtocolMessageType.CreateLS)
 {
     SessionId = sessionid;
     Info      = info;
     Leases    = new I2PLeaseSet(dest, leases, info);
 }
Beispiel #10
0
        void UpdateCachedFields(BufRef reader)
        {
            CachedKey        = new I2PIdentHash(reader);
            CachedContent    = reader.Read8() == 0 ? MessageContent.RouterInfo : MessageContent.LeaseSet;
            CachedReplyToken = reader.Read32();
            if (CachedReplyToken != 0)
            {
                CachedReplyTunnelId = reader.Read32();
                CachedReplyGateway  = new I2PIdentHash(reader);
            }

            switch (CachedContent)
            {
            case MessageContent.RouterInfo:
                var length = reader.ReadFlip16();

#if USE_BC_GZIP
                CachedRouterInfo = new I2PRouterInfo(
                    new BufRefLen(LZUtils.BCGZipDecompressNew(new BufLen(reader, 0, length))), true);
#else
                using (var ms = new MemoryStream())
                {
                    ms.Write(reader.BaseArray, reader.BaseArrayOffset, length);
                    ms.Position = 0;

                    using (var gzs = new GZipStream(ms, CompressionMode.Decompress))
                    {
                        var gzdata = StreamUtils.Read(gzs);
                        CachedRouterInfo = new I2PRouterInfo(new BufRefLen(gzdata), true);
                    }
                }
#endif

                reader.Seek(length);
                break;

            case MessageContent.LeaseSet:
                CachedLeaseSet = new I2PLeaseSet(reader);
                break;

            /*
             * case MessageContent.LeaseSet2:
             * break;
             *
             * case MessageContent.EncryptedLeaseSet:
             * break;
             *
             * case MessageContent.MetaLeaseSet:
             * break;
             */
            default:
                throw new InvalidDataException($"DatabaseStoreMessage: {CachedContent} not supported");
            }
        }
Beispiel #11
0
 static void MyDestination_SignLeasesRequest(I2PLeaseSet ls)
 {
     Logging.LogInformation($"Program {MyDestination}: Signing {ls} for publishing");
     PublishedDestination.SignedLeases = new I2PLeaseSet(
         MyDestination,
         ls.Leases,
         new I2PLeaseInfo(
             MyDestination.PublicKey,
             ls.PublicSigningKey,
             null,
             MyDestinationInfo.PrivateSigningKey));
 }
Beispiel #12
0
        static void LookupResult(I2PIdentHash hash, I2PLeaseSet ls, object o)
        {
            Logging.LogInformation($"Program {MyOrigin}: LookupResult {hash.Id32Short} {ls}");

            if (ls is null)
            {
                // Try again
                MyOrigin.LookupDestination(PublishedDestination.Destination.IdentHash, LookupResult);
                return;
            }

            LookedUpDestination = ls.Destination;
        }
Beispiel #13
0
        public CreateLeaseSetMessage(BufRef reader, I2CPSession session)
            : base(ProtocolMessageType.CreateLS)
        {
            SessionId = reader.ReadFlip16();

            var cert = session.SessionIds[SessionId].Config.Destination.Certificate;

            DSAPrivateSigningKey = new I2PSigningPrivateKey(
                reader,
                new I2PCertificate(I2PSigningKey.SigningKeyTypes.DSA_SHA1));

            PrivateKey = new I2PPrivateKey(reader, cert);
            Leases     = new I2PLeaseSet(reader);
        }
Beispiel #14
0
        void IdentHashLookup_LeaseSetReceived(I2PLeaseSet ls)
        {
            var key = ls.Destination.IdentHash;

            lock ( UnresolvedDestinations )
            {
                DestinationLookupResult cb;

                if (UnresolvedDestinations.TryGetValue(key, out cb))
                {
                    cb(key, ls);
                    UnresolvedDestinations.Remove(key);
                }
            }
        }
Beispiel #15
0
        void NetDb_LeaseSetUpdates(I2PLeaseSet ls)
        {
            if (!OutstandingQueries.TryRemove(ls.Destination.IdentHash, out var info))
            {
                return;
            }

            Logging.Log(string.Format("IdentResolver: Lookup of LeaseSet {0} succeeded. {1}",
                                      ls.Destination.IdentHash.Id32Short, info.Start.DeltaToNow));

            if (LeaseSetReceived != null)
            {
                ThreadPool.QueueUserWorkItem(a => LeaseSetReceived(ls));
            }
        }
Beispiel #16
0
        void HandleDestinationLookupResult(I2PIdentHash hash, I2PLeaseSet ls, object o)
        {
            if (Session.Terminated)
            {
                return;
            }

            Logging.LogDebug($"{this} HandleDestinationLookupResult: {hash.Id32Short} '{ls}'");

            if (ls != null)
            {
                Session.Send(new DestReplyMessage(ls.Destination));
                return;
            }

            Session.Send(new DestReplyMessage(hash));
        }
Beispiel #17
0
        internal void LocalLeaseSetUpdated(I2PLeaseSet leaseset)
        {
            LatestLocalLeaseSet = leaseset;
            var dbsmessage = new DatabaseStoreMessage(leaseset);
            var info       = Send(true, new GarlicCloveDeliveryDestination(dbsmessage, Destination.IdentHash));

#if LOG_ALL_TUNNEL_TRANSFER
            if (info != null)
            {
                Logging.LogDebug(() => string.Format(
                                     "DestinationSession: LeaseSet update bundled in Destination trafic. ({0}) TrackingId: {1}, Ack MessageId: {2}.",
                                     info.KeyType, info.TrackingId, info.AckMessageId));
            }
#endif

            LatestLeaseSetSendTime.SetNow();
        }
Beispiel #18
0
        private void SendLeaseSetUpdateGarlic(
            I2PIdentHash ffdest,
            I2PPublicKey pubkey,
            I2PLeaseSet ls,
            uint token)
        {
            // If greater than zero, a DeliveryStatusMessage
            // is requested with the Message ID set to the value of the Reply Token.
            // A floodfill router is also expected to flood the data to the closest floodfill peers
            // if the token is greater than zero.
            // https://geti2p.net/spec/i2np#databasestore

            var outtunnel = TunnelProvider.Inst.GetEstablishedOutboundTunnel(false);

            var replytunnel = ls.Leases.Random();

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

            var ds          = new DatabaseStoreMessage(ls);
            var delivstatus = new DeliveryStatusMessage(token);

            // As explained on the network database page, local LeaseSets are sent to floodfill
            // routers in a Database Store Message wrapped in a Garlic Message so it is not
            // visible to the tunnel's outbound gateway.

            var garlic = new Garlic(
                new GarlicClove(
                    new GarlicCloveDeliveryLocal(ds)),
                new GarlicClove(
                    new GarlicCloveDeliveryTunnel(delivstatus, replytunnel.TunnelGw, replytunnel.TunnelId))
                );

            var egmsg = Garlic.EGEncryptGarlic(garlic, pubkey, new I2PSessionKey(), null);

            outtunnel.Send(
                new TunnelMessageRouter(
                    egmsg,
                    ffdest));
        }
Beispiel #19
0
        public void TestSimpleDatabaseStoreLeaseSetCreation()
        {
            var linfo = new I2PLeaseInfo(Public, PublicSigning, Private, PrivateSigning);

            var leases = new List <I2PLease>();

            for (int i = 0; i < 5; ++i)
            {
                leases.Add(new I2PLease(
                               new I2PIdentHash(true),
                               new I2PTunnelId()));
            }

            var ls = new I2PLeaseSet(new I2PDestination(Public, PublicSigning), leases, linfo);

            var dbsm = new DatabaseStoreMessage(ls);

            var data = dbsm.CreateHeader16.HeaderAndPayload.Clone();

            var recreated = I2NPMessage.ReadHeader16(new BufRefLen(data));

            Assert.IsTrue(recreated.MessageType == I2NPMessage.MessageTypes.DatabaseStore);
            var rdsm = (DatabaseStoreMessage)recreated.Message;

            Assert.IsTrue(rdsm.LeaseSet.Leases.Count() == 5);

            Assert.IsTrue(BufUtils.Equal(ls.Destination.ToByteArray(), rdsm.LeaseSet.Destination.ToByteArray()));
            Assert.IsTrue(BufUtils.Equal(ls.PublicKey.ToByteArray(), rdsm.LeaseSet.PublicKey.ToByteArray()));
            Assert.IsTrue(BufUtils.Equal(ls.PublicSigningKey.ToByteArray(), rdsm.LeaseSet.PublicSigningKey.ToByteArray()));

            var rdsmlsar = rdsm.LeaseSet.Leases.ToArray();
            var lsar     = ls.Leases.ToArray();

            // Order should be maintained
            for (int i = 0; i < 5; ++i)
            {
                Assert.IsTrue(
                    BufUtils.Equal(
                        lsar[i].ToByteArray(),
                        rdsmlsar[i].ToByteArray()));
            }

            Assert.IsTrue(rdsm.LeaseSet.VerifySignature(PublicSigning));
        }
Beispiel #20
0
        private void NewIdentity()
        {
            ThisDestination = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519);
            MyDestination   = new I2PDestination(ThisDestination);

            LeaseSet = new I2PLeaseSet(MyDestination, null, new I2PLeaseInfo(ThisDestination));

            IncommingSessions = new ReceivedSessions(ThisDestination.PrivateKey);
            Destinations      = new DestinationSessions((dest, header, inf) =>
            {
                DebugUtils.LogDebug(string.Format("ClientDestination: Execute: Sending data. TrackingId: {0} ({1}) ack {2}, msg {3}.",
                                                  inf.TrackingId, inf.KeyType, inf.AckMessageId, header));

                var outtunnel = OutboundEstablishedPool.Random();
                outtunnel.Send(
                    new TunnelMessageTunnel(header, TestRemoteDest.InboundEstablishedPool.Random()));
            },
                                                        () => InboundEstablishedPool.Random());
        }
        /// <summary>
        /// This is used for destinations we have actively looked up.
        /// </summary>
        /// <param name="ls">Ls.</param>
        public void LeaseSetReceived(I2PLeaseSet ls)
        {
            if (!Subscribers.TryGetValue(ls.Destination.IdentHash, out var info))
            {
                Logging.LogDebug(
                    $"{Owner} RemoteDestinations: adding {ls.Destination}");

                info = new DestLeaseInfo {
                    LeaseSet = ls
                };
                Subscribers[ls.Destination.IdentHash] = info;
            }
            else
            {
                Logging.LogDebug(
                    $"{Owner} RemoteDestinations: updating {ls.Destination}");

                info.LeaseSet = ls;
            }
        }
Beispiel #22
0
        public void TestI2PLeaseSet()
        {
            var destinfo = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519);
            var dest     = destinfo.Destination;

            var leases = Enumerable.Range(1, 8).Select(i => new I2PLease(new I2PIdentHash(true), new I2PTunnelId()));
            var ls     = new I2PLeaseSet(dest, leases, new I2PLeaseInfo(destinfo));

            Assert.IsTrue(ls.VerifySignature(dest.SigningPublicKey));

            var ls2 = new I2PLeaseSet(new BufRefLen(ls.ToByteArray()));

            Assert.IsTrue(ls2.VerifySignature(dest.SigningPublicKey));

            var ls3 = new I2PLeaseSet(ls2.Destination, ls2.Leases, new I2PLeaseInfo(destinfo));

            Assert.IsTrue(ls3.VerifySignature(dest.SigningPublicKey));

            Assert.IsTrue(new BufLen(ls.ToByteArray()) == new BufLen(ls3.ToByteArray()));
        }
Beispiel #23
0
        static void IdentHashLookup_LeaseSetReceived(I2PLeaseSet ls)
        {
            var key = ls.Destination.IdentHash;

            lock ( UnresolvedDestinations )
            {
                var cbs = UnresolvedDestinations
                          .Where(e => e.Id == key)
                          .ToArray();

                foreach (var cbe in cbs)
                {
                    if (UnresolvedDestinations.Remove(cbe))
                    {
                        ThreadPool.QueueUserWorkItem(a =>
                                                     cbe.Callback.Invoke(cbe.Id, ls, cbe.Tag));
                    }
                }
            }
        }
Beispiel #24
0
        void StartNewUpdatesLeaseSet(I2PLeaseSet ls)
        {
            // old lease sets are out of date
            while (OutstandingRequests.TryRemove(
                       OutstandingRequests.Where(r => r.Value?.LeaseSet == ls)
                       .Select(r => r.Key)
                       .FirstOrDefault(),
                       out var _))
            {
            }

            var list = GetNewFFList(
                ls.Destination.IdentHash,
                2);

            var destinations = list.Select(i => NetDb.Inst[i]);

            foreach (var ff in destinations)
            {
                try
                {
                    var ffident = ff.Identity.IdentHash;
                    var token   = BufUtils.RandomUint() | 1;

                    Logging.Log($"FloodfillUpdater: New LS update started for " +
                                $"{ls.Destination.IdentHash.Id32Short}, {ls.Leases.Count()} leases " +
                                $"update {ffident.Id32Short}, token {token,10}, " +
                                $"dist: {ffident ^ ls.Destination.IdentHash.RoutingKey}.");

                    OutstandingRequests[token] = new FFUpdateRequestInfo(ffident, token, ls, 0);

                    SendLeaseSetUpdateGarlic(ffident, ff.Identity.PublicKey, ls, token);
                }
                catch (Exception ex)
                {
                    Logging.Log(ex);
                }
            }
        }
Beispiel #25
0
        void UpdateCachedFields(BufRef reader)
        {
            CachedKey        = new I2PIdentHash(reader);
            CachedContent    = reader.Read8() == 0 ? MessageContent.RouterInfo : MessageContent.LeaseSet;
            CachedReplyToken = reader.Read32();
            if (CachedReplyToken != 0)
            {
                CachedReplyTunnelId = reader.Read32();
                CachedReplyGateway  = new I2PIdentHash(reader);
            }

            if (CachedContent == MessageContent.RouterInfo)
            {
                var length = reader.ReadFlip16();

#if USE_BC_GZIP
                CachedRouterInfo = new I2PRouterInfo(
                    new BufRefLen(LZUtils.BCGZipDecompressNew(new BufLen(reader, 0, length))), true);
#else
                using (var ms = new MemoryStream())
                {
                    ms.Write(reader.BaseArray, reader.BaseArrayOffset, length);
                    ms.Position = 0;

                    using (var gzs = new GZipStream(ms, CompressionMode.Decompress))
                    {
                        var gzdata = StreamUtils.Read(gzs);
                        CachedRouterInfo = new I2PRouterInfo(new BufRefLen(gzdata), true);
                    }
                }
#endif

                reader.Seek(length);
            }
            else
            {
                CachedLeaseSet = new I2PLeaseSet(reader);
            }
        }
Beispiel #26
0
        public void AddLeaseSet(I2PLeaseSet leaseset)
        {
            if (!leaseset.VerifySignature(leaseset.Destination.SigningPublicKey))
            {
                Logging.LogWarning($"LeaseSet {0} signature verification failed.");
                return;
            }

            if (LeaseSets.TryGetValue(leaseset.Destination.IdentHash, out var extls))
            {
                if (extls.EndOfLife > leaseset.EndOfLife)
                {
                    return;
                }
            }

            LeaseSets[leaseset.Destination.IdentHash] = leaseset;

            if (LeaseSetUpdates != null)
            {
                ThreadPool.QueueUserWorkItem(a => LeaseSetUpdates(leaseset));
            }
        }
Beispiel #27
0
 static void LookupResult(I2PIdentHash hash, I2PLeaseSet ls)
 {
     LS = ls;
 }
Beispiel #28
0
 internal void LocalLeaseSetUpdated(I2PLeaseSet leaseset)
 {
     this[leaseset.Destination].LocalLeaseSetUpdated(leaseset);
 }
Beispiel #29
0
 internal void RemoteLeaseSetUpdated(I2PLeaseSet leaseset)
 {
     this[leaseset.Destination].RemoteLeaseSetUpdated(leaseset);
 }
Beispiel #30
0
 public void Send(I2PLeaseSet ls, byte[] data, bool ack)
 {
     Destinations.RemoteLeaseSetUpdated(ls);
     Destinations.Send(ls.Destination, ack,
                       new GarlicCloveDeliveryDestination(new DataMessage(new BufLen(data)), ls.Destination.IdentHash));
 }