ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/docs/pws2004/freenet.pod
Revision: 1.2
Committed: Wed May 12 20:09:11 2004 UTC (22 years, 5 months ago) by root
Branch: MAIN
Changes since 1.1: +566 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 Freenet - Informationsfreiheit ohne Zensur, aber mit Perl
2    
3     =head2 Abstract
4    
5 root 1.2 Das Freenet-Projekt (http://www.freenetproject.org) hat es sich zur
6     Aufgabe gemacht, jedem die die Möglichkeit freier Meinungsäußerung zu
7     garantieren. Neben den Implementation einer Lösung für dieses Problem
8     geht es in diesem Artikel darum, wie man in Perl selbst Informationen
9     herunterlädt bzw. veröffentlicht.
10    
11     =head1 Einführung
12    
13     Das Freenet-Projekt (http://www.freenetproject.org) hat es sich zur
14     Aufgabe gemacht, jedem die die Möglichkeit freier Meinungsäußerung
15     zu garantieren. Als Mittel zur Umsetzung hat es ein virtuelles Netzwerk
16     gewählt, in dem es nicht realistisch möglich sein wird, Einspeisung
17     von neuen Daten zu verhindern oder den Urheber von Veröffentlichungen
18     ausfindig zu machen, solange er dies nicht selbst zugibt. Darüberhinaus
19     ist es für Betreiber von Freenet-Knoten nicht möglich, zu wissen, was
20     auf ihrer Festplatte gespeichert wurde oder wo die Daten herstammen, so
21     daß es ab einer bestimmten Netzwerkgröße nicht mehr möglich ist,
22     dem Betreiber einer Freenet-Node nachzuweisen, daß er illegale Inhalte
23     besitzt bzw. weitergegeben hat oder davon gewusst hat.
24    
25     In China beispielsweise wird eine frühe Version von Freenet für ein
26     rein chinesisches Freenet-Netzwerk aktiv benutzt, um politische Inhalte
27     verbreiten zu können ohne Maßnahmen von der Regierung zu befürchten.
28    
29     =head2 Freenet für den Benutzer
30    
31     Freenet speichert nur relativ kleine Dokumente (<1MB) am Stück. Diese
32     Dokumente können beliebige Daten enthalten, z.B. HTML-Seiten. Dise
33     Datenblöcke können mit einem für jeden Block eindeutigen Schlüssel
34     abgerufen werden, z.B. in einem Web-Browser.
35    
36     Hier ist ein Beispiel für eine solche HTML-Seite:
37    
38     freenet1.png
39    
40     Die hier verwendete URL ist C<http://129.13.162.73:8888/SSK@Sc6qV~D6iFhaYord6HtbjJ8MaEYPAgM/YoYo//Controversy.html>.
41     C<http://129.13.162.73:8888> ist die Adresse meines Freenet-Daemons,
42     üblicherweise C<http://127.0.0.1:8888>, der Sicherheit wegen sollte man
43     immer einen eigenen Freenet-Daemon laufen lassen. Der Schlüssel der
44     "Freesite" ist C<SSK@Sc6qV~D6iFhaYord6HtbjJ8MaEYPAgM> und in dieser wird
45     wiederum das Unterdokument C<YoYo//Controversy.html> angezeigt.
46    
47     Diese Seite ist Teil eines sehr bekannten Einsprungpunktes ins
48     Freenet. Generell bevorzugt das Freenet-Projekt keine bestimmten
49     Einsprungpunkte. Die Regel ist: kennt man den Einsprungpunkt nicht, findet
50     man die Inhalte nicht; es ist sogar unmöglich zu bestimmten, wieviel oder
51     welche Informationen im Freenet gespeichert sind: Ein Index a'la google
52     ist prinzipbedingt nicht möglich.
53    
54     Obwohl es einige Freenet-Spider und Directory-Freesites gibt ist der
55     überwältigende Teil der Information im Freenet nicht darüber zu
56     erreichen.
57    
58     Neben HTML-Inhalten gibt es auch Mail-, Foren- und Chat-Systeme im
59     Freenet.
60    
61     Die Einspeisung von Daten kann von überall im Netz
62     geschehen. Mehrfacheinspeisung ist möglich (und meistens notwendig) und
63     erhöht führt nicht zur Dupliziering von Daten.
64    
65     Natürlic gibts es auch einige Nachteile, die teilweise mit dem Design
66     und teilweise mit der Implementierung zusammenhängen. So ist der einzige
67     verfügbare Freenet-Daemon in Java implementiert und daher leider extrem
68     unportabel (läuft praktisch nur auf Linux/x86 und Windows, da das
69     benötige Sun-Java-JDK auf andreen Platformen nicht verfügbar oder
70     veraltet ist), sehr langsam und vor allem Speicherhungrig, und häufig
71     auch sehr instabil.
72    
73     Die aktuellen Versionen des Freenet-Daemons sind alle als "nicht sicher"
74     deklariert, da erst die Release 1.0 verspricht, alle Ideen umgesetzt zu
75     haben, wovon das Projekt noch 0.5 Versionen entfernt ist :)
76    
77     Designbedingt ist das Freenet eher langsam (extrem hohe Latenz,
78     akzeptabler Durchsatz) und für interkative Benutzung teilweise
79     ungeeignet, bzw. eine echte Geduldsprobe.
80    
81     Durch die Art der Speicherung kann nicht garantiert werden daß
82     Informationen überhaupt wiedergefunden werden. "Unpopuläre" Information
83     verschwindet, sofern sie nicht regelmäßig eingespeist oder abgerufen
84     wird, automatisch wieder aus dem Freenet.
85    
86     =head2 Die Freenet-Architektur
87    
88     Herkömmliche File-Sharing-Netzwerke haben zwei Große Nachteile: Entweder
89     sind sie nicht wirklich anonym (selbst anonymisierende Netzwerke oder
90     Proxies sind üblicherweise nicht vor Zugriff durch Regierungen sicher
91     (ein bekanntes Beispiel ist I<JAP>, C<http://anon.inf.tu-dresden.de>, das
92     zwar vollmundig vollkommene Anonymität garantiert aber bekanntermaßen
93     von der Polizei überwacht wird und Log-Informationen regelmäßig an
94     diese weitergibt, wozu die Betreiber nach deutschen Recht verpflichtet
95     sind). Oder sie skalieren nicht, da sie Broadcast-Algorithmen benutzen
96     die größere Netzwerke von vorneherein ausschließen (bekanntes Beispiel
97     dafür ist I<gnutella>).
98    
99     Das erste Problem umgeht Freenet (Achtung, vereinfacht!), indem es
100     jeden Datenblock hasht und aus diesem Hash einen Schlüssel für die
101     Verschlüsselung generiert und die Daten damit verschlüsselt (sic).
102    
103     Der Schlüssel wird ein zweitesmal gehasht. Dieser Hash wird zur
104     eindeutigen ID des Datenblocks. Diese ID und der verschlüsselte
105     Datenblock werden ins Freenet eingespeist. Dabei, wird immer derselbe
106     Key generiert (da er nur von den Daten abhängt) und der verschlüsselte
107     Block ist ebenfalls immer gleich. Daher kann er problemlos mehrfach und
108     von unterschiedlichen Parteien eingespeist werden ohne die Daten faktisch
109     mehrfach im Freenet abzulegen.
110    
111     Das ist sicher, da ein kryptographisch sicherer Hash (der die Grundlage
112     des Systems bilden muß) nur in eine Richtung funktioniert: Aus der ID
113     (== Hash des Hashes der Daten) kann nicht auf den Schlüssel geschlossen
114     werden. Speichert also ein Netzknoten die Daten und die ID dazu, kann man
115     die Daten zwar abrufen, jedoch nicht entschlüsseln. Selbst der Besitzer
116     eines Knotens kann mit vollkommenen Wissen über alle Vorgänge seines
117     Knotens die Inhalte nicht lesen.
118    
119     Eine weitere Konsequenz dieses Verfahrens ist die Tatsache, das Dokumente
120     niemals verändetr werden können: eine Änderung bewirkt eine Änderung
121     des Schlüssels und damit eine neue ID, praktisch eine völlig neue URL.
122    
123     Möchte man z.B. das grüne Blatt der Freesite "Thought Crime" herunterladen so
124     wird man mit folgendem Freenet-Key konfrontiert:
125    
126     CHK@pfAv9IejYPLQwaTLXDguEkUhiNUMAwI,blzDbhN~8Q28esq4JrfRWw
127    
128     C<CHK> steht für I<Content-Hash-Key>, der häufigste Schlüsseltyp im
129     Freenet, der das oben beschriebene Verfahren benutzt. Der CHK besteht
130     aus zwei Teilen: der ID, unter der der Schlüssel im Freenet abgelegt
131     wird (C<pfAv9IejYPLQwaTLXDguEkUhiNUMAwI>) und dem Schlüssel, mit dem die
132     Daten verschlüsselt wurden (C<blzDbhN~8Q28esq4JrfRWw>), durch ein Komma
133     getrennt.
134    
135     Das sind übrigens (mehr oder weniger) base64-encodete Daten, dekodiert
136     sieht der Schlüssel so aus:
137    
138     CHK@
139     ID = a5f02ff487a360f2d0c1a4cb5c382e12452188d50c0302
140     Key = 6e5cc36e137ef10dbc7acab826b7d15b
141    
142     (Man kann daraus tatsächlich ablesen, das der Datenblock 4k groß (0x0c
143     am Ende der ID bedeutet 2**12) ist und Twofish benutzt. Aber derartige
144     Details überläßt man lieber einem Perl-Modul).
145    
146     Nur der erste Teil wird als Anfrage ins Freenet geschickt, der zweite Teil
147     bleibt im lokalen Freenet-Daemon. Wird nun der Datenblock geliefert, kann
148     er mit dem Schlüssel dekodiert werden und wird an den Benutzer geliefert.
149    
150     Das zweite Problem (der Skalierbarkeit) wird durch lineare
151     statt exponentielle Suche gelöst: mit jeder Anfrage wird eine
152     I<Hops-To-Live>-Angabe (HTL, ähnlich wie das TTL in IPv4)
153     verknüpft. Diese Zahl, die üblicherweise zwischen 5 und 25 (maximal)
154     liegt, gibt an, wie viele Knoten die Anfrage maximal weitergeleitet
155     wird. Jeder Knoten, der die Daten nicht lokal vorrätig hat, leitet sie an
156     denjenigen Knoten weiter, der die Daten am wahrscheinlichsten hat. Da das
157     Verfahren linear ist und nicht exponentiell, skaliert es ebenfalls linear
158     mit der Netzwerkgröße.
159    
160     Lädt man das Dokument, wird man mit Metadaten und "normalen" Daten
161     konfrontiert.
162    
163     Metadaten:
164    
165     Revision=1
166     EndPart
167     Document
168     Info.Format=image/png
169     End
170    
171     Daten:
172    
173     PNG^Z...
174    
175     Nun stellt sich die Frage, wie man sicherstellt, daß Daten im Freenet
176     bleiben, da es nur endliche Speicherkapazität hat. Die Antwort ist
177     überraschend: Es geht nicht. Wenn ein Knoten sich entscheidet, Daten
178     zu löschen oder Platz für neue Daten zu schaffen, gehen zwangsläufig
179     andere Daten verloren. Dagegen hilft nur wiederholtes Einfügen und der
180     Wunsch, daß die eigenen Daten beliebt genug sind, damit sie abgerufen
181     werden und damit länger überleben.
182    
183     Absolute Anonymität und nichtnachvollziehbarkeit von Transaktionen ist
184     eben nicht vereinbar mit garantierter Datenspeicherung. Könnte man
185     garantiert Nachweisen, das ein Dokument existiert, so wäre es für
186     einen Knotenbetreiber schlecht möglich, Wissen über die Art der Daten
187     abzustreiten, die er speichert.
188    
189     =head3 SSK-Schlüssel
190    
191     Der zweite gebräuchliche Schlüsseltyp, mit dem man im Freenet
192     konfrontiert wird, ist ein C<SSK>-Schlüssel (C<SSK> steht für I<Signed
193     Subspace Key>). Hier ist einer:
194    
195     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM
196    
197     Zwei Dinge unterscheiden Sie von CHK-Schlüsseln:
198    
199     Erstens ist ein SSK-Schlüssel eigentlich ein Schlüsselpaar, ein
200     Schlüssel (der private Schlüssel) muss für das Einfügen von Daten
201     benutzt werden, der zweite Schlüssel (der öffentliche Key) wird für
202     das Auslesen der Daten benutzt. Da die Daten signiert sind, kann nur der
203     oder die Besitzer des privaten Schlüssels Daten unter diesem einfügen,
204     während die Besitzer des öffentlichen Schlüssels überprüfen könenn,
205     ob die Daten tatsächlich mit dme richtigen Schlüssel signiert wurden.
206    
207     Zweitens ist die ID, unter dem diese Date abgelegt werden, nicht von den
208     Daten sondern nur vom "Namen" (dem Key) abhängig, man kann also URIs
209     erzeugen auf Dateien, die noch nicht eingefügt wurden.
210    
211     Diese Art Schlüssel ist relativ ineffizient und kann keine großen
212     Datenmengen speichern, SSKs werden also vorwiegend für Weiterleitungen
213     auf CHKs benutzt.
214    
215     Der obige SSK gehört übrigens zur "Freenet Explained"-Freesite, die die
216     einzelnen Schlüsseltypen (und mehr) erklärt. Finden kann man sie hier:
217    
218     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//
219    
220     bzw., wenn man einen Freenet-Daemon am Laufen hat, hier:
221    
222     http://127.0.0.1:8888/SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//
223    
224     =head1 Und das ganze in Perl
225    
226     Das ganze wäre relativ witzlos, wenn man nur irgendwelche
227     langweiligen Tools und/oder Java benutzen kann. Es gibt
228     zwei Perl-Module (bzw. Modulfamilien), C<Net::Freenet::FCP>
229     (C<http://www.sf.net/projects/perlfcp>) und C<Net::FCP>.
230    
231     Ersteres ist älter (und vielleicht besser benannt) und konzentriert
232     sich mehr auf die Verarbeitung von Metadaten, ist aber recht schwach
233     beim eigentlichen Protokoll-Handling. Letzteres ist sehr gut beim
234     Protokoll-Handling und stark beim Kodieren und Dekodieren von Daten,
235     überläßt das Metadatenhandling aber dem Programmierer.
236    
237     C<Net::FCP> stammt von mir und ist entstanden, weil ich das andere Modul,
238     die es nur im Freenet gab, nicht herunterladen konnte (tja, so ist das
239     eben als Freenetter). Daher gehe ich auch nur auf dieses Module ein :)
240    
241     =head2 Installation
242    
243     Zuerst braucht man einen Freenet-Daemon
244     (http://www.freenetproject.org/). Die Installation ist unglaublich komplex
245     (unter Windows gibt es einen Installer, unter Unix ein paar Skripte). Der
246     Daemon braucht eine Weile, bis er warm wird (Minuten bis Stunden), was man
247     durch Surf-Versuche unterstützen sollte.
248    
249     Das C<Net::FCP>-Paket gibt es ganz normal per CPAN.
250    
251     =head2 Einfache Abfragen
252    
253     Die Abkürzung I<FCP> steht für I<Freenet Client Protocol> und ist das
254     Protokoll zwischen Freenet-Anwedungen und dem Freenet-Daemon. Es ist
255     unglaublich ineffizient und noch dazu nicht verschlüsselt. Dies ist der
256     Grund für die Empfehlung, den Daemon nur auf dem lokalen Rechner laufen
257     zu lassen: Wäre dumm, wenn man aus dem hochsicheren Freenet über eine
258     ungesicherte Internetverbindung die Windows-Sourcen herunterlädt und
259     sicher erwischen läßt (ist alles schon vorgekommen)...
260    
261     In Perl geht dies denkbar einfach:
262    
263     use Net::FCP;
264     my $fcp = new Net::FCP;
265    
266     Man kann dem Konstruktor von C<Net::FCP> direkt Namen und Port des
267     Freenet-Daemons übergeben. Üblicherweise holt er sich diese aber aus dne
268     Environment-Variablen C<FREDHOST> und C<FREDPORT>, die auf C<127.0.0.1>
269     bzw. C<8481> defaulten.
270    
271     Übrigens wird nur eine virtuelle Verbindung aufgebaut. Möchte man
272     sicherstellen, daß tatsächlich ein Daemon erreichbar ist, kann man einen
273     C<client_hello>-Request ausführen oder einfach loslegen.
274    
275     Im Normalfall heißt das also:: no configuration required.
276    
277     Hat man ein C<Net::FCP>-Objekt, kann man schon alle Requests durchführen,
278     die man amchen möchte:
279    
280     my ($meta, $data) = @{ $fcp->client_get (
281     "freenet:SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//"
282     15
283     ) };
284    
285     Der C<client_get>-Request erwartet zwei Argumente: eine Freenet-URI
286     (C<< freenet:<freenet-schlüssel> >>) und eine HTL. Letztere muss man
287     nicht angeben, man sollte es aber, und vor allem sollte man dem Benutzer
288     die Wahl der HTL überlassen. Das dritte, optionale, Argument ist für
289     spezielle Anwendungen: am besten ignorieren.
290    
291     Als Ergebnis erhält man immer eine Array-Referenz mit den Metadaten
292     und den Daten. Immer. Sollte ein Fehler auftreten wird eine Exception
293     ausgelöst (auf Perl: das Modul C<die>d). C<eval {}> hilft also im
294     Zweifelsfalle, für einfache Anwendungen ist das aber overkill.
295    
296     Bricht das Programm ab, so sieht das folgendermaßen aus:
297    
298     Net::FCP::Exception<<short_data,reason:unexpected eof or internal node error>>
299    
300     Oder, wenn die Daten nicht gefunden wurden:
301    
302     Net::FCP::Exception<<data_not_found,>>
303    
304     Letzteres bedeutet übrigens nicht aufgeben, sondern nochmal versuchen,
305     z.B. mit einer höheren HTL. Ein fehlgeschlagener Versuch mit hoher HTL
306     bedeutet imemr noch nicht aufgeben. Daemons in der "Nähe" wissen nun,
307     das die Daten verlangt werden. Nach einiger Zeit ist es wahrscheinlich,
308     das die Daten auf einmal in der Nähe liegen: daher nie aufgeben, nochmal
309     probieren. Niemand hat behauptet, man bekäme die Daten einfach aus dem
310     Freenet wieder heraus...
311    
312     Die Metadaten sind als Textdokument gespeichert. das Parsen dieser
313     Metadaten ist aber relativ krank, weshalb das Perl-Modul einen Hash mit
314     den geparsten Daten liefert.
315    
316     Die Metadaten und Daten kann man ausgeben:
317    
318     use Data::Dumper;
319     print STDERR Dumper $meta;
320     print $data;
321    
322     Dies ist genau der Quelltext für das "Tool" C<eg/fetch1>, mit dem man
323     I<einen> Freenet-Datenblock herunterladen kann.
324    
325     Ich benutze es üblicherweise so:
326    
327     eg/fetch1 SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3// >data
328    
329     Das schreibt die Daten in eine Datei und gibt gleichzeitig dessen
330     Metadaten aus.
331    
332     Für den Key C<SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//> ergibt dies:
333    
334     'version' => { 'revision' => '1' },
335     'document' => [
336     {
337     'info' => { 'format' => 'image/png' },
338     'redirect' => { 'target' => 'freenet:CHK@pMKWiJyE3t-ZWvL1W9VdZvB3jcIKAwI,7pdyQiW7Hp9-8fEp-25C2w' },
339     'name' => 'activelink.png'
340     },
341     {
342     'info' => { 'format' => 'text/plain' },
343     'redirect' => { 'target' => 'freenet:CHK@2hewSY-I5ZhWpJ84dwhPbtdlvyIKAwI,ovcsrpD79xZfoW2021z91w' },
344     'name' => 'description.txt'
345     },
346     {
347     'info' => { 'format' => 'text/html' },
348     'redirect' => { 'target' => 'freenet:CHK@kME~NY2lX3q-em40ExTAFkyr~NkQAwI,3T2hFmTrPbLhCBANdy4OkA' },
349     'name' => 'index.html'
350     },
351     {
352     'info' => { 'format' => 'text/html' },
353     'redirect' => { 'target' => 'freenet:SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/4' },
354     'name' => '.next'
355     },
356     {
357     'info' => { 'format' => 'text/html' },
358     'redirect' => { 'target' => 'freenet:CHK@kME~NY2lX3q-em40ExTAFkyr~NkQAwI,3T2hFmTrPbLhCBANdy4OkA' }
359     }
360     ],
361     'raw' => 'Version
362     Revision=1
363     [... gekürzt...]
364     Info.Format=text/html
365     End
366     '
367     };
368    
369     Die eigentlichen Daten sind leer (Null Byte gross), das Dokument enthät
370     also nur Metadaten! Man beachte vor allem die teilweise recht tiefe
371     Verschachtelung.
372    
373     Der Key C<< $metadata->{raw} >> enthält die Metadaten, wie sie vom
374     Freenet kamen. Dies ist notwendig, da man manchmal die Metadaten
375     zum Prüfen in der exkaten Form benötigt, wie sie hochgeladen
376     wurden. Ansonsten kann man sie ignorieren.
377    
378     Der Key C<< $metadata->{document} >> enthält Informationen über das
379     Dokument oder in diesem Fall die Dokumente: Ein Hash pro Dokument. Schaut
380     man sich den Inhalt an (ein Array), so sieht man in jedem Hash ein
381     C<name>-Key, der den Namen des Subdokuments angibt (bis auf den letzten,
382     darauf komme ich gleich).
383    
384     Schaut man sich dir Freenet-URIs dieser Freesite an, so sieht man
385     derartige URIs:
386    
387     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3// # Hauptseite
388     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//activelink.png # Icon
389     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//description.txt # Beschreibung für Spider
390    
391     Wenn diese Dokumente mit C<client_get> anfordert, bekommt man immer obiges
392     Dokument. Freenet ignoriert nämlich alles, was hinter dem C<//> steht
393     und liefert daher immer das gleiche Dokument aus dem SSK-Bereich. (Darauf
394     verlassen soltle man sich nicht unbedingt, in Zukunft reagiert der
395     Freenet-Daemon vielleicht anders. Als Freenetter hat mans eben nicht
396     leicht).
397    
398     Der Teil hinter den beiden Slashes (C<//>) ist nun das Unterdokument, das
399     man über den Namen identifizieren kann:
400    
401     $activelink = grep $_->{name} eq "activelink.png",
402     @{ $metadata->{document} };
403    
404     Fehlet der C<name>-Eintrag ist es der Eintrag mit dem leeren Namen, in
405     diesem Fall der erste Link, der nichts nach den C<//> stehen hat. Der
406     C<name>-Key I<kann> vorhanden und leer sein: Freenet überprüft die Daten
407     nicht, daher gibt es durchaus unterschiedliche Auslegungen für das genau
408     Format.
409    
410     Die Metadaten sind etwas genauer in dem *hüstel* etwas veralteten
411     *hüstel* I<Freenet Explained>-Dokument beschrieben.
412    
413     Möchte man nun das C<activelink.png> herunterladen muss man in C<<
414     $activelink->{redirect} >> nachsehen. Meistens verweist dies auf ein
415     C<CHK>-Schlüssel. Letztere sind sozusagen Allgemeingut: jeder kann
416     sie benutzen, und da sie nicht änderbar sind, kann sie auch niemand
417     fälschen, daher muss man sie nicht signieren.
418    
419     Auf C<< $activelink->{info}{format} > sollte man sich übrigens nicht
420     verlassen.
421    
422     Und sollte kein C<redirect>-Key vorhanden sein, so ist das Dokument im
423     mitgelieferten Datenblock. Alles ganz logisch, einfach, und klar, wie man
424     sieht.
425    
426     Egal, der CHK-Key für C<activelink.png> liefert folgendes:
427    
428     'version' => { 'revision' => '1' },
429    
430     Und die Daten stellen ein PNG dar. Naja, nicht gerade üppig, die
431     Metadaten, aber man hätt's ja im Link auf dieses Dokument sehen
432     können. Als Freenetter hat mans nicht leicht.
433    
434     Aber mit diesen Erklärungen kann man schon einfacher Freenet-Spider
435     bauen. Die wichtigsten Tools sind veraltete und spärliche Dokumente
436     wie I<Freenet Explained> und Tools wie C<Data::Dumper>. "Veraltet" ist
437     übrigens nicht immer schlecht, da viele Dokumente auch alt sind oder sich
438     eh' nicht exakt an den "Standard" halten. Mit der Zeit wird hier sicher
439     eine Besserung eintreten.
440    
441     =head2 Methoden des Freesite-Managements
442    
443     Oder: "Wenn man Inhalte nicht mehr verändern kann, wie verändert man
444     sie?"
445    
446     Die offensichtliche Methode ist: "Man macht sie veränderbar". In
447     der Freenet-Gemeinde geistert seit langer Zeit der Mythos des
448     I<TUK>-Schlüssels, des I<Time Updatable Keys>. Diese Schlüssel tauchen
449     immer auf, wenn jemand über veränderbare Schlüssel spricht. Leider
450     weiss niemand, wie man sie implementieren soll, und ganz persönlich
451     fürchte ich, es wird niemals veränderbare Keys geben.
452    
453     =head3 "Editions"
454    
455     Die nächstliegende Methode nutzt die Eigenschaft von SSKs (genauer:
456     redirects) aus, das man den Namen sofort generieren kann, den Inhalt aber
457     erst später einfügt.
458    
459     Dies nutzt man aus, indem man I<Editionen> herausgibt und
460     durchnummeriert. Jede Edition enthält einen Link auf die nächste. Bis
461     man die nächste Edition einfügt, wird der Link-Inhalt nicht gefunden.
462    
463     Üblicherweise benutzt man in HTML ein C<IMG>-Element mit Link auf ein
464     Bild aus der nächsten Edition. Sieht man das Bild, weiss man, die
465     nächste Edition existiert und kann sich hinklicken.
466    
467     I<Freenet Explained> benutzt diese Methode. Der Link auf Edition 4 lautet:
468    
469     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/4// # Link-Ziel
470     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/4//activelink.png # IMG-SRC
471    
472     Beides existierte nicht als ich diesen Artikel schrieb (bzw. Freenet
473     konnte es nicht finden :). Wenn eine neue Edition heruasgegeben werden
474     soll, fügt der Autor einfach einen neuen Datenblock mit vielen Redirects
475     unter obigem SSK-Key ein.
476    
477     Ein C<.next>-Eintrag ist ebenfalls vorhanden: manche Spider folgen diesem
478     und können auf diese Weise immer die aktuelle Edition anzeigen, sofern
479     sie häufig genug scannen.
480    
481     Editionen sind einfach für den Autor einer Freesite und erfordern
482     keine spezielle Unterstützung. In der Benutzung sind sie allerdings
483     umständlich und häufige Updates sind auch nicht effizient.
484    
485     Daher hat sich eine zweite Methode entwickelt, die gerade bei häufig
486     geänderten Inhalten besser funktioniert:
487    
488     =head3 "Date Based Redirects"
489    
490     Freesites, die "Date Based Redirects" benutzen (kurz "DBR-Sites")
491     funktionieren ähnlich wie Editionen-basierte Freesites, nur wird statt
492     einer fortlaufenden Nummer die aktuelle Zeit benutzt.
493    
494     Die Freesite I<The Freenet Help Index>
495     (C<SSK@rjYFfgPHfolmcStiaoxESFfBXz8PAgM/FreenetHelp//>) benutzt diese
496     Methode. Folgende Metadaten wurden dazu hinterlegt:
497    
498     'version' => { 'revision' => '1' },
499     'document' => [
500     { 'date_redirect' => {
501     'increment' => '15180',
502     'target' => 'SSK@rjYFfgPHfolmcStiaoxESFfBXz8PAgM/FreenetHelp'
503     }
504     }
505     ],
506    
507     Statt einem einfachen C<redirect> gibt es jetzt einen
508     C<date_redirect>-Eintrag, und darin ein C<target> (dürfte bekannt sein)
509     und der Key C<increment>. Letzterer darf wie üblich fehlen, man sollte
510     dann C<86400> annehmen (ein Tag hat 86400 Sekunden). In diesem Beispiel
511     wird 86400 genommen (Hexadezimal 15180).
512    
513     Habe ich eigentlich schon erwähnt das jede Zahl im FCP-Protokoll oder
514     im Freenet hexadezimal kodiert wird? Also, praktisch immer, außer wenn
515     es mal nicht so ist. Und wozu man einen Offset addiert ist mir auch
516     schleierhaft. In der freien Wildbahn habe ich sowieso noch keinen gesehen.
517    
518     Der Link in C<target> ist nicht vollständig (unter anderem fehlt
519     hinten ein C<//>). Der komplette Link wird generiert, "indem die
520     aktuelle Zeit (POSIX-Zeit, üblicherweise das, was C<time> liefert),
521     auf C<increment>-Schritte gerundet und C<offset> addiert, als
522     Big-Endian-Hexadezimalzahl nach dem ersten Slash mit folgendem
523     Minuszeichen eingefügt wird."
524    
525     Und jetzt in Perl - zum Verstehen:
526    
527     my $doc = $metadata->{document][0]; # Oder [1] oder ...
528    
529     my $increment = (hex $doc->{increment}) || 86400;
530     my $offset = (hex $doc->{offset}) || 0;
531     my $target = $doc->{target} || die;
532    
533     my ($head, $tail) = split /\//, $target, 2;
534    
535     my $NOW = time;
536     my $time = $NOW - $NOW % $increment + $offset;
537    
538     my $result = sprintf "%s/%x-%s", $head, $time, $tail;
539    
540     Für "jetzt" (C<time() == 1084388445>) liefert der Algorithmus folgenden Link:
541    
542     SSK@rjYFfgPHfolmcStiaoxESFfBXz8PAgM/40a16900-FreenetHelp
543    
544     Und tatsächlich, unter diesem Key findet man wieder ein Dokument mit
545     vielen Redirects.
546    
547     DBRs haben den Vorteil, "automatisch" aktuell zu sein. Solange man nur
548     Redirects einfügt, ist die Belastung durch neue das Einfügen vieler
549     neuer Daten gering, Freenet kommt damit zurecht und löscht alte DBRs
550     bei Bedarf automatisch (ohne natürlich zu wissen, das sich in dne
551     Datenblöcken DBRs befinden, dnen die kann ja niemand dekodieren,d er
552     nicht den Schlüssel besitzt).
553    
554     Der Nachteil ist, das man eine aktuelle Uhrzeit braucht um die Site zu
555     finden. Schlimemr noch: die Freesite muss regelmäßig neu eingefügt
556     werden, eben alle C<increment> Sekunden.
557    
558     DBR-Freesites, die nicht mehr maintained werden, verschwinden deshalb fast
559     sofort, solange man nicht einen Zeitpunkt kennt, zu dem sie noch (bzw.
560     schon!) existierte.
561    
562     All dieses I<sollte> eigentlich in einem Metadata-Modul stattfinden. So
563     weit bin ich aber nicht, da mein Hauptziel das effiziente Herunterladen
564     großer Dateien ist.
565    
566     Womit ich beim Thema wäre.
567    
568     =head1 Effizient herunterladen
569    
570     =head1 Inserts
571 root 1.1
572