rss feed articles activities all_comments

indeedgeek.de

Florian Eitel

1. Advent: Planung und Design

Nachdem gestern Aaron eine gute Projekteinführung gegeben hat, will ich heute versuchen die Architektur etwas zu definieren.

Wir haben nun unser Problem definiert und die Anforderungen an das Programm erfasst. Der nächste elementare Schritt muss die Suche nach bestehenden Programmen sein. Oftmals existiert bereits ein Programm was ein ähnliches Problem löst oder zumindest Teile abdeckt. Durch Open Source ist es oftmals einfacher sich in ein bestehendes Projekt einzubringen. Je nach Projekt reicht es schon die Ideen zu formulieren oder einige Patches einzureichen und schon ist das ursprüngliche Problem gelöst.

Und warum dann der Adventskalender? – Selbstverständlich haben auch wir uns auf dem “Markt” umgeschaut. Wir suchen ein Programm mit dem man möglichst einfach eine Datei an jemand anderen senden kann. Wenn man sich allerdings BitTorrent, Jabber oder FTP anschaut verfolgen diese meist eine andere Philosophie. Deshalb haben wir uns doch für eine neue Implementierung entschieden.

Ok können wir jetzt programmieren? – Noch nicht ganz. Gerade im Umfeld der proprietären Software ist es gang und gäbe, dass man sich einen Client herunterlädt und dann tut dieser auf magische Weise irgend etwas (naja oder halt meistens auch nicht). Was hinter der (werbegefüllten) Oberfläche geschieht ist nicht erkennbar. Dies wird gemacht um den User an das jeweilige Programm zu binden. Es ist dadurch nicht möglich eine alternative Oberfläche zu bauen welche ebenfalls funktioniert. Für den User hat dies ausschließlich Nachteile. Deshalb ist es gerade im Open Source Bereich wichtig ein Protokoll möglichst gut zu beschreiben. So gibt man auch anderen die Möglichkeit Alternativen und Verbesserungen zu bauen. Möchte man zum Beispiel ein Programm auf ein anderes Betriebssystem portieren kann man einfach das Protokoll durcharbeiten und man muss dazu nicht das ursprüngliche Programm verstehen.

Gut, ran ans Protokoll! – Fast, da wir das Rad nicht neu erfinden wollen schauen wir erst einmal was es schon gibt. Vielleicht können wir XMPP oder HTTP zum Austausch verwenden. Dann würde das Protokoll sehr einfach werden, da man sich auf bestehende Implementierungen verlassen kann. Zudem muss man sich eventuell um Aspekte wie Sicherheit und Portabilität nicht kümmern. Und als wichtiger Punkt: Eventuell kann man Programme die das Protokoll sowieso implementieren verwenden. Würden wir zum Beispiel die Dateien über HTTP frei geben, könnte man auf sie auch mit einem Webbrowser zugreifen. Unser Programm würde nur einen alternativen, passenderen Weg anbieten. Aber sollte jemand unser Programm nicht haben gäbe es noch eine Alternative.

Und was nehmen wir nun? – Wir haben uns gegen ein fertiges Protokoll entschieden. Grund dafür ist vor allem die kurze Implementierungszeit. Trotz aller Vorteile von bestehenden Protokollen erfordern sie Einarbeitungszeit. Zudem passen sie vielleicht nicht ganz auf das Problem und man muss unter Umständen einige Umwege gehen. Für ein längerfristiges Projekt lohnt es sich aber sicher intensiver verschiedene bestehende Protokolle zu evaluieren. Man möchte oftmals im weiteren Verlauf mehr Features in seinem Client haben. Würden wir zum Beispiel noch Chat zwischen den Nutzern als Feature mit aufnehmen könnten wir schon fast XMPP eins zu eins verwenden.

Dann ans Protokoll definieren! – Jup, los gehts. Wir wollen Daten senden. Der Sender muss also sehen wer alles Daten empfangen kann und der Empfänger muss dem entsprechend auch auf einkommende Daten warten. Zudem können wir nicht einfach die Daten übers Netzwerk senden. Wir möchten sicher gehen, dass die Daten auch wirklich vom Empfänger kommen und nicht manipuliert wurden. Zudem sollen die Daten eventuell verschlüsselt übertragen werden und auch ausschließlich beim richtigen Sender ankommen.

Somit haben wir neben den eigentlichen Datenstrom eine Reihe von zusätzlichen Metadaten. Schaut man sich FTP an, wird dies ganz gut deutlich. Dort gibt es zwei Verbindungen. Über die eine gehen die Informationen wie Dateinamen, Größe, Rechte, etc und über den anderen Kanal die eigentlichen Nutzdaten. Unser Protokoll ist nicht ganz so komplex wie FTP aber dennoch ist es sinnvoll die Daten zu trennen damit der Empfänger sehen kann was man ihm eigentlich senden möchte. Er kann nun anhand der Metainformationen entscheiden ob er die Datei annimmt oder nicht.

Puh, das hört sich schwerer an als erwartet! – Eins nach dem anderen: Im ersten Schritt muss der Sender sehen welche Clients Dateien empfangen können. Dieser Schritt nennt sich Discovery und ist in vielen Protokollen vorhanden. Die Alternative wäre ein manuelles Eingeben zum Beispiel der IP-Adresse. Das ist einmal lästig und da wir uns erst einmal auf das lokale Netz beschränken ein bisschen zuviel des Guten. Daniel hat in den letzten Kommentaren schon Bonjour ins Gespräch gebracht. Bonjour ist eine Apple Implementierung der Zeroconf Protokollfamilie. Diese ist dafür gedacht einen Rechner einfach ans Netzwerk anzustöpseln und schon geht alles ohne Konfiguration. Dabei möchte man auf eine zentrale Infrastruktur wie DHCP- oder DNS-Server verzichten. Die einzelnen Rechner sollen sich einfach untereinander austauschen. Dazu gehört einmal das aushandeln einer IP-Adresse. Zudem werden über Multicast Anfragen DNS-Namen von Rechnern aufgelöst. Und was mir persönlich am besten gefällt: Es gibt auch die Möglichkeit sich alle verfügbaren Dienste auflisten zu lassen. So kann man sich in ein fremdes LAN einstecken und sieht so welche Drucker angeboten werden, welche Dateiserver oder auch mit wem man chatten kann.

Wir nehmen uns das Discovery heraus und publizieren darüber, dass wir zum Empfang von Dateien bereit sind. Dieser Teil nennt sich DNS-Service Discovery. Etwas näher werden wir uns die Funktionsweise nächste Woche anschauen. Neben der Apple Bonjour Implementierung existiert für Linux eine fast noch bessere Implementierung namens avahi die meistens bereits vorinstalliert ist.

Der Sender findet den passenden Empfänger und schickt diesem eine Nachricht mit den Metainformationen der Datei. Die Informationen wollen wir als JSON-Format versenden. Sicher könnte man hier auch Anderes wie XML verwenden aber im Grunde bleibt sich das relativ gleich. Wir mögen JSON weil es so schön einfach und erweiterbar ist. Sender und Empfänger einigen sich nun auf einen zweiten Port und darüber wird die Datei versendet.

Ich hoffe das nachfolgende Diagramm macht das noch etwas deutlicher.

Image 1. Protokoll-Entwurf.

Um sicherzustellen, dass unser Protokoll erweiterbar ist haben wir einige Maßnahmen vorgesehen: Zum einen hat der Client eine API-Version durch die der Server eventuell ein älteres Protokoll sprechen kann. Zudem sind alle Informationen wie die Daten beim Send-File oder beim Discovery beliebig erweiterbar. Auch ein Feld wie “supported mode” gibt an welche Verschlüsselungen der Client überhaupt unterstützt.

So viel Text und immer noch kein Code! (jaja ich habs nicht so mit kurz fassen…) – Wir haben das Protokoll spezifiziert nun kann es aber endlich ans Programmieren gehen. Wir werden das gesamte Projekt in Ruby implementieren. Ruby ist vielleicht nicht die beste Sprache aber es lässt sich schöner, kompakter und vor allem lesbarer Code darin schreiben. Zudem gibt es viele Bibliotheken die einem Arbeit abnehmen. Wie Julian in den letzten Kommentaren schon angemerkt hat, wäre es schön wenn wir es auf möglichst vielen Plattformen zum laufen bringen können. Da aber weder Aaron noch ich das nötige Wissen, die nötige Motivation und die entsprechenden Nerven haben um für Windows zu entwickeln beschränken wir uns primär auf Linux. Wir werden aber nächste Woche die genaue API und eine erste Implementierung fertig haben. Ihr seit dann gerne eingeladen eine Alternative Implementierung zum Beispiel für Mac zu starten.

Soweit für diese Woche. Wir machen uns nun ans Implementieren. Fragen und Anregungen bitte einfach in die Kommentare.

Comments:

(howto comment?)