Ad-hoc Chatsystem für Mobile Netze Gruppe 4
Transcription
Ad-hoc Chatsystem für Mobile Netze Gruppe 4
Ad-hoc Chatsystem für Mobile Netze Gruppe 4 Softwareentwicklungspraktikum Sommersemester 2007 Entwicklerdokumentation Auftraggeber Technische Universität Braunschweig Institut für Betriebssysteme und Rechnerverbund Prof. Dr.-Ing. Lars Wolf Mühlenpfordtstraße 23, 1. OG 38106 Braunschweig Betreuer: Sven Lahde, Oliver Wellnitz, Wolf-Bastian Pöttner Phasenverantwortlicher: Norman Dankert Auftragnehmer Name Alexander Hoffmann Christoph Peltz Norman Dankert Sven Hesse E-Mail alexhoffmann84@web.de kris@keeg.de n.dankert@tu-bs.de drmccoy@users.sourceforge.net Braunschweig, 07.05.2007 INHALTSVERZEICHNIS Entwicklerdokumentation Inhaltsverzeichnis 1 Projektdetails 1.1 Allgemeine Funktionsweise . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Weiterleitung von Nachrichten . . . . . . . . . . . . . . . . . . . . . . . . 2 Analyse der Produktfunktionen 2.1 Analyse von Funktionalität F10: öffentlichen Kanal erstellen . . . . . 2.1.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Analyse von Funktionalität F11: öffentlichem Kanal beitreten . . . . . 2.2.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Analyse von Funktionalität F12: öffentlichen Kanal verlassen . . . . . 2.3.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 Analyse von Funktionalität F20: geschlossenen Kanal erstellen . . . . 2.4.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 Analyse von Funktionalität F21: geschlossenem Kanal beitreten . . . . 2.5.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6 Analyse von Funktionalität F30: Kanäle auflisten . . . . . . . . . . . 2.6.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.6.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7 Analyse von Funktionalität F40: Nachrichten schreiben . . . . . . . . 2.7.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.7.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8 Analyse von Funktionalität F50: Peerliste aktivieren . . . . . . . . . . 2.8.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.8.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.9 Analyse von Funktionalität F51: Peerliste deaktivieren . . . . . . . . . 2.9.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.9.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.10 Analyse von Funktionalität F52: Peer hinzufügen . . . . . . . . . . . 2.10.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.10.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.11 Analyse von Funktionalität F53: Peer entfernen . . . . . . . . . . . . 2.11.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.11.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.12 Analyse von Funktionalität F60: Alle erreichbaren Teilnehmer auflisten 2.12.1 Grobanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.12.2 Feinanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 4 4 6 6 6 7 7 7 7 8 8 8 9 9 10 10 10 10 11 11 12 12 12 13 13 13 13 14 14 14 14 14 15 15 15 16 16 16 16 INHALTSVERZEICHNIS Entwicklerdokumentation 3 Resultierende Softwarearchitektur 3.1 Komponentenspezifikation . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2 Schnittstellenspezifikation . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3 Protokolle für die Benutzung der Komponenten . . . . . . . . . . . . . . . 17 17 18 25 4 Verteilungsentwurf 26 5 Erfüllung der Kriterien 5.1 Musskriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2 Wunschkriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3 Abgrenzungskriterien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 27 29 30 6 Implementierungsentwurf 6.1 Gesamtsystem . . . . . . . . . . . . . . . . . . . . . . 6.2 Implementierung der Komponente S10: UDP . . . . . 6.2.1 Klassendiagramm . . . . . . . . . . . . . . . . 6.2.2 Klasse UDP . . . . . . . . . . . . . . . . . . . 6.2.3 Klasse Listener . . . . . . . . . . . . . . . . . 6.2.4 Klasse Sender . . . . . . . . . . . . . . . . . . 6.2.5 Klasse SendHellos . . . . . . . . . . . . . . . . 6.3 Implementierung der Komponente S20: Channel . . . . 6.3.1 Klassendiagramm . . . . . . . . . . . . . . . . 6.3.2 Klasse Channel . . . . . . . . . . . . . . . . . 6.3.3 Klasse ClosedChannel . . . . . . . . . . . . . . 6.3.4 Klasse PublicChannel . . . . . . . . . . . . . . 6.3.5 Klasse AnonymousChannel . . . . . . . . . . . 6.3.6 Klasse ChannelManager . . . . . . . . . . . . . 6.4 Implementierung der Komponente S30: Message . . . . 6.4.1 Klassendiagramm . . . . . . . . . . . . . . . . 6.4.2 Klasse Message . . . . . . . . . . . . . . . . . 6.4.3 Klasse ChanneledMessage . . . . . . . . . . . . 6.5 Implementierung der Komponente S40: User . . . . . . 6.5.1 Klassendiagramm . . . . . . . . . . . . . . . . 6.5.2 Klasse User . . . . . . . . . . . . . . . . . . . 6.5.3 Klasse UserList . . . . . . . . . . . . . . . . . 6.5.4 Klasse UserManager . . . . . . . . . . . . . . . 6.5.5 Klasse Purger . . . . . . . . . . . . . . . . . . 6.6 Implementierung der Komponente S50: EventManager 6.6.1 Klassendiagramm . . . . . . . . . . . . . . . . 6.6.2 Klasse EventManager . . . . . . . . . . . . . . 6.7 Implementierung der Komponente S60: Crypt . . . . . 6.7.1 Klassendiagramm . . . . . . . . . . . . . . . . 6.7.2 Klasse CertificateManager . . . . . . . . . . . 6.8 Implementierung der Komponente S70: RoutingTable . 31 31 32 32 33 34 35 35 37 37 38 40 41 41 42 44 44 45 48 49 49 50 52 52 54 55 55 55 57 57 57 59 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . INHALTSVERZEICHNIS Entwicklerdokumentation . . . . . . . . 59 59 60 61 62 63 63 63 7 Datenmodell 7.1 Diagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7.2 Erläuterung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 65 65 6.9 6.8.1 Klassendiagramm . . . . . . . . . . . . 6.8.2 Klasse RoutingTable . . . . . . . . . . . 6.8.3 Klass PeerAddr . . . . . . . . . . . . . 6.8.4 Klasse RoutingData . . . . . . . . . . . 6.8.5 Klasse Peer . . . . . . . . . . . . . . . Implementierung der Komponente S80: Network 6.9.1 Klassendiagramm . . . . . . . . . . . . 6.9.2 Klasse Network . . . . . . . . . . . . . 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ABBILDUNGSVERZEICHNIS Entwicklerdokumentation Abbildungsverzeichnis 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 Allgemeine Funktionsweise . . . . . . Weiterleitung von Nachrichten . . . . Aktivitätsdiagramm für Funktion F10 . Sequenzdiagramm für Funktion F10 . Aktivitätsdiagramm für Funktion F11 . Sequenzdiagramm für Funktion F11 . Aktivitätsdiagramm für Funktion F12 . Sequenzdiagramm für Funktion F12 . Aktivitätsdiagramm für Funktion F20 . Sequenzdiagramm für Funktion F20 . Aktivitätsdiagramm für Funktion F21 . Sequenzdiagramm für Funktion F21 . Aktivitätsdiagramm für Funktion F30 . Sequenzdiagramm für Funktion F30 . Aktivitätsdiagramm für Funktion F40 . Sequenzdiagramm für Funktion F40 . Aktivitätsdiagramm für Funktion F50 . Sequenzdiagramm für Funktion F51 . Aktivitätsdiagramm für Funktion F51 . Sequenzdiagramm für Funktion F51 . Aktivitätsdiagramm für Funktion F52 . Sequenzdiagramm für Funktion F52 . Aktivitätsdiagramm für Funktion F53 . Sequenzdiagramm für Funktion F53 . Aktivitätsdiagramm für Funktion F60 . Sequenzdiagramm für Funktion F60 . Komponenten von MAdChat . . . . . Verteilungsentwurf . . . . . . . . . . . Komponenten von MAdChat . . . . . Klassendiagramm - UDP . . . . . . . Klassendiagramm - Channel . . . . . . Klassendiagramm - Message . . . . . Klassendiagramm - User . . . . . . . . Klassendiagramm - Event . . . . . . . Klassendiagramm - Crypt . . . . . . . Klassendiagramm - RoutingTable . . . Klassendiagramm - Network . . . . . . Datenmodell . . . . . . . . . . . . . . 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 5 6 7 8 8 9 9 9 10 11 11 11 12 12 13 13 14 14 14 15 15 15 16 16 17 17 26 31 32 37 44 49 55 57 59 63 65 1 PROJEKTDETAILS Entwicklerdokumentation 1 1.1 Projektdetails Allgemeine Funktionsweise Abbildung 1: Allgemeine Funktionsweise Nachdem MAdChat gestartet wurde, ist es Betriebsbereit und versucht ein Netz zu finden bzw. ein eigenes aufzubauen. Ist dies gelungen, kann der Nutzer chatten oder andere Nutzer Nachrichten über den neuen Knoten weiterleiten. Das Programm kann durch den Befehl des Benutzers beendet werden, speichert jedoch vorher noch diverse Einstellungen und sendet NACKs für nicht zugestellte Nachrichten zurück und verwirft diese. Erhält der Client eine Nachricht, analysiert er diese und verifiziert sowohl Struktur als auch Inhalt. Sollte es Unstimmigkeiten geben, ist diese Nachricht ungültig und wird nicht weiter bearbeitet. Ist die Nachricht jedoch gültig, wird überprüft, ob sie nur weitergeleitet werden soll, oder der Nutzer des Clients ebenfalls ein Empfänger ist - in diesem Fall wird sie dem Nutzer angezeigt und gegebenenfalls vorher entschlüsselt und anschließend ebenfalls weitergeleitet, falls der Nutzer nicht der einzige Empfänger gewesen ist. Will der Nutzer eine Nachricht versenden, so prüft der Client ob diese verschlüsselt werden muss und tut dies gegebenenfalls. Anschließend wird die Nachricht an ihre Empfänger, also die Nutzer, mit denen der Nutzer im selben Kanal ist, weitergeleitet. Wurde die Nachricht weitergeleitet oder zwischengespeichert, wartet MAdChat auf neue Nachrichten. 1.2 Weiterleitung von Nachrichten Für jeden Empfänger einer Nachricht, also alle Chatteilnehmer eines Kanals bzw. alle in der Nachricht aufgelisteten Chatteilenhmer, wird dieser Statechart abgearbeitet. Sollte die Liste der Empfänger leer sein (der Benutzer war also der letzte Empfänger), wird nichts weitergeleitet. Ist ein Chatteilnehmer aufgrund einer Netztrennung nicht mehr erreichbar, wird der Inhalt der Nachricht solange zwischengespeichert, bis dieser Chatteilnehmer wieder erreichbar ist. 6 1 PROJEKTDETAILS Entwicklerdokumentation Abbildung 2: Weiterleitung von Nachrichten Falls dem nicht so ist, wird der Peer aus der Routingtabelle ausgewählt, über den der Chatteilnehmer erreichbar ist. Existiert bereits eine Nachricht mit dem gleichen Inhalt an diesen Peer, so wird der Chatteilnehmer der Empfängerliste der Nachricht hinzugefügt. Sollte dies nicht der Fall sein, so wird eine neue Nachricht an den Peer erstellt, über den der Chatteilnehmer erreichbar ist und danach die Empfängerliste um den Chatteilnehmer erweitert. Wurden alle Chatteilnehmer abgearbeitet, werden die Nachrichten an die Peers versendet. 7 Entwicklerdokumentation 2 2 ANALYSE DER PRODUKTFUNKTIONEN Analyse der Produktfunktionen Im folgenden Kapitel werden die Funktionen aus dem Pflichtenheft jeweils in einem Aktivitätsdiagramm (Grobanalyse) und in einem Sequenzdiagramm (Feinanalyse) näher erläutert und beschrieben. In den Diagrammen sind die einzelnen Komponenten und deren Methoden enthalten wie sie im Feinentwurf dargestellt sind. Bei Benutzer handelt es sich dabei um den Nutzer, der über die GUI das Programm MAdChat benutzt. Das Objekt Benutzer entspricht also gleichzeitig auch die Eingabe und Ausgabe von MAdChat. 2.1 2.1.1 Analyse von Funktionalität F10: öffentlichen Kanal erstellen Grobanalyse Abbildung 3: Aktivitätsdiagramm für Funktion F10 Diese Funktion dient dazu einen öffentlichen Kanal im Netz zu erstellen. Der Benutzer gibt dabei über ein Eingabefeld den gewünschten Namen ein und bestätigt die Eingabe. Die Komponente Channel, die alle vorhandenen und zu erzeugenden Kanäle durch den ChannelManager verwaltet, überprüft, ob ein Kanal mit gleichem Namen schon vorhanden ist. Wenn ja, wird der Nutzer durch versenden einer JOIN-message (Aufgabe von UDP) dem Kanal hinzugefügt. Wenn ein solcher Kanal noch nicht existiert, wird dieser erstellt, der Nutzer hinzugefügt und dem Netz durch eine CHANNEL-message der neue Kanal mitgeteilt. 8 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Abbildung 4: Sequenzdiagramm für Funktion F10 2.1.2 Feinanalyse Im oberen Teil des Diagramms dargestellt, ist der gewünschte Kanal noch nicht vorhanden. Es wird createChannel() aufgerufen, wodurch ein neuer Kanal erzeugt wird. Channel fügt den neuen Kanal hinzu und durch UDP wird mit einer CHANNEL-message der neue Kanal dem Netz mitgeteilt. Im unteren Teil ist der gewünschte Kanal bereits im Netz vorhanden, wodurch Channel veranlasst wird, den Nutzer dem Kanal hinzuzufügen. Dies geschieht durch verschicken einer JOIN-message durch UDP. Wird das Beitrittwunsch bestätigt setzt Channel den Nutzer auf die Mitgliederliste. Die Änderung wird mit broadcast() im Netz verteilt. 2.2 2.2.1 Analyse von Funktionalität F11: öffentlichem Kanal beitreten Grobanalyse Möchte der Benutzer einem bereits vorhandenen öffentlichen Kanal beitreten, wählt er diesen aus der Kanalliste aus. Ist der Kanal in diesem Moment nicht erreichbar, wird eine Fehlermeldung angezeigt. Ist der Kanal noch vorhanden, wird durch UDP eine JOIN-message verschickt und der Nutzer wird durch User (verwaltet alle Nutzer im Netz) der Mitgliederliste hinzugefügt. Der Kanal mit seinen Mitgliedern wird dem Benutzer dann durch Channel in einem neuen Tab dargestellt. 2.2.2 Feinanalyse Der Benutzer teilt Channel mit, dass er einem Kanal vom Typ PublicChannel beitreten möchte. Channel erzeugt eine JOIN-message die durch UDP dem Netz mitgeteilt wird und die Komponente User setzt den Benutzer auf die Liste. 9 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Abbildung 5: Aktivitätsdiagramm für Funktion F11 Abbildung 6: Sequenzdiagramm für Funktion F11 2.3 2.3.1 Analyse von Funktionalität F12: öffentlichen Kanal verlassen Grobanalyse Der Benutzer verlässt einen öffentlichen Kanal, indem er den zugehörigen Tab schließt. Der Nutzer wird aus der Nutzerliste durch User entfernt und der Kanal wird in Channel entfernt, nachdem eine LEAVE-message durch UDP versendet wurde. 2.3.2 Feinanalyse Durch leave() wird Channel mitgeteilt, dass der Kanal verlassen wird. Channel erzeugt eine Nachricht vom Typ LeaveMessage, während User mit erase() den Benutzer aus der Liste entfernt. Die Nachricht zum Verlassen wird schließlich durch UDP gesendet. 10 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Abbildung 7: Aktivitätsdiagramm für Funktion F12 Abbildung 8: Sequenzdiagramm für Funktion F12 2.4 2.4.1 Analyse von Funktionalität F20: geschlossenen Kanal erstellen Grobanalyse Abbildung 9: Aktivitätsdiagramm für Funktion F20 11 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Der Benutzer gibt beim Erstellen des Kanals zusätzlich an, dass dieser geschlossen sein soll. Für die eindeutige ChannelID wird der lokale Hostname verwendet. Die Komponente Crypt verschlüsselt dann den Kanal und Channel erstellt diesen. UDP teilt dem Netz den neuen Kanal mit. Beim Benutzer öffnet sich ein neuer Kanaltab. 2.4.2 Feinanalyse Abbildung 10: Sequenzdiagramm für Funktion F20 Nachdem der Benutzer den Kanalnamen für den zu erstellenden Kanal eingegeben hat, wird mit getlocalHostname() der lokale Hostname wiedergegeben. Damit wird dann der Kanal durch Crypt verschlüsselt und wiedergegeben. Channel erstellt den neuen Kanal und veranlasst UDP eine CHANNEL-message zu verschicken, um dem Netz den neuen Kanal mitzuteilen. 2.5 2.5.1 Analyse von Funktionalität F21: geschlossenem Kanal beitreten Grobanalyse Der Beuntzer wählt aus einer Liste einen geschlossenen Kanal aus dem er beitreten möchte. Ist der Kanal immer noch im Netz zu erreichen, wird eine JOIN-message verschickt. Hat ein anderer Benutzer, der bereits Mitglied des Kanals ist, den Beitrittwunsch bestätigt, wird die entsprechende KEY-message empfangen und durch Crypt entschlüsselt. Channel fügt den Benutzer dann dem Kanal hinzu. 2.5.2 Feinanalyse Durch die Methode join() wird Channel der Beitrittwunsch des Benutzers mitgeteilt. UDP verschickt daraufhin mit broadcast() die JOIN-message. Ist der Beitrittwunsch bestätigt, wird mit getPrivateKey() der Crypt Komponente der angeforderte Schlüssel des Kanals entschlüsselt und an Channel wiedergegeben. 12 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Abbildung 11: Aktivitätsdiagramm für Funktion F21 Abbildung 12: Sequenzdiagramm für Funktion F21 2.6 2.6.1 Analyse von Funktionalität F30: Kanäle auflisten Grobanalyse Abbildung 13: Aktivitätsdiagramm für Funktion F30 13 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Der Benutzer hat die Möglichkeit alle vorhandenen Kanäle im Netz anzeigen zu lassen. Dafür werden die Kanäle, die Channel bekannt sind, in einer Liste dem Benutzer wiedergegeben. 2.6.2 Feinanalyse Abbildung 14: Sequenzdiagramm für Funktion F30 Das Anzeigen der Kanäle wird in der Komponente Channel durch die Methode getChannels() realisiert. 2.7 2.7.1 Analyse von Funktionalität F40: Nachrichten schreiben Grobanalyse Abbildung 15: Aktivitätsdiagramm für Funktion F40 Innerhalb eines Kanals kann der Benutzer Textnachrichten verschicken, die allen anderen Nutzern im Kanal angezeigt werden. Diese Nachrichten werden in einem Texteingabefeld vom Benutzer eingetippt und per Eingabetaste verschickt. Die Komponente Message erzeugt dann eine ChatMessage mit der Signatur des Benutzers. Wird die Nachricht innerhalb eines geschlossenen Kanals verschickt, wird sie zusätzlich durch Crypt verschlüsselt. UDP sendet die Nachricht schließlich an alle Nutzer des Kanals. 14 Entwicklerdokumentation 2.7.2 2 ANALYSE DER PRODUKTFUNKTIONEN Feinanalyse Abbildung 16: Sequenzdiagramm für Funktion F40 Im oberen Teil ist das Versenden einer Nachricht in einem offenen Kanal dargestellt. Im unteren Teil wird eine Nachricht im geschlossenen Kanal versendet, die durch encryptDES() vor dem Einreihen zum Senden in UDP noch durch Crypt verschlüsselt wird. 2.8 2.8.1 Analyse von Funktionalität F50: Peerliste aktivieren Grobanalyse Abbildung 17: Aktivitätsdiagramm für Funktion F50 Das aktivieren der Peerliste entspricht einem Infrastrukturmodus, in dem man feste IPAdressen eingeben kann um ein geschlossenes Netz zu simulieren (vor allem für Testzwecke). Der Infrastrukturmodus wird durch die Komponente UDP verwaltet. 2.8.2 Feinanalyse Die Peerliste wird durch die Methode enable() aktiviert. Mit der Methode getPeerList() werden die Peers abgerufen. 15 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Abbildung 18: Sequenzdiagramm für Funktion F51 2.9 Analyse von Funktionalität F51: Peerliste deaktivieren 2.9.1 Grobanalyse Abbildung 19: Aktivitätsdiagramm für Funktion F51 Die Peerliste wird durch einen Klick des Benutzers deaktiviert. 2.9.2 Feinanalyse Abbildung 20: Sequenzdiagramm für Funktion F51 Die Methode zum Deaktivieren ist disable() in UDP. 2.10 2.10.1 Analyse von Funktionalität F52: Peer hinzufügen Grobanalyse Der Benutzer kann einen neuen Peer in die Liste eintragen. UDP fügt den gewünschten Peer dann hinzu. 16 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Abbildung 21: Aktivitätsdiagramm für Funktion F52 2.10.2 Feinanalyse Abbildung 22: Sequenzdiagramm für Funktion F52 Das Eintragen eines Peers wird durch die Methode addPeer() innerhalb UDP erledigt. 2.11 2.11.1 Analyse von Funktionalität F53: Peer entfernen Grobanalyse Abbildung 23: Aktivitätsdiagramm für Funktion F53 Der Peer, der entfernt werden soll wird vom Benutzer ausgewähl. UDP entfernt denn Peer dann. 17 Entwicklerdokumentation 2 ANALYSE DER PRODUKTFUNKTIONEN Abbildung 24: Sequenzdiagramm für Funktion F53 2.11.2 Feinanalyse Der Benutzer wählt den zu entfernenden Peer aus. Die Methode delPeer() entfernt dann den Peer. 2.12 2.12.1 Analyse von Funktionalität F60: Alle erreichbaren Teilnehmer auflisten Grobanalyse Abbildung 25: Aktivitätsdiagramm für Funktion F60 Wenn der Benutzer sich mit dem Netz verbindet, wird automatisch ein anonymer Kanal erstellt. Da alle erreichbaren Nutzer immer Mitglied dieses Kanals sind, werden sie in diesem Kanal aufgelistet. 2.12.2 Feinanalyse Beim Verbinden wird der Channelmanager aufgerufen, der den anonymen Kanal erstellt und von User alle erreichbaren Nutzer holt und in den Kanal einträgt. 18 Entwicklerdokumentation 3 RESULTIERENDE SOFTWAREARCHITEKTUR Abbildung 26: Sequenzdiagramm für Funktion F60 3 3.1 Resultierende Softwarearchitektur Komponentenspezifikation Abbildung 27: Komponenten von MAdChat MAdChat besteht aus madchat (dem Front-End mit GUI) und libmadchat. Das Front-End ist nur dafür verantwortlich, mit dem Nutzer zu interagieren, während alles, was das Chatprotokoll betrifft, Aufgabe der Library ist. 19 Entwicklerdokumentation 3 RESULTIERENDE SOFTWAREARCHITEKTUR Die einzelnen Komponenten von libmadchat sind UDP, Channel, Message, User, Event, Crypt, RoutingTable und Network. In der folgenden Schnittstellenspezifikation werden alle öffentlichen Methoden der einzelnen Komponenten erläutert, die dann insgesamt die einzelnen Schnittstellen, wie im Diagramm zu sehen, darstellen. 3.2 Schnittstellenspezifikation Schnittstelle /S10/: UDP Aufgabenbeschreibung Operation Beschreibung Udp (Network network, ost::tpport Konstruktor. port=8888) void send (Message msg, Sende eine Nachricht. ost::IPV4Address ip, ost::tpport port=8888) void broadcast (Message msg) Broadcaste eine Nachricht. Message* receive() Empfange eine gegebenenfalls vorliegende Nachricht. Infrastructure* getInfrastructure() Gibt ein Infrastruktur-Objekt zurück. std::string getLocalHostname() const Gibt den local hostname zurück. void setLocalPeer (const PeerAddr Setzt lokale Adresse. peer) void queueForSending (Message Reiht Nachricht fürs Senden *msg) ein. 20 Entwicklerdokumentation Schnittstelle /S20/: Channel 3 RESULTIERENDE SOFTWAREARCHITEKTUR Aufgabenbeschreibung Operation Beschreibung Channel (ChannelManager manager, Konstruktor. const std::string name, const std::string id, const std::string key=, KeyType keyType=KEYNOKEY) bool isExistent () const Gibt Kanel zurück falls dieser noch im Netz ist. std::string getName () const Gibt den Kanalnamen zurück. std::string getId () const Gibt die KanalID zurück. KeyType getKeyType () const Gibt den Schlüsseltyp zurück. std::string getKey () const Gibt den Schlüssel zurück. UserList* getMembers () const Gibt die Benutzer eines Kanals zurück. timet getLastChannel () const Gibt Wert zurück wenn die letzte CHANNEL-message erhalten wurde. bool getNoChannel () const Gibt an ob eine CHANNELmessage gesendet werden konnte oder nicht. void setKey (const std::string key, Setzt Schlüssel. KeyType type) void setKey (const std::string key, Setzt Schlüssel. const std::string type) bool empty () Gibt zurück ob im Kanal Nutzer sind. bool hasMember (const std::string Gibt an ob der Nutzer im Kanal id) ist. void receivedChannel () CHANNEL-message wurde empfangen. virtual void join () Betrete den Kanal. virtual void leave () Verlasse den Kanal. virtual void confirmJoin (const Bestätigt den Beitritt eines anUserPtr user) deren Nutzers. virtual void send (ChatMessage msg) Sendet eine Nachricht im aktuellen Kanal. virtual ChannelMessage* Erzeugt eine CHANNELcreateChannelMessage () message. static KeyType getKeyType (const Gibt den Schlüsseltyp im String std::string type) zurück. static std::string getKeyType Gibt den Schlüssel als String (KeyType type) zurück. 21 Entwicklerdokumentation Schnittstelle /S30/: Message 3 RESULTIERENDE SOFTWAREARCHITEKTUR Aufgabenbeschreibung Operation Beschreibung virtual Message* clone () const=0 Verfielfätigt die Nachricht. Type getType () Gibt den Typ der Nachricht zurück. std::string getId () Gibt die ID der Nachricht zurück. unsigned int getTtl () Gibt die TTL (Time-to-live) zurück. unsigned int getDelay () Gibt die Laufzeit der Nachricht zurück. SignType getSignType () Gibt den Typ der Signatur zurück. std::string getSignature () Gibt die Signatur zurück. bool getOwnSignature () Gibt an ob eigene Signatur berechnet wurde. std::string getSender () Gibt den Sender der Nachricht zurück. std::list< std::string > getReceivers Gibt die Empfänger zurück. () PeerAddr getPeer () Gibt den Peer zurück von wo aus die Nachricht gesendet wurde oder wohin sie gesendet werden soll. timet getReceivedTime () Gibt zurück wann die Nachricht gesendet wurde. virtual bool getFlood () Gibt an ob die Nachricht im ganzen Netz geflutet werden soll. virtual bool isNackable () Gibt an ob ein NAck gesendet wird, wenn die Nachricht nicht ankommt. virtual bool needsAck () Gibt an ob die Nachricht ein Ack braucht. void createNewId () Erzeugt eine neue NachrichtenID. void setId (const std::string id) Setzt die NachrichtenID. void setTtl (unsigned int ttl) Setzt die TTL der Nachricht. void setDelay (unsigned int delay) Setzt die Laufzeit der Nachricht. void setSignature (const std::string Setzt die Signatur. signature, SignType type) virtual void setSender (const Setzt den Sender der Nachricht. std::string sender) void setReceiver (const std::string Setzt den Empfänger der Nachreceiver) richt. 22 void setReceivers (UserList receivers) Setzt die Empfänger anhand der Nutzerliste. void setPeer (const ost::IPV4Address Setzt die IP und den Port aus ip=0.0.0.0, ost::tpport port=0) einer empfangenen Nachricht. void setReceivedTime (timet time) Gibt die Zeit wenn die Nachricht angekommen ist. Entwicklerdokumentation Schnittstelle /S30/: Message 3 RESULTIERENDE SOFTWAREARCHITEKTUR Aufgabenbeschreibung Operation Beschreibung bool isSignatureValid (RSA Gibt an ob die Signatur korrekt *pubKey) ist. std::string toXml() Konvertiert die Nachricht nach einen XML-String. virtual void fillFromXml (xmlDocPtr Generiert eine Nachricht aus eidoc, xmlNodePtr node)=0 nem XML-Dokument. virtual void evaluate (Network Evaluiert die Nachricht über network)=0 das Netz. static Message* fromXml (std::string Kovertiert aus dem XML-String xml) eine Nachricht. static Message* fromXml Konvertiert aus dem XML(xmlDocPtr doc, xmlNodePtr root) Dokument eine Nachricht. 23 Entwicklerdokumentation Schnittstelle /S40/: User 3 RESULTIERENDE SOFTWAREARCHITEKTUR Aufgabenbeschreibung Operation Beschreibung User (UserManager manager, Konstruktor. std::string id) bool isExistent () Gibt an ob der Nutzer noch im Netz exisitiert. bool isPeer () Gibt an ob der Nutzer direkt erreichbar ist. std::string getId () Gibt die ID des Nutzers zurück. std::string getGreeting () Gibt das Greeting zurück. int getVersion () Gibt die Version zurück. void setGreeting (const std::string Setzt das Greeting. greeting) void setVersion (int version) Setzt die Version. timet lastSeen () Gibt den letzten Zeitpunkt zurück, an dem eine HELLOmessage empfangen wurde. void seenDirect () Zeigt an, dass eine HELLOmessage empfangen wurde. void seenIndirect () Zeigt an, dass eine ROUTINGmessage empfangen wurde. timet lastAskedForCert () Zeigt an, wann das letzte mal nach dem Zertifikat gefragt wurde. void askedForCert () Zeigt an, dass gerade nach dem Zertifikat gefragt wurde. bool hasPublicKey () Zeigt an, ob der Schlüssel eines anderen Nutzers bekannt ist. RSA* getPublicKey () Gibt den Schlüssel eines anderen Nutzers zurück. 24 Entwicklerdokumentation Schnittstelle /S50/: Event 3 RESULTIERENDE SOFTWAREARCHITEKTUR Aufgabenbeschreibung Operation Beschreibung Event (Type type, const Konstruktor für eine ChatChatMessage msg) message. Event (Type type, const Konstruktor für eine NAckNAckMessage msg) messageEvent (Type type, const ChannelPtr Konstruktor für einen Kanal chn, const UserPtr user) und einen Nutzer. Event (Type type, const ChannelPtr Konstruktor nur für einen Kachn) nal. Event (Type type, const UserPtr Konstruktor nur für einen Nutuser) zer. Event (const Event right) Konstruktor. Event operator=(const Event right) Type getType() Gibt den Typ zurück. ChatMessage* getMessage() Gibt eine Nachricht vom Typ ChatMessage zurück. NAckMessage* getNack() Gibt eine NAck-message zurück. ChannelPtr getChannel() Gibt den Kanal zurück. UserPtr getUser() Gibt den Nutzer zurück. 25 Entwicklerdokumentation Schnittstelle /S60/: Crypt 3 RESULTIERENDE SOFTWAREARCHITEKTUR Aufgabenbeschreibung Operation Beschreibung CertificateManager (const std::string Konstruktor basePath, std::string rootCert) std::string add (X509 *cert) Fügt ein neues X509-Zertifikat hinzu und gibt die ID zurück. std::string addFile (std::string Fügt ein X509-Zertifikat aus certFile) der Datei hinzu. std::string addMem (std::string Fügt ein X509-Zertifikat hinzu certString) mit Base64 DER String. bool setPrivateKey (std::string Verifiziert die Signatur von keykeyFile) File mit RSA key. bool save() Speichert alle Zertifikate im angegebenen Ordner. bool load() Lädt abgespeicherte Zertifikate. bool hasPublicKey (const std::string Überprüft ob der Schlüssel des id) Nutzers bereits vorhanden ist. RSA* getPublicKey (const std::string Gibt den öffentlichen Schlüssel id) des Nutzers im RSA-Format wieder. RSA* getPrivateKey() Gibt den privaten Schlüssel zurück. std::string getCertificate (const Gibt das Zerifikat des Nutzers std::string id) im PEM-Format zurück. Schnittstelle /S70/: RoutingTable Aufgabenbeschreibung Operation Beschreibung RoutingTable (Network network) void update (const Message *msg) PeerAddr findRoute (const std::string destination, unsigned int offset) void purge() 26 Konstruktor Aktualisiert die Routing Informationen entsprechend des Nachrichtentyps. Findet den Peer an den die Nachricht geschickt werden soll. Purger. Entwicklerdokumentation Schnittstelle /S80/: Network 3.3 3 RESULTIERENDE SOFTWAREARCHITEKTUR Aufgabenbeschreibung Operation Beschreibung Network (const std::string certBase, Konstruktor const std::string rootCert, const std::string userCert, const std::string privKey, ost::tpportt port=8888) UserPtr getLocalUser() Gibt den lokalen Benutzer zurück. Udp* getUdp () Gibt Udp zurück. ChannelManager* Gibt den ChannelManager getChannelManager() zurück. RoutingTable* getRoutingTable() Gibt die RoutingTable zurück. UserManager* getUserManager() Gibt den UserManager zurück. EventManager* getEventManager() Gibt den EventManager zurück. CertificateManager* Gibt den CertificateManager getCertificateManager() zurück. void getInfrastructure(bool on) Schaltet den Infrastrukturmodus an und aus. Protokolle für die Benutzung der Komponenten Es ist nicht sinnvoll, die Komponenten wiederzuverwenden, da sie zu sehr an das Protokoll und MAdChat angepasst sind. 27 4 VERTEILUNGSENTWURF Entwicklerdokumentation 4 Verteilungsentwurf Auf jedem Knoten läuft im Ad-Hoc Betrieb jeweils eine Instanz von MAdChat, die sich wiederum der Bibliothek bedient um mit anderen Knoten zu kommunizieren. Die einzelnen Instanzen können jeweils andere Front-Ends nutzen, wie zum Beispiel ncmadchat, ein mögliches ncurses-Front-End. Abbildung 28: Verteilungsentwurf 28 5 ERFÜLLUNG DER KRITERIEN Entwicklerdokumentation 5 5.1 Erfüllung der Kriterien Musskriterien Die folgenden Kriterien sind unabdingbar und müssen durch das Produkt erfüllt werden: Das Netz /M30/ Ein Peer speichert die Nachrichten für einen Client, der momentan nicht erreichbar ist, zwischen Peer wiederholt senden, wenn Zielclient wieder in Routingtabelle oder sendet NACK zurück bei Ablauf der TTL /M40/ Das Netz besteht aus beliebig vielen Kanälen Erfüllung durch dynamische Datenstrukturen zur Speicherung der Kanaldaten /M50/ Zwei Netze, die durch mindestens einen Client verbunden sind, werden zusammengeführt Verbindungsclient übermittelt Routinginformationen des einen Netzes an das Andere und vice versa Kanäle /M100/ Es existiert ein permanenter Kanal zur anonymen Unterhaltung, in dem sich alle Clients des Netzes befinden Kanal ist Standardkanal bei Start des Programms und wird realisiert durch eine eigene Klasse /M110/ Es gibt zusätzlich zwei Arten von Kanälen: offene und geschlossene Realisierung durch zwei verschiedene Klassen, eine mit und die andere ohne Verschlüsselungsfunktionen /M120/ Die Gesamtzahl der Kanäle ist nicht begrenzt Erfüllung durch dynamische Datenstrukturen zur Verwaltung der Kanäle /M130/ Jeder Kanal hat einen Namen und eine eindeutige ID Name vom Ersteller gegeben und ID wird automatisch generiert. /M140/ Jeder Chatteilnehmer in einem Kanal erhält die Nachricht, die ein anderer Chatteilnehmer an diesen Kanal gesendet hat Empfängerliste der Nachricht ist gleich der Teilnehmerliste des Kanals. Aufteilung in Einzelnachrichten anhand der Routingtabelle (Wer ist über welchen Peer erreichbar). Es gibt allerdings eine Situation in der dies nicht gewährleistet werden kann. Wenn sich gerade zwei Teilnetze verbunden haben und es in beiden einen öffentlichen Kanal mit gleichem Namen gibt (die ja dann zusammengefügt werden), kann es in der Phase, in der noch nicht alle Teilnehmer des Kanals über die neuen Mitlgieder informiert sind dazu kommen, dass nicht alle wirklichen Mitglieder des Kanals eine Nachricht erhalten. Das Verhalten ist allerdings konsistent zu der GUI, alle Teilnehmer, die bei einem Client angezeigt werden, werden auch die Nachricht bekommen 29 5 ERFÜLLUNG DER KRITERIEN Entwicklerdokumentation /M150/ Werden Netze zusammengeführt und es existieren offene Kanäle mit dem selben Namen, so werden diese verschmolzen Die Teilnehmerlisten der beiden namensgleichen Kanäle werden vereint. Dies wird unter anderem über die CHANNEL Nachrichten erreicht, als auch über MESSAGE Nachrichten, die an diesen Kanal gehen und mehr/andere Empfänger haben als der Kanal (dies ist mit ein Zeichen, dass sich zwei identische Kanäle im Netz befinden) /M160/ Geschlossene Kanäle werden nicht verschmolzen Die Kanäle werden getrennt weiterverwaltet, da dies über die ID und nicht über den Namen geschieht. Nutzer des einen Netzes haben für gewöhnlich nicht die Absicht, Mitglied des geschlossenen Kanals des anderen Netzes zu sein. Für den Fall, dass ein Nutzer nach dem zusammenfügen der beiden Netze auch in beiden Kanälen ist (also wenn er auch in den anderen eingeladen wurde), so werden die Kanäle in der Benutzerschnittstelle durch ein künstliches Suffix auseinandergehalten. /M170/ Geschlossene Kanäle sind mit einem Schlüssel gesichert Die Nachrichten werden mit diesem Schlüssel verschlüsselt, so dass nur Mitglieder des Kanals mit diesem Schlüssel, diese entschlüsseln können. Diese Schlüssel werden beim erstellen eines geschlossenen Kanals erstellt und können danach nicht mehr verändert werden. Chatteilnehmer /M200/ Der Chatteilnehmer hat einen Namen und eine eindeutige ID Der Name kann von jedem Nutzer selbst gewählt werden. Die ID wird durch das vom IBR ausgestellte Zertifikat gegeben /M210/ Die Kommunikation der Chatteilnehmer untereinander erfolgt ausschließlich über Kanäle Ist der Chatteilnehmer Mitglied in einem Kanal, wird nach /M140/ fortgefahren. Ist er kein Mitglied, kann er keine Nachrichten senden /M220/ Der Chatteilnehmer kann einen neuen Kanal erstellen, einem vorhandenen beitreten oder ihn verlassen Wird ein neuer Kanal erstellt tritt der Teilnehmer automatisch ihm bei und es werden CHANNEL Nachrichten ins Netz gesendet um die Existenz eines neuen Kanals bekannt zu machen. Will er einen Vorhandenen erstellen, wird er automatisch diesem beitreten, es sei denn es ist ein geschlossener Kanal. Verlassen kann er nur einen offenen Kanal. Geschlossene bleiben solange bestehen, bis alle Mitglieder offline sind und damit der Schlüssel verschwindet. All dies wird durch die Modifizierung der CHANNEL Nachrichten erreicht /M240/ Der Chatteilnehmer kann in mehreren Kanälen gleichzeitig sein Der Client zeigt für jeden Kanal einen Tab an, zwischen denen der Nutzer wechseln kann, um im jeweils aktiven Kanal Nachrichten zu schreiben. Intern wird eine Datenstruktur über den User geführt, in der auch alle Kanäle vermerkt sind, in denen er Mitglied ist 30 5 ERFÜLLUNG DER KRITERIEN Entwicklerdokumentation /M250/ Ein beliebiger Chatteilnehmer eines geschlossenen Kanals verwaltet dessen Schlüssel Dieser Chatteilnehmer antwortet auf die Schlüsselanfragen von außenstehenden Nutzern, die beitreten wollen und sendet, falls genehmigt, den Schlüssel an den außenstehenden Nutzer Nachrichten /M300/ Nachrichten werden Hop-by-Hop im Netz weitergeleitet Mithilfe der Routingtabelle wird immer der möglichst beste Peer, über den eine Nachricht zum Endziel gelangt, ausgewählt. Zusätzlich wird überprüft ob man immer wieder die selbe Nachricht weiterleiten soll. Wenn dies nämlich der Fall ist muss eine andere Route gefunden werden (vgl. /M20/) /M310/ Nachrichten in geschlossenen Kanälen werden verschlüsselt übertragen Verschlüsselt erfolgt symmetrisch mit Hilfe des Kanalschlüssels, der beim Erstellen des Kanals ebenfalls erstellt wurde /M320/ Nachrichten die nicht zugestellt werden konnten, werden zwischengespeichert und später übertragen Regelmäßige Überprüfung der Routingtabelle, ob das Ziel erreichbar ist. Nach Ablauf der TTL wird ein NACK zurückgesendet und die Nachricht verworfen /M330/ Nachrichten an den anonymen Kanal werden nach dem Zwiebelprinzip anonymisiert Mehrfachverschlüsselung der Nachricht an eine Reihe von Empfängern, die diese nacheinander entschlüsseln, bevor sie beim Ziel ankommt, welches sie dann im Netz flutet (an alle erreichbaren Teilnehmer sendet). So ist eine Rückverfolgung sehr unwahrscheinlich /M340/ Nachrichten können sowohl Text als auch Binärdaten enthalten Falls ein Benutzer einen Anhang (Text- oder Binärdatei) auswählt, wird dieser im Base64 Format in die Nachricht eingebaut. Dabei ist die maximale Nachrichtengröße von 62000 Byte zu beachten /M350/ Verzögerte Nachrichten werden dem Chatteilnehmer besonders angezeigt und in den Kontext eingeordnet Hervorhebung der später eingehenden Nachricht, sowie einen Hinweis auf deren Eingang 5.2 Wunschkriterien Die Erfüllung folgender Kriterien für das abzugebende Produkt wird angestrebt: /W10/ Eine Liste von Chatteilnehmern, deren Nachrichten man nicht erhalten möchte (ignore list) Nachrichten von Nutzern auf der Liste werden verworfen und nicht angezeigt. Nicht möglich im anonymen Kanal 31 5 ERFÜLLUNG DER KRITERIEN Entwicklerdokumentation /W30/ Der Chatteilnehmer erhält Statusinformationen über das Netz in dem er sich befindet Daten, die der Client speichert und verwaltet, werden dem Nutzer auf geeignete Weise angezeigt 5.3 Abgrenzungskriterien Folgende Funktionalität wird nicht durch das Produkt, sondern wie folgt beschrieben anderweitig erfüllt: /A10/ Der Chatteilnehmer muss eigenständig die Konfiguration seiner Hardware übernehmen Einstellung der Funknetzwerkkarte auf Ad-Hoc Modus bzw. eintragen der Peers in die Liste für den Infrastrukturmodus 32 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6 6.1 Implementierungsentwurf Gesamtsystem Abbildung 29: Komponenten von MAdChat Erläuterung: MAdChat besteht aus madchat (dem Front-End mit GUI) und libmadchat. Das Front-End ist nur dafür verantwortlich, mit dem Nutzer zu interagieren, während alles, was das Chatprotokoll betrifft, Aufgabe der Library ist. Die einzelnen Komponenten von libmadchat sind UDP, Channel, Message, User, Event, Crypt, RoutingTable und Network. 33 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.2 Implementierung der Komponente S10: UDP Die Komponente UDP kümmert sich um die einzelnen UDP-Pakete. 6.2.1 Klassendiagramm Abbildung 30: Klassendiagramm - UDP 34 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.2.2 Klasse UDP Erläuterungen: Durch diese Klasse kann die Klasse Network UDP-Pakete empfangen und versenden. Da das direkt geschieht, ohne auf das Chatprotokoll zu beachten, haben andere Klassen – oder gar das Front-End – kein Zugriff darauf. Notwendige Attribute ◦ mutexIn : ost::Mutex ◦ mutexOut : ost::Mutex ◦ network : Network ◦ broadcast : ost::UDPBroadcast ◦ socketIn : ost::UDPSocket ◦ socketOut : ost::UDPSocket ◦ port : ost::tpport t ◦ localPeer : PeerAddr ◦ localHostname : std::string ◦ recBuf [63000] : char ◦ infraMode : Infrastructure ◦ receivedIds : SharedSearchRingBuffer< std::string, 1000 > ◦ receivedAnon : SharedSearchRingBuffer< std::string, 10 > ◦ awaitingKey : SharedList< Message * > ◦ listener : MAdChat::Udp::Listener * ◦ sendHellos : MAdChat::Udp::SendHellos * ◦ sender : MAdChat::Udp::Sender * 35 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - - Name der Aufgabe Udp(Network &network, ost::tpport t port=8888) send(Message&msg, ost::IPV4Address ip, ost::tpport t port=8888) broadcast(Message &msg) - receive() : Message getInfrastructure() : Infrastructure - getLocalHostname() : std::string F40 F40 - - setLocalPeer(const PeerAddr peer) queueForSending(Message *msg) start() send(ost::UDPSocket const std::string &str) nack(Message *msg) *udpSocket, Beschreibung Konstruktor der Klasse UDP. Sendet eine Nachricht vom Typ Message an die angegebene IP. Sendet eine Nachricht an alle Benutzer im Netz. Empfängt eine Nachricht. Gibt ein Objekt vom Typ Infrastructure zurück. Gibt den Namen des lokalen Host zurück. Setzt die Adresse des lokalen Peers. Reiht eine Nachricht zum Senden ein. Startet das Senden von HELLOmessages sowie den Listener und Sender. Interne Funktion zum Senden eines Strings über einen UDPSocket. Ablehnung einer Nachricht. Notwendige Kommunikationspartner Name der Klasse Network Message NAckMessage ObscureMessage 6.2.3 Dauerhaft? Ja Ja Ja Ja Klasse Listener Erläuterungen: Die Klasse Listener fragt ständig nach neuen Nachrichten und evaluiert diese. Notwendige Attribute ◦ parent : Udp * 36 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - Name der Aufgabe Listener(Udp &parent) run() Beschreibung Der Konstruktor der Klasse. Funktion zum starten des Listener. Notwendige Kommunikationspartner Name der Klasse Udp 6.2.4 Dauerhaft? ja Klasse Sender Erläuterungen: Die Klasse Sender reiht Nachrichten zum Senden in eine Liste ein. Notwendige Attribute ◦ parent : Udp * ◦ sendQueue : SharedQueue< Message * > ◦ awaitingAck : SharedMultiMap< std::string, Message * > Aufgabe Aufgaben-ID - Name der Aufgabe Sender(Udp &parent) run() queueMessage(Message *msg) Beschreibung Konstruktor der Klasse. Funktion zum Starten. Reiht die Nachricht zum Senden ein. Notwendige Kommunikationspartner Name der Klasse Udp 6.2.5 Dauerhaft? Ja Klasse SendHellos Erläuterungen: Diese Klasse ist für das ständige Versenden von HELLO-messages zuständig. Notwendige Attribute ◦ parent : Udp * ◦ id : std::string 37 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - Name der Aufgabe SendHellos (Udp &parent, const std::string &id) run() Notwendige Kommunikationspartner Name der Klasse Udp Dauerhaft? Ja 38 Beschreibung Konstruktor der Klasse. Startet das Senden von HELLOmessages. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.3 Implementierung der Komponente S20: Channel In der Komponente Channel sind die Klassen für die Repräsentation von öffentlichen, privaten und dem anonymen Kanal enthalten. Sie ist Teil der Bibliothek. 6.3.1 Klassendiagramm Abbildung 31: Klassendiagramm - Channel 39 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.3.2 Klasse Channel Erläuterungen: Kapselt die Eigenheiten eines generischen Kanals. Von ihr werden die Klassen PublicChannel, PrivateChannel und AnonymChannel abgeleitet und spezialisiert. Notwendige Attribute ◦ mutex : ost::Mutex ◦ manager : ChannelManager * ◦ noChannel : bool ◦ name : std::string ◦ id : std::string ◦ keyType : KeyType ◦ key : std::string ◦ members : UserList * ◦ waitingConfirm : UserList * ◦ lastChn : time t ◦ existent : bool ◦ keyTypeNames [] : static const char * 40 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - F60 Name der Aufgabe Channel(ChannelManager &manager, const std::string &name, const std::string &id, const std::string &key=, KeyType keyType=KEY NOKEY) isExistent() getName() getId() getKeyType() getKey() getMembers() - getLastChannel() - getNoChannel() - setKey(const std::string &key, KeyType type) setKey(const std::string &key, const std::string &type) empty() hasMember(const std::string &id) receivedChannel() F11 F12 - join() leave() confirmJoin(const UserPtr &user) F40 send(ChatMessage &msg) - createChannelMessage() getKeyType(const std::string &type) - getKeyType (KeyType type) sendInternal(ChanneledMessage &msg) 41 Beschreibung Konstruktor der Klasse. Gibt Kanel zurück falls dieser noch im Netz ist. Gibt den Kanalnamen zurück. Gibt die KanalID zurück. Gibt den Schlüsseltyp zurück. Gibt den Schlüssel zurück. Überprüft, ob der User mit der angegeben ID in dem Kanal Mitglied ist. Wenn ja wird dieses Mitglied zurückgegeben. Gibt Wert zurück wenn die letzte CHANNEL-message erhalten wurde. Gibt an ob eine CHANNEL-message gesendet werden konnte oder nicht. Setzt Schlüssel vom Typ KeyType. Setzt Schlüssel. Gibt zurück ob im Kanal Nutzer sind. Gibt an ob der Nutzer im Kanal ist. CHANNEL-message wurde empfangen. Betrete den Kanal. Verlasse den Kanal. Bestätigt den Beitritt eines anderen Nutzers. Sendet eine Nachricht im aktuellen Kanal. Erzeugt eine CHANNEL-message. Gibt den Schlüsseltyp im String zurück. Gibt den Schlüssel als String zurück. Interne Methode zum Senden von Nachrichten. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Notwendige Kommunikationspartner Name der Klasse ChannelManager UserManager JoinMessage LeaveMessage 6.3.3 Dauerhaft? Ja Ja Ja Ja Klasse ClosedChannel Erläuterungen: Repräsentiert einen geschlossenen Kanal.Ein geschlossener Kanal hat einen Schlüssel, mit dem die Übertragungen verschlüsselt werden. Notwendige Attribute ◦ keine Aufgabe Aufgaben-ID - F21 F40 - Name der Aufgabe ClosedChannel(ChannelManager &manager, const std::string &name, const std::string &id, const std::string &key=, KeyType keyType=KEY NOKEY) join() leave() confirmJoin(const UserPtr &user) send(ChatMessage &msg) - createChannelMessage() merge(UserList &users, const std::string &id=) join(const JoinMessage &msg) - leave(const LeaveMessage &msg) Notwendige Kommunikationspartner Name der Klasse ChannelManager Dauerhaft? Ja 42 Beschreibung Konsruktor der Klasse. Funktion zum Beitreten eines geschlossenen Kanals. Verlässt den Kanal. Bestätigt ein Beitrittsversuch eines anderen Nutzers. Sendet eine verschlüsselte Nachricht innerhalb des Kanals. Generiert eine CHANNEL-message. Private Funktion. Private Funktion, die eine JOINmessage verarbeitet. Private Funktion, die eine LEAVEmessage verarbeitet. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.3.4 Klasse PublicChannel Erläuterungen: Die Klasse PublicChannel repräsentiert einen offenen Kanal innerhalb des Netzes. Notwendige Attribute ◦ keine Aufgabe Aufgaben-ID - F10 F12 F40 - Name der Aufgabe PublicChannel(ChannelManager &manager, const std::string &name, const std::string &id) join() leave() send(ChatMessage &msg) - createChannelMessage() merge(UserList &users, const std::string &id=) join(const JoinMessage &msg) - leave(const LeaveMessage &msg) Beschreibung Der Konstruktor. Betritt einen öffentlichen Kanal. Verlassen eines öffentlichen Kanals. Senden einer Nachricht innerhalb des Kanals. Generiert eine CHANNEL-message. Private Funktion, die zwei Kanäle zusammfügt. Private Funktion, die eine JOINmessage verarbeitet. Private Funktion, die eine LEAVEmessage verarbeitet. Notwendige Kommunikationspartner Name der Klasse ChannelManager 6.3.5 Dauerhaft? ja Klasse AnonymousChannel Erläuterungen: Diese Klasse beinhaltet die Funktionen für den anonymen Kanal. Notwendige Attribute ◦ keine 43 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID F40 - Name der Aufgabe AnonymousChannel(ChannelManager &manager) send(ChatMessage &msg) - createChannelMessage() merge(UserList &users, const std::string &id=) join(const JoinMessage &msg) - leave(const LeaveMessage &msg) Beschreibung Der Konstruktor. Sendet Nachrichten innerhalb des Kanals. Generiert eine CHANNEL-message. Vereinigt zwei anonyme Kanäle. Private Funktion, die eine JOINmessage verarbeitet. Private Funktion, die eine LEAVEmessage verarbeitet. Notwendige Kommunikationspartner Name der Klasse ChannelManager 6.3.6 Dauerhaft? Ja Klasse ChannelManager Erläuterungen: Der ChannelManager verwaltet die einzelnen Kanäle im Netz. Notwendige Attribute ◦ network : Network * ◦ channels : ChannelList ◦ nameToIds : IdList ◦ anonChn : ChannelPtr ◦ sendChn : MAdChat::ChannelManager::SendChannel * 44 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID F10 F10 - Name der Aufgabe ChannelManager(Network &network) getChannels() getChannelById(const std::string &id) createChannel(const std::string &name, bool closed, UserList &members) createChannel(const std::string &name, bool closed) start() - addChannel(const ChannelPtr &chn, UserList &members) addChannel(const std::string &name, const std::string &id, bool closed, UserList &members) delChannel(const ChannelPtr &chn) send(ChanneledMessage &msg) - addChannel(const ChannelPtr &chn) - addChannel(const &msg) - ChannelMessage Notwendige Kommunikationspartner Name der Klasse Channel AnonymousChannel PublicChannel ClosedChannel ChannelMessage SendChannel Network Dauerhaft? Ja Ja Ja Ja Ja Ja Ja 45 Beschreibung Der Konstruktor. Gibt alle bekannten Channels zurück. Findet einen Kanal anhand der ID. Erstellt einen Kanael mit vorhandenen Nutzern. Erstellt einen Kanal. Startet das Senden von CHANNELmessages. Fügt einen vorhandenen Kanal mit seinen Nutzern hinzu. Fügt einen vorhandenen Kanal hinzu. Löscht einen Kanal. Sendet eine Nachricht vom Typ ChanneledMessage. Einfache Funktion zum Hinzufügen von Kanälen. Fügt einen Kanal entsprechend einer CHANNEL-message hinzu. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.4 Implementierung der Komponente S30: Message Die Komponete Message hat die Aufgabe Nachrichten des Systems darzustellen, sie aus den empfangenen XML-Daten zu generieren oder aus ihnen XML-Daten zu generieren und zu validieren. 6.4.1 Klassendiagramm Abbildung 32: Klassendiagramm - Message 46 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.4.2 Klasse Message Erläuterungen: Diese Klasse repräsentiert eine Nachricht die gesendet oder empfangen wurde. Die Klasse Network hat uneingeschränkten Zugriff auf alle Attribute, um protokollspezifische Nachrichten zu generieren. Alle anderen Teile des Systems haben nur eingeschränkten Zugriff auf die Attribute. Von dieser Klasse abgeleitet werden die einzelnen Nachrichtentypen wie sie in der Protokollspezifikation beschrieben wurden: HELLO-message, ACK-message, NACKmessage, GETCERTIFICATE-message, CERTIFICATE-message, ROUTING-message und OBSCUREmessage. Notwendige Attribute ◦ type : Type ◦ id : std::string ◦ ttl : unsigned int ◦ delay : unsigned int ◦ ownSignature : bool ◦ signType : SignType ◦ signature : std::string ◦ unknownSignType : std::string ◦ sender : std::string ◦ receivers : std::list< std::string > ◦ peer : PeerAddr ◦ receivedTime : time t ◦ idCount: static int ◦ signTypeNames [] : static const char * 47 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - Name der Aufgabe clone() getType() getId() getTtl() getDelay() - getSignType() getSignature() getOwnSignature() - getSender() getReceivers() getPeer() - getReceivedTime() - getFlood() - isNackable() - needsAck() - createNewId() setId(const std::string &id) setTtl(unsigned int ttl) setDelay(unsigned int delay) setSignature(const std::string &signature, SignType type) setOwnSignature (bool own) setSender(const std::string &sender) - setSender(const UserPtr &user) setReceiver(const std::string &receiver) setReceiver(const UserPtr &user) setReceivers(const std::list< std::string > &receiver) setReceivers(UserList &receivers) 48 Beschreibung Verfielfätigt die Nachricht. Gibt den Typ der Nachricht zurück. Gibt die ID der Nachricht zurück. Gibt die TTL (Time-to-live) zurück. Gibt die Laufzeit der Nachricht zurück. Gibt den Typ der Signatur zurück. Gibt die Signatur zurück. Gibt an ob eigene Signatur berechnet wurde. Gibt den Sender der Nachricht zurück. Gibt die Empfänger zurück. Gibt den Peer zurück von wo aus die Nachricht gesendet wurde oder wohin sie gesendet werden soll. Gibt zurück wann die Nachricht gesendet wurde. Gibt an ob die Nachricht im ganzen Netz geflutet werden soll. Gibt an ob ein NAck gesendet wird, wenn die Nachricht nicht ankommt. Gibt an ob die Nachricht ein Ack braucht. Erzeugt eine neue NachrichtenID. Setzt die NachrichtenID. Setzt die TTL der Nachricht. Setzt die Laufzeit der Nachricht. Setzt die Signatur. Setzt eigene Signatur. Setzt den Sender der Nachricht mit einem String. Setzt den Sender aus UserPtr. Setzt den Empfänger der Nachricht. Setzt den Emfänger aus UserPtr. Setzt die Empfänger einer Nachricht. Setzt die Empfänger anhand der Nutzerliste. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - Name der Aufgabe setPeer(const ost::IPV4Address &ip=0.0.0.0, ost::tpport t port=0) setPeer(const PeerAddr &peer) setReceivedTime(time t time) - isSignatureValid(RSA *pubKey) toXml() - fillFromXml(xmlDocPtr doc, xmlNodePtr node)=0 evaluate(Network network)=0 fromXml(std::string xml) - - - fromXml(xmlDocPtr doc, xmlNodePtr root) writeToXml(xmlTextWriterPtr writer) forward(Network &network) - createSignString() - sign(RSA *privKey) writeToXml(xmlTextWriterPtr writer, const char *rootName) getSignType(const std::string &type) - getSignType(SignType type) - Notwendige Kommunikationspartner Name der Klasse ChannelManager Udp ChanneledMessage Dauerhaft? Ja Ja Ja 49 Beschreibung Setzt die IP und den Port aus einer empfangenen Nachricht. Setzt den Peer. Gibt die Zeit wenn die Nachricht angekommen ist. Gibt an ob die Signatur korrekt ist. Generiert die XML-Repräsentation der Nachricht, dies geschieht normalerweise nur direkt vorm senden. Generiert eine Nachricht aus einem XML-Dokument. Evaluiert die Nachricht über das Netz. Parst die XML-Repräsentation einer Nachricht und setzt die Attribute entsprechend. Dabei wird außerdem der XML-Code überprüft. Konvertiert aus dem XML-Dokument eine Nachricht. Interne Funktion um eine Nachricht nach XML zu schreiben. Verteilt die Nachricht zu allen Empfängern. Erschafft eine Signatur aus einem String. Signiert die Nachricht. Schreibt eine XML-Nachricht mit dem Root-namen. Gibt den Signaturtyp im String zurück. Gibt den Signaturtyp als String zurück. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.4.3 Klasse ChanneledMessage Erläuterungen: Die Klasse ChanneledMessage ist die Vaterklasse für alle Nachrichtentypen, die nur innerhalb eines Kanals genutzt werden. Diese sind: JOIN-message, LEAVE-message, KEY-message, GETKEY-message, CHANNEL-message und CHATMESSAGE-message. Notwendige Attribute ◦ channelName : std::string ◦ channelId : std::string Aufgabe Aufgaben-ID - Name der Aufgabe getChannelName() getChannelId() setChannelName (const std::string &name) setChannelId(const std::string &id) setChannel(const std::string &name, const std::string &id) createSignString() writeToXml(xmlTextWriterPtr ter) Notwendige Kommunikationspartner Name der Klasse Message Dauerhaft? Ja. 50 wri- Beschreibung Gibt den Kanalnamen wieder. Gibt die ID des Kanals wieder. Setzt den Namen des Kanals. Setzt die ID des Kanals. Setzt den Namen und ID des Kanals. Gibt den Namen und ID in einem String wieder. Übergibt den Namen und ID des Channels an den XML-Writer. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.5 Implementierung der Komponente S40: User Die Komponete User hat die Aufgabe Benutzer des Netzes darzustellen. 6.5.1 Klassendiagramm Abbildung 33: Klassendiagramm - User 51 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.5.2 Klasse User Erläuterungen: Diese Klasse repräsentiert einen Nutzer. Notwendige Attribute ◦ manager : UserManager * ◦ existent : bool ◦ peer : bool ◦ lastSeenDirect : time t ◦ lastSeenIndirect : time t ◦ askedForCert : time t ◦ id : std::string ◦ greeting : std::string ◦ version : int ◦ userLists : SharedMap< UserList *, UserList::iterator > 52 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - Name der Aufgabe User(UserManager std::string id) isExistent() - isPeer() - getId() getGreeting() getVersion() setGreeting(const std::string &greeting) setVersion(int version) lastSeen() - seenDirect() - seenIndirect() - lastAskedForCert() - askedForCert() - hasPublicKey() - getPublicKey() - regist(UserList &list, List::iterator &iterator) unregist(UserList &list) - unregist() setExistent(bool existent) &manager, User- Notwendige Kommunikationspartner Name der Klasse UserList UserManager Dauerhaft? Ja Ja 53 Beschreibung Konstruktor. Gibt an ob der Nutzer noch im Netz exisitiert. Gibt an ob der Nutzer direkt erreichbar ist. Gibt die ID des Nutzers zurück. Gibt das Greeting zurück. Gibt die Version zurück. Setzt das Greeting. Setzt die Version. Gibt den letzten Zeitpunkt zurück, an dem eine HELLO-message empfangen wurde. Zeigt an, dass eine HELLO-message empfangen wurde. Zeigt an, dass eine ROUTINGmessage empfangen wurde. Zeigt an, wann das letzte mal nach dem Zertifikat gefragt wurde. Zeigt an, dass gerade nach dem Zertifikat gefragt wurde. Zeigt an, ob der Schlüssel eines anderen Nutzers bekannt ist. Gibt den Schlüssel eines anderen Nutzers zurück. Wird aufgerufen wenn ein Nutzer Mitglied einer UserList werden soll. Entfernt einen Nutzer wieder von der Liste. Entfernt den Nutzer von allen Listen. Setzt den Nutzer als Vorhanden im Netz. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.5.3 Klasse UserList Erläuterungen: Diese Klasse verwaltet die Nutzer im Netzwerk in einer Liste. Notwendige Attribute ◦ users : SharedMap< std::string, UserPtr > Aufgabe Aufgaben-ID - Name der Aufgabe insert(const UserPtr &user) insert(UserList &users) - erase(const UserPtr &user) size () - empty() - clear() find(const std::string &id) random() hasUser(const std::string &id) - getIds(std::list< std::string > &ids) erase(iterator &it) Notwendige Kommunikationspartner Name der Klasse User UserManager 6.5.4 Dauerhaft? Ja Ja Klasse UserManager Erläuterungen: Der UserManager verwaltet die Nutzer im Netz. Notwendige Attribute ◦ mutex : ost::Mutex ◦ network : Network * ◦ users : User * 54 Beschreibung Fügt einen Nutzer der Liste hinzu. Fügt eine ganze Liste mit Nutzern der Liste hinzu. Löscht den Nutzer aus der Liste. Gibt die Anzahl der Nutzer auf der Liste wieder. Gibt true zurück wenn eine Liste leer ist. Löscht alle Nutzer aus der Liste. Findet eine Nutzer anhand der ID. Gibt einen Nutzer zufällig wieder. Gibt an, ob der Nutzer in der List vorhanden ist. Gibt die IDs aller Nutzer in der Liste. Entfernt einen Nutzer aus der Liste. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation ◦ purger : MAdChat::UserManager::Purger * Aufgabe Aufgaben-ID - Name der Aufgabe getUserCount() - getUser(const std::string &id) getRandomUser() - getUsers(const std::list< std::string > &ids, UserList &users) start() addUser(const UserPtr &user) - addUsers(UserList &users) - delUser(const UserPtr &user) - clear() Notwendige Kommunikationspartner Name der Klasse Network RoutingTable User Purger Dauerhaft? Ja Ja Ja Ja 55 Beschreibung Gibt die Anzahl der verwalteten Nutzer zurück. Findet einen Nutzer anhand der ID. Gibt einen zufällig ausgewählten Nutzer zurück. Findet eine Liste von Nutzern anhand von IDs. startet den Purger. Fügt einen Nutzer dem Manager hinzu. Fügt eine Liste von Nutzern dem Manager hinzu. Löscht einen Nutzer, wenn dieser das Netz verlässt. Stoppt die Verwaltung aller Nutzer. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.5.5 Klasse Purger Erläuterungen: Diese Klasse kontrolliert ob die Nutzer in der Liste noch verfügbar sind. Notwendige Attribute ◦ parent : UserManager * Aufgabe Aufgaben-ID - Name der Aufgabe Purger(UserManager &parent) run() Notwendige Kommunikationspartner Name der Klasse UserManager Dauerhaft? Ja 56 Beschreibung Der Konstruktor der Klasse. Startet den Purger. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.6 Implementierung der Komponente S50: EventManager Die Komponente EventManager verarbeitet die Events innerhalb des Netzwerks. 6.6.1 Klassendiagramm Abbildung 34: Klassendiagramm - Event 6.6.2 Klasse EventManager Erläuterungen: Notwendige Attribute ◦ mutex : ost::Mutex ◦ network : Network ◦ events : SharedQueue< Event * > 57 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - Name der Aufgabe EventManager(Network &network) getNextEvent() clear() queueEvent(Event *event) Notwendige Kommunikationspartner Name der Klasse ChatMessage NAckMessage Udp PublicChannel ClosedChannel ChannelManager UserManager Dauerhaft? Ja Ja Ja Ja Ja Ja Ja 58 Beschreibung Konstruktor der Klasse. Gibt das nächste Event in der Reihe zurück. Entfernt alle übirgen Events. Reiht ein Event ein. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.7 Implementierung der Komponente S60: Crypt Die Komponente Crypt verwaltet die Zertifikate und ist für die Verschlüsselung zuständig. 6.7.1 Klassendiagramm Abbildung 35: Klassendiagramm - Crypt 6.7.2 Klasse CertificateManager Erläuterungen: Notwendige Attribute ◦ certs : SharedMap< std::string, X509 * > ◦ rootCert : X509 * ◦ privKey : RSA * ◦ basePath : std::string 59 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID - Name der Aufgabe CertificateManager(const std::string &basePath, std::string rootCert) add (X509 *cert) - addFile(std::string certFile) - addMem(std::string certString) - setPrivateKey(std::string keyFile) - save() - load() hasUser(const std::string &id) - getPublicKey(const std::string &id) - getPrivateKey() getCertificate(const std::string &id) Notwendige Kommunikationspartner Name der Klasse Keine Dauerhaft? - 60 Beschreibung Konstruktor Fügt ein neues X509-Zertifikat hinzu und gibt die ID zurück. Fügt ein X509-Zertifikat aus der Datei hinzu. Fügt ein X509-Zertifikat hinzu mit Base64 DER String. Verifiziert die Signatur von keyFile mit RSA key. Speichert alle Zertifikate im angegebenen Ordner. Lädt abgespeicherte Zertifikate. Überprüft ob der Schlüssel des Nutzers bereits vorhanden ist. Gibt den öffentlichen Schlüssel des Nutzers im RSA-Format wieder. Gibt den privaten Schlüssel zurück. Gibt das Zerifikat des Nutzers im PEM-Format zurück. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.8 Implementierung der Komponente S70: RoutingTable Die Komponente RoutingTable ist für das Routing innerhalb des Netzwerkes zuständig. 6.8.1 Klassendiagramm Abbildung 36: Klassendiagramm - RoutingTable 6.8.2 Klasse RoutingTable Erläuterungen: Diese Klasse ist zuständig für Routing-Informationen und das Finden von Wegen durch das Netz zu den Nutzern. Notwendige Attribute ◦ network : Network * ◦ table : SharedMap< std::string, std::set< RoutingData > > 61 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation ◦ peers : std::set< Peer > ◦ sendRoutesThread : MAdChat::RoutingTable::SendRoutes * Aufgabe Aufgaben-ID - - Name der Aufgabe update(const Message *msg) - findRoute(const std::string &destination, unsigned int offset) purge() - start() - processHello(const Message *msg) - processRouting(const Message *msg) - insertRoute(const std::string &userId, const Peer &peer, int hops, const std::string greeting=, int version=-1) Beschreibung Aktualisiert die RoutingInformationen entprechend der Nachrichtentyps. Findet den Peer zu dem eine Nachricht geschickt werden soll. Sorgt dafür, dass die RoutingTable nicht zu groß wird. Startet das Senden von ROUTINGmessages. Gewinnt Routing-Daten aus HELLOmessages. Gewinnt Routing-Daten aus ROUTING-messages. Fügt neue Route hinzu. Notwendige Kommunikationspartner Name der Klasse Network 6.8.3 Dauerhaft? Ja Klass PeerAddr Erläuterungen: Die Klasse PeerAddr repräsentiert einen Tupel von IP-Adresse und Port. Notwendige Attribute ◦ ip : ost::IPV4Address ◦ port : ost::tpport t 62 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation Aufgabe Aufgaben-ID F50 F50 - Name der Aufgabe PeerAddr(const PeerAddr &right) PeerAddr(ost::IPV4Address ip, int port) operator=(const PeerAddr &right) - operator==(const PeerAddr &right) operator<(const PeerAddr &right) - toString() fromString(std::string str) Beschreibung Der Konstruktor. Der Konstruktor mit IP-Adresse und Port. Operator der Peers auf gleichen Inhalt testet. Operator zum Verlgeich von Peers. Vergleicht ob ein Peer kleiner (IPAdresse oder Port wenn IP-Adressen gleich) ist als der andere. Einfache toString-Methode. Erstellt einen Peer aus einem String. Notwendige Kommunikationspartner Name der Klasse RoutingData Peer 6.8.4 Dauerhaft? Ja Ja Klasse RoutingData Erläuterungen: Erweitert die Klasse PeerAddr mit einem Feld für Hops. Notwendige Attribute ◦ hop : int Aufgabe Aufgaben-ID - Name der Aufgabe RoutingData(const ost::IPV4Address &ip, int port, int hop) RoutingData(const PeerAddr &addr, int hop=0) RoutingData() operator<(const RoutingData &right) Notwendige Kommunikationspartner Name der Klasse PeerAddr Dauerhaft? Ja 63 Beschreibung Konstruktor mit angegebene Parametern. Konstruktor mit Varibale vom Typ PeerAddr als Parameter. Einfacher Konstruktor. Kleiner-Operator. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.8.5 Klasse Peer Erläuterungen: Diese Klasse erweitert die Klasse PeerAddr um den letzten Zeitpunkt einer angekommenen HELLO-message zu speichern. Notwendige Attribute ◦ lastHello : time t Aufgabe Aufgaben-ID - Name der Aufgabe Peer(const PeerAddr &addr, time t lastHello=0) Peer(const ost::IPV4Address &ip, int port, time t lastHello) Notwendige Kommunikationspartner Name der Klasse PeerAddr Dauerhaft? Ja 64 Beschreibung Konstruktor mit Parameter vom Typ PeerAddr. Konstruktor mit IP-Addresse und Port. 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation 6.9 Implementierung der Komponente S80: Network Die Komponente Network verwaltet das Ad-hoc-Netz. 6.9.1 Klassendiagramm Abbildung 37: Klassendiagramm - Network 6.9.2 Klasse Network Erläuterungen: Die Klasse Network verbindet die einzelnen Komponenten miteinander und initialisiert die jeweiligen Manager. Notwendige Attribute ◦ localUser : UserPtr ◦ udp : Udp * ◦ chanMan : ChannelManager * 65 6 IMPLEMENTIERUNGSENTWURF Entwicklerdokumentation ◦ userMan : UserManager * ◦ rTable : RoutingTable * ◦ certMan : CertificateManager * ◦ eventMan : EventManager * Aufgabe Aufgaben-ID - - Name der Aufgabe Network(const std::string &certBase, const std::string &rootCert, const std::string &userCert, const std::string &privKey, ost::tpport t port=8888) getLocalUser() getUdp() getChannelManager() getUserManager() getRoutingTable() getEventManager() getCertificateManager() getInfrastructure() Notwendige Kommunikationspartner Name der Klasse Udp RoutingTable EventManager UserManager ChannelManager CertificateManager Dauerhaft? Ja Ja Ja Ja Ja Ja 66 Beschreibung Konstruktor der mit den erforderlichen Zertifikaten ein Netzwerk erstellt. Gibt Gibt Gibt Gibt Gibt Gibt Gibt Gibt den den lokalen Nutzer zurück. UDP zurück. den ChannelManager zurück. den UserManager zurück. die RoutingTable zurück. den EventManager zurück. den CertificateManager zurück. den Infrastruktur-Modus zurück. 7 Entwicklerdokumentation 7 7.1 DATENMODELL Datenmodell Diagramm Abbildung 38: Datenmodell 7.2 Erläuterung Entitäten X.509 Zertifikat – Benutzereinstellungen X.509 Zertifikat – RootZertifikat Beziehungen Zu jedem Benutzer wird ein X.509 Zertifikat gespeichert Es wird ein RootZertifikat des IBR gespeichert 67