internal void Run() { Resend.Do(() => { try { List <KeyValuePair <II2NPHeader16, GarlicCreationInfo> > tosend = new List <KeyValuePair <II2NPHeader16, GarlicCreationInfo> >(); lock ( Window ) { var resend = Window.Where(gci => gci.Value.LastSend.DeltaToNow > GarlicTimeBetweenResends); if (WaitingForEGAck != null && WaitingForEGAck.DeltaToNow > GarlicTimeBetweenResends) { DebugUtils.LogDebug("TagsTransferWindow: Run: ElGamal message needs to be resent. Starting over."); Session.Reset(); } foreach (var one in resend.ToArray()) { var egmsg = Session.Encrypt(true, one.Value.TrackingId, one.Value.Cloves); var npmsg = new GarlicMessage(egmsg.Garlic).GetHeader16(I2NPHeader.GenerateMessageId()); one.Value.LastSend.SetNow(); tosend.Add(new KeyValuePair <II2NPHeader16, GarlicCreationInfo>(npmsg, egmsg)); if (WaitingForEGAck == null && !one.Value.AckMessageId.HasValue) { // Non explicit ack cloves that should not be retransmitted any more. Window.Remove(one.Key); } } } foreach (var pair in tosend) { DebugUtils.LogDebug(string.Format("TagsTransferWindow: Resend: ({0}) TrackingId: {1}, Ack MessageId: {2}.", pair.Value.KeyType, pair.Value.TrackingId, pair.Value.AckMessageId)); if (pair.Value.AckMessageId.HasValue) { lock ( OutstandingMessageIds ) { OutstandingMessageIds[pair.Value.AckMessageId.Value] = pair.Value; } } TunnelSelector(Session.LatestRemoteLeaseSet, pair.Key, pair.Value); } } catch (Exception ex) { Session.Reset(); DebugUtils.Log("TagsTransferWindow Run", ex); } }); }
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); } }
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); }