public void PublishToSubscriber(Message pMessage) { var oService = new OrderService(); var dnService = new DeliveryNotificationService(); if (pMessage.GetType() == typeof(FundsTransferSuccessfulMessage)) { var lMessage = pMessage as FundsTransferSuccessfulMessage; var lVisitor = new FundsTransferSuccessfulMessageToFundsTransferSuccessfulItem(); lMessage.Accept(lVisitor); oService.FundsTransferSuccessful(lVisitor.Result); } else if (pMessage.GetType() == typeof(FundsTransferErrorMessage)) { var lMessage = pMessage as FundsTransferErrorMessage; var lVisitor = new FundsTransferErrorMessageToFundsTransferErrorItem(); lMessage.Accept(lVisitor); oService.FundsTransferError(lVisitor.Result); } else if (pMessage.GetType() == typeof(DeliverySubmittedMessage)) { DeliverySubmittedMessage lMessage = pMessage as DeliverySubmittedMessage; var lVisitor = new DeliverySubmittedMessageToDeliverySubmittedItem(); lMessage.Accept(lVisitor); oService.DeliverySubmitted(lVisitor.Result); } else if (pMessage.GetType() == typeof(DeliveryStatusMessage)) { DeliveryStatusMessage lMessage = pMessage as DeliveryStatusMessage; var lVisitor = new DeliveryStatusMessageToDeliveryStatusItem(); lMessage.Accept(lVisitor); dnService.NotifyDeliveryStatus(lVisitor.Result.DeliveryIdentifier, (DeliveryInfoStatus)lVisitor.Result.Status); } }
public void TestEncodeDecode() { var recv = new ReceivedSessions(Private); var session = new DestinationSessions((d, h, inf) => { }, () => null); var origmessage = new DeliveryStatusMessage(0x425c); /* * var msg1eg = session.CreateMessage( * Me, * new GarlicCloveDeliveryTunnel( * origmessage, * Destination.IdentHash, * 1234 ) ); * * var msg2aes = session.CreateMessage( * Me, * new GarlicCloveDeliveryTunnel( * origmessage, * Destination.IdentHash, * 1234 ) ); * * var dmsg1eg = recv.DecryptMessage( msg1eg.Garlic ); * var dmsg2aes = recv.DecryptMessage( msg2aes.Garlic ); * * Assert.IsTrue( origmessage.Payload == dmsg1eg.Cloves.First().Message.Payload ); * Assert.IsTrue( origmessage.Payload == dmsg2aes.Cloves.First().Message.Payload ); */ }
void DeliveryStatusReceived(DeliveryStatusMessage dsmsg) { GarlicCreationInfo info; lock ( OutstandingMessageIds ) { info = OutstandingMessageIds[dsmsg.MessageId]; if (info == null) { /* * DebugUtils.LogDebug( string.Format( "TagsTransferWindow: DeliveryStatusReceived: Non matching status message MsgId: {0}.", * dsmsg.MessageId ) ); */ return; } OutstandingMessageIds.Remove(dsmsg.MessageId); } lock ( Window ) { Window.Remove(info.TrackingId); } DebugUtils.LogDebug(string.Format("TagsTransferWindow: DeliveryStatusReceived: Received ACK MsgId: {0} TrackingId: {1}. {2}", dsmsg.MessageId, info.TrackingId, info.Created.DeltaToNow)); if (WaitingForEGAck != null && info.KeyType == GarlicCreationInfo.KeyUsed.ElGamal && dsmsg.MessageId == LatestEGMessage.AckMessageId) { WaitingForEGAck = null; // Aes messages sent after this can be decrypted, hopefully. // Send them one more time. /* * lock ( OutstandingMessageIds ) * { * var remove = OutstandingMessageIds.Where( gci => gci.Value.KeyType == GarlicCreationInfo.KeyUsed.Aes && * !gci.Value.AckMessageId.HasValue && gci.Value.EGAckMessageId == dsmsg.MessageId ); * foreach ( var one in remove.ToArray() ) * { * OutstandingMessageIds.Remove( one.Key ); * } * } * * lock ( Window ) * { * var remove = Window.Where( gci => gci.Value.KeyType == GarlicCreationInfo.KeyUsed.Aes && * !gci.Value.AckMessageId.HasValue && gci.Value.EGAckMessageId == dsmsg.MessageId ); * foreach ( var one in remove.ToArray() ) * { * Window.Remove( one.Key ); * } * } */ } MessageAckEvent(info); }
GarlicCreationInfo UseExistingSessionTags(bool explack, uint trackingid, GarlicCloveDelivery[] cloves) { Garlic msg; DeliveryStatusMessage ackmsg = null; if (explack) { msg = AddExplAck(cloves, out ackmsg); } else { var exp = new I2PDate(DateTime.UtcNow.AddMinutes(5)); msg = new Garlic(cloves.Select(d => new GarlicClove(d, exp)).ToArray()); } #if LOG_ALL_TUNNEL_TRANSFER Logging.LogDebug(() => string.Format( "DestinationSession: Garlic generated with {0} cloves. {1} tags available.", msg.Cloves.Count, SessionTags.Count)); #endif var payload = msg.ToByteArray(); var dest = new BufLen(new byte[61000]); var writer = new BufRefLen(dest, 4); // Reserve 4 bytes for GarlicMessageLength I2PSessionTag tag; lock ( SessionTags ) { var ix = BufUtils.RandomInt(SessionTags.Count); tag = SessionTags[ix]; SessionTags.RemoveAt(ix); } // Tag as header writer.Write(tag.Value); // AES block var aesstart = new BufLen(writer); var aesblock = new GarlicAESBlock(writer, null, null, new BufRefLen(payload)); var pivh = I2PHashSHA256.GetHash(tag.Value); Cipher.Init(true, SessionKey.Key.ToParametersWithIV(new BufLen(pivh, 0, 16))); Cipher.ProcessBytes(aesblock.DataBuf); var length = writer - dest; dest.PokeFlip32((uint)(length - 4), 0); return(new GarlicCreationInfo( Destination.IdentHash, cloves, new EGGarlic(new BufRefLen(dest, 0, length)), GarlicCreationInfo.KeyUsed.Aes, SessionTags.Count(), trackingid, explack ? (uint?)ackmsg.MessageId : null, LatestEGAckMessageId)); }
void InboundTunnel_DeliveryStatusReceived(DeliveryStatusMessage dstatus) { var probe = OutstandingProbeIds[dstatus.MessageId]; if (probe == null) { return; } var run = OutstandingTests[probe.Tunnel]; if (run == null) { return; } var testms = (DateTime.UtcNow - (DateTime)dstatus.Timestamp).TotalMilliseconds; var limit = PassTestTimePerHop.ToMilliseconds * probe.TotalHops; var pass = testms < limit; DebugUtils.LogDebug(string.Format("TunnelTester: DeliveryStatus received. Test with {0} and {1}: {2}. {3:0} vs {4} ms", run.TunnelUnderTest.TunnelDebugTrace, probe.Partner.TunnelDebugTrace, (pass ? "Success" : "Fail"), testms, limit)); var delta = TickSpan.Milliseconds((int)testms); if (probe.Tunnel.MinLatencyMeasured == null || probe.Tunnel.MinLatencyMeasured > delta) { probe.Tunnel.MinLatencyMeasured = delta; } if (probe.Partner.MinLatencyMeasured == null || probe.Partner.MinLatencyMeasured > delta) { probe.Partner.MinLatencyMeasured = delta; } lock ( ExternalEventSync ) { if (pass) { run.SuccessPartners.Add(probe.Partner); } else { run.FailurePartners.Add(probe.Partner); } run.OutstandingProbes.Remove(probe); OutstandingProbeIds.Remove(probe.MessageId); HandleTunnelTestResult(run); } }
public void TestGarlicCreateMessage() { var dsm1 = new DeliveryStatusMessage(0x425c) { MessageId = 2354 }; var dsm2 = new DeliveryStatusMessage(0x425c) { MessageId = 2354 }; dsm2.Timestamp = dsm1.Timestamp; dsm2.Expiration = dsm1.Expiration; var dsm1h = dsm1.CreateHeader16; var dsm2h = dsm2.CreateHeader16; var dsm1hap = dsm1h.HeaderAndPayload; var dsm2hap = dsm2h.HeaderAndPayload; var st11 = FreenetBase64.Encode(dsm1hap); var st12 = FreenetBase64.Encode(dsm2hap); Assert.IsTrue(dsm1hap == dsm2hap); var gcd1 = new GarlicCloveDeliveryDestination( dsm1, Destination.IdentHash); var gcd2 = new GarlicCloveDeliveryDestination( dsm2, Destination.IdentHash); var gcd1ar = gcd1.ToByteArray(); var gcd2ar = gcd2.ToByteArray(); var st1 = FreenetBase64.Encode(new BufLen(gcd1ar)); var st2 = FreenetBase64.Encode(new BufLen(gcd2ar)); Assert.IsTrue(BufUtils.Equal(gcd1ar, gcd2ar)); var msg1 = new GarlicClove(gcd1); var msg2 = new GarlicClove(gcd2); var g1 = new Garlic(msg1, msg2); var g2 = new Garlic(new BufRefLen(g1.ToByteArray()).Clone()); Assert.IsTrue(BufUtils.Equal(g1.ToByteArray(), g2.ToByteArray())); }
void InboundTunnel_DeliveryStatusReceived(DeliveryStatusMessage msg) { lock ( OutstandingRequests ) { if (OutstandingRequests.TryGetValue(msg.MessageId, out var info)) { Logging.Log(string.Format("FloodfillUpdater: Floodfill delivery status {0,10} from {1} received in {2} mseconds.", msg.MessageId, info.FFRouter.Id32Short, info.Start.DeltaToNowMilliseconds)); OutstandingRequests.Remove(msg.MessageId); NetDb.Inst.Statistics.FloodfillUpdateSuccess(info.FFRouter); } } }
public void TestGarlicCreate() { var ls = new I2PDate(DateTime.Now + TimeSpan.FromMinutes(5)); var origmessage = new DeliveryStatusMessage(I2NPMessage.GenerateMessageId()); var bigmessage = new DataMessage(new BufLen(BufUtils.RandomBytes(14 * 1024))); var garlic = new Garlic( new GarlicClove( new GarlicCloveDeliveryLocal(origmessage), ls), new GarlicClove( new GarlicCloveDeliveryLocal(bigmessage), ls) ); var egmsg = Garlic.EGEncryptGarlic( garlic, Public, new I2PSessionKey(), null); var origegdata = I2NPMessage.Clone(egmsg); var origegdata2 = I2NPMessage.Clone(egmsg); // Decrypt var(aesblock, sessionkey1) = Garlic.EGDecryptGarlic(origegdata, Private); var newgarlic = new Garlic((BufRefLen)aesblock.Payload); var g1 = new BufLen(garlic.ToByteArray()); var g2 = new BufLen(newgarlic.ToByteArray()); Assert.IsTrue(g1 == g2); // Retrieve var(aesblock2, sessionkey2) = Garlic.RetrieveAESBlock(origegdata2, Private, null); newgarlic = new Garlic((BufRefLen)aesblock2.Payload); g1 = new BufLen(garlic.ToByteArray()); g2 = new BufLen(newgarlic.ToByteArray()); Assert.IsTrue(g1 == g2); Assert.IsTrue(sessionkey1 == sessionkey2); }
public void Visit(IVisitable pVisitable) { if (pVisitable is DeliveryStatusMessage) { DeliveryStatusMessage lMsg = pVisitable as DeliveryStatusMessage; Result = new DeliveryStatusItem { SourceAddress = lMsg.SourceAddress, DestinationAddress = lMsg.DestinationAddress, OrderNumber = lMsg.OrderNumber, DeliveryIdentifier = lMsg.DeliveryIdentifier, DeliveryNotificationAddress = lMsg.DeliveryNotificationAddress, Status = lMsg.Status }; } }
public void Visit(IVisitable pVisitable) { if (pVisitable is DeliveryStatus) { DeliveryStatus lMsg = pVisitable as DeliveryStatus; Result = new DeliveryStatusMessage() { SourceAddress = lMsg.DeliveryInfo.SourceAddress, DestinationAddress = lMsg.DeliveryInfo.DestinationAddress, OrderNumber = lMsg.DeliveryInfo.OrderNumber, DeliveryIdentifier = lMsg.DeliveryInfo.DeliveryIdentifier, DeliveryNotificationAddress = lMsg.DeliveryInfo.DeliveryNotificationAddress, Status = lMsg.DeliveryInfo.Status, Topic = lMsg.Topic }; } }
public void TestEncodeDecodeAES() { var m1 = new DeliveryStatusMessage(0x4321); var m2 = new DeliveryStatusMessage(0xa3c2); var garlic = new Garlic( new GarlicClove( new GarlicCloveDeliveryDestination( m1, Destination.IdentHash)), new GarlicClove( new GarlicCloveDeliveryDestination( m2, Destination.IdentHash)) ); // No tags var sessionkey = new I2PSessionKey(); var sessiontag = new I2PSessionTag(); var cg = Garlic.AESEncryptGarlic(garlic, sessionkey, sessiontag, null); var egdata = I2NPMessage.Clone(cg); var(aesblock, sk) = Garlic.RetrieveAESBlock(egdata, Private, (t) => sessionkey); var g2 = new Garlic((BufRefLen)aesblock.Payload); Assert.IsTrue(BufUtils.Equal(garlic.ToByteArray(), g2.ToByteArray())); // With tags var tags = new List <I2PSessionTag>(); for (int i = 0; i < 30; ++i) { tags.Add(new I2PSessionTag()); } cg = Garlic.AESEncryptGarlic(garlic, sessionkey, sessiontag, null); egdata = I2NPMessage.Clone(cg); (aesblock, sk) = Garlic.RetrieveAESBlock(egdata, Private, (t) => sessionkey); g2 = new Garlic((BufRefLen)aesblock.Payload); Assert.IsTrue(BufUtils.Equal(garlic.ToByteArray(), g2.ToByteArray())); }
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)); }
void InboundTunnel_DeliveryStatusReceived(DeliveryStatusMessage msg) { if (!OutstandingRequests.TryRemove(msg.StatusMessageId, out var info)) { /* * Logging.LogDebug( $"FloodfillUpdater: Floodfill delivery status " + * $"{msg.StatusMessageId,10} unknown. Dropped." ); */ return; } var id = info?.LeaseSet is null ? info?.IdentToUpdate : info.LeaseSet.Destination.IdentHash; Logging.LogDebug($"FloodfillUpdater: Floodfill delivery status {info} " + $"received in {info.Start.DeltaToNowMilliseconds} mseconds."); NetDb.Inst.Statistics.FloodfillUpdateSuccess(info.CurrentTargetFF); }
internal void Execute() { if (TestRemoteDest != null && OutboundEstablishedPool.Count >= 2 && InboundEstablishedPool.Count >= 2 && TestRemoteDest.InboundEstablishedPool.Count >= 2) { try { SendNewData.Do(() => { var dest = TestRemoteDest.MyDestination; var origmessage = new DeliveryStatusMessage(I2NPHeader.GenerateMessageId()); var big = BufUtils.RandomInt(100) < 5; Destinations.Send(dest, true, new GarlicCloveDeliveryDestination( origmessage, dest.IdentHash), (big ? new GarlicCloveDeliveryDestination(BigMessage, dest.IdentHash) : new GarlicCloveDeliveryDestination(origmessage, dest.IdentHash))); }); } catch (Exception ex) { SendNewData.Reset(); DebugUtils.Log(ex); } } QueueStatusLog.Do(() => { DebugUtils.LogInformation(string.Format( "ClientTunnelProvider {4}: Established tunnels in: {0,2}, out: {1,2}. Pending in: {2,2}, out {3,2}", InboundEstablishedPool.Count, OutboundEstablishedPool.Count, InboundPending.Count, OutboundPending.Count, MyDestination.IdentHash.Id32Short)); }); Destinations.Run(); }
private Garlic AddExplAck(GarlicCloveDelivery[] cloves, out DeliveryStatusMessage ackmsg) { var replytunnel = SelInboundTunnel(); if (replytunnel == null) { throw new FailedToConnectException("No inbound tunnels available"); } ackmsg = new DeliveryStatusMessage(I2NPHeader.GenerateMessageId()); var ackclove = new GarlicCloveDeliveryTunnel(ackmsg, replytunnel); var exp = new I2PDate(DateTime.UtcNow.AddMinutes(5)); var msg = new Garlic(cloves.Concat(new GarlicCloveDelivery[] { ackclove }).Select(d => new GarlicClove(d, exp))); #if LOG_ALL_TUNNEL_TRANSFER var ackmsgid = ackmsg.MessageId; Logging.LogDebug(() => string.Format( "DestinationSession: Added ACK message with MessageId: {0} to {1} cloves. Dest: {2}: {3}", ackmsgid, cloves.Length, replytunnel.Destination.Id32Short, replytunnel.ReceiveTunnelId)); #endif return(msg); }
public void TestBiggerEncodeDecode() { var recv = new ReceivedSessions(Private); var session = new DestinationSessions((d, h, inf) => { }, () => null); var origdsmessage = new DeliveryStatusMessage(0x425c); var datamessage = new DataMessage(new BufLen(BufUtils.Random(16000))); var origmessage1 = CreateDatabaseStoreMessage(); var origmessage2 = CreateDatabaseStoreMessage(); var origmessage3 = CreateDatabaseStoreMessage(); var origmessage4 = CreateDatabaseStoreMessage(); /* * var msg1eg = session.CreateMessage( * Me, * new GarlicCloveDeliveryTunnel( * origmessage1, * Destination.IdentHash, * 1234 ), * new GarlicCloveDeliveryLocal( * origmessage2 ), * new GarlicCloveDeliveryRouter( * origmessage3, * Destination.IdentHash ) * ); * * var msg2aes = session.CreateMessage( * Me, * new GarlicCloveDeliveryTunnel( * origdsmessage, * Destination.IdentHash, * 1234 ), * new GarlicCloveDeliveryRouter( * origmessage1, * Destination.IdentHash ), * new GarlicCloveDeliveryLocal( * datamessage ), * new GarlicCloveDeliveryTunnel( * origmessage4, * Destination.IdentHash, * 1234 ) ); * * var dmsg1eg = recv.DecryptMessage( msg1eg.Garlic ); * var dmsg2aes = recv.DecryptMessage( msg2aes.Garlic ); * * Assert.IsTrue( dmsg1eg.Cloves.Count() == 3 ); * Assert.IsTrue( dmsg2aes.Cloves.Count() == 4 ); * * Assert.IsTrue( dmsg2aes.Cloves[0].Delivery.Delivery == GarlicCloveDelivery.DeliveryMethod.Tunnel ); * Assert.IsTrue( dmsg2aes.Cloves[1].Delivery.Delivery == GarlicCloveDelivery.DeliveryMethod.Router ); * Assert.IsTrue( dmsg2aes.Cloves[2].Delivery.Delivery == GarlicCloveDelivery.DeliveryMethod.Local ); * Assert.IsTrue( dmsg2aes.Cloves[3].Delivery.Delivery == GarlicCloveDelivery.DeliveryMethod.Tunnel ); * * Assert.IsTrue( dmsg1eg.Cloves.All( m => m.Message.MessageType == I2NPMessage.MessageTypes.DatabaseStore ) ); * Assert.IsTrue( !dmsg2aes.Cloves.All( m => m.Message.MessageType == I2NPMessage.MessageTypes.DatabaseStore ) ); * * Assert.IsTrue( dmsg2aes.Cloves.Where( m => m.Message.MessageType == I2NPMessage.MessageTypes.DeliveryStatus ). * All( m => ( (DeliveryStatusMessage)m.Message ).MessageId == 0x425c ) ); * * Assert.IsTrue( dmsg1eg.Cloves.Where( m => m.Message.MessageType == I2NPMessage.MessageTypes.DatabaseStore ). * All( m => ( (DatabaseStoreMessage)m.Message ).RouterInfo.VerifySignature() ) ); * Assert.IsTrue( dmsg2aes.Cloves.Where( m => m.Message.MessageType == I2NPMessage.MessageTypes.DatabaseStore ). * All( m => ( (DatabaseStoreMessage)m.Message ).RouterInfo.VerifySignature() ) ); * Assert.IsTrue( dmsg2aes.Cloves.Where( m => m.Message.MessageType == I2NPMessage.MessageTypes.Data ). * All( m => ( (DataMessage)m.Message ).Payload == datamessage.Payload ) ); */ }
void InboundTunnel_DeliveryStatusReceived(DeliveryStatusMessage dsmsg) { DeliveryStatusReceived(dsmsg); }
void TunnelProvider_DeliveryStatusReceived(DeliveryStatusMessage dsmsg) { DeliveryStatusReceived(dsmsg); }
public void DeliveryStatusReceived(DeliveryStatusMessage msg) { InboundTunnel_DeliveryStatusReceived(msg); }
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); }