Beispiel #1
0
        internal void IntroductionRelayOffered(IntroducerInfo intro)
        {
            if (!RouterContext.Inst.IsFirewalled)
            {
                return;
            }

            Logging.LogTransport($"SSU Introduction: Added introducer {intro.Host}, {intro.IntroKey}, {intro.IntroTag}, {intro.EndPoint}");

            switch (GatherIntroducersState)
            {
            case GatherIntroducersStates.Startup:
                ConsiderUpdateIntroducers.Do(() =>
                {
                    var intros = SelectIntroducers()
                                 .Select(p => p.Left.RemoteIntroducerInfo);

                    if (intros.Any())
                    {
                        SetIntroducers(intros);
                        ConsiderUpdateIntroducers.Frequency = TickSpan.Minutes(10);
                        GatherIntroducersState = GatherIntroducersStates.Established;
                    }
                });
                break;

            case GatherIntroducersStates.Established:
                ConsiderUpdateIntroducers.Do(() =>
                {
                    SetIntroducers(SelectIntroducers()
                                   .Select(p => p.Left.RemoteIntroducerInfo));
                });
                break;
            }
        }
        public override SSUState Run()
        {
            if (Timeout(HandshakeStateTimeoutSeconds))
            {
                if (Session.RemoteRouterIdentity != null)
                {
                    NetDb.Inst.Statistics.SlowHandshakeConnect(Session.RemoteRouterIdentity.IdentHash);
                }

                throw new FailedToConnectException("SSU " + Session.DebugId + " Failed to connect. Timeout.");
            }

            if (Request == null)
            {
                return(this);
            }

            ResendSessionCreatedAction.Do(() =>
            {
                if (++Retries > HandshakeStateMaxRetries)
                {
                    throw new FailedToConnectException("SSU " + Session.DebugId + " Failed to connect. Too many retries.");
                }

                DebugUtils.Log("SSU SessionCreatedState " + Session.DebugId + " : Resending SessionCreated message.");
                SendSessionCreated();
            });

            return(this);
        }
Beispiel #3
0
        public void Execute()
        {
            TunnelBuild.Do(() =>
            {
                try
                {
                    BuildNewTunnels();
                }
                catch (Exception ex)
                {
                    Logging.Log("ClientTunnelProvider Execute BuildNewTunnels", ex);
                }
            });

            DestinationExecute.Do(() =>
            {
                var dests = Destinations.Select(d => d.Value).ToArray();

                foreach (var onedest in dests)
                {
                    try
                    {
                        onedest.Execute();
                    }
                    catch (Exception ex)
                    {
                        Logging.Log("ClientTunnelProvider Execute DestExecute", ex);
                    }
                }

                ReplaceTunnels.Do(CheckForTunnelReplacementTimeout);

                LogStatus.Do(LogStatusReport);
            });
        }
Beispiel #4
0
        public IEnumerable <DataFragment> NotAckedFragments()
        {
            RemoveOldMessages.Do(() =>
            {
                CleanUpOldMessages();
            });

            lock ( AckQueue )
            {
                var one = AckQueue.First;
                while (one != null)
                {
                    var next = one.Next;

                    if (!one.Value.AllFragmentsAcked)
                    {
                        var naf = one.Value.NotAckedFragments();
                        foreach (var frag in naf)
                        {
                            yield return(frag);
                        }
                    }
                    else
                    {
                        AckQueue.Remove(one);
                    }

                    one = next;
                }
            }
        }
Beispiel #5
0
        public override SSUState Run()
        {
            if (Timeout(HandshakeStateTimeout * 4))
            {
                Session.Host.EPStatisitcs.ConnectionTimeout(Session.RemoteEP);
                if (Session.RemoteRouterIdentity != null)
                {
                    NetDb.Inst.Statistics.SlowHandshakeConnect(Session.RemoteRouterIdentity.IdentHash);
                }

                throw new FailedToConnectException($"SSU {this}: Failed to connect. Timeout.");
            }

            ResendSessionRequestAction.Do(() =>
            {
                if (++Retries > HandshakeStateMaxRetries)
                {
                    throw new FailedToConnectException($"SSU {this}: Failed to connect. Too many retries.");
                }

                SendSessionRequest();
            });

            return(this);
        }
Beispiel #6
0
        public override SSUState Run()
        {
            if (Timeout(HandshakeStateTimeout * 2))
            {
                Session.Host.EPStatisitcs.ConnectionTimeout(Session.RemoteEP);

                if (Session.RemoteRouterIdentity != null)
                {
                    NetDb.Inst.Statistics.SlowHandshakeConnect(Session.RemoteRouterIdentity.IdentHash);
                }

                Session.Host.ReportEPProblem(Session.RemoteEP);

                throw new FailedToConnectException($"SSU {Session.DebugId} Failed to connect. Timeout.");
            }

            if (Request == null)
            {
                return(this);
            }

            ResendSessionCreatedAction.Do(() =>
            {
                if (++Retries > HandshakeStateMaxRetries)
                {
                    throw new FailedToConnectException($"SSU {Session.DebugId} Failed to connect. Too many retries.");
                }

                Logging.LogTransport($"SSU SessionCreatedState {Session.DebugId} : Resending SessionCreated message.");
                SendSessionCreated();
            });

            return(this);
        }
Beispiel #7
0
        public override SSUState Run()
        {
            if (NextState != null)
            {
                Session.Host.RelayResponseReceived -= Host_RelayResponseReceived;
                return(NextState);
            }

            // Extra time because of introduction negotiation delay
            if (Timeout(HandshakeStateTimeout * 2))
            {
                Session.Host.RelayResponseReceived -= Host_RelayResponseReceived;
                throw new FailedToConnectException($"SSU RelayRequestState {Session.DebugId} Failed to connect. Timeout.");
            }

            ResendRelayRequestAction.Do(() =>
            {
                if (++Retries > RelayRequestStateMaxRetries)
                {
                    Session.Host.RelayResponseReceived -= Host_RelayResponseReceived;
                    throw new FailedToConnectException($"SSU {Session.DebugId} RelayRequestState, too many retries.");
                }

                SendRelayRequest();
            });

            return(this);
        }
Beispiel #8
0
        public override bool Exectue()
        {
            var ok = true;

            PreTunnelDataBatching.Do(() => { ok = HandleReceiveQueue(); });

            return(ok);
        }
Beispiel #9
0
        private void Run()
        {
            try
            {
                var ntcphost = new NTCPHost();

                ntcphost.ConnectionCreated += new Action <ITransport>(ntcphost_ConnectionCreated);
                SsuHost.ConnectionCreated  += new Action <ITransport>(SsuHost_ConnectionCreated);

                while (!Terminated)
                {
                    try
                    {
                        Thread.Sleep(1000);

                        var known = CurrentlyUnknownRouters.FindKnown();
                        foreach (var found in known)
                        {
                            foreach (var msg in found.Messages)
                            {
                                Logging.LogTransport("TransportProvider: Destination " + found.Destination.Id32Short + " found. Sending data.");
                                TransportProvider.Send(found.Destination, msg);
                            }
                        }

                        ActiveConnectionLog.Log(() => string.Format("TransportProvider: Running: {0}. Established: {1}.",
                                                                    RunningTransports.Count,
                                                                    EstablishedTransports.Count));

                        DropOldExceptions.Do(delegate
                        {
                            lock ( AddressesWithExceptions )
                            {
                                var remove = AddressesWithExceptions.Where(eh =>
                                                                           eh.Value.Generated.DeltaToNow.ToMinutes >= ExeptionHistoryLifetimeMinutes).Select(eh => eh.Key).ToArray();
                                foreach (var one in remove)
                                {
                                    AddressesWithExceptions.Remove(one);
                                }
                            }
                        });
                    }
                    catch (ThreadAbortException ex)
                    {
                        Logging.Log(ex);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(ex);
                    }
                }
            }
            finally
            {
                Terminated = true;
            }
        }
Beispiel #10
0
        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 #11
0
        internal bool IsFiltered(IPAddress addr)
        {
            Decay.Do(() =>
            {
                var toremove = new List <IPAddress>();

                lock ( MonitorIPWindow )
                {
                    foreach (var one in MonitorIPWindow)
                    {
                        var startcount = one.Value.Count;

                        while (one.Value.Count > 0 && one.Value.Last.Value.DeltaToNow.ToMinutes > IPFaultHistoryWindowMinutes)
                        {
                            one.Value.RemoveLast();
                        }

                        if (startcount >= NumberOfFailuresToBlock && one.Value.Count < NumberOfFailuresToBlock)
                        {
                            Logging.LogTransport("DecayingIPBlockFilter: Window under blocking level " + one.Key.ToString());
                            toremove.Add(one.Key);
                        }
                        else
                        if (one.Value.Count == 0)
                        {
                            toremove.Add(one.Key);
                        }
                    }

                    foreach (var remove in toremove)
                    {
                        MonitorIPWindow.Remove(remove);
                    }
                }
            });

            lock ( BlockedIPs )
            {
                TickCounter blocktime;

                if (BlockedIPs.TryGetValue(addr, out blocktime))
                {
                    if (blocktime.DeltaToNow.ToMinutes > BlockTimeMinutes)
                    {
                        Logging.LogTransport("DecayingIPBlockFilter: Unblocking " + addr.ToString());
                        BlockedIPs.Remove(addr);
                        return(false);
                    }

                    return(true);
                }

                return(false);
            }
        }
Beispiel #12
0
        public override bool Exectue()
        {
            FragBufferReport.Do(delegate()
            {
                var fbsize = Reassembler.BufferedFragmentCount;
                DebugUtils.Log("EndpointTunnel: " + Destination.Id32Short + " Fragment buffer size: " + fbsize.ToString());
                if (fbsize > 2000)
                {
                    throw new Exception("BufferedFragmentCount > 2000 !");                    // Trying to fill my memory?
                }
            });

            return(HandleReceiveQueue());
        }
Beispiel #13
0
        private void Run()
        {
            try
            {
                DebugUtils.LogInformation("NetDb: Path: " + NetDbPath);
                DebugUtils.Log("Reading NetDb...");
                var sw1 = new Stopwatch();
                sw1.Start();
                Load();
                sw1.Stop();
                DebugUtils.Log(string.Format("Done reading NetDb. {0}. {1} entries.", sw1.Elapsed, RouterInfos.Count));

                LoadFinished.Set();
                while (TransportProvider.Inst == null)
                {
                    Thread.Sleep(500);
                }

                var PeriodicSave = new PeriodicAction(TickSpan.Minutes(5));

                var PeriodicFFUpdate = new PeriodicAction(TickSpan.Seconds(5));
                var FloodfillUpdate  = new FloodfillUpdater();

                while (!Terminated)
                {
                    try
                    {
                        PeriodicSave.Do(() => Save(true));
                        PeriodicFFUpdate.Do(() => FloodfillUpdate.Run());
                        IdentHashLookup.Run();
                        Thread.Sleep(2000);
                    }
                    catch (ThreadAbortException ex)
                    {
                        DebugUtils.Log(ex);
                        Terminated = true;
                    }
                    catch (Exception ex)
                    {
                        DebugUtils.Log(ex);
                    }
                }
            }
            finally
            {
                Terminated = true;
            }
        }
Beispiel #14
0
        public override bool Exectue()
        {
            if (Terminated || RemoteGateway == null)
            {
                return(false);
            }

            FragBufferReport.Do(delegate()
            {
                var fbsize = Reassembler.BufferedFragmentCount;
                DebugUtils.Log("InboundTunnel " + TunnelDebugTrace + ": " + Destination.Id32Short + " Fragment buffer size: " + fbsize.ToString());
                if (fbsize > 2000)
                {
                    throw new Exception("BufferedFragmentCount > 2000 !");                    // Trying to fill my memory?
                }
            });

            return(HandleReceiveQueue() && HandleSendQueue());
        }
Beispiel #15
0
        public override bool Exectue()
        {
            if (Terminated || RemoteGateway == null)
            {
                return(false);
            }

            FragBufferReport.Do(delegate()
            {
                var fbsize = Reassembler.BufferedFragmentCount;
                Logging.Log($"{this}: {Destination.Id32Short} Fragment buffer size: {fbsize}");
                if (fbsize > 2000)
                {
                    throw new Exception("BufferedFragmentCount > 2000 !");                    // Trying to fill my memory?
                }
            });

            return(HandleReceiveQueue() && HandleSendQueue());
        }
Beispiel #16
0
        public override SSUState Run()
        {
            if (NextState != null)
            {
                Session.Host.RelayResponseReceived -= Host_RelayResponseReceived;
                return(NextState);
            }

            if (Timeout(HandshakeStateTimeoutSeconds))
            {
                Session.Host.RelayResponseReceived -= Host_RelayResponseReceived;
                throw new FailedToConnectException("SSU RelayRequestState {Session.DebugId} Failed to connect. Timeout.");
            }

            ResendRelayRequestAction.Do(() =>
            {
                if (++Retries > RelayRequestStateMaxRetries)
                {
                    Logging.LogTransport($"SSU RelayRequestState: {Session.DebugId}" +
                                         $" Using introducer '{CurrentIntroducer.EndPoint}' timed out.");

                    if (Introducers.Count == 0)
                    {
                        Session.Host.RelayResponseReceived -= Host_RelayResponseReceived;
                        throw new FailedToConnectException($"SSU +{Session.TransportInstance}+ Failed to find a non established introducer");
                    }
                    else
                    {
                        CurrentIntroducer = Introducers[0];
                        Introducers.RemoveAt(0);

                        Logging.LogTransport($"SSU RelayRequestState: +{Session.TransportInstance}+ " +
                                             $"Trying introducer '{CurrentIntroducer.EndPoint}' next.");

                        Retries = 0;
                    }
                }

                SendRelayRequest();
            });

            return(this);
        }
Beispiel #17
0
        public override SSUState Run()
        {
            if (Timeout(HandshakeStateTimeoutSeconds))
            {
                throw new FailedToConnectException("SSU SessionRequestState " + Session.DebugId + " Failed to connect. Timeout.");
            }

            ResendSessionRequestAction.Do(() =>
            {
                if (++Retries > HandshakeStateMaxRetries)
                {
                    throw new FailedToConnectException("SSU SessionRequestState " + Session.DebugId + " Failed to connect. Too many retries.");
                }

                SendSessionRequest();
            });

            return(this);
        }
Beispiel #18
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 #19
0
        public override SSUState Run()
        {
            if (Timeout(HandshakeStateTimeoutSeconds))
            {
                if (Session.RemoteRouterIdentity != null)
                {
                    NetDb.Inst.Statistics.SlowHandshakeConnect(Session.RemoteRouterIdentity.IdentHash);
                }

                throw new FailedToConnectException("SSU SessionConfirmedState " + Session.DebugId + " Failed to connect. Timeout.");
            }

            ResendSessionConfirmedAction.Do(() =>
            {
                if (++Retries > HandshakeStateMaxRetries)
                {
                    throw new FailedToConnectException("SSU " + Session.DebugId + " Failed to connect");
                }

                Logging.LogTransport("SSU SessionConfirmedState " + Session.DebugId + " : Resending SessionConfirmed message.");

                // SendFragmentedSessionConfirmed(); // Not all routers seem to support this

                /**
                 * From InboundEstablishState.java
                 *
                 * -----8<-----
                 *  Note that while a SessionConfirmed could in theory be fragmented,
                 *  in practice a RouterIdentity is 387 bytes and a single fragment is 512 bytes max,
                 *  so it will never be fragmented.
                 * -----8<-----
                 */

                SendUnfragmentedSessionConfirmed();
            });

            return(this);
        }
Beispiel #20
0
        public override SSUState Run()
        {
            // Idle
            if (Timeout(InactivityTimeoutSeconds))
            {
                DebugUtils.LogDebug(() => string.Format("SSU EstablishedState {0}: Inactivity timeout. Sending SessionDestroyed.", Session.DebugId));
                SendSessionDestroyed();
                return(null);
            }

            if (Session.Defragmenter.GotAcks || Session.SendQueue.Count > 0 || Session.Fragmenter.GotUnsentFragments)
            {
                do
                {
                    SendAcksAndData();
                } while (Session.SendQueue.Count > 0);
            }

            ResendFragmentsAction.Do(delegate
            {
                if (Session.Fragmenter.AllFragmentsAcked)
                {
                    return;
                }

                ResendNotAcked(Session.Fragmenter.NotAckedFragments());
            });

            if (Session.QueuedFirstPeerTestToCharlie != null)
            {
                SendFirstPeerTestToCharlie(Session.QueuedFirstPeerTestToCharlie);
                Session.QueuedFirstPeerTestToCharlie = null;
            }

            return(this);
        }
Beispiel #21
0
        internal void Execute()
        {
            TunnelBuild.Do(() =>
            {
                try
                {
                    BuildNewTunnels();
                }
                catch (Exception ex)
                {
                    DebugUtils.Log("ClientTunnelProvider Execute BuildNewTunnels", ex);
                }
            });

            DestinationExecute.Do(() =>
            {
                ClientDestination[] dests;

                lock ( Destinations )
                {
                    dests = Destinations.Select(d => d.Value).ToArray();
                }

                foreach (var onedest in dests)
                {
                    try
                    {
                        onedest.Execute();
                    }
                    catch (Exception ex)
                    {
                        DebugUtils.Log("ClientTunnelProvider Execute DestExecute", ex);
                    }
                }
            });
        }
 internal void Execute()
 {
     TunnelBuild.Do(() => BuildNewTunnels());
 }
Beispiel #23
0
        static void Main(string[] args)
        {
            PeriodicAction LsLookup = new PeriodicAction(TickSpan.Minutes(5));

            DebugUtils.LogToConsole = true;
            DebugUtils.LogToFile("i2p.log");
            DebugUtils.LogInformation("Me: " + RouterContext.Inst.MyRouterIdentity.IdentHash.Id32);

            for (int i = 0; i < args.Length; ++i)
            {
                switch (args[i])
                {
                case "--addr":
                    if (args.Length > i)
                    {
                        RouterContext.Inst.DefaultExtAddress = IPAddress.Parse(args[++i]);
                    }
                    break;

                case "--port":
                    if (args.Length > i)
                    {
                        var port = int.Parse(args[++i]);
                        RouterContext.Inst.DefaultTCPPort = port;
                        RouterContext.Inst.DefaultUDPPort = port;
                    }
                    break;

                case "--nofw":
                    RouterContext.Inst.IsFirewalled = false;
                    break;

                default:
                    Console.WriteLine("Usage: I2P.exe --addr 12.34.56.78 --port 8081 --nofw");
                    break;
                }
            }

            RouterContext.Inst.ApplyNewSettings();

            var pnp = new UPnp();

            Thread.Sleep(5000);   // Give UPnp a chance

            Router.Start();

            while (true)
            {
                try
                {
                    Connected = true;

                    var dest   = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519);
                    var mydest = Router.CreateDestination(dest, false);
                    mydest.DataReceived += new ClientDestination.DestinationDataReceived(mydest_DataReceived);

                    var hashes = new I2PIdentHash[] {
                        new I2PIdentHash("udhdrtrcetjm5sxaskjyr5ztseszydbh4dpl3pl4utgqqw2v4jna.b32.i2p"),
                        new I2PIdentHash("7tbay5p4kzemkxvyvbf6v7eau3zemsnnl2aoyqhg5jzpr5eke7tq.b32.i2p"),
                        new I2PIdentHash("ukeu3k5oycga3uneqgtnvselmt4yemvoilkln7jpvafvfx7dnkdq.b32.i2p")
                    };

                    while (Connected)
                    {
                        Thread.Sleep(20000);

                        /*
                         * if ( LS != null )
                         * {
                         *  mydest.Send( LS, BufUtils.Random( 200 ), false );
                         * }*/
                        LsLookup.Do(() => mydest.LookupDestination(hashes.Random(), new ClientDestination.DestinationLookupResult(LookupResult)));
                    }
                }
                catch (SocketException ex)
                {
                    DebugUtils.Log(ex);
                }
                catch (IOException ex)
                {
                    DebugUtils.Log(ex);
                }
                catch (Exception ex)
                {
                    DebugUtils.Log(ex);
                }
            }
        }
Beispiel #24
0
        public void SendAcks(BufRefLen writer, out bool explicitacks, out bool bitfieldsacks)
        {
            RemoveOldMessages.Do(() =>
            {
                RemoveExpired();
            });

            List <RebuildI2NPMessage> expl = null;
            List <RebuildI2NPMessage> bitm = null;

            var space = writer.Length;

            var remainingackmsgs = AckQueue.Count;

            while (space > 30 &&
                   (expl == null || expl.Count < MaxExplicitAcksPerMessage) &&
                   (bitm == null || bitm.Count < MaxBitmapAcksPerMessage) &&
                   remainingackmsgs-- > 0)
            {
                RebuildI2NPMessage msg = null;
                lock ( AckQueue )
                {
                    if (AckQueue.Count == 0)
                    {
                        break;
                    }
                    var lln = AckQueue.Last;

                    msg = lln.Value;
                    if (msg.AckSent.DeltaToNowMilliseconds < MillisecondsBetweenAcks)
                    {
                        continue;
                    }

                    AckQueue.RemoveLast();

                    bool resendsok;
                    if (msg.AllFragmentsFound)
                    {
                        resendsok = msg.ExplicitAcksSent < NumberOfExplicitAckResends;
                    }
                    else
                    {
                        resendsok = msg.BitmapAcksSent < NumberOfBitmapAckResends;
                    }
                    if (resendsok && msg != null)
                    {
                        AckQueue.AddFirst(lln);
                    }
                }

                if (msg == null)
                {
                    continue;
                }

                if (msg.AllFragmentsFound)
                {
                    if (expl == null)
                    {
                        expl   = new List <RebuildI2NPMessage>(MaxExplicitAcksPerMessage);
                        space -= 1;
                    }
                    space -= 4;
                    expl.Add(msg);
                }
                else
                {
                    if (bitm == null)
                    {
                        bitm   = new List <RebuildI2NPMessage>(MaxBitmapAcksPerMessage);
                        space -= 1;
                    }
                    space -= msg.AckBitmapSize;
                    bitm.Add(msg);
                }
            }

            if (expl != null)
            {
                writer.Write8((byte)expl.Count);
                foreach (var msg in expl)
                {
#if LOG_ALL_TRANSPORT
                    Logging.LogTransport("SSU DataDefragmenter sent expl ack: " + msg.MessageId.ToString() + " (" + msg.ExplicitAcksSent.ToString() + ")");
#endif
                    writer.Write32(msg.MessageId);
                    msg.AckSent.SetNow();
                    ++msg.ExplicitAcksSent;
                }
            }

            if (bitm != null)
            {
                writer.Write8((byte)bitm.Count);
                foreach (var msg in bitm)
                {
#if LOG_ALL_TRANSPORT
                    Logging.LogTransport("SSU DataDefragmenter sent bitmap ack: " + msg.MessageId.ToString());
#endif
                    writer.Write32(msg.MessageId);
                    writer.Write(msg.AckBitmap());
                    msg.AckSent.SetNow();
                    ++msg.BitmapAcksSent;
                }
            }

            explicitacks  = expl != null;
            bitfieldsacks = bitm != null;
        }
Beispiel #25
0
        static void Main(string[] args)
        {
            PeriodicAction SendInterval = new PeriodicAction(TickSpan.Seconds(20));

            Logging.ReadAppConfig();
            Logging.LogToDebug   = false;
            Logging.LogToConsole = true;

            RouterContext.RouterSettingsFile = "I2PDemo.bin";

            MyDestinationInfo = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519);

            for (int i = 0; i < args.Length; ++i)
            {
                switch (args[i])
                {
                case "--addr":
                case "--address":
                    if (args.Length > i + 1)
                    {
                        RouterContext.Inst.DefaultExtAddress = IPAddress.Parse(args[++i]);
                        Console.WriteLine($"addr {RouterContext.Inst.DefaultExtAddress}");
                    }
                    else
                    {
                        Console.WriteLine("--addr require ip number");
                        return;
                    }
                    break;

                case "--port":
                    if (args.Length > i + 1)
                    {
                        var port = int.Parse(args[++i]);
                        RouterContext.Inst.DefaultTCPPort = port;
                        RouterContext.Inst.DefaultUDPPort = port;
                        Console.WriteLine($"port {port}");
                    }
                    else
                    {
                        Console.WriteLine("--port require port number");
                        return;
                    }
                    break;

                case "--nofw":
                    RouterContext.Inst.IsFirewalled = false;
                    Console.WriteLine($"Firewalled {RouterContext.Inst.IsFirewalled}");
                    break;

                case "--mkdest":
                case "--create-destination":
                    var certtype = 0;
                    if (args.Length > i + 1)
                    {
                        certtype = int.Parse(args[++i]);
                    }

                    I2PSigningKey.SigningKeyTypes ct;
                    I2PDestinationInfo            d;

                    switch (certtype)
                    {
                    default:
                    case 0:
                        ct = I2PSigningKey.SigningKeyTypes.EdDSA_SHA512_Ed25519;
                        d  = new I2PDestinationInfo(ct);
                        break;

                    case 1:
                        ct = I2PSigningKey.SigningKeyTypes.DSA_SHA1;
                        d  = new I2PDestinationInfo(ct);
                        break;

                    case 2:
                        ct = I2PSigningKey.SigningKeyTypes.ECDSA_SHA256_P256;
                        d  = new I2PDestinationInfo(ct);
                        break;

                    case 3:
                        ct = I2PSigningKey.SigningKeyTypes.ECDSA_SHA384_P384;
                        d  = new I2PDestinationInfo(ct);
                        break;
                    }

                    Console.WriteLine($"New destination {ct}: {d.ToBase64()}");
                    return;

                case "--destination":
                    if (args.Length > i + 1)
                    {
                        MyDestinationInfo = new I2PDestinationInfo(args[++i]);
                        Console.WriteLine($"Destination {MyDestinationInfo}");
                    }
                    else
                    {
                        Console.WriteLine("Base64 encoded Destination required");
                        return;
                    }
                    break;

                default:
                    Console.WriteLine(args[i]);
                    Console.WriteLine("Usage: I2P.exe --addr 12.34.56.78 --port 8081 --nofw --create-destination [0-3] --destination b64...");
                    break;
                }
            }

            RouterContext.Inst.ApplyNewSettings();

            var pnp = new UPnp();

            Thread.Sleep(5000);   // Give UPnp a chance

            Router.Start();

            // Create new identities for this run

            MyDestination = MyDestinationInfo.Destination;

#if MANUAL_SIGN
            PublishedDestination = Router.CreateDestination(
                MyDestination,
                MyDestinationInfo.PrivateKey,
                true,
                out _);      // Publish our destinaiton
            PublishedDestination.SignLeasesRequest += MyDestination_SignLeasesRequest;
#else
            PublishedDestination = Router.CreateDestination(MyDestinationInfo, true, out _);   // Publish our destinaiton
#endif
            PublishedDestination.DataReceived += MyDestination_DataReceived;
            PublishedDestination.Name          = "PublishedDestination";

            MyOriginInfo = new I2PDestinationInfo(I2PSigningKey.SigningKeyTypes.DSA_SHA1);
            MyOrigin     = Router.CreateDestination(MyOriginInfo, false, out _);
            MyOrigin.ClientStateChanged += MyOrigin_ClientStateChanged;
            MyOrigin.DataReceived       += MyOrigin_DataReceived;
            MyOrigin.Name = "MyOrigin";

            Logging.LogInformation($"MyDestination: {PublishedDestination.Destination.IdentHash} {MyDestinationInfo.Destination.Certificate}");

            while (true)
            {
                try
                {
                    Connected = true;

                    MyOrigin.LookupDestination(PublishedDestination.Destination.IdentHash, LookupResult);

                    var sendevents = 0;

                    while (Connected)
                    {
                        Thread.Sleep(2000);

                        if (LookedUpDestination != null &&
                            MyOrigin.ClientState == ClientDestination.ClientStates.Established)
                        {
                            SendInterval.Do(() =>
                            {
                                if (sendevents++ < 10)
                                {
                                    // Send some data to the MyDestination
                                    DataSent = new BufLen(
                                        BufUtils.RandomBytes(
                                            (int)(1 + BufUtils.RandomDouble(25) * 1024)));

                                    var ok = MyOrigin.Send(LookedUpDestination, DataSent);
                                    Logging.LogInformation($"Program {MyOrigin}: Send[{sendevents}] {ok}, {DataSent:15}");
                                }

                                if (sendevents > 100)
                                {
                                    sendevents = 0;
                                }
                            });
                        }
                    }
                }
                catch (SocketException ex)
                {
                    Logging.Log(ex);
                }
                catch (IOException ex)
                {
                    Logging.Log(ex);
                }
                catch (Exception ex)
                {
                    Logging.Log(ex);
                }
            }
        }
Beispiel #26
0
        private void Run()
        {
            try
            {
                var ntcphost = new NTCPHost();

                ntcphost.ConnectionCreated += NTCPhost_ConnectionCreated;
                SsuHost.ConnectionCreated  += SSUHost_ConnectionCreated;

                while (!Terminated)
                {
                    try
                    {
                        Thread.Sleep(1000);

                        var known = CurrentlyUnknownRouters.FindKnown();
                        foreach (var found in known)
                        {
                            foreach (var msg in found.Messages)
                            {
                                Logging.LogTransport($"TransportProvider: Destination {found.Destination.Id32Short} found. Sending data.");
                                TransportProvider.Send(found.Destination, msg);
                            }
                        }

#if DEBUG
                        ActiveConnectionLog.Do(() =>
                        {
                            var ntcprunning     = RunningTransports.Where(t => t.Protocol == "NTCP").ToArray();
                            var ssurunning      = RunningTransports.Where(t => t.Protocol == "SSU").ToArray();
                            var ntcpestablished = EstablishedTransports.SelectMany(t => t.Value.Where(t2 => t2.Key.Protocol == "NTCP")).ToArray();
                            var ssuestablished  = EstablishedTransports.SelectMany(t => t.Value.Where(t2 => t2.Key.Protocol == "SSU")).ToArray();

                            Logging.LogDebug(
                                $"TransportProvider: Established out/in " +
                                $"({ssuestablished.Count( t => t.Key.Outgoing )}/{ssurunning.Count( t => t.Outgoing )})/" +
                                $"({ssuestablished.Count( t => !t.Key.Outgoing )}/{ssurunning.Count( t => !t.Outgoing )}) SSU, " +
                                $"({ntcpestablished.Count( t => t.Key.Outgoing )}/{ntcprunning.Count( t => t.Outgoing )})/" +
                                $"({ntcpestablished.Count( t => !t.Key.Outgoing )}/{ntcprunning.Count( t => !t.Outgoing )}) NTCP.");

                            var ntcpsent = ntcprunning.Sum(t => t.BytesSent);
                            var ntcprecv = ntcprunning.Sum(t => t.BytesReceived);
                            var ssusent  = ssurunning.Sum(t => t.BytesSent);
                            var ssurecv  = ssurunning.Sum(t => t.BytesReceived);

                            Logging.LogDebug(
                                $"TransportProvider: send / recv  " +
                                $"SSU: {BytesToReadable( ssusent ),12} / {BytesToReadable( ssurecv ),12}    " +
                                $"NTCP: {BytesToReadable( ntcpsent ),12} / {BytesToReadable( ntcprecv ),12}");
                        });
#endif

                        DropOldExceptions.Do(delegate
                        {
                            lock ( AddressesWithExceptions )
                            {
                                var remove = AddressesWithExceptions.Where(eh =>
                                                                           eh.Value.Generated.DeltaToNow.ToMinutes >= ExeptionHistoryLifetimeMinutes).Select(eh => eh.Key).ToArray();
                                foreach (var one in remove)
                                {
                                    AddressesWithExceptions.Remove(one);
                                }
                            }
                        });
                    }
                    catch (ThreadAbortException ex)
                    {
                        Logging.Log(ex);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(ex);
                    }
                }
            }
            finally
            {
                Terminated = true;
            }
        }
Beispiel #27
0
 internal void Execute()
 {
     TunnelBuild.Do(BuildNewTunnels);
 }
Beispiel #28
0
        public override SSUState Run()
        {
            // Idle
            if (Timeout(InactivityTimeout))
            {
                Logging.LogTransport($"SSU EstablishedState {Session.DebugId}: Inactivity timeout. Sending SessionDestroyed.");
                SendSessionDestroyed();
                return(null);
            }

            UpdateSessionLengthStats.Do(() =>
                                        Session.Host.EPStatisitcs.UpdateSessionLength(
                                            Session.RemoteEP,
                                            Session.StartTime.DeltaToNow));

            var dosend = Session.Defragmenter.GotAcks ||
                         (!Session.SendQueue.IsEmpty) ||
                         Session.Fragmenter.GotUnsentFragments;

            TickSpan timeout = null;

            if (!dosend)
            {
                if (SessionLayer.RouterContext.Inst.IsFirewalled)
                {
                    if (Session.IsIntroducerConnection)
                    {
                        timeout = IntroducerKeepaliveTimeout;
                    }
                    else
                    {
                        timeout = NonIntroducerKeepaliveTimeout;
                    }
                }
                else
                {
                    timeout = NotFirewalledKeepaliveTimeout;
                }
            }

            if (!dosend && LastIntroducerKeepalive.DeltaToNow > timeout)
            {
                dosend = true;

#if LOG_MUCH_TRANSPORT
                Logging.LogTransport($"SSU EstablishedState {Session.DebugId}:" +
                                     $"{(Session.IsIntroducerConnection ? " Introducer" : "")} keepalive.");
#endif
                LastIntroducerKeepalive.SetNow();
            }

            if (dosend)
            {
                do
                {
                    SendAcksAndData();
                } while (!Session.SendQueue.IsEmpty);
            }

            ResendFragmentsAction.Do(delegate
            {
                if (Session.Fragmenter.AllFragmentsAcked)
                {
                    return;
                }

                ResendNotAcked(Session.Fragmenter.NotAckedFragments());
            });

            if (Session.QueuedFirstPeerTestToCharlie != null)
            {
                SendFirstPeerTestToCharlie(Session.QueuedFirstPeerTestToCharlie);
                Session.QueuedFirstPeerTestToCharlie = null;
            }

            return(this);
        }
Beispiel #29
0
 public void Execute()
 {
     LogStatus.Do(LogStatusReport);
 }
        public IEnumerable <TunnelMessage> Process(IEnumerable <TunnelDataMessage> tdmsgs)
        {
            var result = new List <TunnelMessage>();

            RemoveUnmatchedFragments.Do(() =>
            {
                lock ( MessageFragments )
                {
                    var remove = MessageFragments.Where(p => p.Value.Created.DeltaToNow.ToMinutes > RememberUnmatchedFragmentsForMinutes).
                                 Select(p => p.Key).ToArray();
                    foreach (var key in remove)
                    {
                        Logging.LogDebug("TunnelDataFragmentReassembly: Removing old unmatched fragment for " + key.ToString());
                        MessageFragments.Remove(key);
                    }
                }
            });

            foreach (var msg in tdmsgs)
            {
                var hash = I2PHashSHA256.GetHash(msg.TunnelDataPayload, msg.IV);
                var eq   = BufUtils.Equal(msg.Checksum.PeekB(0, 4), 0, hash, 0, 4);
                if (!eq)
                {
                    // Do not stop processing, just throw away faulty data
                    // throw new SignatureCheckFailureException( "TunnelDataFragmentReassembly: SHA256 check failed in TunnelData" );
                    Logging.LogDebug("TunnelDataFragmentReassembly: SHA256 check failed in TunnelData");
                    continue;
                }

                var reader = (BufRefLen)msg.TunnelDataPayload;

                while (reader.Length > 0)
                {
                    var frag = new TunnelDataFragment(reader);

                    if (frag.FollowOnFragment)
                    {
                        List <TunnelDataFragment> fragments;

                        if (!MessageFragments.ContainsKey(frag.MessageId))
                        {
                            fragments = new List <TunnelDataFragment>();
                            MessageFragments[frag.MessageId] = new TunnelDataFragmentList(fragments);
                        }
                        else
                        {
                            fragments = MessageFragments[frag.MessageId].List;
                        }

                        if (fragments.Count <= frag.FragmentNumber)
                        {
                            fragments.AddRange(new TunnelDataFragment[frag.FragmentNumber - fragments.Count + 1]);
                        }
                        fragments[frag.FragmentNumber] = frag;

                        CheckForAllFragmentsFound(result, frag.MessageId, fragments);
                    }
                    else
                    {
                        if (frag.Fragmented)
                        {
                            List <TunnelDataFragment> fragments;

                            if (!MessageFragments.ContainsKey(frag.MessageId))
                            {
                                fragments = new List <TunnelDataFragment>();
                                MessageFragments[frag.MessageId] = new TunnelDataFragmentList(fragments);
                            }
                            else
                            {
                                fragments = MessageFragments[frag.MessageId].List;
                            }

                            if (fragments.Count == 0)
                            {
                                fragments.AddRange(new TunnelDataFragment[1]);
                            }
                            fragments[0] = frag;

                            CheckForAllFragmentsFound(result, frag.MessageId, fragments);
                        }
                        else
                        {
                            AddTunnelMessage(result, frag, frag.Payload.ToByteArray());
                        }
                    }
                }
            }

            return(result);
        }