<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sixserv blog &#187; Torrent</title>
	<atom:link href="http://sixserv.org/tag/torrent/feed/" rel="self" type="application/rss+xml" />
	<link>http://sixserv.org</link>
	<description>A Blog about Linux, Networking, Development and Security.</description>
	<lastBuildDate>Tue, 27 Jul 2010 16:45:57 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>implementing bittorrent &#8211; DHT  (teil 3)</title>
		<link>http://sixserv.org/2009/10/02/implementing-bittorrent-dht-teil-3/</link>
		<comments>http://sixserv.org/2009/10/02/implementing-bittorrent-dht-teil-3/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 16:35:16 +0000</pubDate>
		<dc:creator>nks</dc:creator>
				<category><![CDATA[Torrent]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[dht]]></category>
		<category><![CDATA[distributed hash table]]></category>
		<category><![CDATA[hash tale]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[p2p]]></category>

		<guid isPermaLink="false">http://sixserv.org/?p=466</guid>
		<description><![CDATA[<img src="/wp-content/themes/6stheme/icons/icon_bittorrent.png" width="50" height="51" alt="" title="Torrent" /><br/>Eigentlich wollte ich ja was über den BitTorrent Message-Flow schreiben, aber aus aktuellem Anlass gibt es heute einen "kleinen" Artikel über DHT.

DHT

Aus gegebenem Anlass schreibe ich nun etwas früher als geplant über DHT. Die ThePirateBay-Tracker sind nun schon etwas länger Down, es sind zwar etliche Ersatz-Tracker aus dem Boden gesprießt, aber meiner Meinung nach ist das dezentrale Tracking nun an der Reihe. Die Tracker waren bis jetzt einer der grössten Angriffs/Schwachpunkte der BitTorrent Technologie/ des BitTorrent Protokolls.
Doch das muss nicht so sein, denn es gibt ja DHT (BEP005). Ich will mich hier mal etwas näher mit DHT beschäftigen und das DHT Protokoll näher erklären.

Die Technologie hinter DHT im BitTorrent-Protokoll basiert auf Kademlia. Kademlia wurde von Petar Maymounkov und David Mazières entwickelt und "implementiert" bzw spezifiziert Distributed Hastables in P2P-Netzen. Verschaffen wir uns erstmal einen kleinen Überblick über Kademlia.

BEP005 spezifiziert das die Daten per UDP übertragen werden. Zuerst generiert der Client eine Node ID, diese wird genauso wie der BitTorrent Infohash errechnet, bzw nutzt den selben Bit-raum (160Bit). Danach beginnt das Bootstrapping, der Client muss sich ja erstmal im DHT zurechtfinden und einen anderen Client finden dieser Teilt dann weitere IPs mit. Meist ist die erste Node "router.bittorrent.com" da ein Scannen durch die eigene IP-Range oder willkürliches suchen nach anderen Nodes nicht so erfolgversprechend ist.
Zur Indizierung von BitTorrent-Hashes wie es ein Tracker macht trägt bei DHT jeder Peer/Node bei.
Wenn wir nun einen bestimmten Hash suchen kann die Entfernung zu diesem Hash ausgerechnet werden. Dafür werden entweder Node IDs und Node IDs verglichen, oder Infohashes und Node IDs, durch den "Algorithmus" lässt sich die "nähe" der Node ID zur gesuchten ID (Infohash oder Node ID) errechnen. Die Routing Tabelle die der Client nun erstellt wird immer detaillierter je näher wir an den gesuchten ID-Wert kommen und die Node mit der gewünschten Information gefunden haben. Jede Node hat "Kontaktdaten" zu den Nodes mit "nahen" IDs.]]></description>
			<content:encoded><![CDATA[<img src="/wp-content/themes/6stheme/icons/icon_bittorrent.png" width="50" height="51" alt="" title="Torrent" /><br/><p>Eigentlich wollte ich ja was über den BitTorrent Message-Flow schreiben, aber aus aktuellem Anlass gibt es heute einen &#8220;kleinen&#8221; Artikel über DHT.</p>
<p><strong>DHT</strong></p>
<p>Aus gegebenem Anlass schreibe ich nun etwas früher als geplant über DHT. Die ThePirateBay-Tracker sind nun schon etwas länger Down, es sind zwar etliche Ersatz-Tracker aus dem Boden gesprossen, aber meiner Meinung nach ist das dezentrale Tracking nun an der Reihe. Die Tracker waren bis jetzt einer der grössten Angriffs/Schwachpunkte der BitTorrent Technologie/ des BitTorrent Protokolls.<br />
Doch das muss nicht so sein, denn es gibt ja DHT (<a href="http://bittorrent.org/beps/bep_0005.html">BEP005</a>).  Ich will mich hier mal etwas näher mit DHT beschäftigen und das DHT Protokoll näher erklären.</p>
<p>Die Technologie hinter DHT im BitTorrent-Protokoll basiert auf Kademlia. Kademlia wurde von Petar Maymounkov und David Mazières entwickelt und &#8220;implementiert&#8221; bzw spezifiziert Distributed Hashtables in P2P-Netzen. Verschaffen wir uns erstmal einen kleinen Überblick über Kademlia.</p>
<p>BEP005 spezifiziert das die Daten per UDP übertragen werden. Zuerst generiert der Client eine Node ID, diese wird genauso wie der BitTorrent Infohash errechnet, bzw nutzt den selben Bit-raum (160Bit). Danach beginnt das Bootstrapping, der Client muss sich ja erstmal im DHT zurechtfinden und einen anderen Client finden dieser Teilt dann weitere IPs mit. Meist ist die erste Node &#8220;router.bittorrent.com&#8221; da ein Scannen durch die eigene IP-Range oder willkürliches suchen nach anderen Nodes nicht so erfolgversprechend ist.<br />
Zur Indizierung von BitTorrent-Hashes wie es ein Tracker macht trägt bei DHT jeder Peer/Node bei.<br />
Wenn wir nun einen bestimmten Hash suchen kann die Entfernung zu diesem Hash ausgerechnet werden. Dafür werden entweder Node IDs und Node IDs verglichen, oder Infohashes und Node IDs, durch den &#8220;Algorithmus&#8221; lässt sich die &#8220;nähe&#8221; der Node ID zur gesuchten ID (Infohash oder Node ID) errechnen. Die Routing Tabelle die der Client nun erstellt wird immer detaillierter je näher wir an den gesuchten ID-Wert kommen und die Node mit der gewünschten Information gefunden haben. Jede Node hat &#8220;Kontaktdaten&#8221; zu den Nodes mit &#8220;nahen&#8221; IDs.</p>
<p>Die Distanz zwischen 2 IDs wird per XOR berechnet:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">distanz<span style="color: #7a0874; font-weight: bold;">&#40;</span>A,B<span style="color: #7a0874; font-weight: bold;">&#41;</span> = <span style="color: #000000; font-weight: bold;">|</span>A xor B<span style="color: #000000; font-weight: bold;">|</span></pre></div></div>

<p>Je kleiner das Ergebnis desto näher Liegen sich A und B.</p>
<p>Wenn nun eine Node (im DHT) Peers (für BitTorrent) finden will passiert folgendes:<br />
Ich gehe davon aus das das Bootstrapping schon fertig ist, wir also ein  Paar Nodes schon in unserer Routing-Tabelle haben. Unser Client nimmt nun den Infohash aus der Torrent-File.  Wir nehmen Beispielsweise den Hash<br />
<strong> 362b0a1151013916896a9c98b52e0ead803c4ac3</strong> (ubuntu-7.10-alternate-hppa.iso). Unser Client wird die Node mit dem  geringstem Abstand zum Infohash nun Kontaktieren und diese Node nach  Peer-Kontaktdaten Fragen. Wenn diese Node Peer-Kontaktdaten besitzt werden diese zu unserem Client übermittelt und dieser baut dann über das BitTorrent-Protokoll eine Verbindung zum Peer auf. Wenn die Node keine Peer-Kontaktdaten hat wird sie uns Kontaktdaten zu den Nodes aus ihrer Routing-Tabelle geben die am Nächsten an unserer ID liegen, und so weiter und so fort! <img src='http://sixserv.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Die Antwort der Nodes auf die Anfrage nach Peers zu einem Infohash beinhaltet immer einen &#8220;token&#8221;. Wenn wir nun dem Node von dem wir die Peer-Kontaktdaten bekommen haben mitteilen wollen (wie beim Tracker ein sogenannter &#8220;announce&#8221;), müssen wir dem Node neben dem Announce auch den Token schicken den wir zuvor<br />
von ihm erhalten haben.<br />
Es liegt auf der Hand das dies eine Sicherheitsmaßnahme ist, damit nicht irgendwelche unbekannten Hosts (Bots von der MI) den DHT verseuchen. Die BEP005 spezifiziert das die Tokens alle 5 Minuten neu generiert  werden, sie bestehen aus einem SHA1-Hashes auf die IP Adresse verknüpft mit einem Salt (welches alle 5 Minuten wechselt).</p>
<p><strong>Routing</strong><br />
Kommen wir nun zum Aufbau der Routing Tabelle unseres Nodes. Die Routing Tabelle ist beinhaltet alle Bekannten Nodes die noch errechbar sind (das wird in einem Zeitraum von 15 Minuten getan) und diese Nodes dienen als Startpunkte für neue anfragen im DHT.</p>
<p>Die Nodes in unserer Routing Tabelle werden je nach ihrer Erreichbarkeit eingestuft. Die Erreichbarkeit jeder Node wird alle 15 Minuten überprüft. Eine Node wird als &#8220;good&#8221; eingestuft wenn sie uns eine Anfrage geschickt oder beantwortet hat innerhalb der letzten 15 Minuten. Wenn eine Node innerhalb von 15 Minuten nicht aktiv war wird sie  &#8220;questionable&#8221; also Fragwürdig eingestuft. Ein Node wird als &#8220;bad&#8221; eingestuft wenn er auf mehrere Anfragen nicht geantwortet hat. Unsere Routing-Tabelle sollte nur &#8220;good&#8221;-Einträge enthalten.</p>
<p>Die Routing Tabelle deckt den kompletten Raum an möglichen IDs ab (von 0 bis zu 2^160). Die Routing-Tabelle ist in &#8220;Buckets&#8221; (Eimer) unterteilt. Eine leere Routing-Tabelle enthält einen Bucket mit dem ID-Raum von 0 (min) bis 2^169 (max). Wenn wir nun eine Node mit der hypothetischen ID &#8220;A&#8221; (normal ist die ID natürlich 20byte lang wie beim Infohash) dann wird diese in einen Bucket eingefügt der min &lt; A &lt; max ist. Also in einem Bereich bei dem<br />
min kleiner als A ist und A kleiner als max <img src='http://sixserv.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
In einer leeren Routing-Tabelle ist nur ein Bucket also passen in diesen Bucket alle möglichen IDs rein. Allerdings kann ein Bucket nur K verschiedene Einträge enthalten, im Moment ist K=8. Wenn der Bucket voll mit &#8220;good&#8221;-Nodes ist, werden keine Nodes mehr hinzugefügt &#8211; AUßER die eigene Node ID fällt in den Bereich, in diesem Fall wird der Bucket durch zwei neue Buckets ersetzt und die Nodes aus dem Vorherigem Bucket werden auf die zwei neuen Buckets aufgeteilt. Diese zwei Buckets könnten bei einer Routing-Tabelle mit nur einem Bucket dann jeweils die Bereiche vor und nach unserer ID abdecken (min/max werte).</p>
<p>Jeder Bucket sollte (das ist natürlich jedem selbst überlassen, wenn man es denn Implementiert) eine &#8220;last changed&#8221; Eigenschaft haben um die &#8220;frische&#8221; des Buckets ablesen zu können. Auch hier sollte alle 15 Minuten die Erreichbarkeit der enthaltenen Nodes überprüft werden. Laut BEP005 wird dies folgendermaßen gemacht:<br />
Eine zufällig ausgewählte ID aus dem Bereich des Buckets (min/max) wird mit einer &#8220;find_nodes&#8221; (dazu weiter unten im Protokoll-Bereich mehr) Anfrage kontaktiert &#8211; bei Antwort ist die Node noch zu gebrauchen, wenn<br />
nicht sollte die Node aus dem Bucket entfernt werden. Wenn eine Node Anfragen von anderen Nodes nicht beantworten kann, z.B. wegen schlechten Router-Settings, dann sollte Sie ihre Buckets öfter Auffrischen als eine Node die auf Anfragen antworten kann, den eine solche Node erhält ja eh immer wieder neue Node IDs.<br />
Die Node sollte zudem versuchen ihr selbst nahe liegende Nodes zu finden.</p>
<p><strong>BitTorrent Protokoll</strong></p>
<p>Wenn unser BitTorrent-Client DHT unterstützt, wird bei den Protokoll-Flags im Handshake das letzte Byte gesetzt. Wenn nun ein anderer Peer uns beim Handshake das er DHT Supported, senden wir ihm mit der PORT-Message des BitTorrent-Protokolls unseren UDP-Port auf dem unsere DHT-Implementierung lauscht. Die DHT-Implementierung Pingt dann die neue Node und wenn eine Antwort kommt wird diese nach den oben definierten Regeln in einen Bucket eingefügt oder auch nicht (bei keiner Antwort).</p>
<p><strong>Torrent File</strong></p>
<p>Die Torrent-File enthält keine &#8220;announce&#8221;-URL mehr, sondern einen &#8220;nodes&#8221;-Key. Dieses Nodes Dictionary enthält die K (K=8) nähsten bekannten Nodes von dem Client der die .torrent-File erstellt hat. Oder halt eine Liste mit K  bekannten &#8220;good&#8221;-Nodes. Das Nodes-Dictionary ist wie folgt aufgebaut:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">nodes = <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;&quot;</span>,<span style="color: #7a0874; font-weight: bold;">&#93;</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;&quot;</span>,<span style="color: #7a0874; font-weight: bold;">&#93;</span>, ...<span style="color: #7a0874; font-weight: bold;">&#93;</span>
nodes = <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;127.0.0.1&quot;</span>, <span style="color: #000000;">6881</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;your.router.node&quot;</span>, <span style="color: #000000;">4804</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p><strong>Protokolle</strong></p>
<p><strong>Kademlia RPC Protololl</strong></p>
<p>KRPC ist relativ schnelle und einfach erklärt. Die Einzelnen Messages sind wie bei BitTorrent üblich BEncoded. Auf einen Request kommt eine Antwort/Response. Es gibt drei Message-Typen: query, reponse und error.<br />
Beim DHT-Protokoll sind es vier: ping, find_node, get_peers und announce_peer. Eine KPRC-Message besteht aus einem Dictionary mit zwei Keys, sowie zusätzlich je nach Message-Typ zusätzliche Felder.<br />
Der Key &#8220;t&#8221; beinhaltet die &#8220;transaction id&#8221;, die &#8220;tansaction id&#8221; wird beim Query errechnet und dient dazu Anfragen und Antworten zuzuordnen. Sie besteht meistens nur aus 2 Buchstaben, da diese vollkommen ausreichen um eine große Anzahl von Anfragen abzudecken.<br />
Der andere Key ist &#8220;y&#8221; und beinhaltet als Wert nur einen einzigen Buchstaben:</p>
<ul>
<li> q: query</li>
<li>r: response</li>
<li>e: error</li>
</ul>
<p>Um die Kontaktdaten von Peers zu übertragen werden diese  Kodiert. Hier kommt die selbe Kodierung wie beim Compact-Encoding bei BitTorrent zum Einsatz, ein 6-Byte String &#8211; wobei die ersten 4 Byte die IP repräsentieren und die letzten 2 den Port.<br />
Um die Kontaktdaten von anderen Nodes zu übertragen werden diese ebenfalls Kodiert, dies geschieht jedoch mit dem &#8220;Compact Node Encoding&#8221;. Hier ist es ein 26-Byte String. Die ersten 20byte enthalten die Node ID die restlichen 6 sind die Compact-Encodierte IP und der Port wie oben.</p>
<p><strong>Queries/Anfragen</strong><br />
Der &#8220;y&#8221; Key enthält als Wert &#8220;q&#8221; wie weiter oben schon erklärt. Zusätzlich noch die die zwei Keys &#8220;a&#8221; und &#8220;q&#8221;.</p>
<ul>
<li> q: enthält den Methodennamen des Queries (DHT Protokoll z.B. Ping)</li>
<li> a: enthält die Argumente</li>
</ul>
<p><strong>Responses/Antworten</strong><br />
Der &#8220;y&#8221; Key enthält hier den Wert &#8220;r&#8221; für Response.<br />
Zusätzlich enthält diese Message den Key &#8220;r&#8221;:</p>
<ul>
<li> r: ist ein Dictionary mit den Ergebnissen der Anfrage</li>
</ul>
<p><strong>Errors/Fehler</strong><br />
Der &#8220;y&#8221; Key enthält den Key &#8220;e&#8221; für Error.</p>
<ul>
<li> e: enthält eine Liste:
<ul>
<li>das erste Element der Liste enthält den Fehler Code</li>
<li>das zweite Element die Fehlermeldung</li>
</ul>
</li>
</ul>
<p>Mögliche Fehler und ihre Entsprechenden Messages:</p>
<table border="1px">
<tbody>
<tr>
<th>Code</th>
<th>Beschreibung</th>
</tr>
<tr>
<th>201</th>
<th>Generic Error</th>
</tr>
<tr>
<th>202</th>
<th>Server Error</th>
</tr>
<tr>
<th>203</th>
<th>Protocol Error, such as a malformed packet, invalid arguments, or bad token</th>
</tr>
<tr>
<th>204</th>
<th>Method Unknown</th>
</tr>
</tbody>
</table>
<p>Beispielhaftes Error Packet aus BEP005:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">generic error = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;e&quot;</span>, <span style="color: #ff0000;">&quot;e&quot;</span>:<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">201</span>, <span style="color: #ff0000;">&quot;A Generic Error Ocurred&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:eli201e23:A Generic Error Ocurrede1:t2:aa1:y1:ee</pre></div></div>

<p><strong>DHT Queries</strong></p>
<p>Bei den DHT Anfragen enthält jeder Query einen &#8220;id&#8221;-Dictionary als Argument, neben etwaigen anderen Argumenten, welcher die Node ID der anfragenden Node beinhaltet (20-Byte String in Network Byte<br />
Order) die Antworten enthalten natürlich die Node ID der antwortenden Node.</p>
<p>Hier die Möglichen Queries:</p>
<p><strong>ping</strong><br />
Der Key &#8220;q&#8221; für den Query-Typ beinhaltet hier den Wert &#8220;ping&#8221;. Der Key &#8220;a&#8221; für die Argumente enthält einen Dictionary mit dem Key &#8220;id&#8221; und als Wert wie oben schon erklärt die Node ID in Network Byte Order.</p>
<p>Example Packets aus BEP005:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">ping</span> Query = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;q&quot;</span>, <span style="color: #ff0000;">&quot;q&quot;</span>:<span style="color: #ff0000;">&quot;ping&quot;</span>, <span style="color: #ff0000;">&quot;a&quot;</span>:<span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;abcdefghij0123456789&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:ad2:id20:abcdefghij0123456789e1:q4:ping1:t2:aa1:y1:qe
&nbsp;
Response = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;r&quot;</span>, <span style="color: #ff0000;">&quot;r&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;mnopqrstuvwxyz123456&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re</pre></div></div>

<p><strong>find_node:</strong><br />
Dieser Query wird benutzt um die Kontaktinformationen zu einer bestimmten Node anhand ihrer ID herauszufinden. Der &#8220;q&#8221;-Key enthält hier logischerweise &#8220;find_node&#8221;.<br />
Die Argumente im &#8220;a&#8221;-Key enthalten wie immer die eigene Node ID und hier noch das Target-Dictionary welches folgende Keys enthält:</p>
<ul>
<li>&#8220;target&#8221;: 	ID der gesuchten Node</li>
</ul>
<p>Als Antwort auf einen &#8220;find_node&#8221;-Query sollte die Antwort einen Key namens &#8220;nodes&#8221; enthalten der die Compact-Encoded-Node Informationen der gesuchten Node oder 8 (K) der nähsten bekannten &#8220;good&#8221;-Nodes enthalten.</p>
<p>Beispiel aus BEP005:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">find_node Query =<span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;q&quot;</span>, <span style="color: #ff0000;">&quot;q&quot;</span>:<span style="color: #ff0000;">&quot;find_node&quot;</span>,<span style="color: #ff0000;">&quot;a&quot;</span>:<span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;abcdefghij0123456789&quot;</span>,<span style="color: #ff0000;">&quot;target&quot;</span>:<span style="color: #ff0000;">&quot;mnopqrstuvwxyz123456&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:ad2:id20:abcdefghij01234567896:target20:mnopqrstuvwxyz123456e1:q9:find_node1:t2:aa1:y1:qe
&nbsp;
Response = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;r&quot;</span>, <span style="color: #ff0000;">&quot;r&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;0123456789abcdefghij&quot;</span>, <span style="color: #ff0000;">&quot;nodes&quot;</span>: <span style="color: #ff0000;">&quot;def456...&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:rd2:id20:0123456789abcdefghij5:nodes9:def456...e1:t2:aa1:y1:re</pre></div></div>

<p><strong>get_peers:</strong><br />
Mit diesem Query erhält man Peers für den Torrent Download. &#8220;q&#8221; entspricht hier &#8220;get_peers&#8221;. Die Argumente sind &#8220;id&#8221; mit der Node ID und &#8220;info_hash&#8221; mit dem Infohash des Torrents. Die Antwort enthält den Key &#8220;values&#8221; der eine Liste von Strings enthält die entweder Compact-Encoded IP der Peers enthält, oder wenn keine Peers bekannt sind: einen Key &#8220;nodes&#8221; der eine Liste mit 8 (K) Nodes im Compact-Encoded Format enthält. In jedem Fall wird bei der Antwort ein Key &#8220;token&#8221; übertragen (der Token wird bei einem &#8220;announce&#8221; gebraucht).</p>
<p>Beispiele aus BEP005:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">get_peers Query = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;q&quot;</span>, <span style="color: #ff0000;">&quot;q&quot;</span>:<span style="color: #ff0000;">&quot;get_peers&quot;</span>, <span style="color: #ff0000;">&quot;a&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;abcdefghij0123456789&quot;</span>, <span style="color: #ff0000;">&quot;info_hash&quot;</span>:<span style="color: #ff0000;">&quot;mnopqrstuvwxyz123456&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz123456e1:q9:get_peers1:t2:aa1:y1:qe
&nbsp;
Response with peers = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;r&quot;</span>, <span style="color: #ff0000;">&quot;r&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;abcdefghij0123456789&quot;</span>, <span style="color: #ff0000;">&quot;token&quot;</span>:<span style="color: #ff0000;">&quot;aoeusnth&quot;</span>, <span style="color: #ff0000;">&quot;values&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">&quot;axje.u&quot;</span>, <span style="color: #ff0000;">&quot;idhtnm&quot;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:rd2:id20:abcdefghij01234567895:token8:aoeusnth6:valuesl6:axje.u6:idhtnmee1:t2:aa1:y1:re
&nbsp;
Response with closest nodes = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;r&quot;</span>, <span style="color: #ff0000;">&quot;r&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;abcdefghij0123456789&quot;</span>, <span style="color: #ff0000;">&quot;token&quot;</span>:<span style="color: #ff0000;">&quot;aoeusnth&quot;</span>, <span style="color: #ff0000;">&quot;nodes&quot;</span>: <span style="color: #ff0000;">&quot;def456...&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:rd2:id20:abcdefghij01234567895:nodes9:def456...5:token8:aoeusnthe1:t2:aa1:y1:re</pre></div></div>

<p><strong>announce_peer:</strong><br />
Der &#8220;q&#8221; Key enthält logischerweise den String &#8220;announce_peer&#8221;. Dazu kommen noch 4 Argumente in &#8220;a&#8221;, die da wären:</p>
<ul>
<li> id: Node ID</li>
<li> info_hash: Infohash des Torrents</li>
<li> port: BitTorrent Client Port (zb 6881)</li>
<li> token: der token der beim vorherigem query nach peers vomentsprechendem Node gesendet wurde (dem Node welches usn die Peers geschickt hat)</li>
</ul>
<p>Beispiel aus BEP005:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">announce_peers Query = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;q&quot;</span>, <span style="color: #ff0000;">&quot;q&quot;</span>:<span style="color: #ff0000;">&quot;announce_peer&quot;</span>, <span style="color: #ff0000;">&quot;a&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;abcdefghij0123456789&quot;</span>, <span style="color: #ff0000;">&quot;info_hash&quot;</span>:<span style="color: #ff0000;">&quot;mnopqrstuvwxyz123456&quot;</span>, <span style="color: #ff0000;">&quot;port&quot;</span>: <span style="color: #000000;">6881</span>, <span style="color: #ff0000;">&quot;token&quot;</span>: <span style="color: #ff0000;">&quot;aoeusnth&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:ad2:id20:abcdefghij01234567899:info_hash20:mnopqrstuvwxyz1234564:porti6881e5:token8:aoeusnthe1:q13:announce_peer1:t2:aa1:y1:qe
&nbsp;
Response = <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;t&quot;</span>:<span style="color: #ff0000;">&quot;aa&quot;</span>, <span style="color: #ff0000;">&quot;y&quot;</span>:<span style="color: #ff0000;">&quot;r&quot;</span>, <span style="color: #ff0000;">&quot;r&quot;</span>: <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;id&quot;</span>:<span style="color: #ff0000;">&quot;mnopqrstuvwxyz123456&quot;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>
bencoded = d1:rd2:id20:mnopqrstuvwxyz123456e1:t2:aa1:y1:re</pre></div></div>

<p>Ich hoffe das war ein Verständlicher &#8220;kleiner&#8221; Überblick uber DHT im BitTorrent-Protokoll. Und im naechstem teil gehts dann ueber den Message-Flow im BitTorrent-Protokoll xxD Bevor wir dann auch zu anfassbarem Code kommen, bzw einem Release <img src='http://sixserv.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Links:</p>
<ul>
<li> <a href="http://bittorrent.org/beps/bep_0005.html">BitTorrent Enhancement Proposal 005 / BEP005 </a></li>
<li> <a href="http://de.wikipedia.org/w/index.php?title=Kademlia&amp;oldid=64630482">Wikipedia/DE zu Kademlia</a></li>
<li> <a href="http://de.wikipedia.org/w/index.php?title=Verteilte_Hashtabelle&amp;oldid=64994840">Wikipedia/DE zu DHT</a></li>
</ul>
<p>Trotzallem noch tolle Ersatz-Indexer <img src='http://sixserv.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<ul>
<li> <a href="http://www.torrentbox.com/">torrentbox</a> Hier finde ich vor allem das Global-Search Feature ganz nettm da dort auch Torrentbox-Verified Torrents angezeigt werden</li>
<li><a href="http://1337x.org/">1337x </a>Noch etwas kleines aber sympathisches Projekt</li>
<li><a href="http://www.h33t.com/">h33t</a> Die Oberfläche ist gewöhnungsbedürftig, ansonsten auch sehr nice xD</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://sixserv.org/2009/10/02/implementing-bittorrent-dht-teil-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>implementing bittorrent</title>
		<link>http://sixserv.org/2009/01/22/implementing-bittorrent/</link>
		<comments>http://sixserv.org/2009/01/22/implementing-bittorrent/#comments</comments>
		<pubDate>Thu, 22 Jan 2009 19:28:00 +0000</pubDate>
		<dc:creator>nks</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Torrent]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[p2p]]></category>

		<guid isPermaLink="false">http://sixserv.org/?p=11</guid>
		<description><![CDATA[<img src="/wp-content/themes/6stheme/icons/icon_bittorrent.png" width="50" height="51" alt="" title="Torrent" /><br/>Mal wieder was technisches. Ich geh mal ein bisschen ins Detail des BitTorrent Protokolls. Ich werde das ganze in mehrere Teile aufteilen. In den ersten Teilen wird es sehr Theoretisch. In Teil 1 möchte ich auf das BEncoding eingehen und auf Metafile die euch sicherlich als &#8220;.torrent&#8221;-Datei bekannt ist. Im nächstem Teil gehe ich dann [...]]]></description>
			<content:encoded><![CDATA[<img src="/wp-content/themes/6stheme/icons/icon_bittorrent.png" width="50" height="51" alt="" title="Torrent" /><br/><p>Mal wieder was technisches. Ich geh mal ein bisschen ins Detail des BitTorrent Protokolls.<br />
Ich werde das ganze in mehrere Teile aufteilen.</p>
<p>In den ersten Teilen wird es sehr Theoretisch.<br />
In Teil 1 möchte ich auf das BEncoding eingehen und auf Metafile die euch sicherlich als &#8220;.torrent&#8221;-Datei bekannt ist.</p>
<p>Im nächstem Teil gehe ich dann auf grundsätzliches zur Aufgabe eines Trackers ein. Und danach wird es richtig interessant <img src='http://sixserv.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
Aber erstmal zum BEncoding und der Metafile, ohne die BitTorrent nicht funktioniert -<br />
das BEncoding und die Metafile sind Essentiell!</p>
<p>Bevor ich auf das BEncoding eingehe spreche ich erstmal die MetaFile an, da dies die erste<br />
Stelle (und auch wichtigste) ist an der das BEncoding im Protokoll vorgesehen ist.</p>
<p><strong>Metafile</strong></p>
<p>Die Metafile oder wie es die meisten von euch kennen die &#8220;.torrent&#8221;-Datei.<br />
In ihr sind alle Informationen (und auch ein paar unwichtige <img src='http://sixserv.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> ) die ein Client/Peer benötigt<br />
gespeichert.<br />
Also gehen wir mal näher auf den Inhalt der &#8220;.torrent&#8221;-Datei ein (optionale Teile sind mit *<br />
gekennzeichnet):</p>
<ul>
<li>announce: Die Announce-URL des Trackers</li>
<li>creation date*: Erstellungsdatum</li>
<li>comment*: Platz für einen Kommentar zum Torrent oder andere Informationen</li>
<li>created by*: der Name des Erstellers</li>
<li> info: das info-Dictionary &#8211; der &#8220;kern&#8221; einer Metafile!(darauf gehe ich weiter unten ein)</li>
</ul>
<p>Jetzt werden sich sicher einige denken &#8220;whuuut?! wtf? dictionary?!&#8221;<br />
Ein Dictionary ist die Abbildunge einer Map, oder eines Arrays mit Schlüssel als Index<br />
(ArrayList in Java) auf einen String (bzw. eine ByteFolge xD).</p>
<p><strong>Das Info-Dictionary</strong></p>
<p>Diese Keys enthält ein &#8220;info&#8221; Dictionary:</p>
<ul>
<li> piece length: Die Anzahl der Bytes pro Piece (BitTorrent-Peers tauschen die Daten in Pieces)</li>
<li> pieces: Enthält die Hashes der Pieces</li>
<li> info**: Das info-Dictionary für die Spezifizierung der im Torrent enthaltenen Datei/en. (wenn dieses info-Dictionary gemeint ist werde ich es mit ** markieren)</li>
</ul>
<p>Es gibt 2 verschiedene Modi des Info-Dictionary**  den Single-File und den Multifile-Mode,<br />
dementsprechend gibt es auch<br />
2 verschiedene Arten die Datei bzw. die Dateien näher zu Spezifizieren:</p>
<p><strong>&#8220;info&#8221; im Single-File Mode</strong></p>
<ul>
<li> name: Der Dateiname</li>
<li> length: Länge der Datei in Bytes</li>
</ul>
<p><strong>&#8220;info&#8221; im Multi-File Mode</strong></p>
<ul>
<li> name: Der Ordnername in dem sich die Dateien befinden</li>
<li> files: Ein Dictionary das für jede Datei ein weiteres Dictionary enthält</li>
</ul>
<p>Die Keys des &#8220;files&#8221;-Dictionaries:</p>
<ul>
<li>length: Die grösse der Datei in Bytes</li>
<li>path: Der Pfad der Datei</li>
</ul>
<p>Damit waren die wichtigsten Elemente des .torrent-Files erklärt und wir können uns mit de<br />
Kodierung der entsprechenden Elemente/Einträge befassen &#8211; dem BEncoding.</p>
<p><strong>BEncoding</strong></p>
<p>Das BEncoding ist so genial wie einfach.</p>
<p>BitTorrent nutzt BEncoding für:</p>
<ul>
<li> Strings</li>
<li> Integer</li>
<li> Dictionaries</li>
<li> Listen</li>
</ul>
<p>Diese Typen werden alle nach dem selben Schema kodiert:</p>
<p><strong>Strings:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">:
Beispiel:
<span style="color: #000000;">5</span>:w00t<span style="color: #000000; font-weight: bold;">!</span>  <span style="color: #7a0874; font-weight: bold;">&#40;</span>für den String <span style="color: #ff0000;">&quot;w00t!&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p><strong>Integer</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ie
&nbsp;
Beispiel:
i7e <span style="color: #7a0874; font-weight: bold;">&#40;</span>Integer: <span style="color: #ff0000;">&quot;7&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
i-1e <span style="color: #7a0874; font-weight: bold;">&#40;</span>Integer: <span style="color: #ff0000;">&quot;-1&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p><strong>Dictionaries:<br />
</strong></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">de
&nbsp;
Beispiel:
d3:nks6:gentoo4:apoc4:arche<span style="color: #000000; font-weight: bold;">***</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">***</span> Steht für folgendes dictionary:
KEY          VALUE
<span style="color: #7a0874; font-weight: bold;">&#91;</span>nks<span style="color: #7a0874; font-weight: bold;">&#93;</span> = gentoo
<span style="color: #7a0874; font-weight: bold;">&#91;</span>apoc<span style="color: #7a0874; font-weight: bold;">&#93;</span> = <span style="color: #c20cb9; font-weight: bold;">arch</span></pre></div></div>

<p><strong>Listen</strong>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">le
&nbsp;
Beispiel:
l3:nks7:torrente <span style="color: #7a0874; font-weight: bold;">&#40;</span>entspricht den Strings <span style="color: #ff0000;">&quot;nks&quot;</span> und <span style="color: #ff0000;">&quot;torrent&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span></pre></div></div>

<p>Ist recht simpel oder?<br />
Trotzdem muss man bei der Implementierung aufpassen, wenn hier ein Fehler passiert kann es sein<br />
das man manchmal hinterher lange nach dem Fehler suchen muss <img src='http://sixserv.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
Das BEncoding verfolgt einen durch das ganze Protokoll hinweg.</p>
]]></content:encoded>
			<wfw:commentRss>http://sixserv.org/2009/01/22/implementing-bittorrent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>bitlet.org privacy</title>
		<link>http://sixserv.org/2008/08/29/bitletorg-privacy/</link>
		<comments>http://sixserv.org/2008/08/29/bitletorg-privacy/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 00:19:51 +0000</pubDate>
		<dc:creator>nks</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Torrent]]></category>
		<category><![CDATA[bittorrent]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[privacy]]></category>

		<guid isPermaLink="false">http://sixserv.org/?p=48</guid>
		<description><![CDATA[<img src="/wp-content/themes/6stheme/icons/icon_java.png" width="50" height="51" alt="" title="Java" /><br/>Ich nutze gerne den BitTorrent-Client “BitLet”, wenn ich an maschinen ohne installierten BiTorrent-Client arbeite. Wirklich genial und einfach. Zeigt sehr schön wie man mit Java auch nicht resourcenfressende Ressourcen-schonende torrent-Clients schreiben kann, im Gegensatz zu Azureus/Vuze. Ich nutze BitLet recht häufig jedoch bereitet mir schon seit längerem sorgen, dass auf der Startseite eine history der [...]]]></description>
			<content:encoded><![CDATA[<img src="/wp-content/themes/6stheme/icons/icon_java.png" width="50" height="51" alt="" title="Java" /><br/><p>Ich nutze gerne den BitTorrent-Client “<a href="http://bitlet.org">BitLet</a>”, wenn ich an maschinen ohne installierten BiTorrent-Client arbeite. Wirklich genial und einfach. Zeigt sehr schön wie man mit Java auch <span style="text-decoration: line-through;">nicht resourcenfressende</span> Ressourcen-schonende torrent-Clients schreiben kann, im Gegensatz zu <a href="http://www.vuze.com">Azureus/Vuze</a>. Ich nutze BitLet recht häufig jedoch bereitet mir schon seit längerem sorgen, dass auf der Startseite eine history der letzten torrents liegt. Das ist natürlich sehr praktisch fürs resumen bzw. um den aktuellen stand des Downloads zu sehen und ihn bei bedarf zu loeschen oder zu resumen, allerdings liegen diese taten auf dem Server von BitLet.org.<br />
BitLet hat somit auf ihren Servern eine Datenbank laufen die die IPs logt mit denen die User ihre Downloads tätigen und die entsprechenden namen der .torrent-Files (mit ausgelesenen meta-Daten und download-fortschritt). Das wird vermutlich über ein Cookie realisiert.</p>
<p>Also ab und zu mal Cookies löschen&#8230;</p>
<p>Bleibt abzuwarten was sich daraus ergibt.</p>
<p>links:</p>
<blockquote>
<ul>
<li><a href="http://bitlet.org">http://bitlet.org</a></li>
<li><a href="http://vuze.com">http://vuze.com</a></li>
</ul>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://sixserv.org/2008/08/29/bitletorg-privacy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
