source: trunk/CrypPlugins/PeerToPeerManager_NEW/P2PManager_KeyPattern.cs @ 1170

Last change on this file since 1170 was 1170, checked in by arnold, 12 years ago

P2PManager: Locking the Allocation of jobs, because some worker got more than one job, when two or more jobs ran into the function parallely.
@All other changes: Added some TODO comments in the head of the classes

File size: 21.6 KB
Line 
1/* Copyright 2010 Team CrypTool (Christian Arnold), Uni Duisburg-Essen
2
3   Licensed under the Apache License, Version 2.0 (the "License");
4   you may not use this file except in compliance with the License.
5   You may obtain a copy of the License at
6
7       http://www.apache.org/licenses/LICENSE-2.0
8
9   Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14*/
15
16using System;
17using System.Collections.Generic;
18using System.Linq;
19using System.Text;
20using System.Threading;
21using Cryptool.PluginBase;
22using Cryptool.PluginBase.IO;
23using Cryptool.PluginBase.Control;
24using Cryptool.PluginBase.Miscellaneous;
25using System.ComponentModel;
26using KeySearcher;
27using System.Windows.Controls;
28using System.Windows.Threading;
29using Cryptool.Plugins.PeerToPeer.Jobs;
30
31/*TODO:
32 * - Execute: If InitVector is null, try to create a fitting InitVector with the format 0...0
33 * - No linebreaks in the global result list
34 * - 2 Output values (Top1-Key and Top1-Decryption)
35 * - Display the job stati in a kind of a defragmentation list
36 */
37
38namespace Cryptool.Plugins.PeerToPeer
39{
40    /// <summary>
41    /// This PlugIn only works, when its connected with a P2P_Peer object.
42    /// </summary>
43    [Author("Christian Arnold", "arnold@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
44    [PluginInfo(false, "P2P_Manager_KeyPattern", "Creates a new Manager-Peer for distributable KeyPattern-Jobs", "", "PeerToPeerManager_NEW/manager_medium_neutral.png", "PeerToPeerManager_NEW/manager_medium_working.png", "PeerToPeerManager_NEW/manager_medium_finished.png")]
45    public class P2PManager_KeyPattern : IInput
46    {
47        private P2PManagerBase_NEW p2pManager;
48        private P2PManager_KeyPatternSettings settings;
49        // IInput
50        private CryptoolStream decryptedData;
51        private byte[] initVector;
52        // IControls       
53        private IControlEncryption encryptionControl;
54        private IP2PControl p2pControl;
55
56        private KeyPattern pattern = null;
57        public KeyPattern Pattern
58        {
59            get
60            {
61                return pattern;
62            }
63            set
64            {
65                pattern = value;
66                if ((settings.Key == null) || ((settings.Key != null) && !pattern.testWildcardKey(settings.Key)))
67                    settings.Key = pattern.giveInputPattern();
68            }
69        }
70
71        /// <summary>
72        /// after starting the execution, set this value, so after receiving
73        /// a Job result, the WPF UpdateQuickWatch can use this value, without
74        /// accessing the Settings every time.
75        /// </summary>
76        private int bytesToUseForDecryption = 0;
77
78        #region In and Output
79
80        [PropertyInfo(Direction.InputData, "Encrypted Data", "Encrypted data out of an Encryption PlugIn", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, "")]
81        public CryptoolStream DecryptedData
82        {
83            get { return this.decryptedData; }
84            set
85            {
86                if (value != this.decryptedData)
87                {
88                    this.decryptedData = value;
89                }
90            }
91        }
92
93        [PropertyInfo(Direction.InputData, "Initialization Vector", "Initialization vector with which the data were encrypted", "", DisplayLevel.Beginner)]
94        public byte[] InitVector
95        {
96            get { return this.initVector; }
97            set
98            {
99                if (value != this.initVector)
100                    this.initVector = value;
101            }
102        }
103
104        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
105        public IControlEncryption EncryptionControl
106        {
107            get { return this.encryptionControl; }
108            set
109            {
110                if (this.encryptionControl != null)
111                {
112                    this.encryptionControl.keyPatternChanged -= encryptionControl_keyPatternChanged;
113                    this.encryptionControl.OnStatusChanged -= encryptionControl_onStatusChanged;
114                }
115                if (value != null)
116                {
117                    Pattern = new KeyPattern(value.getKeyPattern());
118                    value.keyPatternChanged += encryptionControl_keyPatternChanged;
119                    value.OnStatusChanged += encryptionControl_onStatusChanged;
120                    this.encryptionControl = value;
121                    OnPropertyChanged("ControlMaster");
122
123                }
124                else
125                    this.encryptionControl = null;
126            }
127        }
128
129        private void encryptionControl_keyPatternChanged()
130        {
131            Pattern = new KeyPattern(this.encryptionControl.getKeyPattern());
132        }
133        private void encryptionControl_onStatusChanged(IControl sender, bool readyForExecution)
134        {
135            // obsolete stuff
136            if (readyForExecution)
137            {
138                this.process((IControlEncryption)sender);
139            }
140        }
141
142        /// <summary>
143        /// Catches the completely configurated, initialized and joined P2P object from the P2PPeer-Slave-PlugIn.
144        /// </summary>
145        [PropertyInfo(Direction.ControlMaster, "P2P Slave", "Input the P2P-Peer-PlugIn", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
146        public IP2PControl P2PControl
147        {
148            get
149            {
150                return this.p2pControl;
151            }
152            set
153            {
154                if (this.p2pControl != null)
155                {
156                    this.p2pControl.OnStatusChanged -= P2PControl_OnStatusChanged;
157                }
158                if (value != null)
159                {
160                    this.p2pControl = (P2PPeerMaster)value;
161                    this.p2pControl.OnStatusChanged += new IControlStatusChangedEventHandler(P2PControl_OnStatusChanged);
162                    OnPropertyChanged("P2PMaster");
163                }
164                else
165                {
166                    this.p2pControl = null;
167                }
168            }
169        }
170
171        private void P2PControl_OnStatusChanged(IControl sender, bool readyForExecution)
172        {
173            //throw new NotImplementedException();
174        }
175
176        #endregion
177
178        #region Events
179
180        public event StatusChangedEventHandler OnPluginStatusChanged;
181
182        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
183
184        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
185
186        #endregion
187
188        #region Standard PlugIn-Functionality
189
190        public P2PManager_KeyPattern()
191        {
192            this.settings = new P2PManager_KeyPatternSettings();
193            this.settings.PropertyChanged += new PropertyChangedEventHandler(settings_PropertyChanged);
194            this.settings.TaskPaneAttributeChanged += new TaskPaneAttributeChangedHandler(settings_TaskPaneAttributeChanged);
195            this.settings.OnPluginStatusChanged += new StatusChangedEventHandler(settings_OnPluginStatusChanged);
196
197            QuickWatchPresentation = new P2PManagerPresentation();
198        }
199
200        #region QuickWatchPresentation Stuff
201
202        public UserControl QuickWatchPresentation
203        {
204            get;
205            private set;
206        }
207
208        public UserControl Presentation
209        {
210            get { return QuickWatchPresentation; }
211        }
212
213        private void UpdateQuickWatch(double progressInPercent)
214        {
215            UpdateQuickWatch(this.distributableKeyPatternJob.GlobalResultList, this.distributableKeyPatternJob.TotalAmount,
216                this.distributableKeyPatternJob.AllocatedAmount, this.distributableKeyPatternJob.FinishedAmount, 
217                progressInPercent, this.p2pManager.FreeWorkers(), this.p2pManager.BusyWorkers());
218        }
219
220        private void UpdateQuickWatch(LinkedList<KeySearcher.KeySearcher.ValueKey> globalTop10List,
221            BigInteger jobsTotalAmount, BigInteger jobsInProgress, BigInteger jobsFinished, double progressInPercent,
222            int freeWorkers, int busyWorkers)
223        {
224            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
225            LinkedListNode<KeySearcher.KeySearcher.ValueKey> listNode;
226
227            if (QuickWatchPresentation.IsVisible)
228            {
229                ((P2PManagerPresentation)QuickWatchPresentation).Dispatcher.Invoke(DispatcherPriority.Normal, (SendOrPostCallback)delegate
230                {
231                    ((P2PManagerPresentation)QuickWatchPresentation).txtProgressInPercent.Text = "" + Math.Round(progressInPercent, 2) + "%";
232                    ((P2PManagerPresentation)QuickWatchPresentation).txtTotal.Text = "" + jobsTotalAmount.ToString();
233                    ((P2PManagerPresentation)QuickWatchPresentation).txtInProgress.Text = "" + jobsInProgress.ToString();
234                    ((P2PManagerPresentation)QuickWatchPresentation).txtLeft.Text = "" + new BigInteger((jobsTotalAmount - jobsInProgress - jobsFinished)).ToString();
235                    ((P2PManagerPresentation)QuickWatchPresentation).txtFinished.Text = "" + jobsFinished.ToString();
236
237                    ((P2PManagerPresentation)QuickWatchPresentation).txtTotalWorker.Text = "" + (freeWorkers + busyWorkers);
238                    ((P2PManagerPresentation)QuickWatchPresentation).txtFreeWorker.Text = "" + freeWorkers;
239                    ((P2PManagerPresentation)QuickWatchPresentation).txtBusyWorker.Text = "" + busyWorkers;
240
241                    /* START approximation of end time */
242                    // this value is MinValue until the first job is allocated to a worker
243                    DateTime estimatedDateTime = this.p2pManager.EstimatedEndTime();
244                    if(estimatedDateTime != DateTime.MaxValue)
245                    {
246                        ((P2PManagerPresentation)QuickWatchPresentation).txtEstimatedEndTime.Text = estimatedDateTime.ToString();
247                    }
248                    /* END approximation of end time */
249
250                    ((P2PManagerPresentation)QuickWatchPresentation).entries.Clear();
251                    listNode = globalTop10List.First;
252
253                    int i = 0;
254                    while (listNode != null)
255                    {
256                        i++;
257
258                        ResultEntry entry = new ResultEntry();
259                        entry.Ranking = "" + i;
260                        entry.Value = "" + Math.Round(listNode.Value.value, 3);
261                        entry.Key = listNode.Value.key;
262                        entry.Text = enc.GetString(listNode.Value.decryption, 0, this.bytesToUseForDecryption);
263
264                        ((P2PManagerPresentation)QuickWatchPresentation).entries.Add(entry);
265                        listNode = listNode.Next;
266                    }
267                    // to resize the WPF Presentation, so it will fit in the PlugIn-Borders
268                    ((P2PManagerPresentation)QuickWatchPresentation).P2PManagerPresentation_SizeChanged(null, null);
269                }, null);
270            }
271        }
272
273        #endregion
274
275        void settings_OnPluginStatusChanged(IPlugin sender, StatusEventArgs args)
276        {
277            if (OnPluginStatusChanged != null)
278                OnPluginStatusChanged(this, args);
279        }
280
281        void settings_TaskPaneAttributeChanged(ISettings settings, TaskPaneAttributeChangedEventArgs args)
282        {
283            //throw new NotImplementedException();
284        }
285
286        void settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
287        {
288            if (e.PropertyName == "Key")
289            {
290                if (this.EncryptionControl != null)
291                {
292                    KeyPattern checkPattern = new KeyPattern(this.EncryptionControl.getKeyPattern());
293                    if (!checkPattern.testWildcardKey(this.settings.Key))
294                    {
295                        GuiLogMessage("The set Pattern doesn't fit to the encryption plugin connected with this manager!", NotificationLevel.Warning);
296                    }
297                    else
298                        GuiLogMessage("Successfully changed the KeyPattern in the settings.", NotificationLevel.Info);
299                }
300            }
301
302            if (this.p2pControl == null)
303                return;
304            if (e.PropertyName == "BtnUnregister")
305            {
306                if (this.p2pManager != null && this.p2pManager.Started)
307                {
308                    Stop();
309                    //this.p2pManager.Stop(PubSubMessageType.Unregister);
310                    GuiLogMessage("Unregister button pressed, Publisher has stopped!", NotificationLevel.Info);
311                }
312            }
313            if (e.PropertyName == "BtnRegister")
314            {
315                if (this.p2pManager == null || !this.p2pManager.Started)
316                {
317                    this.process(this.EncryptionControl);
318                    GuiLogMessage("Register button pressed, Publisher has been started!", NotificationLevel.Info);
319                }
320            }
321            if (e.PropertyName == "BtnSolutionFound")
322            {
323                if (this.p2pManager != null && this.p2pManager.Started)
324                {
325                    Stop();
326                    //this.p2pManager.Stop(PubSubMessageType.Solution);
327                    GuiLogMessage("TEST: Emulate Solution-Found-message", NotificationLevel.Info);
328                }
329            }
330        }
331
332        public ISettings Settings
333        {
334            set { this.settings = (P2PManager_KeyPatternSettings)value; }
335            get { return this.settings; }
336        }
337
338        // Pre-Execute Method is below this region
339
340        // Execute-Method is below this region
341
342        public void PostExecution()
343        {
344            //throw new NotImplementedException();
345        }
346
347        public void Pause()
348        {
349            //throw new NotImplementedException();
350        }
351
352        public void Stop()
353        {
354
355            if (this.p2pManager != null && this.p2pManager.Started)
356            {
357                this.p2pManager.Stop(PubSubMessageType.Unregister);
358                this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Neutral);
359                this.p2pManager.OnGuiMessage -= p2pManager_OnGuiMessage;
360                this.p2pManager.OnProcessProgress -= p2pManager_OnProcessProgress;
361                this.p2pManager.OnNewJobAllocated -= p2pManager_OnNewJobAllocated;
362                this.p2pManager.OnNoMoreJobsLeft -= p2pManager_OnNoMoreJobsLeft;
363                this.p2pManager.OnResultReceived -= p2pManager_OnResultReceived;
364                // set Manager to null, so after restarting the Workspace,
365                // a new Distributable stop will be initialized with (maybe)
366                // changed settings
367                this.p2pManager = null;
368            }
369        }
370
371        public void Initialize()
372        {
373        }
374
375        public void Dispose()
376        {
377        }
378
379        #endregion
380
381        public void PreExecution()
382        {
383            // if no P2P Slave PlugIn is connected with this PlugIn --> No execution!
384            if (P2PControl == null)
385            {
386                GuiLogMessage("No P2P_Peer connected with this PlugIn!", NotificationLevel.Error);
387                return;
388            }
389        }
390
391        void p2pManager_OnProcessProgress(double progressInPercent)
392        {
393            ProgressChanged(progressInPercent, 100.0);
394            UpdateQuickWatch(progressInPercent);
395        }
396
397        void p2pManager_OnGuiMessage(string sData, NotificationLevel notificationLevel)
398        {
399            GuiLogMessage(sData, notificationLevel);
400        }
401
402        DistributableKeyPatternJob distributableKeyPatternJob;
403        public void Execute()
404        {
405            if (this.DecryptedData != null)
406            {
407                // TODO: dirty hack because of a missing Initialization vector
408                // it can't be null, because serialization will throw an exception in this case
409                if (this.InitVector == null)
410                {
411                    this.InitVector = new byte[8]{0,0,0,0,0,0,0,0};
412                    GuiLogMessage("Initialization vector not set, so set a standard value - dirty hack!", NotificationLevel.Info);
413                }
414                this.process(this.EncryptionControl);
415            }               
416        }
417
418        private void process(IControlEncryption iControlEncryption)
419        {
420            // if no P2P Slave PlugIn is connected with this PlugIn --> No execution!
421            if (P2PControl == null)
422            {
423                GuiLogMessage("No P2P_Peer connected with this PlugIn!", NotificationLevel.Error);
424                return;
425            }
426            if (iControlEncryption == null)
427            {
428                GuiLogMessage("No Encryption Control connected with this PlugIn", NotificationLevel.Error);
429                return;
430            }
431
432            if (this.p2pManager == null)
433            {
434                byte[] byteEncryptedData = null;
435                CryptoolStream newEncryptedData = new CryptoolStream();
436                try
437                {
438                    newEncryptedData.OpenRead(this.DecryptedData.FileName);
439                    // Convert CryptoolStream to an byte Array and store it in the DHT
440                    if (newEncryptedData.Length > Int32.MaxValue)
441                        throw (new Exception("Encrypted Data are too long for this PlugIn. The maximum size of Data is " + Int32.MaxValue + "!"));
442                    byteEncryptedData = new byte[newEncryptedData.Length];
443                    int k = newEncryptedData.Read(byteEncryptedData, 0, byteEncryptedData.Length);
444                    if (k < byteEncryptedData.Length)
445                        throw (new Exception("Read Data are shorter than byteArrayLen"));
446                }
447                catch (Exception ex)
448                {
449                    throw (new Exception("Fatal error while reading the CryptoolStream. Exception: " + ex.ToString()));
450                }
451                finally
452                {
453                    newEncryptedData.Close();
454                    newEncryptedData.Dispose();
455                }
456                             
457                string pattern = this.encryptionControl.getKeyPattern();
458                KeyPattern kp = new KeyPattern(pattern);
459                if (kp.testWildcardKey(this.settings.Key))
460                {
461                    kp.WildcardKey = this.settings.Key;
462                }
463                else
464                {
465                    GuiLogMessage("The Key Pattern in the settings isn't valid for the given Encryption!", NotificationLevel.Error);
466                    return;
467                }
468
469                // create a new DistributableJob instance
470                distributableKeyPatternJob = new DistributableKeyPatternJob
471                    (kp, this.settings.KeyPatternSize * 10000, byteEncryptedData, this.InitVector);
472
473                this.p2pManager = new P2PManagerBase_NEW(this.P2PControl, distributableKeyPatternJob);
474                this.p2pManager.OnGuiMessage += new P2PPublisherBase.GuiMessage(p2pManager_OnGuiMessage);
475                this.p2pManager.OnProcessProgress += new P2PManagerBase_NEW.ProcessProgress(p2pManager_OnProcessProgress);
476                this.p2pManager.OnNewJobAllocated += new P2PManagerBase_NEW.NewJobAllocated(p2pManager_OnNewJobAllocated);
477                this.p2pManager.OnNoMoreJobsLeft += new P2PManagerBase_NEW.NoMoreJobsLeft(p2pManager_OnNoMoreJobsLeft);
478                this.p2pManager.OnResultReceived += new P2PManagerBase_NEW.ResultReceived(p2pManager_OnResultReceived);
479            }
480
481            this.bytesToUseForDecryption = this.settings.BytesToUse;
482
483            this.p2pManager.StartManager(this.settings.TopicName, this.settings.SendAliveMessageInterval * 1000);
484
485            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Working);
486        }
487
488        void p2pManager_OnResultReceived(BigInteger jobId)
489        {
490            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Finished);
491        }
492
493        void p2pManager_OnNoMoreJobsLeft()
494        {
495            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Finished);
496        }
497
498        void p2pManager_OnNewJobAllocated(BigInteger jobId)
499        {
500            this.settings.MngStatusChanged(P2PManager_KeyPatternSettings.MngStatus.Working);
501        }
502
503
504        #region INotifyPropertyChanged Members
505
506        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
507
508        public void OnPropertyChanged(string name)
509        {
510            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
511        }
512
513        public event PluginProgressChangedEventHandler OnPluginProcessChanged;
514
515        private void ProgressChanged(double value, double max)
516        {
517            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
518        }
519
520        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
521        {
522            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
523        }
524
525        #endregion
526    }
527
528}
Note: See TracBrowser for help on using the repository browser.