VL Peer-2-Peer Netzwerke SS 2009 Dr. Dominic Battré Ausgabe 15.5.2009 Abgabe 4.6.2009 Besprechung 5.6.2009 Übungszettel 5 Hinweise • Übungen können in Gruppen beliebiger Größe bearbeitet werden • Abgabe per e-Mail an [email protected] • Alle abgegebenen Zettel werden korrigiert • Übungen werden nicht benotet – die Bearbeitung wird aber dringend empfohlen! • Der Stoff der Übungen ist grundsätzlich prüfungsrelevant! Ausnahmen sind mit Stern gekennzeichnete Aufgaben. • Homepage der Vorlesung: http://www.cit.tu-berlin.de/?id=51290 Aufgabe 1 Gegeben sei ein Pastry-Netzwerk mit IDs zur Basis 3; die ID-Länge ist ebenfalls 3. Es gibt also max. 27 unterschiedliche IDs. Im Netzwerk befinden sich 6 Knoten mit den IDs 001, 010, 011, 201 212, 220, 221. Die Knoten haben folgende Routing Tabellen: Node 001 L0 XXX — 220 L1 XXX 010 — L2 — XXX — Node 212 L0 011 — XXX L1 — XXX 221 L2 — — XXX Node 010 L0 XXX L1 001 L2 XXX Node 220 L0 010 L1 — L2 XXX — XXX 011 — 212 221 220 — — XXX XXX — Node 011 L0 XXX — 212 L1 001 XXX — L2 010 XXX — Node 221 L0 011 — XXX L1 — 212 XXX L2 220 XXX — Jeder Knoten hat ein Leaf-Set der Länge 2, d.h. er kennt seinen linken und rechten Nachbarn. 1. Wie wird eine Nachricht von Knoten 001 an die ID 222 geroutet? 1 2. Wie sehen die Routing Tabellen aus, wenn ein Knoten 210 das Netzwerk betritt und Knoten 001 als Einstiegspunkt nimmt. Dabei soll sich 210 nur in leere Stellen der Routingtabellen von Knoten eintragen, die er beim Einfügen kennenlernt, und von ihnen Routingtabelleneinträge übernehmen. Lösung: 1. Knoten 001 hat keinen gemeinsamen Präfix mit 222, schlägt also den Eintrag für den Präfix der Länge 0 mit Folgeziffer 2 in der Routing Tabelle nach: 220. Knoten 220 hat die ID 222 nicht im Leaf Set und keinen Eintrag für einen Präfix der Länge 2 mit Folgeziffer 2. Daher routet 220 die Nachricht über sein Leaf Set an 221. 221 sieht in seinem Leaf Set, dass die ID 222 darin enthalten ist und wählt sich selbst als nächsten Nachbarn aus. Daher erfolgt die Zustellung an 221. 2. Knoten 210 findet den Weg 001, 220, 212. Von 001 kann er die erste Zeile übernehmen, von 220 die zweite, von 212 die dritte Zeile. Damit sieht seine Routingtabelle folgendermaßen aus: Node 210 L0 001 L1 — L2 XXX — XXX — XXX 220 212 Die Knoten 001, 212, 220 werden über den neuen Knoten informiert. Da wir aber zur Zeit keine Annahmen über die Latenzen haben, behalten 001 und 220 Ihre Routing Tabellen unverändert. Knoten 212 nimmt den neuen Knoten auf. Node 001 L0 XXX L1 XXX L2 — — 010 XXX 220 — — Node 212 L0 011 — L1 — XXX L2 210 — XXX 221 XXX Node 220 L0 010 L1 — L2 XXX — 212 221 XXX XXX — Aufgabe 2 In dieser Aufgabe soll die Chat Applikation mit diversen neuen Fähigkeiten versehen werden: Wir wollen erreichen, dass sich ein User im Netz anmelden kann, dass seine Daten im Netz gefunden werden können und dass sein Onlinestatus angezeigt werden kann. Wenn ein Benutzer seine Daten nicht regelmäßig aktualisiert hat, sollen sie aus dem Netz verschwinden. Auf der Webseite findest du ein Archiv mit Quellcoden. Darin findest du zunächst einige neue Nachrichten. 2 DominicB h(DominicB) h(n(Berlin)) fragender Knoten alle 60 Sek. ImMessagePublishProfile alle 60 Sek. ImMessageKeyword alle 15 Sek. ImMessagePublishStatus ImMessageAskKeyword ImMessageReplyKeyword ImMessageAskProfileAndStatus ImMessageReplyProfileAndStatus Abbildung 0.1: Kommunikationsmuster Angenommen, der User “DominicB” betritt das Netzwerk. Dann sendet er zunächst sein Profil (First Name: Dominic, Last Name: Battré, Town: Berlin, Email: [email protected]) an h(DominicB) mittels einer ImMessagePublishProfile Nachricht. Desweiteren schickt einer eine ImMessagePublishStatus nachricht an h(DominicB), mit der er hinterlegt, dass User DominicB mit mit einem bestimmten NodeHandle (vergleichbar zu Socket) erreicht werden kann. Der Knoten, der für h(DominicB) zuständig ist, muss die Schlüsselwörter aus dem Profil von DominicB verteilen. Dazu sendet er eine ImMessagePublishKeyword Nachricht an den Knoten h(n(Dominic)), eine an den Knoten h(n(Battré)), u.s.w.. Hierbei steht die Funktion n für die SoundEx Normalisierung. Sie dient dazu, ähnlich klingende Namen auf den gleichen Hash-Wert abzubilden. Zur Normalisierung wird die Funktion Soundex.soundex(String) verwendet. Interessiert sich nun ein User für alle Personen aus Berlin, kann er eine ImMessageAskKeyword Anfrage an h(n(Berlin)) schicken und bekommt eine Liste von UserIDs. Darin enthalten ist auch DominicB. Somit kann der fragende Knoten nun mittels ImMessageAskProfileAndStatus das komplette Profil sowie den Onlinestatus von DominicB abfragen. Das beschriebene Kommunikationsmuster ist in Abbildung 0.1 dargstellt. Das Profil soll alle 60 Sekunden veröffentlicht werden und nach 365 Tagen ohne Update verfallen, Keywords sollen ebenfalls alle 60 Sekunden veröffentlicht werden aber nach 5 Minuten ohne Update verfallen. Der Onlinestatus soll alle 15 Sekunden veröffentlicht werden und nach 60 Sekunden ohne Update verfallen. Diese Werte sind in der Klasse ExpirationTimes gespeichert. Vor dem oben beschriebenen Hintergrund soll jetzt die Klasse ImApplication mit Inhalt gefüllt werden. 1. Implementiere zunächst eine Klasse für das Interface ImDHTStorageInterface. Die ImApplication soll eine Instanz dieser Klasse speichern und bei Aufruf von getDHTStorage zurückliefern. Die Aufgabe dieser Klasse ist, den Inhalt des DHT Bereichs zu speichern, für den der Peer zuständig ist. Es sollen drei Maps unterhalten 3 werden: • User ID → NodeHandle (zum Nachschlagen von NodeHandles; wenn kein Eintrag existiert oder der Eintrag null ist, gilt ein Peer als offline) • User ID → Profile • Keyword → Menge von User IDs Diese Klasse sollte auch dafür sorgen, dass alte und nicht aktualisierte Einträge gelöscht werden. 2. Implementiere nur eine Klasse für das Interface ImDataDisseminatorInterface, welche in regelmäßigen Abständen (s.o.) die Daten ins Netz verteilt. 3. Als drittes implementiere die Methoden searchUserIdsByKeyword und searchProfileByUserId als blockierende Methoden. Das heißt: die GUI ruft diese Methoden auf, sie senden eine Anfrage und warten darauf, dass die Antwort aus dem Netz kommt (über die Methoden replyForProfileAndStatusRequest und replyForKeywordReceived). Wenn die Antwort angekommen ist oder ein 5 Sekunden TimeOut überschritten ist, wird das Ergebnis zurückgeliefert. Jetzt kannst Du bereits nach Profilen und Usern suchen. 4. Als letztes kannst du ImBuddyListInterface implementieren, sodass dein P2P Chat eine vollständige Freundesliste verwalten kann. Die Buddy Liste sollte in regelmäßigen Abständen (15 Sekunden) den Status aller eingetragenen Buddies erfragen und bei Änderungen die Observer benachrichtigen. Du kannst deine Implementierung vollständig lokal testen. Starte einfach zwei Instanzen auf deinem eigenen Rechner: ./start.sh --localPort 7777 --bootHost $HOSTNAME --bootPort 7777 ./start.sh --localPort 7778 --bootHost $HOSTNAME --bootPort 7777 Der Peer auf cit-server.cit.tu-berlin.de ist noch nicht in der Lage, die neuen Nachrichten zu verarbeiten. Die Umstellung wird über die Mailingliste angekündigt. 4