Пример #1
0
        public void TestSimpleDatabaseHeader5StoreCreation()
        {
            var mapping = new I2PMapping();

            mapping["One"] = "1";
            mapping["2"]   = "Two";

            var ri = new I2PRouterInfo(
                new I2PRouterIdentity(Public, PublicSigning),
                I2PDate.Now,
                new I2PRouterAddress[] { new I2PRouterAddress(new IPAddress(424242L), 773, 42, "SSU") },
                mapping,
                PrivateSigning);

            var dbsm = new DatabaseStoreMessage(ri);

            var data = dbsm.CreateHeader16.HeaderAndPayload;

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

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

            Assert.IsTrue(rdsm.RouterInfo.Options["One"] == "1");
            Assert.IsTrue(rdsm.RouterInfo.Options["2"] == "Two");
            Assert.IsTrue(rdsm.RouterInfo.VerifySignature());
        }
Пример #2
0
        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());
        }
Пример #3
0
        private ITransport CreateTransport(I2PRouterInfo ri)
        {
            ITransport transport = null;

            try
            {
                var pproviders = TransportProtocols
                                 .Select(tp => new
                {
                    Provider   = tp,
                    Capability = tp.ContactCapability(ri)
                })
                                 .Where(tp => tp.Capability != ProtocolCapabilities.None)
                                 .GroupBy(tp => tp.Capability)
                                 .OrderByDescending(cc => (int)cc.Key);

                var pprovider = pproviders.FirstOrDefault()?.Random();

                if (pprovider == null)
                {
                    Logging.LogTransport(
                        $"TransportProvider: CreateTransport: No usable address found for {ri.Identity.IdentHash.Id32Short}!");
                    return(null);
                }

                transport = pprovider.Provider.AddSession(ri);

                Logging.LogTransport($"TransportProvider: Creating new {transport} to {ri.Identity.IdentHash.Id32Short}");

                AddTransport(transport);
                transport.Connect();

                var dstore = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo);
                transport.Send(dstore);
            }
            catch (Exception ex)
            {
#if LOG_MUCH_TRANSPORT
                Logging.LogTransport(ex);
                Logging.LogTransport("TransportProvider: CreateTransport stack trace: " + System.Environment.StackTrace);
#else
                Logging.LogTransport($"TransportProvider: Exception [{ex.GetType()}] " +
                                     $"'{ex.Message}' to {ri.Identity.IdentHash.Id32Short}.");
#endif
                if (transport != null)
                {
                    Remove(transport);
                }
                throw;
            }

            return(transport);
        }
Пример #4
0
        private void SendUpdate(I2PIdentHash ff, 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 ds = new DatabaseStoreMessage(
                RouterContext.Inst.MyRouterInfo,
                token,
                RouterContext.Inst.MyRouterInfo.Identity.IdentHash,
                0);

            TransportProvider.Send(ff, ds);
        }
Пример #5
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();
        }
Пример #6
0
        DatabaseStoreMessage CreateDatabaseStoreMessage()
        {
            var mapping = new I2PMapping();

            mapping["One"] = "1";
            mapping["2"]   = "Two";

            var ri = new I2PRouterInfo(
                new I2PRouterIdentity(Public, PublicSigning),
                I2PDate.Now,
                new I2PRouterAddress[] { new I2PRouterAddress(new IPAddress(424242L), 773, 42, "SSU") },
                mapping,
                PrivateSigning);

            var dbsm = new DatabaseStoreMessage(ri);

            return(dbsm);
        }
Пример #7
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));
        }
Пример #8
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));
        }
Пример #9
0
        internal static void HandleDatabaseStore(DatabaseStoreMessage ds)
        {
            if (ds.RouterInfo == null && ds.LeaseSet == null)
            {
                throw new ArgumentException("DatabaseStore without Router or Lease info!");
            }

            if (ds.RouterInfo != null)
            {
#if LOG_ALL_TUNNEL_TRANSFER
                //Logging.Log( "HandleDatabaseStore: DatabaseStore RouterInfo" + ds.ToString() );
#endif
                NetDb.Inst.AddRouterInfo(ds.RouterInfo);
            }
            else
            {
#if LOG_ALL_TUNNEL_TRANSFER
                //Logging.Log( "HandleDatabaseStore: DatabaseStore LeaseSet" + ds.ToString() );
#endif
                NetDb.Inst.AddLeaseSet(ds.LeaseSet);
            }

            if (ds.ReplyToken != 0)
            {
                if (ds.ReplyTunnelId != 0)
                {
                    var outtunnel = TunnelProvider.Inst.GetEstablishedOutboundTunnel(true);
                    if (outtunnel != null)
                    {
                        outtunnel.Send(new TunnelMessageRouter(
                                           (new TunnelGatewayMessage(
                                                new DeliveryStatusMessage(ds.ReplyToken),
                                                ds.ReplyTunnelId)),
                                           ds.ReplyGateway));
                    }
                }
                else
                {
                    TransportProvider.Send(ds.ReplyGateway,
                                           new DeliveryStatusMessage(ds.ReplyToken));
                }
            }
        }
Пример #10
0
        private void SendUpdateTunnelReply(I2PIdentHash ff, 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 replytunnel = TunnelProvider.Inst.GetInboundTunnel(true);
            var ds          = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo,
                                                       token, replytunnel.Destination, replytunnel.ReceiveTunnelId);

            lock ( OutstandingRequests )
            {
                OutstandingRequests[token] = new FFUpdateRequestInfo(ff);
            }

            TransportProvider.Send(ff, ds);
        }
Пример #11
0
        private ITransport CreateTransport(I2PRouterInfo ri)
        {
            ITransport transport = null;

            try
            {
                var ntcpaddr = ri.Adresses.Where(a => (a.TransportStyle == "NTCP") &&
                                                 a.HaveHostAndPort &&
                                                 (RouterContext.Inst.UseIpV6 ||
                                                  a.Options.ValueContains("host", ".")));

                var ssuaddr = ri.Adresses.Where(a => (a.TransportStyle == "SSU") &&
                                                a.Options.Contains("key") &&
                                                (RouterContext.Inst.UseIpV6 ||
                                                 a.Options.ValueContains("host", ".") ||
                                                 a.Options.ValueContains("ihost0", ".")));

                I2PRouterAddress ra = ssuaddr
                                      .Where(a => a.Options.Contains("host"))
                                      .Random()
                                      ?? ntcpaddr.Random()
                                      ?? ssuaddr.Random();

                if (ra == null)
                {
                    Logging.LogTransport(
                        $"TransportProvider: CreateTransport: No usable address found for {ri.Identity.IdentHash.Id32Short}!");
                    return(null);
                }

                switch (ra.TransportStyle.ToString())
                {
                case "SSU":
                    transport = SsuHost.AddSession(ra, ri.Identity);
                    break;

                case "NTCP":
                    transport = new NTCPClientOutgoing(ra, ri.Identity);
                    break;

                default:
                    throw new NotImplementedException();
                }

                Logging.LogTransport(
                    string.Format("TransportProvider: Creating new {0} transport {2} to {1}",
                                  ra.TransportStyle, ri.Identity.IdentHash.Id32Short, transport.DebugId));

                AddTransport(transport);
                transport.Connect();

                var dstore = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo);
                transport.Send(dstore);
            }
            catch (Exception ex)
            {
#if LOG_MUCH_TRANSPORT
                Logging.LogTransport(ex);
                Logging.LogTransport("TransportProvider: CreateTransport stack trace: " + System.Environment.StackTrace);
#else
                Logging.LogTransport($"TransportProvider: Exception [{ex.GetType()}] " +
                                     $"'{ex.Message}' to {ri.Identity.IdentHash.Id32Short}.");
#endif
                if (transport != null)
                {
                    Remove(transport);
                }
                throw;
            }

            return(transport);
        }
Пример #12
0
        private ITransport CreateTransport(I2PRouterInfo ri)
        {
            ITransport transport = null;

            try
            {
                I2PRouterAddress ra_ntcp = null;
                var ntcpaddr             = ri.Adresses.Where(a => (a.TransportStyle == "NTCP") &&
                                                             a.Options.Contains("host") &&
                                                             a.Options.Contains("port") &&
                                                             (RouterContext.Inst.UseIpV6 || a.Options["host"].Contains('.')));
                var a1 = ntcpaddr.Where(a => GetAddressFamiliy(a, "host") == System.Net.Sockets.AddressFamily.InterNetwork);
                if (a1.Any())
                {
                    ra_ntcp = a1.Random();
                }
                else
                {
                    a1 = ntcpaddr.Where(a => Dns.GetHostEntry(a.Options["host"]).AddressList.
                                        Any(aa => aa.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork));
                    if (a1.Any())
                    {
                        ra_ntcp = a1.Random();
                    }
                }

                I2PRouterAddress ra_ssu = null;
                var ssuaddr             = ri.Adresses.Where(a => (a.TransportStyle == "SSU") && a.Options.Contains("key"));
                a1 = ssuaddr.Where(a => GetAddressFamiliy(a, "host") == System.Net.Sockets.AddressFamily.InterNetwork ||
                                   GetAddressFamiliy(a, "ihost0") == System.Net.Sockets.AddressFamily.InterNetwork);
                if (a1.Any())
                {
                    ra_ssu = a1.Random();
                }
                else
                {
                    a1 = ntcpaddr.Where(a => Dns.GetHostEntry(a.Options["host"]).AddressList.
                                        Any(aa => aa.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork));
                    if (a1.Any())
                    {
                        ra_ssu = a1.Random();
                    }
                    else
                    {
                        a1 = ntcpaddr.Where(a => Dns.GetHostEntry(a.Options["ihost0"]).AddressList.
                                            Any(aa => aa.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork));
                        if (a1.Any())
                        {
                            ra_ssu = a1.Random();
                        }
                    }
                }

                I2PRouterAddress ra;

                //if ( ra_ntcp != null ) ra = ra_ntcp; else ra = ra_ssu;
                if (ra_ssu != null)
                {
                    ra = ra_ssu;
                }
                else
                {
                    ra = ra_ntcp;
                }

                if (ra == null)
                {
                    Logging.LogTransport(
                        string.Format("TransportProvider: CreateTransport: No usable address found for {0}!", ri.Identity.IdentHash.Id32Short));
                    return(null);
                }

                switch (ra.TransportStyle.ToString())
                {
                case "SSU":
                    transport = SsuHost.AddSession(ra, ri.Identity);
                    break;

                case "NTCP":
                    transport = new NTCPClientOutgoing(ra, ri.Identity);
                    break;

                default:
                    throw new NotImplementedException();
                }

                Logging.LogTransport(
                    string.Format("TransportProvider: Creating new {0} transport {2} to {1}",
                                  ra.TransportStyle, ri.Identity.IdentHash.Id32Short, transport.DebugId));

                AddTransport(transport, ri.Identity.IdentHash);
                transport.Connect();

                var dstore = new DatabaseStoreMessage(RouterContext.Inst.MyRouterInfo);
                transport.Send(dstore);
            }
            catch (Exception ex)
            {
#if LOG_ALL_TRANSPORT
                Logging.LogTransport(ex);
                Logging.LogTransport("TransportProvider: CreateTransport stack trace: " + System.Environment.StackTrace);
#else
                Logging.LogTransport("TransportProvider: Exception [" + ex.GetType().ToString() + "] '" + ex.Message + "' to " +
                                     ri.Identity.IdentHash.Id32Short + ".");
#endif
                if (transport != null)
                {
                    Remove(transport);
                }
                throw;
            }

            return(transport);
        }
Пример #13
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);
        }