Beispiel #1
0
        public DatabaseLookupMessage(I2NPHeader header, BufRef reader)
        {
            var start = new BufRef(reader);

            UpdateCachedFields(reader);
            SetBuffer(start, reader);
        }
Beispiel #2
0
        public DataMessage(I2NPHeader header, BufRef reader)
        {
            var start = new BufRef(reader);

            reader.Seek((int)reader.ReadFlip32());
            SetBuffer(start, reader);
        }
Beispiel #3
0
        public GarlicMessage(I2NPHeader header, BufRef reader)
        {
            var start = new BufRef(reader);

            UpdateCachedFields(reader);
            SetBuffer(start, reader);
        }
Beispiel #4
0
        public TunnelDataMessage(I2NPHeader header, BufRef reader)
        {
            var start = new BufRef(reader);

            reader.Seek(4 + DataLength);
            SetBuffer(start, reader);

            // The message is encrypted at this stage
            //UpdateFirstDeliveryInstructionPosition();
        }
        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);
                }
            });
        }
Beispiel #6
0
        public static I2NPMessage GetMessage(I2NPHeader header, BufRef reader)
        {
            try
            {
                switch (header.MessageType)
                {
                case I2NPMessage.MessageTypes.Garlic:
                    return(new GarlicMessage(header, reader));

                case I2NPMessage.MessageTypes.Data:
                    return(new DataMessage(header, reader));

                case I2NPMessage.MessageTypes.DatabaseSearchReply:
                    return(new DatabaseSearchReplyMessage(reader));

                case I2NPMessage.MessageTypes.DatabaseStore:
                    return(new DatabaseStoreMessage(header, reader));

                case I2NPMessage.MessageTypes.DeliveryStatus:
                    return(new DeliveryStatusMessage(header, reader));

                case I2NPMessage.MessageTypes.TunnelData:
                    return(new TunnelDataMessage(header, reader));

                case I2NPMessage.MessageTypes.TunnelGateway:
                    return(new TunnelGatewayMessage(reader));

                case I2NPMessage.MessageTypes.DatabaseLookup:
                    return(new DatabaseLookupMessage(header, reader));

                case I2NPMessage.MessageTypes.VariableTunnelBuild:
                    return(new VariableTunnelBuildMessage(reader));

                case I2NPMessage.MessageTypes.TunnelBuild:
                    return(new TunnelBuildMessage(reader));

                case I2NPMessage.MessageTypes.TunnelBuildReply:
                    return(new TunnelBuildReplyMessage(reader));

                case I2NPMessage.MessageTypes.VariableTunnelBuildReply:
                    return(new VariableTunnelBuildReplyMessage(reader));

                default:
                    DebugUtils.LogDebug("GetMessage: '" + header.MessageType.ToString() + "' is not a known message type!");
                    throw new NotImplementedException();
                }
            }
            catch (Exception ex)
            {
                DebugUtils.Log("GetMessage", ex);
                throw;
            }
        }
        // Returns a tracking id supplied with events
        internal GarlicCreationInfo Send(bool explack, params GarlicCloveDelivery[] cloves)
        {
            GarlicCreationInfo egmsg = null;

            try
            {
                egmsg = Session.Encrypt(explack, I2NPHeader.GenerateMessageId(), cloves);
                var npmsg = new GarlicMessage(egmsg.Garlic).GetHeader16(I2NPHeader.GenerateMessageId());

                if (explack || WaitingForEGAck != null || egmsg.KeyType == GarlicCreationInfo.KeyUsed.ElGamal)
                {
                    if (egmsg.KeyType == GarlicCreationInfo.KeyUsed.ElGamal)
                    {
                        LatestEGMessage = egmsg;
                        WaitingForEGAck = TickCounter.Now;
                    }

                    egmsg.LastSend = TickCounter.Now;
                    lock ( Window )
                    {
                        Window[egmsg.TrackingId] = egmsg;
                    }
                }

                if (egmsg.AckMessageId.HasValue)
                {
                    lock ( OutstandingMessageIds )
                    {
                        OutstandingMessageIds[egmsg.AckMessageId.Value] = egmsg;
                    }
                }

                DebugUtils.LogDebug(string.Format("TagsTransferWindow: Send: ({0}) TrackingId: {1}, Ack MessageId: {2}.",
                                                  egmsg.KeyType, egmsg.TrackingId, egmsg.AckMessageId));

                TunnelSelector(Session.LatestRemoteLeaseSet, npmsg, egmsg);
            }
            catch (Exception ex)
            {
                Session.Reset();
                DebugUtils.Log("TagsTransferWindow Send", ex);
            }

            return(egmsg);
        }
Beispiel #8
0
        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();
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        void TestOneOutboundTunnel()
        {
            OutboundTunnel outtunnel;

            lock ( OutboundTunnels )
            {
                if (OutboundTunnels.Count == 0)
                {
                    return;
                }
                outtunnel = OutboundTunnels.First.Value;
                OutboundTunnels.RemoveFirst();

                if (outtunnel.NeedsRecreation)
                {
                    return;
                }
                OutboundTunnels.AddLast(outtunnel);
            }

            var run = OutstandingTests.Get(outtunnel);

            if (run != null)
            {
                // Run has finished?
                if (run.TestedPartners.Count >= RunsPerTest)
                {
                    if (run.LastRun.DeltaToNow < TimeBetweenTests)
                    {
                        return;
                    }
                    run.OutstandingProbes.Clear();
                    run.SuccessPartners.Clear();
                    run.TestedPartners.Clear();
                }
            }
            else
            {
                run = new TestRun2(outtunnel);
                OutstandingTests[outtunnel] = run;
            }

            var test = TestResults.Get(outtunnel, () => new TunnelTestResult(outtunnel));

            var intunnels = TunnelProvider.Inst.GetInboundTunnels().Shuffle().Take(RunsPerTest * 2).ToArray();

            if (!intunnels.Any())
            {
                //DebugUtils.LogDebug( "TunnelTester: Failed to get a established inbound tunnel." );
                return;
            }

            run.LastRun.SetNow();

            string tunneldbginfo = "";

            foreach (var intunnel in intunnels)
            {
                if (run.FailurePartners.Contains(intunnel) ||
                    run.SuccessPartners.Contains(intunnel) ||
                    run.TestedPartners.Contains(intunnel))
                {
                    continue;
                }

                run.TestedPartners.Add(intunnel);
                var probe = new ProbesSent()
                {
                    Tunnel    = outtunnel,
                    Partner   = intunnel,
                    MessageId = I2NPHeader.GenerateMessageId(),
                    TotalHops = outtunnel.Config.Info.Hops.Count + intunnel.Config.Info.Hops.Count
                };

                tunneldbginfo += $"({intunnel.TunnelDebugTrace}:{probe.MessageId})";

                run.OutstandingProbes.Add(probe);
                OutstandingProbeIds[probe.MessageId] = probe;
                outtunnel.Send(new TunnelMessageTunnel((new DeliveryStatusMessage(probe.MessageId)).Header16, intunnel));
            }

            if (tunneldbginfo.Length > 0)
            {
                DebugUtils.LogDebug(
                    $"TunnelTester: Starting outbound tunnel {outtunnel.TunnelDebugTrace} test with tunnels: {tunneldbginfo}");
            }
        }