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()); }
public FFUpdateRequestInfo(I2PIdentHash ff, uint token, I2PLeaseSet ls, int retries) { CurrentTargetFF = ff; Token = token; LeaseSet = ls; Retries = retries; }
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)); }
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); }
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); }
public void AddLeaseSet(I2PLeaseSet leaseset) { LeaseSets[leaseset.Destination.IdentHash] = leaseset; if (LeaseSetUpdates != null) { ThreadPool.QueueUserWorkItem(a => LeaseSetUpdates(leaseset)); } }
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); }
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"); } }
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)); }
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; }
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); }
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); } } }
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)); } }
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)); }
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(); }
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)); }
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)); }
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; } }
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())); }
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)); } } } }
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); } } }
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); } }
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)); } }
static void LookupResult(I2PIdentHash hash, I2PLeaseSet ls) { LS = ls; }
internal void LocalLeaseSetUpdated(I2PLeaseSet leaseset) { this[leaseset.Destination].LocalLeaseSetUpdated(leaseset); }
internal void RemoteLeaseSetUpdated(I2PLeaseSet leaseset) { this[leaseset.Destination].RemoteLeaseSetUpdated(leaseset); }
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)); }