% do-vimlatex-onwrite % šijanec specific
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% datoteka diploma_predloga.tex
%
% ta verzija sproducira pdf datoteko v pdf/A formatu.
%
% vzorčna datoteka za pisanje diplomskega dela v formatu LaTeX
% na UL Fakulteti za računalništvo in informatiko
%
% Leta 2026 je predlogo posodobil Žiga Emeršič. Predlogo je razdelil na več datotek, uvedel spremenljivke, dodal PDF-A in posodobil navodila (tudi združil določena poglavja in pripravil nova).
% Leta 2021 je predlogo posodobil Franc Solina.
% Leta 2010 je predlogo pripravil Gašper Fijavž.
%
% za upravljanje z literaturo ta vezija uporablja BibLaTeX
%
% svetujemo uporabo Overleaf.com - na tej spletni implementaciji LaTeXa ta vzorec zagotovo pravilno deluje
%

% Združljivost s pdfa (sicer nekoliko starejšo različico 1.7)
\DocumentMetadata{pdfstandard = a-2b, pdfversion  = 1.7}

\documentclass[a4paper,12pt,openright]{book}
% \documentclass[a4paper, 12pt, openright, draft]{book}  % TODO Nalogo preverite tudi z opcijo draft, ki pokaže, katere vrstice so predolge! Pozor, v draft opciji, se slike ne pokažejo!


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  PODATKI O DIPLOMI
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Vnesite vaše podatke in podatke mentorjev:
\newcommand{\tauthor}{Anton Luka Šijanec}
\newcommand{\temail}{anton@sijanec.eu}
\newcommand{\tmentor}{izr.~prof.~dr.~Mojca Ciglarič}
% \newcommand{\tsomentor}{viš.~pred./doc./izr.~prof./prof.~dr.~Martin Krpan}
\newcommand{\tsomentor}{}

% Odkomentirajte pravi program:
\newcommand{\tstopnja}%
% {ODKOMENTIRAJTE PRAVI PROGRAM IN ODSTRANITE TO VRSTICO}
% {VISOKOŠOLSKI STROKOVNI ŠTUDIJSKI PROGRAM\\ PRVE STOPNJE}
% {UNIVERZITETNI  ŠTUDIJSKI PROGRAM\\ PRVE STOPNJE\\ RAČUNALNIŠTVO IN INFORMATIKA}
% {INTERDISCIPLINARNI UNIVERZITETNI\\ ŠTUDIJSKI PROGRAM PRVE STOPNJE\\ MULTIMEDIJA}
% {INTERDISCIPLINARNI UNIVERZITETNI\\ ŠTUDIJSKI PROGRAM PRVE STOPNJE\\ UPRAVNA INFORMATIKA}
{INTERDISCIPLINARNI UNIVERZITETNI\\ ŠTUDIJSKI PROGRAM PRVE STOPNJE\\ RAČUNALNIŠTVO IN MATEMATIKA}

% Odkomentirajte pravo institucijo:
\newcommand{\tinst}%
{Fakulteta za računalništvo in informatiko\\Fakulteta za matematiko in fiziko}
% {Fakulteta za elektrotehniko}
% {Fakulteta za upravo}
% {Fakulteta za matematiko in fiziko}

% Napišite pravo vrsto naloge:
% \newcommand{\tvrsta}{Diplomska naloga na univerzitetnem programu prve stopnje Interdisciplinarni študijski program računalništvo in matematika}
\newcommand{\tvrsta}{Diplomska naloga na interdisciplinarnem univerzitetnem študijskem programu prve stopnje računalništvo in matematika}

% Opis iz STUDISa:
\newcommand{\tdescription}
{Besedilo teme diplomskega dela študent prepiše iz študijskega informacijskega sistema, kamor ga je vnesel mentor. V nekaj stavkih bo opisal, kaj pričakuje
od kandidatovega diplomskega dela. Kaj so cilji, kakšne metode naj uporabi,
morda bo zapisal tudi ključno literaturo.}
\newcommand{\tdescriptionEn}
{The student shall transcribe the text of the diploma thesis topic from the student information system, where it was entered by the mentor. In a few sentences, they will describe what is expected of the candidate's thesis. What the objectives are, what methods should be used, and perhaps they will also list the key literature.}

% Naslov:
\newcommand{\ttitle}{Statistika omrežja BitTorrent na podlagi metapodatkov iz DHT}
\newcommand{\ttitleEn}{BitTorrent network statistics based on metadata from DHT}

% Ključne besede:
\newcommand{\tkeywords}{bittorrent, dht, p2p, kademlia}
\newcommand{\tkeywordsEn}{bittorrent, dht, p2p, kademlia}

% Zahvala (opcijsko):
\newcommand{\tzahvala}
{Hvala mentorici izr.~prof.~dr.~Mojci Ciglarič za uporabne nasvete in odzivnost ter staršem za vso podporo.}
% {Na tem mestu zapišite, komu se zahvaljujete za pomoč pri izdelavi diplomske naloge oziroma pri vašem študiju nasploh. Pazite, da ne boste koga pozabili. Utegnil vam bo zameriti. Temu se da izogniti tako, da celotno zahvalo izpustite.}

% Posvetilo (opcijsko):
\newcommand{\tposvetilo}
% {Svojemu dragemu računalniku.}
{}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  VKLJUČITEV NUJNIH ELEMENTOV 1/2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\input{podporno/preambula.tex} 
\begin{document}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% POVZETEK
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\tpovzetek}
{Diplomsko delo predstavi protokol BitTorrent in njegov podporni sistem DHT in se osredotoči na uporabo slednjega za pridobivanje podatkov, ki jih uporabniki tega porazdeljenega omrežja prenašajo, brez potrebe po privilegiranem dostopu do centralnih strežnikov. Opisana je zasnova in nekaj tehničnih značilnosti za ta namen spisane programske opreme, ki z normalnim sodelovanjem v omrežju DHT na podlagi poizvedb drugih uporabnikov pridobiva zgoščene vrednosti metapodatkov (imena datotek in njihove velikosti), ki jih nato od soležnikov prenese. Na podlagi štirih takih zajemov podatkov v letih 2023, 2024 in 2026 (skupno okoli $\num{1,5e6}$ torrentov) v nalogi analiziramo stanje omrežja. Predstavljena statistika vključuje tipe datotek, ki jih uporabniki prenašajo, zastopanost odjemalcev, razširjenost protokola IPv6, podrobnosti o kvaliteti videovsebin in razširjenost uporabe protokola na državo. Navedene so tudi pomanjkljivosti izvedenega zajema in težave, na katere smo med zajemom naleteli.}

%{V vzorcu je predstavljen postopek priprave diplomskega dela z uporabo okolja \LaTeX. Vaš povzetek mora sicer vsebovati med približno 100 in 200 besed, ta tukaj je odločno prekratek.
%Dober povzetek je kot mini diploma in vključuje: (1) kratek opis stanja tehnike in kaj so glavne težave oz. opis obravnavanega problema, (2) kako ste ta problem naslovili oz. kratek opis vašega pristopa za reševanje tega problema in (3) (najbolj uspešen) rezultat ali prispevek diplomske naloge.}

\newcommand{\tabstract}
{The thesis introduces the BitTorrent protocol family and its supporting protocol, the distributed hash table (DHT), focusing on using DHT to acquire data (generated by users of BitTorrent) from the BitTorrent network without requiring any privileged access to remote infrastructure servers. For the acquisition, specialised software, described in this thesis, was developed that records queries that other users' clients, by protocol design, route through our observation node in the DHT network. Those queries contain hashes of torrent metadata which are used to obtain said metadata (file names and sizes) from peers. From four independent acquisitions of data in years 2023, 2024 and 2026, containing information of around $\num{1,5e6}$ torrents, we deduce the state of the BitTorrent network. Presented statistics include types of files that are downloaded by users, which client software is most used, representation of IPv6 protocol in torrent communication, details about the quality of transferred video content and BitTorrent usage per country. We also talk about the shortcomings of our acquisition approach and present possible improvements, and list some problems we encountered.}
% {This sample document presents the process of preparing a thesis using the \LaTeX\ environment. Your abstract should otherwise contain between approximately 100 and 200 words; the one provided here is far too short. A good abstract is like a mini-thesis and includes: (1) a brief description of the state of the art and the main issues or a description of the problem addressed, (2) how you addressed this problem or a brief description of your approach to solving it, and (3) the (most successful) result or contribution of the thesis.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  VKLJUČITEV NUJNIH ELEMENTOV 2/2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\input{podporno/naslovnestrani.tex}
\mainmatter
\setcounter{page}{1}
\pagestyle{fancy}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% GLAVNA VSEBINA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\chapter{Uvod}

\section{Motivacija} % za delo
Dandanes na področju računalniških komunikacij izstopajo razprave o porazdeljenih sistemih, natančneje glede opuščanja klasičnega doslej dolgo uveljavljenega koncepta strežnik-odjemalec v prid modernejšim shemam, denimo brezstrežniški infrastrukturi in komunikacijskim protokolom, ki niso odvisni od centralne entitete, temveč jo poganjajo in na nek način vzdržujejo uporabniki sami, kar naj bi omogočalo boljšo odpornost na izpade, cenzuro in drugačno zlonamerno vplivanje s strani upravljavcev. Ker taki sistemi skoraj vedno slonijo na opremi, ki je pod nadzorom velikega števila uporabnikov, so podatki kot ključni sestavni deli sistemov tudi shranjeni oziroma posredovani prek uporabniške opreme. Ko take sisteme obravnavamo, je zato pomembno vprašanje, kako dostopni so (osebni) podatki, ki se prek njih pretakajo, komu vse in v kakšni meri so prosto dostopni za prenos, in do kakšnih sklepov o porazdeljenem omrežju oziroma njegovih uporabnikih lahko z zajemom teh podatkov pridemo~\cite{ikwyd,griffin17}.

Eno izmed najstarejših še vedno aktivno uporabljenih porazdeljenih omrežij za izmenjavo podatkov oziroma komunikacijo je protokol BitTorrent, katerega začetki segajo četrt stoletja v preteklost~\cite{cohen01}. Protokol je načrtovan tako, da omogoča čim preprostejšo distribucijo datotek prek interneta veliki množici ljudi, s čim manjšo obremenitvijo internetne linije objavljalca, kar doseže tako, da prenašalci datoteke po prenosu tudi sami
začno % arhaizem -> začnejo
oddajati drugim, ki želijo to datoteko prenesti, s čimer linijo izvornega objavljalca razbremeni.

V nalogi predstavimo, kako protokol DHT na osnovi protokola Kademlia~\cite{maymounkov2002kademlia}, podporni sistem omrežja BitTorrent, za omrežje neinvazivno uporabimo na način, ki ni mišljen kot funkcionalnost samega protokola, temveč kot posledica njegovega delovanja, da pridobimo velike količine metapodatkov o datotekah v omrežju, ki se trenutno prenašajo. Nadalje tudi analiziramo statistično reprezentativen tako pridobljen vzorec metapodatkov iz omrežja, kjer metapodatki predstavljajo datoteke, ki se prenašajo (njihova imena in velikost), ob katerem času se prenašajo in kdo jih prenaša (naslov IP).
\section{Cilji} % naloge
Nalogo sestavljata dva ključna cilja, prvič želimo razviti program za množični zajem vzorca metapodatkov iz omrežja BitTorrent, ki ne obremenjuje omrežja (torej komunikacijske opreme ostalih uporabnikov) tako, da bi z zajemom kakorkoli znatno vplival na njegovo delovanje. Želimo si tudi, da pridobljen vzorec metapodatkov vsebinsko ni zaznamovan; vzorec mora biti nepristranski, vsebovati mora naključen vzorec datotek, ki jih prenaša naključno izbrana skupina uporabnikov.
Nočemo torej vzorca, % pogovorno: ne želimo torej vzorca
ki bi bil zaznamovan recimo geografsko (torej da bi npr. pristransko prednostno vseboval metapodatke o prenosih računalnikov v Evropi) -- to vključuje tudi nepristranskost glede omrežne družine, naš zajem ne sme biti omejen samo na IPv4 ali IPv6, ker bi to zaradi različno uspešnega~\cite{cfipv6} prodora IPv6 po državah kazalo popačeno sliko.

Drugič želimo pridobljene metapodatke analizirati in iz njih izvleči najbolj ključne značilnosti uporabnikov omrežja; kaj prenašajo, kdaj, s kakšno programsko opremo, itd.
\section{Hipoteze}
Glede na že izdelane analize prometa omrežja BitTorrent, pridobljene po drugačni poti~\cite{GavaldMiralles2014}, domnevamo, da bodo največji delež vsebin v omrežju predstavljale videovsebine, natančneje piratski filmi. Omrežje BitTorrent ljudje po raziskavah~\cite{GavaldMiralles2014} uporabljajo predvsem za ogled filmov brez ustreznih avtorskih pravic, za kar je omrežje dobro prilagojeno; filmi so velike datoteke, njihovo deljenje v peer-to-peer omrežjih za objavljalce predstavlja manjši strošek, kot če bi se posluževali klasičnega modela strežnik-odjemalec~\cite{Zhong2021P2P}, poleg tega pa so manj izpostavljeni organom pregona, saj je v primeru peer-to-peer omrežij težje določiti, kdo je izvorni objavljalec neke datoteke, ker jo je moč prenesti od velikega števila naprav v internetu~\cite{prado2025piracyshield}.

Ker je iz metapodatkov moč določiti tudi različico programske opreme pošiljatelja, domnevamo, da uporabniki omrežja
vsled % arhaizem -> zaradi
rednih avtomatskih posodobitev programske opreme in dotoka novih uporabnikov v povprečju pretežno uporabljajo najnovejše različice programov za povezavo v omrežje BitTorrent.
\section{Stanje področja in sorodna dela} % mogoče nekaj številk o bittorrentu iz drugih člankov, mogoče kako anketo, podatke ispjev, kak članek
Statistične raziskave prenesenih podatkov na omrežju BitTorrent potekajo že vse od njegovega nastanka~\cite{mateus2011quantifying}. V glavnem se zaradi precej preprostejšega načina zajema osredotočajo na podatke, ki jih zberejo centralni strežniki sledilniki ali pa podatke, ki jih zbirajo na usmerjevalnikih omrežnih operaterjev~\cite{bittorrentisp}. Ti podatki za to nalogo niso zanimivi; mi se osredotočamo na podatke, ki jih je moč pridobiti brez relativno privilegiranega dostopa do dnevniških in analitičnih datotek na večjih sledilniških strežnikih.

Ta naloga se osredotoča na Mainline DHT (Kademlia), ki je dandanes \textit{de facto} implementacija DHT-ja za BitTorrent. Pred trdno uveljavitvijo/standardizacijo tega DHT protokola je podporo za DHT kot prvi tak odjemalec dobil odjemalec, danes znan kot Vuze~\cite{jones15}. O prečesavanju Vuze DHT za statistiko omrežja piše članek~\cite{funandprofit}.

Ves čas Mainline DHT preiskujejo mnogi za omrežje invazivnejši~\cite{sampleih} programi, kot tu opisan. Njihov prvotni namen ni pridobivanje vzorca za statistično analizo, temveč izdelava zbirnega iskalnika po datotekah, ki jih je moč prenesti z odjemalec za torrente. Nekateri trenutno dostopni iskalniki torrent vsebin, ki jih poganjajo preiskovalci Mainline DHT, so~\cite{muo11,evseenko11,gibson_bitmagnet,clzhizhu}.

\section{Struktura dela}

V teoretičnih osnovah (poglavje~\ref{teoreticneosnove}) razložimo osnovne koncepte ključnih protokolov (BitTorrent, DHT in bkodiranje), ki jih je za razumevanje naloge treba poznati. Nadaljujemo z metodologijo (poglavje~\ref{metodologija}) zajema, kjer natančneje obrazložimo, zakaj je zajem mogoč in kako ga bomo izvajali. Izdelavi in delovanju našega za zajem implementiranega programa se posvetimo v poglavju Implementacija (poglavje~\ref{implementacija}). Naposled v poglavju~\ref{zajetipodatkiinrezultati} navedemo, koliko podatkov smo zajeli in prikažemo nekaj ključnih dejstev o njih, v zaključku (poglavje~\ref{zakljucek}) pa rezultate komentiramo, predlagamo izboljšave naši raziskavi in besedo namenimo še etičnosti opravljenih meritev.

\section{Slovar uporabljenih kratic}

\begin{itemize}
	\item \textbf{BEP}: BitTorrent enhancement proposal
	\item \textbf{CPE}: customer premises equipment
	\item \textbf{DHT}: porazdeljena razpršena tabela
	\item \textbf{DNS}: domain name system
	\item \textbf{GPON}: gigabit passive optical network
	\item \textbf{HTTP}: hypertext transfer protocol
	\item \textbf{ID}: identifikator
	\item \textbf{IO}: vhod/izhod
	\item \textbf{IP}: internetni protokol
	\item \textbf{IPv4}: četrta različica internetnega protokola
	\item \textbf{IPv6}: šesta različica internetnega protokola
	\item \textbf{JSON}: javascript object notation
	\item \textbf{PeX}: peer exchange, izmenjava soležnikov
	\item \textbf{SHA-1}: secure hash algorithm 1
	\item \textbf{TCP}: transmission control protocol
	\item \textbf{UDP}: user datagram protocol
	\item \textbf{URI}: uniform resource identifier
	\item \textbf{URL}: uniform resource locator
	\item \textbf{XOR}: ekskluzivni ali
	\item \textbf{{\textmu}TP}: micro torrent protocol
\end{itemize}

\chapter{Teoretične osnove}
\label{teoreticneosnove}
\section{Protokol BitTorrent}
\paragraph{Datoteka torrent} (krajše torrent) vsebuje metapodatke o končni fiksni množici nespremenljivih datotek. Kdor želi prek BitTorrent razširjati neke datoteke, ki jih ima, mora izdelati datoteko \texttt{.torrent} in jo prek poljubnega kanala posredovati bodočim prejemnikom datotek. Ta za vsako datoteko vsebuje njeno relativno pot, ki se konča z imenom datoteke (distribucija s torrenti namreč ohranja hierarhično strukturo map) in njeno dolžino v bajtih. Ključna sestavina torrenta so tudi zgoščene vrednosti (SHA-1~\cite{Eastlake2001}) koščkov datotek, kar zagotavlja integriteto prenesenih podatkov, in velikost koščka, ki je poljubna, a za en torrent konstantna. BitTorrent ne definira iskanja po torrentih; če želimo prenesti datoteke nekega torrenta, moramo datoteko torrent (ali pa vsaj njeno zgoščeno vrednost --~\ref{infohash}) tudi imeti. Njena struktura je naslednji bkodiran slovar:
\begin{itemize}
	\item \texttt{announce}: HTTP URL sledilnika. Tega v naši nalogi ne uporabljamo, niti ne pridobimo, saj je izven slovarja \texttt{info}. 
	\item \texttt{info}: Slovar z metapodatki o torrentu:
	\begin{itemize}
		\item \texttt{private}: Oznaka, da je torrent zaseben~\cite{harrison08}. Odjemalci v primeru zasebnih torrentov po soležnikih sprašujejo le sledilnik, naveden v datoteki torrent, ki jo imajo. Takih torrentov v nalogi sploh ne bomo zaznali, ker jih v DHT ni.
		\item \texttt{name}: Ime torrenta. Če ima torrent samo eno datoteko, je to ime te datoteke.
		\item \texttt{piece length}: Velikost \hyperref[koscek]{koščka}.
		\item \texttt{pieces}: S SHA-1 zgoščene vrednosti koščkov, staknjene v en dolg niz, se pravi je dolžina celega niza deljiva z dvajset. 
		\item \texttt{length}: To polje je prisotno le, če torrent vsebuje samo eno datoteko. V tem primeru je pod ključem \texttt{length} vpisana njena dolžina.
		\item \texttt{files}: Seznam datotek v torrentu, za vsako pa slovar:
		\begin{itemize}
			\item \texttt{length}: Dolžina datoteke v bajtih.
			\item \texttt{path}: Seznam komponent poti, ki se konča z imenom datoteke, torej za datoteko \texttt{slike/morje/2026/IMG\_5824.jpg} bo pripadajoč seznam \mintinline{json}{["slike", "morje", "2026", "IMG_5824.jpg"]}. S takim zapisom poti se izognemo dvoumnostim z različnimi ločili poti (\texttt{\textbackslash} in \texttt{/}). Odjemalci morajo preveriti, da elementi seznama ne vsebujejo spornih podnizov, denimo \texttt{..} ali \texttt{/}.
		\end{itemize}
	\end{itemize}
\end{itemize}
Primer datoteke torrent, ki smo jo prenesli tekom letošnjega zajema (odstranjen ključ \texttt{pieces}, za preglednost pretvorjena v JSON), je v izseku kode~\cite{metainfo}.
\newcommand{\magnetlink}[1]{%
  \href{magnet:?xt=urn:btih:#1}{\texttt{#1}}%
}
\begin{center}
\captionof{listing}{Primer izbrane letos letos zajete datoteke torrent z infohashem \magnetlink{8387dddf9f11e281ae29c191194cf94d272ada72}.}
\label{metainfo}
\inputminted{json}{primer.json}
\end{center}

% TODO primer metainfo datoteke
\paragraph{Košček}\label{koscek} predstavlja najmanjše zaporedje bajtov fiksne dolžine\footnote{Izjema je seveda zadnji košček, ki je lahko krajši, če skupna dolžina datotek ni deljiva z velikostjo koščka.}, ki ga je moč zanesljivo in overjeno prenesti prek torrent omrežja. Po protokolu BitTorrent se prenašajo samo koščki, ne datoteke; za prenos vsebino vseh datotek staknemo skupaj (brez polnila med njimi) in dobljeno zaporedje bajtov razdelimo na koščke enake dolžine, ki jih oštevilčimo začenši z 0. Če je dolžina koščka $L$ bajtov, to je lahko npr. $\qty{1}{\mebi\byte}$, bo prvi košček, ki vsebuje kakšen bajt druge datoteke v torrentu, na indeksu $\left\lfloor{\frac{v_0}{L}}\right\rfloor$, če je $v_0$ velikost prve in $v_1$ druge datoteke v bajtih. Za prenos cele druge datoteke moramo prenesti koščke na intervalu $\left[\left\lfloor{\frac{v_0}{L}}\right\rfloor, \left\lfloor{\frac{v_0+v_1-1}{L}}\right\rfloor\right]$.

Ker so v datoteki torrent navedene zgoščene vrednosti po koščkih, ne po manjših enotah, ne moremo overiti krajših zaporedij bajtov, kot dolžina koščka, čim pa pridobimo celoten košček in preverimo ujemanje zgoščene vrednosti, smo lahko prepričani, da je tak, kot je bil v datoteki izvornega izdelovalca torrenta, ne glede na to, od koga smo košček prenesli.
\paragraph{infohash}\label{infohash} je s SHA-1 zgoščena vrednost bkodiranega slovarja \texttt{info} v torrent. Unikatno identificira torrent, ker slovar \texttt{info} vsebuje vse ključne informacije o torrentu. Če poznamo infohash, lahko iz omrežja rekonstruiramo celotno datoteko torrent, kar počnemo v tej nalogi.
\paragraph{Soležnik} je računalnik v omrežju BitTorrent, ki bodisi pridobiva datoteke nekega specifičnega torrenta (pijavka) od drugih soležnikov bodisi jih daje na voljo soležnikom, ki jih želijo (sejalec). Soležnik je lahko hkrati sejalec in pijavka. Čim namreč od nekega sejalca prenese in overi en košček, lahko ta košček začne deliti naprej pijavkam.
\paragraph{Roj} je množica vseh trenutno v omrežje povezanih soležnikov nekega torrenta.
\paragraph{Sledilnik} je strežnik, ki vzdržuje seznam aktivnih soležnikov (njihove naslove IP in vrata TCP) za posamezen torrent (glede na infohash). Sledilniki predstavljajo šibko točko omrežja, saj lahko izvajajo cenzuro (nek sledilnik lahko zavrne zahteve za določen torrent), lahko pa zaradi izpadov sploh niso dostopni. V nalogi sledilnikov ne obravnavamo; vse funkcije sledilnika namreč lahko zamenja porazdeljena razpršena tabela. 
\subsection{Povezovanje za izmenjavo metapodatkov in datotek}\label{metadata}
Ko soležnik bodisi prek DHT bodisi prek sledilnikov poizve o roju torrenta, se na soležnike v roju poveže s TCP in po isti povezavi zahteva koščke datotek, dokler vseh želenih datotek ne prenese, in izpolnjuje zahteve soležnikov, ki želijo od njega koščke prenesti~\cite{cohen08}. Tako vzpostavljena povezava je dvosmerna in vezana na en torrent; omogoča prenos koščkov v obe smeri. V tej nalogi koščkov ne prenašamo, zato se osredotočimo na specifično nam koristno funkcijo protokola, ki omogoča prenos celih datotek torrent, ko vemo infohash.

V nalogi s sodelovanjem v DHT pridobivamo zgolj infohashe, zato moramo prenesti še metapodatke -- datoteke torrent. To storimo s poizvedbo v DHT o roju, ko dobimo nekaj soležnikov, se povežemo nanje po TCP\footnote{Obstaja sicer tudi novejši protokol {\textmu}TP, ki omogoča učinkovitejše prenašanje velikih količin koščkov prek UDP~\cite{norberg09}, vendar se v nalogi nanj ne fokusiramo, saj prenašamo relativno malo -- samo metapodatke.} in opravimo začetno rokovanje BitTorrent (Slika~\ref{tcp}). Po uspešno opravljenem rokovanju odjemalca drug drugemu pošiljata zaporedje sporočil, ki sestojijo iz štiribajtne dolžine (po pravilu debelega konca), enobajtnega tipa in telesa~\cite{cohen08}.

Podprtost razširitvenega protokola, katerega del je razširitev za prenos metapodatkov~\cite{hazel08}, soležnik izkaže tako, da nastavi 20. bit z desne (začnemo šteti z 0) v osmih bajtih za razširitve v sekvenci rokovanja. Brez razširitvenega protokola prenos metapodatkov ni mogoč, v takem primeru prekinemo povezavo. Naš pogoj za nadaljevanje komunikacije je torej \mintinline{c}{razširitev[5] & 0x10}. Vsa sporočila BitTorrent, ki uporabljajo razširitveni protokol, imajo tip sporočila \texttt{20}. Vsako razširitveno sporočilo se začne z enobajtnim podtipom. Če je podtip 0, gre za začetno rokovanje za razširitve, s katerim odjemalca z bkodiranim slovarjem določita številke podtipov za razširitve, ki jih bosta uporabljala, in en drugemu sporočita, katere razširitve podpirata~\cite{strigeus08}.

Specifična razširitev za prenos metapodatkov se imenuje \texttt{ut\_metadata} in je standardizirana z dokumentom BEP-0009~\cite{hazel08}. Odjemalca, ki jo podpirata, to naznanita na način, ki ga opisuje razširitveni protokol, torej tako, da med razširitvenim rokovanjem pošljeta ustrezen bkodiran slovar, npr. \mintinline{json}{{"m": {"ut_metadata": 3}, "metadata_size": 31235}}. V tem primeru bi uporabljala podtip 3 za prenos metapodatkov, obenem pa odjemalec, ki metapodatke (datoteko torrent) ima -- mi jih nikoli nimamo, to označi tako, da sporoči njihovo dolžino pod ključem \texttt{metadata\_size}. Odjemalci običajno med rokovanjem pod ključem \texttt{v} pošljejo tudi različico svoje programske opreme, kar tudi beležimo za nadaljnjo analizo.

Ko vemo, da soležnik podpira razširitev za prenos metapodatkov in ima metapodatke, jih od njega zahtevamo po delih dolžine \qty{16384}{\byte} tako, da mu pošiljamo sporočila s podtipom, določenim za \texttt{ut\_metadata} in bkodiranimi zahtevami \mintinline{json}{{"msg_type": 0, "piece": 123}}, kjer je 123 zaporedna številka dela, soležnik pa nam odgovarja s sporočili s podtipom za \texttt{ut\_metadata} in bkodiranim odgovorom \mintinline{json}{{"msg_type": 1, "piece": 123, "total_size": 964964}}, ki mu neposredno sledijo zahtevani bajti metapodatkov~\cite{hazel08}.

Po prenosu metapodatkov lahko mi za naše potrebe povezavo prekinemo, resničen odjemalec, ki si želi prenesti vsebino datotek, pa bi nadaljeval s prenosom koščkov datotek, v kar se ne spuščamo. Šele ko prenesemo vse dele metapodatkov, obvezno preverimo njihovo integriteto -- s SHA-1 zgoščena vrednost\footnote{V drugi različici protokola BitTorrent~\cite{v2} je zgoščena vrednost prvih 20 bajtov SHA-256 bkodiranega slovarja \texttt{info}. Da ne bi izpuščali torrentov druge različice, preverimo ujemanje z obema tipoma zgoščenih vrednosti.} celotnega slovarja \texttt{info}, ki smo ga prejeli, se mora ujemati z infohashem tega torrenta.
\begin{figure}
	\begin{center}
		\setlength{\instdist}{0.51\textwidth}
		\begin{msc}[msc keyword=protokol]{Vzpostavitev povezave BitTorrent in prenos metapodatkov}
		\declinst{m1}{Soležnik 1}{naša naprava}
		\declinst{m2}{Soležnik 2}{druga naprava}
		\nextlevel
		\mess{Bajt \texttt{19} in niz \texttt{BitTorrent protocol}}{m1}{m2}
		\nextlevel
		\nextlevel
		\mess{Osem bajtov \texttt{0x0000000000100000}}{m1}{m2}
		\nextlevel
		\nextlevel
		\mess{\qty{20}{\byte} infohash, \qty{20}{\byte} ID odjemalca 1}{m1}{m2}
		\nextlevel
		\nextlevel
		\mess{Bajt \texttt{19} in niz \texttt{BitTorrent protocol}}{m2}{m1}
		\nextlevel
		\nextlevel
		\mess{Osem bajtov za razširitve (preverimo pogoj)}{m2}{m1}
		\nextlevel
		\nextlevel
		\mess{\qty{20}{\byte} infohash, \qty{20}{\byte} ID odjemalca 2}{m2}{m1}
		\nextlevel
		\nextlevel
		\mess{\qty{4}{\byte} dolžine, \texttt{20}, \texttt{0x00}, \mintinline{json}{{"m": {"ut_metadata": 1}}}}{m1}{m2}
		\nextlevel
		\nextlevel
		\nextlevel
		\nextlevel
		\mess{\parbox{0.67\textwidth}{\qty{4}{\byte} dolžine, \texttt{20}, \texttt{0x00},\\\mintinline{json}{{"m": {"ut_metadata": 1}, "metadata_size": 964964}}}}{m2}{m1}
		\nextlevel
		\nextlevel
		\mess{\qty{4}{\byte} dolžine, \texttt{20}, \texttt{0x01}, \mintinline{json}{{"msg_type": 0, "piece": 0}}}{m1}{m2}
		\nextlevel
		\nextlevel
		\nextlevel
		\nextlevel
		\mess{\parbox{0.67\textwidth}{\qty{4}{\byte} dolžine, \texttt{20}, \texttt{0x01},\\\mintinline{json}{{"msg_type": 1, "piece": 0, "total_size": 964964}}}}{m2}{m1}
		\nextlevel
		\nextlevel
		\mess{0. del metapodatkov dolžine \qty{16384}{\byte}}{m2}{m1}
		\nextlevel
		\nextlevel
		\mess{\qty{4}{\byte} dolžine, \texttt{20}, \texttt{0x01}, \mintinline{json}{{"msg_type": 0, "piece": 1}}}{m1}{m2}
		\nextlevel
		\nextlevel
		\nextlevel
		\nextlevel
		\mess{\parbox{0.67\textwidth}{\qty{4}{\byte} dolžine, \texttt{20}, \texttt{0x01},\\\mintinline{json}{{"msg_type": 1, "piece": 1, "total_size": 964964}}}}{m2}{m1}
		\nextlevel
		\nextlevel
		\mess{1. del metapodatkov dolžine \qty{16384}{\byte}}{m2}{m1}
		\end{msc}
	\end{center}
	\caption{Prenos metapodatkov po povezavi TCP~\cite{hazel08}}
	\label{tcp}
\end{figure}



\section{Mainline DHT}

\begin{figure}
	\begin{center}
		% \input{slike/dht.tex} % ta zaradi nekih cmyk color profiles ni pdfa compliant
		% \input{slike/dhtgray.tex}
		\input{slike/dhtmono.tex}
		\caption{Shematski prikaz~\cite{jnlin_dht_en} uporabe DHT v BitTorrentu} % https://commons.wikimedia.org/wiki/File:DHT_en.svg
		\label{dhtshema}
	\end{center}
\end{figure}

Porazdeljena razpršena tabela (DHT) je dinamičen slovar (slika~\ref{dhtshema}). Pod ključem, ki predstavlja infohash torrenta, hrani množico soležnikov. Na najvišjem nivoju podpira dve operaciji:

\begin{itemize}
	\item \textbf{Oznani}\footnote{V angleščini \enquote{announce}.}: Vpiše naslov IP pošiljatelja te operacije in podana vrata v DHT pod ključ, ki pripada podanemu infohashu. Kdor hoče postati soležnik in si želi, da bi se drugi povezovali nanj, s to operacijo objavi svoj naslov.
	\item \textbf{Pridobi soležnike}: Vrne seznam naslovov IP in vrat soležnikov v roju torrenta glede na podani infohash.
\end{itemize}

Uporabnik v porazdeljenem omrežju DHT, ki izvede te operacije, s tem po zasnovi DHT poizvedbe pošlje prek veliko drugih uporabnikov. V tej nalogi torej kot pasivni uporabnik omrežja DHT pridobimo veliko poizvedb, ki vsebujejo infohashe torrentov, ko pa enkrat dobimo infohashe, pa lahko prenesemo še metapodatke.

Porazdeljen sistem DHT si zamislimo kot redek usmerjen graf, katerega vozlišča so posamezne naprave (odjemalci BitTorrent) kot trojice (naslov IP, vrata, dvajsetbajtni ID), povezave pa so definirane na podlagi usmerjevalnih tabel, ki jih hranijo vozlišča. Vrednosti v tabeli (soležniki) se vpisujejo v vozlišča na tak način, ki kasneje omogoča učinkovite vpoglede, torej na strateško izbrana vozlišča~\cite{norberg08}.

\paragraph{ID vozlišča} mora biti izbran enakomerno naključno~\cite{rfc4086} na $\{0,1\}^{160}$ in mora biti shranjen na disk -- med ponovnimi zagoni vozlišča DHT mora ostati nespremenjen. V primeru zamenjave bi vozlišče lahko ostalo pod starim ID-jem, a istim naslovom IP v usmerjevalnih tabelah drugih vozlišč. Pogosto menjanje ID-ja bi povzročalo zmedo in slabše delovanje omrežja, saj je porazdeljenost podatkov in usmerjanje poizvedb za podatki po omrežju, kot bomo videli kasneje, odvisna od ID-jev vozlišč. 

\paragraph{Usmerjevalna tabela} je shranjena na vsakem vozlišču in vsebuje vozlišču sosednja vozlišča (za vsako naslov IP, vrata, dvajsetbajtni ID, stanje aktivnosti in čas zadnjega odgovora). Vozlišča so v njej razdeljena po koših glede na ID. Vsak koš vsebuje največ $K=8$ vozlišč. Koš $i$ na vozlišču z ID $a$ vsebuje natanko tista oddaljena vozlišča, katerih ID-ji se z $a$ ujemajo v prvih $i$ bitih, ne vsebuje pa vozlišč, ki se ujemajo v prvih $i+1$ bitih, razen če koš $i+1$ ne obstaja\footnote{Kako je to mogoče, da koš ne obstaja, bo razvidno kasneje; vsako vozlišče namreč začne samo z enim košem in koše dodaja po potrebi -- ko spoznava nova vozlišča.}. Potemtakem je košev teoretično lahko največ 160, saj je prav toliko bitov v ID-ju vozlišča. V praksi jih bo mnogo manj\footnote{Veliko košev nakazuje na izvajanje napada Sybil, glej razdelek \ref{tezave}}, kajti verjetnost, da se dva naključna ID-ja ujemata v prvih $i$ bitih, z $i$ pada eksponentno -- $2^{-i} = e^{-i\ln2}$.

Vozlišča ohranjajo svoje usmerjevalne tabele v zdravem stanju tako, da sosedom periodično pošiljajo poizvedbe \texttt{ping} in beležijo odzivnost sosedov. Nedostopne označijo kot take in jih, čim je to možno (čim zasledijo nove), zamenjajo z novo pridobljenimi delujočimi.

Ko vozlišče izve za novo vozlišče, preveri, v kateri koš v usmerjevalni tabeli spada. Če je v košu kaj prostora (bodisi je v njem manj kot $K$ vozlišč bodisi je v njem kakšno vozlišče nedosegljivo), ga vstavi v koš. Če pa na novo najdeno vozlišče sodi v koš $i$, koš $i+1$ pa ne obstaja\footnote{Z drugimi besedami: na novo najdeno vozlišče sodi v isti koš kot bi spadalo vozlišče, katerega usmerjevalno tabelo izpolnjujemo (seveda vozlišče sebe ne vpiše v usmerjevalno tabelo).}, vendar je koš $i$ poln, pa koš $i$ razpolovimo na dva (oziroma dodamo koš $i+1$ in prerazporedimo vnose v usmerjevalni tabeli); v prvega damo vozlišča, katerih ID-ji se ujemajo z $a$\footnote{ID vozlišča, katerega usmerjevalno tabelo gledamo.} v $i$ bitih, ne pa v $i+1$ bitih, v drugega pa vozlišča, katerih ID-ji se z $a$ ujemajo v $i+1$ in več bitih.

\begin{definicija}Metrika XOR $d_\text{XOR}:\{0,1\}^{160}\times\{0,1\}^{160}\to \mathbb{Z}_{2^{160}}$ je definirana kot ekskluzivni ali po komponentah (bitih), ki ga interpretiramo kot nepredznačeno dvojiško celo število.\end{definicija}
\begin{trditev}$d_\text{XOR}$ je res metrika.\end{trditev}
\begin{dokaz}Dokažimo lastnosti metrike:
\begin{itemize}
	\item definitnost: $\forall a,b\in \{0,1\}^{160}: d_\text{XOR}(a,b)=0 \Leftrightarrow a = b$. Velja, ker za ekskluzivni ali velja $\forall a,b\in \{0,1\}: a\oplus b=0\Leftrightarrow a = b$, ničla pa je v nepredznačenem dvojiškem zapisu $(0,0,\dots,0)$.
	\item simetričnost: $\forall a,b\in \{0,1\}^{160}: d_\text{XOR}(a,b)=d_\text{XOR}(b,a)$. Velja, ker velja $\forall a,b\in \{0,1\}:a\oplus b = b\oplus a$.
	\item trikotniška neenakost: Naj bodo $a,b,c\in\{0,1\}^{160}$ poljubni. Velja

$$d_\text{XOR}(a,b)\oplus d_\text{XOR}(b,c)\overset{\text{def}}{=}a\oplus b\oplus b\oplus c=a\oplus c=d_\text{XOR}(a,c).$$ Nadalje velja\footnote{Seštevanje in primerjanje 160-bitnih nizov implicitno definiramo na njihovi predstavitvi kot nepredznačena dvojiška števila v $\mathbb{Z}_{2^{160}}$.} $a\oplus b\leq a+ b$ -- bitni XOR je samo seštevanje brez prehoda, torej bo rezultat kvečjemu manjši. Iz povedanega sledi
	$d_\text{XOR}(a,b)+d_\text{XOR}(b,c)\geq d_\text{XOR}(a,b)\oplus d_\text{XOR}(b,c) = d_\text{XOR}(a,c)$.
\end{itemize}
\end{dokaz}

Ta BitTorrentov DHT deluje na principu metrike XOR. V kontekstu BitTorrentovega DHT-ja so 160-bitni nizi tako ključi v porazdeljeni razpršeni tabeli kot tudi ID-ji vozlišč, kar seveda s pridom izkoristimo.

S prej opisanim upravljanjem z usmerjevalno tabelo sčasoma s sodelovanjem v omrežju vozlišče pride v stanje, ko hrani (beri: je povezano z) le peščico vozlišč, ki so po metriki XOR precej oddaljena od njega, in dosti več takimi, ki so po definirani metriki blizu njega.

\paragraph{Komunikacija} med vozlišči poteka prek UDP in je povsem neodvisna od delovanja protokola BitTorrent (uporablja lahko druga vrata, a isti naslov IP). Celotna vsebina paketa UDP je bkodiran slovar z naslednjimi osnovnimi ključi:

\begin{itemize}
	\item \texttt{y}: Enoznakovni niz, ki določa tip paketa -- paket je bodisi poizvedba (\texttt{q}) bodisi odgovor (\texttt{r}) bodisi napaka (\texttt{e}) (na napake se razen zapisovanja v dnevnik v nalogi ne oziramo in jih ne opisujemo).
	\item \texttt{t}: Niz, ki označuje \textit{transakcijo}. Tvorec poizvedbe ga poljubno določi, odgovor nanjo pa mora vsebovati isto vrednost. Namenjen je korelaciji prejetega odgovora z oddano poizvedbo.
	\item \texttt{q} (samo v poizvedbah): Niz s tipom poizvedbe, možni so:
		\begin{itemize}
			\item \texttt{ping}: Poizvedba je brez argumentov, vozlišča pričakujejo prazen odgovor.
			\item \texttt{find\_node}: Zahteva vsebuje argument \texttt{target} z 20-bajtnim iskalnim nizom. Odgovor pod ključem \texttt{nodes} vsebuje niz s $K$ po metriki XOR iskalnemu nizu najbližjih vozlišč (glede na ID) iz usmerjevalne tabele prejemnika poizvedbe. V nizu si vozlišča sledijo en za drugim, vsako pa je opisano s 26 bajti: 20-bajtni ID, štiribajten naslov IPv4 in dvobajtna vrata UDP. Če vozlišče sodeluje v omrežju IPv6 pa odgovor vsebuje še ključ \texttt{nodes6}, kjer je vsako vozlišče opisano z $20+16+2=38$ bajti~\cite{dht6}.
			\item \texttt{get\_peers}: Zahteva vsebuje argument \texttt{info\_hash} z 20-bajtnim infohashem torrenta, za katerega želimo pridobiti soležnike. Odgovor pod ključem \texttt{values} vsebuje seznam soležnikov (vsak je predstavljen kot niz IP+vrata), ki so se z \texttt{announce\_peer} v vprašano vozlišče vpisali kot soležniki torrenta s podanim infohashem, pod ključem \texttt{nodes} in \texttt{nodes6} pa take podatke, kot bi jih vrnil klic \texttt{find\_node} s parametrom \texttt{target}=\texttt{info\_hash}. Odgovor vsebuje še ključ \texttt{token} z naključnim nizom, potreben za kasnejši klic \texttt{announce\_peer}.
			\item \texttt{announce\_peer}: Zahteva vsebuje niz pod ključem \texttt{token}, prej prejet v poizvedbi \texttt{get\_peers} (torej je treba pred njo vsaj enkrat na tem vozlišču klicati \texttt{get\_peers}), s čimer preprečimo, da bi nepridipravi s ponarejenimi izvornimi naslovi IP~\cite{Ehrenkranz2009} vpisali kogarkoli razen sebe v roj, ter ključa \texttt{info\_hash} z 20-bajtnim infohashem torrenta, v katerega roj se pošiljatelj vpisuje, in \texttt{port} s celoštevilskimi vrati TCP, na katerih je dostopen po protokolu BitTorrent. 
		\end{itemize}
	\item \texttt{a} (samo v poizvedbah): Slovar z argumenti poizvedbe. Poleg zgoraj opisanih vedno vsebuje še ključ \texttt{id} z ID-jem pošiljatelja poizvedbe (vozlišča DHT).
	\item \texttt{r} (samo v odgovorih): Slovar z odgovorom. Poleg zgoraj opisanih vedno vsebuje še ključ \texttt{id} z ID-jem pošiljatelja odgovora (vozlišča DHT).
\end{itemize}

S temi poizvedbami lahko definiramo operaciji \textbf{pridobi soležnike} in \textbf{oznanjaj} (postopek \ref{pridobisoleznikeinoznanjaj}). Zaradi takega postopka se podatki o roju nekega torrenta z infohashem $h$ hranijo pretežno na vozliščih z ID-ji blizu $h$ po metriki XOR. Vsled načina izgradnje usmerjevalne tabele in izdelovanja poizvedb ter naključne izbire ID-jev vozlišč pa do tistega vozlišča (in njegovih tesnih sosedov, ki so en do dva koraka proč), ki je izmed vseh v omrežju najbližje nekemu ID-ju, pridemo v $\log_2 n$ korakih (poizvedbah), kjer je $n$ število vseh vozlišč v omrežju. To je bistveno manj, kot da bi morali vprašati vsako vozlišče, in je ključni razlog, zakaj Kademlia nasploh, ne le BitTorrentov DHT, sploh deluje.

\begin{algorithm}[htbp]
\caption{Postopek za pridobivanje soležnikov torrenta z infohashem $h$ in oznanjanje.}
\label{pridobisoleznikeinoznanjaj}
\begin{algorithmic}[1]
	\Require $T_h=\emptyset \wedge V_h=\emptyset$, $U$ so živa vozlišča v usmerjevalni tabeli % Vhodni pogoji
	\Ensure $T_h$ so soležniki torrenta $h$, $V_h$ so živa vozlišča blizu torrenta $h$ % Izhod
	\Statex % Prazna vrstica za boljšo preglednost
	\Procedure{Pridobivaj soležnike in oznanjaj}{$h$}
		\Loop
			\State $N \gets \argmin_{N\subseteq U,\ \vert N\vert=K} \sum_{n\in N}d_\text{XOR}\left( h, n.\text{id}\right)$
			\ForAll{$v \in V_h$}
				\If{$v$ nedosegljivo}
					\State $V_h \gets V_h \setminus \{v\}$
				\EndIf
			\EndFor
			\ForAll{$n\in N \cup V_h$}
				\State $s, v, z \gets \text{get\_peers}_n\left(h\right)$
				\State $T_h \gets T_h \cup s$
				\State $V_h \gets V_h \cup v$
				\If{$z \wedge n\in V_h$}
					\State $\text{announce\_peer}_v\left(h, z\right)$
				\EndIf
			\EndFor
		\EndLoop
	\EndProcedure
\end{algorithmic}
\end{algorithm}

\paragraph{Opomba} 
Algoritem je opisan poenostavljeno. Dalo bi se ga izboljšati, recimo tako, da ne oznanjamo prvih nekaj iteracij, ker so takrat najdena vozlišča v množici $V_h$ še relativno daleč od $h$ po ID. Prav tako običajno resnične implementacije oznanjajo le na nekaj $h$-ju najbližjih vozlišč v $V_h$ in ne vsem~\cite{chroboczek_dht_c}. Cilj Mainline DHT je informacije o soležnikih torrenta $h$ hraniti le na vozliščih z ID blizu $h$, ker jih bodo iskalci soležnikov iskali prav/zgolj tam.


Še vedno ni očitno, kako se vozlišče prvič poveže v omrežje. Začeti mora s povezavo z vsaj enim obstoječim vozliščem v omrežju. Obstaja več načinov, kako tako začetno vozlišče pridobiti:
\begin{itemize}
	\item Odjemalci, ko izdelujejo datoteke torrent, lahko vanje pod ključ \texttt{nodes} vpišejo nekaj vozlišč iz svoje usmerjevalne tabele DHT v upanju, da bo vsaj kakšno vozlišče še dosegljivo, ko bodo prenašalci torrenta datoteko odprli.
	\item Protokol BitTorrent sam ima razširitev za pridobivanje številke vrat UDP vozlišča DHT odjemalca. Odjemalec, ki ni povezan v DHT, ima pa kak torrent z znanim rojem, pridobljenim recimo iz sledilnika, lahko soležnike povpraša po njihovih vratih UDP, v upanju, da so oni v DHT že povezani~\cite{norberg08}.
	\item Programerji odjemalcev gostijo zagonska vozlišča na znanih naslovih, na katera se njihovi odjemalci povežejo in se tako priključijo v omrežje.
	\item Vsako vozlišče svojo usmerjevalno tabelo trajno shrani na disk, zato da se lahko po ponovnem zagonu v upanju, da je vsaj kako vozlišče še vedno dosegljivo, spet priključi v omrežje.
\end{itemize}

Omenili smo, da je za prenos datotek v torrentu dovolj, da poznamo infohash. To storimo tako, da z DHT najdemo soležnike, za kar po opisu protokola Mainline DHT očitno potrebujemo samo infohash (ključ) v razpršeni tabeli, nato pa se na enega povežemo in od njega pridobimo še datoteko torrent, za kar zopet potrebujemo samo infohash. V praksi to uporabniki pogosto izkoriščajo, saj je lažje nekomu poslati samo kratek URI kot pa relativno večjo datoteko, ki jo
itak % pogovorno -> tako ali tako
prejemnik lahko na podlagi infohasha pridobi iz omrežja. Standarden URI za infohash je oblike \texttt{magnet:?dn=\textbf{ime torrenta}\&xt=urn:btih:\textbf{infohash}}. Ime torrenta sicer ni bistveno za delovanje protokola, vendar ga vseeno zapišemo v URI, da ima odjemalec kaj pokazati uporabniku, preden pridobi metapodatke.

\section{Bencoding}\label{bencoding}
Večina struktur (datoteke torrent, paketi DHT, \dots) je serializirana v namensko razvito obliko bencoding (bkodiranje). Le-ta omogoča serializacijo preprostih podatkovnih tipov, ki se uporabljajo v BitTorrentu, v zaporedje bajtov. Oblika bkodiranja je dovolj preprosta, da je hkrati berljiva s prostim očesom in razčlenljiva s preprostim razčlenjevalnikom. 
\begin{itemize}
	\item Nizi bajtov so serializirani v njihovo dolžino kot desetiško številko, dvopičje in bajte niza same. Niz \enquote{diploma} bo torej serializiran v \texttt{7:diploma}. 
	\item Cela števila so serializirana v črko \texttt{i}, desetiško zapisano vrednost številke in črko 
	\texttt{e}. Število 325858382 bo torej serializirano v \texttt{i325858382e}.
	\item Seznami so serializirani v črko \texttt{l}, ki ji en za drugim sledijo serializirani elementi poljubnih tipov izmed vseh štirih navedenih, in črko \texttt{e}. Seznam \mintinline{json}{[23, "julij", 2026]} bo torej serializiran v \texttt{li23e5:juliji2026ee}.
	\item Slovarji so serializirani v črko \texttt{d}, ki ji en za drugim izmenično sledijo serializirani ključi (nizi) in vrednosti poljubnih tipov izmed vseh štirih navedenih, in črko \texttt{e}. Slovar \mintinline{json}{{"msg_type": 0, "piece": 123}} bo torej serializiran v \texttt{d8:msg\_typei0e5:piecei123ee}. Ključi morajo biti leksikografsko urejeni.
\end{itemize}

V nalogi bomo za večjo preglednost strukture pisali v obliki JSON~\cite{rfc8259}, ker je bolj berljiva od bkodiranja.
\chapter{Metodologija}
\label{metodologija}
Kot je razvidno iz algoritma \ref{pridobisoleznikeinoznanjaj} (pridobivanje soležnikov in oznanjanje), vozlišča poizvedbe \texttt{get\_peers} in \texttt{announce\_peer} pošiljajo prek kar nekaj drugih vozlišč, torej s sodelovanjem v omrežju vsako vozlišče sodeluje pri razreševanju mnogih poizvedb drugih članov omrežja. Normalni odjemalci za BitTorrent na take poizvedbe vestno po najboljši moči odgovorijo, vendar jih nikamor ne shranjujejo\footnote{Razen seveda v primeru \texttt{announce\_peer}, ko vozlišča shranijo podatke o soležnikih.}, ker jim ni pomembno, katere vsebine prenašajo drugi uporabniki.

Prav na ti dve poizvedbi, \texttt{get\_peers} in \texttt{announce\_peer}, ki obiščeta vozlišče, se bomo osredotočili v tej nalogi. Poleg tega, da bomo nanju vestno odgovarjali, si bomo zapomnili tudi infohashe torrentov, ki jih take poizvedbe vsebujejo. Tako bomo samo s sodelovanjem v omrežju kot eno samo vozlišče DHT pridobili ogromne količine infohashev torrentov. Nato se bomo prav s pomočjo DHT vpisali v roje teh najdenih torrentov z algoritmom \ref{pridobisoleznikeinoznanjaj} in čim bomo našli soležnike, se bomo nanje povezali in od njih zahtevali metapodatke po metodi, opisani v razdelku \ref{metadata}. Ko bomo naposled metapodatke prejeli in jih shranili na disk skupaj z informacijo, od koga smo jih prejeli (naslov IP, vrata in program ter različica odjemalca), se bomo izpisali\footnote{Izpis iz roja ni definiran v standardu, toda štejemo, da je nekdo vpisan v roj, če aktivno pošilja poizvedbe \texttt{announce\_peer}. Čim jih neha, bodo sčasoma vozlišča izbrisala njegov obstoj iz svoje shrambe.} iz roja za ta torrent in tudi tega torrenta v bodoče več ne bomo prenašali.

Podatke bomo zajemali v več zajemih v različnih časovnih obdobjih, da bomo lahko primerjali populacijo torrentov in uporabnikov v obtoku skozi čas.

Pozoren bralec opazi, da bomo tako pretežno zbirali infohashe in posledično torrente z ID-ji, ki so po metriki XOR blizu ID-ja našega opazovalnega vozlišča, kar na prvi pogled izgleda v kontradikciji s ciljem o reprezentativnosti podatkov. K sreči zgoščevalna funkcija SHA-1, uporabljena za računanje infohasha, infohasha ne izbere pristransko glede na podatke, ki jih zgosti, zato so kljub pristranskemu zajemu podatkov glede na infohash metapodatki sami vseeno enakomerno vzorčeni; neenakomerno vzorčenje glede na zgoščeno vrednost neke vsebine vseeno privede do enakomernega vzorčenja vsebine zaradi razpršilnega značaja zgoščevalne funkcije~\cite{Menezes1996,wikihashuniformity}. Nenazadnje se DHT na to zanaša.

Pristranskost, ki se pojavi s takim načinom zbiranja poizvedb, je pristranskost zaradi popularnosti torrentov. Naše vozlišče bo slišalo veliko več poizvedb za popularne torrente. Toda vsak torrent prenesemo natanko enkrat; ko ga zaznamo drugič, ga ne prenesemo, zato bo v analizi štet le enkrat.

Domnevamo, da je za pridobivanje reprezentativnega vzorca celotnega omrežja tu predstavljen način zajema ustreznejši kot denimo pasivno prisluškovanje povezavam na usmerjevalnikih mrežnih operaterjev, ki bi bilo precej geografsko zaznamovano -- najbrž bi zaznali dosti več torrentov, ki jih prenašajo lokalni uporabniki.

Po prejemu dovolj velikega korpusa torrentov bomo vse torrente razčlenili in na njih izvedli analize populacije, denimo kakšne vrste datotek so popularne v omrežju BitTorrent, kakšna je njihova velikost, iz katerih držav so uporabniki omrežja, katere različice programske opreme za odjem torrentov uporabljajo in podobno.

\chapter{Implementacija}
\label{implementacija}
Naše vozlišče bo hkrati v veliko rojih torrentov, zato bo komuniciralo z veliko drugimi vozlišči DHT. Pričakujemo lahko, da bo v veliko usmerjevalnih tabelah, saj bo pošiljalo veliko poizvedb, torej bo veliko poizvedb tudi prejemalo. Ne želimo, da bi naši odgovori na poizvedbe zamujali, saj bi nas v takem primeru druga vozlišča iz svojih usmerjevalnih tabel zaradi neodzivnosti odstranila.

Odločili smo se za implementacijo vseh v nalogi opisanih protokolov ročno, da lahko nadziramo vse korake njihovega izvajanja in jih prilagodimo za zajem podatkov, ne za prenos datotek, kot to seveda pričakovano počno knjižnice BitTorrent. Minimalističen odjemalec za BitTorrent, ki zna le prenašati metapodatke prek TCP, minimalistično vozlišče DHT, ki pravilno odgovarja na vse poizvedbe in pošteno hrani vpisane soležnike, vendar
% se zavoljo lažje implementacije požvižga na poslane napake s strani drugih vozlišč, % požvižga je pogovorno -> ne obravnava
zavoljo lažje implementacije ne obravnava prejetih napak s strani drugih vozlišč,
in visokonivojski razčlenjevalnik in kodirnik bkodiranja (tak, ki sprejme tudi malce nestandardno bkodiranje, denimo neurejen vrstni red ključev, a se standardov pri kodiranju strogo drži~\cite{postel1980tcp}), smo spisali v programskem jeziku c.

Ker program ni računsko obremenjen, pač pa komunikacijsko (IO), v celoti teče v eni niti in uporablja dogodkovno zanko in nobenih sistemskih klicev, ki blokirajo izvajanje. Jedro izvajanja je dogodkovna zanka, implementirana s sistemskim klicem \texttt{poll(2)}~\cite{poll2}. Program večino časa spi, zbudi se bodisi periodično na nastavljiv časovni interval, v našem primeru $\qty{10}{\second}$, bodisi takoj, ko prejme kakšen klic iz okolja; to je lahko aktivnost (možno branje/pisanje) na kaki izmed povezav TCP za protokol BitTorrent ali pa prejem kakega paketa UDP od oddaljenega vozlišča DHT -- to je lahko tako nova poizvedba kot tudi odgovor na kako našo, poslano prej.

Stanje našega programa med drugim obsega:
\begin{itemize}
	\item njegov ID
	\item obstoječe internetne povezave v svet
	\item usmerjevalno tabelo za DHT
	\item torrente, katerih metapodatke želimo prenesti (smo v njihovem roju) in njihove množice $T_h$ in $V_h$
	\item slovar, s katerim vozlišče DHT hrani soležnike, katerih veljavne poizvedbe \texttt{announce\_peer} je program prejel
\end{itemize}

\section{Knjižnice}

Glavnino implementacije smo zasnovali kot dve ločeni knjižnici, vsaka s svojimi vmesniki.

\subsection{Knjižnica za bencoding}

Ker je bencoding po podatkovnih tipih podoben JSON-u, smo knjižnico zasnovali približno tako, kot je zasnovana cjevska knjižnica cJSON~\cite{cjson}
za delo z JSON-om. Vsak tip je predstavljen s strukturo (koda~\ref{structbencoding}), ki deluje kot oprimek funkcij za denimo iskanje ključa v slovarju, dodajanje ključa v slovar, spreminjanje seznama in iteriranje po njem.

Implementirali smo tudi metodi za izpis strukture v zaporedje bajtov in razčlenjevanje iz zaporedja bajtov nazaj v interno drevesno strukturo.

\begin{center}
\captionof{listing}{Struktura vsakega elementa v knjižnici za bkodiranje\footnote{Nekatere interne komponente so zaradi berljivosti izpuščene.}}
\label{structbencoding}
\begin{minted}{c}
struct bencoding {
	struct bencoding * next; // elem ni član slovarja/seznama => NULL
	struct bencoding * prev;
	struct bencoding * child; // le če je slovar/seznam in ima otroke
	struct bencoding * parent; // NULL za korenski element
	enum benc type; // tip tega elementa in dodatne nastavitve
	struct bencoding * key; // ključ elementa, le v slovarjih
	char * value; // vsebina elementa in \0. slovar/seznam => NULL
	size_t valuelen; // dolžina pri nizih (lahko vsebujejo \0)
	long int intvalue; // vrednost celoštevilskih elementov
	int index; // smiselno le pri slovarjih in seznamih
};
\end{minted}
\end{center}

Nekaj ključnih funkcij, ki operirajo na teh oprimkih:
\begin{itemize}
	\item \texttt{bstr} in \texttt{bnum}: niz ali številko ovije v \mintinline{c}{struct bencoding}
	\item \texttt{b2json}: pretvori \mintinline{c}{struct bencoding} v JSON
	\item \texttt{binsert} in \texttt{bdetach}: v podan seznam ali slovar vstavi/odstrani element
	\item \texttt{bdecode} in \texttt{bencode}: razčleni bkodirano strukturo v \mintinline{c}{struct bencoding} ali stori obratno
	\item \texttt{bpath}: najde element slovarja na dani poti (v primeru gnezdenih slovarjev)
	\item \texttt{bval}: najde vrednost v slovarju
\end{itemize}

\subsection{Knjižnica za DHT in BitTorrent}

Ta knjižnica skrbi za omrežne povezave, vse zahteve DHT in vzdrževanje povezav TCP za BitTorrent. Uporabniku poda seznam oprimkov vtičnic, ki jih mora opazovati s \texttt{poll} in ob dogajanju na njih obvestiti knjižnico, način za vzpostavitev povratnih klicev v primeru najdenih infohashev in nekaj funkcij za vpliv na delovanje knjižnice, denimo za dodajanje torrentov za prenos ter zagonskih vozlišč in funkcijo za opravljanje periodičnega dela, torej za pridobivanje soležnikov, oznanjanje in preverjanje stanja usmerjevalne tabele.

V izseku kode~\ref{dhtstructs} je navedenih nekaj struktur za boljše razumevanje sestave knjižnice. Vsa komunikacija knjižnice poteka prek sklada IPv6, za povezavo v omrežje IPv4 se poslužuje V4MAPPED~\cite{rfc4038}. % https://datatracker.ietf.org/doc/html/rfc4038\#section-4.2

\begin{center}
\captionof{listing}{Nekaj struktur iz knjižnice za DHT in BitTorrent\footnote{Nekatere interne komponente in strukture so zaradi berljivosti izpuščene.}}
\label{dhtstructs}
\begin{minted}{c}
struct node { // opisnik oddaljenega vozlišča
	unsigned char id[20];
	struct sockaddr_in6 addr; // ::ffff:0.1.2.3 za IPv4 (V4MAPPED)
	int unanswered; // neodgovorjenih zahtev od zadnjega paketa
	time_t last_received; // čas prejema zadnjega paketa od vozlišča
	time_t last_sent; // čas pošiljanja zadnjega paketa
};
struct bucket { // opisnik koša v usmerjevalni tabeli
	unsigned char id[20]; // koš vsebuje [id, next->id)
	struct node * nodes;
};
enum state { // stanja BitTorrent TCP povezave
	blank = 0,
	handshake_sent = 1,
	handshake_received = 1 << 1,
	extension_sent = 1 << 2,
	extension_received = 1 << 3,
	incoming = 1 << 4,
	outgoing = 1 << 5
};
struct torrent { // opisnik torrenta ne nujno v prenosu
	unsigned char ut_metadata; // podtip oddaljenega soležnika
	unsigned char ut_pex; // podtip oddaljenega soležnika
	enum state state; // stanje TCP povezave
	void (* disconnection)(struct torrent *); // signal uporabniku, da shrani metapodatke v datoteko
	unsigned char hash[20]; // infohash
	struct peer * peers; // množica $T_h$
	struct node * nodes; // množica $V_h$
	int progress; // koliko koščkov metapodatkov imamo
	int size; // kako veliki so metapodatki torrenta
	unsigned char * metadata; // medpomnilnik za metapodatke
};
struct dht { // glavni oprimek knjižnice
	unsigned char id[20]; // id našega vozlišča
	int socket; // vtičnica za UDP 
	unsigned char secret[16]; // za računanje žetonov brez stanja
	struct bucket * buckets; // usmerjevalna tabela IPv4
	struct bucket * buckets6; // usmerjevalna tabela IPv6
	struct torrent * torrents; // torrenti, ki jih želimo prenesti
	void (* possible_torrent)(struct dht *, const unsigned char *, struct torrent *); // signal uporabniku, da je bil najden nov infohash
};
\end{minted}
\end{center}

Nekaj internih in javnih funkcij knjižnice:

\begin{itemize}
	\item \texttt{closer}: primerja razdalje dveh 20-bajtnih ID-jev do ciljnega po metriki XOR
	\item \texttt{sendb}: pošlje vozlišču bkodiran objekt kot paket UDP
	\item \texttt{find\_node}, \texttt{get\_peers}, \texttt{announce\_peer}: pošlje poizvedbo oddaljenemu vozlišču
	\item \texttt{persistent}: serializira stanje, potrebno za shranjevanje na disk, v seznam bajtov (ID, usmerjevalna tabela, ...)
	\item \texttt{token} in \texttt{valid}: podporni funkciji za kriptografske žetone \texttt{token} v DHT-jevskih \texttt{get\_peers} in \texttt{announce\_peer}
	\item \texttt{add}, \texttt{subtract}, \texttt{divide}, \texttt{midpoint}, \texttt{distance}: aritmetika na 20-bajtnih številih in metrika
	\item \texttt{split}, \texttt{bucket\_grade}: razdeli koš, preveri njegovo zdravje
	\item \texttt{replied}: označi vozlišče kot zdravo, saj je odgovorilo na našo poizvedbo
	\item \texttt{potential\_node}: najdeno novo vozlišče, ki ga lahko dodamo v usmerjevalno tabelo
	\item \texttt{add\_torrent}: doda torrent, bodisi kot uporabniški klic, naj se začne prenos metapodatkov, bodisi kot posledica poizvedbe \texttt{announce\_peer}
	\item \texttt{handle}: obdela dohodni paket DHT, po potrebi nanj odgovori
	\item \texttt{periodic} in \texttt{refresh}: uporabnik ju periodično kliče; preverjata zdravje usmerjevalne tabele, opravljata ostalo periodično delo, opisano zgoraj
	\item \texttt{tcp\_work}: upravlja s povezavami TCP za BitTorrent, od rokovanja do prenosa metapodatkov -- napolni izhodne medpomnilnike za TCP in prebere vhodne
	\item \texttt{work}: uporabnik funkcijo pokliče, ko \texttt{poll(2)} vrne
\end{itemize}

\subsection{Program za obdelavo metapodatkov}

Spisali smo kratek program v jeziku c za razčlenjevanje datotek torrent, ki omogoča hitro razčlenjevanje, in knjižnico v jeziku python za isti namen. Analizo smo opravljali s pythonom v okolju Jupyter Notebook~\cite{Kluyver2016jupyter} in pri tem koristili to slednjo knjižnico.

\section{Težave}\label{tezave}

\subsection{Napad Sybil}

Vozlišča si po standardu DHT Kademlia ID-je res izbirajo naključno, vendar omrežje tega v osnovni obliki\footnote{Obstaja ukrep, ki napade Sybil malce oteži~\cite{norberg14}, vendar ga zaradi svoje vzvratne nekompatibilnosti z originalnim standardom DHT ni mogoče implementirati, ne da bi diskriminirali odjemalce, ki ga ne implementirajo. Za potrebe zajema statistično reprezentativnega vzorca populacije torrentov smo se torej odločili, da BEP-0042 ne implementiramo.} nikakor ne zagotavlja. Vozlišče si lahko ob zagonu izbere poljuben ID, ga tekom programa poljubno spreminja in se različnim vozliščem oglaša z različnimi ID-ji, v najhujšem primeru pa se lahko celo istemu vozlišču oglaša z več različnimi ID-ji z več različnih internetnih naslovov.

Gre za napad Sybil~\cite{sybil}, katerega cilj je onesposobitev vozlišča v DHT. Napadalec se pretvarja, da je veliko vozlišč hkrati, in zastrupi usmerjevalno tabelo žrtve. Nadvse učinkovito je napad izveden tako, da so ponarejeni ID-ji takšni, ki so blizu ID-ja žrtve, torej za vsakega izmed teoretično največ 160 košev po $K$ ID-jev na koš (napadalcu je ID žrtve znan, torej ve, kako sporne ID-je konstruirati). Ko je tabela napolnjena, je žrtev zadušena v poplavi izmišljenih ID-jev, večina povezav v njeni tabeli pa vodi do napadalca, ki na njih odgovarja neiskreno (si recimo izmišljuje soležnike in sosednja vozlišča). S tem je omejena njena sposobnost izdelovanja poizvedb v porazdeljeno razpršeno tabelo in shranjevanje soležnikov.

Napad Sybil lahko napadalcem na vzvratno kompatibilen način otežimo tako, da zaznamo neverjetno nenadno večanje usmerjevalne tabele ($\log_2n$, kjer je $n$ število vseh članov omrežja na svetu, je skozi čas praktično konstanta~\cite{dhtsize,dhtsizeboljsi}), ne dodajamo v usmerjevalno tabelo dvakrat istega naslova IP, ne menjamo zdravih obstoječih vozlišč v tabeli z novimi in ne polnimo košev več kot do $K$ vozlišč.

Naša implementacija šteje, da se je napad Sybil zgodil, ko število košev v njeni usmerjevalni tabeli preseže 64. Da so v usmerjevalni tabeli samo iskrena vozlišča, bi bilo sila neverjetno, saj bi pomenilo, da je neko vozlišče z naključno izbiro ID-ja zadelo enakih prvih 64 bitov kot naš prav tako naključno izbran ID. Ko napad zazna, zbriše celotno usmerjevalno tabelo, zamenja svoj ID, se ponovno priključi v omrežje (z uporabo vozlišč za zagon, vpisanih v DNS \texttt{\_dht.\_udp.travnik.sijanec.eu. IN SRV}) in nadaljuje z izvajanjem.

% Primer stanja usmerjevalne tabele, ko se zgodi napad Sybil, je na izseku kode~\ref{sybil} (izpis našega programa) v prilogi.

\subsection{Ozko grlo omrežne opreme}

Naša implementacija pošilja in prejema veliko paketov UDP v sekundi (ob vrhuncih tudi okoli 2000 paketov v sekundi). Čeprav porablja malo pasovne širine, le nekaj \qty{}{\mega\bit\per\second}, smo imeli tolikšne težave z zajemom na nekaterih modemih GPON, da je bilo v izogib izgubljenim paketom potrebno zmanjšati frekvenco periodičnega dela knjižnice za DHT in zmanjšati število torrentov, ki jih knjižnica hkrati prenaša.

Teh težav ni bilo na boljši mrežni opremi na strežnikih v Grčiji (GRNET)~\cite{okeanos} in strežnikih na Fakulteti za računalništvo in informatiko UL, le na strežniku na rezidenčnem priključku pri operaterju T-2, pa še to le zaradi slabe terminalske opreme (CPE).

\chapter{Zajeti podatki in rezultati}
\label{zajetipodatkiinrezultati}
Podatke smo z našim izdelanim programom zajemali v štirih zajemih, prikazanih v tabeli~\ref{zajemi}. Skupna velikost prenesenih datotek torrent znaša \qty{78,8}{\gibi\byte}. Velikost datotek v tabeli se nanaša na datoteke, na katere se torrent nanaša. Njih seveda nismo prenašali, samo metapodatke o njih. Njihova imena in dolžine so nam znane, vsebina pa ne.

\begin{table}[htbp]
	\centering
	\caption{Zajemi, uporabljeni v analizi. Zajemi so trajali 16, 31, 5 in 84 dni (po vrsti). Stolpec $p$ vsebuje periodo -- koliko časa je v povprečju preteklo med dvema prenosoma torrenta. Izračunano na podlagi časa zajema torrenta, ki smo ga shranili v torrent.}
	\label{zajemi}
	\begin{tabular}{ccccc}
\hline
obdobje & lokacija & torrentov & datotek & $p$ \\
\hline
2023-01--2023-02 & T-2 GPON & 47843 & 3084321, \qty{259}{\tebi\byte} & \qty{29}{\second} \\ % 16 dni
2023-03--2023-05 & \~{}okeanos~\cite{okeanos} & 414620 & 17165425, \qty{1891}{\tebi\byte} & \qty{6}{\second} \\ % 31 dni
2024-02--2024-02 & T-2 GPON & 62108 & 3725125, \qty{344}{\tebi\byte} & \qty{7}{\second} \\ % 5 dni
2026-04--2026-07 & FRI & 1021992 & 80886646, \qty{6837}{\tebi\byte} & \qty{7}{\second} \\ % 84 dni
\hline
\end{tabular}%
\end{table}

Analizirali smo v okolju Jupyter Notebook~\cite{Kluyver2016jupyter} in grafe risali s knjižnico matplotlib~\cite{Hunter:2007}. Analizo smo izvajali na računalniku na FRI na 16 jedrih Opteron 6380 in zanjo porabljali \qty{48}{\gibi\byte} pomnilnika. Analiza vseh podatkov skupaj se izvaja slabe tri ure.

\section{Odjemalci}

Za analizo uporabe odjemalcev smo za vsako posamezno leto primerjali zastopanost odjemalca (brez različice) v prejetih torrentih. Rezultati so prikazani na sliki~\ref{odjemalci}.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/odjemalcipoletih.pgf}
		\caption{Popularnost odjemalcev po letih.}
		\label{odjemalci}
	\end{center}
\end{figure}

% \section{Ključi v slovarju \texttt{info}}
% 
% Na celotni zbirki torrentov smo analizirali pojavnost ključev v slovarju \texttt{info}. Nekateri izdelovalci torrentov namreč v slovar \texttt{info} dodajo nestandardne ključe. Njihova frekvenca je prikazana na sliki~\ref{kljuci}.
% 
% \begin{figure}[htbp]
% 	\begin{center}
% 		\input{slike/keys.pgf}
% 		\caption{Pojavnost ključev v slovarju info na celotnem korpusu.}
% 		\label{kljuci}
% 	\end{center}
% \end{figure}

\section{Tipi datotek}

Frekvenco po tipih datotek, ki se prenašajo, lahko merimo na več načinov. Ustrezen način je za vsak tip datoteke izmeriti število torrentov, v katerih ta tip predstavlja največjo velikost (slika~\ref{tipi}). Alternativna načina merjenja bi bila število datotek z nekim tipom (slika~\ref{stevilo}) in skupna velikost datotek s tem tipom (slika~\ref{velikost}), ki nista ustrezna, saj bi prednost dala v prvem primeru tipom, ki se navadno pošiljajo kot kopica majhnih datotek (denimo slike ali glasba), v drugem primeru pa tipom, ki zavzemajo dosti velikosti na disku, torej recimo filmom.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/po številu po velikosti največjih datotek torrentov.pgf}
		\caption{Tipi glede na število torrentov, pri katerih tip predstavlja glavnino velikosti.}
		\label{tipi}
	\end{center}
\end{figure}

Ker vpogleda v vsebino datotek zaradi načina zajema nimamo, lahko tip datoteke in posledično vrsto vsebine določimo le na podlagi imena oziroma natančneje datotečne končnice. V primeru stisnjenih datotek (zip) ne moremo dobro določiti, katere datoteke vsebuje.

Kot pričakovano so najpogostejša vrsta datotek videovsebina, zato smo s pomočjo pythonske knjižnice~\cite{parse_torrent_title} kategorizirali vse videovsebine glede na kodek in ločljivost (slika~\ref{kodeklocljivost}). Žal podatki temeljijo zgolj na metapodatkih (naslovih) in ne na vsebini datotek, torej izpustimo znaten delež populacije, ki kodeka ali ločljivosti v imenu nima vpisanega.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/kodeki.pgf}
		\caption{Ločljivosti in kodeki videovsebin iz naslovov datotek.}
		\label{kodeklocljivost}
	\end{center}
\end{figure}

\section{Različice programske opreme}
\label{razlicicesection}

Osredotočili smo se na odjemalec qBittorrent~\cite{qbittorrent}, saj je najbolj zastopan v prenesenem korpusu. Pojavnost najdenih različic skozi leta (slika~\ref{razlicice}) potrjuje hipotezo, da bodisi uporabniki res posodabljajo programsko opremo bodisi v omrežje prihajajo novi uporabniki.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/razlicice.pgf}
		\caption{Različice programske opreme qBittorrent skozi leta.}
		\label{razlicice}
	\end{center}
\end{figure}

\section{Popularnost po državah}

Z uporabo podatkovne zbirke~\cite{maxmindgeoip2} smo določili, iz katere države so naslovi IP, od katerih smo prenesli torrente. Na podlagi tega ocenjujemo popularnost uporabe protokola BitTorrent v posamezni državi (slika~\ref{drzave}). Podatkovno zbirko, ki smo jo uporabili za določanje države, smo prenesli julija 2026, zato mogoče vsebuje netočne podatke za naslove iz 2023, saj internetni naslovi, čeprav redko, lahko menjajo državo.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/drzave.pgf}
		\caption{Države, od katerih smo prejeli največ metapodatkov, in Slovenija skozi leta. Oznake držav po~\cite{iso3166-1}.}
		\label{drzave}
	\end{center}
\end{figure}

Opazimo, da je bilo veliko torrentov prejetih s Finske v letu 2023, kasneje pa se je število bistveno zmanjšalo. Zakaj? Podroben pogled pokaže, da je \qty{72}{\percent} torrentov, prejetih s Finske, naložil isti nalagalec ali ista skupina ljudi. Prejeti so bili iz samo osmih različnih naslovov IP. Nalagalec sodeč po nedostopnih domenah iz naslovov torrentov ne nalaga več oziroma ne vzdržuje svojih najetih strežnikov na Finskem.

\section{Prejetih torrentov na dan}

Graf na sliki~\ref{prejetinadan} prikazuje, koliko torrentov na dan smo prejeli med zajemom leta 2026.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/prejetinadan.pgf}
		\caption{Količina zajetih torrentov na dan v zajemu leta 2026. Zajem smo na začetku nekajkrat prekinili, vidna je tudi ena večdnevna prekinitev.}
		\label{prejetinadan}
	\end{center}
\end{figure}

\section{Velikost koščka}

Izvorna različica BitTorrenta, kot smo omenili, v torrentih vsebuje zgoščene vrednosti koščkov dolžine, določene v datoteki. Na sliki~\ref{koscki} smo prikazali najpopularnejše dolžine koščka in primerjali dolžino koščka z velikostjo celotnega torrenta. Odjemalci namreč prav glede na velikost predlagajo neko dolžino koščka, vendar jo lahko uporabniki pred izdelavo torrenta spremenijo.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/kosi.pgf}
		\caption{Porazdelitev velikosti koščkov.}
		\label{koscki}
	\end{center}
\end{figure}

\section{Razširjenost IPv6}

Na sliki~\ref{ipv6} je opazna rast razširjenosti IPv6 skozi leta. Ocenimo jo kot razmerje med torrenti, prenesenimi prek IPv6 in vsemi prenesenimi torrenti. Podobno statistiko o prenosu torrentov glede na omrežni protokol za vsako državo posebej smo prikazali v sliki~\ref{ipv6drzave}.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/ipv6.pgf}
		\caption{Rast uporabe IPv6 skozi leta.}
		\label{ipv6}
	\end{center}
\end{figure}
\begin{figure}[htbp]
	\begin{center}
		\input{slike/ipv6drzave.pgf}
		\caption{Rast uporabe IPv6 skozi leta po državah.}
		\label{ipv6drzave}
	\end{center}
\end{figure}

\section{Piratska vsebina}

V članku~\cite{WATTERS2011} iz 2011 delež piratske vsebine v omrežju BitTorrent ocenijo na~\qty{97}{\percent}. Podobno analizo bomo avtomatizirano izdelali tudi na našem korpusu. Z odprtim jezikovnim modelom Qwen3.6-35B-A3B~\cite{qwen3.6-35b-a3b}, ki smo ga z orodjem Ollama~\cite{ollama} poganjali na Arnesovi HPC gruči na dveh grafičnih karticah Tesla V100S, 2799 torrentom (vsem tistim iz zajema leta 2026, katerih infohash se začne z bajtom \texttt{0x4a}) priredili oznako legalnosti in oznako tipa vsebine izmed tipov, ki so jih uporabili v~\cite{WATTERS2011}, da lahko dobljene rezultate primerjamo. Deleže torrentov po kategorijah prikazuje tabela~\ref{kategorije}.

Pri 441 torrentih (\qty{15.76}{\percent}) je bil izhod modela v neustrezni obliki. V tem primeru smo isti pogovorni seji dodali vnovičen poziv, naj se izhod popravi.

\begin{table}[htbp]
\centering
\caption{Torrenti iz vzorca velikosti 2799 po kategorijah, določenih z jezikovnim modelom.}
\label{kategorije}
\begin{tabular}{@{}r l p{7cm}@{}}
\hline
kategorija & število torrentov & delež \\
\hline
anime & 263 & \qty{9.40}{\percent} \\
book & 175 & \qty{6.25}{\percent} \\
childporn & 23 & \qty{0.82}{\percent} \\
documentary & 28 & \qty{1.00}{\percent} \\
game & 107 & \qty{3.82}{\percent} \\
hentai & 86 & \qty{3.07}{\percent} \\
movie & 383 & \qty{13.68}{\percent} \\
music & 321 & \qty{11.47}{\percent} \\
pictures & 35 & \qty{1.25}{\percent} \\
porn & 700 & \qty{25.01}{\percent} \\
software & 114 & \qty{4.07}{\percent} \\
tvshows & 426 & \qty{15.22}{\percent} \\
other & 101 & \qty{3.61}{\percent} \\
unknown & 21 & \qty{0.75}{\percent} \\
various & 14 & \qty{0.50}{\percent} \\
error & 2 & \qty{0.07}{\percent} \\
\hline
\end{tabular}
\end{table}

Po legalnosti smo torrente z jezikovnim modelom razločili v skupine, prikazane v tabeli~\ref{legalnosti}.

\begin{table}[htbp]
\centering
\caption{Torrenti iz vzorca velikosti 2799 po legalnostih, določenih z jezikovnim modelom.}
\label{legalnosti}
\begin{tabular}{@{}r l p{7cm}@{}}
\hline
legalnost & število torrentov & delež \\
\hline
piracy & 2603 & \qty{93.00}{\percent} \\
legitimate & 66 & \qty{2.36}{\percent} \\
illegal & 52 & \qty{1.86}{\percent} \\
unknown & 76 & \qty{2.72}{\percent} \\
error & 2 & \qty{0.07}{\percent} \\
\hline
\end{tabular}
\end{table}

\section{Rekordni primerki v populaciji}

Tabeli~\ref{najvdatotekeslo} in~\ref{najvdatoteke} prikazujeta največje odkrite datoteke v Sloveniji in največje odkrite datoteke nasploh.

\begin{table}[htbp]
\centering
\caption{10 največjih posameznih datotek iz Slovenije.}
\label{najvdatotekeslo}
\begin{tabular}{@{}r l p{7cm}@{}}
\hline
velikost & infohash & ime \\
\hline
\qty{155}{\gibi\byte} & \href{magnet:?xt=urn:btih:ceafd85e89ac4d59f27dd68f77636af214d4434d}{\texttt{ceafd85e}} & rune-stalker.2.{\allowbreak}heart.of.chornobyl.v1.7.iso \\
\qty{113}{\gibi\byte} & \href{magnet:?xt=urn:btih:5b9c536774168f2f272ca612d2b819b152972cb7}{\texttt{5b9c5367}} & repack-warhammer.3.iso \\
\qty{95}{\gibi\byte} & \href{magnet:?xt=urn:btih:b3af5e6dbd51409ca88995d75a1fd5490b6a7854}{\texttt{b3af5e6d}} & Content/DOSMagazines.zip \\
\qty{88.4}{\gibi\byte} & \href{magnet:?xt=urn:btih:a7da1c58c32735c72228e486e385ad6ac66fb046}{\texttt{a7da1c58}} & rune-grand.theft.auto.v.enhanced.iso \\
\qty{82.4}{\gibi\byte} & \href{magnet:?xt=urn:btih:a5a187290a4b27219d9d2054a7281a908270df9d}{\texttt{a5a18729}} & Dune.1984.2160p.BluRay.REMUX.{\allowbreak}HEVC.DTS-HD.MA.5.1-FGT.mkv \\
\qty{78}{\gibi\byte} & \href{magnet:?xt=urn:btih:09b53cde6f88e3884f5696bc350644f70832b86a}{\texttt{09b53cde}} & The Long Kiss Goodnight 1996 2160p UHD Blu-ray Remux HEVC DV TrueHD 7.1 Atmos-HDT.mkv \\
\qty{76.6}{\gibi\byte} & \href{magnet:?xt=urn:btih:07215cb998c5cd8fcf8476757ea7216deb9a4e2b}{\texttt{07215cb9}} & Setup-1.bin \\
\qty{69.4}{\gibi\byte} & \href{magnet:?xt=urn:btih:99bf377edfb38d1982c0342907ea02dfaa71ef3f}{\texttt{99bf377e}} & Blade.Runner.2049.Open.Matte.{\allowbreak}INTERNAL.HDR-X.DoVi.Ver.1.0.4.TrueHD.Atmos.7.1-TEKNO3D.mkv \\
\qty{64.5}{\gibi\byte} & \href{magnet:?xt=urn:btih:98f974dd97493bc7d4f6928f634bcae0458f981c}{\texttt{98f974dd}} & In.Bruges.2008.4K.HDR.DV.2160p.{\allowbreak}BDRemux Ita Eng x265-NAHOM.mkv \\
\qty{62.4}{\gibi\byte} & \href{magnet:?xt=urn:btih:c15a97ca776530bae512c4c4e72da0a95d9c9960}{\texttt{c15a97ca}} & Shrek.2001.2160p.BluRay.REMUX.{\allowbreak}HEVC.DTS-X.7.1-FGT.mkv \\
\hline
\end{tabular}
\end{table}
% \begin{table}%[htbp]
% \centering
% \caption{10 največjih torrentov (po skupni velikosti)}
% \label{najvtorrenti}
% \begin{tabular}{@{}r l p{7cm}@{}}
% \hline
% velikost & infohash\footnote{Za lepši prikaz okrajšan, v celoti dostopen kot povezava na besedilu.} & ime \\
% \hline
% \qty{17.2}{\tebi\byte} & \href{magnet:?xt=urn:btih:1edfd986f73cc2875561050c239c3e42d1e459bc}{\texttt{1edfd986}} & Minerva\_Myrient \\
% \qty{16.3}{\tebi\byte} & \href{magnet:?xt=urn:btih:9210e4c2d6fc592175f9bd18ab538bb53e317d4d}{\texttt{9210e4c2}} & nrel-pds-nsrdb-partial \\
% \qty{11.2}{\tebi\byte} & \href{magnet:?xt=urn:btih:522c00588bab73a54a2044fe8da082043885d980}{\texttt{522c0058}} & Movies \\
% \qty{7.26}{\tebi\byte} & \href{magnet:?xt=urn:btih:14261f76757f4ddd401364fc4648b4d5bca164d5}{\texttt{14261f76}} & e-hentai raws JAP Image Set VI \\
% \qty{7.01}{\tebi\byte} & \href{magnet:?xt=urn:btih:a7edcf3f3a5fb8233263f2495f69c0b3ab3780bd}{\texttt{a7edcf3f}} & Japan \\
% \qty{6.91}{\tebi\byte} & \href{magnet:?xt=urn:btih:faf6e127104dcc1c1585d42861b28612c5f60722}{\texttt{faf6e127}} & 20210901 \\
% \qty{6.75}{\tebi\byte} & \href{magnet:?xt=urn:btih:d9ba79d29c7b34130f02e75ae80c61d95e67879c}{\texttt{d9ba79d2}} & MIG Switch Game Collection \\
% \qty{6.27}{\tebi\byte} & \href{magnet:?xt=urn:btih:3983c158cdc379f42f12a0175f63d8918944a33f}{\texttt{3983c158}} & e-hentai raws JAP Image Set VII \\
% \qty{6.11}{\tebi\byte} & \href{magnet:?xt=urn:btih:0e54f2b218407399f80c34d2f43ed6c41c72b4dc}{\texttt{0e54f2b2}} & NTLM 9 \\
% \qty{6.09}{\tebi\byte} & \href{magnet:?xt=urn:btih:5fd27f4076c44da03b942794935f5d83a4152849}{\texttt{5fd27f40}} & [metart.com] Photosets - 1999 to 2023 \\
% \hline
% \end{tabular}
% \end{table}

\begin{table}[htbp]
\centering
\caption{10 največjih posameznih datotek (globalno).}
\label{najvdatoteke}
\begin{tabular}{@{}r l p{7cm}@{}}
\hline
velikost & infohash & ime \\
\hline
\qty{3.35}{\tebi\byte} & \href{magnet:?xt=urn:btih:37eb5bd38c8c07a593f1f0480a1a693c48e5d4ca}{\texttt{37eb5bd3}} & annas-archive-ia-lcpdf-per\_c.tar \\
\qty{2.81}{\tebi\byte} & \href{magnet:?xt=urn:btih:51e3001946e63a7a7ee2da4412b98ca620e71c5d}{\texttt{51e30019}} & Pegasus G V1.1 without Android only Windows.CHT.7z \\
\qty{2.27}{\tebi\byte} & \href{magnet:?xt=urn:btih:e48b620bf5c44b111589fba0538ead1396dbd550}{\texttt{e48b620b}} & annas-archive-ia-lcpdf-b.tar \\
\qty{2.13}{\tebi\byte} & \href{magnet:?xt=urn:btih:5e80fab708851a4e3629edbf6947a6d014ba99e8}{\texttt{5e80fab7}} & annas-archive-ia-acsm-m.tar \\
\qty{2.09}{\tebi\byte} & \href{magnet:?xt=urn:btih:a883ce9e746b590925be3ca3ae3c1fe98e7c6c17}{\texttt{a883ce9e}} & annas-archive-ia-acsm-p.tar \\
\qty{2.04}{\tebi\byte} & \href{magnet:?xt=urn:btih:fa023aae0bf3cf8fb8878f0f0a99d3f3c02b650d}{\texttt{fa023aae}} & annas-archive-ia-acsm-a.tar \\
\qty{1.97}{\tebi\byte} & \href{magnet:?xt=urn:btih:5bccfd692a2ce67234b00c8865ab58e36b9b72d3}{\texttt{5bccfd69}} & annas\_archive\_spotify\_2025\_07\_{\allowbreak}coverart.tar \\
\qty{1.95}{\tebi\byte} & \href{magnet:?xt=urn:btih:42c3e52b83853859df386c2d07632e3fd2f44176}{\texttt{42c3e52b}} & Comfyui\_Mie\_Models.zip \\
\qty{1.86}{\tebi\byte} & \href{magnet:?xt=urn:btih:503655cf3ccf1548edb4e2be1b9b7a2893476231}{\texttt{503655cf}} & annas-archive-ia-acsm-l.tar \\
\qty{1.83}{\tebi\byte} & \href{magnet:?xt=urn:btih:9cf538794683db6296b0c2c90645605067673c82}{\texttt{9cf53879}} & annas-archive-ia-acsm-b.tar \\
\hline
\end{tabular}
\end{table}

Najpogosteje uporabljena vrata TCP odjemalcev, po katerih smo prejeli torrente, so prikazana na sliki~\ref{vrata}, najpogosteje uporabljeni naslovi IP pa na sliki~\ref{naslovi}. Od \qty{75,37}{\percent} naslovov IP smo prejeli natanko en torrent.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/vrata.pgf}
		\caption{Najpogosteje uporabljena oddaljena vrata TCP, na katera smo se povezovali za prenos metapodatkov.}
		\label{vrata}
	\end{center}
\end{figure}
\begin{figure}[htbp]
	\begin{center}
		\input{slike/ipnaslovi.pgf}
		\caption{Naslovi IP, od katerih smo prejeli največ metapodatkov.}
		\label{naslovi}
	\end{center}
\end{figure}

Od 43161 naslovov smo prejeli vsaj dva torrenta v razmaku vsaj enega meseca. Izmed njih jih je svoj odjemalec posodobilo vsaj 6920 (\qty{16.03}{\percent}). Toliko izmed njih smo namreč videli najprej z nižjo in nato z višjo različico odjemalca.

Trdili smo, da infohashi najbrž ne bodo enakomerno porazdeljeni, zato smo pripravili izrise porazdelitve prejetih infohashev na sliki~\ref{infohashi}.
\begin{figure}[htbp]
	\begin{center}
		\includegraphics{slike/infohashi-crop.pdf}
		\caption{Gostota porazdelitve infohashev prejetih torrentov.}
		\label{infohashi}
	\end{center}
\end{figure}

Omenili smo, da smo za reševanje pred napadom Sybil med zajemom menjali ID. Ker smo ga vedno zamenjali na povsem naključnega, iz slike z gostoto porazdelitve infohashev na celotnem korpusu ni razvidno, da bi bili pristranski do izbire infohashev. Da bi bolje prikazali pristranskost ob nespremenljivem ID-ju, smo pognali namenski zajem s konstantnim ID (zajemali smo dokler nismo naleteli na napad Sybil). Slika~\ref{infohashiconstid} (in povečava na sliki~\ref{infohashiconstidzoom}) prikazuje gostoto porazdelitve tako pridobljenih torrentov.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/infohashiconstid.pgf}
		\caption{Gostota porazdelitve infohashev prejetih torrentov v majhnem namenskem zajemu 518 torrentov.}
		\label{infohashiconstid}
	\end{center}
\end{figure}
\begin{figure}[htbp]
	\begin{center}
		\input{slike/infohashiconstidzoom.pgf}
		\caption{Gostota porazdelitve infohashev prejetih torrentov v majhnem namenskem zajemu 518 torrentov -- povečava na območje z veliko torrenti.}
		\label{infohashiconstidzoom}
	\end{center}
\end{figure}

\chapter{Zaključek}
\label{zakljucek}
Predstavljeni podatki kažejo sliko uporabe omrežja BitTorrent. Med analizo opažena ključna pomanjkljivost podatkov, ki izvira že iz načina zajema, je, da nimamo vsebine datotek, poleg tega pa imamo za vsak torrent shranjenega samo enega člana roja -- tistega, od katerega smo metapodatke prejeli.

V bodočih raziskavah na tem področju bi bilo vsled tega smiselno pridobivati podatke o celotnem roju, najlažje in najučinkovitejše z dodatkom standarda PeX (izmenjava soležnikov)~\cite{bep11}, ter podatke o vsebini datotek od soležnikov. Za določanje podrobnosti tipa datoteke (kodek, vsebina arhiva ZIP, jezik dokumentov, itd.) bi bilo dovolj prenesti le prvi ali zadnji košček datoteke, s čimer bi
napram % arhaizem -> v primerjavi z
nemogočemu podvigu prenašanja celotne vsebine datotek znatno zmanjšali porabo pasovne širine.

Naša zastavljena cilja o izdelavi programa za zajem in o analizi pridobljenih podatkov sta bila dosežena. Program je po sklepu o algoritmu~\ref{pridobisoleznikeinoznanjaj} res nepristranski in omrežja ni motil, saj se je držal standardov za izdelavo odjemalca BitTorrent. Zajeli smo dovolj podatkov, da smo lahko sklepali o sestavi omrežja.

Hipotezo tipu vsebine, ki jo uporabniki prenašajo, potrdimo. Videovsebine so res najpopularnejša oblika datotek glede na končnico. Prav tako na podlagi razdelka~\ref{razlicicesection} o različicah odjemalcev qBittorrent sklepamo, da uporabniki res po večini uporabljajo aktualne različice programske opreme.

\section{Etika in varstvo podatkov}

Uporabnike omrežja BitTorrent programska oprema za povezavo v omrežje običajno pred prvim zagonom obvesti o javnosti njihove komunikacije v omrežju. Prav tako odjemalci jasno kažejo naslove IP drugih uporabnikov v omrežju med prenosom podatkov, kar pomeni, da se uporabniki zavedajo, da je njihova aktivnost v omrežju drugim znana. Iz tega sklepamo, da naša raziskava ni pretirano posegala v osebne podatke uporabnikov omrežja.

V nalogi nismo objavili naslovov IP domačih uporabnikov. Objavili smo le naslove, ki rekordno izstopajo po količini torrentov, ki jih prenašajo. Razumno lahko sklepamo, da ne gre za posamezne fizične osebe, temveč za strežnike, ki prenašajo torrente po navodilih velike množice oseb (seedbox).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  LITERATURA
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%\cleardoublepage
\printbibliography[heading=bibintoc]

\chapter{Priloge}
\label{priloge}
Izvorna koda programa za zajem, ki smo ga implementirali, je dostopna na \url{http://ni.4a.si/sijanec/travnik}. % http://4a.si/travnikprog
Korpus, na katerem smo izvajali analizo, pošljemo na zahtevo na elektronski naslov \href{mailto:anton@sijanec.eu}{anton@sijanec.eu}.

\begin{figure}[htbp]
	\begin{center}
		\input{slike/po številu datotek.pgf}
		\caption{Tipi glede na število datotek v vseh torrentih.}
		\label{stevilo}
	\end{center}
\end{figure}

\begin{figure}[htbp]
	\begin{center}
		\input{slike/po velikosti datotek.pgf}
		\caption{Tipi glede na skupno velikost datotek v vseh torrentih.}
		\label{velikost}
	\end{center}
\end{figure}

% \begin{center}
% \captionof{listing}{Izpis usmerjevalne tabele, ko je bil zaznan napad Sybil.}
% \label{sybil}
% \lstset{
%   basicstyle=\fontsize{6}{8}\selectfont\ttfamily,
%   breaklines=true,
%   frame=single,        % optional
%   columns=fullflexible  % nicer spacing
% }
% \lstinputlisting{podporno/sybil.txt}
% \end{center}

\end{document}
