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

Last change on this file since 2295 was 2295, checked in by Sven Rech, 11 years ago

Prepared KeySearcher for Localization

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