58
Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit Jan Hartmann Aug 22, 2016

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Embed Size (px)

Citation preview

Page 1: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis vonXMPP und BitTorrent

Release Bachelorarbeit

Jan Hartmann

Aug 22 2016

Contents

1 Abstract 1

2 Einleitung 3

3 Planung 531 Anforderungen 532 Konzept 6

4 Zusammenhaumlnge und Grundlagen 741 XMPP 742 BitTorrent 11

5 Implementierung 1351 Allgemeines zur Implementierung 1352 Entwurf 1453 BitTorrent 1654 XMPP 2155 Web 2956 Inter-Process Communication 3457 Abschluss der Implementierung 37

6 Beurteilung der Ergebnisse 4161 Vor- und Nachteile der serverlosen Dateiuumlbertragung 4162 libtorrent 4263 XMPP Ansaumltze 4264 Threading 42

7 Ausblick 45

8 Zusammenfassung 47

9 Anhaumlnge 49

i

91 Uumlbersicht der IPC Topics 4992 Inhaltsverzeichnis der CD 49

10 Literaturverzeichnis 51101 Buumlcher 51102 URLs 51

Bibliography 53

ii

CHAPTER 1

Abstract

Die in XMPP uumlblichen Dateiuumlbertragungen sind aufgrund eingeschraumlnkter Funktionalitaumlt derServer oder inkompatibelen XMPP Clients haumlufig langsam oder es kommen wegen mangelnderKompatibilitaumlt keine Uumlbertragung zustande Auszligerdem ist es nicht moumlglich Dateien dauerhaftzum Download anzubieten Diese Thesis beschreibt die Moumlglichkeit Metadaten von zu uumlbertra-genden Dateien und IP Adressen des Nutzers per XMPP zu verteilen die Dateiuumlbertragung selbstaber uumlber BitTorrent zu fuumlhren Dies ermoumlglicht verteilte Downloads sowie dauerhafte Freiga-ben Um die Moumlglichkeiten und Limitierungen dieser Methode aufzuzeigen wurde ein XMPP-und BitTorrent Client implementiert

1

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

2 Chapter 1 Abstract

CHAPTER 2

Einleitung

Das eXtensible Messaging and Presence Protocol (XMPP) umgangssprachlich ldquoJabberrdquo ist einoffenes Kommunikationsprotokoll das im Wesentlichen eine Technologie darstellt in XML einge-bettete Daten zu streamen und das sich seit seiner Veroumlffentlichung 1999 [XMPa] (page 54) starkverbreitet hat Beispielsweise arbeiten der Facebook-Chat WhatsApp und GoogleTalk mit XMPPAusserdem verwenden Apple Cisco IBM Nokia und Sun XMPP in einigen ihrer Produkte (Vgl[XMP8] (page 53))

Durch die Moumlglichkeit XMPP Server aumlhnlich wie Email Server in einem dezentralen Netzwerk zubetreiben ist aber auch ein Netzwerk von vielen oumlffentlichen privat betriebenen XMPP Serverngewachsen Listen einiger oumlffentlicher Server finden sich beispielsweise unter jabberesorgservers[jab] (page 53) oder xmppnetdirectory [imo] (page 53)

Allerdings bringt die Tatsache dass XMPP auf einem textbasierten Protokoll aufbaut auchNachteile mit sich

So werden im Falle der Uumlbertragungen von Binaumlrdaten diese erst Base64 kodiert um sie in denXML Stream einzubetten Dies vergroumlszligert die Datenmenge auf ca 43 fuumlr diese sogenannten In-Band Uumlbertragungen und haumlufig wird die Uumlbertragungsrate dieser XML-Datenpakete dann nochvon den beteiligten Servern gedrosselt

Deshalb stellen In-Band Uumlbertragungen in den meisten Faumlllen nur den Fallback Modus darbevorzugt werden Out-of-Band Uumlbertragungen

Das bedeutet dass eine separate Client-zu-Client Verbindung hergestellt wird uumlber die dieDatenuumlbertragung stattfinden soll Da hier aber mehrere Erweiterungen existieren die wiederumvon beteiligten Clients sowie Servern unterstuumltzt werden muumlssen schlagen diese Uumlbertragungenhaumlufig fehl sodass in vielen Faumlllen die Clients auf In-Band Uumlbertragung zuruumlckfallen oder dieUumlbertragung gar nicht zustande kommt

Diese Thesis untersucht eine andere Methode die Dateiuumlbertragungen abzuwickeln uumlber das Peer-to-Peer Protokoll BitTorrent (BT)

XMPP dient hierbei nur noch dazu die Daten weiter zu leiten die fuumlr das Starten einer Datenuumlber-tragung per BitTorrent noumltig sind Das Herstellen der Verbindung zwischen den Clients sowie dieeigentliche Datenuumlbertragung finden komplett uumlber BitTorrent statt

3

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Dazu wurde ein XMPP- und BitTorrent Client in Python implementiert der dazu dient die fuumlr denDatenaustausch wichtigen Informationen unter den Teilnehmern zu verteilen und gegebenenfallsdie Datenuumlbertragungen abzuwickeln

Diese Thesis geht im Kapitel Planung (page 5) auf die Anforderungen an das Programm und dasKonzept ein Darauf folgt das Kapitel Zusammenhaumlnge und Grundlagen (page 7) in dem dasbenoumltigte Wissen uumlber XMPP und dessen Erweiterungen sowie BitTorrent vermittelt wird DasKapitel Implementierung (page 13) unterteilt sich in Kapitel zum Entwurf der Anwendung und zurkonkreten Umsetzung der einzelnen Komponenten Darauf folgt die Beurteilung der Ergebnisseim Kapitel Beurteilung der Ergebnisse (page 41) und eine Zusammenfassung mit Ausblick aufErweiterungsmoumlglichkeiten in Kapitel Zusammenfassung (page 47)

4 Chapter 2 Einleitung

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 2: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Contents

1 Abstract 1

2 Einleitung 3

3 Planung 531 Anforderungen 532 Konzept 6

4 Zusammenhaumlnge und Grundlagen 741 XMPP 742 BitTorrent 11

5 Implementierung 1351 Allgemeines zur Implementierung 1352 Entwurf 1453 BitTorrent 1654 XMPP 2155 Web 2956 Inter-Process Communication 3457 Abschluss der Implementierung 37

6 Beurteilung der Ergebnisse 4161 Vor- und Nachteile der serverlosen Dateiuumlbertragung 4162 libtorrent 4263 XMPP Ansaumltze 4264 Threading 42

7 Ausblick 45

8 Zusammenfassung 47

9 Anhaumlnge 49

i

91 Uumlbersicht der IPC Topics 4992 Inhaltsverzeichnis der CD 49

10 Literaturverzeichnis 51101 Buumlcher 51102 URLs 51

Bibliography 53

ii

CHAPTER 1

Abstract

Die in XMPP uumlblichen Dateiuumlbertragungen sind aufgrund eingeschraumlnkter Funktionalitaumlt derServer oder inkompatibelen XMPP Clients haumlufig langsam oder es kommen wegen mangelnderKompatibilitaumlt keine Uumlbertragung zustande Auszligerdem ist es nicht moumlglich Dateien dauerhaftzum Download anzubieten Diese Thesis beschreibt die Moumlglichkeit Metadaten von zu uumlbertra-genden Dateien und IP Adressen des Nutzers per XMPP zu verteilen die Dateiuumlbertragung selbstaber uumlber BitTorrent zu fuumlhren Dies ermoumlglicht verteilte Downloads sowie dauerhafte Freiga-ben Um die Moumlglichkeiten und Limitierungen dieser Methode aufzuzeigen wurde ein XMPP-und BitTorrent Client implementiert

1

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

2 Chapter 1 Abstract

CHAPTER 2

Einleitung

Das eXtensible Messaging and Presence Protocol (XMPP) umgangssprachlich ldquoJabberrdquo ist einoffenes Kommunikationsprotokoll das im Wesentlichen eine Technologie darstellt in XML einge-bettete Daten zu streamen und das sich seit seiner Veroumlffentlichung 1999 [XMPa] (page 54) starkverbreitet hat Beispielsweise arbeiten der Facebook-Chat WhatsApp und GoogleTalk mit XMPPAusserdem verwenden Apple Cisco IBM Nokia und Sun XMPP in einigen ihrer Produkte (Vgl[XMP8] (page 53))

Durch die Moumlglichkeit XMPP Server aumlhnlich wie Email Server in einem dezentralen Netzwerk zubetreiben ist aber auch ein Netzwerk von vielen oumlffentlichen privat betriebenen XMPP Serverngewachsen Listen einiger oumlffentlicher Server finden sich beispielsweise unter jabberesorgservers[jab] (page 53) oder xmppnetdirectory [imo] (page 53)

Allerdings bringt die Tatsache dass XMPP auf einem textbasierten Protokoll aufbaut auchNachteile mit sich

So werden im Falle der Uumlbertragungen von Binaumlrdaten diese erst Base64 kodiert um sie in denXML Stream einzubetten Dies vergroumlszligert die Datenmenge auf ca 43 fuumlr diese sogenannten In-Band Uumlbertragungen und haumlufig wird die Uumlbertragungsrate dieser XML-Datenpakete dann nochvon den beteiligten Servern gedrosselt

Deshalb stellen In-Band Uumlbertragungen in den meisten Faumlllen nur den Fallback Modus darbevorzugt werden Out-of-Band Uumlbertragungen

Das bedeutet dass eine separate Client-zu-Client Verbindung hergestellt wird uumlber die dieDatenuumlbertragung stattfinden soll Da hier aber mehrere Erweiterungen existieren die wiederumvon beteiligten Clients sowie Servern unterstuumltzt werden muumlssen schlagen diese Uumlbertragungenhaumlufig fehl sodass in vielen Faumlllen die Clients auf In-Band Uumlbertragung zuruumlckfallen oder dieUumlbertragung gar nicht zustande kommt

Diese Thesis untersucht eine andere Methode die Dateiuumlbertragungen abzuwickeln uumlber das Peer-to-Peer Protokoll BitTorrent (BT)

XMPP dient hierbei nur noch dazu die Daten weiter zu leiten die fuumlr das Starten einer Datenuumlber-tragung per BitTorrent noumltig sind Das Herstellen der Verbindung zwischen den Clients sowie dieeigentliche Datenuumlbertragung finden komplett uumlber BitTorrent statt

3

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Dazu wurde ein XMPP- und BitTorrent Client in Python implementiert der dazu dient die fuumlr denDatenaustausch wichtigen Informationen unter den Teilnehmern zu verteilen und gegebenenfallsdie Datenuumlbertragungen abzuwickeln

Diese Thesis geht im Kapitel Planung (page 5) auf die Anforderungen an das Programm und dasKonzept ein Darauf folgt das Kapitel Zusammenhaumlnge und Grundlagen (page 7) in dem dasbenoumltigte Wissen uumlber XMPP und dessen Erweiterungen sowie BitTorrent vermittelt wird DasKapitel Implementierung (page 13) unterteilt sich in Kapitel zum Entwurf der Anwendung und zurkonkreten Umsetzung der einzelnen Komponenten Darauf folgt die Beurteilung der Ergebnisseim Kapitel Beurteilung der Ergebnisse (page 41) und eine Zusammenfassung mit Ausblick aufErweiterungsmoumlglichkeiten in Kapitel Zusammenfassung (page 47)

4 Chapter 2 Einleitung

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 3: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

91 Uumlbersicht der IPC Topics 4992 Inhaltsverzeichnis der CD 49

10 Literaturverzeichnis 51101 Buumlcher 51102 URLs 51

Bibliography 53

ii

CHAPTER 1

Abstract

Die in XMPP uumlblichen Dateiuumlbertragungen sind aufgrund eingeschraumlnkter Funktionalitaumlt derServer oder inkompatibelen XMPP Clients haumlufig langsam oder es kommen wegen mangelnderKompatibilitaumlt keine Uumlbertragung zustande Auszligerdem ist es nicht moumlglich Dateien dauerhaftzum Download anzubieten Diese Thesis beschreibt die Moumlglichkeit Metadaten von zu uumlbertra-genden Dateien und IP Adressen des Nutzers per XMPP zu verteilen die Dateiuumlbertragung selbstaber uumlber BitTorrent zu fuumlhren Dies ermoumlglicht verteilte Downloads sowie dauerhafte Freiga-ben Um die Moumlglichkeiten und Limitierungen dieser Methode aufzuzeigen wurde ein XMPP-und BitTorrent Client implementiert

1

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

2 Chapter 1 Abstract

CHAPTER 2

Einleitung

Das eXtensible Messaging and Presence Protocol (XMPP) umgangssprachlich ldquoJabberrdquo ist einoffenes Kommunikationsprotokoll das im Wesentlichen eine Technologie darstellt in XML einge-bettete Daten zu streamen und das sich seit seiner Veroumlffentlichung 1999 [XMPa] (page 54) starkverbreitet hat Beispielsweise arbeiten der Facebook-Chat WhatsApp und GoogleTalk mit XMPPAusserdem verwenden Apple Cisco IBM Nokia und Sun XMPP in einigen ihrer Produkte (Vgl[XMP8] (page 53))

Durch die Moumlglichkeit XMPP Server aumlhnlich wie Email Server in einem dezentralen Netzwerk zubetreiben ist aber auch ein Netzwerk von vielen oumlffentlichen privat betriebenen XMPP Serverngewachsen Listen einiger oumlffentlicher Server finden sich beispielsweise unter jabberesorgservers[jab] (page 53) oder xmppnetdirectory [imo] (page 53)

Allerdings bringt die Tatsache dass XMPP auf einem textbasierten Protokoll aufbaut auchNachteile mit sich

So werden im Falle der Uumlbertragungen von Binaumlrdaten diese erst Base64 kodiert um sie in denXML Stream einzubetten Dies vergroumlszligert die Datenmenge auf ca 43 fuumlr diese sogenannten In-Band Uumlbertragungen und haumlufig wird die Uumlbertragungsrate dieser XML-Datenpakete dann nochvon den beteiligten Servern gedrosselt

Deshalb stellen In-Band Uumlbertragungen in den meisten Faumlllen nur den Fallback Modus darbevorzugt werden Out-of-Band Uumlbertragungen

Das bedeutet dass eine separate Client-zu-Client Verbindung hergestellt wird uumlber die dieDatenuumlbertragung stattfinden soll Da hier aber mehrere Erweiterungen existieren die wiederumvon beteiligten Clients sowie Servern unterstuumltzt werden muumlssen schlagen diese Uumlbertragungenhaumlufig fehl sodass in vielen Faumlllen die Clients auf In-Band Uumlbertragung zuruumlckfallen oder dieUumlbertragung gar nicht zustande kommt

Diese Thesis untersucht eine andere Methode die Dateiuumlbertragungen abzuwickeln uumlber das Peer-to-Peer Protokoll BitTorrent (BT)

XMPP dient hierbei nur noch dazu die Daten weiter zu leiten die fuumlr das Starten einer Datenuumlber-tragung per BitTorrent noumltig sind Das Herstellen der Verbindung zwischen den Clients sowie dieeigentliche Datenuumlbertragung finden komplett uumlber BitTorrent statt

3

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Dazu wurde ein XMPP- und BitTorrent Client in Python implementiert der dazu dient die fuumlr denDatenaustausch wichtigen Informationen unter den Teilnehmern zu verteilen und gegebenenfallsdie Datenuumlbertragungen abzuwickeln

Diese Thesis geht im Kapitel Planung (page 5) auf die Anforderungen an das Programm und dasKonzept ein Darauf folgt das Kapitel Zusammenhaumlnge und Grundlagen (page 7) in dem dasbenoumltigte Wissen uumlber XMPP und dessen Erweiterungen sowie BitTorrent vermittelt wird DasKapitel Implementierung (page 13) unterteilt sich in Kapitel zum Entwurf der Anwendung und zurkonkreten Umsetzung der einzelnen Komponenten Darauf folgt die Beurteilung der Ergebnisseim Kapitel Beurteilung der Ergebnisse (page 41) und eine Zusammenfassung mit Ausblick aufErweiterungsmoumlglichkeiten in Kapitel Zusammenfassung (page 47)

4 Chapter 2 Einleitung

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 4: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 1

Abstract

Die in XMPP uumlblichen Dateiuumlbertragungen sind aufgrund eingeschraumlnkter Funktionalitaumlt derServer oder inkompatibelen XMPP Clients haumlufig langsam oder es kommen wegen mangelnderKompatibilitaumlt keine Uumlbertragung zustande Auszligerdem ist es nicht moumlglich Dateien dauerhaftzum Download anzubieten Diese Thesis beschreibt die Moumlglichkeit Metadaten von zu uumlbertra-genden Dateien und IP Adressen des Nutzers per XMPP zu verteilen die Dateiuumlbertragung selbstaber uumlber BitTorrent zu fuumlhren Dies ermoumlglicht verteilte Downloads sowie dauerhafte Freiga-ben Um die Moumlglichkeiten und Limitierungen dieser Methode aufzuzeigen wurde ein XMPP-und BitTorrent Client implementiert

1

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

2 Chapter 1 Abstract

CHAPTER 2

Einleitung

Das eXtensible Messaging and Presence Protocol (XMPP) umgangssprachlich ldquoJabberrdquo ist einoffenes Kommunikationsprotokoll das im Wesentlichen eine Technologie darstellt in XML einge-bettete Daten zu streamen und das sich seit seiner Veroumlffentlichung 1999 [XMPa] (page 54) starkverbreitet hat Beispielsweise arbeiten der Facebook-Chat WhatsApp und GoogleTalk mit XMPPAusserdem verwenden Apple Cisco IBM Nokia und Sun XMPP in einigen ihrer Produkte (Vgl[XMP8] (page 53))

Durch die Moumlglichkeit XMPP Server aumlhnlich wie Email Server in einem dezentralen Netzwerk zubetreiben ist aber auch ein Netzwerk von vielen oumlffentlichen privat betriebenen XMPP Serverngewachsen Listen einiger oumlffentlicher Server finden sich beispielsweise unter jabberesorgservers[jab] (page 53) oder xmppnetdirectory [imo] (page 53)

Allerdings bringt die Tatsache dass XMPP auf einem textbasierten Protokoll aufbaut auchNachteile mit sich

So werden im Falle der Uumlbertragungen von Binaumlrdaten diese erst Base64 kodiert um sie in denXML Stream einzubetten Dies vergroumlszligert die Datenmenge auf ca 43 fuumlr diese sogenannten In-Band Uumlbertragungen und haumlufig wird die Uumlbertragungsrate dieser XML-Datenpakete dann nochvon den beteiligten Servern gedrosselt

Deshalb stellen In-Band Uumlbertragungen in den meisten Faumlllen nur den Fallback Modus darbevorzugt werden Out-of-Band Uumlbertragungen

Das bedeutet dass eine separate Client-zu-Client Verbindung hergestellt wird uumlber die dieDatenuumlbertragung stattfinden soll Da hier aber mehrere Erweiterungen existieren die wiederumvon beteiligten Clients sowie Servern unterstuumltzt werden muumlssen schlagen diese Uumlbertragungenhaumlufig fehl sodass in vielen Faumlllen die Clients auf In-Band Uumlbertragung zuruumlckfallen oder dieUumlbertragung gar nicht zustande kommt

Diese Thesis untersucht eine andere Methode die Dateiuumlbertragungen abzuwickeln uumlber das Peer-to-Peer Protokoll BitTorrent (BT)

XMPP dient hierbei nur noch dazu die Daten weiter zu leiten die fuumlr das Starten einer Datenuumlber-tragung per BitTorrent noumltig sind Das Herstellen der Verbindung zwischen den Clients sowie dieeigentliche Datenuumlbertragung finden komplett uumlber BitTorrent statt

3

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Dazu wurde ein XMPP- und BitTorrent Client in Python implementiert der dazu dient die fuumlr denDatenaustausch wichtigen Informationen unter den Teilnehmern zu verteilen und gegebenenfallsdie Datenuumlbertragungen abzuwickeln

Diese Thesis geht im Kapitel Planung (page 5) auf die Anforderungen an das Programm und dasKonzept ein Darauf folgt das Kapitel Zusammenhaumlnge und Grundlagen (page 7) in dem dasbenoumltigte Wissen uumlber XMPP und dessen Erweiterungen sowie BitTorrent vermittelt wird DasKapitel Implementierung (page 13) unterteilt sich in Kapitel zum Entwurf der Anwendung und zurkonkreten Umsetzung der einzelnen Komponenten Darauf folgt die Beurteilung der Ergebnisseim Kapitel Beurteilung der Ergebnisse (page 41) und eine Zusammenfassung mit Ausblick aufErweiterungsmoumlglichkeiten in Kapitel Zusammenfassung (page 47)

4 Chapter 2 Einleitung

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 5: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

2 Chapter 1 Abstract

CHAPTER 2

Einleitung

Das eXtensible Messaging and Presence Protocol (XMPP) umgangssprachlich ldquoJabberrdquo ist einoffenes Kommunikationsprotokoll das im Wesentlichen eine Technologie darstellt in XML einge-bettete Daten zu streamen und das sich seit seiner Veroumlffentlichung 1999 [XMPa] (page 54) starkverbreitet hat Beispielsweise arbeiten der Facebook-Chat WhatsApp und GoogleTalk mit XMPPAusserdem verwenden Apple Cisco IBM Nokia und Sun XMPP in einigen ihrer Produkte (Vgl[XMP8] (page 53))

Durch die Moumlglichkeit XMPP Server aumlhnlich wie Email Server in einem dezentralen Netzwerk zubetreiben ist aber auch ein Netzwerk von vielen oumlffentlichen privat betriebenen XMPP Serverngewachsen Listen einiger oumlffentlicher Server finden sich beispielsweise unter jabberesorgservers[jab] (page 53) oder xmppnetdirectory [imo] (page 53)

Allerdings bringt die Tatsache dass XMPP auf einem textbasierten Protokoll aufbaut auchNachteile mit sich

So werden im Falle der Uumlbertragungen von Binaumlrdaten diese erst Base64 kodiert um sie in denXML Stream einzubetten Dies vergroumlszligert die Datenmenge auf ca 43 fuumlr diese sogenannten In-Band Uumlbertragungen und haumlufig wird die Uumlbertragungsrate dieser XML-Datenpakete dann nochvon den beteiligten Servern gedrosselt

Deshalb stellen In-Band Uumlbertragungen in den meisten Faumlllen nur den Fallback Modus darbevorzugt werden Out-of-Band Uumlbertragungen

Das bedeutet dass eine separate Client-zu-Client Verbindung hergestellt wird uumlber die dieDatenuumlbertragung stattfinden soll Da hier aber mehrere Erweiterungen existieren die wiederumvon beteiligten Clients sowie Servern unterstuumltzt werden muumlssen schlagen diese Uumlbertragungenhaumlufig fehl sodass in vielen Faumlllen die Clients auf In-Band Uumlbertragung zuruumlckfallen oder dieUumlbertragung gar nicht zustande kommt

Diese Thesis untersucht eine andere Methode die Dateiuumlbertragungen abzuwickeln uumlber das Peer-to-Peer Protokoll BitTorrent (BT)

XMPP dient hierbei nur noch dazu die Daten weiter zu leiten die fuumlr das Starten einer Datenuumlber-tragung per BitTorrent noumltig sind Das Herstellen der Verbindung zwischen den Clients sowie dieeigentliche Datenuumlbertragung finden komplett uumlber BitTorrent statt

3

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Dazu wurde ein XMPP- und BitTorrent Client in Python implementiert der dazu dient die fuumlr denDatenaustausch wichtigen Informationen unter den Teilnehmern zu verteilen und gegebenenfallsdie Datenuumlbertragungen abzuwickeln

Diese Thesis geht im Kapitel Planung (page 5) auf die Anforderungen an das Programm und dasKonzept ein Darauf folgt das Kapitel Zusammenhaumlnge und Grundlagen (page 7) in dem dasbenoumltigte Wissen uumlber XMPP und dessen Erweiterungen sowie BitTorrent vermittelt wird DasKapitel Implementierung (page 13) unterteilt sich in Kapitel zum Entwurf der Anwendung und zurkonkreten Umsetzung der einzelnen Komponenten Darauf folgt die Beurteilung der Ergebnisseim Kapitel Beurteilung der Ergebnisse (page 41) und eine Zusammenfassung mit Ausblick aufErweiterungsmoumlglichkeiten in Kapitel Zusammenfassung (page 47)

4 Chapter 2 Einleitung

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 6: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 2

Einleitung

Das eXtensible Messaging and Presence Protocol (XMPP) umgangssprachlich ldquoJabberrdquo ist einoffenes Kommunikationsprotokoll das im Wesentlichen eine Technologie darstellt in XML einge-bettete Daten zu streamen und das sich seit seiner Veroumlffentlichung 1999 [XMPa] (page 54) starkverbreitet hat Beispielsweise arbeiten der Facebook-Chat WhatsApp und GoogleTalk mit XMPPAusserdem verwenden Apple Cisco IBM Nokia und Sun XMPP in einigen ihrer Produkte (Vgl[XMP8] (page 53))

Durch die Moumlglichkeit XMPP Server aumlhnlich wie Email Server in einem dezentralen Netzwerk zubetreiben ist aber auch ein Netzwerk von vielen oumlffentlichen privat betriebenen XMPP Serverngewachsen Listen einiger oumlffentlicher Server finden sich beispielsweise unter jabberesorgservers[jab] (page 53) oder xmppnetdirectory [imo] (page 53)

Allerdings bringt die Tatsache dass XMPP auf einem textbasierten Protokoll aufbaut auchNachteile mit sich

So werden im Falle der Uumlbertragungen von Binaumlrdaten diese erst Base64 kodiert um sie in denXML Stream einzubetten Dies vergroumlszligert die Datenmenge auf ca 43 fuumlr diese sogenannten In-Band Uumlbertragungen und haumlufig wird die Uumlbertragungsrate dieser XML-Datenpakete dann nochvon den beteiligten Servern gedrosselt

Deshalb stellen In-Band Uumlbertragungen in den meisten Faumlllen nur den Fallback Modus darbevorzugt werden Out-of-Band Uumlbertragungen

Das bedeutet dass eine separate Client-zu-Client Verbindung hergestellt wird uumlber die dieDatenuumlbertragung stattfinden soll Da hier aber mehrere Erweiterungen existieren die wiederumvon beteiligten Clients sowie Servern unterstuumltzt werden muumlssen schlagen diese Uumlbertragungenhaumlufig fehl sodass in vielen Faumlllen die Clients auf In-Band Uumlbertragung zuruumlckfallen oder dieUumlbertragung gar nicht zustande kommt

Diese Thesis untersucht eine andere Methode die Dateiuumlbertragungen abzuwickeln uumlber das Peer-to-Peer Protokoll BitTorrent (BT)

XMPP dient hierbei nur noch dazu die Daten weiter zu leiten die fuumlr das Starten einer Datenuumlber-tragung per BitTorrent noumltig sind Das Herstellen der Verbindung zwischen den Clients sowie dieeigentliche Datenuumlbertragung finden komplett uumlber BitTorrent statt

3

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Dazu wurde ein XMPP- und BitTorrent Client in Python implementiert der dazu dient die fuumlr denDatenaustausch wichtigen Informationen unter den Teilnehmern zu verteilen und gegebenenfallsdie Datenuumlbertragungen abzuwickeln

Diese Thesis geht im Kapitel Planung (page 5) auf die Anforderungen an das Programm und dasKonzept ein Darauf folgt das Kapitel Zusammenhaumlnge und Grundlagen (page 7) in dem dasbenoumltigte Wissen uumlber XMPP und dessen Erweiterungen sowie BitTorrent vermittelt wird DasKapitel Implementierung (page 13) unterteilt sich in Kapitel zum Entwurf der Anwendung und zurkonkreten Umsetzung der einzelnen Komponenten Darauf folgt die Beurteilung der Ergebnisseim Kapitel Beurteilung der Ergebnisse (page 41) und eine Zusammenfassung mit Ausblick aufErweiterungsmoumlglichkeiten in Kapitel Zusammenfassung (page 47)

4 Chapter 2 Einleitung

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 7: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Dazu wurde ein XMPP- und BitTorrent Client in Python implementiert der dazu dient die fuumlr denDatenaustausch wichtigen Informationen unter den Teilnehmern zu verteilen und gegebenenfallsdie Datenuumlbertragungen abzuwickeln

Diese Thesis geht im Kapitel Planung (page 5) auf die Anforderungen an das Programm und dasKonzept ein Darauf folgt das Kapitel Zusammenhaumlnge und Grundlagen (page 7) in dem dasbenoumltigte Wissen uumlber XMPP und dessen Erweiterungen sowie BitTorrent vermittelt wird DasKapitel Implementierung (page 13) unterteilt sich in Kapitel zum Entwurf der Anwendung und zurkonkreten Umsetzung der einzelnen Komponenten Darauf folgt die Beurteilung der Ergebnisseim Kapitel Beurteilung der Ergebnisse (page 41) und eine Zusammenfassung mit Ausblick aufErweiterungsmoumlglichkeiten in Kapitel Zusammenfassung (page 47)

4 Chapter 2 Einleitung

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 8: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 3

Planung

31 Anforderungen

Da es sich bei der geplanten Anwendung um einen Prototypen handelt der in erster Linie dazudient das Konzept der Datenuumlbertragung zu testen sollen die Anwendungsfaumllle auf ein fuumlr diegrundlegenden Funktionen wichtiges Minimum reduziert bleiben

Fig 31 Anwendungsfaumllle

Das Diagramm Anwendungsfaumllle (page 5) zeigt die geplanten Anwendungsfaumllle die implementiertwerden sollen um grundlegende Funktionalitaumlt zu gewaumlhrleisten und die Anwendung sinnvollnutzen zu koumlnnen

So sollen eigene Freigaben erstellt und entfernt werden koumlnnen (AF10 und AF20) sowie Freiga-ben anderer Nutzer aufgelistet und durchsucht werden als auch Downloads angestoszligen wer-den koumlnnen (AF30 bis AF40) Als Teil der Konfiguration soll auszligerdem ein XMPP Accounteingestellt werden koumlnnen (AF60 und AF70)

5

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 9: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

32 Konzept

Fig 32 Grafik zum Konzept der Anwendung

Diagramm 32 zeigt das Grundkonzept der Anwendung Erreicht werden soll also im erstenSchritt eine Datenfreigabe uumlber BitTorrent und das Verteilen der noumltigen Freigabeinformationenuumlber XMPP an die Kontakte der jeweiligen Kontaktliste

Freigabeinformationen umfassen die von BitTorrent benoumltigten Pruumlfsummen der freigegebenenDaten die zur eindeutigen Identifikation dienen dazu Dateinamen und -Groumlszlige was den Anwen-dern hilft den Inhalt einzuschaumltzen sowie Adresse und Port unter der die Freigaben fuumlr andereTeilnehmer zu finden sind

Eine Gegenstelle die die Freigabeinformationen empfangen hat kann dann uumlber IP-Adresse Portund die Pruumlfsumme einen Download von der Gegenstelle anstoszligen Falls fuumlr eine Pruumlfsumme (unddamit eine Freigabe) mehrere Adressen vorliegen kann der Download auch von mehreren Quellengleichzeitig erfolgen

Sobald ein Teil der Daten von einer Gegenstelle heruntergeladen wurde wird diese als neueFreigabe des Kontakts auch an dessen Kontakte uumlbermittelt und agiert so als ein neuer Knoten-punkt der ebenfalls Teile dieser Datei zum Download anbietet

Auf diese Art kann in relativ kleinem Kreis ein verteiltes Filesharing stattfinden

6 Chapter 3 Planung

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 10: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 4

Zusammenhaumlnge und Grundlagen

Um das in der Einleitung beschriebene Konzept umzusetzen werden im folgenden KapitelldquoXMPPrdquo einige Grundlagen uumlber die Funktionsweise von XMPP und dessen Erweiterung PersonalEventing Protocol (PEP) erlaumlutert

Auszligerdem wird im darauf folgenden Kapitel ldquoBitTorrentrdquo auf einige Grundlagen zur Funktion vonBitTorrent und dessen Verfahren zur Identifikation von Daten eingegangen

41 XMPP

Das Extensible Messaging and Presence Protocol ist im Grunde eine Technologie zum XML strea-men (vgl [XMP16] (page 53)) und kann so benutzt werden um alle moumlglichen Arten textbasierterInformationen zu versenden und zu empfangen

Ein Stream beginnt immer mit dem Oumlffnen eines Stream Tags mit ldquoltstreamgtrdquo und endet mit demSchlieszligen desselben mit ldquoltstreamgtrdquo Innerhalb dieses Streams koumlnnen eine beliebige Menge anXML Elementen die sogenannten ldquoStanzasrdquo versendet werden Die XMPP Core RFC definiertein Stanza als ldquodiscrete semantic unit of structured information that is sent from one entity toanotherrdquo [Ext] (page 53) also als ein XML Tag in den wiederum Tags eingebettet sein koumlnnen

Fuumlr die Tiefe eins des Streams also unmittelbar dem Stream Stanza untergeordnet sind dreiBasis-Stanzatypen definiert die sich im default-Namespace ldquojabberclientrdquo bzw ldquojabberserverrdquobefinden

ltmessagegt ltpresencegt ltiqgt

Jedes dieser Basisstanzas erfuumlllt unterschiedliche Funktionen

So ist mit dem Message Stanza ein ldquoPushrdquo Mechanismus verbunden um Nachrichten direkt anandere Teilnehmer zu verschicken beispielsweise

Das Presence Stanza funktioniert als ldquoPublish-Subscriberdquo Mechanismus In der Basisfunktionalitaumltist dies der Verfuumlgbarkeitsstatus ist ein Kontakt online oder nicht Es wird also jeder Kontaktder die eigene Presence abonniert hat automatisch uumlber Statusaumlnderungen benachrichtigt Diese

7

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 11: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ist uumlblicherweise erweitert durch ein Show und Status Stanza das eine naumlhere Beschreibung derAnwesenheit gibt

Um diese Nachrichten zu empfangen wird eine Presence-Subscription benoumltigt also ein Hand-shake bei dem die Gegenstelle das ldquoAbonnementrdquo des Kontakts akzeptiert Dies wird uumlblicher-weise von den Clients durchgefuumlhrt wenn ein neuer Kontakt zum Roster hinzugefuumlgt werden soll1

Das Presence Stanza wird durch viele XMPP Extension Protocols (XEP) erweitert insbeson-dere XEP-0060 (ldquoPublish-Subcriberdquo) und XEP-0163 (ldquoPersonal Eventing Protocolrdquo) auf die nochnaumlher eingegangen wird

Das InfoQuery Stanza (IQ) implementiert einen Query-Response Mechanismus und ist vergleich-bar mit der HTTP Funktionalitaumlt

Ein IQ Stanza kann eins von vier type-Attributen haben

Listing 41 4 IQ Stanzatypes [Ext] (page 53)

get -- The stanza is a request for information or requirementsset -- The stanza provides required data sets new values orrarr˓replaces existing valuesresult -- The stanza is a response to a successful get or set requesterror -- An error has occurred regarding processing or delivery of ararr˓previously-sent get or set (see Stanza Errors)

Zur Verdeutlichung wie diese unterschliedlichen Funktionen ineinander greifen sei dieses Beispielaus XMPP The Definitive Guide [SAST09] (page 53) gegeben

Listing 42 XML Beispielstream aus [SAST09] (page 53) (s17)

C ltstreamstreamgt

C ltpresencegt

C ltiq type=getgtltquery xmlns=jabberiqrostergtltiqgt

S ltiq type=resultgtltquery xmlns=jabberiqrostergtltitem jid=alicewonderlandlitgtltitem jid=madhatterwonderlandlitgtltitem jid=whiterabbitwonderlandlitgt

ltquerygtltiqgt

1 Der Handshake uumlberschreitet die fuumlr diese Thesis benoumltigten Grundlagen deshalb sei an dieser Stelle auf dasBuch ldquoXMPP - The definitive Guiderdquo von Peter Saint-Andre Kevin Smith und Remko Tronccedilon [XMP16] (page 53)verwiesen

8 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 12: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

C ltmessage from=queenwonderlandlitto=madhatterwonderlandlitgt

ltbodygtOff with his headltbodygtltmessagegt

S ltmessage from=kingwonderlandlitto=partyconferencewonderlandlitgt

ltbodygtYou are all pardonedltbodygtltmessagegt

C ltpresence type=unavailablegt

C ltstreamstreamgt

Uumlblicherweise wird sich ein User mit seiner ldquoJabber IDrdquo (JID) anmelden Diese besteht aus demAccountnamen der Serveradresse und einer Ressource die die jeweiligen Endpunkte unterschei-det im Format ldquousernameserveraddresseresourcerdquo Die Kombination aus Accountname undServeraddresse wird ldquobarerdquo JID genannt kommt die Ressource hinzu spricht man von der ldquofullrdquoJID

411 Erweiterungen

lsquoThe ldquoXrdquo in XML and XMPP stands for ldquoextensiblerdquo so payload types are limitedonly by your imaginationrsquo [SAST09] (page 53)

Dadurch dass XMPP auf der Extensible Markup Language aufbaut kann es relativ leicht um eigeneFunktionen erweitert werden Die XMPP Standards Foundation fuumlhrt hierzu eine Liste der eingere-ichten Erweiterungen als XMPP Extension Protocols (XEP) Diese umfassen zu diesem Zeitpunkt379 Dokumente

Als Moumlglichkeit mit wenig Aufwand definierte Informationen an die eigenen Kontakte zu sendensoll hier eine Einfuumlhrung in das Personal Eventing Protocol (PEP definiert in XEP-0163) bzweine seiner Anwendungen das auf PEP aufbauende ldquoUser Tunerdquo (XEP-0118) gegeben werden

PEP User Tune

ldquoInstead of extending ltpresencegt stanzas directly it is a best practice to make useof the Personal Eventing Protocol or PEP defined in XEP-0163 which allows usersto subscribe to the extra data they are interested in The PEP extension along withEntity Capabilities (XEP-0114) and Service Discovery (XEP-0015) make providingextended presence-type information efficient and opt-inrdquo [pro35] (page 53)

Mit dem Personal Eventing Protocol (PEP) existiert eine gute Moumlglichkeit nutzerbezogene In-formationen zu teilen Hier wird jedem Nutzeraccount eine PubSub Node zugeordnet auf der er

41 XMPP 9

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 13: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Informationen in die jeweiligen Namespaces publishen kann

Mithilfe von Entity Capabilities (XEP-0115) [XEPa] (page 54) kann ein Kontakt dem Server mit-teilen welche Namespaces er unterstuumltzt (PEP spricht hier von ldquointerestrdquo) und wird daraufhinnach diesen Namespaces gefilterte Listen mit Userinformationen bekommen Auszligerdem wird derServer falls noumltig Updates ausliefern

Eine zweite Moumlglichkeit PEP Nachrichten zu erhalten ist das ldquoauto-subscriberdquo Feature bei demdie gesamte Presence eines Users abonniert wird In diesem Fall bekommt der Client immer alleNodes es wird nicht gefiltert

Bereits in vielen Clients umgesetzt sind die auf PEP basierenden Erweiterungen ldquoUser Geolo-cationrdquo (XEP-0080) ldquoUser Moodrdquo (XEP-0107) ldquoUser Activityrdquo (XEP-0108) und ldquoUser Tunerdquo(XEP-0118) All diese XEPs sind darauf ausgelegt Informationen die sich auf den aktuellenUseraccount beziehen an interessierte Kontakte auszuliefern

Ein uumlbersichtliches Beispiel zur Anwendung von PEP ist in der User Tune Spezifikation gegeben

Listing 43 Beispiel Publishing an event xep-0118 [XEPb] (page 54)

1 ltiq type=set2 from=stpeterjabberorg14793c64-0f94-11dc-9430-000bcd821bfb3 id=tunes123gt4 ltpubsub xmlns=httpjabberorgprotocolpubsubgt5 ltpublish node=httpjabberorgprotocoltunegt6 ltitemgt7 lttune xmlns=httpjabberorgprotocoltunegt8 ltartistgtYesltartistgt9 ltlengthgt686ltlengthgt

10 ltratinggt8ltratinggt11 ltsourcegtYessongsltsourcegt12 lttitlegtHeart of the Sunriselttitlegt13 lttrackgt3lttrackgt14 lturigthttpwwwyesworldcomlyricsFragilehtml9lturigt15 lttunegt16 ltitemgt17 ltpublishgt18 ltpubsubgt19 ltiqgt

In Beispiel Publishing an event xep-0118 [XEP-0118online] (page 10) sendet Userlsquostpeterjabberorglsquo vom Endpunkt lsquo14793c64-[]rsquo ein PEP Event Stanza auf die Node lsquohttpjabberorgprotocoltunelsquo was dem Namespace des eingebetteten Stanza ldquotunerdquo entspricht undkeine aufrufbare URL sondern nur ein Name fuumlr Namespace und Node ist

Daraufhin werden alle User in seiner Kontaktliste die die Presence oder den Namespace abonnierthaben das aktuelle pubsub Stanza bekommen

Im Kapitel XMPP (page 21) ImplementierungXMPP wird beschrieben wie eine eigene PEP Er-

10 Chapter 4 Zusammenhaumlnge und Grundlagen

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 14: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

weiterung die fuumlr BitTorrent benoumltigten Informationen einbetten kann

42 BitTorrent

Fuumlr die Datenuumlbertragung soll das BitTorrent Protokoll genutzt werden Dieses nutzt wenn keineProtokollerweiterungen genutzt werden einen ldquoTrackerrdquo genannten Server zur Vermittlung derTeilnehmer (ldquoPeersrdquo)

ldquoBitTorrent is a protocol for distributing files It identifies content by URL and is de-signed to integrate seamlessly with the web Its advantage over plain HTTP is thatwhen multiple downloads of the same file happen concurrently the downloaders up-load to each other making it possible for the file source to support very large numbersof downloaders with only a modest increase in its loadrdquo

mdash[wwwa] (page 54)

Sinngemaumlszlig uumlbersetzt

ldquoBitTorrent ist ein Protokoll zum Verteilen von Dateien Es bestimmt Inhalt anhandeiner URL und ist dazu entworfen sich nahtlos ins Internet zu integrieren Der Vorteilzu HTTP ist dass wenn multiple Downloads derselben Datei zur gleichen Zeit stat-tfinden die Downloader zueinander uploaden Dadurch kann eine Dateiquelle sehrviele Downloader bei geringem Anstieg seiner Last habenrdquo

Der Vorteil von BitTorrent als Uumlbertragungsprotokoll ist also dass wenn mehr als ein Kontaktdieselbe Datei zum Download anbietet auch von mehreren Kontakten gleichzeitig herunterge-laden werden kann Hierzu wuumlrde normalerweise der Tracker die Peers vermitteln In dieserImplementierung soll dies jedoch uumlber XMPP geschehen

Die Identifikation der Dateien findet laut der BitTorrent Protocol Specification ([wwwa] (page 54))uumlber ein ldquoinfo dictrdquo im torrent-File statt In dieser Implementierung soll jedoch eine andere Meth-ode genutzt werden Die in der BitTorrent Extension Protocol (BEP) 9 beschriebene Unterstuumltzungfuumlr Magnet Links

ldquoThe purpose of this extension is to allow clients to join a swarm and complete adownload without the need of downloading a torrent file first This extension insteadallows clients to download the metadata from peers It makes it possible to supportmagnet links a link on a web page only containing enough information to join theswarm (the info hash)rdquo [wwwb] (page 54)

Das in der Spezifikation beschriebene Format eines Magnet Links ist dabei wie folgt

magnetxt=urnbtihltinfo-hashgtampdn=ltnamegtamptr=lttracker-urlgtampxpe=ltpeer-addressgt

Da kein Tracker benoumltigt wird um Informationen zu verteilen und dynamisch Peer Adressenhinzugefuumlgt werden sollen wird hier also nur der Info Hash benoumltigt Dieser ist der SHA-1 Hashdes info dict des torrent-Files

42 BitTorrent 11

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 15: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Da in der zur Implementierung genutzten Libary (libtorrent) die Moumlglichkeit besteht einen neuenTorrent auf Basis eines Magnet Links anzulegen der nur einen Info Hash enthaumllt und spaumlter dy-namisch Peer Adressen hinzuzufuumlgen ist es moumlglich das komplette Peer Management zur Laufzeitabzuwickeln

12 Chapter 4 Zusammenhaumlnge und Grundlagen

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 16: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 5

Implementierung

51 Allgemeines zur Implementierung

Als Programmiersprache zur Implementierung des Prototypen wurde aufgrund der bisherigenProgrammiererfahrungen des Autors und des Vorhandenseins aller noumltigen Bibliotheken Pythongewaumlhlt

Die Verzeichnisstruktur des Projektes ist dabei angelehnt an die Empfehlungen des ldquoHitchhikersGuide To Pythonrdquo [hit] (page 53) Eine der Uumlbersichtlichkeit wegen vereinfachte Version derStruktur sieht wie folgt aus

Listing 51 Projektstruktur

bitweencomponentsbitweendpybitweencpy

docsconfpyindexrst

testsrequirementstxtsetuppy

bitween

Der Name des Programms und der Name des Verzeichnisses das den Programmcodeenthaumllt

Im Unterverzeichnis ldquocomponentsrdquo befinden sich die Module in denen die jeweiligenFunktionen und Klassen implementiert wurden Ein Modul umfasst dabei jeweils eineDatei ldquo__init__pyrdquo die das Verzeichnis als Modul in Python importierbar macht Dain Python keine privaten Methoden existieren werden in der __init__py alle Funk-tionen oder Klassen aus dem Modul importiert die von anderen Modulen benoumltigt

13

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 17: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

werden koumlnnten So wird eine logische Abgrenzung zu Elementen geschaffen dienur im Modul benoumltigt werden und solchen die fuumlr die Nutzung von anderen Mod-ulen gedacht sind Der Aufbau der einzelnen Komponenten wird in den folgendenKapiteln besprochen

bitweendpy

Der Einstiegspunkt fuumlr das Programm zum Starten des Daemons (Bitweend ist hierkurz fuumlr Bitween Daemon)

bitweencpy

Client fuumlr die JSON-RPC API des Programms

docs

Verzeichnis das alle benoumltigten Dateien zum Generieren der Dokumentation enthaumlltIm einfachsten Fall die vom Dokumentationsgenerator Sphinx benoumltigte Konfigura-tionsdatei confpy und eine reStructuredText-Datei indexrst die als Einstiegspunktfuumlr die Dokumentation dient

tests

Das tests-Verzeichnis enthaumllt alle Testlaumlufe Durch das Hinzufuumlgen der __init__pywird hier eine automatische Testdiscovery ermoumlglicht ldquopython setuppy testrdquo aus-gefuumlhrt im Wurzelverzeichnis des Projektes wuumlrde hier automatisch alle hinterlegtenTests ausfuumlhren

requirementstxt

Die requirementstxt enthaumllt eine Liste der uumlber den Python Paketmanager pip instal-lierbaren Abhaumlngigkeiten des Projekts

setuppy

Das Setupscript enthaumllt alle Informationen um das Programm mit den Python Distutilsbzw pip zu installieren

52 Entwurf

Das Programm gliedert sich in verschiedene Kernkomponenten (Abbildung 51) die in den fol-genden Kapiteln besprochen werden

bull der XMPP Client (XmppClient)

Der XMPP Client ist dafuumlr zustaumlndig eine Verbindung mit dem gewuumlnschtenXMPP Server herzustellen bei jeder Aktualisierung der Torrents eine neue Uumlber-sicht uumlber die angebotenen Shares an den Server zu uumlbermitteln und Aktual-isierungen aus der Kontaktliste zu empfangen Daruumlber hinaus startet der Client

14 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 18: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 51 Moduluumlbersicht

alle weiteren benoumltigten Prozesse und dient somit als ldquoAufseherrdquo uumlber die Startrei-henfolge und eventuelle Abhaumlngigkeiten Als XMPP Libary wird hier die PythonBibliothek SleekXMPP verwendet

bull der BitTorrent Client (BitTorrentClient)

Der BitTorrent Client laumldt beim Start gespeicherte Torrents der letzten Session Erstellt im Falle von hinzugefuumlgten Torrents eine Verbindung zu allen IP-Adressen(und damit zu allen anderen BitTorrent Clients) her die bisher per XMPP emp-fangen wurden Als Libary wird libtorrent verwendet eine in C++ geschriebeneBibliothek mit optionaler Python Anbindung

bull eine Nutzerschnittstelle zur Bedienung (Web)

Die JSON-RPC API des Web Moduls dient als Schnittstelle fuumlr Frontends Da dasProgramm theoretisch als Daemon auf einem entfernten Rechner laufen koumlnnteoumlffnet es einen Port zur Steuerung Hier wurde mit Hilfe des Frameworks Flaskein minimales Webinterface und eine JSON-RPC Schnittstelle fuumlr andere externeAnwendungen entwickelt

bull ein Modul zur IPC (Subscriber)

Da alle genannten Module in eigenen nebenlaumlufigen Threads laufen wird eineKomponente zur Inter-Process Communication benoumltigt Hierzu wurde einePublish-Subscribe Pattern implementiert die das Zuweisen der Nachrichten zuSubscribern uumlbernimmt Auszligerdem dient es als Basisklasse von der alle Klassenderen Objekte Nachrichten empfangen abgeleitet werden Dazu wurde eine ein-fache Scheduling Funktion implementiert

Auszligerdem wurden Klassen zur Abstrahierung der Daten zur Laufzeit geschrieben

bull Addresses fuumlr die eigenen IP-Adressen und BitTorrent Ports

52 Entwurf 15

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 19: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Handles fuumlr die einzelnen Torrent Handles

bull ContactShares fuumlr alle empfangenen Shares

53 BitTorrent

Als erster Teil der beschriebenen Problemstellung soll die Implementierung eines BitTorrentClients zur Uumlbertragung der Nutzdaten besprochen werden

Als Anforderung an die Komponente stellt sich dass diese uumlber die komplette Laufzeit des Pro-gramms neben der XMPP Komponente laufen muss Daher arbeitet der BitTorrent Client in einemeigenen Thread

Dazu ist eine Kommunikation mit anderen Programmteilen noumltig deren genaue Implementierungim Kapitel Inter-Process Communication (page 34) erlaumlutert wird Dieses Kapitel beschraumlnkt sichauf die benoumltigten Schnittstellen und geht auf deren Zweck ein

531 Aufbau der Komponente

Wie in Diagramm 52 zu sehen leitet sich die BitTorrentClient Klasse aus der Thread Klasse ab diesich in der Python Standard Libary befindet und somit zum Lieferumfang jeder Python Installationgehoumlrt

Auszligerdem erbt BitTorrentClient von der Klasse Subscriber deren Implementierung im KapitelInter-Process Communication (page 34) erlaumlutert wird und die Funktionen zur Prozesskommu-nikation bereitstellt

Als BitTorrent Libary wurde libtorrent verwendet Uumlber diese kann ein ldquosessionrdquo Objekt erzeugtwerden uumlber das Einstellungen wie die zu nutzenden Ports gemacht werden koumlnnen und dasHilfsfunktionen wie das Erstellen eines Torrent Objektes aus einem Magnet Link zur Verfuumlgungstellt

Zur Verwaltung der Torrent Handles also der Objekte die die jeweiligen Torrents repraumlsentierenwurde auszligerdem die Klasse ldquoHandlesrdquo als Wrapper um eine Liste implementiert Genutzt wirdvom Client nur append() und remove() um Torrent Handles anzuhaumlngen bzw zu entfernen Dieget_shares() Methode wird vom XMPP Client genutzt um die eigenen Handles als Liste von Dic-tionarys mit einigen Eckdaten auszulesen

532 Erstellen des BitTorrentClient Objekts

16 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 20: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 52 Klassendiagramm BitTorrent

53 BitTorrent 17

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 21: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 52 initalisieren des BitTorrent Clients

def __init__(self)Thread__init__(self)Subscriber__init__(self autosubscribe=True)

[]

Im ersten Schritt werden im Konstruktor die beiden Basisklassen Thread und Subscriber inital-isiert

Subscriber wird hier mit ldquoautosubscribe=Truerdquo erstellt Dies bedeutet dass alle Methoden die mitldquoon_rdquo beginnen automatisch als Topic zum Empfangen von Nachrichten registriert werden So istes relativ einfach moumlglich aus anderen Programmteilen beispielsweise einen Torrent hinzuzufuumlgenoder das Beenden des Threads anzustoszligen

Danach wird uumlberpruumlft ob eine SQLite Datenbank in Homeverzeichnis des Nutzers existiert DerDateiname ist festgelegt auf rdquobitweendbrdquo Ist diese Datei nicht praumlsent wird sie erzeugt Dazuwird in der Methode setup_db() eine neue Tabelle ldquotorrentsrdquo mit den Spalten ldquomagnetlinkrdquo ldquotor-rentrdquo ldquostatusrdquo und ldquosave_pathrdquo angelegt Diese werden benoumltigt um die Torrents zu persistieren

Als naumlchstes wird das session Objekt erzeugt und je nach geladener Konfiguration Einstellungengemacht Ports auf denen BitTorrent arbeiten soll werden festgelegt (oder wenn nicht gesetzt dy-namisch von der Libary gewaumlhlt) UPNP und NATPMP werden aktiviert wenn gewuumlnscht DieseTechniken werden benutzt um automatisch Ports in der NAT Table zu setzen und werden uumlblicher-weise fuumlr den Betrieb hinter einem DSL Router benoumltigt

Zu guter Letzt werden die in der SQLite Datenbank vorhandenen Torrents geladen und mit demsession Objekt verknuumlpft

Danach ist der BitTorrentClient fuumlr den Start vorbereitet

533 Der Run-Loop

Die Aktivitaumlt eines Thread Objektes wird in der run() Methode der Klasse definiert Diese kanndann nach dem Erzeugen des Objektes mit start() gestartet werden

In diesem Fall wird solange Variable ldquoendrdquo des BitTorrentClient Objektes False ist eine Methodehandle_queue() aufgerufen danach mit der Methode handle_alert() die Meldungen des sessionObjektes verarbeitet und danach eine Sekunde gewartet

Listing 53 handle_queue() Methode

def handle_queue(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)

18 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 22: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 53 BitTorrent run() Loop (1) (Fortsetzung in Abb BitTorrent run() Loop (2) (page 21))

53 BitTorrent 19

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 23: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

f(args kwargs)except Exception as e

loggererror(something went wrong when calling on_s srarr˓ (topic e))

handle_queue() uumlberpruumlft ob Nachrichten vorliegen die von Subscriber geerbte Methodeget_message() wird aufgerufen und das Ergebnis in die Variablen ldquotopicrdquo ldquoargsrdquo ldquokwargsrdquogeschrieben Es folgt ein try-except Block in dem versucht wird eine Methode mit dem Na-men ldquoon_rdquo verknuumlpft mit ldquotopicrdquo und ldquoargsrdquo als Argumente und ldquokwargsrdquo als Named Argumentsaufzurufen Wie fuumlr Python Methoden uumlblich sollte args eine Liste sein kwargs ein Dictionary

Ein Beispiel zur Funktion

get_message() liefert als topic den String ldquotestrdquo als args = [2 4] und als kwargs= lsquonamersquo lsquoPeterrsquo Dann wird im try-Block eine Funktion mit Namen ldquoon_testrdquogesucht und der Variable f zugewiesen In dieser Klasse wuumlrde an dieser Stelle schoneine Exception geworfen und eine Fehlermeldung ausgegeben werden Waumlre dieFunktion vorhanden wuumlrde dann on_test(2 4 name=rsquoPeterrsquo) aufgerufen werden

So koumlnnen alle Funktionen die mit ldquoon_rdquo beginnen ldquovon auszligenrdquo genutzt werden Beispielsweisekann ein neuer Torrent per SHA1 Hash uumlber die Methode on_add_hash() hinzugefuumlgt werden Indieser wuumlrde dann ein neuer Torrent angelegt und entsprechende IP-Adressen und Ports hinzuge-fuumlgt unter denen der Torrent zu finden ist Dazu muumlssen natuumlrlich in der XMPP Komponente dieentsprechenden Informationen gesammelt worden sein

In der handle_alert() Methode wird jeweils eine Meldung der Session verarbeitet So wird zumBeispiel bei einem ldquotorrent_update_alertrdquo eine Nachricht mit topic ldquopublish_sharesrdquo erzeugtwas den XMPP Client veranlassen wuumlrde eine Liste der aktuellen Torrents zu senden Einldquoportmap_alertrdquo waumlre zu erwarten wenn ein Port per NAT gemapped wurde In diesem Fall wuumlrdeeine Nachricht auf topic ldquoset_portrdquo mit dem externen Port als Argument erzeugt

534 Beenden des Run-Loops

Wird on_exit() aufgerufen wird die ldquoendrdquo Variable auf True gesetzt und das saubere Beendendes Threads wird eingeleitet Als erstes werden alle Eintraumlge aus der SQLite Datenbank entferntdamit nur Torrents die noch Teil der Session sind gespeichert werden koumlnnen Dann wird fuumlrjeden Torrent das Erzeugen der ldquoresume datardquo angetriggert

Danach laumluft eine Schleife solange noch Torrent Handles vorhanden sind Da fuumlr jeden Tor-rent ein ldquosave_resume_data_alertrdquo erwartet wird kann im Handling dieses Alerts der Torrent indie SQLite Datenbank gespeichert und aus der Session entfernt werden Wird stattdessen einldquosave_resume_data_failed_alertrdquo empfangen wird der Torrent ohne zu speichern aus der Sessionentfernt Das kommt vor wenn ein Torrent neu hinzugefuumlgt wurde und das Programm beendetwird bevor genug Daten geladen wurden um ein komplettes Torrent File zu erzeugen

Um nun eine Uumlbersicht der eigenen Torrents zu versenden und Daten uumlber andere Torrents zu

20 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 24: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 54 BitTorrent run() Loop (2)

empfangen wird die XMPP Komponente benoumltigt die im folgenden Kapitel beschrieben wird

54 XMPP

Im vorigen Kapitel BitTorrent (page 16) wurde die Implementierung eines BitTorrent Clientsbeschrieben der eine Liste der zu verteilenden Torrents generiert und der andererseits die IPAdressen und Ports der zu downloadenden Torrents benoumltigt

Die XMPP Komponente muss nun also diese Liste inklusive der eigenen IP Adressen an alle Kon-takte verteilen und auszligerdem eine Liste der empfangenen Torrents und der entsprechenden Quellenfuumlhren

Das hier verwendete Python Modul SleekXMPP bietet hier die Moumlglichkeit diese Funktionen ineinem Plugin zu implementieren das in einem ansonsten uumlbersichtlichem XMPP Client geladenwerden kann

Die folgenden Kapitel beschreiben die Stanzas in denen die benoumltigten Informationen uumlbertragenwerden sollen sowie den Aufbau des Plugins Danach wird das Einbinden in den XMPP Clienterlaumlutert

54 XMPP 21

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 25: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

541 Benoumltigte Stanzas

Die benoumltigten Informationen umfassen mehrere gekapselte Elemente

Es wird davon ausgegangen dass ein XMPP Account an mehreren Ressourcen zur gleichen Zeitonline ist Diese wiederum haben sehr wahrscheinlich unterschiedliche IP Adressen und Ports undbieten verschiedene Torrents an

Daraus ergibt sich folgende Struktur der Daten (hier als Beispiel in Pseudo-XML)

Listing 54 Beispiel der XML-Struktur

ltRessourcengtlt1 Ressourcegt

ltAddressengtltaddresse ip=1111 port=11gtltaddresse ip=2222 port=22gt

ltAddressengt

ltSharesgtltshare hash=123123123 name=beispiel1 size=123gtltshare hash=234234234 name=beispiel2 size=234gt

ltSharesgt

lt1 Ressourcegtltn Ressourcegt

ltAddressengt ltAddressengtltSharesgt ltSharesgt

ltn RessourcegtltRessourcengt

Diese logische Verschachtelung wurde in den folgenden Stanzas abgebildet

Jede Stanzaklasse wurde von ElementBase abgeleitet der Basisklasse fuumlr Stanzas aus SleekXMPPMithilfe dieser koumlnnen die XML Elemente einfach als Klassen und Attribute von Klassen behandeltwerden ohne das XML als String behandelt werden muss

Das ldquoaumluszligersterdquo Stanza ist das UserShareStanza Diesem Container Stanza koumlnnen uumlber die Meth-ode add_resource() Ressourcen also angemeldete XMPP Clients als Endpunkte hinzugefuumlgt wer-den In diesem ResourceStanza koumlnnen nun per add_address() und add_share() AddressStanzasund ShareItems eingebettet werden

Die Verknuumlpfung der jeweiligen Stanzas erfolgt dabei aus dem jeweils uumlbergeordnetem Stanza

22 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 26: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 55 Klassendiagramm der benoumltigten Stanzas

Listing 55 UserShareStanza mit add_resource() Methode

class UserSharesStanza(ElementBase)name = user_sharesnamespace = httpsxmppkwohdeprotocolsharesplugin_attrib = user_shares

def add_resource(self resource=)[]resource_stanza = ResourceStanza(None self)resource_stanza[resource] = resourcereturn resource_stanza

Hier wird in der Methode add_resource() ein neues ResourceStanza erzeugt ldquoResourceS-tanza(None self)rdquo verknuumlpft das neu erstellte Stanza mit ldquoselfrdquo dem UserSharesStanza

Der Namespace ist hier Erkennungsmerkmal aller zum Plugin gehoumlrigen Stanzas und wird genutztum eingehende Stanzas dem Plugin zuzuordnen

Diese Stanzastruktur wird vom im folgenden Kapitel beschriebenen Plugin benutzt

542 Aufbau des Plugins

Im SleekXMPP Plugin wird nun die beschriebene Datenstruktur benutzt um die zu verteilendenDaten zu senden bzw auszulesen

Jedes SleekXMPP Plugin wird implementiert indem eine neue Klasse aus der SleekXMPP KlasseBasePlugin abgeleitet wird und in dieser die benoumltigten Methoden uumlberschrieben werden

54 XMPP 23

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 27: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 56 Klassendiagramm XMPP Erweiterung

24 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 28: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Hier wird eine neue Klasse UserShares erstellt und die Methoden plugin_init() und plugin_end()uumlberschrieben Diese werden spaumlter vom Client beim Starten bzw Beenden des Plugins ausgefuumlhrt

Auszligerdem wurden hier die Methoden publish_shares() und stop() implementiert

publish_shares() wird aufgerufen sobald der Client startet auszligerdem wenn Aumlnderungen an denTorrents oder des BitTorrent Clients stattfinden beispielsweise falls ein neuer Torrent hinzugefuumlgtwird oder sich der NAT Port aumlndert

on_shares_publish() hingegen stellt das Gegenstuumlck zu publish_shares() dar diese Methode solldas Empfangen der Daten abwickeln

Hier soll ein Plugin implementiert werden das auf dem bereits in Kapitel Zusammenhaumlnge undGrundlagen (page 7) beschriebenen Personal Eventing Protocol (PEP) aufsetzt

Aufgrund der Funktionalitaumlt vom PEP muumlssen Informationen nur gesendet werden wenn sich et-was an den zu verteilenden Daten aumlndert Der XMPP Server wird selbst dafuumlr sorgen das Clientsdie zur Laufzeit erst online gehen die aktuellen Daten bekommen und im Falle von Aktualisierun-gen alle betreffenden Clients ein Update erhalten

Dabei muss beachtet werden dass eine Limitierung vom PEP umgangen werden muss es werdenkeine multiplen Ressourcen pro Account unterstuumltzt Da allerdings bei der Anmeldung eine Listeder bisherigen veroumlffentlichten Daten vom Server gesendet wird auch an den eigenen Accountkann diese Liste einfach um die neue Ressource erweitert werden

543 Start des Plugins

Listing 56 plugin_init() Methode

def plugin_init(self)register_stanza_plugin(

UserSharesStanza ResourceStanza iterable=True)register_stanza_plugin(

ResourceStanza ShareItemStanza iterable=True)register_stanza_plugin(

ResourceStanza AddressStanza iterable=True)

selfxmpp[xep_0163]register_pep(shares UserSharesStanza)selfxmppadd_event_handler(shares_publish selfon_shares_

rarr˓publish)

Wird das Plugin vom Client geladen wird zuerst die plugin_init() Methode aufgerufen In dieserwerden die vom Plugin genutzten Stanzas registriert und das UserShares Stanza unter dem Namenldquosharesrdquo im PEP Plugin registriert Das PEP Plugin wird daraufhin den Namespace des User-Shares Stanzas als unterstuumltztes Feature der Service Discovery hinzufuumlgen Auf diese Art werdennur solche Clients die Informationen erhalten die das Plugin unterstuumltzen Auszligerdem werden inregister_pep() die Events ldquoshares_publishrdquo und ldquoshares_retractrdquo angelegt

54 XMPP 25

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 29: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Als naumlchstes wird ein Event Handler fuumlr shares_publish registriert In der damit verknuumlpften Meth-ode on_shares_publish() soll das Empfangen und Einpflegen der Daten erfolgen

544 Empfangen von Daten

Wird nun ein UserShare Stanza empfangen wird uumlber den Namespace identifiziert dass das User-Share Plugin dafuumlr zustaumlndig ist und die zugehoumlrige Methode on_shares_publish() wird mit demStanza als erstem Argument aufgerufen

Diese Informationen werden in einem Objekt der Klasse ContactShares der Models gehaltenDiese dient als Wrapper um ein Python Dictionary und bietet einige von der Datenstruktur ab-strahierte Funktionen wie get_resource(jid resource) die fuumlr einen bestimmten User die Dateneiner bestimmten Ressource liefert Auszligerdem wurden mit threadingLock Sperren gegen denZugriff aus mehreren Threads zur gleichen Zeit implementiert

Listing 57 Handling des Datenempfangs

staticmethoddef on_shares_publish(msg)

handle incoming files incoming_shares = msg[pubsub_event][items][item][user_

rarr˓shares]loggerinfo(s incoming_shares)

contact_sharesclear(msg[from])

for resource in incoming_shares[resources][]

for item in resource[share_items]loggerinfo(adding share s to resource s (item[name

rarr˓] resource[resource]))contact_sharesadd_share( msg[from]

resource[resource]item[hash]item[name]item[size])

for address in resource[ip_addresses]contact_sharesadd_address( msg[from]

resource[resource]address[address]address[port])

publish(recheck_handles)

In der on_shares_publish() Methode werden dann zuerst alle bislang vorhandenen Daten geloumlscht

26 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 30: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

da davon ausgegangen wird dass in dem erhaltenen Paket alle aktuellen Daten vorhanden sind Da-raufhin wird uumlber die gesendete Liste an Ressourcen iteriert Jede Ressource sollte ldquoshare_itemsrdquoalso Informationen uumlber Torrents und mindestens eine IP-Adresse mit Port haben

Wurde das Datenpaket verarbeitet wird eine Nachricht ohne Argumente auf Topicldquorecheck_handlesrdquo geschickt Das wiederum hat zur Folge dass im BitTorrent Client uumlber alleeigenen Torrents iteriert und uumlberpruumlft wird ob neue Quellen fuumlr einen der eigenen Torrents vor-liegen

Auf diese Art koumlnnen zur Laufzeit neue Quellen zu vorhandenen Torrents hinzugefuumlgt werdenAuszligerdem liegt eine durchsuchbare Datenstruktur vor die beispielsweise von Frontends benutztwerden kann um die empfangenen Torrentlisten anzuzeigen

545 Versenden der Daten

Das Versenden der Daten wird in der Methode publish_shares() abgewickelt Diese soll wennaufgerufen eine aktuelle Liste der Torrents verpackt in die definierten Stanzas versenden

Hier muss darauf geachtet werden dass nicht nur eine Liste der aktuellen Torrents gesendet wirdEs muumlssen auszligerdem die bereits empfangenen Torrents anderer Ressourcen des eigenen Accountsmit einbezogen werden

Dazu wird die Tatsache genutzt dass nach dem Senden auch immer eine Liste der eigenen Torrentsempfangen wird Das hat zur Folge dass in derselben Datenstruktur in der auch die Torrent Datenanderer Nutzer gespeichert werden die eigenen Daten vorliegen

Es muss also nur noch der eigene Useraccount aus der Liste ausgelesen und die Daten der lokalenRessource aktualisiert werden

Danach wird die bereits erlaumluterte Struktur aus Stanzas entsprechend der Daten erstellt undgesendet

546 Aufbau des Clients

Das beschriebene Plugin soll nun von einem XMPP Client genutzt werden Hierfuumlr wird eine neueKlasse XmppClient aus der SleekXMPP Klasse ClientXMPP und der bereits im BitTorrent Clientgenutzten Klasse Subscriber abgeleitet (Abb Klassendiagramm XMPP (page 28))

ClientXMPP bringt hierbei schon alle zum Verbinden benoumltigten Voraussetzungen mit Initalisiertwird das Objekt im XmppClient Konstruktor mit der JID und dem benoumltigten Passwort

Listing 58 registrieren der benoumltigten Plugins

selfregister_plugin(xep_0030) service discoveryselfregister_plugin(xep_0115) entity capsselfregister_plugin(xep_0163) pepselfregister_plugin(shares module=share_plugin)

54 XMPP 27

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 31: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 57 Klassendiagramm XMPP

28 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 32: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Danach werden die benoumltigten Erweiterungen registriert die bereits Teil von SleekXMPP sindService Discovery Entity Caps und PEP Auch das UserShares Modul wird wie die anderen Plug-ins uumlber register_plugin() registriert Hier wird allerdings noch auf das vorher importierte Modulverwiesen da dieses nicht Teil von SleekXMPP ist

Auszligerdem wird im Konstruktor das ldquosession_startrdquo Event mit einer Methode start() der Klasseverknuumlpft Hier wird nach dem Verbinden die eigene Praumlsenz gesendet und der Roster also dieKontaktliste empfangen

In dieser Grundkonfiguration waumlre der Client grundsaumltzlich schon betriebsbereit Allerdings fehltnoch jegliche Art der Interaktion mit anderen Komponenten der Anwendung

Daher wird im Konstruktor noch ein Scheduler hinzugefuumlgt der zyklisch die vom Subscribergeerbte Message Queue verarbeitet Dies erfolgt auf dieselbe Art wie schon im BitTorrent Clientalle mit ldquoon_rdquo beginnenden Methoden werden automatisch als Topic abonniert und werden in derverknuumlpften Methode aufgerufen wenn die entsprechenden Nachrichten vorliegen

Auszligerdem werden im Konstruktor die anderen Komponenten der Anwendung gestartet der Bit-Torrent Client und eine im Kapitel Web (page 29) naumlher beschriebene JSON-RPC API mit einemWeb Frontend zur Uumlbersicht uumlber die Torrents

Da die eigene IP Adresse Teil der zu versendenden Datenpakete ist wird hier auszligerdem ein Prozessangestoszligen der die eigene IPv4 Adresse herausfinden soll Da diese hinter einem DSL Router imlokalen Netz nicht bekannt ist wurde hier das Modul ipgetter genutzt In diesem sind eine Reihean Servern hinterlegt die die IP zuruumlck geben von der die Anfrage kommt

Die IPv6 Adresse kann jedoch aus dem System ausgelesen werden Hierfuumlr kommt das Modulnetifaces zum Einsatz das betriebssystemunabhaumlngig die momentanen IP Adressen auslesen kann

Der so konstruierte Client ist somit der Hauptteil der Anwendung Aus ihm heraus werden dieanderen Teile der Anwendung kontrolliert gestartet Dadurch dass wesentliche Funktionalitaumlt indas Plugin ausgelagert wurde ist er uumlbersichtlich aber um neue Funktionen erweiterbar ohne dieFunktion des Plugins zu beeinflussen

Im folgenden Kapitel wird die Web Komponente beschrieben die einerseits eine minimale We-boberflaumlche zur Uumlbersicht darstellt aber auch eine JSON-RPC API zur Verfuumlgung stellt uumlber dieeventuelle Frontends mit der Anwendung kommunizieren koumlnnen

55 Web

Die Web Komponente soll nun nachdem die Basisfunktionalitaumlt seitens der Datenuumlbertragungimplementiert ist eine Schnittstelle fuumlr Nutzer und Frontends zur Steuerung bieten

Um das Programm auch auf entfernten Rechnern steuern zu koumlnnen wurde hier die Variante einerJSON-RPC API gewaumlhlt Auszligerdem wurde ein minimales Web Frontend implementiert um bereitserhaltene Torrentlisten und eigene Torrents darzustellen Dafuumlr wurde das Web Framework Flaskbzw das Flask Plugin Flask-JSONRPC genutzt

55 Web 29

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 33: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Eine minimale Flask Anwendung ist dabei sehr einfach strukturiert Erst wird ein Flask-Objekterzeugt welches dann Methoden zur Verfuumlgung stellt die wiederum als Decorator fuumlr Funktionengenutzt werden

Listing 59 Flask Beispiel [fla] (page 53)

from flask import Flaskapp = Flask(__name__)

approute()def hello()

return Hello World

if __name__ == __main__apprun()

In diesem Beispiel wird ein Objekt ldquoapprdquo der Klasse Flask erzeugt Daraufhin wird die Funktionhello() mit approute(ldquordquo) dekoriert was zur Folge hat dass wenn die Anwendung mit apprun()lokal gestartet wird beim Aufruf von ldquohttplocalhost5000rdquo in einem Browser der String ldquoHelloWorldrdquo ausgegeben wird 5000 ist hier der Standardport von Flask und kann bei Bedarf angepasstwerden

551 Aufbau der Komponente

Fig 58 Klassendiagramm Web

Da auch dieser Teil parallel zum XmppClient und dem BitTorrentClient laufen muss soll das app-Objekt in einem neuen Thread gestartet werden

30 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 34: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 510 Web initalization

app = Flask(__name__)

[]

class Web(Thread)def __init__(self api_host=localhost api_port=8080)

super(Web self)__init__()selfapi_port = api_portselfapi_host = api_host

def run(self)apprun(host=selfapi_host port=selfapi_port)

Dazu wird wie in Web initalization (page 31) zu sehen auf Modulebene das app-Objekt erstelltund in einer Klasse genutzt die spaumlter wiederum zusammen mit den anderen Komponenten imXMPP Client als Thread gestartet werden kann

Fig 59 Packages Web

Das Modul ist unterteilt in die Submodule api und gui

Im Modul api sind die Funktionen der JSON-RPC API definiert Dieses ist wiederum unterteilt inldquobtrdquo und ldquoxmpprdquo um die dort definierten Routen entsprechend ihrem Zweck aufzuteilen

Das gui Modul beinhaltet Routen und Ressourcen des Web Frontends Dieses bietet aber nurFunktionen um eigene Torrents und gesammelte Shares anzuzeigen Es ist als Uumlbersicht gedachtund stellt keineswegs eine komplette Schnittstelle zu allen Funktionen dar

552 Das api Modul

55 Web 31

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 35: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 511 initalisieren des jsonrpc Objekts und Import der Funktionen(bitweencomponentsweb__init__py)

[]app = Flask(__name__)jsonrpc = JSONRPC(app api enable_web_browsable_api=enable_web_api)

from api import versions safe_exit get_all_torrentsfrom apibt import []from apixmpp import []

Das api Modul basiert auf der Flask Erweiterung Flask-JSONRPC Diese wird mit dem app Objektund einem Prefix fuumlr die gewuumlnschten Routen initialisiert

Die entsprechenden Funktionen werden dann aus dem Submodul importiert

Listing 512 Definition einer JSON-RPC Funktion (bitweencomponentswebapi__init__py)

from import jsonrpc

[]jsonrpcmethod(Apiversions)def versions()

import libtorrentimport sleekxmppversions = libtorrent + libtorrentversion

sleekxmpp + sleekxmpp__version__loggerdebug(versions)return versions

[]

Das Submodul importiert dann das jsonrpc Objekt Hier ist wichtig zu beachten dass diese Importserst nach dem Erstellen des Objektes im uumlbergeordneten Modul auszufuumlhren sind Die Funktionselbst implementiert die Abfrage der verwendeten libtorrent und SleekXMPP Funktionen Dazuwird ein Dictionary erstellt das als JSON String zuruumlckgegeben und von Flask versendet werdenkann

Aufgerufen werden die so implementierten Funktionen dann mit einem HTTP POST auf die Routeldquohttpipportapirdquo mit einem JSON Payload in folgendem Format

Listing 513 Format des JSON Payloads

jsonrpc 20method Apiversionsparams id 1234

32 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 36: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

In diesem Beispiel wird die oben beschriebene Methode ldquoApiversionsrdquo ohne Parameteraufgerufen Die ID ist eine zufaumlllige Nummer die der Antwort ebenfalls als ldquoidrdquo angehangenwird um den Aufruf zuordnen zu koumlnnen

Auf diese Art wurden folgende Funktionen eingefuumlgt

Aufruf Parameter FunktionApiversions ndash gibt die Verwendeten Versionsnummern zuruumlckApiexit ndash leitet das saubere Beenden der Anwendung einbtget_torrents ndash listet die eigenen Torrents aufbtadd_path path generiert einen neuen Torrent aus Datei oder Verzeichnis

unter ltpathgtbtadd_torrent_by_hashhash

save_pathlegt einen neuen Torrent anhand von lthashgt an speichertnach ltsave_pathgt

btdel_torrent hash loumlscht Torrent mit Hash lthashgtxmppget_hashes ndash liefert eine Liste mit aggregierten Hashes und gefundenen

Endpunktenxmppget_shares ndash liefert eine Liste aller Kontakte und deren Shares

553 Das gui Modul

Mit dem gui Modul wurde ein Interface implementiert uumlber das der User eine Uumlbersicht uumlber diegefundenen und eigenen Torrents bekommen kann Dies dient allerdings eher als Beispiel Hierwurde keine komplette Nutzerschnittstelle geschrieben sondern lediglich genug Funktionalitaumlt umschnell eine Uumlbersicht bekommen zu koumlnnen

Diese Funktionen wurden gekapselt als Flask Blueprint und koumlnnen somit fuumlr spaumltere Versionenleicht entfernt oder weiterentwickelt werden Hier soll deshalb nur ein kurzer Uumlberblick uumlber dasbisherige Vorgehen gegeben werden

Listing 514 Setup des gui Blueprints (bitweencomponentswebgui__init__py)

from flask import Blueprint

gui = Blueprint(gui __name__ template_folder=templates static_rarr˓folder=static)

from import views errors

Es wird ein neues Blueprint Objekt gui erstellt Dieses wird benoumltigt um im naumlchsten Schritt dieRouten zu importieren da diese wiederum mit der guiroute() Funktion dekoriert werden

Listing 515 Index Funktion des gui Blueprints (bitweencomponentswebguiviewspy)

guiroute( methods=[GET])def index()

55 Web 33

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 37: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[]return render_template(gui_indexhtml torrents=handlesget_

rarr˓shares())

Diese Beispielroute fuumlr die Index Route ldquordquo wird nur fuumlr die GET Methode definiert Es wirdeine neue Liste der eigenen Torrents erstellt und als ldquotorrentsrdquo zusammen mit dem Templateldquogui_indexhtmlrdquo (im Unterordner ldquotemplatesrdquo) an die Funktion render_template() uumlbergeben diedaraufhin einen String mit dem HTML Code generiert der wiederum zuruumlckgegeben und vonFlask ausgeliefert wird

Listing 516 Registrieren des Blueprints am app Objekt

from gui import gui as gui_blueprint

[]

appregister_blueprint(gui_blueprint)

Registriert wird der Blueprint dann am app Objekt uumlber die Funktion register_blueprint() mit demimportierten Blueprint als Parameter

56 Inter-Process Communication

Die Kommunikation zwischen den Threads wurde durch eine Publish-Subscribe Pattern geloumlstWie bei Publish-Subscribe des XMPP Protokolls koumlnnen Teilnehmer (in diesem Fall Objekte derjeweiligen Klassen) Nachrichten zu bestimmten Topics abonnieren (ldquosubscribenrdquo) Auszligerdemsteht eine ldquopublishrdquo Methode zur Verfuumlgung mit der Nachrichten auf bestimmten Topics veroumlf-fentlicht werden koumlnnen

Hierzu wurde eine Klasse ldquoSubscriberrdquo implementiert die als Basisklasse fuumlr alle anderen Klassendient die Nachrichten empfangen Jedes Subscriber-Objekt besitzt eine Queue die alle noch un-verarbeiteten Nachrichten enthaumllt eine subscribe() Methode um Nachrichten zu Topics zu ldquoAbon-nierenrdquo sowie eine has_messages() und get_messages() Methode um den Zustand der Queueabzufragen und Nachrichten zu entnehmen

Im folgenden Diagramm ist auszligerdem eine Klasse ldquoAutoSubrdquo zu sehen die dazu dient die PubSubKlasse zu testen und die gleichzeitig als einfaches Beispiel dienen soll wie eine Klasse einigeihrer Methoden direkt als Topics abonnieren kann Hierauf wird am Ende dieses Kapitels genauereingegangen

Im einfachsten Fall wird ein Subscriber Objekt ohne Parameter erstellt Dann wird nur eineNachrichtenqueue angelegt und es koumlnnen Topics mit subscribe(lsquotopicnamersquo) abonniert werden

34 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 38: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Listing 517 Subscriber abonniert ldquosome_topicrdquo

s = Subscriber()ssubscribe(some_topic)

Wird daraufhin die Methode publish() eines Objekts der Subscriber Klasse oder die Funktion pub-lish() des pubsub Moduls mit lsquotopicnamersquo als erstem Argument aufgerufen wird eine Nachrichtim Queue Objekt der entsprechenden Klasse hinterlegt

Die Grafik concept-pubsub soll dieses Konzept verdeutlichen Hier sind subscriber_A und sub-scriber_B Abonnenten des ldquotopic_Ardquo Wird nun im ersten Schritt publish() mit den Argumentenlsquotopic_Arsquo 12 lsquotestrsquo aufgerufen Dann wird im zweiten Schritt im Modul die die Zuordnung ausdem topics Dictionary gelesen das diese waumlhrend der Laufzeit speichert Hier hat ldquotopic_Ardquo dieSubscriber subscriber_A und subscriber_B Das Topic und die Argumente werden daraufhin in dieQueues der beiden Objekte gelegt

561 Automatisches Abonnieren von Topics

Listing 518 automatisches subscriben von Topics

1 class Subscriber2 def __init__(self name= autosubscribe=False)3 []4 if autosubscribe5 listen_to = [x for x y in self__class____dict__items()

rarr˓if6 (type(y) == FunctionType and xstartswith(on_

rarr˓))]

56 Inter-Process Communication 35

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 39: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

7 for l in listen_to8 selfsubscribe(lsplit(on_)[1])

Eine interessantere Anwendung ergibt sich wenn eine Subklasse von Subscriber erstellt und au-tosubscribe mit True aufgerufen wird wie in Codebeispiel automatisches subscriben von Topics(page 35) zu sehen In diesem Fall wird erst eine Liste mit allen Methoden erstellt deren Namemit ldquoon_rdquo beginnt (Zeile 5 und 6) Dann wird uumlber die Liste der gesammelten Namen iteriert dasldquoon_rdquo am Anfang wird abgeschnitten und der resultierende String wird als Topic abonniert

Damit besteht die Moumlglichkeit Methoden der Klassen direkt als Topics zu abonnieren und esentfaumlllt das haumlndische Zuordnen von Topics und Funktionsaufrufen

Als Beispiel hierzu dient die folgende Klasse AutoSub die sich von Subscriber ableitet

Listing 519 AutoSub Klasse

class AutoSub(Subscriber)def __init__(self)

Subscriber__init__(self autosubscribe=True)

def process_messages(self)if selfhas_messages()

topic args kwargs = selfget_message()try

f = getattr(self on_s topic)f(args kwargs)

36 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 40: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

except Exception as eloggererror(something went wrong when calling on_s s

rarr˓ (topic e))

def on_some_topic(self some_string some_int=1)print(some_string is s some_string)print(some_int is s some_int)

Die Subklasse mit einer Scheduling Methode wie der hier gezeigten process_messages() und deron_some_topic() Methode wuumlrde dann also automatisch das Thema ldquosome_topicrdquo abonnieren dahier eine Methode namens ldquoon_some_topicrdquo definiert wurde Wird dann eine Nachricht in diesemTopic abgelegt wuumlrde waumlhrend des Schedulings on_some_topic() mit den Argumenten aus derNachricht aufgerufen

In einer Python Shell sieht das ganze wie folgt aus

Listing 520 Benutzen der AutoSub Klasse

gtgtgt s = AutoSub()gtgtgt publish(some_topic teststring)Truegtgtgt sprocess_messages()some_string is teststringsome_int is 1

Somit ist es moumlglich in Subklassen von Subscriber abonnierte Topics direkt mit Methoden zuverknuumlpfen ohne dabei das Scheduling anpassen zu muumlssen

Das wird von den bereits erlaumluterten Klassen BitTorrentClient und XmppClient genutzt umNachrichten uumlber die entsprechenden Threads hinweg zu senden und zu empfangen

Eine Uumlbersicht uumlber alle Topics und deren Subscriber befindet sich im Anhang

57 Abschluss der Implementierung

571 Start Skript

Nachdem nun die wesentlichen Komponenten beschrieben wurden fehlt noch ein Skript dasdie Anwendung in der gewuumlnschten Konfiguration startet Hierfuumlr wurde das Skript bitweendpygeschrieben

Die Basiskonfiguration der Anwendung wird in einer Json Datei abgelegt die als ldquoconfjsonrdquo imVerzeichnis bitween gesucht wird oder falls dort nicht vorhanden im Home Verzeichnis desBenutzers unter dem Namen rdquobitweenjsonrdquo

Dann kann bitweend gestartet werden Hier hat man zusaumltzlich die Moumlglichkeit mit dem Argument

57 Abschluss der Implementierung 37

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 41: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

ldquondashdebugrdquo das Loglevel auf Debugausgaben zu setzen und die API mittels ldquondashportrdquo und ldquondashbindrdquo aneinen Port und IP Adresse zu binden Dies ist sinnvoll wenn das Programm auf einem entfern-ten Rechner laumluft und von auszligerhalb bedient werden soll da der Defaultwert fuumlr die IP Adresseldquolocalhostrdquo und die API damit nur fuumlr denselben Rechner erreichbar ist auf dem die Anwendunglaumluft

572 Cmd-Client

Auszligerdem wurde ein Kommandozeilenclient entworfen um die grundlegenden Funktionen derAnwendung zu bedienen Diese umfassen Pfade als Torrent freigeben gefundene Freigaben au-flisten und Freigaben anhand von Hashsummen downloaden Genutzt wird hierfuumlr die PythonLibary Requests um Befehle an die JSON-RPC API der Anwendung zu uumlbermitteln

573 setuppy

Um diese Anwendung mit den Python setuptools bzw dem Paketmanager pip installierbar zumachen wurde auszligerdem eine Datei setuppy im Wurzelverzeichnis des Projekts angelegt

Wie in Code Ausschnitt aus setuppy (page 38) zu sehen werden der Funktion setup() der Pythonsetuptools einige Informationen uumlber das Programm uumlbergeben

Listing 521 Ausschnitt aus setuppy

[]install_reqs = parse_requirements(requirementstxt session=False)

reqs = [str(irreq) for ir in install_reqs]

[]

setup(name=bitweenversion=001description=experimental XMPPBT Clientlong_description=readmeauthor=Jan Hartmannurl=httpsgithubcompuhoybitween license=licensepackages=find_packages(exclude=(tests docs))test_suite=testsentry_points=

console_scripts [bitweend=bitweenbitweendmainbitweenc=bitweenbitweencmain

]

38 Chapter 5 Implementierung

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 42: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

install_requires=reqs

)

Hier werden etwa die benoumltigten Python Pakete aus der Datei ldquorequirementstxtrdquo eingelesen Vari-ablen wie der Name des Programms die Version und der Autor Auszligerdem werden Entrypointsuumlbergeben ldquobitweendrdquo kann daraufhin nach der Installation ausgefuumlhrt werden und verweist aufdie Funktion main() im bitweend Skript Analog dazu wird ein Entrypoint fuumlr ldquobitweencrdquo angelegt

Die Installation kann dann mit dem Aufruf von ldquopip install -e pfadzumprojektrdquo erfolgen

574 Dokumentation

Fuumlr die gesamte Anwendung wurde Dokumentation in Form von Docstrings an allen FunktionenMethoden Modulen und Klassen verfasst Diese sind im reStructuredText Format gehalten

Um diese Dokumentation uumlbersichtlich dar zu stellen kann aus den Docstrings mit dem Dokumen-tationsgenerator Sphinx (wwwsphinx-docorg [Ove] (page 53)) eine Dokumentation in anderenFormaten wie HTML oder PDF erstellt werden

Die Konfiguration von Sphinx geschieht dabei uumlber die Datei confpy im Verzeichnis docs Mitdem Skript build_docssh im Wurzelverzeichnis des Projekts kann dann das automatisierte Er-stellen der benoumltigten Dokumentationsdateien angestoszligen werden Diese sind untereinander lo-gisch verkettet und koumlnnen so in spaumlteren Formaten wie HTML verlinkt werden

Auszligerdem wurde eine Datei indexrst geschrieben die als Einsprungpunkt in die automatischgenerierte Dateistruktur dient

575 Integration in andere Dienste

Dadurch dass dieses Projekt in Git versioniert und auf GitHub einem Git Hostingdienst entwick-elt wurde war es naheliegend darauf basierende weiterfuumlhrende Dienste zu benutzen So wurdendrei externe Dienste in dieses Projekt integriert

ReadTheDocs (readthedocsio [Wel] (page 53)) um automatisch Dokumentationen in HTMLaus den Docstrings des Programms zu erstellen und zu hosten Dabei wird nach jedemldquogit pushrdquo auf den Server ein Webhook ausgeloumlst der das Erstellen einer neuen Versionder Dokumentation antriggert Zu finden ist diese Dokumentation unter httpbitweenreadthedocsioendevelop und auf der beiliegenden CD

Travis-CI (travis-ciorg [puha] (page 54)) fuumlr automatisierte Unittests Diese werden ebenfallsper Webhook vom Server ausgeloumlst So wird jeder Commit automatisch getestet Auszligerdemwird eine History uumlber vergangene Tests gefuumlhrt

Coveralls (coverallsio [puhb] (page 54)) das die prozentuale Abdeckung des Codes durch dieTestfaumllle darstellt Dieser erhaumllt die Testabdeckung von Travis-CI nach jedem Test Auch

57 Abschluss der Implementierung 39

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 43: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

hier wird eine History bis auf die Ebene einzelner Dateien erstellt Auszligerdem wird grafischdargestellt welche Zeilen einer Datei ausgefuumlhrt wurden

40 Chapter 5 Implementierung

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 44: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 6

Beurteilung der Ergebnisse

Waumlhrend der Implementierung traten eine ganze Reihe an Problemen groumlszligerer und kleinerer Naturauf die so nicht erwartet wurden

61 Vor- und Nachteile der serverlosen Dateiuumlbertragung

Durch die serverlose Dateiuumlbertragung per BitTorrent umgeht man zwar potentiell langsameServer verliert aber auch einen ldquoMittelsmannrdquo fuumlr die Uumlbertragung Befinden sich beispielsweisebeide Teilnehmer hinter einem DSL Router muumlssen beide Techniken zum Port oumlffnen unterstuumltzen(oder manuell Ports oumlffnen) um eine Kommunikation in beide Richtungen zu ermoumlglichen Auszliger-dem muumlssen naumltuumlrlich beide Parteien dasselbe Protokoll sprechen Hat ein Teilnehmer eine IPv4Adresse und ein anderer eine IPv6 Adresse werden diese zwar gegenseitig ihre Torrentlisten er-halten Allerdings wird nie eine Datenuumlbertragung zustande kommen da diese vom XMPP Serveruumlbermittelt wird Zum Teil werden diese Probleme aufgefangen wenn sich die Teilnehmerzahlerhoumlht aber trotzdem werden die Uumlbertragungen aufgrund der Beschraumlnkung auf die bekanntenKontakte nie so reibungsfrei laufen wie ldquoechterdquo BitTorrent Dateiuumlbertragungen bei denen einTracker oder das Torrent Netz selbst andere Teilnehmer vermittelt und daher viel mehr Endpunktevorhanden sind

Aus diesem Grund ist der Erfolg dieser Art der Datenuumlbertragung zu einem gewissen Grad von derHomogenitaumlt und Funktionalitaumlt des genutzen Netzwerks der Teilnehmer abhaumlngig

Ebenfalls entfaumlllt mit einem Server eine Instanz bei der IP Adressen erfragt werden koumlnnen AlsErsatz kam hier ipgetter zum Einsatz das lediglich aus einer Reihe hinterlegter Server einen zufaumll-ligen auswaumlhlt und die IP erfragt Ist dieser Server nicht erreichbar kommt es hier zu Wartezeitenbeim Starten des Programms

41

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 45: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

62 libtorrent

Die libtorrent Libary die sich selbst als ldquofeature completerdquo [wwwc] (page 54) bezeichnet ist vorallem zu Beginn sehr unuumlbersichtlich Die Dokumentation bezieht sich auf die C++ Schnittstelleund verweist auch bezuumlglich der Python Bindings auf diese Dokumentation da alle Elementedieselben Bezeichnungen haben und aumlhnlich funktionieren Trotzdem wurde waumlhrend der Imple-mentierung zumindest eine Uumlbersicht der zu erwarteten Python Datentypen vermisst

Dazu kommt eine asynchrone Arbeitsweise bei der viele Funktionen nur Alerts ausloumlsen die danndas Ergebnis enthalten und die das Debugging und Tests erheblich verkomplizieren

Auszligerdem existieren Inkompatibilitaumlten zwischen den Versionen die in den Changelogs nicht ge-funden wurden So aumlndert sich beispielsweise die Codecerkennung bei Magnet Links zwischenVersion 01613 (in den Ubuntu 1404 Paketquellen) und Version 110 (zu diesem Zeitpunkt ak-tuell) Da hier keine Warnung gegeben wird sondern nur ein Torrent mit invalidem Hash an-gelegt wird war die Fehlersuche sehr zeitaufwaumlndig Zur Loumlsung wurden zwei Funktionen zumUmwandeln nach UTF-8 aus dem ebenfalls auf libtorrent aufbauenden BitTorrent Client Delugeuumlbernommen (siehe bitweencomponentsbthelperspy)

Auszligerdem exisiert fuumlr die libtorrent Installation kein Python Wheel das die vorkompilierte Libaryenthaumllt Der Nutzer ist hier darauf angewiesen entweder selbst zu kompilieren oder moumlglicher-weise alte Versionen zu nutzen die das Betriebssystem bereitstellt Auch das ist negativ zu wertenda es eine Huumlrde fuumlr unerfahrene Nutzer darstellt und somit die Verbreitung einschraumlnkt

63 XMPP Ansaumltze

Auch die Komplexitaumlt vom XMPP und seinen Erweiterungen ist nicht zu unterschaumltzen Es wurdeauf 2 Buumlcher zuruumlck gegriffen die beide einen Einstieg in XMPP geben und von denen einesauch ein Codebeispiel fuumlr SleekXMPP verfolgt jedoch wurde hier PEP nicht naumlher beleuchtetDaher bezog sich die genauere Recherche in den meisten Faumlllen auf die haumlufig sehr umfassendenProtokollspezifikationen

64 Threading

Waumlhrend des Testens war es auffaumlllig das sich die Anwendung in einigen nicht reproduzierbarenFaumlllen nicht komplett herunterfahren lieszlig Hier wurden die Threads des BitTorrent Client und derAPI Schnittstelle beendet jedoch lief der XMPP Client weiter Der Prozess musste in diesen Faumlllenvon Hand beendet werden Da die BitTorrent Komponente immer kontrolliert herunter gefahrenwurde wurden dabei aber alle zu speichernden Daten in die zugehoumlrige Datenbank geschriebensodass kein Datenverlust auftrat

42 Chapter 6 Beurteilung der Ergebnisse

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 46: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

641 Tests

Aufgrund der Tatsache dass hier ein Prototyp entwickelt wurde dessen Aufbau und Konzept sichunter Umstaumlnden noch haumlufig aumlndern wurden ausgiebige Unittests nur fuumlr die Datenmodelle unddie Inter-Process Communication implementiert Diese stellen eher statische Elemente dar diesich auch bei neuen Funktionen wenig aumlndern

Hierfuumlr wurde der Dienst Travis-CI [puha] (page 54) in das Git Repository des Projektes aufGitHub (httpsgithubcompuhoybitween [puhc] (page 54)) integriert Dieser fuumlhrt bei jedemneuen Commit des Codes mittels eines Webhooks automatische Unittests aus

Der Rest der Anwendung wurde manuell getestet Hierfuumlr wurden zwei Clients gestartet aufeinem zur Verfuumlgung stehenden Server mit installiertem Debian 8 und auf einem Ubuntu 1404bzw 1604 System hinter einem DSL Router bei aktiviertem UPNP

In den Tests wurde auf jeder Instanz eine Datei freigegeben und auf die jeweils andere Instanzuumlbertragen Die Tests beschraumlnkten sich in diesem Fall auf das IPv4 IPv6 konnte nicht getestetwerden

64 Threading 43

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 47: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

44 Chapter 6 Beurteilung der Ergebnisse

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 48: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 7

Ausblick

Diese erste Version der Anwendung schoumlpft bei weitem noch nicht das volle Potential derMoumlglichkeiten dieser Technik aus Es sind sowohl noch Probleme zu loumlsen als auch das Pro-gramm zu erweitern

So fehlt zur Zeit die Funktionalitaumlt um moumlgliche Fehler bei Uumlbertragungen zu erkennenEs muss etwa uumlberpruumlft werden ob mindestens zwei Teilnehmer dieselbe IP Versionverwenden oder ob der Client Probleme hatte Ports am Router zu oumlffnen In diesen Faumlllensollten an den Shares Hinweise verteilt werden sodass ein Client entscheiden kann welcheErgebnisse uumlberhaupt angezeigt oder mit Warnungen versehen werden Genauso solltenldquobevorzugterdquo Verbindungen implementiert werden Nutzen beide Teilnehmer einen vollenIPv4 und IPv6 Stack koumlnnte man Verbindungen standardmaumlszligig auf IPv6 starten um IPv4NAT zu umgehen

Auszligerdem werden die IPv4 Adressen in dieser Version ausschlieszliglich uumlber andere Server her-ausgefunden die die eigene oumlffentliche IP Adresse zuruumlckliefern Ist ein Server aus dieser Listenicht erreichbar wird lange auf ein Timeout der Verbindung gewartet bevor eine naumlchste Anfragegestellt wird Hier sollte man zusaumltzlich auf andere Techniken zuruumlckgreifen BitTorrent nutztbeispielsweise eine Technik um bei anderen Peers die IP Adresse zu erfragen Hierfuumlr sind natuumlr-lich andere Peers noumltig Der erste Kontakt in einer Nutzergruppe muumlsste also weiterhin andereTechniken nutzen

Andere moumlgliche Erweiterungen waumlren

bull grafischer Client mit Statistiken uumlber Up-Downloads

bull Kontrolllisten fuumlr Torrents nicht jeder Kontakt sollte alle Shares bekommen

bull ldquoBackup-Moderdquo alle Freigaben anderer Ressourcen des eigenen Accounts automatischdownloaden

bull ldquoWantedrdquo Listen Kontakte koumlnnen gesuchte Hashes als ldquoWantedrdquo publishen Werden diesevon anderen Kontakten gefunden werden diese downloaden und dem urspruumlnglich Suchen-den zur Verfuumlgung stellen

bull Usermanagementpasswortgeschuumltzter Login fuumlr die API

45

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 49: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

bull Implementierung einer nativen Python BitTorrent Bibliothek um fuumlr eine einfache Installa-tion nicht auf das vorkompilierte libtorrent angewiesen zu sein

46 Chapter 7 Ausblick

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 50: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 8

Zusammenfassung

In der Thesis wurde untersucht ob es sinnvoll ist Dateiuumlbertragungen des XMPP Protokolls Out-Of-Band uumlber das BitTorrent Protokoll abzuwickeln Dazu wurde ein XMPP und BitTorrent Cliententworfen und implementiert

Daraus zeigten sich neben einigen ldquoKinderkrankheitenrdquo dieser fruumlhen Version der Anwendungauch generelle Probleme dieser Art der Datenuumlbertragung Durch die serverlose Datenuumlbertragungfehlt hier eine Instanz die als Bindeglied zwischen den Clients dient Das hat zur Folge dass dieClients sehr genau konfiguriert sein muumlssen alle Teilnehmer muumlssen dasselbe Internet Protocolsprechen sowie gegebenenfalls die Ports am Router konfiguriert und Firewalls eingestellt werdenEin Server hingegen koumlnnte als Bruumlcke zwischen IPv4 und IPv6 dienen und uumlber holepunchingMethoden Ports oumlffnen

Der entfallende Server ist somit Vor- und Nachteil zugleich einerseits entfaumlllt hier zentrale In-frastruktur was das Netzwerk im Ganzen ausfallsicherer und schneller machen kann anderer-seits entfaumlllt auch ein ldquoAnsprechpartnerrdquo der Verbindungen vermittelt oder als Proxyserver dienenkann Demzufolge stellt die Datenuumlbertragung per BitTorrent in gut konfigurierter Umgebung eineVerbesserung gegenuumlber der Uumlbertragung uumlber Server dar fuumlr den Endanwender allerdings muumlsstedas Programm noch sehr viel mehr Funktionalitaumlt zur Fehlererkennung mitbringen um moumlglicheVerbindungsfehler aufzufangen

47

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 51: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

48 Chapter 8 Zusammenfassung

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 52: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 9

Anhaumlnge

91 Uumlbersicht der IPC Topics

92 Inhaltsverzeichnis der CD

bull website_snapshots Kopien der genutzten Webseiten

bull thesis Quellcode PDF-Version und HTML-Version der Thesis

bull bitween Quellcode und generierte API des Programms

bull pubsub_overviewpng Uumlbersicht der genutzten Topics und deren Abonnenten

Todo

bull Quellcode der Thesis

bull Thesis als PDF

bull Thesis als HTML

bull Quellcode des Programms

bull generierte API Docs HTML

bull Uumlbersicht der Topics und Abonnenten

bull

49

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 53: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

Fig 91 Uumlbersicht der Publisher Topics und Subscriber

50 Chapter 9 Anhaumlnge

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 54: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

CHAPTER 10

Literaturverzeichnis

References

101 Buumlcher

102 URLs

51

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 55: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

52 Chapter 10 Literaturverzeichnis

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 56: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Bibliography

[XMP16] Ref~citenum XMPPTheDefinitiveGuide p16

[XMP8] Ref~citenum XMPPTheDefinitiveGuide p8

[pro35] Ref~citenum professionalxmpp p35

[Mof10] Jack Moffitt Professional XMPP Programming with JavaScript and jQuery Wrox 2010ISBN 0470540710

[SAST09] Peter Saint-Andre Kevin Smith and Remko Tronccedilon XMPP The Definitive GuideBuilding Real-Time Applications with Jabber Technologies OrsquoReilly Media 2009 ISBN059652126X

[Ext] Extensible messaging and presence protocol (xmpp) corehttpsxmpporgrfcsrfc3920htmlbind (Accessed on 07212016)

[imo] Im observatory httpsxmppnetdirectoryphp (Accessed on 07072016)

[jab] Jabberxmpp server list httpwwwjabberesorgservers (Accessed on 07072016)

[Ove] Overview mdash sphinx 145 documentation httpwwwsphinx-docorgenstable (Accessedon 08182016)

[Sch] Scheduler mdash sleekxmpp httpsleekxmppcomapixmlstreamschedulerhtml (Accessedon 07182016)

[hit] Structuring your project mdash the hitchhikerrsquos guide to python httpdocspython-guideorgenlatestwritingstructure (Accessed on 07172016)

[Wel] Welcome to bitweenrsquos documentation mdash bitween documentationhttpbitweenreadthedocsioenlatest (Accessed on 08182016)

[fla] Welcome | flask (a python microframework) httpflaskpocooorg (Accessed on08112016)

53

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography
Page 57: Ein File-Sharing-Client auf Basis von XMPP und BitTorrent · to-Peer Protokoll BitTorrent (BT). XMPP dient hierbei nur noch dazu, die Daten weiter zu leiten, die für das Starten

Ein File-Sharing-Client auf Basis von XMPP und BitTorrent Release Bachelorarbeit

[XEPa] Xep-0115 entity capabilities httpxmpporgextensionsxep-0115html (Accessed on07262016)

[XEPb] Xep-0118 user tune httpxmpporgextensionsxep-0118html (Accessed on07262016)

[XEPc] Xep-0163 personal eventing protocol httpxmpporgextensionsxep-0163html (Ac-cessed on 07182016)

[XMPa] Xmpp | history of xmpp httpxmpporgabouthistoryhtml (Accessed on 07072016)

[XMPb] Xmpp | specifications httpxmpporgextensions (Accessed on 07262016)

[al4] Al45tair netifaces pull request 5 add support for retrieving ipv6 address flags onbsdmac-os mdash bitbucket httpsbitbucketorgal45tairnetifacespull-requests5add-support-for-retrieving-ipv6-addressdiff (Accessed on 07182016)

[puha] Puhoybitween - travis ci httpstravis-ciorgpuhoybitween (Accessed on 08172016)

[puhb] Puhoybitween | coveralls - test coverage history amp statisticshttpscoverallsiogithubpuhoybitween (Accessed on 08182016)

[puhc] Puhoybitween a somewhat experimental xmppbittorrent clienthttpsgithubcompuhoybitween (Accessed on 08182016)

[wwwa] Wwwbittorrentorgbepsbep_0003html httpwwwbittorrentorgbepsbep_0003html(Accessed on 07252016)

[wwwb] Wwwbittorrentorgbepsbep_0009html httpwwwbittorrentorgbepsbep_0009html(Accessed on 07272016)

[wwwc] Wwwlibtorrentorg httpwwwlibtorrentorg (Accessed on 08152016)

54 Bibliography

  • Abstract
  • Einleitung
  • Planung
    • Anforderungen
    • Konzept
      • Zusammenhaumlnge und Grundlagen
        • XMPP
        • BitTorrent
          • Implementierung
            • Allgemeines zur Implementierung
            • Entwurf
            • BitTorrent
            • XMPP
            • Web
            • Inter-Process Communication
            • Abschluss der Implementierung
              • Beurteilung der Ergebnisse
                • Vor- und Nachteile der serverlosen Dateiuumlbertragung
                • libtorrent
                • XMPP Ansaumltze
                • Threading
                  • Ausblick
                  • Zusammenfassung
                  • Anhaumlnge
                    • Uumlbersicht der IPC Topics
                    • Inhaltsverzeichnis der CD
                      • Literaturverzeichnis
                        • Buumlcher
                        • URLs
                          • Bibliography