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
[email protected]
[email protected]
[email protected]
[email protected]
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