source: trunk/CrypPlugins/KeySearcher/P2P/DistributedBruteForceManager.cs @ 2527

Last change on this file since 2527 was 2527, checked in by nolte, 11 years ago

Added more Information to the Information-Tag of the
StatisticPresentation.

File size: 19.0 KB
RevLine 
[1634]1using System;
[2024]2using System.Collections.Generic;
[1682]3using System.Diagnostics;
[1643]4using System.Numerics;
[2115]5using System.Threading;
[1682]6using System.Windows.Threading;
[1707]7using Cryptool.P2P;
[2115]8using Cryptool.P2P.Internal;
[1634]9using Cryptool.PluginBase;
10using KeySearcher.Helper;
[1674]11using KeySearcher.KeyPattern;
[1647]12using KeySearcher.P2P.Exceptions;
[1707]13using KeySearcher.P2P.Helper;
[1682]14using KeySearcher.P2P.Presentation;
[1674]15using KeySearcher.P2P.Storage;
16using KeySearcher.P2P.Tree;
[1682]17using KeySearcherPresentation.Controls;
[2295]18using KeySearcher.Properties;
[2024]19using System.Timers;
[2115]20using Timer = System.Timers.Timer;
[1634]21
22namespace KeySearcher.P2P
23{
[1674]24    internal class DistributedBruteForceManager
[1634]25    {
[1674]26        private readonly StorageKeyGenerator keyGenerator;
27        private readonly KeySearcher keySearcher;
[1682]28        private readonly KeySearcherSettings settings;
[1707]29        private readonly KeyQualityHelper keyQualityHelper;
[1682]30        private readonly P2PQuickWatchPresentation quickWatch;
[1674]31        private readonly KeyPatternPool patternPool;
[1682]32        private readonly StatusContainer status;
33        internal readonly StatisticsGenerator StatisticsGenerator;
34        internal readonly Stopwatch StopWatch;
[1634]35
[1707]36        private KeyPoolTree keyPoolTree;
[2115]37        private AutoResetEvent systemJoinEvent = new AutoResetEvent(false);
[1707]38
[1674]39        public DistributedBruteForceManager(KeySearcher keySearcher, KeyPattern.KeyPattern keyPattern, KeySearcherSettings settings,
[1682]40                                            KeyQualityHelper keyQualityHelper, P2PQuickWatchPresentation quickWatch)
[1634]41        {
[1674]42            this.keySearcher = keySearcher;
[1682]43            this.settings = settings;
[1707]44            this.keyQualityHelper = keyQualityHelper;
[1682]45            this.quickWatch = quickWatch;
[1634]46
[1647]47            // TODO when setting is still default (21), it is only displayed as 21 - but the settings-instance contains 0 for that key!
[1634]48            if (settings.ChunkSize == 0)
49            {
[1647]50                settings.ChunkSize = 21;
[1634]51            }
52
[1698]53            StopWatch = new Stopwatch();
[2078]54            status = new StatusContainer(keySearcher);
[1698]55            status.IsCurrentProgressIndeterminate = true;
56
[1674]57            keyGenerator = new StorageKeyGenerator(keySearcher, settings);
58            patternPool = new KeyPatternPool(keyPattern, new BigInteger(Math.Pow(2, settings.ChunkSize)));
[1682]59            StatisticsGenerator = new StatisticsGenerator(status, quickWatch, keySearcher, settings, this);
60            quickWatch.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(UpdateStatusContainerInQuickWatch));
[1707]61        }
[1682]62
[1707]63        public void Execute()
64        {
[2295]65            status.CurrentOperation = Resources.Initializing_connection_to_the_peer_to_peer_system;
[1707]66            new ConnectionHelper(keySearcher, settings).ValidateConnectionToPeerToPeerSystem();
67
68            if (!P2PManager.IsConnected)
69            {
[2295]70                keySearcher.GuiLogMessage(Resources.Unable_to_use_peer_to_peer_system_, NotificationLevel.Error);
71                status.CurrentOperation = Resources.Unable_to_use_peer_to_peer_system_;
[1707]72                return;
73            }
74
[2295]75            status.CurrentOperation = Resources.Initializing_distributed_key_pool_tree;
[2283]76            InitializeTree();
[2142]77           
[2283]78            bool statupdate = false;
79            Leaf currentLeaf;
[2527]80            keySearcher.InitialiseInformationQuickwatch();
[2283]81            var statisticTimer = new Timer { Interval = 30 * 60 * 1000 };    //Update of the statistics after every 30 minutes
82            statisticTimer.Start();
[1707]83
[1674]84            while (!keySearcher.stop)
[1634]85            {
[2434]86                try
[2283]87                {
[2434]88                    if (statupdate)
89                    {
90                        statisticTimer.Stop();
91                        statisticTimer.Dispose();
92                        keyPoolTree.Reset();
93                        keySearcher.ResetStatistics();
94                        keySearcher.SetInitialized(false);
95                        status.CurrentOperation = Resources.Updating_statistic;
96                        InitializeTree();
97                        statupdate = false;
98                        statisticTimer = new Timer { Interval = 30 * 60 * 1000 };
99                        statisticTimer.Start();
100                    }
[2283]101
[2434]102                    status.IsCurrentProgressIndeterminate = true;
[1698]103
[2434]104                    BigInteger displayablePatternId;
105                    try
[1671]106                    {
[2434]107                        status.CurrentOperation = Resources.Finding_next_leaf_to_calculate;
108                        currentLeaf = keyPoolTree.FindNextLeaf();
109                        if (currentLeaf == null)
110                        {
111                            break;
112                        }
113                        displayablePatternId = currentLeaf.PatternId() + 1;
[1671]114                    }
[2434]115                    catch (AlreadyCalculatedException)
116                    {
117                        keySearcher.GuiLogMessage(Resources.Node_was_already_calculated_, NotificationLevel.Info);
118                        keyPoolTree.Reset();
119                        continue;
120                    }
121                    catch (KeySearcherStopException)  //Fullstopfunction
122                    {
123                        keySearcher.GuiLogMessage(Resources.Keysearcher_Fullstop__Please_Update_your_Version_, NotificationLevel.Debug);
124                        status.CurrentOperation = Resources.PLEASE_UPDATE;
125                        keyPoolTree.Reset();
126                        keySearcher.Stop();
127                        return;
128                    }
[1671]129
[2434]130                    // TODO if reserve returns successfully, start timer to update our reserveration every few minutes
131                    // if we cannot reacquire our lock in the timer, calculation must be aborted
132                    if (!currentLeaf.ReserveLeaf())
133                    {
134                        keySearcher.GuiLogMessage(
135                            string.Format(Resources.Pattern___0__was_reserved_before_it_could_be_reserved_for_this_CrypTool_instance_, displayablePatternId),
136                            NotificationLevel.Info);
137                        keyPoolTree.Reset();
138                        continue;
139                    }
[1665]140
[2434]141                    bool reservationRemoved = false;
142                    var reservationTimer = new Timer { Interval = 18 * 60 * 1000 };    //Every 18 minutes
143                    reservationTimer.Elapsed += new ElapsedEventHandler(delegate
[2115]144                                                                            {
[2434]145                                                                                var oldMessage = status.CurrentOperation;
146                                                                                var message = string.Format(Resources.Rereserving_pattern___0_, displayablePatternId);
147                                                                                keySearcher.GuiLogMessage(message, NotificationLevel.Info);
148                                                                                status.CurrentOperation = message;
149                                                                                try
150                                                                                {
151                                                                                    if (!currentLeaf.ReserveLeaf())
152                                                                                        keySearcher.GuiLogMessage(Resources.Rereserving_pattern_failed_, NotificationLevel.Warning);
[2160]153
[2434]154                                                                                    //if (!currentLeaf.ReserveLeaf())
155                                                                                    //{
156                                                                                    //    keySearcher.GuiLogMessage("Rereserving pattern failed! Skipping to next pattern!",
157                                                                                    //        NotificationLevel.Warning);
158                                                                                    //    reservationRemoved = true;
159                                                                                    //    keySearcher.stop = true;
160                                                                                    //}
161                                                                                }
162                                                                                catch (Cryptool.P2P.Internal.NotConnectedException)
163                                                                                {
164                                                                                    keySearcher.GuiLogMessage(Resources.Rereserving_pattern_failed__because_there_is_no_connection_,
165                                                                                            NotificationLevel.Warning);
166                                                                                    //TODO: Register OnSystemJoined event to rereserve pattern immediately after reconnect
167                                                                                }
168                                                                                status.CurrentOperation = oldMessage;
169                                                                            });
[2024]170
[2434]171                    statisticTimer.Elapsed += new ElapsedEventHandler(delegate
172                                                                          {
173                                                                              statupdate = true;
174                                                                          });
[2283]175
[2434]176                    keySearcher.GuiLogMessage(
177                        string.Format(Resources.Running_pattern___0__of__1_, displayablePatternId, patternPool.Length),
178                        NotificationLevel.Info);
179                    status.CurrentChunk = displayablePatternId;
180                    status.CurrentOperation = Resources.Calculating_pattern_ + status.CurrentChunk;
[1634]181
[2024]182                    try
183                    {
[2434]184                        LinkedList<KeySearcher.ValueKey> result;
185
186                        status.IsCurrentProgressIndeterminate = false;
187                        StopWatch.Start();
188                        reservationTimer.Start();
189                        try
[2115]190                        {
[2434]191                            result = keySearcher.BruteForceWithLocalSystem(patternPool[currentLeaf.PatternId()], true);
192                            if (reservationRemoved)
193                            {
194                                keySearcher.stop = false;
195                                throw new ReservationRemovedException("");
196                            }
[2115]197                        }
[2434]198                        finally
[2115]199                        {
[2434]200                            reservationTimer.Stop();
201                            reservationTimer.Dispose();
202                            StopWatch.Stop();
203                            status.IsCurrentProgressIndeterminate = true;
[2115]204                        }
[1727]205
[2434]206                        if (!keySearcher.stop)
207                        {
208                            if (!P2PManager.IsConnected)
209                            {
210                                status.CurrentOperation = Resources.Connection_lost__Waiting_for_reconnection_to_store_the_results_;
211                                keySearcher.GuiLogMessage(status.CurrentOperation, NotificationLevel.Info);
[2436]212                                do
213                                {
214                                    P2PManager.P2PBase.OnSystemJoined += P2PBase_OnSystemJoined;
215                                    systemJoinEvent.WaitOne(1000);
216                                } while (!P2PManager.IsConnected);
[2434]217                            }
218                            status.CurrentOperation = Resources.Processing_results_of_calculation;
[2495]219
220                            String hostname = Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetHostName();
221                            Int64 hostid = Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
222                            if (settings.UseExternalClient)
223                            {
224                                hostname = keySearcher.ExternalClientHostname;
225                                hostid = keySearcher.ExternaClientId;
226                            }
227                            KeyPoolTree.ProcessCurrentPatternCalculationResult(currentLeaf, result, hostid, hostname);
[2434]228                            StatisticsGenerator.ProcessPatternResults(result);
[1727]229
[2434]230                            status.CurrentOperation = Resources.Calculating_global_statistics;
231                            StatisticsGenerator.CalculateGlobalStatistics(displayablePatternId);
232
233                            status.LocalFinishedChunks++;
234                            keySearcher.GuiLogMessage(
235                                string.Format(Resources.Best_match___0__with__1_, result.First.Value.key, result.First.Value.value),
236                                NotificationLevel.Info);
237
238                            status.CurrentOperation = Resources.Updating_status_in_DHT;
239                            keyPoolTree.UpdateStatus(currentLeaf);
240                        }
241                        else
242                        {
243                            keySearcher.GuiLogMessage(Resources.Brute_force_was_stopped__not_saving_results___,
244                                                      NotificationLevel.Info);
245                            status.ProgressOfCurrentChunk = 0;
246                            currentLeaf.GiveLeafFree();
247                            var message = string.Format(Resources.Removed_reservation_of_pattern___0_, displayablePatternId);
248                            keySearcher.GuiLogMessage(message, NotificationLevel.Info);
249                            status.CurrentOperation = message;
250                        }
[1682]251                    }
[2434]252                    catch (ReservationRemovedException)
[1682]253                    {
[2434]254                        keySearcher.GuiLogMessage(Resources.Reservation_removed_by_another_node__while_calculating___To_avoid_a_state_in_limbo__proceeding_to_first_available_leaf___,
[1674]255                                                  NotificationLevel.Info);
[2434]256                        keyPoolTree.Reset();
257                        continue;
[1682]258                    }
[2434]259                    catch (UpdateFailedException e)
260                    {
261                        keySearcher.GuiLogMessage(Resources.Could_not_store_results__ + e.Message, NotificationLevel.Info);
262                        keyPoolTree.Reset();
263                        continue;
264                    }
265                    catch (KeySearcherStopException)  //Fullstopfunction
266                    {
267                        keySearcher.GuiLogMessage(Resources.Keysearcher_Fullstop__Please_Update_your_Version_, NotificationLevel.Debug);
268                        status.CurrentOperation = Resources.PLEASE_UPDATE;
269                        keyPoolTree.Reset();
270                        keySearcher.Stop();
271                        return;
272                    }
273
274                    // Push statistics to database
275                    status.CurrentOperation = Resources.Pushing_statistics_to_evaluation_database;
276                    DatabaseStatistics.PushToDatabase(status, StopWatch.ElapsedMilliseconds, keyPoolTree.Identifier, settings, keySearcher);
[1665]277                }
[2434]278                catch (NotConnectedException)
[1634]279                {
[2434]280                    status.CurrentOperation = "Connection lost. Waiting for reconnect...";
281                    keySearcher.GuiLogMessage(status.CurrentOperation, NotificationLevel.Info);
[2436]282                    do
283                    {
284                        P2PManager.P2PBase.OnSystemJoined += P2PBase_OnSystemJoined;
285                        systemJoinEvent.WaitOne(1000);
286                    } while (!P2PManager.IsConnected);
[1634]287                }
[2439]288                catch (InvalidOperationException)
289                {
290                    //do nothing
291                }
[1634]292            }
293
294            // Set progress to 100%
[1674]295            if (!keySearcher.stop && keyPoolTree.IsCalculationFinished())
[1634]296            {
[2150]297                keySearcher.showProgress(keySearcher.costList, 1, 1, 1);
[2295]298                keySearcher.GuiLogMessage(Resources.Calculation_complete_, NotificationLevel.Info);
[1727]299                keyPoolTree.UpdateStatusForFinishedCalculation();
[1634]300            }
[1698]301
[1708]302            StatisticsGenerator.CalculationStopped();
[1698]303            status.ProgressOfCurrentChunk = 0;
304            status.IsSearchingForReservedNodes = false;
305            status.IsCurrentProgressIndeterminate = false;
[1705]306            status.CurrentOperation = "Idle";
[2283]307            statisticTimer.Stop();
308            statisticTimer.Dispose();
[1707]309            status.RemainingTimeTotal = new TimeSpan(0);
[1634]310        }
[1682]311
[2262]312        private int FindLocalPatterns()
313        {
[2275]314            //String myAvatar = "CrypTool2";
315            String myAvatar = P2PSettings.Default.PeerName;
[2262]316            long myID = Cryptool.PluginBase.Miscellaneous.UniqueIdentifier.GetID();
317            Dictionary<string, Dictionary<long, Information>> myStats = keySearcher.GetStatistics();
318
319            if(myStats.ContainsKey(myAvatar))
320            {
321                if(myStats[myAvatar].ContainsKey(myID))
322                {
323                    return myStats[myAvatar][myID].Count;
324                }
325            }
326            return 0;
327        }
328
[2283]329        private void InitializeTree()
330        {
331            try
332            {
333                keyPoolTree = new KeyPoolTree(patternPool, keySearcher, keyQualityHelper, keyGenerator, status, StatisticsGenerator);
334            }
335            catch (KeySearcherStopException)
336            {
[2295]337                status.CurrentOperation = Resources.PLEASE_UPDATE;
338                keySearcher.GuiLogMessage(Resources.Keysearcher_Fullstop__Please_Update_your_Version_, NotificationLevel.Error);
[2283]339                keySearcher.Stop();
340                throw new KeySearcherStopException();
341            }
342
343
344            keySearcher.GuiLogMessage(
[2295]345                string.Format(Resources.Total_amount_of_patterns___0___each_containing__1__keys_, patternPool.Length, patternPool.PartSize), NotificationLevel.Info);
346            status.CurrentOperation = Resources.Ready_for_calculation;
[2283]347
348            status.StartDate = keyPoolTree.StartDate();
[2527]349            keySearcher.SetBeginningDate(keyPoolTree.StartDate());
[2283]350            status.JobSubmitterID = keyPoolTree.SubmitterID();
351            status.LocalFinishedChunks = FindLocalPatterns();
352
353            keyPoolTree.UpdateStatusForNewCalculation();
354            keySearcher.SetInitialized(true);
355        }
356
[2115]357        void P2PBase_OnSystemJoined()
358        {
359            P2PManager.P2PBase.OnSystemJoined -= P2PBase_OnSystemJoined;
360            systemJoinEvent.Set();
361        }
362
[1682]363        private void UpdateStatusContainerInQuickWatch()
364        {
365            quickWatch.DataContext = status;
366            quickWatch.UpdateSettings(keySearcher, settings);
367        }
[1634]368    }
[1674]369}
Note: See TracBrowser for help on using the repository browser.